1// Polyfills 2 3if ( Number.EPSILON === undefined ) { 4 5 Number.EPSILON = Math.pow( 2, - 52 ); 6 7} 8 9if ( Number.isInteger === undefined ) { 10 11 // Missing in IE 12 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger 13 14 Number.isInteger = function ( value ) { 15 16 return typeof value === 'number' && isFinite( value ) && Math.floor( value ) === value; 17 18 }; 19 20} 21 22// 23 24if ( Math.sign === undefined ) { 25 26 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign 27 28 Math.sign = function ( x ) { 29 30 return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x; 31 32 }; 33 34} 35 36if ( 'name' in Function.prototype === false ) { 37 38 // Missing in IE 39 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name 40 41 Object.defineProperty( Function.prototype, 'name', { 42 43 get: function () { 44 45 return this.toString().match( /^\s*function\s*([^\(\s]*)/ )[ 1 ]; 46 47 } 48 49 } ); 50 51} 52 53if ( Object.assign === undefined ) { 54 55 // Missing in IE 56 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign 57 58 Object.assign = function ( target ) { 59 60 if ( target === undefined || target === null ) { 61 62 throw new TypeError( 'Cannot convert undefined or null to object' ); 63 64 } 65 66 var output = Object( target ); 67 68 for ( var index = 1; index < arguments.length; index ++ ) { 69 70 var source = arguments[ index ]; 71 72 if ( source !== undefined && source !== null ) { 73 74 for ( var nextKey in source ) { 75 76 if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) { 77 78 output[ nextKey ] = source[ nextKey ]; 79 80 } 81 82 } 83 84 } 85 86 } 87 88 return output; 89 90 }; 91 92} 93 94var REVISION = '116'; 95var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 }; 96var TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 }; 97var CullFaceNone = 0; 98var CullFaceBack = 1; 99var CullFaceFront = 2; 100var CullFaceFrontBack = 3; 101var FrontFaceDirectionCW = 0; 102var FrontFaceDirectionCCW = 1; 103var BasicShadowMap = 0; 104var PCFShadowMap = 1; 105var PCFSoftShadowMap = 2; 106var VSMShadowMap = 3; 107var FrontSide = 0; 108var BackSide = 1; 109var DoubleSide = 2; 110var FlatShading = 1; 111var SmoothShading = 2; 112var NoBlending = 0; 113var NormalBlending = 1; 114var AdditiveBlending = 2; 115var SubtractiveBlending = 3; 116var MultiplyBlending = 4; 117var CustomBlending = 5; 118var AddEquation = 100; 119var SubtractEquation = 101; 120var ReverseSubtractEquation = 102; 121var MinEquation = 103; 122var MaxEquation = 104; 123var ZeroFactor = 200; 124var OneFactor = 201; 125var SrcColorFactor = 202; 126var OneMinusSrcColorFactor = 203; 127var SrcAlphaFactor = 204; 128var OneMinusSrcAlphaFactor = 205; 129var DstAlphaFactor = 206; 130var OneMinusDstAlphaFactor = 207; 131var DstColorFactor = 208; 132var OneMinusDstColorFactor = 209; 133var SrcAlphaSaturateFactor = 210; 134var NeverDepth = 0; 135var AlwaysDepth = 1; 136var LessDepth = 2; 137var LessEqualDepth = 3; 138var EqualDepth = 4; 139var GreaterEqualDepth = 5; 140var GreaterDepth = 6; 141var NotEqualDepth = 7; 142var MultiplyOperation = 0; 143var MixOperation = 1; 144var AddOperation = 2; 145var NoToneMapping = 0; 146var LinearToneMapping = 1; 147var ReinhardToneMapping = 2; 148var Uncharted2ToneMapping = 3; 149var CineonToneMapping = 4; 150var ACESFilmicToneMapping = 5; 151 152var UVMapping = 300; 153var CubeReflectionMapping = 301; 154var CubeRefractionMapping = 302; 155var EquirectangularReflectionMapping = 303; 156var EquirectangularRefractionMapping = 304; 157var SphericalReflectionMapping = 305; 158var CubeUVReflectionMapping = 306; 159var CubeUVRefractionMapping = 307; 160var RepeatWrapping = 1000; 161var ClampToEdgeWrapping = 1001; 162var MirroredRepeatWrapping = 1002; 163var NearestFilter = 1003; 164var NearestMipmapNearestFilter = 1004; 165var NearestMipMapNearestFilter = 1004; 166var NearestMipmapLinearFilter = 1005; 167var NearestMipMapLinearFilter = 1005; 168var LinearFilter = 1006; 169var LinearMipmapNearestFilter = 1007; 170var LinearMipMapNearestFilter = 1007; 171var LinearMipmapLinearFilter = 1008; 172var LinearMipMapLinearFilter = 1008; 173var UnsignedByteType = 1009; 174var ByteType = 1010; 175var ShortType = 1011; 176var UnsignedShortType = 1012; 177var IntType = 1013; 178var UnsignedIntType = 1014; 179var FloatType = 1015; 180var HalfFloatType = 1016; 181var UnsignedShort4444Type = 1017; 182var UnsignedShort5551Type = 1018; 183var UnsignedShort565Type = 1019; 184var UnsignedInt248Type = 1020; 185var AlphaFormat = 1021; 186var RGBFormat = 1022; 187var RGBAFormat = 1023; 188var LuminanceFormat = 1024; 189var LuminanceAlphaFormat = 1025; 190var RGBEFormat = RGBAFormat; 191var DepthFormat = 1026; 192var DepthStencilFormat = 1027; 193var RedFormat = 1028; 194var RedIntegerFormat = 1029; 195var RGFormat = 1030; 196var RGIntegerFormat = 1031; 197var RGBIntegerFormat = 1032; 198var RGBAIntegerFormat = 1033; 199 200var RGB_S3TC_DXT1_Format = 33776; 201var RGBA_S3TC_DXT1_Format = 33777; 202var RGBA_S3TC_DXT3_Format = 33778; 203var RGBA_S3TC_DXT5_Format = 33779; 204var RGB_PVRTC_4BPPV1_Format = 35840; 205var RGB_PVRTC_2BPPV1_Format = 35841; 206var RGBA_PVRTC_4BPPV1_Format = 35842; 207var RGBA_PVRTC_2BPPV1_Format = 35843; 208var RGB_ETC1_Format = 36196; 209var RGB_ETC2_Format = 37492; 210var RGBA_ETC2_EAC_Format = 37496; 211var RGBA_ASTC_4x4_Format = 37808; 212var RGBA_ASTC_5x4_Format = 37809; 213var RGBA_ASTC_5x5_Format = 37810; 214var RGBA_ASTC_6x5_Format = 37811; 215var RGBA_ASTC_6x6_Format = 37812; 216var RGBA_ASTC_8x5_Format = 37813; 217var RGBA_ASTC_8x6_Format = 37814; 218var RGBA_ASTC_8x8_Format = 37815; 219var RGBA_ASTC_10x5_Format = 37816; 220var RGBA_ASTC_10x6_Format = 37817; 221var RGBA_ASTC_10x8_Format = 37818; 222var RGBA_ASTC_10x10_Format = 37819; 223var RGBA_ASTC_12x10_Format = 37820; 224var RGBA_ASTC_12x12_Format = 37821; 225var RGBA_BPTC_Format = 36492; 226var SRGB8_ALPHA8_ASTC_4x4_Format = 37840; 227var SRGB8_ALPHA8_ASTC_5x4_Format = 37841; 228var SRGB8_ALPHA8_ASTC_5x5_Format = 37842; 229var SRGB8_ALPHA8_ASTC_6x5_Format = 37843; 230var SRGB8_ALPHA8_ASTC_6x6_Format = 37844; 231var SRGB8_ALPHA8_ASTC_8x5_Format = 37845; 232var SRGB8_ALPHA8_ASTC_8x6_Format = 37846; 233var SRGB8_ALPHA8_ASTC_8x8_Format = 37847; 234var SRGB8_ALPHA8_ASTC_10x5_Format = 37848; 235var SRGB8_ALPHA8_ASTC_10x6_Format = 37849; 236var SRGB8_ALPHA8_ASTC_10x8_Format = 37850; 237var SRGB8_ALPHA8_ASTC_10x10_Format = 37851; 238var SRGB8_ALPHA8_ASTC_12x10_Format = 37852; 239var SRGB8_ALPHA8_ASTC_12x12_Format = 37853; 240var LoopOnce = 2200; 241var LoopRepeat = 2201; 242var LoopPingPong = 2202; 243var InterpolateDiscrete = 2300; 244var InterpolateLinear = 2301; 245var InterpolateSmooth = 2302; 246var ZeroCurvatureEnding = 2400; 247var ZeroSlopeEnding = 2401; 248var WrapAroundEnding = 2402; 249var NormalAnimationBlendMode = 2500; 250var AdditiveAnimationBlendMode = 2501; 251var TrianglesDrawMode = 0; 252var TriangleStripDrawMode = 1; 253var TriangleFanDrawMode = 2; 254var LinearEncoding = 3000; 255var sRGBEncoding = 3001; 256var GammaEncoding = 3007; 257var RGBEEncoding = 3002; 258var LogLuvEncoding = 3003; 259var RGBM7Encoding = 3004; 260var RGBM16Encoding = 3005; 261var RGBDEncoding = 3006; 262var BasicDepthPacking = 3200; 263var RGBADepthPacking = 3201; 264var TangentSpaceNormalMap = 0; 265var ObjectSpaceNormalMap = 1; 266 267var ZeroStencilOp = 0; 268var KeepStencilOp = 7680; 269var ReplaceStencilOp = 7681; 270var IncrementStencilOp = 7682; 271var DecrementStencilOp = 7683; 272var IncrementWrapStencilOp = 34055; 273var DecrementWrapStencilOp = 34056; 274var InvertStencilOp = 5386; 275 276var NeverStencilFunc = 512; 277var LessStencilFunc = 513; 278var EqualStencilFunc = 514; 279var LessEqualStencilFunc = 515; 280var GreaterStencilFunc = 516; 281var NotEqualStencilFunc = 517; 282var GreaterEqualStencilFunc = 518; 283var AlwaysStencilFunc = 519; 284 285var StaticDrawUsage = 35044; 286var DynamicDrawUsage = 35048; 287var StreamDrawUsage = 35040; 288var StaticReadUsage = 35045; 289var DynamicReadUsage = 35049; 290var StreamReadUsage = 35041; 291var StaticCopyUsage = 35046; 292var DynamicCopyUsage = 35050; 293var StreamCopyUsage = 35042; 294 295/** 296 * https://github.com/mrdoob/eventdispatcher.js/ 297 */ 298 299function EventDispatcher() {} 300 301Object.assign( EventDispatcher.prototype, { 302 303 addEventListener: function ( type, listener ) { 304 305 if ( this._listeners === undefined ) this._listeners = {}; 306 307 var listeners = this._listeners; 308 309 if ( listeners[ type ] === undefined ) { 310 311 listeners[ type ] = []; 312 313 } 314 315 if ( listeners[ type ].indexOf( listener ) === - 1 ) { 316 317 listeners[ type ].push( listener ); 318 319 } 320 321 }, 322 323 hasEventListener: function ( type, listener ) { 324 325 if ( this._listeners === undefined ) return false;
326 327 var listeners = this._listeners; 328 329 return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1; 330 331 }, 332 333 removeEventListener: function ( type, listener ) { 334 335 if ( this._listeners === undefined ) return; 336 337 var listeners = this._listeners; 338 var listenerArray = listeners[ type ]; 339 340 if ( listenerArray !== undefined ) { 341 342 var index = listenerArray.indexOf( listener ); 343 344 if ( index !== - 1 ) { 345 346 listenerArray.splice( index, 1 ); 347 348 } 349 350 } 351 352 }, 353 354 dispatchEvent: function ( event ) { 355 356 if ( this._listeners === undefined ) return; 357 358 var listeners = this._listeners; 359 var listenerArray = listeners[ event.type ]; 360 361 if ( listenerArray !== undefined ) { 362 363 event.target = this; 364 365 // Make a copy, in case listeners are removed while iterating. 366 var array = listenerArray.slice( 0 ); 367 368 for ( var i = 0, l = array.length; i < l; i ++ ) { 369 370 array[ i ].call( this, event ); 371 372 } 373 374 } 375 376 } 377 378} ); 379 380/** 381 * @author alteredq / http://alteredqualia.com/ 382 * @author mrdoob / http://mrdoob.com/ 383 * @author WestLangley / http://github.com/WestLangley 384 * @author thezwap 385 */ 386 387var _lut = []; 388 389for ( var i = 0; i < 256; i ++ ) { 390 391 _lut[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 ); 392 393} 394 395var MathUtils = { 396 397 DEG2RAD: Math.PI / 180, 398 RAD2DEG: 180 / Math.PI, 399 400 generateUUID: function () { 401 402 // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 403 404 var d0 = Math.random() * 0xffffffff | 0; 405 var d1 = Math.random() * 0xffffffff | 0; 406 var d2 = Math.random() * 0xffffffff | 0; 407 var d3 = Math.random() * 0xffffffff | 0; 408 var uuid = _lut[ d0 & 0xff ] + _lut[ d0 >> 8 & 0xff ] + _lut[ d0 >> 16 & 0xff ] + _lut[ d0 >> 24 & 0xff ] + '-' + 409 _lut[ d1 & 0xff ] + _lut[ d1 >> 8 & 0xff ] + '-' + _lut[ d1 >> 16 & 0x0f | 0x40 ] + _lut[ d1 >> 24 & 0xff ] + '-' + 410 _lut[ d2 & 0x3f | 0x80 ] + _lut[ d2 >> 8 & 0xff ] + '-' + _lut[ d2 >> 16 & 0xff ] + _lut[ d2 >> 24 & 0xff ] + 411 _lut[ d3 & 0xff ] + _lut[ d3 >> 8 & 0xff ] + _lut[ d3 >> 16 & 0xff ] + _lut[ d3 >> 24 & 0xff ]; 412 413 // .toUpperCase() here flattens concatenated strings to save heap memory space. 414 return uuid.toUpperCase(); 415 416 }, 417 418 clamp: function ( value, min, max ) { 419 420 return Math.max( min, Math.min( max, value ) ); 421 422 }, 423 424 // compute euclidian modulo of m % n 425 // https://en.wikipedia.org/wiki/Modulo_operation 426 427 euclideanModulo: function ( n, m ) { 428 429 return ( ( n % m ) + m ) % m; 430 431 }, 432 433 // Linear mapping from range <a1, a2> to range <b1, b2> 434 435 mapLinear: function ( x, a1, a2, b1, b2 ) { 436 437 return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 ); 438 439 }, 440 441 // https://en.wikipedia.org/wiki/Linear_interpolation 442 443 lerp: function ( x, y, t ) { 444 445 return ( 1 - t ) * x + t * y; 446 447 }, 448 449 // http://en.wikipedia.org/wiki/Smoothstep 450 451 smoothstep: function ( x, min, max ) { 452 453 if ( x <= min ) return 0; 454 if ( x >= max ) return 1; 455 456 x = ( x - min ) / ( max - min ); 457 458 return x * x * ( 3 - 2 * x ); 459 460 }, 461 462 smootherstep: function ( x, min, max ) { 463 464 if ( x <= min ) return 0; 465 if ( x >= max ) return 1; 466 467 x = ( x - min ) / ( max - min ); 468 469 return x * x * x * ( x * ( x * 6 - 15 ) + 10 ); 470 471 }, 472 473 // Random integer from <low, high> interval 474 475 randInt: function ( low, high ) { 476 477 return low + Math.floor( Math.random() * ( high - low + 1 ) ); 478 479 }, 480 481 // Random float from <low, high> interval 482 483 randFloat: function ( low, high ) { 484 485 return low + Math.random() * ( high - low ); 486 487 }, 488 489 // Random float from <-range/2, range/2> interval 490 491 randFloatSpread: function ( range ) { 492 493 return range * ( 0.5 - Math.random() ); 494 495 }, 496 497 degToRad: function ( degrees ) { 498 499 return degrees * MathUtils.DEG2RAD; 500 501 }, 502 503 radToDeg: function ( radians ) { 504 505 return radians * MathUtils.RAD2DEG; 506 507 }, 508 509 isPowerOfTwo: function ( value ) { 510 511 return ( value & ( value - 1 ) ) === 0 && value !== 0; 512 513 }, 514 515 ceilPowerOfTwo: function ( value ) { 516 517 return Math.pow( 2, Math.ceil( Math.log( value ) / Math.LN2 ) ); 518 519 }, 520 521 floorPowerOfTwo: function ( value ) { 522 523 return Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) ); 524 525 }, 526 527 setQuaternionFromProperEuler: function ( q, a, b, c, order ) { 528 529 // Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles 530 531 // rotations are applied to the axes in the order specified by 'order' 532 // rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c' 533 // angles are in radians 534 535 var cos = Math.cos; 536 var sin = Math.sin; 537 538 var c2 = cos( b / 2 ); 539 var s2 = sin( b / 2 ); 540 541 var c13 = cos( ( a + c ) / 2 ); 542 var s13 = sin( ( a + c ) / 2 ); 543 544 var c1_3 = cos( ( a - c ) / 2 ); 545 var s1_3 = sin( ( a - c ) / 2 ); 546 547 var c3_1 = cos( ( c - a ) / 2 ); 548 var s3_1 = sin( ( c - a ) / 2 ); 549 550 switch ( order ) { 551 552 case 'XYX': 553 q.set( c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13 ); 554 break; 555 556 case 'YZY': 557 q.set( s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13 ); 558 break; 559 560 case 'ZXZ': 561 q.set( s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13 ); 562 break; 563 564 case 'XZX': 565 q.set( c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13 ); 566 break; 567 568 case 'YXY': 569 q.set( s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13 ); 570 break; 571 572 case 'ZYZ': 573 q.set( s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13 ); 574 break; 575 576 default: 577 console.warn( 'THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order ); 578 579 } 580 581 } 582 583}; 584 585/** 586 * @author mrdoob / http://mrdoob.com/ 587 * @author philogb / http://blog.thejit.org/ 588 * @author egraether / http://egraether.com/ 589 * @author zz85 / http://www.lab4games.net/zz85/blog 590 */ 591 592function Vector2( x, y ) { 593 594 this.x = x || 0; 595 this.y = y || 0; 596 597} 598 599Object.defineProperties( Vector2.prototype, { 600 601 "width": { 602 603 get: function () { 604 605 return this.x; 606 607 }, 608 609 set: function ( value ) { 610 611 this.x = value; 612 613 } 614 615 }, 616 617 "height": { 618 619 get: function () { 620 621 return this.y; 622 623 }, 624 625 set: function ( value ) { 626 627 this.y = value; 628 629 } 630 631 } 632 633} ); 634 635Object.assign( Vector2.prototype, { 636 637 isVector2: true, 638 639 set: function ( x, y ) { 640 641 this.x = x; 642 this.y = y; 643 644 return this; 645 646 }, 647 648 setScalar: function ( scalar ) { 649 650 this.x = scalar; 651 this.y = scalar; 652 653 return this; 654 655 }, 656 657 setX: function ( x ) { 658 659 this.x = x; 660 661 return this; 662 663 }, 664 665 setY: function ( y ) { 666 667 this.y = y; 668 669 return this; 670 671 }, 672 673 setComponent: function ( index, value ) { 674 675 switch ( index ) { 676 677 case 0: this.x = value; break; 678 case 1: this.y = value; break; 679 default: throw new Error( 'index is out of range: ' + index ); 680 681 } 682 683 return this; 684 685 }, 686 687 getComponent: function ( index ) { 688 689 switch ( index ) { 690 691 case 0: return this.x; 692 case 1: return this.y; 693 default: throw new Error( 'index is out of range: ' + index ); 694 695 } 696 697 }, 698 699 clone: function () { 700 701 return new this.constructor( this.x, this.y ); 702 703 }, 704 705 copy: function ( v ) { 706 707 this.x = v.x; 708 this.y = v.y; 709 710 return this; 711 712 }, 713 714 add: function ( v, w ) { 715 716 if ( w !== undefined ) { 717 718 console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); 719 return this.addVectors( v, w ); 720 721 } 722 723 this.x += v.x; 724 this.y += v.y; 725 726 return this; 727 728 }, 729 730 addScalar: function ( s ) { 731 732 this.x += s; 733 this.y += s; 734 735 return this; 736 737 }, 738 739 addVectors: function ( a, b ) { 740 741 this.x = a.x + b.x; 742 this.y = a.y + b.y; 743 744 return this; 745 746 }, 747 748 addScaledVector: function ( v, s ) { 749 750 this.x += v.x * s; 751 this.y += v.y * s; 752 753 return this; 754 755 }, 756 757 sub: function ( v, w ) { 758 759 if ( w !== undefined ) { 760 761 console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); 762 return this.subVectors( v, w ); 763 764 } 765 766 this.x -= v.x; 767 this.y -= v.y; 768 769 return this; 770 771 }, 772 773 subScalar: function ( s ) { 774 775 this.x -= s; 776 this.y -= s; 777 778 return this; 779 780 }, 781 782 subVectors: function ( a, b ) { 783 784 this.x = a.x - b.x; 785 this.y = a.y - b.y; 786 787 return this; 788 789 }, 790 791 multiply: function ( v ) { 792 793 this.x *= v.x; 794 this.y *= v.y; 795 796 return this; 797 798 }, 799 800 multiplyScalar: function ( scalar ) { 801 802 this.x *= scalar; 803 this.y *= scalar; 804 805 return this; 806 807 }, 808 809 divide: function ( v ) { 810 811 this.x /= v.x; 812 this.y /= v.y; 813 814 return this; 815 816 }, 817 818 divideScalar: function ( scalar ) { 819 820 return this.multiplyScalar( 1 / scalar ); 821 822 }, 823 824 applyMatrix3: function ( m ) { 825 826 var x = this.x, y = this.y; 827 var e = m.elements; 828 829 this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ]; 830 this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ]; 831 832 return this; 833 834 }, 835 836 min: function ( v ) { 837 838 this.x = Math.min( this.x, v.x ); 839 this.y = Math.min( this.y, v.y ); 840 841 return this; 842 843 }, 844 845 max: function ( v ) { 846 847 this.x = Math.max( this.x, v.x ); 848 this.y = Math.max( this.y, v.y ); 849 850 return this; 851 852 }, 853 854 clamp: function ( min, max ) { 855 856 // assumes min < max, componentwise 857 858 this.x = Math.max( min.x, Math.min( max.x, this.x ) ); 859 this.y = Math.max( min.y, Math.min( max.y, this.y ) ); 860 861 return this; 862 863 }, 864 865 clampScalar: function ( minVal, maxVal ) { 866 867 this.x = Math.max( minVal, Math.min( maxVal, this.x ) ); 868 this.y = Math.max( minVal, Math.min( maxVal, this.y ) ); 869 870 return this; 871 872 }, 873 874 clampLength: function ( min, max ) { 875 876 var length = this.length(); 877 878 return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); 879 880 }, 881 882 floor: function () { 883 884 this.x = Math.floor( this.x ); 885 this.y = Math.floor( this.y ); 886 887 return this; 888 889 }, 890 891 ceil: function () { 892 893 this.x = Math.ceil( this.x ); 894 this.y = Math.ceil( this.y ); 895 896 return this; 897 898 }, 899 900 round: function () { 901 902 this.x = Math.round( this.x ); 903 this.y = Math.round( this.y ); 904 905 return this; 906 907 }, 908 909 roundToZero: function () { 910 911 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); 912 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); 913 914 return this; 915 916 }, 917 918 negate: function () { 919 920 this.x = - this.x; 921 this.y = - this.y; 922 923 return this; 924 925 }, 926 927 dot: function ( v ) { 928 929 return this.x * v.x + this.y * v.y; 930 931 }, 932 933 cross: function ( v ) { 934 935 return this.x * v.y - this.y * v.x; 936 937 }, 938 939 lengthSq: function () { 940 941 return this.x * this.x + this.y * this.y; 942 943 }, 944 945 length: function () { 946 947 return Math.sqrt( this.x * this.x + this.y * this.y ); 948 949 }, 950 951 manhattanLength: function () { 952 953 return Math.abs( this.x ) + Math.abs( this.y ); 954 955 }, 956 957 normalize: function () { 958 959 return this.divideScalar( this.length() || 1 ); 960 961 }, 962 963 angle: function () { 964 965 // computes the angle in radians with respect to the positive x-axis 966 967 var angle = Math.atan2( - this.y, - this.x ) + Math.PI; 968 969 return angle; 970 971 }, 972 973 distanceTo: function ( v ) { 974 975 return Math.sqrt( this.distanceToSquared( v ) ); 976 977 }, 978 979 distanceToSquared: function ( v ) { 980 981 var dx = this.x - v.x, dy = this.y - v.y; 982 return dx * dx + dy * dy; 983 984 }, 985 986 manhattanDistanceTo: function ( v ) { 987 988 return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ); 989 990 }, 991 992 setLength: function ( length ) { 993 994 return this.normalize().multiplyScalar( length ); 995 996 }, 997 998 lerp: function ( v, alpha ) { 999 1000 this.x += ( v.x - this.x ) * alpha; 1001 this.y += ( v.y - this.y ) * alpha; 1002 1003 return this; 1004 1005 }, 1006 1007 lerpVectors: function ( v1, v2, alpha ) { 1008 1009 return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); 1010 1011 }, 1012 1013 equals: function ( v ) { 1014 1015 return ( ( v.x === this.x ) && ( v.y === this.y ) ); 1016 1017 }, 1018 1019 fromArray: function ( array, offset ) { 1020 1021 if ( offset === undefined ) offset = 0; 1022 1023 this.x = array[ offset ]; 1024 this.y = array[ offset + 1 ]; 1025 1026 return this; 1027 1028 }, 1029 1030 toArray: function ( array, offset ) { 1031 1032 if ( array === undefined ) array = []; 1033 if ( offset === undefined ) offset = 0; 1034 1035 array[ offset ] = this.x; 1036 array[ offset + 1 ] = this.y; 1037 1038 return array; 1039 1040 }, 1041 1042 fromBufferAttribute: function ( attribute, index, offset ) { 1043 1044 if ( offset !== undefined ) { 1045 1046 console.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' ); 1047 1048 } 1049 1050 this.x = attribute.getX( index ); 1051 this.y = attribute.getY( index ); 1052 1053 return this; 1054 1055 }, 1056
1057 rotateAround: function ( center, angle ) { 1058 1059 var c = Math.cos( angle ), s = Math.sin( angle ); 1060 1061 var x = this.x - center.x; 1062 var y = this.y - center.y; 1063 1064 this.x = x * c - y * s + center.x; 1065 this.y = x * s + y * c + center.y; 1066 1067 return this; 1068 1069 }, 1070 1071 random: function () { 1072 1073 this.x = Math.random(); 1074 this.y = Math.random(); 1075 1076 return this; 1077 1078 } 1079 1080} ); 1081 1082/** 1083 * @author alteredq / http://alteredqualia.com/ 1084 * @author WestLangley / http://github.com/WestLangley 1085 * @author bhouston / http://clara.io 1086 * @author tschw 1087 */ 1088 1089function Matrix3() { 1090 1091 this.elements = [ 1092 1093 1, 0, 0, 1094 0, 1, 0, 1095 0, 0, 1 1096 1097 ]; 1098 1099 if ( arguments.length > 0 ) { 1100 1101 console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); 1102 1103 } 1104 1105} 1106 1107Object.assign( Matrix3.prototype, { 1108 1109 isMatrix3: true, 1110 1111 set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { 1112 1113 var te = this.elements; 1114 1115 te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31; 1116 te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32; 1117 te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33; 1118 1119 return this; 1120 1121 }, 1122 1123 identity: function () { 1124 1125 this.set( 1126 1127 1, 0, 0, 1128 0, 1, 0, 1129 0, 0, 1 1130 1131 ); 1132 1133 return this; 1134 1135 }, 1136 1137 clone: function () { 1138 1139 return new this.constructor().fromArray( this.elements ); 1140 1141 }, 1142 1143 copy: function ( m ) { 1144 1145 var te = this.elements; 1146 var me = m.elements; 1147 1148 te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; 1149 te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; 1150 te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ]; 1151 1152 return this; 1153 1154 }, 1155 1156 extractBasis: function ( xAxis, yAxis, zAxis ) { 1157 1158 xAxis.setFromMatrix3Column( this, 0 ); 1159 yAxis.setFromMatrix3Column( this, 1 ); 1160 zAxis.setFromMatrix3Column( this, 2 ); 1161 1162 return this; 1163 1164 }, 1165 1166 setFromMatrix4: function ( m ) { 1167 1168 var me = m.elements; 1169 1170 this.set( 1171 1172 me[ 0 ], me[ 4 ], me[ 8 ], 1173 me[ 1 ], me[ 5 ], me[ 9 ], 1174 me[ 2 ], me[ 6 ], me[ 10 ] 1175 1176 ); 1177 1178 return this; 1179 1180 }, 1181 1182 multiply: function ( m ) { 1183 1184 return this.multiplyMatrices( this, m ); 1185 1186 }, 1187 1188 premultiply: function ( m ) { 1189 1190 return this.multiplyMatrices( m, this ); 1191 1192 }, 1193 1194 multiplyMatrices: function ( a, b ) { 1195 1196 var ae = a.elements; 1197 var be = b.elements; 1198 var te = this.elements; 1199 1200 var a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ]; 1201 var a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ]; 1202 var a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ]; 1203 1204 var b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ]; 1205 var b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ]; 1206 var b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ]; 1207 1208 te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31; 1209 te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32; 1210 te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33; 1211 1212 te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31; 1213 te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32; 1214 te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33; 1215 1216 te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31; 1217 te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32; 1218 te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33; 1219 1220 return this; 1221 1222 }, 1223 1224 multiplyScalar: function ( s ) { 1225 1226 var te = this.elements; 1227 1228 te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s; 1229 te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s; 1230 te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s; 1231 1232 return this; 1233 1234 }, 1235 1236 determinant: function () { 1237 1238 var te = this.elements; 1239 1240 var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ], 1241 d = te[ 3 ], e = te[ 4 ], f = te[ 5 ], 1242 g = te[ 6 ], h = te[ 7 ], i = te[ 8 ]; 1243 1244 return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; 1245 1246 }, 1247 1248 getInverse: function ( matrix, throwOnDegenerate ) { 1249 1250 if ( throwOnDegenerate !== undefined ) { 1251 1252 console.warn( "THREE.Matrix3: .getInverse() can no longer be configured to throw on degenerate." ); 1253 1254 } 1255 1256 var me = matrix.elements, 1257 te = this.elements, 1258 1259 n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], 1260 n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ], 1261 n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ], 1262 1263 t11 = n33 * n22 - n32 * n23, 1264 t12 = n32 * n13 - n33 * n12, 1265 t13 = n23 * n12 - n22 * n13, 1266 1267 det = n11 * t11 + n21 * t12 + n31 * t13; 1268 1269 if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0 ); 1270 1271 var detInv = 1 / det; 1272 1273 te[ 0 ] = t11 * detInv; 1274 te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv; 1275 te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv; 1276 1277 te[ 3 ] = t12 * detInv; 1278 te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv; 1279 te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv; 1280 1281 te[ 6 ] = t13 * detInv; 1282 te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv; 1283 te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv; 1284 1285 return this; 1286 1287 }, 1288 1289 transpose: function () { 1290 1291 var tmp, m = this.elements; 1292 1293 tmp = m[ 1 ]; m[ 1 ] = m[ 3 ];
vendor: 8,738 bytes, lines 1293-1734
1293 m[ 3 ] = tmp; 1294 tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp; 1295 tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp; 1296 1297 return this; 1298 1299 }, 1300 1301 getNormalMatrix: function ( matrix4 ) { 1302 1303 return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose(); 1304 1305 }, 1306 1307 transposeIntoArray: function ( r ) { 1308 1309 var m = this.elements; 1310 1311 r[ 0 ] = m[ 0 ]; 1312 r[ 1 ] = m[ 3 ]; 1313 r[ 2 ] = m[ 6 ]; 1314 r[ 3 ] = m[ 1 ]; 1315 r[ 4 ] = m[ 4 ]; 1316 r[ 5 ] = m[ 7 ]; 1317 r[ 6 ] = m[ 2 ]; 1318 r[ 7 ] = m[ 5 ]; 1319 r[ 8 ] = m[ 8 ]; 1320 1321 return this; 1322 1323 }, 1324 1325 setUvTransform: function ( tx, ty, sx, sy, rotation, cx, cy ) { 1326 1327 var c = Math.cos( rotation ); 1328 var s = Math.sin( rotation ); 1329 1330 this.set( 1331 sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx, 1332 - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty, 1333 0, 0, 1 1334 ); 1335 1336 }, 1337 1338 scale: function ( sx, sy ) { 1339 1340 var te = this.elements; 1341 1342 te[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx; 1343 te[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy; 1344 1345 return this; 1346 1347 }, 1348 1349 rotate: function ( theta ) { 1350 1351 var c = Math.cos( theta ); 1352 var s = Math.sin( theta ); 1353 1354 var te = this.elements; 1355 1356 var a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ]; 1357 var a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ]; 1358 1359 te[ 0 ] = c * a11 + s * a21; 1360 te[ 3 ] = c * a12 + s * a22; 1361 te[ 6 ] = c * a13 + s * a23; 1362 1363 te[ 1 ] = - s * a11 + c * a21; 1364 te[ 4 ] = - s * a12 + c * a22; 1365 te[ 7 ] = - s * a13 + c * a23; 1366 1367 return this; 1368 1369 }, 1370 1371 translate: function ( tx, ty ) { 1372 1373 var te = this.elements; 1374 1375 te[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ]; 1376 te[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ]; 1377 1378 return this; 1379 1380 }, 1381 1382 equals: function ( matrix ) { 1383 1384 var te = this.elements; 1385 var me = matrix.elements; 1386 1387 for ( var i = 0; i < 9; i ++ ) { 1388 1389 if ( te[ i ] !== me[ i ] ) return false; 1390 1391 } 1392 1393 return true; 1394 1395 }, 1396 1397 fromArray: function ( array, offset ) { 1398 1399 if ( offset === undefined ) offset = 0; 1400 1401 for ( var i = 0; i < 9; i ++ ) { 1402 1403 this.elements[ i ] = array[ i + offset ]; 1404 1405 } 1406 1407 return this; 1408 1409 }, 1410 1411 toArray: function ( array, offset ) { 1412 1413 if ( array === undefined ) array = []; 1414 if ( offset === undefined ) offset = 0; 1415 1416 var te = this.elements; 1417 1418 array[ offset ] = te[ 0 ]; 1419 array[ offset + 1 ] = te[ 1 ]; 1420 array[ offset + 2 ] = te[ 2 ]; 1421 1422 array[ offset + 3 ] = te[ 3 ]; 1423 array[ offset + 4 ] = te[ 4 ]; 1424 array[ offset + 5 ] = te[ 5 ]; 1425 1426 array[ offset + 6 ] = te[ 6 ]; 1427 array[ offset + 7 ] = te[ 7 ]; 1428 array[ offset + 8 ] = te[ 8 ]; 1429 1430 return array; 1431 1432 } 1433 1434} ); 1435 1436/** 1437 * @author mrdoob / http://mrdoob.com/ 1438 * @author alteredq / http://alteredqualia.com/ 1439 * @author szimek / https://github.com/szimek/ 1440 */ 1441 1442var _canvas; 1443 1444var ImageUtils = { 1445 1446 getDataURL: function ( image ) { 1447 1448 var canvas; 1449 1450 if ( typeof HTMLCanvasElement == 'undefined' ) { 1451 1452 return image.src; 1453 1454 } else if ( image instanceof HTMLCanvasElement ) { 1455 1456 canvas = image; 1457 1458 } else { 1459 1460 if ( _canvas === undefined ) _canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); 1461 1462 _canvas.width = image.width; 1463 _canvas.height = image.height; 1464 1465 var context = _canvas.getContext( '2d' ); 1466 1467 if ( image instanceof ImageData ) { 1468 1469 context.putImageData( image, 0, 0 ); 1470 1471 } else { 1472 1473 context.drawImage( image, 0, 0, image.width, image.height ); 1474 1475 } 1476 1477 canvas = _canvas; 1478 1479 } 1480 1481 if ( canvas.width > 2048 || canvas.height > 2048 ) { 1482 1483 return canvas.toDataURL( 'image/jpeg', 0.6 ); 1484 1485 } else { 1486 1487 return canvas.toDataURL( 'image/png' ); 1488 1489 } 1490 1491 } 1492 1493}; 1494 1495/** 1496 * @author mrdoob / http://mrdoob.com/ 1497 * @author alteredq / http://alteredqualia.com/ 1498 * @author szimek / https://github.com/szimek/ 1499 */ 1500 1501var textureId = 0; 1502 1503function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { 1504 1505 Object.defineProperty( this, 'id', { value: textureId ++ } ); 1506 1507 this.uuid = MathUtils.generateUUID(); 1508 1509 this.name = ''; 1510 1511 this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE; 1512 this.mipmaps = []; 1513 1514 this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING; 1515 1516 this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping; 1517 this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping; 1518 1519 this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; 1520 this.minFilter = minFilter !== undefined ? minFilter : LinearMipmapLinearFilter; 1521 1522 this.anisotropy = anisotropy !== undefined ? anisotropy : 1; 1523 1524 this.format = format !== undefined ? format : RGBAFormat; 1525 this.internalFormat = null; 1526 this.type = type !== undefined ? type : UnsignedByteType; 1527 1528 this.offset = new Vector2( 0, 0 ); 1529 this.repeat = new Vector2( 1, 1 ); 1530 this.center = new Vector2( 0, 0 ); 1531 this.rotation = 0; 1532 1533 this.matrixAutoUpdate = true; 1534 this.matrix = new Matrix3(); 1535 1536 this.generateMipmaps = true; 1537 this.premultiplyAlpha = false; 1538 this.flipY = true; 1539 this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) 1540 1541 // Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap. 1542 // 1543 // Also changing the encoding after already used by a Material will not automatically make the Material 1544 // update. You need to explicitly call Material.needsUpdate to trigger it to recompile. 1545 this.encoding = encoding !== undefined ? encoding : LinearEncoding; 1546 1547 this.version = 0; 1548 this.onUpdate = null; 1549 1550} 1551 1552Texture.DEFAULT_IMAGE = undefined; 1553Texture.DEFAULT_MAPPING = UVMapping; 1554 1555Texture.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { 1556 1557 constructor: Texture, 1558 1559 isTexture: true, 1560 1561 updateMatrix: function () { 1562 1563 this.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y ); 1564 1565 }, 1566 1567 clone: function () { 1568 1569 return new this.constructor().copy( this ); 1570 1571 }, 1572 1573 copy: function ( source ) { 1574 1575 this.name = source.name; 1576 1577 this.image = source.image; 1578 this.mipmaps = source.mipmaps.slice( 0 ); 1579 1580 this.mapping = source.mapping; 1581 1582 this.wrapS = source.wrapS; 1583 this.wrapT = source.wrapT; 1584 1585 this.magFilter = source.magFilter; 1586 this.minFilter = source.minFilter; 1587 1588 this.anisotropy = source.anisotropy; 1589 1590 this.format = source.format; 1591 this.internalFormat = source.internalFormat; 1592 this.type = source.type; 1593 1594 this.offset.copy( source.offset ); 1595 this.repeat.copy( source.repeat ); 1596 this.center.copy( source.center ); 1597 this.rotation = source.rotation; 1598 1599 this.matrixAutoUpdate = source.matrixAutoUpdate; 1600 this.matrix.copy( source.matrix ); 1601 1602 this.generateMipmaps = source.generateMipmaps; 1603 this.premultiplyAlpha = source.premultiplyAlpha; 1604 this.flipY = source.flipY; 1605 this.unpackAlignment = source.unpackAlignment; 1606 this.encoding = source.encoding; 1607 1608 return this; 1609 1610 }, 1611 1612 toJSON: function ( meta ) { 1613 1614 var isRootObject = ( meta === undefined || typeof meta === 'string' ); 1615 1616 if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) { 1617 1618 return meta.textures[ this.uuid ]; 1619 1620 } 1621 1622 var output = { 1623 1624 metadata: { 1625 version: 4.5, 1626 type: 'Texture', 1627 generator: 'Texture.toJSON' 1628 }, 1629 1630 uuid: this.uuid, 1631 name: this.name, 1632 1633 mapping: this.mapping, 1634 1635 repeat: [ this.repeat.x, this.repeat.y ], 1636 offset: [ this.offset.x, this.offset.y ], 1637 center: [ this.center.x, this.center.y ], 1638 rotation: this.rotation, 1639 1640 wrap: [ this.wrapS, this.wrapT ], 1641 1642 format: this.format, 1643 type: this.type, 1644 encoding: this.encoding, 1645 1646 minFilter: this.minFilter, 1647 magFilter: this.magFilter, 1648 anisotropy: this.anisotropy, 1649 1650 flipY: this.flipY, 1651 1652 premultiplyAlpha: this.premultiplyAlpha, 1653 unpackAlignment: this.unpackAlignment 1654 1655 }; 1656 1657 if ( this.image !== undefined ) { 1658 1659 // TODO: Move to THREE.Image 1660 1661 var image = this.image; 1662 1663 if ( image.uuid === undefined ) { 1664 1665 image.uuid = MathUtils.generateUUID(); // UGH 1666 1667 } 1668 1669 if ( ! isRootObject && meta.images[ image.uuid ] === undefined ) { 1670 1671 var url; 1672 1673 if ( Array.isArray( image ) ) { 1674 1675 // process array of images e.g. CubeTexture 1676 1677 url = []; 1678 1679 for ( var i = 0, l = image.length; i < l; i ++ ) { 1680 1681 url.push( ImageUtils.getDataURL( image[ i ] ) ); 1682 1683 } 1684 1685 } else { 1686 1687 // process single image 1688 1689 url = ImageUtils.getDataURL( image ); 1690 1691 } 1692 1693 meta.images[ image.uuid ] = { 1694 uuid: image.uuid, 1695 url: url 1696 }; 1697 1698 } 1699 1700 output.image = image.uuid; 1701 1702 } 1703 1704 if ( ! isRootObject ) { 1705 1706 meta.textures[ this.uuid ] = output; 1707 1708 } 1709 1710 return output; 1711 1712 }, 1713 1714 dispose: function () { 1715 1716 this.dispatchEvent( { type: 'dispose' } ); 1717 1718 }, 1719 1720 transformUv: function ( uv ) { 1721 1722 if ( this.mapping !== UVMapping ) return uv; 1723 1724 uv.applyMatrix3( this.matrix ); 1725 1726 if ( uv.x < 0 || uv.x > 1 ) { 1727 1728 switch ( this.wrapS ) { 1729 1730 case RepeatWrapping: 1731 1732 uv.x = uv.x - Math.floor( uv.x ); 1733 break; 1734
1735 case ClampToEdgeWrapping: 1736 1737 uv.x = uv.x < 0 ? 0 : 1; 1738 break; 1739 1740 case MirroredRepeatWrapping: 1741 1742 if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) { 1743 1744 uv.x = Math.ceil( uv.x ) - uv.x; 1745 1746 } else { 1747 1748 uv.x = uv.x - Math.floor( uv.x ); 1749 1750 } 1751 1752 break; 1753 1754 } 1755 1756 } 1757 1758 if ( uv.y < 0 || uv.y > 1 ) { 1759 1760 switch ( this.wrapT ) { 1761 1762 case RepeatWrapping: 1763 1764 uv.y = uv.y - Math.floor( uv.y ); 1765 break; 1766 1767 case ClampToEdgeWrapping: 1768 1769 uv.y = uv.y < 0 ? 0 : 1; 1770 break; 1771 1772 case MirroredRepeatWrapping: 1773 1774 if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) { 1775 1776 uv.y = Math.ceil( uv.y ) - uv.y; 1777 1778 } else { 1779 1780 uv.y = uv.y - Math.floor( uv.y ); 1781 1782 } 1783 1784 break; 1785 1786 } 1787 1788 } 1789 1790 if ( this.flipY ) { 1791 1792 uv.y = 1 - uv.y; 1793 1794 } 1795 1796 return uv; 1797 1798 } 1799 1800} ); 1801 1802Object.defineProperty( Texture.prototype, "needsUpdate", { 1803 1804 set: function ( value ) { 1805 1806 if ( value === true ) this.version ++; 1807 1808 } 1809 1810} ); 1811 1812/** 1813 * @author supereggbert / http://www.paulbrunt.co.uk/ 1814 * @author philogb / http://blog.thejit.org/ 1815 * @author mikael emtinger / http://gomo.se/ 1816 * @author egraether / http://egraether.com/ 1817 * @author WestLangley / http://github.com/WestLangley 1818 */ 1819 1820function Vector4( x, y, z, w ) { 1821 1822 this.x = x || 0; 1823 this.y = y || 0; 1824 this.z = z || 0; 1825 this.w = ( w !== undefined ) ? w : 1; 1826 1827} 1828 1829Object.defineProperties( Vector4.prototype, { 1830 1831 "width": { 1832 1833 get: function () { 1834 1835 return this.z; 1836 1837 }, 1838 1839 set: function ( value ) { 1840 1841 this.z = value; 1842 1843 } 1844 1845 }, 1846 1847 "height": { 1848 1849 get: function () { 1850 1851 return this.w; 1852 1853 }, 1854 1855 set: function ( value ) { 1856 1857 this.w = value; 1858 1859 } 1860 1861 } 1862 1863} ); 1864 1865Object.assign( Vector4.prototype, { 1866 1867 isVector4: true, 1868 1869 set: function ( x, y, z, w ) { 1870 1871 this.x = x; 1872 this.y = y; 1873 this.z = z; 1874 this.w = w; 1875 1876 return this; 1877 1878 }, 1879 1880 setScalar: function ( scalar ) { 1881 1882 this.x = scalar; 1883 this.y = scalar; 1884 this.z = scalar; 1885 this.w = scalar; 1886 1887 return this; 1888 1889 }, 1890 1891 setX: function ( x ) { 1892 1893 this.x = x; 1894 1895 return this; 1896 1897 }, 1898 1899 setY: function ( y ) { 1900 1901 this.y = y; 1902 1903 return this; 1904 1905 }, 1906 1907 setZ: function ( z ) { 1908 1909 this.z = z; 1910 1911 return this; 1912 1913 }, 1914 1915 setW: function ( w ) { 1916 1917 this.w = w; 1918 1919 return this; 1920 1921 }, 1922 1923 setComponent: function ( index, value ) { 1924 1925 switch ( index ) { 1926 1927 case 0: this.x = value; break; 1928 case 1: this.y = value; break; 1929 case 2: this.z = value; break; 1930 case 3: this.w = value; break; 1931 default: throw new Error( 'index is out of range: ' + index ); 1932 1933 } 1934 1935 return this; 1936 1937 }, 1938 1939 getComponent: function ( index ) { 1940 1941 switch ( index ) { 1942 1943 case 0: return this.x; 1944 case 1: return this.y; 1945 case 2: return this.z; 1946 case 3: return this.w; 1947 default: throw new Error( 'index is out of range: ' + index ); 1948 1949 } 1950 1951 }, 1952 1953 clone: function () { 1954 1955 return new this.constructor( this.x, this.y, this.z, this.w ); 1956 1957 }, 1958 1959 copy: function ( v ) { 1960 1961 this.x = v.x; 1962 this.y = v.y; 1963 this.z = v.z; 1964 this.w = ( v.w !== undefined ) ? v.w : 1; 1965 1966 return this; 1967 1968 }, 1969 1970 add: function ( v, w ) { 1971 1972 if ( w !== undefined ) { 1973 1974 console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); 1975 return this.addVectors( v, w ); 1976 1977 } 1978 1979 this.x += v.x; 1980 this.y += v.y; 1981 this.z += v.z; 1982 this.w += v.w; 1983 1984 return this; 1985 1986 }, 1987 1988 addScalar: function ( s ) { 1989 1990 this.x += s; 1991 this.y += s; 1992 this.z += s; 1993 this.w += s; 1994 1995 return this; 1996 1997 }, 1998 1999 addVectors: function ( a, b ) { 2000 2001 this.x = a.x + b.x; 2002 this.y = a.y + b.y; 2003 this.z = a.z + b.z; 2004 this.w = a.w + b.w; 2005 2006 return this; 2007 2008 }, 2009 2010 addScaledVector: function ( v, s ) { 2011 2012 this.x += v.x * s; 2013 this.y += v.y * s; 2014 this.z += v.z * s; 2015 this.w += v.w * s; 2016 2017 return this; 2018 2019 }, 2020 2021 sub: function ( v, w ) { 2022 2023 if ( w !== undefined ) { 2024 2025 console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); 2026 return this.subVectors( v, w ); 2027 2028 } 2029 2030 this.x -= v.x; 2031 this.y -= v.y; 2032 this.z -= v.z; 2033 this.w -= v.w; 2034 2035 return this; 2036 2037 }, 2038 2039 subScalar: function ( s ) { 2040 2041 this.x -= s; 2042 this.y -= s; 2043 this.z -= s; 2044 this.w -= s; 2045 2046 return this; 2047 2048 }, 2049 2050 subVectors: function ( a, b ) { 2051 2052 this.x = a.x - b.x; 2053 this.y = a.y - b.y; 2054 this.z = a.z - b.z; 2055 this.w = a.w - b.w; 2056 2057 return this; 2058 2059 }, 2060 2061 multiplyScalar: function ( scalar ) { 2062 2063 this.x *= scalar; 2064 this.y *= scalar; 2065 this.z *= scalar; 2066 this.w *= scalar; 2067 2068 return this; 2069 2070 }, 2071 2072 applyMatrix4: function ( m ) { 2073 2074 var x = this.x, y = this.y, z = this.z, w = this.w; 2075 var e = m.elements; 2076 2077 this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w; 2078 this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w; 2079 this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w; 2080 this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w; 2081 2082 return this; 2083 2084 }, 2085 2086 divideScalar: function ( scalar ) { 2087 2088 return this.multiplyScalar( 1 / scalar ); 2089 2090 }, 2091 2092 setAxisAngleFromQuaternion: function ( q ) { 2093 2094 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm 2095 2096 // q is assumed to be normalized 2097 2098 this.w = 2 * Math.acos( q.w ); 2099
2100 var s = Math.sqrt( 1 - q.w * q.w ); 2101 2102 if ( s < 0.0001 ) { 2103 2104 this.x = 1; 2105 this.y = 0; 2106 this.z = 0; 2107 2108 } else { 2109 2110 this.x = q.x / s; 2111 this.y = q.y / s; 2112 this.z = q.z / s; 2113 2114 } 2115 2116 return this; 2117 2118 }, 2119 2120 setAxisAngleFromRotationMatrix: function ( m ) { 2121 2122 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm 2123 2124 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) 2125 2126 var angle, x, y, z, // variables for result 2127 epsilon = 0.01, // margin to allow for rounding errors 2128 epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees 2129 2130 te = m.elements, 2131 2132 m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], 2133 m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], 2134 m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; 2135 2136 if ( ( Math.abs( m12 - m21 ) < epsilon ) && 2137 ( Math.abs( m13 - m31 ) < epsilon ) && 2138 ( Math.abs( m23 - m32 ) < epsilon ) ) { 2139 2140 // singularity found 2141 // first check for identity matrix which must have +1 for all terms 2142 // in leading diagonal and zero in other terms 2143 2144 if ( ( Math.abs( m12 + m21 ) < epsilon2 ) && 2145 ( Math.abs( m13 + m31 ) < epsilon2 ) && 2146 ( Math.abs( m23 + m32 ) < epsilon2 ) && 2147 ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) { 2148 2149 // this singularity is identity matrix so angle = 0 2150 2151 this.set( 1, 0, 0, 0 ); 2152 2153 return this; // zero angle, arbitrary axis 2154 2155 } 2156 2157 // otherwise this singularity is angle = 180 2158 2159 angle = Math.PI; 2160 2161 var xx = ( m11 + 1 ) / 2; 2162 var yy = ( m22 + 1 ) / 2; 2163 var zz = ( m33 + 1 ) / 2; 2164 var xy = ( m12 + m21 ) / 4; 2165 var xz = ( m13 + m31 ) / 4; 2166 var yz = ( m23 + m32 ) / 4; 2167 2168 if ( ( xx > yy ) && ( xx > zz ) ) { 2169 2170 // m11 is the largest diagonal term 2171 2172 if ( xx < epsilon ) { 2173 2174 x = 0; 2175 y = 0.707106781; 2176 z = 0.707106781; 2177 2178 } else { 2179 2180 x = Math.sqrt( xx ); 2181 y = xy / x; 2182 z = xz / x; 2183 2184 } 2185 2186 } else if ( yy > zz ) { 2187 2188 // m22 is the largest diagonal term 2189 2190 if ( yy < epsilon ) { 2191 2192 x = 0.707106781; 2193 y = 0; 2194 z = 0.707106781; 2195 2196 } else { 2197 2198 y = Math.sqrt( yy ); 2199 x = xy / y; 2200 z = yz / y; 2201 2202 } 2203 2204 } else { 2205 2206 // m33 is the largest diagonal term so base result on this 2207 2208 if ( zz < epsilon ) { 2209 2210 x = 0.707106781; 2211 y = 0.707106781; 2212 z = 0; 2213 2214 } else { 2215 2216 z = Math.sqrt( zz ); 2217 x = xz / z; 2218 y = yz / z; 2219 2220 } 2221 2222 } 2223 2224 this.set( x, y, z, angle ); 2225 2226 return this; // return 180 deg rotation 2227 2228 } 2229 2230 // as we have reached here there are no singularities so we can handle normally 2231 2232 var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) + 2233 ( m13 - m31 ) * ( m13 - m31 ) + 2234 ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize 2235 2236 if ( Math.abs( s ) < 0.001 ) s = 1; 2237 2238 // prevent divide by zero, should not happen if matrix is orthogonal and should be 2239 // caught by singularity test above, but I've left it in just in case 2240 2241 this.x = ( m32 - m23 ) / s; 2242 this.y = ( m13 - m31 ) / s; 2243 this.z = ( m21 - m12 ) / s; 2244 this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 ); 2245 2246 return this; 2247 2248 }, 2249 2250 min: function ( v ) { 2251 2252 this.x = Math.min( this.x, v.x ); 2253 this.y = Math.min( this.y, v.y ); 2254 this.z = Math.min( this.z, v.z ); 2255 this.w = Math.min( this.w, v.w ); 2256 2257 return this; 2258 2259 }, 2260 2261 max: function ( v ) { 2262 2263 this.x = Math.max( this.x, v.x ); 2264 this.y = Math.max( this.y, v.y ); 2265 this.z = Math.max( this.z, v.z ); 2266 this.w = Math.max( this.w, v.w ); 2267 2268 return this; 2269 2270 }, 2271 2272 clamp: function ( min, max ) { 2273 2274 // assumes min < max, componentwise 2275 2276 this.x = Math.max( min.x, Math.min( max.x, this.x ) ); 2277 this.y = Math.max( min.y, Math.min( max.y, this.y ) ); 2278 this.z = Math.max( min.z, Math.min( max.z, this.z ) ); 2279 this.w = Math.max( min.w, Math.min( max.w, this.w ) ); 2280 2281 return this; 2282 2283 }, 2284 2285 clampScalar: function ( minVal, maxVal ) { 2286 2287 this.x = Math.max( minVal, Math.min( maxVal, this.x ) ); 2288 this.y = Math.max( minVal, Math.min( maxVal, this.y ) ); 2289 this.z = Math.max( minVal, Math.min( maxVal, this.z ) ); 2290 this.w = Math.max( minVal, Math.min( maxVal, this.w ) ); 2291 2292 return this; 2293 2294 }, 2295 2296 clampLength: function ( min, max ) { 2297 2298 var length = this.length(); 2299 2300 return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); 2301 2302 }, 2303 2304 floor: function () { 2305 2306 this.x = Math.floor( this.x ); 2307 this.y = Math.floor( this.y ); 2308 this.z = Math.floor( this.z ); 2309 this.w = Math.floor( this.w ); 2310 2311 return this; 2312 2313 }, 2314 2315 ceil: function () { 2316 2317 this.x = Math.ceil( this.x ); 2318 this.y = Math.ceil( this.y );
2319 this.z = Math.ceil( this.z ); 2320 this.w = Math.ceil( this.w ); 2321 2322 return this; 2323 2324 }, 2325 2326 round: function () { 2327 2328 this.x = Math.round( this.x ); 2329 this.y = Math.round( this.y ); 2330 this.z = Math.round( this.z ); 2331 this.w = Math.round( this.w ); 2332 2333 return this; 2334 2335 }, 2336 2337 roundToZero: function () { 2338 2339 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); 2340 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); 2341 this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); 2342 this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); 2343 2344 return this; 2345 2346 }, 2347 2348 negate: function () { 2349 2350 this.x = - this.x; 2351 this.y = - this.y; 2352 this.z = - this.z; 2353 this.w = - this.w; 2354 2355 return this; 2356 2357 }, 2358 2359 dot: function ( v ) { 2360 2361 return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; 2362 2363 }, 2364 2365 lengthSq: function () { 2366 2367 return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; 2368 2369 }, 2370 2371 length: function () { 2372 2373 return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); 2374 2375 }, 2376 2377 manhattanLength: function () { 2378 2379 return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w ); 2380 2381 }, 2382 2383 normalize: function () { 2384 2385 return this.divideScalar( this.length() || 1 ); 2386 2387 }, 2388 2389 setLength: function ( length ) { 2390 2391 return this.normalize().multiplyScalar( length ); 2392 2393 }, 2394 2395 lerp: function ( v, alpha ) { 2396 2397 this.x += ( v.x - this.x ) * alpha; 2398 this.y += ( v.y - this.y ) * alpha; 2399 this.z += ( v.z - this.z ) * alpha; 2400 this.w += ( v.w - this.w ) * alpha; 2401 2402 return this; 2403 2404 }, 2405 2406 lerpVectors: function ( v1, v2, alpha ) { 2407 2408 return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); 2409 2410 }, 2411 2412 equals: function ( v ) { 2413 2414 return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) ); 2415 2416 }, 2417 2418 fromArray: function ( array, offset ) { 2419 2420 if ( offset === undefined ) offset = 0; 2421 2422 this.x = array[ offset ]; 2423 this.y = array[ offset + 1 ]; 2424 this.z = array[ offset + 2 ]; 2425 this.w = array[ offset + 3 ]; 2426 2427 return this; 2428 2429 }, 2430 2431 toArray: function ( array, offset ) { 2432 2433 if ( array === undefined ) array = []; 2434 if ( offset === undefined ) offset = 0; 2435 2436 array[ offset ] = this.x; 2437 array[ offset + 1 ] = this.y; 2438 array[ offset + 2 ] = this.z; 2439 array[ offset + 3 ] = this.w; 2440 2441 return array; 2442 2443 }, 2444 2445 fromBufferAttribute: function ( attribute, index, offset ) { 2446 2447 if ( offset !== undefined ) { 2448 2449 console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' ); 2450 2451 } 2452 2453 this.x = attribute.getX( index ); 2454 this.y = attribute.getY( index ); 2455 this.z = attribute.getZ( index ); 2456 this.w = attribute.getW( index ); 2457 2458 return this; 2459 2460 }, 2461 2462 random: function () { 2463 2464 this.x = Math.random(); 2465 this.y = Math.random(); 2466 this.z = Math.random(); 2467 this.w = Math.random(); 2468 2469 return this; 2470 2471 } 2472 2473} ); 2474 2475/** 2476 * @author szimek / https://github.com/szimek/ 2477 * @author alteredq / http://alteredqualia.com/ 2478 * @author Marius Kintel / https://github.com/kintel 2479 */ 2480 2481/* 2482 In options, we can specify: 2483 * Texture parameters for an auto-generated target texture 2484 * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers 2485*/ 2486function WebGLRenderTarget( width, height, options ) { 2487 2488 this.width = width; 2489 this.height = height; 2490 2491 this.scissor = new Vector4( 0, 0, width, height ); 2492 this.scissorTest = false; 2493 2494 this.viewport = new Vector4( 0, 0, width, height ); 2495 2496 options = options || {}; 2497 2498 this.texture = new Texture( undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding ); 2499 2500 this.texture.image = {}; 2501 this.texture.image.width = width; 2502 this.texture.image.height = height; 2503 2504 this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; 2505 this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; 2506 2507 this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; 2508 this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true; 2509 this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null; 2510 2511} 2512
2513WebGLRenderTarget.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { 2514 2515 constructor: WebGLRenderTarget, 2516 2517 isWebGLRenderTarget: true, 2518 2519 setSize: function ( width, height ) { 2520 2521 if ( this.width !== width || this.height !== height ) { 2522 2523 this.width = width; 2524 this.height = height; 2525 2526 this.texture.image.width = width; 2527 this.texture.image.height = height; 2528 2529 this.dispose(); 2530 2531 } 2532 2533 this.viewport.set( 0, 0, width, height ); 2534 this.scissor.set( 0, 0, width, height ); 2535 2536 }, 2537 2538 clone: function () { 2539 2540 return new this.constructor().copy( this ); 2541 2542 }, 2543 2544 copy: function ( source ) { 2545 2546 this.width = source.width; 2547 this.height = source.height; 2548 2549 this.viewport.copy( source.viewport ); 2550 2551 this.texture = source.texture.clone(); 2552 2553 this.depthBuffer = source.depthBuffer; 2554 this.stencilBuffer = source.stencilBuffer; 2555 this.depthTexture = source.depthTexture; 2556 2557 return this; 2558 2559 }, 2560 2561 dispose: function () { 2562 2563 this.dispatchEvent( { type: 'dispose' } ); 2564 2565 } 2566 2567} ); 2568 2569/** 2570 * @author Mugen87 / https://github.com/Mugen87 2571 * @author Matt DesLauriers / @mattdesl 2572 */ 2573 2574function WebGLMultisampleRenderTarget( width, height, options ) { 2575 2576 WebGLRenderTarget.call( this, width, height, options ); 2577 2578 this.samples = 4; 2579 2580} 2581 2582WebGLMultisampleRenderTarget.prototype = Object.assign( Object.create( WebGLRenderTarget.prototype ), { 2583 2584 constructor: WebGLMultisampleRenderTarget, 2585 2586 isWebGLMultisampleRenderTarget: true, 2587 2588 copy: function ( source ) { 2589 2590 WebGLRenderTarget.prototype.copy.call( this, source ); 2591 2592 this.samples = source.samples; 2593 2594 return this; 2595 2596 } 2597 2598} ); 2599 2600/** 2601 * @author mikael emtinger / http://gomo.se/ 2602 * @author alteredq / http://alteredqualia.com/ 2603 * @author WestLangley / http://github.com/WestLangley 2604 * @author bhouston / http://clara.io 2605 */ 2606 2607function Quaternion( x, y, z, w ) { 2608 2609 this._x = x || 0; 2610 this._y = y || 0; 2611 this._z = z || 0; 2612 this._w = ( w !== undefined ) ? w : 1; 2613 2614} 2615 2616Object.assign( Quaternion, { 2617 2618 slerp: function ( qa, qb, qm, t ) { 2619 2620 return qm.copy( qa ).slerp( qb, t ); 2621 2622 }, 2623 2624 slerpFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) { 2625 2626 // fuzz-free, array-based Quaternion SLERP operation 2627 2628 var x0 = src0[ srcOffset0 + 0 ], 2629 y0 = src0[ srcOffset0 + 1 ], 2630 z0 = src0[ srcOffset0 + 2 ], 2631 w0 = src0[ srcOffset0 + 3 ], 2632 2633 x1 = src1[ srcOffset1 + 0 ], 2634 y1 = src1[ srcOffset1 + 1 ], 2635 z1 = src1[ srcOffset1 + 2 ], 2636 w1 = src1[ srcOffset1 + 3 ]; 2637 2638 if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) { 2639 2640 var s = 1 - t, 2641 2642 cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, 2643 2644 dir = ( cos >= 0 ? 1 : - 1 ), 2645 sqrSin = 1 - cos * cos; 2646 2647 // Skip the Slerp for tiny steps to avoid numeric problems: 2648 if ( sqrSin > Number.EPSILON ) { 2649 2650 var sin = Math.sqrt( sqrSin ), 2651 len = Math.atan2( sin, cos * dir ); 2652 2653 s = Math.sin( s * len ) / sin; 2654 t = Math.sin( t * len ) / sin; 2655 2656 } 2657 2658 var tDir = t * dir; 2659 2660 x0 = x0 * s + x1 * tDir; 2661 y0 = y0 * s + y1 * tDir; 2662 z0 = z0 * s + z1 * tDir; 2663 w0 = w0 * s + w1 * tDir; 2664 2665 // Normalize in case we just did a lerp: 2666 if ( s === 1 - t ) { 2667 2668 var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 ); 2669 2670 x0 *= f; 2671 y0 *= f; 2672 z0 *= f; 2673 w0 *= f; 2674 2675 } 2676 2677 } 2678 2679 dst[ dstOffset ] = x0; 2680 dst[ dstOffset + 1 ] = y0; 2681 dst[ dstOffset + 2 ] = z0; 2682 dst[ dstOffset + 3 ] = w0; 2683 2684 }, 2685 2686 multiplyQuaternionsFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1 ) { 2687 2688 var x0 = src0[ srcOffset0 ]; 2689 var y0 = src0[ srcOffset0 + 1 ]; 2690 var z0 = src0[ srcOffset0 + 2 ]; 2691 var w0 = src0[ srcOffset0 + 3 ]; 2692 2693 var x1 = src1[ srcOffset1 ]; 2694 var y1 = src1[ srcOffset1 + 1 ]; 2695 var z1 = src1[ srcOffset1 + 2 ]; 2696 var w1 = src1[ srcOffset1 + 3 ]; 2697 2698 dst[ dstOffset ] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1; 2699 dst[ dstOffset + 1 ] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1; 2700 dst[ dstOffset + 2 ] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1; 2701 dst[ dstOffset + 3 ] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1; 2702 2703 return dst; 2704 2705 } 2706 2707} ); 2708 2709Object.defineProperties( Quaternion.prototype, { 2710 2711 x: { 2712 2713 get: function () { 2714 2715 return this._x; 2716 2717 }, 2718 2719 set: function ( value ) { 2720 2721 this._x = value; 2722 this._onChangeCallback(); 2723 2724 } 2725 2726 }, 2727 2728 y: { 2729 2730 get: function () { 2731 2732 return this._y; 2733 2734 }, 2735 2736 set: function ( value ) { 2737 2738 this._y = value; 2739 this._onChangeCallback(); 2740 2741 } 2742 2743 }, 2744
vendor: 14,380 bytes, lines 2745-3560
2745 z: { 2746 2747 get: function () { 2748 2749 return this._z; 2750 2751 }, 2752 2753 set: function ( value ) { 2754 2755 this._z = value; 2756 this._onChangeCallback(); 2757 2758 } 2759 2760 }, 2761 2762 w: { 2763 2764 get: function () { 2765 2766 return this._w; 2767 2768 }, 2769 2770 set: function ( value ) { 2771 2772 this._w = value; 2773 this._onChangeCallback(); 2774 2775 } 2776 2777 } 2778 2779} ); 2780 2781Object.assign( Quaternion.prototype, { 2782 2783 isQuaternion: true, 2784 2785 set: function ( x, y, z, w ) { 2786 2787 this._x = x; 2788 this._y = y; 2789 this._z = z; 2790 this._w = w; 2791 2792 this._onChangeCallback(); 2793 2794 return this; 2795 2796 }, 2797 2798 clone: function () { 2799 2800 return new this.constructor( this._x, this._y, this._z, this._w ); 2801 2802 }, 2803 2804 copy: function ( quaternion ) { 2805 2806 this._x = quaternion.x; 2807 this._y = quaternion.y; 2808 this._z = quaternion.z; 2809 this._w = quaternion.w; 2810 2811 this._onChangeCallback(); 2812 2813 return this; 2814 2815 }, 2816 2817 setFromEuler: function ( euler, update ) { 2818 2819 if ( ! ( euler && euler.isEuler ) ) { 2820 2821 throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' ); 2822 2823 } 2824 2825 var x = euler._x, y = euler._y, z = euler._z, order = euler.order; 2826 2827 // http://www.mathworks.com/matlabcentral/fileexchange/ 2828 // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ 2829 // content/SpinCalc.m 2830 2831 var cos = Math.cos; 2832 var sin = Math.sin; 2833 2834 var c1 = cos( x / 2 ); 2835 var c2 = cos( y / 2 ); 2836 var c3 = cos( z / 2 ); 2837 2838 var s1 = sin( x / 2 ); 2839 var s2 = sin( y / 2 ); 2840 var s3 = sin( z / 2 ); 2841 2842 switch ( order ) { 2843 2844 case 'XYZ': 2845 this._x = s1 * c2 * c3 + c1 * s2 * s3; 2846 this._y = c1 * s2 * c3 - s1 * c2 * s3; 2847 this._z = c1 * c2 * s3 + s1 * s2 * c3; 2848 this._w = c1 * c2 * c3 - s1 * s2 * s3; 2849 break; 2850 2851 case 'YXZ': 2852 this._x = s1 * c2 * c3 + c1 * s2 * s3; 2853 this._y = c1 * s2 * c3 - s1 * c2 * s3; 2854 this._z = c1 * c2 * s3 - s1 * s2 * c3; 2855 this._w = c1 * c2 * c3 + s1 * s2 * s3; 2856 break; 2857 2858 case 'ZXY': 2859 this._x = s1 * c2 * c3 - c1 * s2 * s3; 2860 this._y = c1 * s2 * c3 + s1 * c2 * s3; 2861 this._z = c1 * c2 * s3 + s1 * s2 * c3; 2862 this._w = c1 * c2 * c3 - s1 * s2 * s3; 2863 break; 2864 2865 case 'ZYX': 2866 this._x = s1 * c2 * c3 - c1 * s2 * s3; 2867 this._y = c1 * s2 * c3 + s1 * c2 * s3; 2868 this._z = c1 * c2 * s3 - s1 * s2 * c3; 2869 this._w = c1 * c2 * c3 + s1 * s2 * s3; 2870 break; 2871 2872 case 'YZX': 2873 this._x = s1 * c2 * c3 + c1 * s2 * s3; 2874 this._y = c1 * s2 * c3 + s1 * c2 * s3; 2875 this._z = c1 * c2 * s3 - s1 * s2 * c3; 2876 this._w = c1 * c2 * c3 - s1 * s2 * s3; 2877 break; 2878 2879 case 'XZY': 2880 this._x = s1 * c2 * c3 - c1 * s2 * s3; 2881 this._y = c1 * s2 * c3 - s1 * c2 * s3; 2882 this._z = c1 * c2 * s3 + s1 * s2 * c3; 2883 this._w = c1 * c2 * c3 + s1 * s2 * s3; 2884 break; 2885 2886 default: 2887 console.warn( 'THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order ); 2888 2889 } 2890 2891 if ( update !== false ) this._onChangeCallback(); 2892 2893 return this; 2894 2895 }, 2896 2897 setFromAxisAngle: function ( axis, angle ) { 2898 2899 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm 2900 2901 // assumes axis is normalized 2902 2903 var halfAngle = angle / 2, s = Math.sin( halfAngle ); 2904 2905 this._x = axis.x * s; 2906 this._y = axis.y * s; 2907 this._z = axis.z * s; 2908 this._w = Math.cos( halfAngle ); 2909 2910 this._onChangeCallback(); 2911 2912 return this; 2913 2914 }, 2915 2916 setFromRotationMatrix: function ( m ) { 2917 2918 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm 2919 2920 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) 2921 2922 var te = m.elements, 2923 2924 m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], 2925 m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], 2926 m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ], 2927 2928 trace = m11 + m22 + m33, 2929 s; 2930 2931 if ( trace > 0 ) { 2932 2933 s = 0.5 / Math.sqrt( trace + 1.0 ); 2934 2935 this._w = 0.25 / s; 2936 this._x = ( m32 - m23 ) * s; 2937 this._y = ( m13 - m31 ) * s; 2938 this._z = ( m21 - m12 ) * s; 2939 2940 } else if ( m11 > m22 && m11 > m33 ) { 2941 2942 s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 ); 2943 2944 this._w = ( m32 - m23 ) / s; 2945 this._x = 0.25 * s; 2946 this._y = ( m12 + m21 ) / s; 2947 this._z = ( m13 + m31 ) / s; 2948 2949 } else if ( m22 > m33 ) { 2950 2951 s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 ); 2952 2953 this._w = ( m13 - m31 ) / s; 2954 this._x = ( m12 + m21 ) / s; 2955 this._y = 0.25 * s; 2956 this._z = ( m23 + m32 ) / s; 2957 2958 } else { 2959 2960 s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 ); 2961 2962 this._w = ( m21 - m12 ) / s; 2963 this._x = ( m13 + m31 ) / s; 2964 this._y = ( m23 + m32 ) / s; 2965 this._z = 0.25 * s; 2966 2967 } 2968 2969 this._onChangeCallback(); 2970 2971 return this; 2972 2973 }, 2974 2975 setFromUnitVectors: function ( vFrom, vTo ) { 2976 2977 // assumes direction vectors vFrom and vTo are normalized 2978 2979 var EPS = 0.000001; 2980 2981 var r = vFrom.dot( vTo ) + 1; 2982 2983 if ( r < EPS ) { 2984 2985 r = 0; 2986 2987 if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) { 2988 2989 this._x = - vFrom.y; 2990 this._y = vFrom.x; 2991 this._z = 0; 2992 this._w = r; 2993 2994 } else { 2995 2996 this._x = 0; 2997 this._y = - vFrom.z; 2998 this._z = vFrom.y; 2999 this._w = r; 3000 3001 } 3002 3003 } else { 3004 3005 // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3 3006 3007 this._x = vFrom.y * vTo.z - vFrom.z * vTo.y; 3008 this._y = vFrom.z * vTo.x - vFrom.x * vTo.z; 3009 this._z = vFrom.x * vTo.y - vFrom.y * vTo.x; 3010 this._w = r; 3011 3012 } 3013 3014 return this.normalize(); 3015 3016 }, 3017 3018 angleTo: function ( q ) { 3019 3020 return 2 * Math.acos( Math.abs( MathUtils.clamp( this.dot( q ), - 1, 1 ) ) ); 3021 3022 }, 3023 3024 rotateTowards: function ( q, step ) { 3025 3026 var angle = this.angleTo( q ); 3027 3028 if ( angle === 0 ) return this; 3029 3030 var t = Math.min( 1, step / angle ); 3031 3032 this.slerp( q, t ); 3033 3034 return this; 3035 3036 }, 3037 3038 inverse: function () { 3039 3040 // quaternion is assumed to have unit length 3041 3042 return this.conjugate(); 3043 3044 }, 3045 3046 conjugate: function () { 3047 3048 this._x *= - 1; 3049 this._y *= - 1; 3050 this._z *= - 1; 3051 3052 this._onChangeCallback(); 3053 3054 return this; 3055 3056 }, 3057 3058 dot: function ( v ) { 3059 3060 return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; 3061 3062 }, 3063 3064 lengthSq: function () { 3065 3066 return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; 3067 3068 }, 3069 3070 length: function () { 3071 3072 return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w ); 3073 3074 }, 3075 3076 normalize: function () { 3077 3078 var l = this.length(); 3079 3080 if ( l === 0 ) { 3081 3082 this._x = 0; 3083 this._y = 0; 3084 this._z = 0; 3085 this._w = 1; 3086 3087 } else { 3088 3089 l = 1 / l; 3090 3091 this._x = this._x * l; 3092 this._y = this._y * l; 3093 this._z = this._z * l; 3094 this._w = this._w * l; 3095 3096 } 3097 3098 this._onChangeCallback(); 3099 3100 return this; 3101 3102 }, 3103 3104 multiply: function ( q, p ) { 3105 3106 if ( p !== undefined ) { 3107 3108 console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); 3109 return this.multiplyQuaternions( q, p ); 3110 3111 } 3112 3113 return this.multiplyQuaternions( this, q ); 3114 3115 }, 3116 3117 premultiply: function ( q ) { 3118 3119 return this.multiplyQuaternions( q, this ); 3120 3121 }, 3122 3123 multiplyQuaternions: function ( a, b ) { 3124 3125 // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm 3126 3127 var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w; 3128 var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; 3129 3130 this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; 3131 this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; 3132 this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; 3133 this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; 3134 3135 this._onChangeCallback(); 3136 3137 return this; 3138 3139 }, 3140 3141 slerp: function ( qb, t ) { 3142 3143 if ( t === 0 ) return this; 3144 if ( t === 1 ) return this.copy( qb ); 3145 3146 var x = this._x, y = this._y, z = this._z, w = this._w; 3147 3148 // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ 3149 3150 var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; 3151 3152 if ( cosHalfTheta < 0 ) { 3153 3154 this._w = - qb._w; 3155 this._x = - qb._x; 3156 this._y = - qb._y; 3157 this._z = - qb._z; 3158 3159 cosHalfTheta = - cosHalfTheta; 3160 3161 } else { 3162 3163 this.copy( qb ); 3164 3165 } 3166 3167 if ( cosHalfTheta >= 1.0 ) { 3168 3169 this._w = w; 3170 this._x = x; 3171 this._y = y; 3172 this._z = z; 3173 3174 return this; 3175 3176 } 3177 3178 var sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta; 3179 3180 if ( sqrSinHalfTheta <= Number.EPSILON ) { 3181 3182 var s = 1 - t; 3183 this._w = s * w + t * this._w; 3184 this._x = s * x + t * this._x; 3185 this._y = s * y + t * this._y; 3186 this._z = s * z + t * this._z; 3187 3188 this.normalize(); 3189 this._onChangeCallback(); 3190 3191 return this; 3192 3193 } 3194 3195 var sinHalfTheta = Math.sqrt( sqrSinHalfTheta ); 3196 var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta ); 3197 var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta, 3198 ratioB = Math.sin( t * halfTheta ) / sinHalfTheta; 3199 3200 this._w = ( w * ratioA + this._w * ratioB ); 3201 this._x = ( x * ratioA + this._x * ratioB ); 3202 this._y = ( y * ratioA + this._y * ratioB ); 3203 this._z = ( z * ratioA + this._z * ratioB ); 3204 3205 this._onChangeCallback(); 3206 3207 return this; 3208 3209 }, 3210 3211 equals: function ( quaternion ) { 3212 3213 return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w ); 3214 3215 }, 3216 3217 fromArray: function ( array, offset ) { 3218 3219 if ( offset === undefined ) offset = 0; 3220 3221 this._x = array[ offset ]; 3222 this._y = array[ offset + 1 ]; 3223 this._z = array[ offset + 2 ]; 3224 this._w = array[ offset + 3 ]; 3225 3226 this._onChangeCallback(); 3227 3228 return this; 3229 3230 }, 3231 3232 toArray: function ( array, offset ) { 3233 3234 if ( array === undefined ) array = []; 3235 if ( offset === undefined ) offset = 0; 3236 3237 array[ offset ] = this._x; 3238 array[ offset + 1 ] = this._y; 3239 array[ offset + 2 ] = this._z; 3240 array[ offset + 3 ] = this._w; 3241 3242 return array; 3243 3244 }, 3245 3246 fromBufferAttribute: function ( attribute, index ) { 3247 3248 this._x = attribute.getX( index ); 3249 this._y = attribute.getY( index ); 3250 this._z = attribute.getZ( index ); 3251 this._w = attribute.getW( index ); 3252 3253 return this; 3254 3255 }, 3256 3257 _onChange: function ( callback ) { 3258 3259 this._onChangeCallback = callback; 3260 3261 return this; 3262 3263 }, 3264 3265 _onChangeCallback: function () {} 3266 3267} ); 3268 3269/** 3270 * @author mrdoob / http://mrdoob.com/ 3271 * @author kile / http://kile.stravaganza.org/ 3272 * @author philogb / http://blog.thejit.org/ 3273 * @author mikael emtinger / http://gomo.se/ 3274 * @author egraether / http://egraether.com/ 3275 * @author WestLangley / http://github.com/WestLangley 3276 */ 3277 3278var _vector = new Vector3(); 3279var _quaternion = new Quaternion(); 3280 3281function Vector3( x, y, z ) { 3282 3283 this.x = x || 0; 3284 this.y = y || 0; 3285 this.z = z || 0; 3286 3287} 3288 3289Object.assign( Vector3.prototype, { 3290 3291 isVector3: true, 3292 3293 set: function ( x, y, z ) { 3294 3295 this.x = x; 3296 this.y = y; 3297 this.z = z; 3298 3299 return this; 3300 3301 }, 3302 3303 setScalar: function ( scalar ) { 3304 3305 this.x = scalar; 3306 this.y = scalar; 3307 this.z = scalar; 3308 3309 return this; 3310 3311 }, 3312 3313 setX: function ( x ) { 3314 3315 this.x = x; 3316 3317 return this; 3318 3319 }, 3320 3321 setY: function ( y ) { 3322 3323 this.y = y; 3324 3325 return this; 3326 3327 }, 3328 3329 setZ: function ( z ) { 3330 3331 this.z = z; 3332 3333 return this; 3334 3335 }, 3336 3337 setComponent: function ( index, value ) { 3338 3339 switch ( index ) { 3340 3341 case 0: this.x = value; break; 3342 case 1: this.y = value; break; 3343 case 2: this.z = value; break; 3344 default: throw new Error( 'index is out of range: ' + index ); 3345 3346 } 3347 3348 return this; 3349 3350 }, 3351 3352 getComponent: function ( index ) { 3353 3354 switch ( index ) { 3355 3356 case 0: return this.x; 3357 case 1: return this.y; 3358 case 2: return this.z; 3359 default: throw new Error( 'index is out of range: ' + index ); 3360 3361 } 3362 3363 }, 3364 3365 clone: function () { 3366 3367 return new this.constructor( this.x, this.y, this.z ); 3368 3369 }, 3370 3371 copy: function ( v ) { 3372 3373 this.x = v.x; 3374 this.y = v.y; 3375 this.z = v.z; 3376 3377 return this; 3378 3379 }, 3380 3381 add: function ( v, w ) { 3382 3383 if ( w !== undefined ) { 3384 3385 console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); 3386 return this.addVectors( v, w ); 3387 3388 } 3389 3390 this.x += v.x; 3391 this.y += v.y; 3392 this.z += v.z; 3393 3394 return this; 3395 3396 }, 3397 3398 addScalar: function ( s ) { 3399 3400 this.x += s; 3401 this.y += s; 3402 this.z += s; 3403 3404 return this; 3405 3406 }, 3407 3408 addVectors: function ( a, b ) { 3409 3410 this.x = a.x + b.x; 3411 this.y = a.y + b.y; 3412 this.z = a.z + b.z; 3413 3414 return this; 3415 3416 }, 3417 3418 addScaledVector: function ( v, s ) { 3419 3420 this.x += v.x * s; 3421 this.y += v.y * s; 3422 this.z += v.z * s; 3423 3424 return this; 3425 3426 }, 3427 3428 sub: function ( v, w ) { 3429 3430 if ( w !== undefined ) { 3431 3432 console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); 3433 return this.subVectors( v, w ); 3434 3435 } 3436 3437 this.x -= v.x; 3438 this.y -= v.y; 3439 this.z -= v.z; 3440 3441 return this; 3442 3443 }, 3444 3445 subScalar: function ( s ) { 3446 3447 this.x -= s; 3448 this.y -= s; 3449 this.z -= s; 3450 3451 return this; 3452 3453 }, 3454 3455 subVectors: function ( a, b ) { 3456 3457 this.x = a.x - b.x; 3458 this.y = a.y - b.y; 3459 this.z = a.z - b.z; 3460 3461 return this; 3462 3463 }, 3464 3465 multiply: function ( v, w ) { 3466 3467 if ( w !== undefined ) { 3468 3469 console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); 3470 return this.multiplyVectors( v, w ); 3471 3472 } 3473 3474 this.x *= v.x; 3475 this.y *= v.y; 3476 this.z *= v.z; 3477 3478 return this; 3479 3480 }, 3481 3482 multiplyScalar: function ( scalar ) { 3483 3484 this.x *= scalar; 3485 this.y *= scalar; 3486 this.z *= scalar; 3487 3488 return this; 3489 3490 }, 3491 3492 multiplyVectors: function ( a, b ) { 3493 3494 this.x = a.x * b.x; 3495 this.y = a.y * b.y; 3496 this.z = a.z * b.z; 3497 3498 return this; 3499 3500 }, 3501 3502 applyEuler: function ( euler ) { 3503 3504 if ( ! ( euler && euler.isEuler ) ) { 3505 3506 console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' ); 3507 3508 } 3509 3510 return this.applyQuaternion( _quaternion.setFromEuler( euler ) ); 3511 3512 }, 3513 3514 applyAxisAngle: function ( axis, angle ) { 3515 3516 return this.applyQuaternion( _quaternion.setFromAxisAngle( axis, angle ) ); 3517 3518 }, 3519 3520 applyMatrix3: function ( m ) { 3521 3522 var x = this.x, y = this.y, z = this.z; 3523 var e = m.elements; 3524 3525 this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z; 3526 this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z; 3527 this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z; 3528 3529 return this; 3530 3531 }, 3532 3533 applyNormalMatrix: function ( m ) { 3534 3535 return this.applyMatrix3( m ).normalize(); 3536 3537 }, 3538 3539 applyMatrix4: function ( m ) { 3540 3541 var x = this.x, y = this.y, z = this.z; 3542 var e = m.elements; 3543 3544 var w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); 3545 3546 this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w; 3547 this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w; 3548 this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w; 3549 3550 return this; 3551 3552 }, 3553 3554 applyQuaternion: function ( q ) { 3555 3556 var x = this.x, y = this.y, z = this.z; 3557 var qx = q.x, qy = q.y, qz = q.z, qw = q.w; 3558 3559 // calculate quat * vector 3560
3561 var ix = qw * x + qy * z - qz * y; 3562 var iy = qw * y + qz * x - qx * z; 3563 var iz = qw * z + qx * y - qy * x; 3564 var iw = - qx * x - qy * y - qz * z; 3565 3566 // calculate result * inverse quat 3567 3568 this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy; 3569 this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz; 3570 this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx; 3571 3572 return this; 3573 3574 }, 3575 3576 project: function ( camera ) { 3577 3578 return this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix ); 3579 3580 }, 3581 3582 unproject: function ( camera ) { 3583 3584 return this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld ); 3585 3586 }, 3587 3588 transformDirection: function ( m ) { 3589 3590 // input: THREE.Matrix4 affine matrix 3591 // vector interpreted as a direction 3592 3593 var x = this.x, y = this.y, z = this.z; 3594 var e = m.elements; 3595 3596 this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z; 3597 this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z; 3598 this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z; 3599 3600 return this.normalize(); 3601 3602 }, 3603 3604 divide: function ( v ) { 3605 3606 this.x /= v.x; 3607 this.y /= v.y; 3608 this.z /= v.z; 3609 3610 return this; 3611 3612 }, 3613 3614 divideScalar: function ( scalar ) { 3615 3616 return this.multiplyScalar( 1 / scalar ); 3617 3618 }, 3619 3620 min: function ( v ) { 3621 3622 this.x = Math.min( this.x, v.x ); 3623 this.y = Math.min( this.y, v.y ); 3624 this.z = Math.min( this.z, v.z ); 3625 3626 return this; 3627 3628 }, 3629 3630 max: function ( v ) { 3631 3632 this.x = Math.max( this.x, v.x ); 3633 this.y = Math.max( this.y, v.y ); 3634 this.z = Math.max( this.z, v.z ); 3635 3636 return this; 3637 3638 }, 3639 3640 clamp: function ( min, max ) { 3641 3642 // assumes min < max, componentwise 3643 3644 this.x = Math.max( min.x, Math.min( max.x, this.x ) ); 3645 this.y = Math.max( min.y, Math.min( max.y, this.y ) ); 3646 this.z = Math.max( min.z, Math.min( max.z, this.z ) ); 3647 3648 return this; 3649 3650 }, 3651 3652 clampScalar: function ( minVal, maxVal ) { 3653 3654 this.x = Math.max( minVal, Math.min( maxVal, this.x ) ); 3655 this.y = Math.max( minVal, Math.min( maxVal, this.y ) ); 3656 this.z = Math.max( minVal, Math.min( maxVal, this.z ) ); 3657 3658 return this; 3659 3660 }, 3661 3662 clampLength: function ( min, max ) { 3663 3664 var length = this.length(); 3665 3666 return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); 3667 3668 }, 3669 3670 floor: function () { 3671 3672 this.x = Math.floor( this.x ); 3673 this.y = Math.floor( this.y ); 3674 this.z = Math.floor( this.z ); 3675 3676 return this; 3677 3678 }, 3679 3680 ceil: function () { 3681 3682 this.x = Math.ceil( this.x ); 3683 this.y = Math.ceil( this.y ); 3684 this.z = Math.ceil( this.z ); 3685 3686 return this; 3687 3688 }, 3689 3690 round: function () { 3691 3692 this.x = Math.round( this.x ); 3693 this.y = Math.round( this.y ); 3694 this.z = Math.round( this.z ); 3695 3696 return this; 3697 3698 }, 3699 3700 roundToZero: function () { 3701 3702 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); 3703 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); 3704 this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); 3705 3706 return this; 3707 3708 }, 3709 3710 negate: function () { 3711 3712 this.x = - this.x; 3713 this.y = - this.y; 3714 this.z = - this.z; 3715 3716 return this; 3717 3718 }, 3719 3720 dot: function ( v ) { 3721 3722 return this.x * v.x + this.y * v.y + this.z * v.z; 3723 3724 }, 3725 3726 // TODO lengthSquared? 3727 3728 lengthSq: function () { 3729 3730 return this.x * this.x + this.y * this.y + this.z * this.z; 3731 3732 }, 3733 3734 length: function () { 3735 3736 return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); 3737 3738 }, 3739 3740 manhattanLength: function () { 3741 3742 return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ); 3743 3744 }, 3745 3746 normalize: function () { 3747 3748 return this.divideScalar( this.length() || 1 ); 3749 3750 }, 3751 3752 setLength: function ( length ) { 3753 3754 return this.normalize().multiplyScalar( length ); 3755 3756 }, 3757 3758 lerp: function ( v, alpha ) { 3759 3760 this.x += ( v.x - this.x ) * alpha; 3761 this.y += ( v.y - this.y ) * alpha; 3762 this.z += ( v.z - this.z ) * alpha; 3763 3764 return this; 3765 3766 }, 3767 3768 lerpVectors: function ( v1, v2, alpha ) { 3769 3770 return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); 3771 3772 }, 3773 3774 cross: function ( v, w ) { 3775 3776 if ( w !== undefined ) { 3777 3778 console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); 3779 return this.crossVectors( v, w ); 3780 3781 } 3782 3783 return this.crossVectors( this, v ); 3784 3785 }, 3786 3787 crossVectors: function ( a, b ) { 3788 3789 var ax = a.x, ay = a.y, az = a.z; 3790 var bx = b.x, by = b.y, bz = b.z; 3791 3792 this.x = ay * bz - az * by; 3793 this.y = az * bx - ax * bz; 3794 this.z = ax * by - ay * bx; 3795 3796 return this; 3797 3798 }, 3799 3800 projectOnVector: function ( v ) { 3801 3802 var denominator = v.lengthSq(); 3803 3804 if ( denominator === 0 ) return this.set( 0, 0, 0 ); 3805 3806 var scalar = v.dot( this ) / denominator; 3807 3808 return this.copy( v ).multiplyScalar( scalar ); 3809 3810 }, 3811 3812 projectOnPlane: function ( planeNormal ) { 3813 3814 _vector.copy( this ).projectOnVector( planeNormal ); 3815 3816 return this.sub( _vector ); 3817 3818 }, 3819 3820 reflect: function ( normal ) { 3821 3822 // reflect incident vector off plane orthogonal to normal 3823 // normal is assumed to have unit length 3824 3825 return this.sub( _vector.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) ); 3826 3827 }, 3828 3829 angleTo: function ( v ) { 3830 3831 var denominator = Math.sqrt( this.lengthSq() * v.lengthSq() ); 3832 3833 if ( denominator === 0 ) return Math.PI / 2; 3834 3835 var theta = this.dot( v ) / denominator; 3836 3837 // clamp, to handle numerical problems 3838 3839 return Math.acos( MathUtils.clamp( theta, - 1, 1 ) ); 3840 3841 }, 3842 3843 distanceTo: function ( v ) { 3844 3845 return Math.sqrt( this.distanceToSquared( v ) ); 3846 3847 }, 3848 3849 distanceToSquared: function ( v ) { 3850 3851 var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; 3852 3853 return dx * dx + dy * dy + dz * dz; 3854 3855 }, 3856 3857 manhattanDistanceTo: function ( v ) { 3858 3859 return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z ); 3860 3861 }, 3862 3863 setFromSpherical: function ( s ) { 3864 3865 return this.setFromSphericalCoords( s.radius, s.phi, s.theta ); 3866 3867 }, 3868 3869 setFromSphericalCoords: function ( radius, phi, theta ) { 3870 3871 var sinPhiRadius = Math.sin( phi ) * radius; 3872 3873 this.x = sinPhiRadius * Math.sin( theta ); 3874 this.y = Math.cos( phi ) * radius; 3875 this.z = sinPhiRadius * Math.cos( theta ); 3876 3877 return this; 3878 3879 }, 3880 3881 setFromCylindrical: function ( c ) { 3882 3883 return this.setFromCylindricalCoords( c.radius, c.theta, c.y ); 3884 3885 }, 3886 3887 setFromCylindricalCoords: function ( radius, theta, y ) { 3888
3889 this.x = radius * Math.sin( theta ); 3890 this.y = y; 3891 this.z = radius * Math.cos( theta ); 3892 3893 return this; 3894 3895 }, 3896 3897 setFromMatrixPosition: function ( m ) { 3898 3899 var e = m.elements; 3900 3901 this.x = e[ 12 ]; 3902 this.y = e[ 13 ]; 3903 this.z = e[ 14 ]; 3904 3905 return this; 3906 3907 }, 3908 3909 setFromMatrixScale: function ( m ) { 3910 3911 var sx = this.setFromMatrixColumn( m, 0 ).length(); 3912 var sy = this.setFromMatrixColumn( m, 1 ).length(); 3913 var sz = this.setFromMatrixColumn( m, 2 ).length(); 3914 3915 this.x = sx; 3916 this.y = sy; 3917 this.z = sz; 3918 3919 return this; 3920 3921 }, 3922 3923 setFromMatrixColumn: function ( m, index ) { 3924 3925 return this.fromArray( m.elements, index * 4 ); 3926 3927 }, 3928 3929 setFromMatrix3Column: function ( m, index ) { 3930 3931 return this.fromArray( m.elements, index * 3 ); 3932 3933 }, 3934 3935 equals: function ( v ) { 3936 3937 return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) ); 3938 3939 }, 3940 3941 fromArray: function ( array, offset ) { 3942 3943 if ( offset === undefined ) offset = 0; 3944 3945 this.x = array[ offset ]; 3946 this.y = array[ offset + 1 ]; 3947 this.z = array[ offset + 2 ]; 3948 3949 return this; 3950 3951 }, 3952 3953 toArray: function ( array, offset ) { 3954 3955 if ( array === undefined ) array = []; 3956 if ( offset === undefined ) offset = 0; 3957 3958 array[ offset ] = this.x; 3959 array[ offset + 1 ] = this.y; 3960 array[ offset + 2 ] = this.z; 3961 3962 return array; 3963 3964 }, 3965 3966 fromBufferAttribute: function ( attribute, index, offset ) { 3967 3968 if ( offset !== undefined ) { 3969 3970 console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' ); 3971 3972 } 3973 3974 this.x = attribute.getX( index ); 3975 this.y = attribute.getY( index ); 3976 this.z = attribute.getZ( index ); 3977 3978 return this; 3979 3980 }, 3981 3982 random: function () { 3983 3984 this.x = Math.random(); 3985 this.y = Math.random(); 3986 this.z = Math.random(); 3987 3988 return this; 3989 3990 } 3991 3992} ); 3993 3994var _v1 = new Vector3(); 3995var _m1 = new Matrix4(); 3996var _zero = new Vector3( 0, 0, 0 ); 3997var _one = new Vector3( 1, 1, 1 ); 3998var _x = new Vector3(); 3999var _y = new Vector3(); 4000var _z = new Vector3(); 4001 4002/** 4003 * @author mrdoob / http://mrdoob.com/ 4004 * @author supereggbert / http://www.paulbrunt.co.uk/ 4005 * @author philogb / http://blog.thejit.org/ 4006 * @author jordi_ros / http://plattsoft.com 4007 * @author D1plo1d / http://github.com/D1plo1d 4008 * @author alteredq / http://alteredqualia.com/ 4009 * @author mikael emtinger / http://gomo.se/ 4010 * @author timknip / http://www.floorplanner.com/ 4011 * @author bhouston / http://clara.io 4012 * @author WestLangley / http://github.com/WestLangley 4013 */ 4014 4015function Matrix4() { 4016 4017 this.elements = [ 4018 4019 1, 0, 0, 0, 4020 0, 1, 0, 0, 4021 0, 0, 1, 0, 4022 0, 0, 0, 1 4023 4024 ]; 4025 4026 if ( arguments.length > 0 ) { 4027 4028 console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' ); 4029 4030 } 4031 4032} 4033 4034Object.assign( Matrix4.prototype, { 4035 4036 isMatrix4: true, 4037 4038 set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { 4039 4040 var te = this.elements; 4041 4042 te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14; 4043 te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24; 4044 te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34; 4045 te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44; 4046 4047 return this; 4048 4049 }, 4050 4051 identity: function () { 4052 4053 this.set( 4054 4055 1, 0, 0, 0, 4056 0, 1, 0, 0, 4057 0, 0, 1, 0, 4058 0, 0, 0, 1 4059 4060 ); 4061 4062 return this; 4063 4064 }, 4065 4066 clone: function () { 4067 4068 return new Matrix4().fromArray( this.elements ); 4069 4070 }, 4071 4072 copy: function ( m ) { 4073 4074 var te = this.elements; 4075 var me = m.elements; 4076 4077 te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ]; 4078 te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; 4079 te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ]; 4080 te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ]; 4081 4082 return this; 4083 4084 }, 4085 4086 copyPosition: function ( m ) { 4087 4088 var te = this.elements, me = m.elements; 4089 4090 te[ 12 ] = me[ 12 ]; 4091 te[ 13 ] = me[ 13 ]; 4092 te[ 14 ] = me[ 14 ]; 4093 4094 return this; 4095 4096 }, 4097 4098 extractBasis: function ( xAxis, yAxis, zAxis ) { 4099 4100 xAxis.setFromMatrixColumn( this, 0 ); 4101 yAxis.setFromMatrixColumn( this, 1 ); 4102 zAxis.setFromMatrixColumn( this, 2 ); 4103 4104 return this; 4105 4106 }, 4107 4108 makeBasis: function ( xAxis, yAxis, zAxis ) { 4109 4110 this.set( 4111 xAxis.x, yAxis.x, zAxis.x, 0, 4112 xAxis.y, yAxis.y, zAxis.y, 0,
vendor: 15,119 bytes, lines 4113-4780
4113 xAxis.z, yAxis.z, zAxis.z, 0, 4114 0, 0, 0, 1 4115 ); 4116 4117 return this; 4118 4119 }, 4120 4121 extractRotation: function ( m ) { 4122 4123 // this method does not support reflection matrices 4124 4125 var te = this.elements; 4126 var me = m.elements; 4127 4128 var scaleX = 1 / _v1.setFromMatrixColumn( m, 0 ).length(); 4129 var scaleY = 1 / _v1.setFromMatrixColumn( m, 1 ).length(); 4130 var scaleZ = 1 / _v1.setFromMatrixColumn( m, 2 ).length(); 4131 4132 te[ 0 ] = me[ 0 ] * scaleX; 4133 te[ 1 ] = me[ 1 ] * scaleX; 4134 te[ 2 ] = me[ 2 ] * scaleX; 4135 te[ 3 ] = 0; 4136 4137 te[ 4 ] = me[ 4 ] * scaleY; 4138 te[ 5 ] = me[ 5 ] * scaleY; 4139 te[ 6 ] = me[ 6 ] * scaleY; 4140 te[ 7 ] = 0; 4141 4142 te[ 8 ] = me[ 8 ] * scaleZ; 4143 te[ 9 ] = me[ 9 ] * scaleZ; 4144 te[ 10 ] = me[ 10 ] * scaleZ; 4145 te[ 11 ] = 0; 4146 4147 te[ 12 ] = 0; 4148 te[ 13 ] = 0; 4149 te[ 14 ] = 0; 4150 te[ 15 ] = 1; 4151 4152 return this; 4153 4154 }, 4155 4156 makeRotationFromEuler: function ( euler ) { 4157 4158 if ( ! ( euler && euler.isEuler ) ) { 4159 4160 console.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' ); 4161 4162 } 4163 4164 var te = this.elements; 4165 4166 var x = euler.x, y = euler.y, z = euler.z; 4167 var a = Math.cos( x ), b = Math.sin( x ); 4168 var c = Math.cos( y ), d = Math.sin( y ); 4169 var e = Math.cos( z ), f = Math.sin( z ); 4170 4171 if ( euler.order === 'XYZ' ) { 4172 4173 var ae = a * e, af = a * f, be = b * e, bf = b * f; 4174 4175 te[ 0 ] = c * e; 4176 te[ 4 ] = - c * f; 4177 te[ 8 ] = d; 4178 4179 te[ 1 ] = af + be * d; 4180 te[ 5 ] = ae - bf * d; 4181 te[ 9 ] = - b * c; 4182 4183 te[ 2 ] = bf - ae * d; 4184 te[ 6 ] = be + af * d; 4185 te[ 10 ] = a * c; 4186 4187 } else if ( euler.order === 'YXZ' ) { 4188 4189 var ce = c * e, cf = c * f, de = d * e, df = d * f; 4190 4191 te[ 0 ] = ce + df * b; 4192 te[ 4 ] = de * b - cf; 4193 te[ 8 ] = a * d; 4194 4195 te[ 1 ] = a * f; 4196 te[ 5 ] = a * e; 4197 te[ 9 ] = - b; 4198 4199 te[ 2 ] = cf * b - de; 4200 te[ 6 ] = df + ce * b; 4201 te[ 10 ] = a * c; 4202 4203 } else if ( euler.order === 'ZXY' ) { 4204 4205 var ce = c * e, cf = c * f, de = d * e, df = d * f; 4206 4207 te[ 0 ] = ce - df * b; 4208 te[ 4 ] = - a * f; 4209 te[ 8 ] = de + cf * b; 4210 4211 te[ 1 ] = cf + de * b; 4212 te[ 5 ] = a * e; 4213 te[ 9 ] = df - ce * b; 4214 4215 te[ 2 ] = - a * d; 4216 te[ 6 ] = b; 4217 te[ 10 ] = a * c; 4218 4219 } else if ( euler.order === 'ZYX' ) { 4220 4221 var ae = a * e, af = a * f, be = b * e, bf = b * f; 4222 4223 te[ 0 ] = c * e; 4224 te[ 4 ] = be * d - af; 4225 te[ 8 ] = ae * d + bf; 4226 4227 te[ 1 ] = c * f; 4228 te[ 5 ] = bf * d + ae; 4229 te[ 9 ] = af * d - be; 4230 4231 te[ 2 ] = - d; 4232 te[ 6 ] = b * c; 4233 te[ 10 ] = a * c; 4234 4235 } else if ( euler.order === 'YZX' ) { 4236 4237 var ac = a * c, ad = a * d, bc = b * c, bd = b * d; 4238 4239 te[ 0 ] = c * e; 4240 te[ 4 ] = bd - ac * f; 4241 te[ 8 ] = bc * f + ad; 4242 4243 te[ 1 ] = f; 4244 te[ 5 ] = a * e; 4245 te[ 9 ] = - b * e; 4246 4247 te[ 2 ] = - d * e; 4248 te[ 6 ] = ad * f + bc; 4249 te[ 10 ] = ac - bd * f; 4250 4251 } else if ( euler.order === 'XZY' ) { 4252 4253 var ac = a * c, ad = a * d, bc = b * c, bd = b * d; 4254 4255 te[ 0 ] = c * e; 4256 te[ 4 ] = - f; 4257 te[ 8 ] = d * e; 4258 4259 te[ 1 ] = ac * f + bd; 4260 te[ 5 ] = a * e; 4261 te[ 9 ] = ad * f - bc; 4262 4263 te[ 2 ] = bc * f - ad; 4264 te[ 6 ] = b * e; 4265 te[ 10 ] = bd * f + ac; 4266 4267 } 4268 4269 // bottom row 4270 te[ 3 ] = 0; 4271 te[ 7 ] = 0; 4272 te[ 11 ] = 0; 4273 4274 // last column 4275 te[ 12 ] = 0; 4276 te[ 13 ] = 0; 4277 te[ 14 ] = 0; 4278 te[ 15 ] = 1; 4279 4280 return this; 4281 4282 }, 4283 4284 makeRotationFromQuaternion: function ( q ) { 4285 4286 return this.compose( _zero, q, _one ); 4287 4288 }, 4289 4290 lookAt: function ( eye, target, up ) { 4291 4292 var te = this.elements; 4293 4294 _z.subVectors( eye, target ); 4295 4296 if ( _z.lengthSq() === 0 ) { 4297 4298 // eye and target are in the same position 4299 4300 _z.z = 1; 4301 4302 } 4303 4304 _z.normalize(); 4305 _x.crossVectors( up, _z ); 4306 4307 if ( _x.lengthSq() === 0 ) { 4308 4309 // up and z are parallel 4310 4311 if ( Math.abs( up.z ) === 1 ) { 4312 4313 _z.x += 0.0001; 4314 4315 } else { 4316 4317 _z.z += 0.0001; 4318 4319 } 4320 4321 _z.normalize(); 4322 _x.crossVectors( up, _z ); 4323 4324 } 4325 4326 _x.normalize(); 4327 _y.crossVectors( _z, _x ); 4328 4329 te[ 0 ] = _x.x; te[ 4 ] = _y.x; te[ 8 ] = _z.x; 4330 te[ 1 ] = _x.y; te[ 5 ] = _y.y; te[ 9 ] = _z.y; 4331 te[ 2 ] = _x.z; te[ 6 ] = _y.z; te[ 10 ] = _z.z; 4332 4333 return this; 4334 4335 }, 4336 4337 multiply: function ( m, n ) { 4338 4339 if ( n !== undefined ) { 4340 4341 console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); 4342 return this.multiplyMatrices( m, n ); 4343 4344 } 4345 4346 return this.multiplyMatrices( this, m ); 4347 4348 }, 4349 4350 premultiply: function ( m ) { 4351 4352 return this.multiplyMatrices( m, this ); 4353 4354 }, 4355 4356 multiplyMatrices: function ( a, b ) { 4357 4358 var ae = a.elements; 4359 var be = b.elements; 4360 var te = this.elements; 4361 4362 var a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ]; 4363 var a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ]; 4364 var a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ]; 4365 var a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ]; 4366 4367 var b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ]; 4368 var b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ]; 4369 var b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ]; 4370 var b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ]; 4371 4372 te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; 4373 te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; 4374 te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; 4375 te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; 4376 4377 te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; 4378 te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; 4379 te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; 4380 te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; 4381 4382 te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; 4383 te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; 4384 te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; 4385 te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; 4386 4387 te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; 4388 te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; 4389 te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; 4390 te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; 4391 4392 return this; 4393 4394 }, 4395 4396 multiplyScalar: function ( s ) { 4397 4398 var te = this.elements; 4399 4400 te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s; 4401 te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s; 4402 te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s; 4403 te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s; 4404 4405 return this; 4406 4407 }, 4408 4409 determinant: function () { 4410 4411 var te = this.elements; 4412 4413 var n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ]; 4414 var n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ]; 4415 var n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ]; 4416 var n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ]; 4417 4418 //TODO: make this more efficient 4419 //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm ) 4420 4421 return ( 4422 n41 * ( 4423 + n14 * n23 * n32 4424 - n13 * n24 * n32 4425 - n14 * n22 * n33 4426 + n12 * n24 * n33 4427 + n13 * n22 * n34 4428 - n12 * n23 * n34 4429 ) + 4430 n42 * ( 4431 + n11 * n23 * n34 4432 - n11 * n24 * n33 4433 + n14 * n21 * n33 4434 - n13 * n21 * n34 4435 + n13 * n24 * n31 4436 - n14 * n23 * n31 4437 ) + 4438 n43 * ( 4439 + n11 * n24 * n32 4440 - n11 * n22 * n34 4441 - n14 * n21 * n32 4442 + n12 * n21 * n34 4443 + n14 * n22 * n31 4444 - n12 * n24 * n31 4445 ) + 4446 n44 * ( 4447 - n13 * n22 * n31 4448 - n11 * n23 * n32 4449 + n11 * n22 * n33 4450 + n13 * n21 * n32 4451 - n12 * n21 * n33 4452 + n12 * n23 * n31 4453 ) 4454 4455 ); 4456 4457 }, 4458 4459 transpose: function () { 4460 4461 var te = this.elements; 4462 var tmp; 4463 4464 tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp; 4465 tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp; 4466 tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp; 4467 4468 tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp; 4469 tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp; 4470 tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp; 4471 4472 return this; 4473 4474 }, 4475 4476 setPosition: function ( x, y, z ) { 4477 4478 var te = this.elements; 4479 4480 if ( x.isVector3 ) { 4481 4482 te[ 12 ] = x.x; 4483 te[ 13 ] = x.y; 4484 te[ 14 ] = x.z; 4485 4486 } else { 4487 4488 te[ 12 ] = x; 4489 te[ 13 ] = y; 4490 te[ 14 ] = z; 4491 4492 } 4493 4494 return this; 4495 4496 }, 4497 4498 getInverse: function ( m, throwOnDegenerate ) { 4499 4500 if ( throwOnDegenerate !== undefined ) { 4501 4502 console.warn( "THREE.Matrix4: .getInverse() can no longer be configured to throw on degenerate." ); 4503 4504 } 4505 4506 // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm 4507 var te = this.elements, 4508 me = m.elements, 4509 4510 n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ], 4511 n12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ], 4512 n13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ], 4513 n14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ], 4514 4515 t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, 4516 t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, 4517 t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, 4518 t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; 4519 4520 var det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; 4521 4522 if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); 4523 4524 var detInv = 1 / det; 4525 4526 te[ 0 ] = t11 * detInv; 4527 te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv; 4528 te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv; 4529 te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv; 4530 4531 te[ 4 ] = t12 * detInv; 4532 te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv; 4533 te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv; 4534 te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv; 4535 4536 te[ 8 ] = t13 * detInv; 4537 te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv; 4538 te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv; 4539 te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv; 4540 4541 te[ 12 ] = t14 * detInv; 4542 te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv; 4543 te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv; 4544 te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv; 4545 4546 return this; 4547 4548 }, 4549 4550 scale: function ( v ) { 4551 4552 var te = this.elements; 4553 var x = v.x, y = v.y, z = v.z; 4554 4555 te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z; 4556 te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z; 4557 te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z; 4558 te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z; 4559 4560 return this; 4561 4562 }, 4563 4564 getMaxScaleOnAxis: function () { 4565 4566 var te = this.elements; 4567 4568 var scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ]; 4569 var scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ]; 4570 var scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ]; 4571 4572 return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) ); 4573 4574 }, 4575 4576 makeTranslation: function ( x, y, z ) { 4577 4578 this.set( 4579 4580 1, 0, 0, x, 4581 0, 1, 0, y, 4582 0, 0, 1, z, 4583 0, 0, 0, 1 4584 4585 ); 4586 4587 return this; 4588 4589 }, 4590 4591 makeRotationX: function ( theta ) { 4592 4593 var c = Math.cos( theta ), s = Math.sin( theta ); 4594 4595 this.set( 4596 4597 1, 0, 0, 0, 4598 0, c, - s, 0, 4599 0, s, c, 0, 4600 0, 0, 0, 1 4601 4602 ); 4603 4604 return this; 4605 4606 }, 4607 4608 makeRotationY: function ( theta ) { 4609 4610 var c = Math.cos( theta ), s = Math.sin( theta ); 4611 4612 this.set( 4613 4614 c, 0, s, 0, 4615 0, 1, 0, 0, 4616 - s, 0, c, 0, 4617 0, 0, 0, 1 4618 4619 ); 4620 4621 return this; 4622 4623 }, 4624 4625 makeRotationZ: function ( theta ) { 4626 4627 var c = Math.cos( theta ), s = Math.sin( theta ); 4628 4629 this.set( 4630 4631 c, - s, 0, 0, 4632 s, c, 0, 0, 4633 0, 0, 1, 0, 4634 0, 0, 0, 1 4635 4636 ); 4637 4638 return this; 4639 4640 }, 4641 4642 makeRotationAxis: function ( axis, angle ) { 4643 4644 // Based on http://www.gamedev.net/reference/articles/article1199.asp 4645 4646 var c = Math.cos( angle ); 4647 var s = Math.sin( angle ); 4648 var t = 1 - c; 4649 var x = axis.x, y = axis.y, z = axis.z; 4650 var tx = t * x, ty = t * y; 4651 4652 this.set( 4653 4654 tx * x + c, tx * y - s * z, tx * z + s * y, 0, 4655 tx * y + s * z, ty * y + c, ty * z - s * x, 0, 4656 tx * z - s * y, ty * z + s * x, t * z * z + c, 0, 4657 0, 0, 0, 1 4658 4659 ); 4660 4661 return this; 4662 4663 }, 4664 4665 makeScale: function ( x, y, z ) { 4666 4667 this.set( 4668 4669 x, 0, 0, 0, 4670 0, y, 0, 0, 4671 0, 0, z, 0, 4672 0, 0, 0, 1 4673 4674 ); 4675 4676 return this; 4677 4678 }, 4679 4680 makeShear: function ( x, y, z ) { 4681 4682 this.set( 4683 4684 1, y, z, 0, 4685 x, 1, z, 0, 4686 x, y, 1, 0, 4687 0, 0, 0, 1 4688 4689 ); 4690 4691 return this; 4692 4693 }, 4694 4695 compose: function ( position, quaternion, scale ) { 4696 4697 var te = this.elements; 4698 4699 var x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w; 4700 var x2 = x + x, y2 = y + y, z2 = z + z; 4701 var xx = x * x2, xy = x * y2, xz = x * z2; 4702 var yy = y * y2, yz = y * z2, zz = z * z2; 4703 var wx = w * x2, wy = w * y2, wz = w * z2; 4704 4705 var sx = scale.x, sy = scale.y, sz = scale.z; 4706 4707 te[ 0 ] = ( 1 - ( yy + zz ) ) * sx; 4708 te[ 1 ] = ( xy + wz ) * sx; 4709 te[ 2 ] = ( xz - wy ) * sx; 4710 te[ 3 ] = 0; 4711 4712 te[ 4 ] = ( xy - wz ) * sy; 4713 te[ 5 ] = ( 1 - ( xx + zz ) ) * sy; 4714 te[ 6 ] = ( yz + wx ) * sy; 4715 te[ 7 ] = 0; 4716 4717 te[ 8 ] = ( xz + wy ) * sz; 4718 te[ 9 ] = ( yz - wx ) * sz; 4719 te[ 10 ] = ( 1 - ( xx + yy ) ) * sz; 4720 te[ 11 ] = 0; 4721 4722 te[ 12 ] = position.x; 4723 te[ 13 ] = position.y; 4724 te[ 14 ] = position.z; 4725 te[ 15 ] = 1; 4726 4727 return this; 4728 4729 }, 4730 4731 decompose: function ( position, quaternion, scale ) { 4732 4733 var te = this.elements; 4734 4735 var sx = _v1.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length(); 4736 var sy = _v1.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length(); 4737 var sz = _v1.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length(); 4738 4739 // if determine is negative, we need to invert one scale 4740 var det = this.determinant(); 4741 if ( det < 0 ) sx = - sx; 4742 4743 position.x = te[ 12 ]; 4744 position.y = te[ 13 ]; 4745 position.z = te[ 14 ]; 4746 4747 // scale the rotation part 4748 _m1.copy( this ); 4749 4750 var invSX = 1 / sx; 4751 var invSY = 1 / sy; 4752 var invSZ = 1 / sz; 4753 4754 _m1.elements[ 0 ] *= invSX; 4755 _m1.elements[ 1 ] *= invSX; 4756 _m1.elements[ 2 ] *= invSX; 4757 4758 _m1.elements[ 4 ] *= invSY; 4759 _m1.elements[ 5 ] *= invSY; 4760 _m1.elements[ 6 ] *= invSY; 4761 4762 _m1.elements[ 8 ] *= invSZ; 4763 _m1.elements[ 9 ] *= invSZ; 4764 _m1.elements[ 10 ] *= invSZ; 4765 4766 quaternion.setFromRotationMatrix( _m1 ); 4767 4768 scale.x = sx; 4769 scale.y = sy; 4770 scale.z = sz; 4771 4772 return this; 4773 4774 }, 4775 4776 makePerspective: function ( left, right, top, bottom, near, far ) { 4777 4778 if ( far === undefined ) { 4779 4780 console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a
4780new signature. Please check the docs.' ); 4781 4782 } 4783 4784 var te = this.elements; 4785 var x = 2 * near / ( right - left ); 4786 var y = 2 * near / ( top - bottom ); 4787 4788 var a = ( right + left ) / ( right - left ); 4789 var b = ( top + bottom ) / ( top - bottom ); 4790 var c = - ( far + near ) / ( far - near ); 4791 var d = - 2 * far * near / ( far - near ); 4792 4793 te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0; 4794 te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0; 4795 te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; 4796 te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0; 4797 4798 return this; 4799 4800 }, 4801 4802 makeOrthographic: function ( left, right, top, bottom, near, far ) { 4803 4804 var te = this.elements; 4805 var w = 1.0 / ( right - left ); 4806 var h = 1.0 / ( top - bottom ); 4807 var p = 1.0 / ( far - near ); 4808 4809 var x = ( right + left ) * w; 4810 var y = ( top + bottom ) * h; 4811 var z = ( far + near ) * p; 4812 4813 te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x; 4814 te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y; 4815 te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 * p; te[ 14 ] = - z; 4816 te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1; 4817 4818 return this; 4819 4820 }, 4821 4822 equals: function ( matrix ) { 4823 4824 var te = this.elements; 4825 var me = matrix.elements; 4826 4827 for ( var i = 0; i < 16; i ++ ) { 4828 4829 if ( te[ i ] !== me[ i ] ) return false; 4830 4831 } 4832 4833 return true; 4834 4835 }, 4836 4837 fromArray: function ( array, offset ) { 4838 4839 if ( offset === undefined ) offset = 0; 4840 4841 for ( var i = 0; i < 16; i ++ ) { 4842 4843 this.elements[ i ] = array[ i + offset ]; 4844 4845 } 4846 4847 return this; 4848 4849 }, 4850 4851 toArray: function ( array, offset ) { 4852 4853 if ( array === undefined ) array = []; 4854 if ( offset === undefined ) offset = 0; 4855 4856 var te = this.elements; 4857 4858 array[ offset ] = te[ 0 ]; 4859 array[ offset + 1 ] = te[ 1 ]; 4860 array[ offset + 2 ] = te[ 2 ]; 4861 array[ offset + 3 ] = te[ 3 ]; 4862 4863 array[ offset + 4 ] = te[ 4 ]; 4864 array[ offset + 5 ] = te[ 5 ]; 4865 array[ offset + 6 ] = te[ 6 ]; 4866 array[ offset + 7 ] = te[ 7 ]; 4867 4868 array[ offset + 8 ] = te[ 8 ]; 4869 array[ offset + 9 ] = te[ 9 ]; 4870 array[ offset + 10 ] = te[ 10 ]; 4871 array[ offset + 11 ] = te[ 11 ]; 4872 4873 array[ offset + 12 ] = te[ 12 ]; 4874 array[ offset + 13 ] = te[ 13 ]; 4875 array[ offset + 14 ] = te[ 14 ]; 4876 array[ offset + 15 ] = te[ 15 ]; 4877 4878 return array; 4879 4880 } 4881 4882} ); 4883 4884/** 4885 * @author mrdoob / http://mrdoob.com/ 4886 * @author WestLangley / http://github.com/WestLangley 4887 * @author bhouston / http://clara.io 4888 */ 4889 4890var _matrix = new Matrix4(); 4891var _quaternion$1 = new Quaternion(); 4892 4893function Euler( x, y, z, order ) { 4894 4895 this._x = x || 0; 4896 this._y = y || 0; 4897 this._z = z || 0; 4898 this._order = order || Euler.DefaultOrder; 4899 4900} 4901 4902Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ]; 4903 4904Euler.DefaultOrder = 'XYZ'; 4905 4906Object.defineProperties( Euler.prototype, { 4907 4908 x: { 4909 4910 get: function () { 4911 4912 return this._x; 4913 4914 }, 4915 4916 set: function ( value ) { 4917 4918 this._x = value; 4919 this._onChangeCallback(); 4920 4921 } 4922 4923 }, 4924 4925 y: { 4926 4927 get: function () { 4928 4929 return this._y; 4930 4931 }, 4932 4933 set: function ( value ) { 4934 4935 this._y = value; 4936 this._onChangeCallback(); 4937 4938 } 4939 4940 }, 4941 4942 z: { 4943 4944 get: function () { 4945 4946 return this._z; 4947 4948 }, 4949 4950 set: function ( value ) { 4951 4952 this._z = value; 4953 this._onChangeCallback(); 4954 4955 } 4956 4957 }, 4958 4959 order: { 4960 4961 get: function () { 4962 4963 return this._order; 4964 4965 }, 4966 4967 set: function ( value ) { 4968 4969 this._order = value; 4970 this._onChangeCallback(); 4971 4972 } 4973 4974 } 4975 4976} ); 4977 4978Object.assign( Euler.prototype, { 4979 4980 isEuler: true, 4981 4982 set: function ( x, y, z, order ) { 4983 4984 this._x = x; 4985 this._y = y; 4986 this._z = z; 4987 this._order = order || this._order; 4988 4989 this._onChangeCallback(); 4990 4991 return this; 4992 4993 }, 4994 4995 clone: function () { 4996 4997 return new this.constructor( this._x, this._y, this._z, this._order ); 4998 4999 }, 5000 5001 copy: function ( euler ) { 5002 5003 this._x = euler._x; 5004 this._y = euler._y; 5005 this._z = euler._z; 5006 this._order = euler._order; 5007 5008 this._onChangeCallback(); 5009 5010 return this; 5011 5012 }, 5013 5014 setFromRotationMatrix: function ( m, order, update ) { 5015 5016 var clamp = MathUtils.clamp; 5017 5018 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) 5019 5020 var te = m.elements; 5021 var m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ]; 5022 var m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ]; 5023 var m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; 5024 5025 order = order || this._order;
5026 5027 switch ( order ) { 5028 5029 case 'XYZ': 5030 5031 this._y = Math.asin( clamp( m13, - 1, 1 ) ); 5032 5033 if ( Math.abs( m13 ) < 0.9999999 ) { 5034 5035 this._x = Math.atan2( - m23, m33 ); 5036 this._z = Math.atan2( - m12, m11 ); 5037 5038 } else { 5039 5040 this._x = Math.atan2( m32, m22 ); 5041 this._z = 0; 5042 5043 } 5044 5045 break; 5046 5047 case 'YXZ': 5048 5049 this._x = Math.asin( - clamp( m23, - 1, 1 ) ); 5050 5051 if ( Math.abs( m23 ) < 0.9999999 ) { 5052 5053 this._y = Math.atan2( m13, m33 ); 5054 this._z = Math.atan2( m21, m22 ); 5055 5056 } else { 5057 5058 this._y = Math.atan2( - m31, m11 ); 5059 this._z = 0; 5060 5061 } 5062 5063 break; 5064 5065 case 'ZXY': 5066 5067 this._x = Math.asin( clamp( m32, - 1, 1 ) ); 5068 5069 if ( Math.abs( m32 ) < 0.9999999 ) { 5070 5071 this._y = Math.atan2( - m31, m33 ); 5072 this._z = Math.atan2( - m12, m22 ); 5073 5074 } else { 5075 5076 this._y = 0; 5077 this._z = Math.atan2( m21, m11 ); 5078 5079 } 5080 5081 break; 5082 5083 case 'ZYX': 5084 5085 this._y = Math.asin( - clamp( m31, - 1, 1 ) ); 5086 5087 if ( Math.abs( m31 ) < 0.9999999 ) { 5088 5089 this._x = Math.atan2( m32, m33 ); 5090 this._z = Math.atan2( m21, m11 ); 5091 5092 } else { 5093 5094 this._x = 0; 5095 this._z = Math.atan2( - m12, m22 ); 5096 5097 } 5098 5099 break; 5100 5101 case 'YZX': 5102 5103 this._z = Math.asin( clamp( m21, - 1, 1 ) ); 5104 5105 if ( Math.abs( m21 ) < 0.9999999 ) { 5106 5107 this._x = Math.atan2( - m23, m22 ); 5108 this._y = Math.atan2( - m31, m11 ); 5109 5110 } else { 5111 5112 this._x = 0; 5113 this._y = Math.atan2( m13, m33 ); 5114 5115 } 5116 5117 break; 5118 5119 case 'XZY': 5120 5121 this._z = Math.asin( - clamp( m12, - 1, 1 ) ); 5122 5123 if ( Math.abs( m12 ) < 0.9999999 ) { 5124 5125 this._x = Math.atan2( m32, m22 ); 5126 this._y = Math.atan2( m13, m11 ); 5127 5128 } else { 5129 5130 this._x = Math.atan2( - m23, m33 ); 5131 this._y = 0; 5132 5133 } 5134 5135 break; 5136 5137 default: 5138 5139 console.warn( 'THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order ); 5140 5141 } 5142 5143 this._order = order; 5144 5145 if ( update !== false ) this._onChangeCallback(); 5146 5147 return this; 5148 5149 }, 5150 5151 setFromQuaternion: function ( q, order, update ) { 5152 5153 _matrix.makeRotationFromQuaternion( q ); 5154 5155 return this.setFromRotationMatrix( _matrix, order, update ); 5156 5157 }, 5158 5159 setFromVector3: function ( v, order ) { 5160 5161 return this.set( v.x, v.y, v.z, order || this._order ); 5162 5163 }, 5164 5165 reorder: function ( newOrder ) { 5166 5167 // WARNING: this discards revolution information -bhouston 5168 5169 _quaternion$1.setFromEuler( this ); 5170 5171 return this.setFromQuaternion( _quaternion$1, newOrder ); 5172 5173 }, 5174 5175 equals: function ( euler ) { 5176 5177 return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order ); 5178 5179 }, 5180 5181 fromArray: function ( array ) { 5182 5183 this._x = array[ 0 ]; 5184 this._y = array[ 1 ]; 5185 this._z = array[ 2 ]; 5186 if ( array[ 3 ] !== undefined ) this._order = array[ 3 ]; 5187 5188 this._onChangeCallback(); 5189 5190 return this; 5191 5192 }, 5193 5194 toArray: function ( array, offset ) { 5195 5196 if ( array === undefined ) array = []; 5197 if ( offset === undefined ) offset = 0; 5198 5199 array[ offset ] = this._x; 5200 array[ offset + 1 ] = this._y; 5201 array[ offset + 2 ] = this._z; 5202 array[ offset + 3 ] = this._order; 5203 5204 return array; 5205 5206 }, 5207 5208 toVector3: function ( optionalResult ) { 5209 5210 if ( optionalResult ) { 5211 5212 return optionalResult.set( this._x, this._y, this._z ); 5213 5214 } else { 5215 5216 return new Vector3( this._x, this._y, this._z ); 5217 5218 } 5219 5220 }, 5221 5222 _onChange: function ( callback ) { 5223 5224 this._onChangeCallback = callback; 5225 5226 return this; 5227 5228 }, 5229 5230 _onChangeCallback: function () {} 5231 5232} ); 5233 5234/** 5235 * @author mrdoob / http://mrdoob.com/ 5236 */ 5237 5238function Layers() { 5239 5240 this.mask = 1 | 0; 5241 5242} 5243 5244Object.assign( Layers.prototype, { 5245 5246 set: function ( channel ) { 5247 5248 this.mask = 1 << channel | 0; 5249 5250 }, 5251 5252 enable: function ( channel ) { 5253 5254 this.mask |= 1 << channel | 0; 5255 5256 }, 5257 5258 enableAll: function () { 5259 5260 this.mask = 0xffffffff | 0; 5261 5262 }, 5263 5264 toggle: function ( channel ) { 5265 5266 this.mask ^= 1 << channel | 0; 5267 5268 }, 5269 5270 disable: function ( channel ) { 5271 5272 this.mask &= ~ ( 1 << channel | 0 ); 5273 5274 }, 5275 5276 disableAll: function () { 5277 5278 this.mask = 0; 5279 5280 }, 5281 5282 test: function ( layers ) { 5283 5284 return ( this.mask & layers.mask ) !== 0; 5285 5286 } 5287 5288} ); 5289 5290var _object3DId = 0; 5291 5292var _v1$1 = new Vector3(); 5293var _q1 = new Quaternion(); 5294var _m1$1 = new Matrix4(); 5295var _target = new Vector3(); 5296 5297var _position = new Vector3(); 5298var _scale = new Vector3(); 5299var _quaternion$2 = new Quaternion(); 5300 5301var _xAxis = new Vector3( 1, 0, 0 ); 5302var _yAxis = new Vector3( 0, 1, 0 ); 5303var _zAxis = new Vector3( 0, 0, 1 ); 5304 5305var _addedEvent = { type: 'added' }; 5306var _removedEvent = { type: 'removed' }; 5307 5308/** 5309 * @author mrdoob / http://mrdoob.com/ 5310 * @author mikael emtinger / http://gomo.se/ 5311 * @author alteredq / http://alteredqualia.com/ 5312 * @author WestLangley / http://github.com/WestLangley 5313 * @author elephantatwork / www.elephantatwork.ch 5314 */ 5315 5316function Object3D() { 5317 5318 Object.defineProperty( this, 'id', { value: _object3DId ++ } ); 5319 5320 this.uuid = MathUtils.generateUUID(); 5321 5322 this.name = ''; 5323 this.type = 'Object3D'; 5324 5325 this.parent = null; 5326 this.children = []; 5327 5328 this.up = Object3D.DefaultUp.clone(); 5329 5330 var position = new Vector3(); 5331 var rotation = new Euler(); 5332 var quaternion = new Quaternion(); 5333 var scale = new Vector3( 1, 1, 1 ); 5334 5335 function onRotationChange() { 5336 5337 quaternion.setFromEuler( rotation, false ); 5338 5339 } 5340 5341 function onQuaternionChange() { 5342 5343 rotation.setFromQuaternion( quaternion, undefined, false ); 5344 5345 } 5346 5347 rotation._onChange( onRotationChange ); 5348 quaternion._onChange( onQuaternionChange ); 5349 5350 Object.defineProperties( this, { 5351 position: { 5352 configurable: true, 5353 enumerable: true, 5354 value: position 5355 }, 5356 rotation: { 5357 configurable: true, 5358 enumerable: true, 5359 value: rotation 5360 }, 5361 quaternion: { 5362 configurable: true, 5363 enumerable: true, 5364 value: quaternion 5365 }, 5366 scale: { 5367 configurable: true, 5368 enumerable: true, 5369 value: scale 5370 }, 5371 modelViewMatrix: { 5372 value: new Matrix4() 5373 }, 5374 normalMatrix: { 5375 value: new Matrix3() 5376 } 5377 } ); 5378 5379 this.matrix = new Matrix4(); 5380 this.matrixWorld = new Matrix4(); 5381 5382 this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; 5383 this.matrixWorldNeedsUpdate = false;
vendor: 7,965 bytes, lines 5384-5856
5384 5385 this.layers = new Layers(); 5386 this.visible = true; 5387 5388 this.castShadow = false; 5389 this.receiveShadow = false; 5390 5391 this.frustumCulled = true; 5392 this.renderOrder = 0; 5393 5394 this.userData = {}; 5395 5396} 5397 5398Object3D.DefaultUp = new Vector3( 0, 1, 0 ); 5399Object3D.DefaultMatrixAutoUpdate = true; 5400 5401Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { 5402 5403 constructor: Object3D, 5404 5405 isObject3D: true, 5406 5407 onBeforeRender: function () {}, 5408 onAfterRender: function () {}, 5409 5410 applyMatrix4: function ( matrix ) { 5411 5412 if ( this.matrixAutoUpdate ) this.updateMatrix(); 5413 5414 this.matrix.premultiply( matrix ); 5415 5416 this.matrix.decompose( this.position, this.quaternion, this.scale ); 5417 5418 }, 5419 5420 applyQuaternion: function ( q ) { 5421 5422 this.quaternion.premultiply( q ); 5423 5424 return this; 5425 5426 }, 5427 5428 setRotationFromAxisAngle: function ( axis, angle ) { 5429 5430 // assumes axis is normalized 5431 5432 this.quaternion.setFromAxisAngle( axis, angle ); 5433 5434 }, 5435 5436 setRotationFromEuler: function ( euler ) { 5437 5438 this.quaternion.setFromEuler( euler, true ); 5439 5440 }, 5441 5442 setRotationFromMatrix: function ( m ) { 5443 5444 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) 5445 5446 this.quaternion.setFromRotationMatrix( m ); 5447 5448 }, 5449 5450 setRotationFromQuaternion: function ( q ) { 5451 5452 // assumes q is normalized 5453 5454 this.quaternion.copy( q ); 5455 5456 }, 5457 5458 rotateOnAxis: function ( axis, angle ) { 5459 5460 // rotate object on axis in object space 5461 // axis is assumed to be normalized 5462 5463 _q1.setFromAxisAngle( axis, angle ); 5464 5465 this.quaternion.multiply( _q1 ); 5466 5467 return this; 5468 5469 }, 5470 5471 rotateOnWorldAxis: function ( axis, angle ) { 5472 5473 // rotate object on axis in world space 5474 // axis is assumed to be normalized 5475 // method assumes no rotated parent 5476 5477 _q1.setFromAxisAngle( axis, angle ); 5478 5479 this.quaternion.premultiply( _q1 ); 5480 5481 return this; 5482 5483 }, 5484 5485 rotateX: function ( angle ) { 5486 5487 return this.rotateOnAxis( _xAxis, angle ); 5488 5489 }, 5490 5491 rotateY: function ( angle ) { 5492 5493 return this.rotateOnAxis( _yAxis, angle ); 5494 5495 }, 5496 5497 rotateZ: function ( angle ) { 5498 5499 return this.rotateOnAxis( _zAxis, angle ); 5500 5501 }, 5502 5503 translateOnAxis: function ( axis, distance ) { 5504 5505 // translate object by distance along axis in object space 5506 // axis is assumed to be normalized 5507 5508 _v1$1.copy( axis ).applyQuaternion( this.quaternion ); 5509 5510 this.position.add( _v1$1.multiplyScalar( distance ) ); 5511 5512 return this; 5513 5514 }, 5515 5516 translateX: function ( distance ) { 5517 5518 return this.translateOnAxis( _xAxis, distance ); 5519 5520 }, 5521 5522 translateY: function ( distance ) { 5523 5524 return this.translateOnAxis( _yAxis, distance ); 5525 5526 }, 5527 5528 translateZ: function ( distance ) { 5529 5530 return this.translateOnAxis( _zAxis, distance ); 5531 5532 }, 5533 5534 localToWorld: function ( vector ) { 5535 5536 return vector.applyMatrix4( this.matrixWorld ); 5537 5538 }, 5539 5540 worldToLocal: function ( vector ) { 5541 5542 return vector.applyMatrix4( _m1$1.getInverse( this.matrixWorld ) ); 5543 5544 }, 5545 5546 lookAt: function ( x, y, z ) { 5547 5548 // This method does not support objects having non-uniformly-scaled parent(s) 5549 5550 if ( x.isVector3 ) { 5551 5552 _target.copy( x ); 5553 5554 } else { 5555 5556 _target.set( x, y, z ); 5557 5558 } 5559 5560 var parent = this.parent; 5561 5562 this.updateWorldMatrix( true, false ); 5563 5564 _position.setFromMatrixPosition( this.matrixWorld ); 5565 5566 if ( this.isCamera || this.isLight ) { 5567 5568 _m1$1.lookAt( _position, _target, this.up ); 5569 5570 } else { 5571 5572 _m1$1.lookAt( _target, _position, this.up ); 5573 5574 } 5575 5576 this.quaternion.setFromRotationMatrix( _m1$1 ); 5577 5578 if ( parent ) { 5579 5580 _m1$1.extractRotation( parent.matrixWorld ); 5581 _q1.setFromRotationMatrix( _m1$1 ); 5582 this.quaternion.premultiply( _q1.inverse() ); 5583 5584 } 5585 5586 }, 5587 5588 add: function ( object ) { 5589 5590 if ( arguments.length > 1 ) { 5591 5592 for ( var i = 0; i < arguments.length; i ++ ) { 5593 5594 this.add( arguments[ i ] ); 5595 5596 } 5597 5598 return this; 5599 5600 } 5601 5602 if ( object === this ) { 5603 5604 console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object ); 5605 return this; 5606 5607 } 5608 5609 if ( ( object && object.isObject3D ) ) { 5610 5611 if ( object.parent !== null ) { 5612 5613 object.parent.remove( object ); 5614 5615 } 5616 5617 object.parent = this; 5618 this.children.push( object ); 5619 5620 object.dispatchEvent( _addedEvent ); 5621 5622 } else { 5623 5624 console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object ); 5625 5626 } 5627 5628 return this; 5629 5630 }, 5631 5632 remove: function ( object ) { 5633 5634 if ( arguments.length > 1 ) { 5635 5636 for ( var i = 0; i < arguments.length; i ++ ) { 5637 5638 this.remove( arguments[ i ] ); 5639 5640 } 5641 5642 return this; 5643 5644 } 5645 5646 var index = this.children.indexOf( object ); 5647 5648 if ( index !== - 1 ) { 5649 5650 object.parent = null; 5651 this.children.splice( index, 1 ); 5652 5653 object.dispatchEvent( _removedEvent ); 5654 5655 } 5656 5657 return this; 5658 5659 }, 5660 5661 attach: function ( object ) { 5662 5663 // adds object as a child of this, while maintaining the object's world transform 5664 5665 this.updateWorldMatrix( true, false ); 5666 5667 _m1$1.getInverse( this.matrixWorld ); 5668 5669 if ( object.parent !== null ) { 5670 5671 object.parent.updateWorldMatrix( true, false ); 5672 5673 _m1$1.multiply( object.parent.matrixWorld ); 5674 5675 } 5676 5677 object.applyMatrix4( _m1$1 ); 5678 5679 object.updateWorldMatrix( false, false ); 5680 5681 this.add( object ); 5682 5683 return this; 5684 5685 }, 5686 5687 getObjectById: function ( id ) { 5688 5689 return this.getObjectByProperty( 'id', id ); 5690 5691 }, 5692 5693 getObjectByName: function ( name ) { 5694 5695 return this.getObjectByProperty( 'name', name ); 5696 5697 }, 5698 5699 getObjectByProperty: function ( name, value ) { 5700 5701 if ( this[ name ] === value ) return this; 5702 5703 for ( var i = 0, l = this.children.length; i < l; i ++ ) { 5704 5705 var child = this.children[ i ]; 5706 var object = child.getObjectByProperty( name, value ); 5707 5708 if ( object !== undefined ) { 5709 5710 return object; 5711 5712 } 5713 5714 } 5715 5716 return undefined; 5717 5718 }, 5719 5720 getWorldPosition: function ( target ) { 5721 5722 if ( target === undefined ) { 5723 5724 console.warn( 'THREE.Object3D: .getWorldPosition() target is now required' ); 5725 target = new Vector3(); 5726 5727 } 5728 5729 this.updateMatrixWorld( true ); 5730 5731 return target.setFromMatrixPosition( this.matrixWorld ); 5732 5733 }, 5734 5735 getWorldQuaternion: function ( target ) { 5736 5737 if ( target === undefined ) { 5738 5739 console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' ); 5740 target = new Quaternion(); 5741 5742 } 5743 5744 this.updateMatrixWorld( true ); 5745 5746 this.matrixWorld.decompose( _position, target, _scale ); 5747 5748 return target; 5749 5750 }, 5751 5752 getWorldScale: function ( target ) { 5753 5754 if ( target === undefined ) { 5755 5756 console.warn( 'THREE.Object3D: .getWorldScale() target is now required' ); 5757 target = new Vector3(); 5758 5759 } 5760 5761 this.updateMatrixWorld( true ); 5762 5763 this.matrixWorld.decompose( _position, _quaternion$2, target ); 5764 5765 return target; 5766 5767 }, 5768 5769 getWorldDirection: function ( target ) { 5770 5771 if ( target === undefined ) { 5772 5773 console.warn( 'THREE.Object3D: .getWorldDirection() target is now required' ); 5774 target = new Vector3(); 5775 5776 } 5777 5778 this.updateMatrixWorld( true ); 5779 5780 var e = this.matrixWorld.elements; 5781 5782 return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize(); 5783 5784 }, 5785 5786 raycast: function () {}, 5787 5788 traverse: function ( callback ) { 5789 5790 callback( this ); 5791 5792 var children = this.children; 5793 5794 for ( var i = 0, l = children.length; i < l; i ++ ) { 5795 5796 children[ i ].traverse( callback ); 5797 5798 } 5799 5800 }, 5801 5802 traverseVisible: function ( callback ) { 5803 5804 if ( this.visible === false ) return; 5805 5806 callback( this ); 5807 5808 var children = this.children; 5809 5810 for ( var i = 0, l = children.length; i < l; i ++ ) { 5811 5812 children[ i ].traverseVisible( callback ); 5813 5814 } 5815 5816 }, 5817 5818 traverseAncestors: function ( callback ) { 5819 5820 var parent = this.parent; 5821 5822 if ( parent !== null ) { 5823 5824 callback( parent ); 5825 5826 parent.traverseAncestors( callback ); 5827 5828 } 5829 5830 }, 5831 5832 updateMatrix: function () { 5833 5834 this.matrix.compose( this.position, this.quaternion, this.scale ); 5835 5836 this.matrixWorldNeedsUpdate = true; 5837 5838 }, 5839 5840 updateMatrixWorld: function ( force ) { 5841 5842 if ( this.matrixAutoUpdate ) this.updateMatrix(); 5843 5844 if ( this.matrixWorldNeedsUpdate || force ) { 5845 5846 if ( this.parent === null ) { 5847 5848 this.matrixWorld.copy( this.matrix ); 5849 5850 } else { 5851 5852 this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); 5853 5854 } 5855 5856 this.matrixWorldNeedsUpdate = false;
vendor: 6,160 bytes, lines 5857-6170
5857 5858 force = true; 5859 5860 } 5861 5862 // update children 5863 5864 var children = this.children; 5865 5866 for ( var i = 0, l = children.length; i < l; i ++ ) { 5867 5868 children[ i ].updateMatrixWorld( force ); 5869 5870 } 5871 5872 }, 5873 5874 updateWorldMatrix: function ( updateParents, updateChildren ) { 5875 5876 var parent = this.parent; 5877 5878 if ( updateParents === true && parent !== null ) { 5879 5880 parent.updateWorldMatrix( true, false ); 5881 5882 } 5883 5884 if ( this.matrixAutoUpdate ) this.updateMatrix(); 5885 5886 if ( this.parent === null ) { 5887 5888 this.matrixWorld.copy( this.matrix ); 5889 5890 } else { 5891 5892 this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); 5893 5894 } 5895 5896 // update children 5897 5898 if ( updateChildren === true ) { 5899 5900 var children = this.children; 5901 5902 for ( var i = 0, l = children.length; i < l; i ++ ) { 5903 5904 children[ i ].updateWorldMatrix( false, true ); 5905 5906 } 5907 5908 } 5909 5910 }, 5911 5912 toJSON: function ( meta ) { 5913 5914 // meta is a string when called from JSON.stringify 5915 var isRootObject = ( meta === undefined || typeof meta === 'string' ); 5916 5917 var output = {}; 5918 5919 // meta is a hash used to collect geometries, materials. 5920 // not providing it implies that this is the root object 5921 // being serialized. 5922 if ( isRootObject ) { 5923 5924 // initialize meta obj 5925 meta = { 5926 geometries: {}, 5927 materials: {}, 5928 textures: {}, 5929 images: {}, 5930 shapes: {} 5931 }; 5932 5933 output.metadata = { 5934 version: 4.5, 5935 type: 'Object', 5936 generator: 'Object3D.toJSON' 5937 }; 5938 5939 } 5940 5941 // standard Object3D serialization 5942 5943 var object = {}; 5944 5945 object.uuid = this.uuid; 5946 object.type = this.type; 5947 5948 if ( this.name !== '' ) object.name = this.name; 5949 if ( this.castShadow === true ) object.castShadow = true; 5950 if ( this.receiveShadow === true ) object.receiveShadow = true; 5951 if ( this.visible === false ) object.visible = false; 5952 if ( this.frustumCulled === false ) object.frustumCulled = false; 5953 if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder; 5954 if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData; 5955 5956 object.layers = this.layers.mask; 5957 object.matrix = this.matrix.toArray(); 5958 5959 if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false; 5960 5961 // object specific properties 5962 5963 if ( this.isInstancedMesh ) { 5964 5965 object.type = 'InstancedMesh'; 5966 object.count = this.count; 5967 object.instanceMatrix = this.instanceMatrix.toJSON(); 5968 5969 } 5970 5971 // 5972 5973 function serialize( library, element ) { 5974 5975 if ( library[ element.uuid ] === undefined ) { 5976 5977 library[ element.uuid ] = element.toJSON( meta ); 5978 5979 } 5980 5981 return element.uuid; 5982 5983 } 5984 5985 if ( this.isMesh || this.isLine || this.isPoints ) { 5986 5987 object.geometry = serialize( meta.geometries, this.geometry ); 5988 5989 var parameters = this.geometry.parameters; 5990 5991 if ( parameters !== undefined && parameters.shapes !== undefined ) { 5992 5993 var shapes = parameters.shapes; 5994 5995 if ( Array.isArray( shapes ) ) { 5996 5997 for ( var i = 0, l = shapes.length; i < l; i ++ ) { 5998 5999 var shape = shapes[ i ]; 6000 6001 serialize( meta.shapes, shape ); 6002 6003 } 6004 6005 } else { 6006 6007 serialize( meta.shapes, shapes ); 6008 6009 } 6010 6011 } 6012 6013 } 6014 6015 if ( this.material !== undefined ) { 6016 6017 if ( Array.isArray( this.material ) ) { 6018 6019 var uuids = []; 6020 6021 for ( var i = 0, l = this.material.length; i < l; i ++ ) { 6022 6023 uuids.push( serialize( meta.materials, this.material[ i ] ) ); 6024 6025 } 6026 6027 object.material = uuids; 6028 6029 } else { 6030 6031 object.material = serialize( meta.materials, this.material ); 6032 6033 } 6034 6035 } 6036 6037 // 6038 6039 if ( this.children.length > 0 ) { 6040 6041 object.children = []; 6042 6043 for ( var i = 0; i < this.children.length; i ++ ) { 6044 6045 object.children.push( this.children[ i ].toJSON( meta ).object ); 6046 6047 } 6048 6049 } 6050 6051 if ( isRootObject ) { 6052 6053 var geometries = extractFromCache( meta.geometries ); 6054 var materials = extractFromCache( meta.materials ); 6055 var textures = extractFromCache( meta.textures ); 6056 var images = extractFromCache( meta.images ); 6057 var shapes = extractFromCache( meta.shapes ); 6058 6059 if ( geometries.length > 0 ) output.geometries = geometries; 6060 if ( materials.length > 0 ) output.materials = materials; 6061 if ( textures.length > 0 ) output.textures = textures; 6062 if ( images.length > 0 ) output.images = images; 6063 if ( shapes.length > 0 ) output.shapes = shapes; 6064 6065 } 6066 6067 output.object = object; 6068 6069 return output; 6070 6071 // extract data from the cache hash 6072 // remove metadata on each item 6073 // and return as array 6074 function extractFromCache( cache ) { 6075 6076 var values = []; 6077 for ( var key in cache ) { 6078 6079 var data = cache[ key ]; 6080 delete data.metadata; 6081 values.push( data ); 6082 6083 } 6084 6085 return values; 6086 6087 } 6088 6089 }, 6090 6091 clone: function ( recursive ) { 6092 6093 return new this.constructor().copy( this, recursive ); 6094 6095 }, 6096 6097 copy: function ( source, recursive ) { 6098 6099 if ( recursive === undefined ) recursive = true; 6100 6101 this.name = source.name; 6102 6103 this.up.copy( source.up ); 6104 6105 this.position.copy( source.position ); 6106 this.quaternion.copy( source.quaternion ); 6107 this.scale.copy( source.scale ); 6108 6109 this.matrix.copy( source.matrix ); 6110 this.matrixWorld.copy( source.matrixWorld ); 6111 6112 this.matrixAutoUpdate = source.matrixAutoUpdate; 6113 this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; 6114 6115 this.layers.mask = source.layers.mask; 6116 this.visible = source.visible; 6117 6118 this.castShadow = source.castShadow; 6119 this.receiveShadow = source.receiveShadow; 6120 6121 this.frustumCulled = source.frustumCulled; 6122 this.renderOrder = source.renderOrder; 6123 6124 this.userData = JSON.parse( JSON.stringify( source.userData ) ); 6125 6126 if ( recursive === true ) { 6127 6128 for ( var i = 0; i < source.children.length; i ++ ) { 6129 6130 var child = source.children[ i ]; 6131 this.add( child.clone() ); 6132 6133 } 6134 6135 } 6136 6137 return this; 6138 6139 } 6140 6141} ); 6142 6143/** 6144 * @author mrdoob / http://mrdoob.com/ 6145 */ 6146 6147function Scene() { 6148 6149 Object3D.call( this ); 6150 6151 this.type = 'Scene'; 6152 6153 this.background = null; 6154 this.environment = null; 6155 this.fog = null; 6156 6157 this.overrideMaterial = null; 6158 6159 this.autoUpdate = true; // checked by the renderer 6160 6161 if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { 6162 6163 __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); // eslint-disable-line no-undef 6164 6165 } 6166 6167} 6168 6169Scene.prototype = Object.assign( Object.create( Object3D.prototype ), { 6170
6171 constructor: Scene, 6172 6173 isScene: true, 6174 6175 copy: function ( source, recursive ) { 6176 6177 Object3D.prototype.copy.call( this, source, recursive ); 6178 6179 if ( source.background !== null ) this.background = source.background.clone(); 6180 if ( source.environment !== null ) this.environment = source.environment.clone(); 6181 if ( source.fog !== null ) this.fog = source.fog.clone(); 6182 6183 if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone(); 6184 6185 this.autoUpdate = source.autoUpdate; 6186 this.matrixAutoUpdate = source.matrixAutoUpdate; 6187 6188 return this; 6189 6190 }, 6191 6192 toJSON: function ( meta ) { 6193 6194 var data = Object3D.prototype.toJSON.call( this, meta ); 6195 6196 if ( this.background !== null ) data.object.background = this.background.toJSON( meta ); 6197 if ( this.environment !== null ) data.object.environment = this.environment.toJSON( meta ); 6198 if ( this.fog !== null ) data.object.fog = this.fog.toJSON(); 6199 6200 return data; 6201 6202 }, 6203 6204 dispose: function () { 6205 6206 this.dispatchEvent( { type: 'dispose' } ); 6207 6208 } 6209 6210} ); 6211 6212var _points = [ 6213 new Vector3(), 6214 new Vector3(), 6215 new Vector3(), 6216 new Vector3(), 6217 new Vector3(), 6218 new Vector3(), 6219 new Vector3(), 6220 new Vector3() 6221]; 6222 6223var _vector$1 = new Vector3(); 6224 6225var _box = new Box3(); 6226 6227// triangle centered vertices 6228 6229var _v0 = new Vector3(); 6230var _v1$2 = new Vector3(); 6231var _v2 = new Vector3(); 6232 6233// triangle edge vectors 6234 6235var _f0 = new Vector3(); 6236var _f1 = new Vector3(); 6237var _f2 = new Vector3(); 6238 6239var _center = new Vector3(); 6240var _extents = new Vector3(); 6241var _triangleNormal = new Vector3(); 6242var _testAxis = new Vector3(); 6243 6244/** 6245 * @author bhouston / http://clara.io 6246 * @author WestLangley / http://github.com/WestLangley 6247 */ 6248 6249function Box3( min, max ) { 6250 6251 this.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity ); 6252 this.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity ); 6253 6254} 6255 6256 6257Object.assign( Box3.prototype, { 6258 6259 isBox3: true, 6260 6261 set: function ( min, max ) { 6262 6263 this.min.copy( min ); 6264 this.max.copy( max ); 6265 6266 return this; 6267 6268 }, 6269 6270 setFromArray: function ( array ) { 6271 6272 var minX = + Infinity; 6273 var minY = + Infinity; 6274 var minZ = + Infinity; 6275 6276 var maxX = - Infinity; 6277 var maxY = - Infinity; 6278 var maxZ = - Infinity; 6279 6280 for ( var i = 0, l = array.length; i < l; i += 3 ) { 6281 6282 var x = array[ i ]; 6283 var y = array[ i + 1 ]; 6284 var z = array[ i + 2 ]; 6285 6286 if ( x < minX ) minX = x; 6287 if ( y < minY ) minY = y; 6288 if ( z < minZ ) minZ = z; 6289 6290 if ( x > maxX ) maxX = x; 6291 if ( y > maxY ) maxY = y; 6292 if ( z > maxZ ) maxZ = z; 6293 6294 } 6295 6296 this.min.set( minX, minY, minZ ); 6297 this.max.set( maxX, maxY, maxZ ); 6298 6299 return this; 6300 6301 }, 6302 6303 setFromBufferAttribute: function ( attribute ) { 6304 6305 var minX = + Infinity; 6306 var minY = + Infinity; 6307 var minZ = + Infinity; 6308 6309 var maxX = - Infinity; 6310 var maxY = - Infinity; 6311 var maxZ = - Infinity; 6312 6313 for ( var i = 0, l = attribute.count; i < l; i ++ ) { 6314 6315 var x = attribute.getX( i ); 6316 var y = attribute.getY( i ); 6317 var z = attribute.getZ( i ); 6318 6319 if ( x < minX ) minX = x; 6320 if ( y < minY ) minY = y; 6321 if ( z < minZ ) minZ = z; 6322 6323 if ( x > maxX ) maxX = x; 6324 if ( y > maxY ) maxY = y; 6325 if ( z > maxZ ) maxZ = z; 6326 6327 } 6328 6329 this.min.set( minX, minY, minZ ); 6330 this.max.set( maxX, maxY, maxZ ); 6331 6332 return this; 6333 6334 }, 6335 6336 setFromPoints: function ( points ) { 6337 6338 this.makeEmpty(); 6339 6340 for ( var i = 0, il = points.length; i < il; i ++ ) { 6341 6342 this.expandByPoint( points[ i ] ); 6343 6344 } 6345 6346 return this; 6347 6348 }, 6349 6350 setFromCenterAndSize: function ( center, size ) { 6351 6352 var halfSize = _vector$1.copy( size ).multiplyScalar( 0.5 ); 6353 6354 this.min.copy( center ).sub( halfSize ); 6355 this.max.copy( center ).add( halfSize ); 6356 6357 return this; 6358 6359 }, 6360 6361 setFromObject: function ( object ) { 6362 6363 this.makeEmpty(); 6364 6365 return this.expandByObject( object ); 6366 6367 }, 6368 6369 clone: function () { 6370 6371 return new this.constructor().copy( this ); 6372 6373 }, 6374 6375 copy: function ( box ) { 6376 6377 this.min.copy( box.min ); 6378 this.max.copy( box.max ); 6379 6380 return this; 6381 6382 }, 6383 6384 makeEmpty: function () { 6385 6386 this.min.x = this.min.y = this.min.z = + Infinity; 6387 this.max.x = this.max.y = this.max.z = - Infinity; 6388 6389 return this; 6390 6391 }, 6392 6393 isEmpty: function () { 6394 6395 // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes 6396 6397 return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z ); 6398 6399 }, 6400 6401 getCenter: function ( target ) { 6402 6403 if ( target === undefined ) { 6404 6405 console.warn( 'THREE.Box3: .getCenter() target is now required' ); 6406 target = new Vector3(); 6407 6408 } 6409 6410 return this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); 6411 6412 }, 6413 6414 getSize: function ( target ) { 6415 6416 if ( target === undefined ) { 6417 6418 console.warn( 'THREE.Box3: .getSize() target is now required' ); 6419 target = new Vector3(); 6420 6421 } 6422 6423 return this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min ); 6424 6425 }, 6426 6427 expandByPoint: function ( point ) { 6428 6429 this.min.min( point ); 6430 this.max.max( point ); 6431 6432 return this; 6433 6434 }, 6435 6436 expandByVector: function ( vector ) { 6437 6438 this.min.sub( vector ); 6439 this.max.add( vector ); 6440 6441 return this; 6442 6443 }, 6444 6445 expandByScalar: function ( scalar ) { 6446 6447 this.min.addScalar( - scalar ); 6448 this.max.addScalar( scalar ); 6449 6450 return this; 6451 6452 }, 6453 6454 expandByObject: function ( object ) { 6455
6456 // Computes the world-axis-aligned bounding box of an object (including its children), 6457 // accounting for both the object's, and children's, world transforms 6458 6459 object.updateWorldMatrix( false, false ); 6460 6461 var geometry = object.geometry; 6462 6463 if ( geometry !== undefined ) { 6464 6465 if ( geometry.boundingBox === null ) { 6466 6467 geometry.computeBoundingBox(); 6468 6469 } 6470 6471 _box.copy( geometry.boundingBox ); 6472 _box.applyMatrix4( object.matrixWorld ); 6473 6474 this.union( _box ); 6475 6476 } 6477 6478 var children = object.children; 6479 6480 for ( var i = 0, l = children.length; i < l; i ++ ) { 6481 6482 this.expandByObject( children[ i ] ); 6483 6484 } 6485 6486 return this; 6487 6488 }, 6489 6490 containsPoint: function ( point ) { 6491 6492 return point.x < this.min.x || point.x > this.max.x || 6493 point.y < this.min.y || point.y > this.max.y || 6494 point.z < this.min.z || point.z > this.max.z ? false : true; 6495 6496 }, 6497 6498 containsBox: function ( box ) { 6499 6500 return this.min.x <= box.min.x && box.max.x <= this.max.x && 6501 this.min.y <= box.min.y && box.max.y <= this.max.y && 6502 this.min.z <= box.min.z && box.max.z <= this.max.z; 6503 6504 }, 6505 6506 getParameter: function ( point, target ) { 6507 6508 // This can potentially have a divide by zero if the box 6509 // has a size dimension of 0. 6510 6511 if ( target === undefined ) { 6512 6513 console.warn( 'THREE.Box3: .getParameter() target is now required' ); 6514 target = new Vector3(); 6515 6516 } 6517 6518 return target.set( 6519 ( point.x - this.min.x ) / ( this.max.x - this.min.x ), 6520 ( point.y - this.min.y ) / ( this.max.y - this.min.y ), 6521 ( point.z - this.min.z ) / ( this.max.z - this.min.z ) 6522 ); 6523 6524 }, 6525 6526 intersectsBox: function ( box ) { 6527 6528 // using 6 splitting planes to rule out intersections. 6529 return box.max.x < this.min.x || box.min.x > this.max.x || 6530 box.max.y < this.min.y || box.min.y > this.max.y || 6531 box.max.z < this.min.z || box.min.z > this.max.z ? false : true; 6532 6533 }, 6534 6535 intersectsSphere: function ( sphere ) { 6536 6537 // Find the point on the AABB closest to the sphere center. 6538 this.clampPoint( sphere.center, _vector$1 ); 6539 6540 // If that point is inside the sphere, the AABB and sphere intersect. 6541 return _vector$1.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); 6542 6543 }, 6544 6545 intersectsPlane: function ( plane ) { 6546 6547 // We compute the minimum and maximum dot product values. If those values 6548 // are on the same side (back or front) of the plane, then there is no intersection. 6549 6550 var min, max; 6551 6552 if ( plane.normal.x > 0 ) { 6553 6554 min = plane.normal.x * this.min.x; 6555 max = plane.normal.x * this.max.x; 6556 6557 } else { 6558 6559 min = plane.normal.x * this.max.x; 6560 max = plane.normal.x * this.min.x; 6561 6562 } 6563 6564 if ( plane.normal.y > 0 ) { 6565 6566 min += plane.normal.y * this.min.y; 6567 max += plane.normal.y * this.max.y; 6568 6569 } else { 6570 6571 min += plane.normal.y * this.max.y; 6572 max += plane.normal.y * this.min.y; 6573 6574 } 6575 6576 if ( plane.normal.z > 0 ) { 6577 6578 min += plane.normal.z * this.min.z; 6579 max += plane.normal.z * this.max.z; 6580 6581 } else { 6582 6583 min += plane.normal.z * this.max.z; 6584 max += plane.normal.z * this.min.z; 6585 6586 } 6587 6588 return ( min <= - plane.constant && max >= - plane.constant ); 6589 6590 }, 6591 6592 intersectsTriangle: function ( triangle ) { 6593 6594 if ( this.isEmpty() ) { 6595 6596 return false; 6597 6598 } 6599 6600 // compute box center and extents 6601 this.getCenter( _center ); 6602 _extents.subVectors( this.max, _center ); 6603 6604 // translate triangle to aabb origin 6605 _v0.subVectors( triangle.a, _center ); 6606 _v1$2.subVectors( triangle.b, _center ); 6607 _v2.subVectors( triangle.c, _center ); 6608 6609 // compute edge vectors for triangle 6610 _f0.subVectors( _v1$2, _v0 ); 6611 _f1.subVectors( _v2, _v1$2 ); 6612 _f2.subVectors( _v0, _v2 ); 6613 6614 // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb 6615 // 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 6616 // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned) 6617 var axes = [ 6618 0, - _f0.z, _f0.y, 0, - _f1.z, _f1.y, 0, - _f2.z, _f2.y, 6619 _f0.z, 0, - _f0.x, _f1.z, 0, - _f1.x, _f2.z, 0, - _f2.x, 6620 - _f0.y, _f0.x, 0, - _f1.y, _f1.x, 0, - _f2.y, _f2.x, 0 6621 ]; 6622 if ( ! satForAxes( axes, _v0, _v1$2, _v2, _extents ) ) { 6623 6624 return false;
6625 6626 } 6627 6628 // test 3 face normals from the aabb 6629 axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; 6630 if ( ! satForAxes( axes, _v0, _v1$2, _v2, _extents ) ) { 6631 6632 return false; 6633 6634 } 6635 6636 // finally testing the face normal of the triangle 6637 // use already existing triangle edge vectors here 6638 _triangleNormal.crossVectors( _f0, _f1 ); 6639 axes = [ _triangleNormal.x, _triangleNormal.y, _triangleNormal.z ]; 6640 6641 return satForAxes( axes, _v0, _v1$2, _v2, _extents ); 6642 6643 }, 6644 6645 clampPoint: function ( point, target ) { 6646 6647 if ( target === undefined ) { 6648 6649 console.warn( 'THREE.Box3: .clampPoint() target is now required' ); 6650 target = new Vector3(); 6651 6652 } 6653 6654 return target.copy( point ).clamp( this.min, this.max ); 6655 6656 }, 6657 6658 distanceToPoint: function ( point ) { 6659 6660 var clampedPoint = _vector$1.copy( point ).clamp( this.min, this.max ); 6661 6662 return clampedPoint.sub( point ).length(); 6663 6664 }, 6665 6666 getBoundingSphere: function ( target ) { 6667 6668 if ( target === undefined ) { 6669 6670 console.error( 'THREE.Box3: .getBoundingSphere() target is now required' ); 6671 //target = new Sphere(); // removed to avoid cyclic dependency 6672 6673 } 6674 6675 this.getCenter( target.center ); 6676 6677 target.radius = this.getSize( _vector$1 ).length() * 0.5; 6678 6679 return target; 6680 6681 }, 6682 6683 intersect: function ( box ) { 6684 6685 this.min.max( box.min ); 6686 this.max.min( box.max ); 6687 6688 // 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. 6689 if ( this.isEmpty() ) this.makeEmpty(); 6690 6691 return this; 6692 6693 }, 6694 6695 union: function ( box ) { 6696 6697 this.min.min( box.min ); 6698 this.max.max( box.max ); 6699 6700 return this; 6701 6702 }, 6703 6704 applyMatrix4: function ( matrix ) { 6705 6706 // transform of empty box is an empty box. 6707 if ( this.isEmpty() ) return this; 6708 6709 // NOTE: I am using a binary pattern to specify all 2^3 combinations below 6710 _points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000 6711 _points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001 6712 _points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010 6713 _points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011 6714 _points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100 6715 _points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101 6716 _points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110 6717 _points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111 6718 6719 this.setFromPoints( _points ); 6720 6721 return this; 6722 6723 }, 6724 6725 translate: function ( offset ) { 6726 6727 this.min.add( offset ); 6728 this.max.add( offset ); 6729 6730 return this; 6731 6732 }, 6733 6734 equals: function ( box ) { 6735 6736 return box.min.equals( this.min ) && box.max.equals( this.max ); 6737 6738 } 6739 6740} ); 6741 6742function satForAxes( axes, v0, v1, v2, extents ) { 6743 6744 var i, j; 6745 6746 for ( i = 0, j = axes.length - 3; i <= j; i += 3 ) { 6747 6748 _testAxis.fromArray( axes, i ); 6749 // project the aabb onto the seperating axis 6750 var r = extents.x * Math.abs( _testAxis.x ) + extents.y * Math.abs( _testAxis.y ) + extents.z * Math.abs( _testAxis.z ); 6751 // project all 3 vertices of the triangle onto the seperating axis 6752 var p0 = v0.dot( _testAxis ); 6753 var p1 = v1.dot( _testAxis ); 6754 var p2 = v2.dot( _testAxis ); 6755 // actual test, basically see if either of the most extreme of the triangle points intersects r 6756 if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) { 6757 6758 // points of the projected triangle are outside the projected half-length of the aabb 6759 // the axis is seperating and we can exit 6760 return false; 6761 6762 } 6763 6764 } 6765 6766 return true; 6767 6768} 6769 6770var _box$1 = new Box3(); 6771 6772/** 6773 * @author bhouston / http://clara.io 6774 * @author mrdoob / http://mrdoob.com/ 6775 */ 6776 6777function Sphere( center, radius ) { 6778 6779 this.center = ( center !== undefined ) ? center : new Vector3(); 6780 this.radius = ( radius !== undefined ) ? radius : - 1; 6781 6782} 6783 6784Object.assign( Sphere.prototype, { 6785 6786 set: function ( center, radius ) { 6787 6788 this.center.copy( center ); 6789 this.radius = radius; 6790 6791 return this; 6792 6793 }, 6794 6795 setFromPoints: function ( points, optionalCenter ) { 6796 6797 var center = this.center; 6798 6799 if ( optionalCenter !== undefined ) { 6800 6801 center.copy( optionalCenter ); 6802 6803 } else { 6804 6805 _box$1.setFromPoints( points ).getCenter( center ); 6806 6807 } 6808 6809 var maxRadiusSq = 0; 6810 6811 for ( var i = 0, il = points.length; i < il; i ++ ) { 6812 6813 maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) ); 6814 6815 } 6816 6817 this.radius = Math.sqrt( maxRadiusSq ); 6818 6819 return this; 6820 6821 }, 6822 6823 clone: function () { 6824 6825 return new this.constructor().copy( this ); 6826 6827 }, 6828 6829 copy: function ( sphere ) { 6830 6831 this.center.copy( sphere.center ); 6832 this.radius = sphere.radius; 6833 6834 return this; 6835 6836 }, 6837 6838 isEmpty: function () { 6839 6840 return ( this.radius < 0 ); 6841 6842 }, 6843 6844 makeEmpty: function () { 6845 6846 this.center.set( 0, 0, 0 ); 6847 this.radius = - 1; 6848 6849 return this; 6850 6851 }, 6852 6853 containsPoint: function ( point ) { 6854 6855 return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) ); 6856 6857 }, 6858 6859 distanceToPoint: function ( point ) { 6860 6861 return ( point.distanceTo( this.center ) - this.radius ); 6862 6863 }, 6864 6865 intersectsSphere: function ( sphere ) { 6866 6867 var radiusSum = this.radius + sphere.radius; 6868 6869 return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum ); 6870 6871 }, 6872 6873 intersectsBox: function ( box ) { 6874 6875 return box.intersectsSphere( this ); 6876 6877 }, 6878 6879 intersectsPlane: function ( plane ) { 6880 6881 return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius; 6882 6883 }, 6884 6885 clampPoint: function ( point, target ) { 6886 6887 var deltaLengthSq = this.center.distanceToSquared( point ); 6888 6889 if ( target === undefined ) { 6890 6891 console.warn( 'THREE.Sphere: .clampPoint() target is now required' ); 6892 target = new Vector3(); 6893 6894 } 6895 6896 target.copy( point ); 6897 6898 if ( deltaLengthSq > ( this.radius * this.radius ) ) { 6899 6900 target.sub( this.center ).normalize(); 6901 target.multiplyScalar( this.radius ).add( this.center ); 6902 6903 } 6904 6905 return target; 6906 6907 }, 6908 6909 getBoundingBox: function ( target ) { 6910 6911 if ( target === undefined ) { 6912 6913 console.warn( 'THREE.Sphere: .getBoundingBox() target is now required' ); 6914 target = new Box3(); 6915 6916 } 6917 6918 if ( this.isEmpty() ) { 6919 6920 // Empty sphere produces empty bounding box 6921 target.makeEmpty(); 6922 return target; 6923 6924 } 6925 6926 target.set( this.center, this.center ); 6927 target.expandByScalar( this.radius ); 6928 6929 return target; 6930 6931 }, 6932 6933 applyMatrix4: function ( matrix ) { 6934
6935 this.center.applyMatrix4( matrix ); 6936 this.radius = this.radius * matrix.getMaxScaleOnAxis(); 6937 6938 return this; 6939 6940 }, 6941 6942 translate: function ( offset ) { 6943 6944 this.center.add( offset ); 6945 6946 return this; 6947 6948 }, 6949 6950 equals: function ( sphere ) { 6951 6952 return sphere.center.equals( this.center ) && ( sphere.radius === this.radius ); 6953 6954 } 6955 6956} ); 6957 6958var _vector$2 = new Vector3(); 6959var _segCenter = new Vector3(); 6960var _segDir = new Vector3(); 6961var _diff = new Vector3(); 6962 6963var _edge1 = new Vector3(); 6964var _edge2 = new Vector3(); 6965var _normal = new Vector3(); 6966 6967/** 6968 * @author bhouston / http://clara.io 6969 */ 6970 6971function Ray( origin, direction ) { 6972 6973 this.origin = ( origin !== undefined ) ? origin : new Vector3(); 6974 this.direction = ( direction !== undefined ) ? direction : new Vector3( 0, 0, - 1 ); 6975 6976} 6977 6978Object.assign( Ray.prototype, { 6979 6980 set: function ( origin, direction ) { 6981 6982 this.origin.copy( origin ); 6983 this.direction.copy( direction ); 6984 6985 return this; 6986 6987 }, 6988 6989 clone: function () { 6990 6991 return new this.constructor().copy( this ); 6992 6993 }, 6994 6995 copy: function ( ray ) { 6996 6997 this.origin.copy( ray.origin ); 6998 this.direction.copy( ray.direction ); 6999 7000 return this; 7001 7002 }, 7003 7004 at: function ( t, target ) { 7005 7006 if ( target === undefined ) { 7007 7008 console.warn( 'THREE.Ray: .at() target is now required' ); 7009 target = new Vector3(); 7010 7011 } 7012 7013 return target.copy( this.direction ).multiplyScalar( t ).add( this.origin ); 7014 7015 }, 7016 7017 lookAt: function ( v ) { 7018 7019 this.direction.copy( v ).sub( this.origin ).normalize(); 7020 7021 return this; 7022 7023 }, 7024 7025 recast: function ( t ) { 7026 7027 this.origin.copy( this.at( t, _vector$2 ) ); 7028 7029 return this; 7030 7031 }, 7032 7033 closestPointToPoint: function ( point, target ) { 7034 7035 if ( target === undefined ) { 7036 7037 console.warn( 'THREE.Ray: .closestPointToPoint() target is now required' ); 7038 target = new Vector3(); 7039 7040 } 7041 7042 target.subVectors( point, this.origin ); 7043 7044 var directionDistance = target.dot( this.direction ); 7045 7046 if ( directionDistance < 0 ) { 7047 7048 return target.copy( this.origin ); 7049 7050 } 7051 7052 return target.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); 7053 7054 }, 7055 7056 distanceToPoint: function ( point ) { 7057 7058 return Math.sqrt( this.distanceSqToPoint( point ) ); 7059 7060 }, 7061 7062 distanceSqToPoint: function ( point ) { 7063 7064 var directionDistance = _vector$2.subVectors( point, this.origin ).dot( this.direction ); 7065 7066 // point behind the ray 7067 7068 if ( directionDistance < 0 ) { 7069 7070 return this.origin.distanceToSquared( point ); 7071 7072 } 7073 7074 _vector$2.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); 7075 7076 return _vector$2.distanceToSquared( point ); 7077 7078 }, 7079 7080 distanceSqToSegment: function ( v0, v1, optionalPointOnRay, optionalPointOnSegment ) { 7081 7082 // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h 7083 // It returns the min distance between the ray and the segment 7084 // defined by v0 and v1 7085 // It can also set two optional targets : 7086 // - The closest point on the ray 7087 // - The closest point on the segment 7088 7089 _segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 ); 7090 _segDir.copy( v1 ).sub( v0 ).normalize(); 7091 _diff.copy( this.origin ).sub( _segCenter ); 7092 7093 var segExtent = v0.distanceTo( v1 ) * 0.5; 7094 var a01 = - this.direction.dot( _segDir ); 7095 var b0 = _diff.dot( this.direction ); 7096 var b1 = - _diff.dot( _segDir ); 7097 var c = _diff.lengthSq(); 7098 var det = Math.abs( 1 - a01 * a01 ); 7099 var s0, s1, sqrDist, extDet; 7100 7101 if ( det > 0 ) { 7102 7103 // The ray and segment are not parallel. 7104 7105 s0 = a01 * b1 - b0; 7106 s1 = a01 * b0 - b1; 7107 extDet = segExtent * det; 7108 7109 if ( s0 >= 0 ) { 7110 7111 if ( s1 >= - extDet ) { 7112 7113 if ( s1 <= extDet ) { 7114 7115 // region 0 7116 // Minimum at interior points of ray and segment. 7117 7118 var invDet = 1 / det; 7119 s0 *= invDet; 7120 s1 *= invDet; 7121 sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c; 7122 7123 } else { 7124 7125 // region 1 7126 7127 s1 = segExtent; 7128 s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); 7129 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; 7130 7131 } 7132 7133 } else { 7134 7135 // region 5 7136 7137 s1 = - segExtent; 7138 s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); 7139 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; 7140 7141 } 7142 7143 } else { 7144 7145 if ( s1 <= - extDet ) { 7146 7147 // region 4 7148 7149 s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) ); 7150 s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); 7151 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; 7152 7153 } else if ( s1 <= extDet ) { 7154 7155 // region 3 7156 7157 s0 = 0; 7158 s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent ); 7159 sqrDist = s1 * ( s1 + 2 * b1 ) + c; 7160 7161 } else { 7162 7163 // region 2 7164 7165 s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); 7166 s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); 7167 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; 7168 7169 } 7170 7171 } 7172 7173 } else { 7174 7175 // Ray and segment are parallel. 7176 7177 s1 = ( a01 > 0 ) ? - segExtent : segExtent; 7178 s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); 7179 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; 7180 7181 } 7182 7183 if ( optionalPointOnRay ) { 7184 7185 optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin ); 7186 7187 } 7188 7189 if ( optionalPointOnSegment ) { 7190 7191 optionalPointOnSegment.copy( _segDir ).multiplyScalar( s1 ).add( _segCenter ); 7192 7193 } 7194 7195 return sqrDist; 7196 7197 }, 7198 7199 intersectSphere: function ( sphere, target ) { 7200 7201 _vector$2.subVectors( sphere.center, this.origin ); 7202 var tca = _vector$2.dot( this.direction ); 7203 var d2 = _vector$2.dot( _vector$2 ) - tca * tca; 7204 var radius2 = sphere.radius * sphere.radius; 7205 7206 if ( d2 > radius2 ) return null; 7207 7208 var thc = Math.sqrt( radius2 - d2 ); 7209 7210 // t0 = first intersect point - entrance on front of sphere 7211 var t0 = tca - thc; 7212 7213 // t1 = second intersect point - exit point on back of sphere 7214 var t1 = tca + thc; 7215 7216 // test to see if both t0 and t1 are behind the ray - if so, return null 7217 if ( t0 < 0 && t1 < 0 ) return null; 7218 7219 // test to see if t0 is behind the ray: 7220 // if it is, the ray is inside the sphere, so return the second exit point scaled by t1, 7221 // in order to always return an intersect point that is in front of the ray.
vendor: 4,311 bytes, lines 7222-7437
7222 if ( t0 < 0 ) return this.at( t1, target ); 7223 7224 // else t0 is in front of the ray, so return the first collision point scaled by t0 7225 return this.at( t0, target ); 7226 7227 }, 7228 7229 intersectsSphere: function ( sphere ) { 7230 7231 return this.distanceSqToPoint( sphere.center ) <= ( sphere.radius * sphere.radius ); 7232 7233 }, 7234 7235 distanceToPlane: function ( plane ) { 7236 7237 var denominator = plane.normal.dot( this.direction ); 7238 7239 if ( denominator === 0 ) { 7240 7241 // line is coplanar, return origin 7242 if ( plane.distanceToPoint( this.origin ) === 0 ) { 7243 7244 return 0; 7245 7246 } 7247 7248 // Null is preferable to undefined since undefined means.... it is undefined 7249 7250 return null; 7251 7252 } 7253 7254 var t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator; 7255 7256 // Return if the ray never intersects the plane 7257 7258 return t >= 0 ? t : null; 7259 7260 }, 7261 7262 intersectPlane: function ( plane, target ) { 7263 7264 var t = this.distanceToPlane( plane ); 7265 7266 if ( t === null ) { 7267 7268 return null; 7269 7270 } 7271 7272 return this.at( t, target ); 7273 7274 }, 7275 7276 intersectsPlane: function ( plane ) { 7277 7278 // check if the ray lies on the plane first 7279 7280 var distToPoint = plane.distanceToPoint( this.origin ); 7281 7282 if ( distToPoint === 0 ) { 7283 7284 return true; 7285 7286 } 7287 7288 var denominator = plane.normal.dot( this.direction ); 7289 7290 if ( denominator * distToPoint < 0 ) { 7291 7292 return true; 7293 7294 } 7295 7296 // ray origin is behind the plane (and is pointing behind it) 7297 7298 return false; 7299 7300 }, 7301 7302 intersectBox: function ( box, target ) { 7303 7304 var tmin, tmax, tymin, tymax, tzmin, tzmax; 7305 7306 var invdirx = 1 / this.direction.x, 7307 invdiry = 1 / this.direction.y, 7308 invdirz = 1 / this.direction.z; 7309 7310 var origin = this.origin; 7311 7312 if ( invdirx >= 0 ) { 7313 7314 tmin = ( box.min.x - origin.x ) * invdirx; 7315 tmax = ( box.max.x - origin.x ) * invdirx; 7316 7317 } else { 7318 7319 tmin = ( box.max.x - origin.x ) * invdirx; 7320 tmax = ( box.min.x - origin.x ) * invdirx; 7321 7322 } 7323 7324 if ( invdiry >= 0 ) { 7325 7326 tymin = ( box.min.y - origin.y ) * invdiry; 7327 tymax = ( box.max.y - origin.y ) * invdiry; 7328 7329 } else { 7330 7331 tymin = ( box.max.y - origin.y ) * invdiry; 7332 tymax = ( box.min.y - origin.y ) * invdiry; 7333 7334 } 7335 7336 if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null; 7337 7338 // These lines also handle the case where tmin or tmax is NaN 7339 // (result of 0 * Infinity). x !== x returns true if x is NaN 7340 7341 if ( tymin > tmin || tmin !== tmin ) tmin = tymin; 7342 7343 if ( tymax < tmax || tmax !== tmax ) tmax = tymax; 7344 7345 if ( invdirz >= 0 ) { 7346 7347 tzmin = ( box.min.z - origin.z ) * invdirz; 7348 tzmax = ( box.max.z - origin.z ) * invdirz; 7349 7350 } else { 7351 7352 tzmin = ( box.max.z - origin.z ) * invdirz; 7353 tzmax = ( box.min.z - origin.z ) * invdirz; 7354 7355 } 7356 7357 if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null; 7358 7359 if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin; 7360 7361 if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax; 7362 7363 //return point closest to the ray (positive side) 7364 7365 if ( tmax < 0 ) return null; 7366 7367 return this.at( tmin >= 0 ? tmin : tmax, target ); 7368 7369 }, 7370 7371 intersectsBox: function ( box ) { 7372 7373 return this.intersectBox( box, _vector$2 ) !== null; 7374 7375 }, 7376 7377 intersectTriangle: function ( a, b, c, backfaceCulling, target ) { 7378 7379 // Compute the offset origin, edges, and normal. 7380 7381 // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h 7382 7383 _edge1.subVectors( b, a ); 7384 _edge2.subVectors( c, a ); 7385 _normal.crossVectors( _edge1, _edge2 ); 7386 7387 // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, 7388 // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by 7389 // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) 7390 // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) 7391 // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) 7392 var DdN = this.direction.dot( _normal ); 7393 var sign; 7394 7395 if ( DdN > 0 ) { 7396 7397 if ( backfaceCulling ) return null; 7398 sign = 1; 7399 7400 } else if ( DdN < 0 ) { 7401 7402 sign = - 1; 7403 DdN = - DdN; 7404 7405 } else { 7406 7407 return null; 7408 7409 } 7410 7411 _diff.subVectors( this.origin, a ); 7412 var DdQxE2 = sign * this.direction.dot( _edge2.crossVectors( _diff, _edge2 ) ); 7413 7414 // b1 < 0, no intersection 7415 if ( DdQxE2 < 0 ) { 7416 7417 return null; 7418 7419 } 7420 7421 var DdE1xQ = sign * this.direction.dot( _edge1.cross( _diff ) ); 7422 7423 // b2 < 0, no intersection 7424 if ( DdE1xQ < 0 ) { 7425 7426 return null; 7427 7428 } 7429 7430 // b1+b2 > 1, no intersection 7431 if ( DdQxE2 + DdE1xQ > DdN ) { 7432 7433 return null; 7434 7435 } 7436 7437 // Line intersects triangle, check if ray does.
7438 var QdN = - sign * _diff.dot( _normal ); 7439 7440 // t < 0, no intersection 7441 if ( QdN < 0 ) { 7442 7443 return null; 7444 7445 } 7446 7447 // Ray intersects triangle. 7448 return this.at( QdN / DdN, target ); 7449 7450 }, 7451 7452 applyMatrix4: function ( matrix4 ) { 7453 7454 this.origin.applyMatrix4( matrix4 ); 7455 this.direction.transformDirection( matrix4 ); 7456 7457 return this; 7458 7459 }, 7460 7461 equals: function ( ray ) { 7462 7463 return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction ); 7464 7465 } 7466 7467} ); 7468 7469/** 7470 * @author bhouston / http://clara.io 7471 */ 7472 7473var _vector1 = new Vector3(); 7474var _vector2 = new Vector3(); 7475var _normalMatrix = new Matrix3(); 7476 7477function Plane( normal, constant ) { 7478 7479 // normal is assumed to be normalized 7480 7481 this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 ); 7482 this.constant = ( constant !== undefined ) ? constant : 0; 7483 7484} 7485 7486Object.assign( Plane.prototype, { 7487 7488 isPlane: true, 7489 7490 set: function ( normal, constant ) { 7491 7492 this.normal.copy( normal ); 7493 this.constant = constant; 7494 7495 return this; 7496 7497 }, 7498 7499 setComponents: function ( x, y, z, w ) { 7500 7501 this.normal.set( x, y, z ); 7502 this.constant = w; 7503 7504 return this; 7505 7506 }, 7507 7508 setFromNormalAndCoplanarPoint: function ( normal, point ) { 7509 7510 this.normal.copy( normal ); 7511 this.constant = - point.dot( this.normal ); 7512 7513 return this; 7514 7515 }, 7516 7517 setFromCoplanarPoints: function ( a, b, c ) { 7518 7519 var normal = _vector1.subVectors( c, b ).cross( _vector2.subVectors( a, b ) ).normalize(); 7520 7521 // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? 7522 7523 this.setFromNormalAndCoplanarPoint( normal, a ); 7524 7525 return this; 7526 7527 }, 7528 7529 clone: function () { 7530 7531 return new this.constructor().copy( this ); 7532 7533 }, 7534 7535 copy: function ( plane ) { 7536 7537 this.normal.copy( plane.normal ); 7538 this.constant = plane.constant; 7539 7540 return this; 7541 7542 }, 7543 7544 normalize: function () { 7545 7546 // Note: will lead to a divide by zero if the plane is invalid. 7547 7548 var inverseNormalLength = 1.0 / this.normal.length(); 7549 this.normal.multiplyScalar( inverseNormalLength ); 7550 this.constant *= inverseNormalLength; 7551 7552 return this; 7553 7554 }, 7555 7556 negate: function () { 7557 7558 this.constant *= - 1; 7559 this.normal.negate(); 7560 7561 return this; 7562 7563 }, 7564 7565 distanceToPoint: function ( point ) { 7566 7567 return this.normal.dot( point ) + this.constant; 7568 7569 }, 7570 7571 distanceToSphere: function ( sphere ) { 7572 7573 return this.distanceToPoint( sphere.center ) - sphere.radius; 7574 7575 }, 7576 7577 projectPoint: function ( point, target ) { 7578 7579 if ( target === undefined ) { 7580 7581 console.warn( 'THREE.Plane: .projectPoint() target is now required' ); 7582 target = new Vector3(); 7583 7584 } 7585 7586 return target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point ); 7587 7588 }, 7589 7590 intersectLine: function ( line, target ) { 7591 7592 if ( target === undefined ) { 7593 7594 console.warn( 'THREE.Plane: .intersectLine() target is now required' ); 7595 target = new Vector3(); 7596 7597 } 7598 7599 var direction = line.delta( _vector1 ); 7600 7601 var denominator = this.normal.dot( direction ); 7602 7603 if ( denominator === 0 ) { 7604 7605 // line is coplanar, return origin 7606 if ( this.distanceToPoint( line.start ) === 0 ) { 7607 7608 return target.copy( line.start ); 7609 7610 } 7611 7612 // Unsure if this is the correct method to handle this case. 7613 return undefined; 7614 7615 } 7616 7617 var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; 7618 7619 if ( t < 0 || t > 1 ) { 7620 7621 return undefined; 7622 7623 } 7624 7625 return target.copy( direction ).multiplyScalar( t ).add( line.start ); 7626 7627 }, 7628 7629 intersectsLine: function ( line ) { 7630 7631 // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. 7632 7633 var startSign = this.distanceToPoint( line.start ); 7634 var endSign = this.distanceToPoint( line.end ); 7635 7636 return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 ); 7637 7638 }, 7639 7640 intersectsBox: function ( box ) { 7641 7642 return box.intersectsPlane( this ); 7643 7644 }, 7645 7646 intersectsSphere: function ( sphere ) { 7647 7648 return sphere.intersectsPlane( this ); 7649 7650 }, 7651 7652 coplanarPoint: function ( target ) { 7653 7654 if ( target === undefined ) { 7655 7656 console.warn( 'THREE.Plane: .coplanarPoint() target is now required' ); 7657 target = new Vector3(); 7658 7659 } 7660 7661 return target.copy( this.normal ).multiplyScalar( - this.constant ); 7662 7663 }, 7664 7665 applyMatrix4: function ( matrix, optionalNormalMatrix ) { 7666 7667 var normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix( matrix ); 7668 7669 var referencePoint = this.coplanarPoint( _vector1 ).applyMatrix4( matrix ); 7670
7671 var normal = this.normal.applyMatrix3( normalMatrix ).normalize(); 7672 7673 this.constant = - referencePoint.dot( normal ); 7674 7675 return this; 7676 7677 }, 7678 7679 translate: function ( offset ) { 7680 7681 this.constant -= offset.dot( this.normal ); 7682 7683 return this; 7684 7685 }, 7686 7687 equals: function ( plane ) { 7688 7689 return plane.normal.equals( this.normal ) && ( plane.constant === this.constant ); 7690 7691 } 7692 7693} ); 7694 7695/** 7696 * @author bhouston / http://clara.io 7697 * @author mrdoob / http://mrdoob.com/ 7698 */ 7699 7700var _v0$1 = new Vector3(); 7701var _v1$3 = new Vector3(); 7702var _v2$1 = new Vector3(); 7703var _v3 = new Vector3(); 7704 7705var _vab = new Vector3(); 7706var _vac = new Vector3(); 7707var _vbc = new Vector3(); 7708var _vap = new Vector3(); 7709var _vbp = new Vector3(); 7710var _vcp = new Vector3(); 7711 7712function Triangle( a, b, c ) { 7713 7714 this.a = ( a !== undefined ) ? a : new Vector3(); 7715 this.b = ( b !== undefined ) ? b : new Vector3(); 7716 this.c = ( c !== undefined ) ? c : new Vector3(); 7717 7718} 7719 7720Object.assign( Triangle, { 7721 7722 getNormal: function ( a, b, c, target ) { 7723 7724 if ( target === undefined ) { 7725 7726 console.warn( 'THREE.Triangle: .getNormal() target is now required' ); 7727 target = new Vector3(); 7728 7729 } 7730 7731 target.subVectors( c, b ); 7732 _v0$1.subVectors( a, b ); 7733 target.cross( _v0$1 ); 7734 7735 var targetLengthSq = target.lengthSq(); 7736 if ( targetLengthSq > 0 ) { 7737 7738 return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) ); 7739 7740 } 7741 7742 return target.set( 0, 0, 0 ); 7743 7744 }, 7745 7746 // static/instance method to calculate barycentric coordinates 7747 // based on: http://www.blackpawn.com/texts/pointinpoly/default.html 7748 getBarycoord: function ( point, a, b, c, target ) { 7749 7750 _v0$1.subVectors( c, a ); 7751 _v1$3.subVectors( b, a ); 7752 _v2$1.subVectors( point, a ); 7753 7754 var dot00 = _v0$1.dot( _v0$1 ); 7755 var dot01 = _v0$1.dot( _v1$3 ); 7756 var dot02 = _v0$1.dot( _v2$1 ); 7757 var dot11 = _v1$3.dot( _v1$3 ); 7758 var dot12 = _v1$3.dot( _v2$1 ); 7759 7760 var denom = ( dot00 * dot11 - dot01 * dot01 ); 7761 7762 if ( target === undefined ) { 7763 7764 console.warn( 'THREE.Triangle: .getBarycoord() target is now required' ); 7765 target = new Vector3(); 7766 7767 } 7768 7769 // collinear or singular triangle 7770 if ( denom === 0 ) { 7771 7772 // arbitrary location outside of triangle? 7773 // not sure if this is the best idea, maybe should be returning undefined 7774 return target.set( - 2, - 1, - 1 ); 7775 7776 } 7777 7778 var invDenom = 1 / denom; 7779 var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; 7780 var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; 7781 7782 // barycentric coordinates must always sum to 1 7783 return target.set( 1 - u - v, v, u ); 7784 7785 }, 7786 7787 containsPoint: function ( point, a, b, c ) { 7788 7789 Triangle.getBarycoord( point, a, b, c, _v3 ); 7790 7791 return ( _v3.x >= 0 ) && ( _v3.y >= 0 ) && ( ( _v3.x + _v3.y ) <= 1 ); 7792 7793 }, 7794 7795 getUV: function ( point, p1, p2, p3, uv1, uv2, uv3, target ) { 7796 7797 this.getBarycoord( point, p1, p2, p3, _v3 ); 7798 7799 target.set( 0, 0 ); 7800 target.addScaledVector( uv1, _v3.x ); 7801 target.addScaledVector( uv2, _v3.y ); 7802 target.addScaledVector( uv3, _v3.z ); 7803 7804 return target; 7805 7806 }, 7807 7808 isFrontFacing: function ( a, b, c, direction ) { 7809 7810 _v0$1.subVectors( c, b ); 7811 _v1$3.subVectors( a, b ); 7812 7813 // strictly front facing 7814 return ( _v0$1.cross( _v1$3 ).dot( direction ) < 0 ) ? true : false; 7815 7816 } 7817 7818} ); 7819 7820Object.assign( Triangle.prototype, { 7821 7822 set: function ( a, b, c ) { 7823 7824 this.a.copy( a ); 7825 this.b.copy( b ); 7826 this.c.copy( c ); 7827 7828 return this; 7829 7830 }, 7831 7832 setFromPointsAndIndices: function ( points, i0, i1, i2 ) { 7833 7834 this.a.copy( points[ i0 ] ); 7835 this.b.copy( points[ i1 ] ); 7836 this.c.copy( points[ i2 ] ); 7837 7838 return this; 7839 7840 }, 7841 7842 clone: function () { 7843 7844 return new this.constructor().copy( this ); 7845 7846 }, 7847 7848 copy: function ( triangle ) { 7849 7850 this.a.copy( triangle.a ); 7851 this.b.copy( triangle.b ); 7852 this.c.copy( triangle.c ); 7853 7854 return this; 7855 7856 }, 7857 7858 getArea: function () { 7859 7860 _v0$1.subVectors( this.c, this.b ); 7861 _v1$3.subVectors( this.a, this.b ); 7862 7863 return _v0$1.cross( _v1$3 ).length() * 0.5; 7864 7865 }, 7866 7867 getMidpoint: function ( target ) { 7868 7869 if ( target === undefined ) { 7870 7871 console.warn( 'THREE.Triangle: .getMidpoint() target is now required' ); 7872 target = new Vector3(); 7873 7874 } 7875 7876 return target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 ); 7877 7878 }, 7879 7880 getNormal: function ( target ) { 7881 7882 return Triangle.getNormal( this.a, this.b, this.c, target ); 7883 7884 }, 7885 7886 getPlane: function ( target ) { 7887 7888 if ( target === undefined ) { 7889 7890 console.warn( 'THREE.Triangle: .getPlane() target is now required' ); 7891 target = new Plane(); 7892 7893 } 7894 7895 return target.setFromCoplanarPoints( this.a, this.b, this.c ); 7896 7897 }, 7898 7899 getBarycoord: function ( point, target ) { 7900 7901 return Triangle.getBarycoord( point, this.a, this.b, this.c, target ); 7902 7903 }, 7904 7905 getUV: function ( point, uv1, uv2, uv3, target ) { 7906 7907 return Triangle.getUV( point, this.a, this.b, this.c, uv1, uv2, uv3, target ); 7908 7909 }, 7910 7911 containsPoint: function ( point ) { 7912 7913 return Triangle.containsPoint( point, this.a, this.b, this.c ); 7914 7915 }, 7916 7917 isFrontFacing: function ( direction ) { 7918 7919 return Triangle.isFrontFacing( this.a, this.b, this.c, direction ); 7920 7921 }, 7922 7923 intersectsBox: function ( box ) { 7924 7925 return box.intersectsTriangle( this ); 7926 7927 }, 7928 7929 closestPointToPoint: function ( p, target ) { 7930 7931 if ( target === undefined ) { 7932 7933 console.warn( 'THREE.Triangle: .closestPointToPoint() target is now required' ); 7934 target = new Vector3(); 7935 7936 } 7937 7938 var a = this.a, b = this.b, c = this.c; 7939 var v, w; 7940 7941 // algorithm thanks to Real-Time Collision Detection by Christer Ericson, 7942 // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc., 7943 // under the accompanying license; see chapter 5.1.5 for detailed explanation.
7944 // basically, we're distinguishing which of the voronoi regions of the triangle 7945 // the point lies in with the minimum amount of redundant computation. 7946 7947 _vab.subVectors( b, a ); 7948 _vac.subVectors( c, a ); 7949 _vap.subVectors( p, a ); 7950 var d1 = _vab.dot( _vap ); 7951 var d2 = _vac.dot( _vap ); 7952 if ( d1 <= 0 && d2 <= 0 ) { 7953 7954 // vertex region of A; barycentric coords (1, 0, 0) 7955 return target.copy( a ); 7956 7957 } 7958 7959 _vbp.subVectors( p, b ); 7960 var d3 = _vab.dot( _vbp ); 7961 var d4 = _vac.dot( _vbp ); 7962 if ( d3 >= 0 && d4 <= d3 ) { 7963 7964 // vertex region of B; barycentric coords (0, 1, 0) 7965 return target.copy( b ); 7966 7967 } 7968 7969 var vc = d1 * d4 - d3 * d2; 7970 if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) { 7971 7972 v = d1 / ( d1 - d3 ); 7973 // edge region of AB; barycentric coords (1-v, v, 0) 7974 return target.copy( a ).addScaledVector( _vab, v ); 7975 7976 } 7977 7978 _vcp.subVectors( p, c ); 7979 var d5 = _vab.dot( _vcp ); 7980 var d6 = _vac.dot( _vcp ); 7981 if ( d6 >= 0 && d5 <= d6 ) { 7982 7983 // vertex region of C; barycentric coords (0, 0, 1) 7984 return target.copy( c ); 7985 7986 } 7987 7988 var vb = d5 * d2 - d1 * d6; 7989 if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) { 7990 7991 w = d2 / ( d2 - d6 ); 7992 // edge region of AC; barycentric coords (1-w, 0, w) 7993 return target.copy( a ).addScaledVector( _vac, w ); 7994 7995 } 7996 7997 var va = d3 * d6 - d5 * d4; 7998 if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) { 7999 8000 _vbc.subVectors( c, b ); 8001 w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) ); 8002 // edge region of BC; barycentric coords (0, 1-w, w) 8003 return target.copy( b ).addScaledVector( _vbc, w ); // edge region of BC 8004 8005 } 8006 8007 // face region 8008 var denom = 1 / ( va + vb + vc ); 8009 // u = va * denom 8010 v = vb * denom; 8011 w = vc * denom; 8012 8013 return target.copy( a ).addScaledVector( _vab, v ).addScaledVector( _vac, w ); 8014 8015 }, 8016 8017 equals: function ( triangle ) { 8018 8019 return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); 8020 8021 } 8022 8023} ); 8024 8025/** 8026 * @author mrdoob / http://mrdoob.com/ 8027 */ 8028 8029var _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, 8030 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, 8031 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, 8032 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, 8033 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B, 8034 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F, 8035 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3, 8036 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222, 8037 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700, 8038 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4, 8039 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00, 8040 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3, 8041 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA, 8042 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32, 8043 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3, 8044 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC, 8045 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD, 8046 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6, 8047 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9, 8048 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,
vendor: 5,188 bytes, lines 8049-8306
8049 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE, 8050 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA, 8051 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, 8052 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; 8053 8054var _hslA = { h: 0, s: 0, l: 0 }; 8055var _hslB = { h: 0, s: 0, l: 0 }; 8056 8057function Color( r, g, b ) { 8058 8059 if ( g === undefined && b === undefined ) { 8060 8061 // r is THREE.Color, hex or string 8062 return this.set( r ); 8063 8064 } 8065 8066 return this.setRGB( r, g, b ); 8067 8068} 8069 8070function hue2rgb( p, q, t ) { 8071 8072 if ( t < 0 ) t += 1; 8073 if ( t > 1 ) t -= 1; 8074 if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t; 8075 if ( t < 1 / 2 ) return q; 8076 if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t ); 8077 return p; 8078 8079} 8080 8081function SRGBToLinear( c ) { 8082 8083 return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 ); 8084 8085} 8086 8087function LinearToSRGB( c ) { 8088 8089 return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055; 8090 8091} 8092 8093Object.assign( Color.prototype, { 8094 8095 isColor: true, 8096 8097 r: 1, g: 1, b: 1, 8098 8099 set: function ( value ) { 8100 8101 if ( value && value.isColor ) { 8102 8103 this.copy( value ); 8104 8105 } else if ( typeof value === 'number' ) { 8106 8107 this.setHex( value ); 8108 8109 } else if ( typeof value === 'string' ) { 8110 8111 this.setStyle( value ); 8112 8113 } 8114 8115 return this; 8116 8117 }, 8118 8119 setScalar: function ( scalar ) { 8120 8121 this.r = scalar; 8122 this.g = scalar; 8123 this.b = scalar; 8124 8125 return this; 8126 8127 }, 8128 8129 setHex: function ( hex ) { 8130 8131 hex = Math.floor( hex ); 8132 8133 this.r = ( hex >> 16 & 255 ) / 255; 8134 this.g = ( hex >> 8 & 255 ) / 255; 8135 this.b = ( hex & 255 ) / 255; 8136 8137 return this; 8138 8139 }, 8140 8141 setRGB: function ( r, g, b ) { 8142 8143 this.r = r; 8144 this.g = g; 8145 this.b = b; 8146 8147 return this; 8148 8149 }, 8150 8151 setHSL: function ( h, s, l ) { 8152 8153 // h,s,l ranges are in 0.0 - 1.0 8154 h = MathUtils.euclideanModulo( h, 1 ); 8155 s = MathUtils.clamp( s, 0, 1 ); 8156 l = MathUtils.clamp( l, 0, 1 ); 8157 8158 if ( s === 0 ) { 8159 8160 this.r = this.g = this.b = l; 8161 8162 } else { 8163 8164 var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s ); 8165 var q = ( 2 * l ) - p; 8166 8167 this.r = hue2rgb( q, p, h + 1 / 3 ); 8168 this.g = hue2rgb( q, p, h ); 8169 this.b = hue2rgb( q, p, h - 1 / 3 ); 8170 8171 } 8172 8173 return this; 8174 8175 }, 8176 8177 setStyle: function ( style ) { 8178 8179 function handleAlpha( string ) { 8180 8181 if ( string === undefined ) return; 8182 8183 if ( parseFloat( string ) < 1 ) { 8184 8185 console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' ); 8186 8187 } 8188 8189 } 8190 8191 8192 var m; 8193 8194 if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) { 8195 8196 // rgb / hsl 8197 8198 var color; 8199 var name = m[ 1 ]; 8200 var components = m[ 2 ]; 8201 8202 switch ( name ) { 8203 8204 case 'rgb': 8205 case 'rgba': 8206 8207 if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { 8208 8209 // rgb(255,0,0) rgba(255,0,0,0.5) 8210 this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255; 8211 this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255; 8212 this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255; 8213 8214 handleAlpha( color[ 5 ] ); 8215 8216 return this; 8217 8218 } 8219 8220 if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { 8221 8222 // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) 8223 this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100; 8224 this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100; 8225 this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100; 8226 8227 handleAlpha( color[ 5 ] ); 8228 8229 return this; 8230 8231 } 8232 8233 break; 8234 8235 case 'hsl': 8236 case 'hsla': 8237 8238 if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { 8239 8240 // hsl(120,50%,50%) hsla(120,50%,50%,0.5) 8241 var h = parseFloat( color[ 1 ] ) / 360; 8242 var s = parseInt( color[ 2 ], 10 ) / 100; 8243 var l = parseInt( color[ 3 ], 10 ) / 100; 8244 8245 handleAlpha( color[ 5 ] ); 8246 8247 return this.setHSL( h, s, l ); 8248 8249 } 8250 8251 break; 8252 8253 } 8254 8255 } else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) { 8256 8257 // hex color 8258 8259 var hex = m[ 1 ]; 8260 var size = hex.length; 8261 8262 if ( size === 3 ) { 8263 8264 // #ff0 8265 this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255; 8266 this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255; 8267 this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255; 8268 8269 return this; 8270 8271 } else if ( size === 6 ) { 8272 8273 // #ff0000 8274 this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255; 8275 this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255; 8276 this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255; 8277 8278 return this; 8279 8280 } 8281 8282 } 8283 8284 if ( style && style.length > 0 ) { 8285 8286 return this.setColorName( style ); 8287 8288 } 8289 8290 return this; 8291 8292 }, 8293 8294 setColorName: function ( style ) { 8295 8296 // color keywords 8297 var hex = _colorKeywords[ style ]; 8298 8299 if ( hex !== undefined ) { 8300 8301 // red 8302 this.setHex( hex ); 8303 8304 } else { 8305 8306 // unknown color
8307 console.warn( 'THREE.Color: Unknown color ' + style ); 8308 8309 } 8310 8311 return this; 8312 8313 }, 8314 8315 clone: function () { 8316 8317 return new this.constructor( this.r, this.g, this.b ); 8318 8319 }, 8320 8321 copy: function ( color ) { 8322 8323 this.r = color.r; 8324 this.g = color.g; 8325 this.b = color.b; 8326 8327 return this; 8328 8329 }, 8330 8331 copyGammaToLinear: function ( color, gammaFactor ) { 8332 8333 if ( gammaFactor === undefined ) gammaFactor = 2.0; 8334 8335 this.r = Math.pow( color.r, gammaFactor ); 8336 this.g = Math.pow( color.g, gammaFactor ); 8337 this.b = Math.pow( color.b, gammaFactor ); 8338 8339 return this; 8340 8341 }, 8342 8343 copyLinearToGamma: function ( color, gammaFactor ) { 8344 8345 if ( gammaFactor === undefined ) gammaFactor = 2.0; 8346 8347 var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0; 8348 8349 this.r = Math.pow( color.r, safeInverse ); 8350 this.g = Math.pow( color.g, safeInverse ); 8351 this.b = Math.pow( color.b, safeInverse ); 8352 8353 return this; 8354 8355 }, 8356 8357 convertGammaToLinear: function ( gammaFactor ) { 8358 8359 this.copyGammaToLinear( this, gammaFactor ); 8360 8361 return this; 8362 8363 }, 8364 8365 convertLinearToGamma: function ( gammaFactor ) { 8366 8367 this.copyLinearToGamma( this, gammaFactor ); 8368 8369 return this; 8370 8371 }, 8372 8373 copySRGBToLinear: function ( color ) { 8374 8375 this.r = SRGBToLinear( color.r ); 8376 this.g = SRGBToLinear( color.g ); 8377 this.b = SRGBToLinear( color.b ); 8378 8379 return this; 8380 8381 }, 8382 8383 copyLinearToSRGB: function ( color ) { 8384 8385 this.r = LinearToSRGB( color.r ); 8386 this.g = LinearToSRGB( color.g ); 8387 this.b = LinearToSRGB( color.b ); 8388 8389 return this; 8390 8391 }, 8392 8393 convertSRGBToLinear: function () { 8394 8395 this.copySRGBToLinear( this ); 8396 8397 return this; 8398 8399 }, 8400 8401 convertLinearToSRGB: function () { 8402 8403 this.copyLinearToSRGB( this ); 8404 8405 return this; 8406 8407 }, 8408 8409 getHex: function () { 8410 8411 return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0; 8412 8413 }, 8414 8415 getHexString: function () { 8416 8417 return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 ); 8418 8419 }, 8420 8421 getHSL: function ( target ) { 8422 8423 // h,s,l ranges are in 0.0 - 1.0 8424 8425 if ( target === undefined ) { 8426 8427 console.warn( 'THREE.Color: .getHSL() target is now required' ); 8428 target = { h: 0, s: 0, l: 0 }; 8429 8430 } 8431 8432 var r = this.r, g = this.g, b = this.b; 8433 8434 var max = Math.max( r, g, b ); 8435 var min = Math.min( r, g, b ); 8436 8437 var hue, saturation; 8438 var lightness = ( min + max ) / 2.0; 8439 8440 if ( min === max ) { 8441 8442 hue = 0; 8443 saturation = 0; 8444 8445 } else { 8446 8447 var delta = max - min; 8448 8449 saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min ); 8450 8451 switch ( max ) { 8452 8453 case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break; 8454 case g: hue = ( b - r ) / delta + 2; break; 8455 case b: hue = ( r - g ) / delta + 4; break; 8456 8457 } 8458 8459 hue /= 6; 8460 8461 } 8462 8463 target.h = hue; 8464 target.s = saturation; 8465 target.l = lightness; 8466 8467 return target; 8468 8469 }, 8470 8471 getStyle: function () { 8472 8473 return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')'; 8474 8475 }, 8476 8477 offsetHSL: function ( h, s, l ) { 8478 8479 this.getHSL( _hslA ); 8480 8481 _hslA.h += h; _hslA.s += s; _hslA.l += l; 8482 8483 this.setHSL( _hslA.h, _hslA.s, _hslA.l ); 8484 8485 return this; 8486 8487 }, 8488 8489 add: function ( color ) { 8490 8491 this.r += color.r; 8492 this.g += color.g; 8493 this.b += color.b; 8494 8495 return this; 8496 8497 }, 8498 8499 addColors: function ( color1, color2 ) { 8500 8501 this.r = color1.r + color2.r; 8502 this.g = color1.g + color2.g; 8503 this.b = color1.b + color2.b; 8504 8505 return this; 8506 8507 }, 8508 8509 addScalar: function ( s ) { 8510 8511 this.r += s; 8512 this.g += s; 8513 this.b += s; 8514 8515 return this; 8516 8517 }, 8518 8519 sub: function ( color ) { 8520 8521 this.r = Math.max( 0, this.r - color.r ); 8522 this.g = Math.max( 0, this.g - color.g ); 8523 this.b = Math.max( 0, this.b - color.b ); 8524 8525 return this; 8526 8527 }, 8528 8529 multiply: function ( color ) { 8530 8531 this.r *= color.r; 8532 this.g *= color.g; 8533 this.b *= color.b; 8534 8535 return this; 8536 8537 }, 8538 8539 multiplyScalar: function ( s ) { 8540 8541 this.r *= s; 8542 this.g *= s; 8543 this.b *= s; 8544 8545 return this; 8546 8547 }, 8548 8549 lerp: function ( color, alpha ) { 8550 8551 this.r += ( color.r - this.r ) * alpha; 8552 this.g += ( color.g - this.g ) * alpha; 8553 this.b += ( color.b - this.b ) * alpha; 8554 8555 return this; 8556 8557 }, 8558 8559 lerpHSL: function ( color, alpha ) { 8560 8561 this.getHSL( _hslA ); 8562 color.getHSL( _hslB ); 8563
8564 var h = MathUtils.lerp( _hslA.h, _hslB.h, alpha ); 8565 var s = MathUtils.lerp( _hslA.s, _hslB.s, alpha ); 8566 var l = MathUtils.lerp( _hslA.l, _hslB.l, alpha ); 8567 8568 this.setHSL( h, s, l ); 8569 8570 return this; 8571 8572 }, 8573 8574 equals: function ( c ) { 8575 8576 return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b ); 8577 8578 }, 8579 8580 fromArray: function ( array, offset ) { 8581 8582 if ( offset === undefined ) offset = 0; 8583 8584 this.r = array[ offset ]; 8585 this.g = array[ offset + 1 ]; 8586 this.b = array[ offset + 2 ]; 8587 8588 return this; 8589 8590 }, 8591 8592 toArray: function ( array, offset ) { 8593 8594 if ( array === undefined ) array = []; 8595 if ( offset === undefined ) offset = 0; 8596 8597 array[ offset ] = this.r; 8598 array[ offset + 1 ] = this.g; 8599 array[ offset + 2 ] = this.b; 8600 8601 return array; 8602 8603 }, 8604 8605 toJSON: function () { 8606 8607 return this.getHex(); 8608 8609 } 8610 8611} ); 8612 8613Color.NAMES = _colorKeywords; 8614 8615/** 8616 * @author mrdoob / http://mrdoob.com/ 8617 * @author alteredq / http://alteredqualia.com/ 8618 */ 8619 8620function Face3( a, b, c, normal, color, materialIndex ) { 8621 8622 this.a = a; 8623 this.b = b; 8624 this.c = c; 8625 8626 this.normal = ( normal && normal.isVector3 ) ? normal : new Vector3(); 8627 this.vertexNormals = Array.isArray( normal ) ? normal : []; 8628 8629 this.color = ( color && color.isColor ) ? color : new Color(); 8630 this.vertexColors = Array.isArray( color ) ? color : []; 8631 8632 this.materialIndex = materialIndex !== undefined ? materialIndex : 0; 8633 8634} 8635 8636Object.assign( Face3.prototype, { 8637 8638 clone: function () { 8639 8640 return new this.constructor().copy( this ); 8641 8642 }, 8643 8644 copy: function ( source ) { 8645 8646 this.a = source.a; 8647 this.b = source.b; 8648 this.c = source.c; 8649 8650 this.normal.copy( source.normal ); 8651 this.color.copy( source.color ); 8652 8653 this.materialIndex = source.materialIndex; 8654 8655 for ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) { 8656 8657 this.vertexNormals[ i ] = source.vertexNormals[ i ].clone(); 8658 8659 } 8660 8661 for ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) { 8662 8663 this.vertexColors[ i ] = source.vertexColors[ i ].clone(); 8664 8665 } 8666 8667 return this; 8668 8669 } 8670 8671} ); 8672 8673/** 8674 * @author mrdoob / http://mrdoob.com/ 8675 * @author alteredq / http://alteredqualia.com/ 8676 */ 8677 8678var materialId = 0; 8679 8680function Material() { 8681 8682 Object.defineProperty( this, 'id', { value: materialId ++ } ); 8683 8684 this.uuid = MathUtils.generateUUID(); 8685 8686 this.name = ''; 8687 this.type = 'Material'; 8688 8689 this.fog = true; 8690 8691 this.blending = NormalBlending; 8692 this.side = FrontSide; 8693 this.flatShading = false; 8694 this.vertexColors = false; 8695 8696 this.opacity = 1; 8697 this.transparent = false; 8698 8699 this.blendSrc = SrcAlphaFactor; 8700 this.blendDst = OneMinusSrcAlphaFactor; 8701 this.blendEquation = AddEquation; 8702 this.blendSrcAlpha = null; 8703 this.blendDstAlpha = null; 8704 this.blendEquationAlpha = null; 8705 8706 this.depthFunc = LessEqualDepth; 8707 this.depthTest = true; 8708 this.depthWrite = true; 8709 8710 this.stencilWriteMask = 0xff; 8711 this.stencilFunc = AlwaysStencilFunc; 8712 this.stencilRef = 0; 8713 this.stencilFuncMask = 0xff; 8714 this.stencilFail = KeepStencilOp; 8715 this.stencilZFail = KeepStencilOp; 8716 this.stencilZPass = KeepStencilOp; 8717 this.stencilWrite = false; 8718 8719 this.clippingPlanes = null; 8720 this.clipIntersection = false; 8721 this.clipShadows = false; 8722 8723 this.shadowSide = null; 8724 8725 this.colorWrite = true; 8726 8727 this.precision = null; // override the renderer's default precision for this material 8728 8729 this.polygonOffset = false; 8730 this.polygonOffsetFactor = 0; 8731 this.polygonOffsetUnits = 0; 8732 8733 this.dithering = false; 8734 8735 this.alphaTest = 0; 8736 this.premultipliedAlpha = false; 8737 8738 this.visible = true; 8739 8740 this.toneMapped = true; 8741 8742 this.userData = {}; 8743 8744 this.version = 0; 8745 8746} 8747 8748Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { 8749 8750 constructor: Material, 8751 8752 isMaterial: true, 8753 8754 onBeforeCompile: function () {}, 8755 8756 setValues: function ( values ) { 8757 8758 if ( values === undefined ) return; 8759 8760 for ( var key in values ) { 8761 8762 var newValue = values[ key ]; 8763 8764 if ( newValue === undefined ) { 8765 8766 console.warn( "THREE.Material: '" + key + "' parameter is undefined." ); 8767 continue; 8768 8769 } 8770 8771 // for backward compatability if shading is set in the constructor 8772 if ( key === 'shading' ) { 8773 8774 console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); 8775 this.flatShading = ( newValue === FlatShading ) ? true : false;
vendor: 6,735 bytes, lines 8776-8975
8776 continue; 8777 8778 } 8779 8780 var currentValue = this[ key ]; 8781 8782 if ( currentValue === undefined ) { 8783 8784 console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." ); 8785 continue; 8786 8787 } 8788 8789 if ( currentValue && currentValue.isColor ) { 8790 8791 currentValue.set( newValue ); 8792 8793 } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) { 8794 8795 currentValue.copy( newValue ); 8796 8797 } else { 8798 8799 this[ key ] = newValue; 8800 8801 } 8802 8803 } 8804 8805 }, 8806 8807 toJSON: function ( meta ) { 8808 8809 var isRoot = ( meta === undefined || typeof meta === 'string' ); 8810 8811 if ( isRoot ) { 8812 8813 meta = { 8814 textures: {}, 8815 images: {} 8816 }; 8817 8818 } 8819 8820 var data = { 8821 metadata: { 8822 version: 4.5, 8823 type: 'Material', 8824 generator: 'Material.toJSON' 8825 } 8826 }; 8827 8828 // standard Material serialization 8829 data.uuid = this.uuid; 8830 data.type = this.type; 8831 8832 if ( this.name !== '' ) data.name = this.name; 8833 8834 if ( this.color && this.color.isColor ) data.color = this.color.getHex(); 8835 8836 if ( this.roughness !== undefined ) data.roughness = this.roughness; 8837 if ( this.metalness !== undefined ) data.metalness = this.metalness; 8838 8839 if ( this.sheen && this.sheen.isColor ) data.sheen = this.sheen.getHex(); 8840 if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex(); 8841 if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity; 8842 8843 if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex(); 8844 if ( this.shininess !== undefined ) data.shininess = this.shininess; 8845 if ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat; 8846 if ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness; 8847 8848 if ( this.clearcoatMap && this.clearcoatMap.isTexture ) { 8849 8850 data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid; 8851 8852 } 8853 8854 if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) { 8855 8856 data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid; 8857 8858 } 8859 8860 if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) { 8861 8862 data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid; 8863 data.clearcoatNormalScale = this.clearcoatNormalScale.toArray(); 8864 8865 } 8866 8867 if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid; 8868 if ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid; 8869 if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid; 8870 if ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid; 8871 8872 if ( this.aoMap && this.aoMap.isTexture ) { 8873 8874 data.aoMap = this.aoMap.toJSON( meta ).uuid; 8875 data.aoMapIntensity = this.aoMapIntensity; 8876 8877 } 8878 8879 if ( this.bumpMap && this.bumpMap.isTexture ) { 8880 8881 data.bumpMap = this.bumpMap.toJSON( meta ).uuid; 8882 data.bumpScale = this.bumpScale; 8883 8884 } 8885 8886 if ( this.normalMap && this.normalMap.isTexture ) { 8887 8888 data.normalMap = this.normalMap.toJSON( meta ).uuid; 8889 data.normalMapType = this.normalMapType; 8890 data.normalScale = this.normalScale.toArray(); 8891 8892 } 8893 8894 if ( this.displacementMap && this.displacementMap.isTexture ) { 8895 8896 data.displacementMap = this.displacementMap.toJSON( meta ).uuid; 8897 data.displacementScale = this.displacementScale; 8898 data.displacementBias = this.displacementBias; 8899 8900 } 8901 8902 if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid; 8903 if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid; 8904 8905 if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid; 8906 if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid; 8907 8908 if ( this.envMap && this.envMap.isTexture ) { 8909 8910 data.envMap = this.envMap.toJSON( meta ).uuid; 8911 data.reflectivity = this.reflectivity; // Scale behind envMap 8912 data.refractionRatio = this.refractionRatio; 8913 8914 if ( this.combine !== undefined ) data.combine = this.combine; 8915 if ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity; 8916 8917 } 8918 8919 if ( this.gradientMap && this.gradientMap.isTexture ) { 8920 8921 data.gradientMap = this.gradientMap.toJSON( meta ).uuid; 8922 8923 } 8924 8925 if ( this.size !== undefined ) data.size = this.size; 8926 if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation; 8927 8928 if ( this.blending !== NormalBlending ) data.blending = this.blending; 8929 if ( this.flatShading === true ) data.flatShading = this.flatShading; 8930 if ( this.side !== FrontSide ) data.side = this.side; 8931 if ( this.vertexColors ) data.vertexColors = true; 8932 8933 if ( this.opacity < 1 ) data.opacity = this.opacity; 8934 if ( this.transparent === true ) data.transparent = this.transparent; 8935 8936 data.depthFunc = this.depthFunc; 8937 data.depthTest = this.depthTest; 8938 data.depthWrite = this.depthWrite; 8939 8940 data.stencilWrite = this.stencilWrite; 8941 data.stencilWriteMask = this.stencilWriteMask; 8942 data.stencilFunc = this.stencilFunc; 8943 data.stencilRef = this.stencilRef; 8944 data.stencilFuncMask = this.stencilFuncMask; 8945 data.stencilFail = this.stencilFail; 8946 data.stencilZFail = this.stencilZFail; 8947 data.stencilZPass = this.stencilZPass; 8948 8949 // rotation (SpriteMaterial) 8950 if ( this.rotation && this.rotation !== 0 ) data.rotation = this.rotation; 8951 8952 if ( this.polygonOffset === true ) data.polygonOffset = true; 8953 if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor; 8954 if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits; 8955 8956 if ( this.linewidth && this.linewidth !== 1 ) data.linewidth = this.linewidth; 8957 if ( this.dashSize !== undefined ) data.dashSize = this.dashSize; 8958 if ( this.gapSize !== undefined ) data.gapSize = this.gapSize; 8959 if ( this.scale !== undefined ) data.scale = this.scale; 8960 8961 if ( this.dithering === true ) data.dithering = true; 8962 8963 if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest; 8964 if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha; 8965 8966 if ( this.wireframe === true ) data.wireframe = this.wireframe; 8967 if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth; 8968 if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap; 8969 if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin; 8970 8971 if ( this.morphTargets === true ) data.morphTargets = true; 8972 if ( this.morphNormals === true ) data.morphNormals = true; 8973 if ( this.skinning === true ) data.skinning = true; 8974 8975 if ( this.visible === false ) data.visible = false;
vendor: 4,149 bytes, lines 8976-9173
8976 8977 if ( this.toneMapped === false ) data.toneMapped = false; 8978 8979 if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData; 8980 8981 // TODO: Copied from Object3D.toJSON 8982 8983 function extractFromCache( cache ) { 8984 8985 var values = []; 8986 8987 for ( var key in cache ) { 8988 8989 var data = cache[ key ]; 8990 delete data.metadata; 8991 values.push( data ); 8992 8993 } 8994 8995 return values; 8996 8997 } 8998 8999 if ( isRoot ) { 9000 9001 var textures = extractFromCache( meta.textures ); 9002 var images = extractFromCache( meta.images ); 9003 9004 if ( textures.length > 0 ) data.textures = textures; 9005 if ( images.length > 0 ) data.images = images; 9006 9007 } 9008 9009 return data; 9010 9011 }, 9012 9013 clone: function () { 9014 9015 return new this.constructor().copy( this ); 9016 9017 }, 9018 9019 copy: function ( source ) { 9020 9021 this.name = source.name; 9022 9023 this.fog = source.fog; 9024 9025 this.blending = source.blending; 9026 this.side = source.side; 9027 this.flatShading = source.flatShading; 9028 this.vertexColors = source.vertexColors; 9029 9030 this.opacity = source.opacity; 9031 this.transparent = source.transparent; 9032 9033 this.blendSrc = source.blendSrc; 9034 this.blendDst = source.blendDst; 9035 this.blendEquation = source.blendEquation; 9036 this.blendSrcAlpha = source.blendSrcAlpha; 9037 this.blendDstAlpha = source.blendDstAlpha; 9038 this.blendEquationAlpha = source.blendEquationAlpha; 9039 9040 this.depthFunc = source.depthFunc; 9041 this.depthTest = source.depthTest; 9042 this.depthWrite = source.depthWrite; 9043 9044 this.stencilWriteMask = source.stencilWriteMask; 9045 this.stencilFunc = source.stencilFunc; 9046 this.stencilRef = source.stencilRef; 9047 this.stencilFuncMask = source.stencilFuncMask; 9048 this.stencilFail = source.stencilFail; 9049 this.stencilZFail = source.stencilZFail; 9050 this.stencilZPass = source.stencilZPass; 9051 this.stencilWrite = source.stencilWrite; 9052 9053 var srcPlanes = source.clippingPlanes, 9054 dstPlanes = null; 9055 9056 if ( srcPlanes !== null ) { 9057 9058 var n = srcPlanes.length; 9059 dstPlanes = new Array( n ); 9060 9061 for ( var i = 0; i !== n; ++ i ) 9062 dstPlanes[ i ] = srcPlanes[ i ].clone(); 9063 9064 } 9065 9066 this.clippingPlanes = dstPlanes; 9067 this.clipIntersection = source.clipIntersection; 9068 this.clipShadows = source.clipShadows; 9069 9070 this.shadowSide = source.shadowSide; 9071 9072 this.colorWrite = source.colorWrite; 9073 9074 this.precision = source.precision; 9075 9076 this.polygonOffset = source.polygonOffset; 9077 this.polygonOffsetFactor = source.polygonOffsetFactor; 9078 this.polygonOffsetUnits = source.polygonOffsetUnits; 9079 9080 this.dithering = source.dithering; 9081 9082 this.alphaTest = source.alphaTest; 9083 this.premultipliedAlpha = source.premultipliedAlpha; 9084 9085 this.visible = source.visible; 9086 9087 this.toneMapped = source.toneMapped; 9088 9089 this.userData = JSON.parse( JSON.stringify( source.userData ) ); 9090 9091 return this; 9092 9093 }, 9094 9095 dispose: function () { 9096 9097 this.dispatchEvent( { type: 'dispose' } ); 9098 9099 } 9100 9101} ); 9102 9103Object.defineProperty( Material.prototype, 'needsUpdate', { 9104 9105 set: function ( value ) { 9106 9107 if ( value === true ) this.version ++; 9108 9109 } 9110 9111} ); 9112 9113/** 9114 * @author mrdoob / http://mrdoob.com/ 9115 * @author alteredq / http://alteredqualia.com/ 9116 * 9117 * parameters = { 9118 * color: <hex>, 9119 * opacity: <float>, 9120 * map: new THREE.Texture( <Image> ), 9121 * 9122 * lightMap: new THREE.Texture( <Image> ), 9123 * lightMapIntensity: <float> 9124 * 9125 * aoMap: new THREE.Texture( <Image> ), 9126 * aoMapIntensity: <float> 9127 * 9128 * specularMap: new THREE.Texture( <Image> ), 9129 * 9130 * alphaMap: new THREE.Texture( <Image> ), 9131 * 9132 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), 9133 * combine: THREE.Multiply, 9134 * reflectivity: <float>, 9135 * refractionRatio: <float>, 9136 * 9137 * depthTest: <bool>, 9138 * depthWrite: <bool>, 9139 * 9140 * wireframe: <boolean>, 9141 * wireframeLinewidth: <float>, 9142 * 9143 * skinning: <bool>, 9144 * morphTargets: <bool> 9145 * } 9146 */ 9147 9148function MeshBasicMaterial( parameters ) { 9149 9150 Material.call( this ); 9151 9152 this.type = 'MeshBasicMaterial'; 9153 9154 this.color = new Color( 0xffffff ); // emissive 9155 9156 this.map = null; 9157 9158 this.lightMap = null; 9159 this.lightMapIntensity = 1.0; 9160 9161 this.aoMap = null; 9162 this.aoMapIntensity = 1.0; 9163 9164 this.specularMap = null; 9165 9166 this.alphaMap = null; 9167 9168 this.envMap = null; 9169 this.combine = MultiplyOperation; 9170 this.reflectivity = 1; 9171 this.refractionRatio = 0.98; 9172 9173 this.wireframe = false;
vendor: 10,660 bytes, lines 9174-9732
9174 this.wireframeLinewidth = 1; 9175 this.wireframeLinecap = 'round'; 9176 this.wireframeLinejoin = 'round'; 9177 9178 this.skinning = false; 9179 this.morphTargets = false; 9180 9181 this.setValues( parameters ); 9182 9183} 9184 9185MeshBasicMaterial.prototype = Object.create( Material.prototype ); 9186MeshBasicMaterial.prototype.constructor = MeshBasicMaterial; 9187 9188MeshBasicMaterial.prototype.isMeshBasicMaterial = true; 9189 9190MeshBasicMaterial.prototype.copy = function ( source ) { 9191 9192 Material.prototype.copy.call( this, source ); 9193 9194 this.color.copy( source.color ); 9195 9196 this.map = source.map; 9197 9198 this.lightMap = source.lightMap; 9199 this.lightMapIntensity = source.lightMapIntensity; 9200 9201 this.aoMap = source.aoMap; 9202 this.aoMapIntensity = source.aoMapIntensity; 9203 9204 this.specularMap = source.specularMap; 9205 9206 this.alphaMap = source.alphaMap; 9207 9208 this.envMap = source.envMap; 9209 this.combine = source.combine; 9210 this.reflectivity = source.reflectivity; 9211 this.refractionRatio = source.refractionRatio; 9212 9213 this.wireframe = source.wireframe; 9214 this.wireframeLinewidth = source.wireframeLinewidth; 9215 this.wireframeLinecap = source.wireframeLinecap; 9216 this.wireframeLinejoin = source.wireframeLinejoin; 9217 9218 this.skinning = source.skinning; 9219 this.morphTargets = source.morphTargets; 9220 9221 return this; 9222 9223}; 9224 9225/** 9226 * @author mrdoob / http://mrdoob.com/ 9227 */ 9228 9229var _vector$3 = new Vector3(); 9230 9231function BufferAttribute( array, itemSize, normalized ) { 9232 9233 if ( Array.isArray( array ) ) { 9234 9235 throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); 9236 9237 } 9238 9239 this.name = ''; 9240 9241 this.array = array; 9242 this.itemSize = itemSize; 9243 this.count = array !== undefined ? array.length / itemSize : 0; 9244 this.normalized = normalized === true; 9245 9246 this.usage = StaticDrawUsage; 9247 this.updateRange = { offset: 0, count: - 1 }; 9248 9249 this.version = 0; 9250 9251} 9252 9253Object.defineProperty( BufferAttribute.prototype, 'needsUpdate', { 9254 9255 set: function ( value ) { 9256 9257 if ( value === true ) this.version ++; 9258 9259 } 9260 9261} ); 9262 9263Object.assign( BufferAttribute.prototype, { 9264 9265 isBufferAttribute: true, 9266 9267 onUploadCallback: function () {}, 9268 9269 setUsage: function ( value ) { 9270 9271 this.usage = value; 9272 9273 return this; 9274 9275 }, 9276 9277 copy: function ( source ) { 9278 9279 this.name = source.name; 9280 this.array = new source.array.constructor( source.array ); 9281 this.itemSize = source.itemSize; 9282 this.count = source.count; 9283 this.normalized = source.normalized; 9284 9285 this.usage = source.usage; 9286 9287 return this; 9288 9289 }, 9290 9291 copyAt: function ( index1, attribute, index2 ) { 9292 9293 index1 *= this.itemSize; 9294 index2 *= attribute.itemSize; 9295 9296 for ( var i = 0, l = this.itemSize; i < l; i ++ ) { 9297 9298 this.array[ index1 + i ] = attribute.array[ index2 + i ]; 9299 9300 } 9301 9302 return this; 9303 9304 }, 9305 9306 copyArray: function ( array ) { 9307 9308 this.array.set( array ); 9309 9310 return this; 9311 9312 }, 9313 9314 copyColorsArray: function ( colors ) { 9315 9316 var array = this.array, offset = 0; 9317 9318 for ( var i = 0, l = colors.length; i < l; i ++ ) { 9319 9320 var color = colors[ i ]; 9321 9322 if ( color === undefined ) { 9323 9324 console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i ); 9325 color = new Color(); 9326 9327 } 9328 9329 array[ offset ++ ] = color.r; 9330 array[ offset ++ ] = color.g; 9331 array[ offset ++ ] = color.b; 9332 9333 } 9334 9335 return this; 9336 9337 }, 9338 9339 copyVector2sArray: function ( vectors ) { 9340 9341 var array = this.array, offset = 0; 9342 9343 for ( var i = 0, l = vectors.length; i < l; i ++ ) { 9344 9345 var vector = vectors[ i ]; 9346 9347 if ( vector === undefined ) { 9348 9349 console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i ); 9350 vector = new Vector2(); 9351 9352 } 9353 9354 array[ offset ++ ] = vector.x; 9355 array[ offset ++ ] = vector.y; 9356 9357 } 9358 9359 return this; 9360 9361 }, 9362 9363 copyVector3sArray: function ( vectors ) { 9364 9365 var array = this.array, offset = 0; 9366 9367 for ( var i = 0, l = vectors.length; i < l; i ++ ) { 9368 9369 var vector = vectors[ i ]; 9370 9371 if ( vector === undefined ) { 9372 9373 console.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i ); 9374 vector = new Vector3(); 9375 9376 } 9377 9378 array[ offset ++ ] = vector.x; 9379 array[ offset ++ ] = vector.y; 9380 array[ offset ++ ] = vector.z; 9381 9382 } 9383 9384 return this; 9385 9386 }, 9387 9388 copyVector4sArray: function ( vectors ) { 9389 9390 var array = this.array, offset = 0; 9391 9392 for ( var i = 0, l = vectors.length; i < l; i ++ ) { 9393 9394 var vector = vectors[ i ]; 9395 9396 if ( vector === undefined ) { 9397 9398 console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i ); 9399 vector = new Vector4(); 9400 9401 } 9402 9403 array[ offset ++ ] = vector.x; 9404 array[ offset ++ ] = vector.y; 9405 array[ offset ++ ] = vector.z; 9406 array[ offset ++ ] = vector.w; 9407 9408 } 9409 9410 return this; 9411 9412 }, 9413 9414 applyMatrix3: function ( m ) { 9415 9416 for ( var i = 0, l = this.count; i < l; i ++ ) { 9417 9418 _vector$3.x = this.getX( i ); 9419 _vector$3.y = this.getY( i ); 9420 _vector$3.z = this.getZ( i ); 9421 9422 _vector$3.applyMatrix3( m ); 9423 9424 this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); 9425 9426 } 9427 9428 return this; 9429 9430 }, 9431 9432 applyMatrix4: function ( m ) { 9433 9434 for ( var i = 0, l = this.count; i < l; i ++ ) { 9435 9436 _vector$3.x = this.getX( i ); 9437 _vector$3.y = this.getY( i ); 9438 _vector$3.z = this.getZ( i ); 9439 9440 _vector$3.applyMatrix4( m ); 9441 9442 this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); 9443 9444 } 9445 9446 return this; 9447 9448 }, 9449 9450 applyNormalMatrix: function ( m ) { 9451 9452 for ( var i = 0, l = this.count; i < l; i ++ ) { 9453 9454 _vector$3.x = this.getX( i ); 9455 _vector$3.y = this.getY( i ); 9456 _vector$3.z = this.getZ( i ); 9457 9458 _vector$3.applyNormalMatrix( m ); 9459 9460 this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); 9461 9462 } 9463 9464 return this; 9465 9466 }, 9467 9468 transformDirection: function ( m ) { 9469 9470 for ( var i = 0, l = this.count; i < l; i ++ ) { 9471 9472 _vector$3.x = this.getX( i ); 9473 _vector$3.y = this.getY( i ); 9474 _vector$3.z = this.getZ( i ); 9475 9476 _vector$3.transformDirection( m ); 9477 9478 this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); 9479 9480 } 9481 9482 return this; 9483 9484 }, 9485 9486 set: function ( value, offset ) { 9487 9488 if ( offset === undefined ) offset = 0; 9489 9490 this.array.set( value, offset ); 9491 9492 return this; 9493 9494 }, 9495 9496 getX: function ( index ) { 9497 9498 return this.array[ index * this.itemSize ]; 9499 9500 }, 9501 9502 setX: function ( index, x ) { 9503 9504 this.array[ index * this.itemSize ] = x; 9505 9506 return this; 9507 9508 }, 9509 9510 getY: function ( index ) { 9511 9512 return this.array[ index * this.itemSize + 1 ]; 9513 9514 }, 9515 9516 setY: function ( index, y ) { 9517 9518 this.array[ index * this.itemSize + 1 ] = y; 9519 9520 return this; 9521 9522 }, 9523 9524 getZ: function ( index ) { 9525 9526 return this.array[ index * this.itemSize + 2 ]; 9527 9528 }, 9529 9530 setZ: function ( index, z ) { 9531 9532 this.array[ index * this.itemSize + 2 ] = z; 9533 9534 return this; 9535 9536 }, 9537 9538 getW: function ( index ) { 9539 9540 return this.array[ index * this.itemSize + 3 ]; 9541 9542 }, 9543 9544 setW: function ( index, w ) { 9545 9546 this.array[ index * this.itemSize + 3 ] = w; 9547 9548 return this; 9549 9550 }, 9551 9552 setXY: function ( index, x, y ) { 9553 9554 index *= this.itemSize; 9555 9556 this.array[ index + 0 ] = x; 9557 this.array[ index + 1 ] = y; 9558 9559 return this; 9560 9561 }, 9562 9563 setXYZ: function ( index, x, y, z ) { 9564 9565 index *= this.itemSize; 9566 9567 this.array[ index + 0 ] = x; 9568 this.array[ index + 1 ] = y; 9569 this.array[ index + 2 ] = z; 9570 9571 return this; 9572 9573 }, 9574 9575 setXYZW: function ( index, x, y, z, w ) { 9576 9577 index *= this.itemSize; 9578 9579 this.array[ index + 0 ] = x; 9580 this.array[ index + 1 ] = y; 9581 this.array[ index + 2 ] = z; 9582 this.array[ index + 3 ] = w; 9583 9584 return this; 9585 9586 }, 9587 9588 onUpload: function ( callback ) { 9589 9590 this.onUploadCallback = callback; 9591 9592 return this; 9593 9594 }, 9595 9596 clone: function () { 9597 9598 return new this.constructor( this.array, this.itemSize ).copy( this ); 9599 9600 }, 9601 9602 toJSON: function () { 9603 9604 return { 9605 itemSize: this.itemSize, 9606 type: this.array.constructor.name, 9607 array: Array.prototype.slice.call( this.array ), 9608 normalized: this.normalized 9609 }; 9610 9611 } 9612 9613} ); 9614 9615// 9616 9617function Int8BufferAttribute( array, itemSize, normalized ) { 9618 9619 BufferAttribute.call( this, new Int8Array( array ), itemSize, normalized ); 9620 9621} 9622 9623Int8BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 9624Int8BufferAttribute.prototype.constructor = Int8BufferAttribute; 9625 9626 9627function Uint8BufferAttribute( array, itemSize, normalized ) { 9628 9629 BufferAttribute.call( this, new Uint8Array( array ), itemSize, normalized ); 9630 9631} 9632 9633Uint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 9634Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute; 9635 9636 9637function Uint8ClampedBufferAttribute( array, itemSize, normalized ) { 9638 9639 BufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize, normalized ); 9640 9641} 9642 9643Uint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 9644Uint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute; 9645 9646 9647function Int16BufferAttribute( array, itemSize, normalized ) { 9648 9649 BufferAttribute.call( this, new Int16Array( array ), itemSize, normalized ); 9650 9651} 9652 9653Int16BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 9654Int16BufferAttribute.prototype.constructor = Int16BufferAttribute; 9655 9656 9657function Uint16BufferAttribute( array, itemSize, normalized ) { 9658 9659 BufferAttribute.call( this, new Uint16Array( array ), itemSize, normalized ); 9660 9661} 9662 9663Uint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 9664Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute; 9665 9666 9667function Int32BufferAttribute( array, itemSize, normalized ) { 9668 9669 BufferAttribute.call( this, new Int32Array( array ), itemSize, normalized ); 9670 9671} 9672 9673Int32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 9674Int32BufferAttribute.prototype.constructor = Int32BufferAttribute; 9675 9676 9677function Uint32BufferAttribute( array, itemSize, normalized ) { 9678 9679 BufferAttribute.call( this, new Uint32Array( array ), itemSize, normalized ); 9680 9681} 9682 9683Uint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 9684Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute; 9685 9686 9687function Float32BufferAttribute( array, itemSize, normalized ) { 9688 9689 BufferAttribute.call( this, new Float32Array( array ), itemSize, normalized ); 9690 9691} 9692 9693Float32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 9694Float32BufferAttribute.prototype.constructor = Float32BufferAttribute; 9695 9696 9697function Float64BufferAttribute( array, itemSize, normalized ) { 9698 9699 BufferAttribute.call( this, new Float64Array( array ), itemSize, normalized ); 9700 9701} 9702 9703Float64BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 9704Float64BufferAttribute.prototype.constructor = Float64BufferAttribute; 9705 9706/** 9707 * @author mrdoob / http://mrdoob.com/ 9708 */ 9709 9710function DirectGeometry() { 9711 9712 this.vertices = []; 9713 this.normals = []; 9714 this.colors = []; 9715 this.uvs = []; 9716 this.uvs2 = []; 9717 9718 this.groups = []; 9719 9720 this.morphTargets = {}; 9721 9722 this.skinWeights = []; 9723 this.skinIndices = []; 9724 9725 // this.lineDistances = []; 9726 9727 this.boundingBox = null; 9728 this.boundingSphere = null; 9729 9730 // update flags 9731 9732 this.verticesNeedUpdate = false;
vendor: 17,705 bytes, lines 9733-10653
9733 this.normalsNeedUpdate = false; 9734 this.colorsNeedUpdate = false; 9735 this.uvsNeedUpdate = false; 9736 this.groupsNeedUpdate = false; 9737 9738} 9739 9740Object.assign( DirectGeometry.prototype, { 9741 9742 computeGroups: function ( geometry ) { 9743 9744 var group; 9745 var groups = []; 9746 var materialIndex = undefined; 9747 9748 var faces = geometry.faces; 9749 9750 for ( var i = 0; i < faces.length; i ++ ) { 9751 9752 var face = faces[ i ]; 9753 9754 // materials 9755 9756 if ( face.materialIndex !== materialIndex ) { 9757 9758 materialIndex = face.materialIndex; 9759 9760 if ( group !== undefined ) { 9761 9762 group.count = ( i * 3 ) - group.start; 9763 groups.push( group ); 9764 9765 } 9766 9767 group = { 9768 start: i * 3, 9769 materialIndex: materialIndex 9770 }; 9771 9772 } 9773 9774 } 9775 9776 if ( group !== undefined ) { 9777 9778 group.count = ( i * 3 ) - group.start; 9779 groups.push( group ); 9780 9781 } 9782 9783 this.groups = groups; 9784 9785 }, 9786 9787 fromGeometry: function ( geometry ) { 9788 9789 var faces = geometry.faces; 9790 var vertices = geometry.vertices; 9791 var faceVertexUvs = geometry.faceVertexUvs; 9792 9793 var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0; 9794 var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0; 9795 9796 // morphs 9797 9798 var morphTargets = geometry.morphTargets; 9799 var morphTargetsLength = morphTargets.length; 9800 9801 var morphTargetsPosition; 9802 9803 if ( morphTargetsLength > 0 ) { 9804 9805 morphTargetsPosition = []; 9806 9807 for ( var i = 0; i < morphTargetsLength; i ++ ) { 9808 9809 morphTargetsPosition[ i ] = { 9810 name: morphTargets[ i ].name, 9811 data: [] 9812 }; 9813 9814 } 9815 9816 this.morphTargets.position = morphTargetsPosition; 9817 9818 } 9819 9820 var morphNormals = geometry.morphNormals; 9821 var morphNormalsLength = morphNormals.length; 9822 9823 var morphTargetsNormal; 9824 9825 if ( morphNormalsLength > 0 ) { 9826 9827 morphTargetsNormal = []; 9828 9829 for ( var i = 0; i < morphNormalsLength; i ++ ) { 9830 9831 morphTargetsNormal[ i ] = { 9832 name: morphNormals[ i ].name, 9833 data: [] 9834 }; 9835 9836 } 9837 9838 this.morphTargets.normal = morphTargetsNormal; 9839 9840 } 9841 9842 // skins 9843 9844 var skinIndices = geometry.skinIndices; 9845 var skinWeights = geometry.skinWeights; 9846 9847 var hasSkinIndices = skinIndices.length === vertices.length; 9848 var hasSkinWeights = skinWeights.length === vertices.length; 9849 9850 // 9851 9852 if ( vertices.length > 0 && faces.length === 0 ) { 9853 9854 console.error( 'THREE.DirectGeometry: Faceless geometries are not supported.' ); 9855 9856 } 9857 9858 for ( var i = 0; i < faces.length; i ++ ) { 9859 9860 var face = faces[ i ]; 9861 9862 this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] ); 9863 9864 var vertexNormals = face.vertexNormals; 9865 9866 if ( vertexNormals.length === 3 ) { 9867 9868 this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] ); 9869 9870 } else { 9871 9872 var normal = face.normal; 9873 9874 this.normals.push( normal, normal, normal ); 9875 9876 } 9877 9878 var vertexColors = face.vertexColors; 9879 9880 if ( vertexColors.length === 3 ) { 9881 9882 this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] ); 9883 9884 } else { 9885 9886 var color = face.color; 9887 9888 this.colors.push( color, color, color ); 9889 9890 } 9891 9892 if ( hasFaceVertexUv === true ) { 9893 9894 var vertexUvs = faceVertexUvs[ 0 ][ i ]; 9895 9896 if ( vertexUvs !== undefined ) { 9897 9898 this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] ); 9899 9900 } else { 9901 9902 console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i ); 9903 9904 this.uvs.push( new Vector2(), new Vector2(), new Vector2() ); 9905 9906 } 9907 9908 } 9909 9910 if ( hasFaceVertexUv2 === true ) { 9911 9912 var vertexUvs = faceVertexUvs[ 1 ][ i ]; 9913 9914 if ( vertexUvs !== undefined ) { 9915 9916 this.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] ); 9917 9918 } else { 9919 9920 console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i ); 9921 9922 this.uvs2.push( new Vector2(), new Vector2(), new Vector2() ); 9923 9924 } 9925 9926 } 9927 9928 // morphs 9929 9930 for ( var j = 0; j < morphTargetsLength; j ++ ) { 9931 9932 var morphTarget = morphTargets[ j ].vertices; 9933 9934 morphTargetsPosition[ j ].data.push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] ); 9935 9936 } 9937 9938 for ( var j = 0; j < morphNormalsLength; j ++ ) { 9939 9940 var morphNormal = morphNormals[ j ].vertexNormals[ i ]; 9941 9942 morphTargetsNormal[ j ].data.push( morphNormal.a, morphNormal.b, morphNormal.c ); 9943 9944 } 9945 9946 // skins 9947 9948 if ( hasSkinIndices ) { 9949 9950 this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] ); 9951 9952 } 9953 9954 if ( hasSkinWeights ) { 9955 9956 this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] ); 9957 9958 } 9959 9960 } 9961 9962 this.computeGroups( geometry ); 9963 9964 this.verticesNeedUpdate = geometry.verticesNeedUpdate; 9965 this.normalsNeedUpdate = geometry.normalsNeedUpdate; 9966 this.colorsNeedUpdate = geometry.colorsNeedUpdate; 9967 this.uvsNeedUpdate = geometry.uvsNeedUpdate; 9968 this.groupsNeedUpdate = geometry.groupsNeedUpdate; 9969 9970 if ( geometry.boundingSphere !== null ) { 9971 9972 this.boundingSphere = geometry.boundingSphere.clone(); 9973 9974 } 9975 9976 if ( geometry.boundingBox !== null ) { 9977 9978 this.boundingBox = geometry.boundingBox.clone(); 9979 9980 } 9981 9982 return this; 9983 9984 } 9985 9986} ); 9987 9988/** 9989 * @author mrdoob / http://mrdoob.com/ 9990 */ 9991 9992function arrayMax( array ) { 9993 9994 if ( array.length === 0 ) return - Infinity; 9995 9996 var max = array[ 0 ]; 9997 9998 for ( var i = 1, l = array.length; i < l; ++ i ) { 9999 10000 if ( array[ i ] > max ) max = array[ i ]; 10001 10002 } 10003 10004 return max; 10005 10006} 10007 10008/** 10009 * @author alteredq / http://alteredqualia.com/ 10010 * @author mrdoob / http://mrdoob.com/ 10011 */ 10012 10013var _bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id 10014 10015var _m1$2 = new Matrix4(); 10016var _obj = new Object3D(); 10017var _offset = new Vector3(); 10018var _box$2 = new Box3(); 10019var _boxMorphTargets = new Box3(); 10020var _vector$4 = new Vector3(); 10021 10022function BufferGeometry() { 10023 10024 Object.defineProperty( this, 'id', { value: _bufferGeometryId += 2 } ); 10025 10026 this.uuid = MathUtils.generateUUID(); 10027 10028 this.name = ''; 10029 this.type = 'BufferGeometry'; 10030 10031 this.index = null; 10032 this.attributes = {}; 10033 10034 this.morphAttributes = {}; 10035 this.morphTargetsRelative = false; 10036 10037 this.groups = []; 10038 10039 this.boundingBox = null; 10040 this.boundingSphere = null; 10041 10042 this.drawRange = { start: 0, count: Infinity }; 10043 10044 this.userData = {}; 10045 10046} 10047 10048BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { 10049 10050 constructor: BufferGeometry, 10051 10052 isBufferGeometry: true, 10053 10054 getIndex: function () { 10055 10056 return this.index; 10057 10058 }, 10059 10060 setIndex: function ( index ) { 10061 10062 if ( Array.isArray( index ) ) { 10063 10064 this.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 ); 10065 10066 } else { 10067 10068 this.index = index; 10069 10070 } 10071 10072 }, 10073 10074 getAttribute: function ( name ) { 10075 10076 return this.attributes[ name ]; 10077 10078 }, 10079 10080 setAttribute: function ( name, attribute ) { 10081 10082 this.attributes[ name ] = attribute; 10083 10084 return this; 10085 10086 }, 10087 10088 deleteAttribute: function ( name ) { 10089 10090 delete this.attributes[ name ]; 10091 10092 return this; 10093 10094 }, 10095 10096 addGroup: function ( start, count, materialIndex ) { 10097 10098 this.groups.push( { 10099 10100 start: start, 10101 count: count, 10102 materialIndex: materialIndex !== undefined ? materialIndex : 0 10103 10104 } ); 10105 10106 }, 10107 10108 clearGroups: function () { 10109 10110 this.groups = []; 10111 10112 }, 10113 10114 setDrawRange: function ( start, count ) { 10115 10116 this.drawRange.start = start; 10117 this.drawRange.count = count; 10118 10119 }, 10120 10121 applyMatrix4: function ( matrix ) { 10122 10123 var position = this.attributes.position; 10124 10125 if ( position !== undefined ) { 10126 10127 position.applyMatrix4( matrix ); 10128 10129 position.needsUpdate = true; 10130 10131 } 10132 10133 var normal = this.attributes.normal; 10134 10135 if ( normal !== undefined ) { 10136 10137 var normalMatrix = new Matrix3().getNormalMatrix( matrix ); 10138 10139 normal.applyNormalMatrix( normalMatrix ); 10140 10141 normal.needsUpdate = true; 10142 10143 } 10144 10145 var tangent = this.attributes.tangent; 10146 10147 if ( tangent !== undefined ) { 10148 10149 tangent.transformDirection( matrix ); 10150 10151 tangent.needsUpdate = true; 10152 10153 } 10154 10155 if ( this.boundingBox !== null ) { 10156 10157 this.computeBoundingBox(); 10158 10159 } 10160 10161 if ( this.boundingSphere !== null ) { 10162 10163 this.computeBoundingSphere(); 10164 10165 } 10166 10167 return this; 10168 10169 }, 10170 10171 rotateX: function ( angle ) { 10172 10173 // rotate geometry around world x-axis 10174 10175 _m1$2.makeRotationX( angle ); 10176 10177 this.applyMatrix4( _m1$2 ); 10178 10179 return this; 10180 10181 }, 10182 10183 rotateY: function ( angle ) { 10184 10185 // rotate geometry around world y-axis 10186 10187 _m1$2.makeRotationY( angle ); 10188 10189 this.applyMatrix4( _m1$2 ); 10190 10191 return this; 10192 10193 }, 10194 10195 rotateZ: function ( angle ) { 10196 10197 // rotate geometry around world z-axis 10198 10199 _m1$2.makeRotationZ( angle ); 10200 10201 this.applyMatrix4( _m1$2 ); 10202 10203 return this; 10204 10205 }, 10206 10207 translate: function ( x, y, z ) { 10208 10209 // translate geometry 10210 10211 _m1$2.makeTranslation( x, y, z ); 10212 10213 this.applyMatrix4( _m1$2 ); 10214 10215 return this; 10216 10217 }, 10218 10219 scale: function ( x, y, z ) { 10220 10221 // scale geometry 10222 10223 _m1$2.makeScale( x, y, z ); 10224 10225 this.applyMatrix4( _m1$2 ); 10226 10227 return this; 10228 10229 }, 10230 10231 lookAt: function ( vector ) { 10232 10233 _obj.lookAt( vector ); 10234 10235 _obj.updateMatrix(); 10236 10237 this.applyMatrix4( _obj.matrix ); 10238 10239 return this; 10240 10241 }, 10242 10243 center: function () { 10244 10245 this.computeBoundingBox(); 10246 10247 this.boundingBox.getCenter( _offset ).negate(); 10248 10249 this.translate( _offset.x, _offset.y, _offset.z ); 10250 10251 return this; 10252 10253 }, 10254 10255 setFromObject: function ( object ) { 10256 10257 // console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this ); 10258 10259 var geometry = object.geometry; 10260 10261 if ( object.isPoints || object.isLine ) { 10262 10263 var positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 ); 10264 var colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 ); 10265 10266 this.setAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) ); 10267 this.setAttribute( 'color', colors.copyColorsArray( geometry.colors ) ); 10268 10269 if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) { 10270 10271 var lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 ); 10272 10273 this.setAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) ); 10274 10275 } 10276 10277 if ( geometry.boundingSphere !== null ) { 10278 10279 this.boundingSphere = geometry.boundingSphere.clone(); 10280 10281 } 10282 10283 if ( geometry.boundingBox !== null ) { 10284 10285 this.boundingBox = geometry.boundingBox.clone(); 10286 10287 } 10288 10289 } else if ( object.isMesh ) { 10290 10291 if ( geometry && geometry.isGeometry ) { 10292 10293 this.fromGeometry( geometry ); 10294 10295 } 10296 10297 } 10298 10299 return this; 10300 10301 }, 10302 10303 setFromPoints: function ( points ) { 10304 10305 var position = []; 10306 10307 for ( var i = 0, l = points.length; i < l; i ++ ) { 10308 10309 var point = points[ i ]; 10310 position.push( point.x, point.y, point.z || 0 ); 10311 10312 } 10313 10314 this.setAttribute( 'position', new Float32BufferAttribute( position, 3 ) ); 10315 10316 return this; 10317 10318 }, 10319 10320 updateFromObject: function ( object ) { 10321 10322 var geometry = object.geometry; 10323 10324 if ( object.isMesh ) { 10325 10326 var direct = geometry.__directGeometry; 10327 10328 if ( geometry.elementsNeedUpdate === true ) { 10329 10330 direct = undefined; 10331 geometry.elementsNeedUpdate = false; 10332 10333 } 10334 10335 if ( direct === undefined ) { 10336 10337 return this.fromGeometry( geometry ); 10338 10339 } 10340 10341 direct.verticesNeedUpdate = geometry.verticesNeedUpdate; 10342 direct.normalsNeedUpdate = geometry.normalsNeedUpdate; 10343 direct.colorsNeedUpdate = geometry.colorsNeedUpdate; 10344 direct.uvsNeedUpdate = geometry.uvsNeedUpdate; 10345 direct.groupsNeedUpdate = geometry.groupsNeedUpdate; 10346 10347 geometry.verticesNeedUpdate = false; 10348 geometry.normalsNeedUpdate = false; 10349 geometry.colorsNeedUpdate = false; 10350 geometry.uvsNeedUpdate = false; 10351 geometry.groupsNeedUpdate = false; 10352 10353 geometry = direct; 10354 10355 } 10356 10357 var attribute; 10358 10359 if ( geometry.verticesNeedUpdate === true ) { 10360 10361 attribute = this.attributes.position; 10362 10363 if ( attribute !== undefined ) { 10364 10365 attribute.copyVector3sArray( geometry.vertices ); 10366 attribute.needsUpdate = true; 10367 10368 } 10369 10370 geometry.verticesNeedUpdate = false; 10371 10372 } 10373 10374 if ( geometry.normalsNeedUpdate === true ) { 10375 10376 attribute = this.attributes.normal; 10377 10378 if ( attribute !== undefined ) { 10379 10380 attribute.copyVector3sArray( geometry.normals ); 10381 attribute.needsUpdate = true; 10382 10383 } 10384 10385 geometry.normalsNeedUpdate = false; 10386 10387 } 10388 10389 if ( geometry.colorsNeedUpdate === true ) { 10390 10391 attribute = this.attributes.color; 10392 10393 if ( attribute !== undefined ) { 10394 10395 attribute.copyColorsArray( geometry.colors ); 10396 attribute.needsUpdate = true; 10397 10398 } 10399 10400 geometry.colorsNeedUpdate = false; 10401 10402 } 10403 10404 if ( geometry.uvsNeedUpdate ) { 10405 10406 attribute = this.attributes.uv; 10407 10408 if ( attribute !== undefined ) { 10409 10410 attribute.copyVector2sArray( geometry.uvs ); 10411 attribute.needsUpdate = true; 10412 10413 } 10414 10415 geometry.uvsNeedUpdate = false; 10416 10417 } 10418 10419 if ( geometry.lineDistancesNeedUpdate ) { 10420 10421 attribute = this.attributes.lineDistance; 10422 10423 if ( attribute !== undefined ) { 10424 10425 attribute.copyArray( geometry.lineDistances ); 10426 attribute.needsUpdate = true; 10427 10428 } 10429 10430 geometry.lineDistancesNeedUpdate = false; 10431 10432 } 10433 10434 if ( geometry.groupsNeedUpdate ) { 10435 10436 geometry.computeGroups( object.geometry ); 10437 this.groups = geometry.groups; 10438 10439 geometry.groupsNeedUpdate = false; 10440 10441 } 10442 10443 return this; 10444 10445 }, 10446 10447 fromGeometry: function ( geometry ) { 10448 10449 geometry.__directGeometry = new DirectGeometry().fromGeometry( geometry ); 10450 10451 return this.fromDirectGeometry( geometry.__directGeometry ); 10452 10453 }, 10454 10455 fromDirectGeometry: function ( geometry ) { 10456 10457 var positions = new Float32Array( geometry.vertices.length * 3 ); 10458 this.setAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) ); 10459 10460 if ( geometry.normals.length > 0 ) { 10461 10462 var normals = new Float32Array( geometry.normals.length * 3 ); 10463 this.setAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) ); 10464 10465 } 10466 10467 if ( geometry.colors.length > 0 ) { 10468 10469 var colors = new Float32Array( geometry.colors.length * 3 ); 10470 this.setAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) ); 10471 10472 } 10473 10474 if ( geometry.uvs.length > 0 ) { 10475 10476 var uvs = new Float32Array( geometry.uvs.length * 2 ); 10477 this.setAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) ); 10478 10479 } 10480 10481 if ( geometry.uvs2.length > 0 ) { 10482 10483 var uvs2 = new Float32Array( geometry.uvs2.length * 2 ); 10484 this.setAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) ); 10485 10486 } 10487 10488 // groups 10489 10490 this.groups = geometry.groups; 10491 10492 // morphs 10493 10494 for ( var name in geometry.morphTargets ) { 10495 10496 var array = []; 10497 var morphTargets = geometry.morphTargets[ name ]; 10498 10499 for ( var i = 0, l = morphTargets.length; i < l; i ++ ) { 10500 10501 var morphTarget = morphTargets[ i ]; 10502 10503 var attribute = new Float32BufferAttribute( morphTarget.data.length * 3, 3 ); 10504 attribute.name = morphTarget.name; 10505 10506 array.push( attribute.copyVector3sArray( morphTarget.data ) ); 10507 10508 } 10509 10510 this.morphAttributes[ name ] = array; 10511 10512 } 10513 10514 // skinning 10515 10516 if ( geometry.skinIndices.length > 0 ) { 10517 10518 var skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 ); 10519 this.setAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) ); 10520 10521 } 10522 10523 if ( geometry.skinWeights.length > 0 ) { 10524 10525 var skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 ); 10526 this.setAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) ); 10527 10528 } 10529 10530 // 10531 10532 if ( geometry.boundingSphere !== null ) { 10533 10534 this.boundingSphere = geometry.boundingSphere.clone(); 10535 10536 } 10537 10538 if ( geometry.boundingBox !== null ) { 10539 10540 this.boundingBox = geometry.boundingBox.clone(); 10541 10542 } 10543 10544 return this; 10545 10546 }, 10547 10548 computeBoundingBox: function () { 10549 10550 if ( this.boundingBox === null ) { 10551 10552 this.boundingBox = new Box3(); 10553 10554 } 10555 10556 var position = this.attributes.position; 10557 var morphAttributesPosition = this.morphAttributes.position; 10558 10559 if ( position !== undefined ) { 10560 10561 this.boundingBox.setFromBufferAttribute( position ); 10562 10563 // process morph attributes if present 10564 10565 if ( morphAttributesPosition ) { 10566 10567 for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { 10568 10569 var morphAttribute = morphAttributesPosition[ i ]; 10570 _box$2.setFromBufferAttribute( morphAttribute ); 10571 10572 if ( this.morphTargetsRelative ) { 10573 10574 _vector$4.addVectors( this.boundingBox.min, _box$2.min ); 10575 this.boundingBox.expandByPoint( _vector$4 ); 10576 10577 _vector$4.addVectors( this.boundingBox.max, _box$2.max ); 10578 this.boundingBox.expandByPoint( _vector$4 ); 10579 10580 } else { 10581 10582 this.boundingBox.expandByPoint( _box$2.min ); 10583 this.boundingBox.expandByPoint( _box$2.max ); 10584 10585 } 10586 10587 } 10588 10589 } 10590 10591 } else { 10592 10593 this.boundingBox.makeEmpty(); 10594 10595 } 10596 10597 if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) { 10598 10599 console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this ); 10600 10601 } 10602 10603 }, 10604 10605 computeBoundingSphere: function () { 10606 10607 if ( this.boundingSphere === null ) { 10608 10609 this.boundingSphere = new Sphere(); 10610 10611 } 10612 10613 var position = this.attributes.position; 10614 var morphAttributesPosition = this.morphAttributes.position; 10615 10616 if ( position ) { 10617 10618 // first, find the center of the bounding sphere 10619 10620 var center = this.boundingSphere.center; 10621 10622 _box$2.setFromBufferAttribute( position ); 10623 10624 // process morph attributes if present 10625 10626 if ( morphAttributesPosition ) { 10627 10628 for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { 10629 10630 var morphAttribute = morphAttributesPosition[ i ]; 10631 _boxMorphTargets.setFromBufferAttribute( morphAttribute ); 10632 10633 if ( this.morphTargetsRelative ) { 10634 10635 _vector$4.addVectors( _box$2.min, _boxMorphTargets.min ); 10636 _box$2.expandByPoint( _vector$4 ); 10637 10638 _vector$4.addVectors( _box$2.max, _boxMorphTargets.max ); 10639 _box$2.expandByPoint( _vector$4 ); 10640 10641 } else { 10642 10643 _box$2.expandByPoint( _boxMorphTargets.min ); 10644 _box$2.expandByPoint( _boxMorphTargets.max ); 10645 10646 } 10647 10648 } 10649 10650 } 10651 10652 _box$2.getCenter( center ); 10653
10654 // second, try to find a boundingSphere with a radius smaller than the 10655 // boundingSphere of the boundingBox: sqrt(3) smaller in the best case 10656 10657 var maxRadiusSq = 0; 10658 10659 for ( var i = 0, il = position.count; i < il; i ++ ) { 10660 10661 _vector$4.fromBufferAttribute( position, i ); 10662 10663 maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$4 ) ); 10664 10665 } 10666 10667 // process morph attributes if present 10668 10669 if ( morphAttributesPosition ) { 10670 10671 for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { 10672 10673 var morphAttribute = morphAttributesPosition[ i ]; 10674 var morphTargetsRelative = this.morphTargetsRelative; 10675 10676 for ( var j = 0, jl = morphAttribute.count; j < jl; j ++ ) { 10677 10678 _vector$4.fromBufferAttribute( morphAttribute, j ); 10679 10680 if ( morphTargetsRelative ) { 10681 10682 _offset.fromBufferAttribute( position, j ); 10683 _vector$4.add( _offset ); 10684 10685 } 10686 10687 maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$4 ) ); 10688 10689 } 10690 10691 } 10692 10693 } 10694 10695 this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); 10696 10697 if ( isNaN( this.boundingSphere.radius ) ) { 10698 10699 console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this ); 10700 10701 } 10702 10703 } 10704 10705 }, 10706 10707 computeFaceNormals: function () { 10708 10709 // backwards compatibility 10710 10711 }, 10712 10713 computeVertexNormals: function () { 10714 10715 var index = this.index; 10716 var attributes = this.attributes; 10717 10718 if ( attributes.position ) { 10719 10720 var positions = attributes.position.array; 10721 10722 if ( attributes.normal === undefined ) { 10723 10724 this.setAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) ); 10725 10726 } else { 10727 10728 // reset existing normals to zero 10729 10730 var array = attributes.normal.array; 10731 10732 for ( var i = 0, il = array.length; i < il; i ++ ) { 10733 10734 array[ i ] = 0; 10735 10736 } 10737 10738 } 10739 10740 var normals = attributes.normal.array; 10741 10742 var vA, vB, vC; 10743 var pA = new Vector3(), pB = new Vector3(), pC = new Vector3(); 10744 var cb = new Vector3(), ab = new Vector3(); 10745 10746 // indexed elements 10747 10748 if ( index ) { 10749 10750 var indices = index.array; 10751 10752 for ( var i = 0, il = index.count; i < il; i += 3 ) { 10753 10754 vA = indices[ i + 0 ] * 3; 10755 vB = indices[ i + 1 ] * 3; 10756 vC = indices[ i + 2 ] * 3; 10757 10758 pA.fromArray( positions, vA ); 10759 pB.fromArray( positions, vB ); 10760 pC.fromArray( positions, vC ); 10761 10762 cb.subVectors( pC, pB ); 10763 ab.subVectors( pA, pB ); 10764 cb.cross( ab ); 10765 10766 normals[ vA ] += cb.x; 10767 normals[ vA + 1 ] += cb.y; 10768 normals[ vA + 2 ] += cb.z; 10769 10770 normals[ vB ] += cb.x; 10771 normals[ vB + 1 ] += cb.y; 10772 normals[ vB + 2 ] += cb.z; 10773 10774 normals[ vC ] += cb.x; 10775 normals[ vC + 1 ] += cb.y; 10776 normals[ vC + 2 ] += cb.z; 10777 10778 } 10779 10780 } else { 10781 10782 // non-indexed elements (unconnected triangle soup) 10783 10784 for ( var i = 0, il = positions.length; i < il; i += 9 ) { 10785 10786 pA.fromArray( positions, i ); 10787 pB.fromArray( positions, i + 3 ); 10788 pC.fromArray( positions, i + 6 ); 10789 10790 cb.subVectors( pC, pB ); 10791 ab.subVectors( pA, pB ); 10792 cb.cross( ab ); 10793 10794 normals[ i ] = cb.x; 10795 normals[ i + 1 ] = cb.y; 10796 normals[ i + 2 ] = cb.z; 10797 10798 normals[ i + 3 ] = cb.x; 10799 normals[ i + 4 ] = cb.y; 10800 normals[ i + 5 ] = cb.z; 10801 10802 normals[ i + 6 ] = cb.x; 10803 normals[ i + 7 ] = cb.y; 10804 normals[ i + 8 ] = cb.z; 10805 10806 } 10807 10808 } 10809 10810 this.normalizeNormals(); 10811 10812 attributes.normal.needsUpdate = true; 10813 10814 } 10815 10816 }, 10817 10818 merge: function ( geometry, offset ) { 10819 10820 if ( ! ( geometry && geometry.isBufferGeometry ) ) { 10821 10822 console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry ); 10823 return; 10824 10825 } 10826 10827 if ( offset === undefined ) { 10828 10829 offset = 0; 10830 10831 console.warn( 10832 'THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' 10833 + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.' 10834 ); 10835 10836 } 10837 10838 var attributes = this.attributes; 10839 10840 for ( var key in attributes ) { 10841 10842 if ( geometry.attributes[ key ] === undefined ) continue; 10843 10844 var attribute1 = attributes[ key ]; 10845 var attributeArray1 = attribute1.array; 10846 10847 var attribute2 = geometry.attributes[ key ]; 10848 var attributeArray2 = attribute2.array; 10849 10850 var attributeOffset = attribute2.itemSize * offset; 10851 var length = Math.min( attributeArray2.length, attributeArray1.length - attributeOffset ); 10852 10853 for ( var i = 0, j = attributeOffset; i < length; i ++, j ++ ) { 10854 10855 attributeArray1[ j ] = attributeArray2[ i ]; 10856 10857 } 10858 10859 } 10860 10861 return this; 10862 10863 }, 10864 10865 normalizeNormals: function () { 10866 10867 var normals = this.attributes.normal; 10868 10869 for ( var i = 0, il = normals.count; i < il; i ++ ) { 10870 10871 _vector$4.x = normals.getX( i ); 10872 _vector$4.y = normals.getY( i ); 10873 _vector$4.z = normals.getZ( i ); 10874 10875 _vector$4.normalize(); 10876 10877 normals.setXYZ( i, _vector$4.x, _vector$4.y, _vector$4.z ); 10878 10879 } 10880 10881 }, 10882 10883 toNonIndexed: function () { 10884 10885 function convertBufferAttribute( attribute, indices ) { 10886 10887 var array = attribute.array; 10888 var itemSize = attribute.itemSize; 10889 10890 var array2 = new array.constructor( indices.length * itemSize ); 10891 10892 var index = 0, index2 = 0; 10893 10894 for ( var i = 0, l = indices.length; i < l; i ++ ) { 10895 10896 index = indices[ i ] * itemSize; 10897 10898 for ( var j = 0; j < itemSize; j ++ ) { 10899 10900 array2[ index2 ++ ] = array[ index ++ ]; 10901 10902 } 10903 10904 } 10905 10906 return new BufferAttribute( array2, itemSize ); 10907 10908 } 10909 10910 // 10911 10912 if ( this.index === null ) { 10913 10914 console.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' ); 10915 return this; 10916 10917 } 10918 10919 var geometry2 = new BufferGeometry(); 10920 10921 var indices = this.index.array; 10922 var attributes = this.attributes; 10923 10924 // attributes 10925 10926 for ( var name in attributes ) { 10927 10928 var attribute = attributes[ name ]; 10929 10930 var newAttribute = convertBufferAttribute( attribute, indices ); 10931 10932 geometry2.setAttribute( name, newAttribute ); 10933 10934 } 10935 10936 // morph attributes 10937 10938 var morphAttributes = this.morphAttributes; 10939 10940 for ( name in morphAttributes ) { 10941 10942 var morphArray = []; 10943 var morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes 10944 10945 for ( var i = 0, il = morphAttribute.length; i < il; i ++ ) { 10946 10947 var attribute = morphAttribute[ i ]; 10948 10949 var newAttribute = convertBufferAttribute( attribute, indices ); 10950 10951 morphArray.push( newAttribute ); 10952 10953 } 10954 10955 geometry2.morphAttributes[ name ] = morphArray; 10956 10957 } 10958 10959 geometry2.morphTargetsRelative = this.morphTargetsRelative; 10960 10961 // groups 10962 10963 var groups = this.groups; 10964 10965 for ( var i = 0, l = groups.length; i < l; i ++ ) { 10966 10967 var group = groups[ i ]; 10968 geometry2.addGroup( group.start, group.count, group.materialIndex ); 10969 10970 } 10971 10972 return geometry2; 10973 10974 },
vendor: 16,177 bytes, lines 10975-11736
10975 10976 toJSON: function () { 10977 10978 var data = { 10979 metadata: { 10980 version: 4.5, 10981 type: 'BufferGeometry', 10982 generator: 'BufferGeometry.toJSON' 10983 } 10984 }; 10985 10986 // standard BufferGeometry serialization 10987 10988 data.uuid = this.uuid; 10989 data.type = this.type; 10990 if ( this.name !== '' ) data.name = this.name; 10991 if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; 10992 10993 if ( this.parameters !== undefined ) { 10994 10995 var parameters = this.parameters; 10996 10997 for ( var key in parameters ) { 10998 10999 if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; 11000 11001 } 11002 11003 return data; 11004 11005 } 11006 11007 data.data = { attributes: {} }; 11008 11009 var index = this.index; 11010 11011 if ( index !== null ) { 11012 11013 data.data.index = { 11014 type: index.array.constructor.name, 11015 array: Array.prototype.slice.call( index.array ) 11016 }; 11017 11018 } 11019 11020 var attributes = this.attributes; 11021 11022 for ( var key in attributes ) { 11023 11024 var attribute = attributes[ key ]; 11025 11026 var attributeData = attribute.toJSON(); 11027 11028 if ( attribute.name !== '' ) attributeData.name = attribute.name; 11029 11030 data.data.attributes[ key ] = attributeData; 11031 11032 } 11033 11034 var morphAttributes = {}; 11035 var hasMorphAttributes = false; 11036 11037 for ( var key in this.morphAttributes ) { 11038 11039 var attributeArray = this.morphAttributes[ key ]; 11040 11041 var array = []; 11042 11043 for ( var i = 0, il = attributeArray.length; i < il; i ++ ) { 11044 11045 var attribute = attributeArray[ i ]; 11046 11047 var attributeData = attribute.toJSON(); 11048 11049 if ( attribute.name !== '' ) attributeData.name = attribute.name; 11050 11051 array.push( attributeData ); 11052 11053 } 11054 11055 if ( array.length > 0 ) { 11056 11057 morphAttributes[ key ] = array; 11058 11059 hasMorphAttributes = true; 11060 11061 } 11062 11063 } 11064 11065 if ( hasMorphAttributes ) { 11066 11067 data.data.morphAttributes = morphAttributes; 11068 data.data.morphTargetsRelative = this.morphTargetsRelative; 11069 11070 } 11071 11072 var groups = this.groups; 11073 11074 if ( groups.length > 0 ) { 11075 11076 data.data.groups = JSON.parse( JSON.stringify( groups ) ); 11077 11078 } 11079 11080 var boundingSphere = this.boundingSphere; 11081 11082 if ( boundingSphere !== null ) { 11083 11084 data.data.boundingSphere = { 11085 center: boundingSphere.center.toArray(), 11086 radius: boundingSphere.radius 11087 }; 11088 11089 } 11090 11091 return data; 11092 11093 }, 11094 11095 clone: function () { 11096 11097 /* 11098 // Handle primitives 11099 11100 var parameters = this.parameters; 11101 11102 if ( parameters !== undefined ) { 11103 11104 var values = []; 11105 11106 for ( var key in parameters ) { 11107 11108 values.push( parameters[ key ] ); 11109 11110 } 11111 11112 var geometry = Object.create( this.constructor.prototype ); 11113 this.constructor.apply( geometry, values ); 11114 return geometry; 11115 11116 } 11117 11118 return new this.constructor().copy( this ); 11119 */ 11120 11121 return new BufferGeometry().copy( this ); 11122 11123 }, 11124 11125 copy: function ( source ) { 11126 11127 var name, i, l; 11128 11129 // reset 11130 11131 this.index = null; 11132 this.attributes = {}; 11133 this.morphAttributes = {}; 11134 this.groups = []; 11135 this.boundingBox = null; 11136 this.boundingSphere = null; 11137 11138 // name 11139 11140 this.name = source.name; 11141 11142 // index 11143 11144 var index = source.index; 11145 11146 if ( index !== null ) { 11147 11148 this.setIndex( index.clone() ); 11149 11150 } 11151 11152 // attributes 11153 11154 var attributes = source.attributes; 11155 11156 for ( name in attributes ) { 11157 11158 var attribute = attributes[ name ]; 11159 this.setAttribute( name, attribute.clone() ); 11160 11161 } 11162 11163 // morph attributes 11164 11165 var morphAttributes = source.morphAttributes; 11166 11167 for ( name in morphAttributes ) { 11168 11169 var array = []; 11170 var morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes 11171 11172 for ( i = 0, l = morphAttribute.length; i < l; i ++ ) { 11173 11174 array.push( morphAttribute[ i ].clone() ); 11175 11176 } 11177 11178 this.morphAttributes[ name ] = array; 11179 11180 } 11181 11182 this.morphTargetsRelative = source.morphTargetsRelative; 11183 11184 // groups 11185 11186 var groups = source.groups; 11187 11188 for ( i = 0, l = groups.length; i < l; i ++ ) { 11189 11190 var group = groups[ i ]; 11191 this.addGroup( group.start, group.count, group.materialIndex ); 11192 11193 } 11194 11195 // bounding box 11196 11197 var boundingBox = source.boundingBox; 11198 11199 if ( boundingBox !== null ) { 11200 11201 this.boundingBox = boundingBox.clone(); 11202 11203 } 11204 11205 // bounding sphere 11206 11207 var boundingSphere = source.boundingSphere; 11208 11209 if ( boundingSphere !== null ) { 11210 11211 this.boundingSphere = boundingSphere.clone(); 11212 11213 } 11214 11215 // draw range 11216 11217 this.drawRange.start = source.drawRange.start; 11218 this.drawRange.count = source.drawRange.count; 11219 11220 // user data 11221 11222 this.userData = source.userData; 11223 11224 return this; 11225 11226 }, 11227 11228 dispose: function () { 11229 11230 this.dispatchEvent( { type: 'dispose' } ); 11231 11232 } 11233 11234} ); 11235 11236/** 11237 * @author mrdoob / http://mrdoob.com/ 11238 * @author alteredq / http://alteredqualia.com/ 11239 * @author mikael emtinger / http://gomo.se/ 11240 * @author jonobr1 / http://jonobr1.com/ 11241 */ 11242 11243var _inverseMatrix = new Matrix4(); 11244var _ray = new Ray(); 11245var _sphere = new Sphere(); 11246 11247var _vA = new Vector3(); 11248var _vB = new Vector3(); 11249var _vC = new Vector3(); 11250 11251var _tempA = new Vector3(); 11252var _tempB = new Vector3(); 11253var _tempC = new Vector3(); 11254 11255var _morphA = new Vector3(); 11256var _morphB = new Vector3(); 11257var _morphC = new Vector3(); 11258 11259var _uvA = new Vector2(); 11260var _uvB = new Vector2(); 11261var _uvC = new Vector2(); 11262 11263var _intersectionPoint = new Vector3(); 11264var _intersectionPointWorld = new Vector3(); 11265 11266function Mesh( geometry, material ) { 11267 11268 Object3D.call( this ); 11269 11270 this.type = 'Mesh'; 11271 11272 this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); 11273 this.material = material !== undefined ? material : new MeshBasicMaterial(); 11274 11275 this.updateMorphTargets(); 11276 11277} 11278 11279Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { 11280 11281 constructor: Mesh, 11282 11283 isMesh: true, 11284 11285 copy: function ( source ) { 11286 11287 Object3D.prototype.copy.call( this, source ); 11288 11289 if ( source.morphTargetInfluences !== undefined ) { 11290 11291 this.morphTargetInfluences = source.morphTargetInfluences.slice(); 11292 11293 } 11294 11295 if ( source.morphTargetDictionary !== undefined ) { 11296 11297 this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary ); 11298 11299 } 11300 11301 return this; 11302 11303 }, 11304 11305 updateMorphTargets: function () { 11306 11307 var geometry = this.geometry; 11308 var m, ml, name; 11309 11310 if ( geometry.isBufferGeometry ) { 11311 11312 var morphAttributes = geometry.morphAttributes; 11313 var keys = Object.keys( morphAttributes ); 11314 11315 if ( keys.length > 0 ) { 11316 11317 var morphAttribute = morphAttributes[ keys[ 0 ] ]; 11318 11319 if ( morphAttribute !== undefined ) { 11320 11321 this.morphTargetInfluences = []; 11322 this.morphTargetDictionary = {}; 11323 11324 for ( m = 0, ml = morphAttribute.length; m < ml; m ++ ) { 11325 11326 name = morphAttribute[ m ].name || String( m ); 11327 11328 this.morphTargetInfluences.push( 0 ); 11329 this.morphTargetDictionary[ name ] = m; 11330 11331 } 11332 11333 } 11334 11335 } 11336 11337 } else { 11338 11339 var morphTargets = geometry.morphTargets; 11340 11341 if ( morphTargets !== undefined && morphTargets.length > 0 ) { 11342 11343 console.error( 'THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' ); 11344 11345 } 11346 11347 } 11348 11349 }, 11350 11351 raycast: function ( raycaster, intersects ) { 11352 11353 var geometry = this.geometry; 11354 var material = this.material; 11355 var matrixWorld = this.matrixWorld; 11356 11357 if ( material === undefined ) return; 11358 11359 // Checking boundingSphere distance to ray 11360 11361 if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); 11362 11363 _sphere.copy( geometry.boundingSphere ); 11364 _sphere.applyMatrix4( matrixWorld ); 11365 11366 if ( raycaster.ray.intersectsSphere( _sphere ) === false ) return; 11367 11368 // 11369 11370 _inverseMatrix.getInverse( matrixWorld ); 11371 _ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix ); 11372 11373 // Check boundingBox before continuing 11374 11375 if ( geometry.boundingBox !== null ) { 11376 11377 if ( _ray.intersectsBox( geometry.boundingBox ) === false ) return; 11378 11379 } 11380 11381 var intersection; 11382 11383 if ( geometry.isBufferGeometry ) { 11384 11385 var a, b, c; 11386 var index = geometry.index; 11387 var position = geometry.attributes.position; 11388 var morphPosition = geometry.morphAttributes.position; 11389 var morphTargetsRelative = geometry.morphTargetsRelative; 11390 var uv = geometry.attributes.uv; 11391 var uv2 = geometry.attributes.uv2; 11392 var groups = geometry.groups; 11393 var drawRange = geometry.drawRange; 11394 var i, j, il, jl; 11395 var group, groupMaterial; 11396 var start, end; 11397 11398 if ( index !== null ) { 11399 11400 // indexed buffer geometry 11401 11402 if ( Array.isArray( material ) ) { 11403 11404 for ( i = 0, il = groups.length; i < il; i ++ ) { 11405 11406 group = groups[ i ]; 11407 groupMaterial = material[ group.materialIndex ]; 11408 11409 start = Math.max( group.start, drawRange.start ); 11410 end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); 11411 11412 for ( j = start, jl = end; j < jl; j += 3 ) { 11413 11414 a = index.getX( j ); 11415 b = index.getX( j + 1 ); 11416 c = index.getX( j + 2 ); 11417 11418 intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); 11419 11420 if ( intersection ) { 11421 11422 intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics 11423 intersection.face.materialIndex = group.materialIndex; 11424 intersects.push( intersection ); 11425 11426 } 11427 11428 } 11429 11430 } 11431 11432 } else { 11433 11434 start = Math.max( 0, drawRange.start ); 11435 end = Math.min( index.count, ( drawRange.start + drawRange.count ) ); 11436 11437 for ( i = start, il = end; i < il; i += 3 ) { 11438 11439 a = index.getX( i ); 11440 b = index.getX( i + 1 ); 11441 c = index.getX( i + 2 ); 11442 11443 intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); 11444 11445 if ( intersection ) { 11446 11447 intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics 11448 intersects.push( intersection ); 11449 11450 } 11451 11452 } 11453 11454 } 11455 11456 } else if ( position !== undefined ) { 11457 11458 // non-indexed buffer geometry 11459 11460 if ( Array.isArray( material ) ) { 11461 11462 for ( i = 0, il = groups.length; i < il; i ++ ) { 11463 11464 group = groups[ i ]; 11465 groupMaterial = material[ group.materialIndex ]; 11466 11467 start = Math.max( group.start, drawRange.start ); 11468 end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); 11469 11470 for ( j = start, jl = end; j < jl; j += 3 ) { 11471 11472 a = j; 11473 b = j + 1; 11474 c = j + 2; 11475 11476 intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); 11477 11478 if ( intersection ) { 11479 11480 intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics 11481 intersection.face.materialIndex = group.materialIndex; 11482 intersects.push( intersection ); 11483 11484 } 11485 11486 } 11487 11488 } 11489 11490 } else { 11491 11492 start = Math.max( 0, drawRange.start ); 11493 end = Math.min( position.count, ( drawRange.start + drawRange.count ) ); 11494 11495 for ( i = start, il = end; i < il; i += 3 ) { 11496 11497 a = i; 11498 b = i + 1; 11499 c = i + 2; 11500 11501 intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); 11502 11503 if ( intersection ) { 11504 11505 intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics 11506 intersects.push( intersection ); 11507 11508 } 11509 11510 } 11511 11512 } 11513 11514 } 11515 11516 } else if ( geometry.isGeometry ) { 11517 11518 var fvA, fvB, fvC; 11519 var isMultiMaterial = Array.isArray( material ); 11520 11521 var vertices = geometry.vertices; 11522 var faces = geometry.faces; 11523 var uvs; 11524 11525 var faceVertexUvs = geometry.faceVertexUvs[ 0 ]; 11526 if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs; 11527 11528 for ( var f = 0, fl = faces.length; f < fl; f ++ ) { 11529 11530 var face = faces[ f ]; 11531 var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material; 11532 11533 if ( faceMaterial === undefined ) continue; 11534 11535 fvA = vertices[ face.a ]; 11536 fvB = vertices[ face.b ]; 11537 fvC = vertices[ face.c ]; 11538 11539 intersection = checkIntersection( this, faceMaterial, raycaster, _ray, fvA, fvB, fvC, _intersectionPoint ); 11540 11541 if ( intersection ) { 11542 11543 if ( uvs && uvs[ f ] ) { 11544 11545 var uvs_f = uvs[ f ]; 11546 _uvA.copy( uvs_f[ 0 ] ); 11547 _uvB.copy( uvs_f[ 1 ] ); 11548 _uvC.copy( uvs_f[ 2 ] ); 11549 11550 intersection.uv = Triangle.getUV( _intersectionPoint, fvA, fvB, fvC, _uvA, _uvB, _uvC, new Vector2() ); 11551 11552 } 11553 11554 intersection.face = face; 11555 intersection.faceIndex = f; 11556 intersects.push( intersection ); 11557 11558 } 11559 11560 } 11561 11562 } 11563 11564 }, 11565 11566 clone: function () { 11567 11568 return new this.constructor( this.geometry, this.material ).copy( this ); 11569 11570 } 11571 11572} ); 11573 11574function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) { 11575 11576 var intersect; 11577 11578 if ( material.side === BackSide ) { 11579 11580 intersect = ray.intersectTriangle( pC, pB, pA, true, point ); 11581 11582 } else { 11583 11584 intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point ); 11585 11586 } 11587 11588 if ( intersect === null ) return null; 11589 11590 _intersectionPointWorld.copy( point ); 11591 _intersectionPointWorld.applyMatrix4( object.matrixWorld ); 11592 11593 var distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld ); 11594 11595 if ( distance < raycaster.near || distance > raycaster.far ) return null; 11596 11597 return { 11598 distance: distance, 11599 point: _intersectionPointWorld.clone(), 11600 object: object 11601 }; 11602 11603} 11604 11605function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ) { 11606 11607 _vA.fromBufferAttribute( position, a ); 11608 _vB.fromBufferAttribute( position, b ); 11609 _vC.fromBufferAttribute( position, c ); 11610 11611 var morphInfluences = object.morphTargetInfluences; 11612 11613 if ( material.morphTargets && morphPosition && morphInfluences ) { 11614 11615 _morphA.set( 0, 0, 0 ); 11616 _morphB.set( 0, 0, 0 ); 11617 _morphC.set( 0, 0, 0 ); 11618 11619 for ( var i = 0, il = morphPosition.length; i < il; i ++ ) { 11620 11621 var influence = morphInfluences[ i ]; 11622 var morphAttribute = morphPosition[ i ]; 11623 11624 if ( influence === 0 ) continue; 11625 11626 _tempA.fromBufferAttribute( morphAttribute, a ); 11627 _tempB.fromBufferAttribute( morphAttribute, b ); 11628 _tempC.fromBufferAttribute( morphAttribute, c ); 11629 11630 if ( morphTargetsRelative ) { 11631 11632 _morphA.addScaledVector( _tempA, influence ); 11633 _morphB.addScaledVector( _tempB, influence ); 11634 _morphC.addScaledVector( _tempC, influence ); 11635 11636 } else { 11637 11638 _morphA.addScaledVector( _tempA.sub( _vA ), influence ); 11639 _morphB.addScaledVector( _tempB.sub( _vB ), influence ); 11640 _morphC.addScaledVector( _tempC.sub( _vC ), influence ); 11641 11642 } 11643 11644 } 11645 11646 _vA.add( _morphA ); 11647 _vB.add( _morphB ); 11648 _vC.add( _morphC ); 11649 11650 } 11651 11652 if ( object.isSkinnedMesh ) { 11653 11654 object.boneTransform( a, _vA ); 11655 object.boneTransform( b, _vB ); 11656 object.boneTransform( c, _vC ); 11657 11658 } 11659 11660 var intersection = checkIntersection( object, material, raycaster, ray, _vA, _vB, _vC, _intersectionPoint ); 11661 11662 if ( intersection ) { 11663 11664 if ( uv ) { 11665 11666 _uvA.fromBufferAttribute( uv, a ); 11667 _uvB.fromBufferAttribute( uv, b ); 11668 _uvC.fromBufferAttribute( uv, c ); 11669 11670 intersection.uv = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() ); 11671 11672 } 11673 11674 if ( uv2 ) { 11675 11676 _uvA.fromBufferAttribute( uv2, a ); 11677 _uvB.fromBufferAttribute( uv2, b ); 11678 _uvC.fromBufferAttribute( uv2, c ); 11679 11680 intersection.uv2 = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() ); 11681 11682 } 11683 11684 var face = new Face3( a, b, c ); 11685 Triangle.getNormal( _vA, _vB, _vC, face.normal ); 11686 11687 intersection.face = face; 11688 11689 } 11690 11691 return intersection; 11692 11693} 11694 11695/** 11696 * @author mrdoob / http://mrdoob.com/ 11697 * @author kile / http://kile.stravaganza.org/ 11698 * @author alteredq / http://alteredqualia.com/ 11699 * @author mikael emtinger / http://gomo.se/ 11700 * @author zz85 / http://www.lab4games.net/zz85/blog 11701 * @author bhouston / http://clara.io 11702 */ 11703 11704var _geometryId = 0; // Geometry uses even numbers as Id 11705var _m1$3 = new Matrix4(); 11706var _obj$1 = new Object3D(); 11707var _offset$1 = new Vector3(); 11708 11709function Geometry() { 11710 11711 Object.defineProperty( this, 'id', { value: _geometryId += 2 } ); 11712 11713 this.uuid = MathUtils.generateUUID(); 11714 11715 this.name = ''; 11716 this.type = 'Geometry'; 11717 11718 this.vertices = []; 11719 this.colors = []; 11720 this.faces = []; 11721 this.faceVertexUvs = [[]]; 11722 11723 this.morphTargets = []; 11724 this.morphNormals = []; 11725 11726 this.skinWeights = []; 11727 this.skinIndices = []; 11728 11729 this.lineDistances = []; 11730 11731 this.boundingBox = null; 11732 this.boundingSphere = null; 11733 11734 // update flags 11735 11736 this.elementsNeedUpdate = false;
11737 this.verticesNeedUpdate = false; 11738 this.uvsNeedUpdate = false; 11739 this.normalsNeedUpdate = false; 11740 this.colorsNeedUpdate = false; 11741 this.lineDistancesNeedUpdate = false; 11742 this.groupsNeedUpdate = false; 11743 11744} 11745 11746Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { 11747 11748 constructor: Geometry, 11749 11750 isGeometry: true, 11751 11752 applyMatrix4: function ( matrix ) { 11753 11754 var normalMatrix = new Matrix3().getNormalMatrix( matrix ); 11755 11756 for ( var i = 0, il = this.vertices.length; i < il; i ++ ) { 11757 11758 var vertex = this.vertices[ i ]; 11759 vertex.applyMatrix4( matrix ); 11760 11761 } 11762 11763 for ( var i = 0, il = this.faces.length; i < il; i ++ ) { 11764 11765 var face = this.faces[ i ]; 11766 face.normal.applyMatrix3( normalMatrix ).normalize(); 11767 11768 for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { 11769 11770 face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize(); 11771 11772 } 11773 11774 } 11775 11776 if ( this.boundingBox !== null ) { 11777 11778 this.computeBoundingBox(); 11779 11780 } 11781 11782 if ( this.boundingSphere !== null ) { 11783 11784 this.computeBoundingSphere(); 11785 11786 } 11787 11788 this.verticesNeedUpdate = true; 11789 this.normalsNeedUpdate = true; 11790 11791 return this; 11792 11793 }, 11794 11795 rotateX: function ( angle ) { 11796 11797 // rotate geometry around world x-axis 11798 11799 _m1$3.makeRotationX( angle ); 11800 11801 this.applyMatrix4( _m1$3 ); 11802 11803 return this; 11804 11805 }, 11806 11807 rotateY: function ( angle ) { 11808 11809 // rotate geometry around world y-axis 11810 11811 _m1$3.makeRotationY( angle ); 11812 11813 this.applyMatrix4( _m1$3 ); 11814 11815 return this; 11816 11817 }, 11818 11819 rotateZ: function ( angle ) { 11820 11821 // rotate geometry around world z-axis 11822 11823 _m1$3.makeRotationZ( angle ); 11824 11825 this.applyMatrix4( _m1$3 ); 11826 11827 return this; 11828 11829 }, 11830 11831 translate: function ( x, y, z ) { 11832 11833 // translate geometry 11834 11835 _m1$3.makeTranslation( x, y, z ); 11836 11837 this.applyMatrix4( _m1$3 ); 11838 11839 return this; 11840 11841 }, 11842 11843 scale: function ( x, y, z ) { 11844 11845 // scale geometry 11846 11847 _m1$3.makeScale( x, y, z ); 11848 11849 this.applyMatrix4( _m1$3 ); 11850 11851 return this; 11852 11853 }, 11854 11855 lookAt: function ( vector ) { 11856 11857 _obj$1.lookAt( vector ); 11858 11859 _obj$1.updateMatrix(); 11860 11861 this.applyMatrix4( _obj$1.matrix ); 11862 11863 return this; 11864 11865 }, 11866 11867 fromBufferGeometry: function ( geometry ) { 11868 11869 var scope = this; 11870 11871 var indices = geometry.index !== null ? geometry.index.array : undefined; 11872 var attributes = geometry.attributes; 11873 11874 if ( attributes.position === undefined ) { 11875 11876 console.error( 'THREE.Geometry.fromBufferGeometry(): Position attribute required for conversion.' ); 11877 return this; 11878 11879 } 11880 11881 var positions = attributes.position.array; 11882 var normals = attributes.normal !== undefined ? attributes.normal.array : undefined; 11883 var colors = attributes.color !== undefined ? attributes.color.array : undefined; 11884 var uvs = attributes.uv !== undefined ? attributes.uv.array : undefined; 11885 var uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined; 11886 11887 if ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = []; 11888 11889 for ( var i = 0; i < positions.length; i += 3 ) { 11890 11891 scope.vertices.push( new Vector3().fromArray( positions, i ) ); 11892 11893 if ( colors !== undefined ) { 11894 11895 scope.colors.push( new Color().fromArray( colors, i ) ); 11896 11897 } 11898 11899 } 11900 11901 function addFace( a, b, c, materialIndex ) { 11902 11903 var vertexColors = ( colors === undefined ) ? [] : [ 11904 scope.colors[ a ].clone(), 11905 scope.colors[ b ].clone(), 11906 scope.colors[ c ].clone() ]; 11907 11908 var vertexNormals = ( normals === undefined ) ? [] : [ 11909 new Vector3().fromArray( normals, a * 3 ), 11910 new Vector3().fromArray( normals, b * 3 ), 11911 new Vector3().fromArray( normals, c * 3 ) 11912 ]; 11913 11914 var face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex ); 11915 11916 scope.faces.push( face ); 11917 11918 if ( uvs !== undefined ) { 11919 11920 scope.faceVertexUvs[ 0 ].push( [ 11921 new Vector2().fromArray( uvs, a * 2 ), 11922 new Vector2().fromArray( uvs, b * 2 ), 11923 new Vector2().fromArray( uvs, c * 2 ) 11924 ] ); 11925 11926 } 11927 11928 if ( uvs2 !== undefined ) { 11929 11930 scope.faceVertexUvs[ 1 ].push( [ 11931 new Vector2().fromArray( uvs2, a * 2 ), 11932 new Vector2().fromArray( uvs2, b * 2 ), 11933 new Vector2().fromArray( uvs2, c * 2 ) 11934 ] ); 11935 11936 } 11937 11938 } 11939 11940 var groups = geometry.groups; 11941 11942 if ( groups.length > 0 ) { 11943 11944 for ( var i = 0; i < groups.length; i ++ ) { 11945 11946 var group = groups[ i ]; 11947 11948 var start = group.start; 11949 var count = group.count; 11950 11951 for ( var j = start, jl = start + count; j < jl; j += 3 ) { 11952 11953 if ( indices !== undefined ) { 11954 11955 addFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex ); 11956 11957 } else { 11958 11959 addFace( j, j + 1, j + 2, group.materialIndex ); 11960 11961 } 11962 11963 } 11964 11965 } 11966 11967 } else { 11968 11969 if ( indices !== undefined ) { 11970 11971 for ( var i = 0; i < indices.length; i += 3 ) { 11972 11973 addFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] ); 11974 11975 } 11976 11977 } else { 11978 11979 for ( var i = 0; i < positions.length / 3; i += 3 ) { 11980 11981 addFace( i, i + 1, i + 2 ); 11982 11983 } 11984 11985 } 11986 11987 } 11988 11989 this.computeFaceNormals(); 11990 11991 if ( geometry.boundingBox !== null ) { 11992 11993 this.boundingBox = geometry.boundingBox.clone(); 11994 11995 } 11996 11997 if ( geometry.boundingSphere !== null ) { 11998 11999 this.boundingSphere = geometry.boundingSphere.clone(); 12000 12001 } 12002 12003 return this; 12004 12005 }, 12006 12007 center: function () { 12008 12009 this.computeBoundingBox(); 12010 12011 this.boundingBox.getCenter( _offset$1 ).negate(); 12012 12013 this.translate( _offset$1.x, _offset$1.y, _offset$1.z ); 12014 12015 return this; 12016 12017 }, 12018 12019 normalize: function () { 12020 12021 this.computeBoundingSphere(); 12022 12023 var center = this.boundingSphere.center; 12024 var radius = this.boundingSphere.radius; 12025
12026 var s = radius === 0 ? 1 : 1.0 / radius; 12027 12028 var matrix = new Matrix4(); 12029 matrix.set( 12030 s, 0, 0, - s * center.x, 12031 0, s, 0, - s * center.y, 12032 0, 0, s, - s * center.z, 12033 0, 0, 0, 1 12034 ); 12035 12036 this.applyMatrix4( matrix ); 12037 12038 return this; 12039 12040 }, 12041 12042 computeFaceNormals: function () { 12043 12044 var cb = new Vector3(), ab = new Vector3(); 12045 12046 for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) { 12047 12048 var face = this.faces[ f ]; 12049 12050 var vA = this.vertices[ face.a ]; 12051 var vB = this.vertices[ face.b ]; 12052 var vC = this.vertices[ face.c ]; 12053 12054 cb.subVectors( vC, vB ); 12055 ab.subVectors( vA, vB ); 12056 cb.cross( ab ); 12057 12058 cb.normalize(); 12059 12060 face.normal.copy( cb ); 12061 12062 } 12063 12064 }, 12065 12066 computeVertexNormals: function ( areaWeighted ) { 12067 12068 if ( areaWeighted === undefined ) areaWeighted = true; 12069 12070 var v, vl, f, fl, face, vertices; 12071 12072 vertices = new Array( this.vertices.length ); 12073 12074 for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { 12075 12076 vertices[ v ] = new Vector3(); 12077 12078 } 12079 12080 if ( areaWeighted ) { 12081 12082 // vertex normals weighted by triangle areas 12083 // http://www.iquilezles.org/www/articles/normals/normals.htm 12084 12085 var vA, vB, vC; 12086 var cb = new Vector3(), ab = new Vector3(); 12087 12088 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 12089 12090 face = this.faces[ f ]; 12091 12092 vA = this.vertices[ face.a ]; 12093 vB = this.vertices[ face.b ]; 12094 vC = this.vertices[ face.c ]; 12095 12096 cb.subVectors( vC, vB ); 12097 ab.subVectors( vA, vB ); 12098 cb.cross( ab ); 12099 12100 vertices[ face.a ].add( cb ); 12101 vertices[ face.b ].add( cb ); 12102 vertices[ face.c ].add( cb ); 12103 12104 } 12105 12106 } else { 12107 12108 this.computeFaceNormals(); 12109 12110 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 12111 12112 face = this.faces[ f ]; 12113 12114 vertices[ face.a ].add( face.normal ); 12115 vertices[ face.b ].add( face.normal ); 12116 vertices[ face.c ].add( face.normal ); 12117 12118 } 12119 12120 } 12121 12122 for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { 12123 12124 vertices[ v ].normalize(); 12125 12126 } 12127 12128 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 12129 12130 face = this.faces[ f ]; 12131 12132 var vertexNormals = face.vertexNormals; 12133 12134 if ( vertexNormals.length === 3 ) { 12135 12136 vertexNormals[ 0 ].copy( vertices[ face.a ] ); 12137 vertexNormals[ 1 ].copy( vertices[ face.b ] ); 12138 vertexNormals[ 2 ].copy( vertices[ face.c ] ); 12139 12140 } else { 12141 12142 vertexNormals[ 0 ] = vertices[ face.a ].clone(); 12143 vertexNormals[ 1 ] = vertices[ face.b ].clone(); 12144 vertexNormals[ 2 ] = vertices[ face.c ].clone(); 12145 12146 } 12147 12148 } 12149 12150 if ( this.faces.length > 0 ) { 12151 12152 this.normalsNeedUpdate = true; 12153 12154 } 12155 12156 }, 12157 12158 computeFlatVertexNormals: function () { 12159 12160 var f, fl, face; 12161 12162 this.computeFaceNormals(); 12163 12164 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 12165 12166 face = this.faces[ f ]; 12167 12168 var vertexNormals = face.vertexNormals; 12169 12170 if ( vertexNormals.length === 3 ) { 12171 12172 vertexNormals[ 0 ].copy( face.normal ); 12173 vertexNormals[ 1 ].copy( face.normal ); 12174 vertexNormals[ 2 ].copy( face.normal ); 12175 12176 } else { 12177 12178 vertexNormals[ 0 ] = face.normal.clone(); 12179 vertexNormals[ 1 ] = face.normal.clone(); 12180 vertexNormals[ 2 ] = face.normal.clone(); 12181 12182 } 12183 12184 } 12185 12186 if ( this.faces.length > 0 ) { 12187 12188 this.normalsNeedUpdate = true; 12189 12190 } 12191 12192 }, 12193 12194 computeMorphNormals: function () { 12195 12196 var i, il, f, fl, face; 12197 12198 // save original normals 12199 // - create temp variables on first access 12200 // otherwise just copy (for faster repeated calls) 12201 12202 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 12203 12204 face = this.faces[ f ]; 12205
12206 if ( ! face.__originalFaceNormal ) { 12207 12208 face.__originalFaceNormal = face.normal.clone(); 12209 12210 } else { 12211 12212 face.__originalFaceNormal.copy( face.normal ); 12213 12214 } 12215 12216 if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = []; 12217 12218 for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) { 12219 12220 if ( ! face.__originalVertexNormals[ i ] ) { 12221 12222 face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone(); 12223 12224 } else { 12225 12226 face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] ); 12227 12228 } 12229 12230 } 12231 12232 } 12233 12234 // use temp geometry to compute face and vertex normals for each morph 12235 12236 var tmpGeo = new Geometry(); 12237 tmpGeo.faces = this.faces; 12238 12239 for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) { 12240 12241 // create on first access 12242 12243 if ( ! this.morphNormals[ i ] ) { 12244 12245 this.morphNormals[ i ] = {}; 12246 this.morphNormals[ i ].faceNormals = []; 12247 this.morphNormals[ i ].vertexNormals = []; 12248 12249 var dstNormalsFace = this.morphNormals[ i ].faceNormals; 12250 var dstNormalsVertex = this.morphNormals[ i ].vertexNormals; 12251 12252 var faceNormal, vertexNormals; 12253 12254 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 12255 12256 faceNormal = new Vector3(); 12257 vertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() }; 12258 12259 dstNormalsFace.push( faceNormal ); 12260 dstNormalsVertex.push( vertexNormals ); 12261 12262 } 12263 12264 } 12265 12266 var morphNormals = this.morphNormals[ i ]; 12267 12268 // set vertices to morph target 12269 12270 tmpGeo.vertices = this.morphTargets[ i ].vertices; 12271 12272 // compute morph normals 12273 12274 tmpGeo.computeFaceNormals(); 12275 tmpGeo.computeVertexNormals(); 12276 12277 // store morph normals 12278 12279 var faceNormal, vertexNormals; 12280 12281 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 12282 12283 face = this.faces[ f ]; 12284 12285 faceNormal = morphNormals.faceNormals[ f ]; 12286 vertexNormals = morphNormals.vertexNormals[ f ]; 12287 12288 faceNormal.copy( face.normal ); 12289 12290 vertexNormals.a.copy( face.vertexNormals[ 0 ] ); 12291 vertexNormals.b.copy( face.vertexNormals[ 1 ] ); 12292 vertexNormals.c.copy( face.vertexNormals[ 2 ] ); 12293 12294 } 12295 12296 } 12297 12298 // restore original normals 12299 12300 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 12301 12302 face = this.faces[ f ]; 12303
vendor: 26,128 bytes, lines 12304-13596
12304 face.normal = face.__originalFaceNormal; 12305 face.vertexNormals = face.__originalVertexNormals; 12306 12307 } 12308 12309 }, 12310 12311 computeBoundingBox: function () { 12312 12313 if ( this.boundingBox === null ) { 12314 12315 this.boundingBox = new Box3(); 12316 12317 } 12318 12319 this.boundingBox.setFromPoints( this.vertices ); 12320 12321 }, 12322 12323 computeBoundingSphere: function () { 12324 12325 if ( this.boundingSphere === null ) { 12326 12327 this.boundingSphere = new Sphere(); 12328 12329 } 12330 12331 this.boundingSphere.setFromPoints( this.vertices ); 12332 12333 }, 12334 12335 merge: function ( geometry, matrix, materialIndexOffset ) { 12336 12337 if ( ! ( geometry && geometry.isGeometry ) ) { 12338 12339 console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry ); 12340 return; 12341 12342 } 12343 12344 var normalMatrix, 12345 vertexOffset = this.vertices.length, 12346 vertices1 = this.vertices, 12347 vertices2 = geometry.vertices, 12348 faces1 = this.faces, 12349 faces2 = geometry.faces, 12350 colors1 = this.colors, 12351 colors2 = geometry.colors; 12352 12353 if ( materialIndexOffset === undefined ) materialIndexOffset = 0; 12354 12355 if ( matrix !== undefined ) { 12356 12357 normalMatrix = new Matrix3().getNormalMatrix( matrix ); 12358 12359 } 12360 12361 // vertices 12362 12363 for ( var i = 0, il = vertices2.length; i < il; i ++ ) { 12364 12365 var vertex = vertices2[ i ]; 12366 12367 var vertexCopy = vertex.clone(); 12368 12369 if ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix ); 12370 12371 vertices1.push( vertexCopy ); 12372 12373 } 12374 12375 // colors 12376 12377 for ( var i = 0, il = colors2.length; i < il; i ++ ) { 12378 12379 colors1.push( colors2[ i ].clone() ); 12380 12381 } 12382 12383 // faces 12384 12385 for ( i = 0, il = faces2.length; i < il; i ++ ) { 12386 12387 var face = faces2[ i ], faceCopy, normal, color, 12388 faceVertexNormals = face.vertexNormals, 12389 faceVertexColors = face.vertexColors; 12390 12391 faceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset ); 12392 faceCopy.normal.copy( face.normal ); 12393 12394 if ( normalMatrix !== undefined ) { 12395 12396 faceCopy.normal.applyMatrix3( normalMatrix ).normalize(); 12397 12398 } 12399 12400 for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) { 12401 12402 normal = faceVertexNormals[ j ].clone(); 12403 12404 if ( normalMatrix !== undefined ) { 12405 12406 normal.applyMatrix3( normalMatrix ).normalize(); 12407 12408 } 12409 12410 faceCopy.vertexNormals.push( normal ); 12411 12412 } 12413 12414 faceCopy.color.copy( face.color ); 12415 12416 for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) { 12417 12418 color = faceVertexColors[ j ]; 12419 faceCopy.vertexColors.push( color.clone() ); 12420 12421 } 12422 12423 faceCopy.materialIndex = face.materialIndex + materialIndexOffset; 12424 12425 faces1.push( faceCopy ); 12426 12427 } 12428 12429 // uvs 12430 12431 for ( var i = 0, il = geometry.faceVertexUvs.length; i < il; i ++ ) { 12432 12433 var faceVertexUvs2 = geometry.faceVertexUvs[ i ]; 12434 12435 if ( this.faceVertexUvs[ i ] === undefined ) this.faceVertexUvs[ i ] = []; 12436 12437 for ( var j = 0, jl = faceVertexUvs2.length; j < jl; j ++ ) { 12438 12439 var uvs2 = faceVertexUvs2[ j ], uvsCopy = []; 12440 12441 for ( var k = 0, kl = uvs2.length; k < kl; k ++ ) { 12442 12443 uvsCopy.push( uvs2[ k ].clone() ); 12444 12445 } 12446 12447 this.faceVertexUvs[ i ].push( uvsCopy ); 12448 12449 } 12450 12451 } 12452 12453 }, 12454 12455 mergeMesh: function ( mesh ) { 12456 12457 if ( ! ( mesh && mesh.isMesh ) ) { 12458 12459 console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh ); 12460 return; 12461 12462 } 12463 12464 if ( mesh.matrixAutoUpdate ) mesh.updateMatrix(); 12465 12466 this.merge( mesh.geometry, mesh.matrix ); 12467 12468 }, 12469 12470 /* 12471 * Checks for duplicate vertices with hashmap. 12472 * Duplicated vertices are removed 12473 * and faces' vertices are updated. 12474 */ 12475 12476 mergeVertices: function () { 12477 12478 var verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique) 12479 var unique = [], changes = []; 12480 12481 var v, key; 12482 var precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001 12483 var precision = Math.pow( 10, precisionPoints ); 12484 var i, il, face; 12485 var indices, j, jl; 12486 12487 for ( i = 0, il = this.vertices.length; i < il; i ++ ) { 12488 12489 v = this.vertices[ i ]; 12490 key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision ); 12491 12492 if ( verticesMap[ key ] === undefined ) { 12493 12494 verticesMap[ key ] = i; 12495 unique.push( this.vertices[ i ] ); 12496 changes[ i ] = unique.length - 1; 12497 12498 } else { 12499 12500 //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]); 12501 changes[ i ] = changes[ verticesMap[ key ] ]; 12502 12503 } 12504 12505 } 12506 12507 12508 // if faces are completely degenerate after merging vertices, we 12509 // have to remove them from the geometry. 12510 var faceIndicesToRemove = []; 12511 12512 for ( i = 0, il = this.faces.length; i < il; i ++ ) { 12513 12514 face = this.faces[ i ]; 12515 12516 face.a = changes[ face.a ]; 12517 face.b = changes[ face.b ]; 12518 face.c = changes[ face.c ]; 12519 12520 indices = [ face.a, face.b, face.c ]; 12521 12522 // if any duplicate vertices are found in a Face3 12523 // we have to remove the face as nothing can be saved 12524 for ( var n = 0; n < 3; n ++ ) { 12525 12526 if ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) { 12527 12528 faceIndicesToRemove.push( i ); 12529 break; 12530 12531 } 12532 12533 } 12534 12535 } 12536 12537 for ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) { 12538 12539 var idx = faceIndicesToRemove[ i ]; 12540 12541 this.faces.splice( idx, 1 ); 12542 12543 for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) { 12544 12545 this.faceVertexUvs[ j ].splice( idx, 1 ); 12546 12547 } 12548 12549 } 12550 12551 // Use unique set of vertices 12552 12553 var diff = this.vertices.length - unique.length; 12554 this.vertices = unique; 12555 return diff; 12556 12557 }, 12558 12559 setFromPoints: function ( points ) { 12560 12561 this.vertices = []; 12562 12563 for ( var i = 0, l = points.length; i < l; i ++ ) { 12564 12565 var point = points[ i ]; 12566 this.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) ); 12567 12568 } 12569 12570 return this; 12571 12572 }, 12573 12574 sortFacesByMaterialIndex: function () { 12575 12576 var faces = this.faces; 12577 var length = faces.length; 12578 12579 // tag faces 12580 12581 for ( var i = 0; i < length; i ++ ) { 12582 12583 faces[ i ]._id = i; 12584 12585 } 12586 12587 // sort faces 12588 12589 function materialIndexSort( a, b ) { 12590 12591 return a.materialIndex - b.materialIndex; 12592 12593 } 12594 12595 faces.sort( materialIndexSort ); 12596 12597 // sort uvs 12598 12599 var uvs1 = this.faceVertexUvs[ 0 ]; 12600 var uvs2 = this.faceVertexUvs[ 1 ]; 12601 12602 var newUvs1, newUvs2; 12603 12604 if ( uvs1 && uvs1.length === length ) newUvs1 = []; 12605 if ( uvs2 && uvs2.length === length ) newUvs2 = []; 12606 12607 for ( var i = 0; i < length; i ++ ) { 12608 12609 var id = faces[ i ]._id; 12610 12611 if ( newUvs1 ) newUvs1.push( uvs1[ id ] ); 12612 if ( newUvs2 ) newUvs2.push( uvs2[ id ] ); 12613 12614 } 12615 12616 if ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1; 12617 if ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2; 12618 12619 }, 12620 12621 toJSON: function () { 12622 12623 var data = { 12624 metadata: { 12625 version: 4.5, 12626 type: 'Geometry', 12627 generator: 'Geometry.toJSON' 12628 } 12629 }; 12630 12631 // standard Geometry serialization 12632 12633 data.uuid = this.uuid; 12634 data.type = this.type; 12635 if ( this.name !== '' ) data.name = this.name; 12636 12637 if ( this.parameters !== undefined ) { 12638 12639 var parameters = this.parameters; 12640 12641 for ( var key in parameters ) { 12642 12643 if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; 12644 12645 } 12646 12647 return data; 12648 12649 } 12650 12651 var vertices = []; 12652 12653 for ( var i = 0; i < this.vertices.length; i ++ ) { 12654 12655 var vertex = this.vertices[ i ]; 12656 vertices.push( vertex.x, vertex.y, vertex.z ); 12657 12658 } 12659 12660 var faces = []; 12661 var normals = []; 12662 var normalsHash = {}; 12663 var colors = []; 12664 var colorsHash = {}; 12665 var uvs = []; 12666 var uvsHash = {}; 12667 12668 for ( var i = 0; i < this.faces.length; i ++ ) { 12669 12670 var face = this.faces[ i ]; 12671 12672 var hasMaterial = true; 12673 var hasFaceUv = false; // deprecated 12674 var hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined; 12675 var hasFaceNormal = face.normal.length() > 0; 12676 var hasFaceVertexNormal = face.vertexNormals.length > 0; 12677 var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1; 12678 var hasFaceVertexColor = face.vertexColors.length > 0; 12679 12680 var faceType = 0; 12681 12682 faceType = setBit( faceType, 0, 0 ); // isQuad 12683 faceType = setBit( faceType, 1, hasMaterial ); 12684 faceType = setBit( faceType, 2, hasFaceUv ); 12685 faceType = setBit( faceType, 3, hasFaceVertexUv ); 12686 faceType = setBit( faceType, 4, hasFaceNormal ); 12687 faceType = setBit( faceType, 5, hasFaceVertexNormal ); 12688 faceType = setBit( faceType, 6, hasFaceColor ); 12689 faceType = setBit( faceType, 7, hasFaceVertexColor ); 12690 12691 faces.push( faceType ); 12692 faces.push( face.a, face.b, face.c ); 12693 faces.push( face.materialIndex ); 12694 12695 if ( hasFaceVertexUv ) { 12696 12697 var faceVertexUvs = this.faceVertexUvs[ 0 ][ i ]; 12698 12699 faces.push( 12700 getUvIndex( faceVertexUvs[ 0 ] ), 12701 getUvIndex( faceVertexUvs[ 1 ] ), 12702 getUvIndex( faceVertexUvs[ 2 ] ) 12703 ); 12704 12705 } 12706 12707 if ( hasFaceNormal ) { 12708 12709 faces.push( getNormalIndex( face.normal ) ); 12710 12711 } 12712 12713 if ( hasFaceVertexNormal ) { 12714 12715 var vertexNormals = face.vertexNormals; 12716 12717 faces.push( 12718 getNormalIndex( vertexNormals[ 0 ] ), 12719 getNormalIndex( vertexNormals[ 1 ] ), 12720 getNormalIndex( vertexNormals[ 2 ] ) 12721 ); 12722 12723 } 12724 12725 if ( hasFaceColor ) { 12726 12727 faces.push( getColorIndex( face.color ) ); 12728 12729 } 12730 12731 if ( hasFaceVertexColor ) { 12732 12733 var vertexColors = face.vertexColors; 12734 12735 faces.push( 12736 getColorIndex( vertexColors[ 0 ] ), 12737 getColorIndex( vertexColors[ 1 ] ), 12738 getColorIndex( vertexColors[ 2 ] ) 12739 ); 12740 12741 } 12742 12743 } 12744 12745 function setBit( value, position, enabled ) { 12746 12747 return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) ); 12748 12749 } 12750 12751 function getNormalIndex( normal ) { 12752 12753 var hash = normal.x.toString() + normal.y.toString() + normal.z.toString(); 12754 12755 if ( normalsHash[ hash ] !== undefined ) { 12756 12757 return normalsHash[ hash ]; 12758 12759 } 12760 12761 normalsHash[ hash ] = normals.length / 3; 12762 normals.push( normal.x, normal.y, normal.z ); 12763 12764 return normalsHash[ hash ]; 12765 12766 } 12767 12768 function getColorIndex( color ) { 12769 12770 var hash = color.r.toString() + color.g.toString() + color.b.toString(); 12771 12772 if ( colorsHash[ hash ] !== undefined ) { 12773 12774 return colorsHash[ hash ]; 12775 12776 } 12777 12778 colorsHash[ hash ] = colors.length; 12779 colors.push( color.getHex() ); 12780 12781 return colorsHash[ hash ]; 12782 12783 } 12784 12785 function getUvIndex( uv ) { 12786 12787 var hash = uv.x.toString() + uv.y.toString(); 12788 12789 if ( uvsHash[ hash ] !== undefined ) { 12790 12791 return uvsHash[ hash ]; 12792 12793 } 12794 12795 uvsHash[ hash ] = uvs.length / 2; 12796 uvs.push( uv.x, uv.y ); 12797 12798 return uvsHash[ hash ]; 12799 12800 } 12801 12802 data.data = {}; 12803 12804 data.data.vertices = vertices; 12805 data.data.normals = normals; 12806 if ( colors.length > 0 ) data.data.colors = colors; 12807 if ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility 12808 data.data.faces = faces; 12809 12810 return data; 12811 12812 }, 12813 12814 clone: function () { 12815 12816 /* 12817 // Handle primitives 12818 12819 var parameters = this.parameters; 12820 12821 if ( parameters !== undefined ) { 12822 12823 var values = []; 12824 12825 for ( var key in parameters ) { 12826 12827 values.push( parameters[ key ] ); 12828 12829 } 12830 12831 var geometry = Object.create( this.constructor.prototype ); 12832 this.constructor.apply( geometry, values ); 12833 return geometry; 12834 12835 } 12836 12837 return new this.constructor().copy( this ); 12838 */ 12839 12840 return new Geometry().copy( this ); 12841 12842 }, 12843 12844 copy: function ( source ) { 12845 12846 var i, il, j, jl, k, kl; 12847 12848 // reset 12849 12850 this.vertices = []; 12851 this.colors = []; 12852 this.faces = []; 12853 this.faceVertexUvs = [[]]; 12854 this.morphTargets = []; 12855 this.morphNormals = []; 12856 this.skinWeights = []; 12857 this.skinIndices = []; 12858 this.lineDistances = []; 12859 this.boundingBox = null; 12860 this.boundingSphere = null; 12861 12862 // name 12863 12864 this.name = source.name; 12865 12866 // vertices 12867 12868 var vertices = source.vertices; 12869 12870 for ( i = 0, il = vertices.length; i < il; i ++ ) { 12871 12872 this.vertices.push( vertices[ i ].clone() ); 12873 12874 } 12875 12876 // colors 12877 12878 var colors = source.colors; 12879 12880 for ( i = 0, il = colors.length; i < il; i ++ ) { 12881 12882 this.colors.push( colors[ i ].clone() ); 12883 12884 } 12885 12886 // faces 12887 12888 var faces = source.faces; 12889 12890 for ( i = 0, il = faces.length; i < il; i ++ ) { 12891 12892 this.faces.push( faces[ i ].clone() ); 12893 12894 } 12895 12896 // face vertex uvs 12897 12898 for ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) { 12899 12900 var faceVertexUvs = source.faceVertexUvs[ i ]; 12901 12902 if ( this.faceVertexUvs[ i ] === undefined ) { 12903 12904 this.faceVertexUvs[ i ] = []; 12905 12906 } 12907 12908 for ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) { 12909 12910 var uvs = faceVertexUvs[ j ], uvsCopy = []; 12911 12912 for ( k = 0, kl = uvs.length; k < kl; k ++ ) { 12913 12914 var uv = uvs[ k ]; 12915 12916 uvsCopy.push( uv.clone() ); 12917 12918 } 12919 12920 this.faceVertexUvs[ i ].push( uvsCopy ); 12921 12922 } 12923 12924 } 12925 12926 // morph targets 12927 12928 var morphTargets = source.morphTargets; 12929 12930 for ( i = 0, il = morphTargets.length; i < il; i ++ ) { 12931 12932 var morphTarget = {}; 12933 morphTarget.name = morphTargets[ i ].name; 12934 12935 // vertices 12936 12937 if ( morphTargets[ i ].vertices !== undefined ) { 12938 12939 morphTarget.vertices = []; 12940 12941 for ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) { 12942 12943 morphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() ); 12944 12945 } 12946 12947 } 12948 12949 // normals 12950 12951 if ( morphTargets[ i ].normals !== undefined ) { 12952 12953 morphTarget.normals = []; 12954 12955 for ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) { 12956 12957 morphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() ); 12958 12959 } 12960 12961 } 12962 12963 this.morphTargets.push( morphTarget ); 12964 12965 } 12966 12967 // morph normals 12968 12969 var morphNormals = source.morphNormals; 12970 12971 for ( i = 0, il = morphNormals.length; i < il; i ++ ) { 12972 12973 var morphNormal = {}; 12974 12975 // vertex normals 12976 12977 if ( morphNormals[ i ].vertexNormals !== undefined ) { 12978 12979 morphNormal.vertexNormals = []; 12980 12981 for ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) { 12982 12983 var srcVertexNormal = morphNormals[ i ].vertexNormals[ j ]; 12984 var destVertexNormal = {}; 12985 12986 destVertexNormal.a = srcVertexNormal.a.clone(); 12987 destVertexNormal.b = srcVertexNormal.b.clone(); 12988 destVertexNormal.c = srcVertexNormal.c.clone(); 12989 12990 morphNormal.vertexNormals.push( destVertexNormal ); 12991 12992 } 12993 12994 } 12995 12996 // face normals 12997 12998 if ( morphNormals[ i ].faceNormals !== undefined ) { 12999 13000 morphNormal.faceNormals = []; 13001 13002 for ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) { 13003 13004 morphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() ); 13005 13006 } 13007 13008 } 13009 13010 this.morphNormals.push( morphNormal ); 13011 13012 } 13013 13014 // skin weights 13015 13016 var skinWeights = source.skinWeights; 13017 13018 for ( i = 0, il = skinWeights.length; i < il; i ++ ) { 13019 13020 this.skinWeights.push( skinWeights[ i ].clone() ); 13021 13022 } 13023 13024 // skin indices 13025 13026 var skinIndices = source.skinIndices; 13027 13028 for ( i = 0, il = skinIndices.length; i < il; i ++ ) { 13029 13030 this.skinIndices.push( skinIndices[ i ].clone() ); 13031 13032 } 13033 13034 // line distances 13035 13036 var lineDistances = source.lineDistances; 13037 13038 for ( i = 0, il = lineDistances.length; i < il; i ++ ) { 13039 13040 this.lineDistances.push( lineDistances[ i ] ); 13041 13042 } 13043 13044 // bounding box 13045 13046 var boundingBox = source.boundingBox; 13047 13048 if ( boundingBox !== null ) { 13049 13050 this.boundingBox = boundingBox.clone(); 13051 13052 } 13053 13054 // bounding sphere 13055 13056 var boundingSphere = source.boundingSphere; 13057 13058 if ( boundingSphere !== null ) { 13059 13060 this.boundingSphere = boundingSphere.clone(); 13061 13062 } 13063 13064 // update flags 13065 13066 this.elementsNeedUpdate = source.elementsNeedUpdate; 13067 this.verticesNeedUpdate = source.verticesNeedUpdate; 13068 this.uvsNeedUpdate = source.uvsNeedUpdate; 13069 this.normalsNeedUpdate = source.normalsNeedUpdate; 13070 this.colorsNeedUpdate = source.colorsNeedUpdate; 13071 this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate; 13072 this.groupsNeedUpdate = source.groupsNeedUpdate; 13073 13074 return this; 13075 13076 }, 13077 13078 dispose: function () { 13079 13080 this.dispatchEvent( { type: 'dispose' } ); 13081 13082 } 13083 13084} ); 13085 13086/** 13087 * @author mrdoob / http://mrdoob.com/ 13088 * @author Mugen87 / https://github.com/Mugen87 13089 */ 13090 13091// BoxGeometry 13092 13093class BoxGeometry extends Geometry { 13094 13095 constructor( width, height, depth, widthSegments, heightSegments, depthSegments ) { 13096 13097 super(); 13098 13099 this.type = 'BoxGeometry'; 13100 13101 this.parameters = { 13102 width: width, 13103 height: height, 13104 depth: depth, 13105 widthSegments: widthSegments, 13106 heightSegments: heightSegments, 13107 depthSegments: depthSegments 13108 }; 13109 13110 this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) ); 13111 this.mergeVertices(); 13112 13113 } 13114 13115} 13116 13117// BoxBufferGeometry 13118 13119class BoxBufferGeometry extends BufferGeometry { 13120 13121 constructor( width, height, depth, widthSegments, heightSegments, depthSegments ) { 13122 13123 super(); 13124 13125 this.type = 'BoxBufferGeometry'; 13126 13127 this.parameters = { 13128 width: width, 13129 height: height, 13130 depth: depth, 13131 widthSegments: widthSegments, 13132 heightSegments: heightSegments, 13133 depthSegments: depthSegments 13134 }; 13135 13136 var scope = this; 13137 13138 width = width || 1; 13139 height = height || 1; 13140 depth = depth || 1; 13141 13142 // segments 13143 13144 widthSegments = Math.floor( widthSegments ) || 1; 13145 heightSegments = Math.floor( heightSegments ) || 1; 13146 depthSegments = Math.floor( depthSegments ) || 1; 13147 13148 // buffers 13149 13150 var indices = []; 13151 var vertices = []; 13152 var normals = []; 13153 var uvs = []; 13154 13155 // helper variables 13156 13157 var numberOfVertices = 0; 13158 var groupStart = 0; 13159 13160 // build each side of the box geometry 13161 13162 buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px 13163 buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx 13164 buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py 13165 buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny 13166 buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz 13167 buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz 13168 13169 // build geometry 13170 13171 this.setIndex( indices ); 13172 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 13173 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 13174 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 13175 13176 function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) { 13177 13178 var segmentWidth = width / gridX; 13179 var segmentHeight = height / gridY; 13180 13181 var widthHalf = width / 2; 13182 var heightHalf = height / 2; 13183 var depthHalf = depth / 2; 13184 13185 var gridX1 = gridX + 1; 13186 var gridY1 = gridY + 1; 13187 13188 var vertexCounter = 0; 13189 var groupCount = 0; 13190 13191 var ix, iy; 13192 13193 var vector = new Vector3(); 13194 13195 // generate vertices, normals and uvs 13196 13197 for ( iy = 0; iy < gridY1; iy ++ ) { 13198 13199 var y = iy * segmentHeight - heightHalf; 13200 13201 for ( ix = 0; ix < gridX1; ix ++ ) { 13202 13203 var x = ix * segmentWidth - widthHalf; 13204 13205 // set values to correct vector component 13206 13207 vector[ u ] = x * udir; 13208 vector[ v ] = y * vdir; 13209 vector[ w ] = depthHalf; 13210 13211 // now apply vector to vertex buffer 13212 13213 vertices.push( vector.x, vector.y, vector.z ); 13214 13215 // set values to correct vector component 13216 13217 vector[ u ] = 0; 13218 vector[ v ] = 0; 13219 vector[ w ] = depth > 0 ? 1 : - 1; 13220 13221 // now apply vector to normal buffer 13222 13223 normals.push( vector.x, vector.y, vector.z ); 13224 13225 // uvs 13226 13227 uvs.push( ix / gridX ); 13228 uvs.push( 1 - ( iy / gridY ) ); 13229 13230 // counters 13231 13232 vertexCounter += 1; 13233 13234 } 13235 13236 } 13237 13238 // indices 13239 13240 // 1. you need three indices to draw a single face 13241 // 2. a single segment consists of two faces 13242 // 3. so we need to generate six (2*3) indices per segment 13243 13244 for ( iy = 0; iy < gridY; iy ++ ) { 13245 13246 for ( ix = 0; ix < gridX; ix ++ ) { 13247 13248 var a = numberOfVertices + ix + gridX1 * iy; 13249 var b = numberOfVertices + ix + gridX1 * ( iy + 1 ); 13250 var c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 ); 13251 var d = numberOfVertices + ( ix + 1 ) + gridX1 * iy; 13252 13253 // faces 13254 13255 indices.push( a, b, d ); 13256 indices.push( b, c, d ); 13257 13258 // increase counter 13259 13260 groupCount += 6; 13261 13262 } 13263 13264 } 13265 13266 // add a group to the geometry. this will ensure multi material support 13267 13268 scope.addGroup( groupStart, groupCount, materialIndex ); 13269 13270 // calculate new start value for groups 13271 13272 groupStart += groupCount; 13273 13274 // update total number of vertices 13275 13276 numberOfVertices += vertexCounter; 13277 13278 } 13279 13280 } 13281 13282} 13283 13284/** 13285 * Uniform Utilities 13286 */ 13287 13288function cloneUniforms( src ) { 13289 13290 var dst = {}; 13291 13292 for ( var u in src ) { 13293 13294 dst[ u ] = {}; 13295 13296 for ( var p in src[ u ] ) { 13297 13298 var property = src[ u ][ p ]; 13299 13300 if ( property && ( property.isColor || 13301 property.isMatrix3 || property.isMatrix4 || 13302 property.isVector2 || property.isVector3 || property.isVector4 || 13303 property.isTexture ) ) { 13304 13305 dst[ u ][ p ] = property.clone(); 13306 13307 } else if ( Array.isArray( property ) ) { 13308 13309 dst[ u ][ p ] = property.slice(); 13310 13311 } else { 13312 13313 dst[ u ][ p ] = property; 13314 13315 } 13316 13317 } 13318 13319 } 13320 13321 return dst; 13322 13323} 13324 13325function mergeUniforms( uniforms ) { 13326 13327 var merged = {}; 13328 13329 for ( var u = 0; u < uniforms.length; u ++ ) { 13330 13331 var tmp = cloneUniforms( uniforms[ u ] ); 13332 13333 for ( var p in tmp ) { 13334 13335 merged[ p ] = tmp[ p ]; 13336 13337 } 13338 13339 } 13340 13341 return merged; 13342 13343} 13344 13345// Legacy 13346 13347var UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms }; 13348 13349var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; 13350 13351var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; 13352 13353/** 13354 * @author alteredq / http://alteredqualia.com/ 13355 * 13356 * parameters = { 13357 * defines: { "label" : "value" }, 13358 * uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } }, 13359 * 13360 * fragmentShader: <string>, 13361 * vertexShader: <string>, 13362 * 13363 * wireframe: <boolean>, 13364 * wireframeLinewidth: <float>, 13365 * 13366 * lights: <bool>, 13367 * 13368 * skinning: <bool>, 13369 * morphTargets: <bool>, 13370 * morphNormals: <bool> 13371 * } 13372 */ 13373 13374function ShaderMaterial( parameters ) { 13375 13376 Material.call( this ); 13377 13378 this.type = 'ShaderMaterial'; 13379 13380 this.defines = {}; 13381 this.uniforms = {}; 13382 13383 this.vertexShader = default_vertex; 13384 this.fragmentShader = default_fragment; 13385 13386 this.linewidth = 1; 13387 13388 this.wireframe = false; 13389 this.wireframeLinewidth = 1; 13390 13391 this.fog = false; // set to use scene fog 13392 this.lights = false; // set to use scene lights 13393 this.clipping = false; // set to use user-defined clipping planes 13394 13395 this.skinning = false; // set to use skinning attribute streams 13396 this.morphTargets = false; // set to use morph targets 13397 this.morphNormals = false; // set to use morph normals 13398 13399 this.extensions = { 13400 derivatives: false, // set to use derivatives 13401 fragDepth: false, // set to use fragment depth values 13402 drawBuffers: false, // set to use draw buffers 13403 shaderTextureLOD: false // set to use shader texture LOD 13404 }; 13405 13406 // When rendered geometry doesn't include these attributes but the material does, 13407 // use these default values in WebGL. This avoids errors when buffer data is missing. 13408 this.defaultAttributeValues = { 13409 'color': [ 1, 1, 1 ], 13410 'uv': [ 0, 0 ], 13411 'uv2': [ 0, 0 ] 13412 }; 13413 13414 this.index0AttributeName = undefined; 13415 this.uniformsNeedUpdate = false; 13416 13417 if ( parameters !== undefined ) { 13418 13419 if ( parameters.attributes !== undefined ) { 13420 13421 console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' ); 13422 13423 } 13424 13425 this.setValues( parameters ); 13426 13427 } 13428 13429} 13430 13431ShaderMaterial.prototype = Object.create( Material.prototype ); 13432ShaderMaterial.prototype.constructor = ShaderMaterial; 13433 13434ShaderMaterial.prototype.isShaderMaterial = true; 13435 13436ShaderMaterial.prototype.copy = function ( source ) { 13437 13438 Material.prototype.copy.call( this, source ); 13439 13440 this.fragmentShader = source.fragmentShader; 13441 this.vertexShader = source.vertexShader; 13442 13443 this.uniforms = cloneUniforms( source.uniforms ); 13444 13445 this.defines = Object.assign( {}, source.defines ); 13446 13447 this.wireframe = source.wireframe; 13448 this.wireframeLinewidth = source.wireframeLinewidth; 13449 13450 this.lights = source.lights; 13451 this.clipping = source.clipping; 13452 13453 this.skinning = source.skinning; 13454 13455 this.morphTargets = source.morphTargets; 13456 this.morphNormals = source.morphNormals; 13457 13458 this.extensions = source.extensions; 13459 13460 return this; 13461 13462}; 13463 13464ShaderMaterial.prototype.toJSON = function ( meta ) { 13465 13466 var data = Material.prototype.toJSON.call( this, meta ); 13467 13468 data.uniforms = {}; 13469 13470 for ( var name in this.uniforms ) { 13471 13472 var uniform = this.uniforms[ name ]; 13473 var value = uniform.value; 13474 13475 if ( value && value.isTexture ) { 13476 13477 data.uniforms[ name ] = { 13478 type: 't', 13479 value: value.toJSON( meta ).uuid 13480 }; 13481 13482 } else if ( value && value.isColor ) { 13483 13484 data.uniforms[ name ] = { 13485 type: 'c', 13486 value: value.getHex() 13487 }; 13488 13489 } else if ( value && value.isVector2 ) { 13490 13491 data.uniforms[ name ] = { 13492 type: 'v2', 13493 value: value.toArray() 13494 }; 13495 13496 } else if ( value && value.isVector3 ) { 13497 13498 data.uniforms[ name ] = { 13499 type: 'v3', 13500 value: value.toArray() 13501 }; 13502 13503 } else if ( value && value.isVector4 ) { 13504 13505 data.uniforms[ name ] = { 13506 type: 'v4', 13507 value: value.toArray() 13508 }; 13509 13510 } else if ( value && value.isMatrix3 ) { 13511 13512 data.uniforms[ name ] = { 13513 type: 'm3', 13514 value: value.toArray() 13515 }; 13516 13517 } else if ( value && value.isMatrix4 ) { 13518 13519 data.uniforms[ name ] = { 13520 type: 'm4', 13521 value: value.toArray() 13522 }; 13523 13524 } else { 13525 13526 data.uniforms[ name ] = { 13527 value: value 13528 }; 13529 13530 // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far 13531 13532 } 13533 13534 } 13535 13536 if ( Object.keys( this.defines ).length > 0 ) data.defines = this.defines; 13537 13538 data.vertexShader = this.vertexShader; 13539 data.fragmentShader = this.fragmentShader; 13540 13541 var extensions = {}; 13542 13543 for ( var key in this.extensions ) { 13544 13545 if ( this.extensions[ key ] === true ) extensions[ key ] = true; 13546 13547 } 13548 13549 if ( Object.keys( extensions ).length > 0 ) data.extensions = extensions; 13550 13551 return data; 13552 13553}; 13554 13555/** 13556 * @author mrdoob / http://mrdoob.com/ 13557 * @author mikael emtinger / http://gomo.se/ 13558 * @author WestLangley / http://github.com/WestLangley 13559*/ 13560 13561function Camera() { 13562 13563 Object3D.call( this ); 13564 13565 this.type = 'Camera'; 13566 13567 this.matrixWorldInverse = new Matrix4(); 13568 13569 this.projectionMatrix = new Matrix4(); 13570 this.projectionMatrixInverse = new Matrix4(); 13571 13572} 13573 13574Camera.prototype = Object.assign( Object.create( Object3D.prototype ), { 13575 13576 constructor: Camera, 13577 13578 isCamera: true, 13579 13580 copy: function ( source, recursive ) { 13581 13582 Object3D.prototype.copy.call( this, source, recursive ); 13583 13584 this.matrixWorldInverse.copy( source.matrixWorldInverse ); 13585 13586 this.projectionMatrix.copy( source.projectionMatrix ); 13587 this.projectionMatrixInverse.copy( source.projectionMatrixInverse ); 13588 13589 return this; 13590 13591 }, 13592 13593 getWorldDirection: function ( target ) { 13594 13595 if ( target === undefined ) { 13596
vendor: 4,994 bytes, lines 13597-13810
13597 console.warn( 'THREE.Camera: .getWorldDirection() target is now required' ); 13598 target = new Vector3(); 13599 13600 } 13601 13602 this.updateMatrixWorld( true ); 13603 13604 var e = this.matrixWorld.elements; 13605 13606 return target.set( - e[ 8 ], - e[ 9 ], - e[ 10 ] ).normalize(); 13607 13608 }, 13609 13610 updateMatrixWorld: function ( force ) { 13611 13612 Object3D.prototype.updateMatrixWorld.call( this, force ); 13613 13614 this.matrixWorldInverse.getInverse( this.matrixWorld ); 13615 13616 }, 13617 13618 updateWorldMatrix: function ( updateParents, updateChildren ) { 13619 13620 Object3D.prototype.updateWorldMatrix.call( this, updateParents, updateChildren ); 13621 13622 this.matrixWorldInverse.getInverse( this.matrixWorld ); 13623 13624 }, 13625 13626 clone: function () { 13627 13628 return new this.constructor().copy( this ); 13629 13630 } 13631 13632} ); 13633 13634/** 13635 * @author mrdoob / http://mrdoob.com/ 13636 * @author greggman / http://games.greggman.com/ 13637 * @author zz85 / http://www.lab4games.net/zz85/blog 13638 * @author tschw 13639 */ 13640 13641function PerspectiveCamera( fov, aspect, near, far ) { 13642 13643 Camera.call( this ); 13644 13645 this.type = 'PerspectiveCamera'; 13646 13647 this.fov = fov !== undefined ? fov : 50; 13648 this.zoom = 1; 13649 13650 this.near = near !== undefined ? near : 0.1; 13651 this.far = far !== undefined ? far : 2000; 13652 this.focus = 10; 13653 13654 this.aspect = aspect !== undefined ? aspect : 1; 13655 this.view = null; 13656 13657 this.filmGauge = 35; // width of the film (default in millimeters) 13658 this.filmOffset = 0; // horizontal film offset (same unit as gauge) 13659 13660 this.updateProjectionMatrix(); 13661 13662} 13663 13664PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), { 13665 13666 constructor: PerspectiveCamera, 13667 13668 isPerspectiveCamera: true, 13669 13670 copy: function ( source, recursive ) { 13671 13672 Camera.prototype.copy.call( this, source, recursive ); 13673 13674 this.fov = source.fov; 13675 this.zoom = source.zoom; 13676 13677 this.near = source.near; 13678 this.far = source.far; 13679 this.focus = source.focus; 13680 13681 this.aspect = source.aspect; 13682 this.view = source.view === null ? null : Object.assign( {}, source.view ); 13683 13684 this.filmGauge = source.filmGauge; 13685 this.filmOffset = source.filmOffset; 13686 13687 return this; 13688 13689 }, 13690 13691 /** 13692 * Sets the FOV by focal length in respect to the current .filmGauge. 13693 * 13694 * The default film gauge is 35, so that the focal length can be specified for 13695 * a 35mm (full frame) camera. 13696 * 13697 * Values for focal length and film gauge must have the same unit. 13698 */ 13699 setFocalLength: function ( focalLength ) { 13700 13701 // see http://www.bobatkins.com/photography/technical/field_of_view.html 13702 var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; 13703 13704 this.fov = MathUtils.RAD2DEG * 2 * Math.atan( vExtentSlope ); 13705 this.updateProjectionMatrix(); 13706 13707 }, 13708 13709 /** 13710 * Calculates the focal length from the current .fov and .filmGauge. 13711 */ 13712 getFocalLength: function () { 13713 13714 var vExtentSlope = Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ); 13715 13716 return 0.5 * this.getFilmHeight() / vExtentSlope; 13717 13718 }, 13719 13720 getEffectiveFOV: function () { 13721 13722 return MathUtils.RAD2DEG * 2 * Math.atan( 13723 Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom ); 13724 13725 }, 13726 13727 getFilmWidth: function () { 13728 13729 // film not completely covered in portrait format (aspect < 1) 13730 return this.filmGauge * Math.min( this.aspect, 1 ); 13731 13732 }, 13733 13734 getFilmHeight: function () { 13735 13736 // film not completely covered in landscape format (aspect > 1) 13737 return this.filmGauge / Math.max( this.aspect, 1 ); 13738 13739 }, 13740 13741 /** 13742 * Sets an offset in a larger frustum. This is useful for multi-window or 13743 * multi-monitor/multi-machine setups. 13744 * 13745 * For example, if you have 3x2 monitors and each monitor is 1920x1080 and 13746 * the monitors are in grid like this 13747 * 13748 * +---+---+---+ 13749 * | A | B | C | 13750 * +---+---+---+ 13751 * | D | E | F | 13752 * +---+---+---+ 13753 * 13754 * then for each monitor you would call it like this 13755 * 13756 * var w = 1920; 13757 * var h = 1080; 13758 * var fullWidth = w * 3; 13759 * var fullHeight = h * 2; 13760 * 13761 * --A-- 13762 * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); 13763 * --B-- 13764 * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); 13765 * --C-- 13766 * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); 13767 * --D-- 13768 * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); 13769 * --E-- 13770 * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); 13771 * --F-- 13772 * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); 13773 * 13774 * Note there is no reason monitors have to be the same size or in a grid. 13775 */ 13776 setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) { 13777 13778 this.aspect = fullWidth / fullHeight; 13779 13780 if ( this.view === null ) { 13781 13782 this.view = { 13783 enabled: true, 13784 fullWidth: 1, 13785 fullHeight: 1, 13786 offsetX: 0, 13787 offsetY: 0, 13788 width: 1, 13789 height: 1 13790 }; 13791 13792 } 13793 13794 this.view.enabled = true; 13795 this.view.fullWidth = fullWidth; 13796 this.view.fullHeight = fullHeight; 13797 this.view.offsetX = x; 13798 this.view.offsetY = y; 13799 this.view.width = width; 13800 this.view.height = height; 13801 13802 this.updateProjectionMatrix(); 13803 13804 }, 13805 13806 clearViewOffset: function () { 13807 13808 if ( this.view !== null ) { 13809 13810 this.view.enabled = false;
vendor: 4,331 bytes, lines 13811-13984
13811 13812 } 13813 13814 this.updateProjectionMatrix(); 13815 13816 }, 13817 13818 updateProjectionMatrix: function () { 13819 13820 var near = this.near, 13821 top = near * Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom, 13822 height = 2 * top, 13823 width = this.aspect * height, 13824 left = - 0.5 * width, 13825 view = this.view; 13826 13827 if ( this.view !== null && this.view.enabled ) { 13828 13829 var fullWidth = view.fullWidth, 13830 fullHeight = view.fullHeight; 13831 13832 left += view.offsetX * width / fullWidth; 13833 top -= view.offsetY * height / fullHeight; 13834 width *= view.width / fullWidth; 13835 height *= view.height / fullHeight; 13836 13837 } 13838 13839 var skew = this.filmOffset; 13840 if ( skew !== 0 ) left += near * skew / this.getFilmWidth(); 13841 13842 this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far ); 13843 13844 this.projectionMatrixInverse.getInverse( this.projectionMatrix ); 13845 13846 }, 13847 13848 toJSON: function ( meta ) { 13849 13850 var data = Object3D.prototype.toJSON.call( this, meta ); 13851 13852 data.object.fov = this.fov; 13853 data.object.zoom = this.zoom; 13854 13855 data.object.near = this.near; 13856 data.object.far = this.far; 13857 data.object.focus = this.focus; 13858 13859 data.object.aspect = this.aspect; 13860 13861 if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); 13862 13863 data.object.filmGauge = this.filmGauge; 13864 data.object.filmOffset = this.filmOffset; 13865 13866 return data; 13867 13868 } 13869 13870} ); 13871 13872/** 13873 * Camera for rendering cube maps 13874 * - renders scene into axis-aligned cube 13875 * 13876 * @author alteredq / http://alteredqualia.com/ 13877 */ 13878 13879var fov = 90, aspect = 1; 13880 13881function CubeCamera( near, far, cubeResolution, options ) { 13882 13883 Object3D.call( this ); 13884 13885 this.type = 'CubeCamera'; 13886 13887 var cameraPX = new PerspectiveCamera( fov, aspect, near, far ); 13888 cameraPX.up.set( 0, - 1, 0 ); 13889 cameraPX.lookAt( new Vector3( 1, 0, 0 ) ); 13890 this.add( cameraPX ); 13891 13892 var cameraNX = new PerspectiveCamera( fov, aspect, near, far ); 13893 cameraNX.up.set( 0, - 1, 0 ); 13894 cameraNX.lookAt( new Vector3( - 1, 0, 0 ) ); 13895 this.add( cameraNX ); 13896 13897 var cameraPY = new PerspectiveCamera( fov, aspect, near, far ); 13898 cameraPY.up.set( 0, 0, 1 ); 13899 cameraPY.lookAt( new Vector3( 0, 1, 0 ) ); 13900 this.add( cameraPY ); 13901 13902 var cameraNY = new PerspectiveCamera( fov, aspect, near, far ); 13903 cameraNY.up.set( 0, 0, - 1 ); 13904 cameraNY.lookAt( new Vector3( 0, - 1, 0 ) ); 13905 this.add( cameraNY ); 13906 13907 var cameraPZ = new PerspectiveCamera( fov, aspect, near, far ); 13908 cameraPZ.up.set( 0, - 1, 0 ); 13909 cameraPZ.lookAt( new Vector3( 0, 0, 1 ) ); 13910 this.add( cameraPZ ); 13911 13912 var cameraNZ = new PerspectiveCamera( fov, aspect, near, far ); 13913 cameraNZ.up.set( 0, - 1, 0 ); 13914 cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) ); 13915 this.add( cameraNZ ); 13916 13917 options = options || { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter }; 13918 13919 this.renderTarget = new WebGLCubeRenderTarget( cubeResolution, options ); 13920 this.renderTarget.texture.name = "CubeCamera"; 13921 13922 this.update = function ( renderer, scene ) { 13923 13924 if ( this.parent === null ) this.updateMatrixWorld(); 13925 13926 var currentRenderTarget = renderer.getRenderTarget(); 13927 13928 var renderTarget = this.renderTarget; 13929 var generateMipmaps = renderTarget.texture.generateMipmaps; 13930 13931 renderTarget.texture.generateMipmaps = false; 13932 13933 renderer.setRenderTarget( renderTarget, 0 ); 13934 renderer.render( scene, cameraPX ); 13935 13936 renderer.setRenderTarget( renderTarget, 1 ); 13937 renderer.render( scene, cameraNX ); 13938 13939 renderer.setRenderTarget( renderTarget, 2 ); 13940 renderer.render( scene, cameraPY ); 13941 13942 renderer.setRenderTarget( renderTarget, 3 ); 13943 renderer.render( scene, cameraNY ); 13944 13945 renderer.setRenderTarget( renderTarget, 4 ); 13946 renderer.render( scene, cameraPZ ); 13947 13948 renderTarget.texture.generateMipmaps = generateMipmaps; 13949 13950 renderer.setRenderTarget( renderTarget, 5 ); 13951 renderer.render( scene, cameraNZ ); 13952 13953 renderer.setRenderTarget( currentRenderTarget ); 13954 13955 }; 13956 13957 this.clear = function ( renderer, color, depth, stencil ) { 13958 13959 var currentRenderTarget = renderer.getRenderTarget(); 13960 13961 var renderTarget = this.renderTarget; 13962 13963 for ( var i = 0; i < 6; i ++ ) { 13964 13965 renderer.setRenderTarget( renderTarget, i ); 13966 13967 renderer.clear( color, depth, stencil ); 13968 13969 } 13970 13971 renderer.setRenderTarget( currentRenderTarget ); 13972 13973 }; 13974 13975} 13976 13977CubeCamera.prototype = Object.create( Object3D.prototype ); 13978CubeCamera.prototype.constructor = CubeCamera; 13979 13980/** 13981 * @author alteredq / http://alteredqualia.com 13982 * @author WestLangley / http://github.com/WestLangley 13983 */ 13984
13985function WebGLCubeRenderTarget( size, options, dummy ) { 13986 13987 if ( Number.isInteger( options ) ) { 13988 13989 console.warn( 'THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )' ); 13990 13991 options = dummy; 13992 13993 } 13994 13995 WebGLRenderTarget.call( this, size, size, options ); 13996 13997} 13998 13999WebGLCubeRenderTarget.prototype = Object.create( WebGLRenderTarget.prototype ); 14000WebGLCubeRenderTarget.prototype.constructor = WebGLCubeRenderTarget; 14001 14002WebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true; 14003 14004WebGLCubeRenderTarget.prototype.fromEquirectangularTexture = function ( renderer, texture ) { 14005 14006 this.texture.type = texture.type; 14007 this.texture.format = texture.format; 14008 this.texture.encoding = texture.encoding; 14009 14010 var scene = new Scene(); 14011 14012 var shader = { 14013 14014 uniforms: { 14015 tEquirect: { value: null }, 14016 }, 14017 14018 vertexShader: [ 14019 14020 "varying vec3 vWorldDirection;", 14021 14022 "vec3 transformDirection( in vec3 dir, in mat4 matrix ) {", 14023 14024 " return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );", 14025 14026 "}", 14027 14028 "void main() {", 14029 14030 " vWorldDirection = transformDirection( position, modelMatrix );", 14031 14032 " #include <begin_vertex>", 14033 " #include <project_vertex>", 14034 14035 "}" 14036 14037 ].join( '\n' ), 14038 14039 fragmentShader: [ 14040 14041 "uniform sampler2D tEquirect;", 14042 14043 "varying vec3 vWorldDirection;", 14044 14045 "#define RECIPROCAL_PI 0.31830988618", 14046 "#define RECIPROCAL_PI2 0.15915494", 14047 14048 "void main() {", 14049 14050 " vec3 direction = normalize( vWorldDirection );", 14051 14052 " vec2 sampleUV;", 14053 14054 " sampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;", 14055 14056 " sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;", 14057 14058 " gl_FragColor = texture2D( tEquirect, sampleUV );", 14059 14060 "}" 14061 14062 ].join( '\n' ), 14063 }; 14064 14065 var material = new ShaderMaterial( { 14066 14067 type: 'CubemapFromEquirect', 14068 14069 uniforms: cloneUniforms( shader.uniforms ), 14070 vertexShader: shader.vertexShader, 14071 fragmentShader: shader.fragmentShader, 14072 side: BackSide, 14073 blending: NoBlending 14074 14075 } ); 14076 14077 material.uniforms.tEquirect.value = texture; 14078 14079 var mesh = new Mesh( new BoxBufferGeometry( 5, 5, 5 ), material ); 14080 14081 scene.add( mesh ); 14082 14083 var camera = new CubeCamera( 1, 10, 1 ); 14084 14085 camera.renderTarget = this; 14086 camera.renderTarget.texture.name = 'CubeCameraTexture'; 14087 14088 camera.update( renderer, scene ); 14089 14090 mesh.geometry.dispose(); 14091 mesh.material.dispose(); 14092 14093 return this; 14094 14095}; 14096 14097/** 14098 * @author alteredq / http://alteredqualia.com/ 14099 */ 14100 14101function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) { 14102 14103 Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); 14104 14105 this.image = { data: data || null, width: width || 1, height: height || 1 }; 14106 14107 this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; 14108 this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; 14109 14110 this.generateMipmaps = false; 14111 this.flipY = false; 14112 this.unpackAlignment = 1; 14113 14114 this.needsUpdate = true; 14115 14116} 14117 14118DataTexture.prototype = Object.create( Texture.prototype ); 14119DataTexture.prototype.constructor = DataTexture; 14120 14121DataTexture.prototype.isDataTexture = true; 14122 14123/** 14124 * @author mrdoob / http://mrdoob.com/ 14125 * @author alteredq / http://alteredqualia.com/ 14126 * @author bhouston / http://clara.io 14127 */ 14128 14129var _sphere$1 = new Sphere(); 14130var _vector$5 = new Vector3(); 14131 14132function Frustum( p0, p1, p2, p3, p4, p5 ) { 14133 14134 this.planes = [ 14135 14136 ( p0 !== undefined ) ? p0 : new Plane(), 14137 ( p1 !== undefined ) ? p1 : new Plane(), 14138 ( p2 !== undefined ) ? p2 : new Plane(), 14139 ( p3 !== undefined ) ? p3 : new Plane(), 14140 ( p4 !== undefined ) ? p4 : new Plane(), 14141 ( p5 !== undefined ) ? p5 : new Plane() 14142 14143 ]; 14144 14145} 14146 14147Object.assign( Frustum.prototype, { 14148 14149 set: function ( p0, p1, p2, p3, p4, p5 ) { 14150 14151 var planes = this.planes; 14152 14153 planes[ 0 ].copy( p0 ); 14154 planes[ 1 ].copy( p1 ); 14155 planes[ 2 ].copy( p2 ); 14156 planes[ 3 ].copy( p3 ); 14157 planes[ 4 ].copy( p4 ); 14158 planes[ 5 ].copy( p5 ); 14159 14160 return this; 14161 14162 }, 14163 14164 clone: function () { 14165 14166 return new this.constructor().copy( this ); 14167 14168 }, 14169 14170 copy: function ( frustum ) { 14171 14172 var planes = this.planes; 14173 14174 for ( var i = 0; i < 6; i ++ ) { 14175 14176 planes[ i ].copy( frustum.planes[ i ] ); 14177 14178 } 14179 14180 return this; 14181 14182 }, 14183 14184 setFromProjectionMatrix: function ( m ) { 14185 14186 var planes = this.planes; 14187 var me = m.elements; 14188 var me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ]; 14189 var me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ]; 14190 var me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ]; 14191 var me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ]; 14192 14193 planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize(); 14194 planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize(); 14195 planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize(); 14196 planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize(); 14197 planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize(); 14198 planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize(); 14199 14200 return this; 14201 14202 }, 14203 14204 intersectsObject: function ( object ) { 14205 14206 var geometry = object.geometry; 14207 14208 if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); 14209 14210 _sphere$1.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld ); 14211 14212 return this.intersectsSphere( _sphere$1 ); 14213 14214 }, 14215 14216 intersectsSprite: function ( sprite ) { 14217 14218 _sphere$1.center.set( 0, 0, 0 ); 14219 _sphere$1.radius = 0.7071067811865476; 14220 _sphere$1.applyMatrix4( sprite.matrixWorld ); 14221 14222 return this.intersectsSphere( _sphere$1 ); 14223 14224 }, 14225 14226 intersectsSphere: function ( sphere ) { 14227 14228 var planes = this.planes; 14229 var center = sphere.center; 14230 var negRadius = - sphere.radius; 14231 14232 for ( var i = 0; i < 6; i ++ ) { 14233
vendor: 4,154 bytes, lines 14234-14504
14234 var distance = planes[ i ].distanceToPoint( center ); 14235 14236 if ( distance < negRadius ) { 14237 14238 return false; 14239 14240 } 14241 14242 } 14243 14244 return true; 14245 14246 }, 14247 14248 intersectsBox: function ( box ) { 14249 14250 var planes = this.planes; 14251 14252 for ( var i = 0; i < 6; i ++ ) { 14253 14254 var plane = planes[ i ]; 14255 14256 // corner at max distance 14257 14258 _vector$5.x = plane.normal.x > 0 ? box.max.x : box.min.x; 14259 _vector$5.y = plane.normal.y > 0 ? box.max.y : box.min.y; 14260 _vector$5.z = plane.normal.z > 0 ? box.max.z : box.min.z; 14261 14262 if ( plane.distanceToPoint( _vector$5 ) < 0 ) { 14263 14264 return false; 14265 14266 } 14267 14268 } 14269 14270 return true; 14271 14272 }, 14273 14274 containsPoint: function ( point ) { 14275 14276 var planes = this.planes; 14277 14278 for ( var i = 0; i < 6; i ++ ) { 14279 14280 if ( planes[ i ].distanceToPoint( point ) < 0 ) { 14281 14282 return false; 14283 14284 } 14285 14286 } 14287 14288 return true; 14289 14290 } 14291 14292} ); 14293 14294/** 14295 * Uniforms library for shared webgl shaders 14296 */ 14297 14298var UniformsLib = { 14299 14300 common: { 14301 14302 diffuse: { value: new Color( 0xeeeeee ) }, 14303 opacity: { value: 1.0 }, 14304 14305 map: { value: null }, 14306 uvTransform: { value: new Matrix3() }, 14307 uv2Transform: { value: new Matrix3() }, 14308 14309 alphaMap: { value: null }, 14310 14311 }, 14312 14313 specularmap: { 14314 14315 specularMap: { value: null }, 14316 14317 }, 14318 14319 envmap: { 14320 14321 envMap: { value: null }, 14322 flipEnvMap: { value: - 1 }, 14323 reflectivity: { value: 1.0 }, 14324 refractionRatio: { value: 0.98 }, 14325 maxMipLevel: { value: 0 } 14326 14327 }, 14328 14329 aomap: { 14330 14331 aoMap: { value: null }, 14332 aoMapIntensity: { value: 1 } 14333 14334 }, 14335 14336 lightmap: { 14337 14338 lightMap: { value: null }, 14339 lightMapIntensity: { value: 1 } 14340 14341 }, 14342 14343 emissivemap: { 14344 14345 emissiveMap: { value: null } 14346 14347 }, 14348 14349 bumpmap: { 14350 14351 bumpMap: { value: null }, 14352 bumpScale: { value: 1 } 14353 14354 }, 14355 14356 normalmap: { 14357 14358 normalMap: { value: null }, 14359 normalScale: { value: new Vector2( 1, 1 ) } 14360 14361 }, 14362 14363 displacementmap: { 14364 14365 displacementMap: { value: null }, 14366 displacementScale: { value: 1 }, 14367 displacementBias: { value: 0 } 14368 14369 }, 14370 14371 roughnessmap: { 14372 14373 roughnessMap: { value: null } 14374 14375 }, 14376 14377 metalnessmap: { 14378 14379 metalnessMap: { value: null } 14380 14381 }, 14382 14383 gradientmap: { 14384 14385 gradientMap: { value: null } 14386 14387 }, 14388 14389 fog: { 14390 14391 fogDensity: { value: 0.00025 }, 14392 fogNear: { value: 1 }, 14393 fogFar: { value: 2000 }, 14394 fogColor: { value: new Color( 0xffffff ) } 14395 14396 }, 14397 14398 lights: { 14399 14400 ambientLightColor: { value: [] }, 14401 14402 lightProbe: { value: [] }, 14403 14404 directionalLights: { value: [], properties: { 14405 direction: {}, 14406 color: {} 14407 } }, 14408 14409 directionalLightShadows: { value: [], properties: { 14410 shadowBias: {}, 14411 shadowRadius: {}, 14412 shadowMapSize: {} 14413 } }, 14414 14415 directionalShadowMap: { value: [] }, 14416 directionalShadowMatrix: { value: [] }, 14417 14418 spotLights: { value: [], properties: { 14419 color: {}, 14420 position: {}, 14421 direction: {}, 14422 distance: {}, 14423 coneCos: {}, 14424 penumbraCos: {}, 14425 decay: {} 14426 } }, 14427 14428 spotLightShadows: { value: [], properties: { 14429 shadowBias: {}, 14430 shadowRadius: {}, 14431 shadowMapSize: {} 14432 } }, 14433 14434 spotShadowMap: { value: [] }, 14435 spotShadowMatrix: { value: [] }, 14436 14437 pointLights: { value: [], properties: { 14438 color: {}, 14439 position: {}, 14440 decay: {}, 14441 distance: {} 14442 } }, 14443 14444 pointLightShadows: { value: [], properties: { 14445 shadowBias: {}, 14446 shadowRadius: {}, 14447 shadowMapSize: {}, 14448 shadowCameraNear: {}, 14449 shadowCameraFar: {} 14450 } }, 14451 14452 pointShadowMap: { value: [] }, 14453 pointShadowMatrix: { value: [] }, 14454 14455 hemisphereLights: { value: [], properties: { 14456 direction: {}, 14457 skyColor: {}, 14458 groundColor: {} 14459 } }, 14460 14461 // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src 14462 rectAreaLights: { value: [], properties: { 14463 color: {}, 14464 position: {}, 14465 width: {}, 14466 height: {} 14467 } } 14468 14469 }, 14470 14471 points: { 14472 14473 diffuse: { value: new Color( 0xeeeeee ) }, 14474 opacity: { value: 1.0 }, 14475 size: { value: 1.0 }, 14476 scale: { value: 1.0 }, 14477 map: { value: null }, 14478 alphaMap: { value: null }, 14479 uvTransform: { value: new Matrix3() } 14480 14481 }, 14482 14483 sprite: { 14484 14485 diffuse: { value: new Color( 0xeeeeee ) }, 14486 opacity: { value: 1.0 }, 14487 center: { value: new Vector2( 0.5, 0.5 ) }, 14488 rotation: { value: 0.0 }, 14489 map: { value: null }, 14490 alphaMap: { value: null }, 14491 uvTransform: { value: new Matrix3() } 14492 14493 } 14494 14495}; 14496 14497/** 14498 * @author mrdoob / http://mrdoob.com/ 14499 */ 14500 14501function WebGLAnimation() { 14502 14503 var context = null; 14504 var isAnimating = false;
14505 var animationLoop = null; 14506 14507 function onAnimationFrame( time, frame ) { 14508 14509 if ( isAnimating === false ) return; 14510 14511 animationLoop( time, frame ); 14512 14513 context.requestAnimationFrame( onAnimationFrame ); 14514 14515 } 14516 14517 return { 14518 14519 start: function () { 14520 14521 if ( isAnimating === true ) return; 14522 if ( animationLoop === null ) return; 14523 14524 context.requestAnimationFrame( onAnimationFrame ); 14525 14526 isAnimating = true; 14527 14528 }, 14529 14530 stop: function () { 14531 14532 isAnimating = false; 14533 14534 }, 14535 14536 setAnimationLoop: function ( callback ) { 14537 14538 animationLoop = callback; 14539 14540 }, 14541 14542 setContext: function ( value ) { 14543 14544 context = value; 14545 14546 } 14547 14548 }; 14549 14550} 14551 14552/** 14553 * @author mrdoob / http://mrdoob.com/ 14554 */ 14555 14556function WebGLAttributes( gl, capabilities ) { 14557 14558 var isWebGL2 = capabilities.isWebGL2; 14559 14560 var buffers = new WeakMap(); 14561 14562 function createBuffer( attribute, bufferType ) { 14563 14564 var array = attribute.array; 14565 var usage = attribute.usage; 14566 14567 var buffer = gl.createBuffer(); 14568 14569 gl.bindBuffer( bufferType, buffer ); 14570 gl.bufferData( bufferType, array, usage ); 14571 14572 attribute.onUploadCallback(); 14573 14574 var type = 5126; 14575 14576 if ( array instanceof Float32Array ) { 14577 14578 type = 5126; 14579 14580 } else if ( array instanceof Float64Array ) { 14581 14582 console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' ); 14583 14584 } else if ( array instanceof Uint16Array ) { 14585 14586 type = 5123; 14587 14588 } else if ( array instanceof Int16Array ) { 14589 14590 type = 5122; 14591 14592 } else if ( array instanceof Uint32Array ) { 14593 14594 type = 5125; 14595 14596 } else if ( array instanceof Int32Array ) { 14597 14598 type = 5124; 14599 14600 } else if ( array instanceof Int8Array ) { 14601 14602 type = 5120; 14603 14604 } else if ( array instanceof Uint8Array ) { 14605 14606 type = 5121; 14607 14608 } 14609 14610 return { 14611 buffer: buffer, 14612 type: type, 14613 bytesPerElement: array.BYTES_PER_ELEMENT, 14614 version: attribute.version 14615 }; 14616 14617 } 14618 14619 function updateBuffer( buffer, attribute, bufferType ) { 14620 14621 var array = attribute.array; 14622 var updateRange = attribute.updateRange; 14623 14624 gl.bindBuffer( bufferType, buffer ); 14625 14626 if ( updateRange.count === - 1 ) { 14627 14628 // Not using update ranges 14629 14630 gl.bufferSubData( bufferType, 0, array ); 14631 14632 } else { 14633 14634 if ( isWebGL2 ) { 14635 14636 gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, 14637 array, updateRange.offset, updateRange.count ); 14638 14639 } else { 14640 14641 gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, 14642 array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) ); 14643 14644 } 14645 14646 updateRange.count = - 1; // reset range 14647 14648 } 14649 14650 } 14651 14652 // 14653 14654 function get( attribute ) { 14655 14656 if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; 14657 14658 return buffers.get( attribute ); 14659 14660 } 14661 14662 function remove( attribute ) { 14663 14664 if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; 14665 14666 var data = buffers.get( attribute ); 14667 14668 if ( data ) { 14669 14670 gl.deleteBuffer( data.buffer ); 14671 14672 buffers.delete( attribute ); 14673 14674 } 14675 14676 } 14677 14678 function update( attribute, bufferType ) { 14679 14680 if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; 14681 14682 var data = buffers.get( attribute ); 14683 14684 if ( data === undefined ) { 14685 14686 buffers.set( attribute, createBuffer( attribute, bufferType ) ); 14687 14688 } else if ( data.version < attribute.version ) { 14689 14690 updateBuffer( data.buffer, attribute, bufferType ); 14691 14692 data.version = attribute.version; 14693 14694 } 14695 14696 } 14697 14698 return { 14699 14700 get: get, 14701 remove: remove, 14702 update: update 14703 14704 }; 14705 14706} 14707 14708/** 14709 * @author mrdoob / http://mrdoob.com/ 14710 * @author Mugen87 / https://github.com/Mugen87 14711 */ 14712 14713// PlaneGeometry 14714 14715function PlaneGeometry( width, height, widthSegments, heightSegments ) { 14716 14717 Geometry.call( this ); 14718 14719 this.type = 'PlaneGeometry'; 14720 14721 this.parameters = { 14722 width: width, 14723 height: height, 14724 widthSegments: widthSegments, 14725 heightSegments: heightSegments 14726 }; 14727 14728 this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) ); 14729 this.mergeVertices(); 14730 14731} 14732 14733PlaneGeometry.prototype = Object.create( Geometry.prototype ); 14734PlaneGeometry.prototype.constructor = PlaneGeometry; 14735 14736// PlaneBufferGeometry 14737 14738function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) { 14739 14740 BufferGeometry.call( this ); 14741 14742 this.type = 'PlaneBufferGeometry'; 14743 14744 this.parameters = { 14745 width: width, 14746 height: height, 14747 widthSegments: widthSegments, 14748 heightSegments: heightSegments 14749 }; 14750 14751 width = width || 1; 14752 height = height || 1; 14753 14754 var width_half = width / 2; 14755 var height_half = height / 2; 14756
14757 var gridX = Math.floor( widthSegments ) || 1; 14758 var gridY = Math.floor( heightSegments ) || 1; 14759 14760 var gridX1 = gridX + 1; 14761 var gridY1 = gridY + 1; 14762 14763 var segment_width = width / gridX; 14764 var segment_height = height / gridY; 14765 14766 var ix, iy; 14767 14768 // buffers 14769 14770 var indices = []; 14771 var vertices = []; 14772 var normals = []; 14773 var uvs = []; 14774 14775 // generate vertices, normals and uvs 14776 14777 for ( iy = 0; iy < gridY1; iy ++ ) { 14778 14779 var y = iy * segment_height - height_half; 14780 14781 for ( ix = 0; ix < gridX1; ix ++ ) { 14782 14783 var x = ix * segment_width - width_half; 14784 14785 vertices.push( x, - y, 0 ); 14786 14787 normals.push( 0, 0, 1 ); 14788 14789 uvs.push( ix / gridX ); 14790 uvs.push( 1 - ( iy / gridY ) ); 14791 14792 } 14793 14794 } 14795 14796 // indices 14797 14798 for ( iy = 0; iy < gridY; iy ++ ) { 14799 14800 for ( ix = 0; ix < gridX; ix ++ ) { 14801 14802 var a = ix + gridX1 * iy; 14803 var b = ix + gridX1 * ( iy + 1 ); 14804 var c = ( ix + 1 ) + gridX1 * ( iy + 1 ); 14805 var d = ( ix + 1 ) + gridX1 * iy; 14806 14807 // faces 14808 14809 indices.push( a, b, d ); 14810 indices.push( b, c, d ); 14811 14812 } 14813 14814 } 14815 14816 // build geometry 14817 14818 this.setIndex( indices ); 14819 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 14820 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 14821 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 14822 14823} 14824 14825PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 14826PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry; 14827 14828var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif"; 14829 14830var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; 14831 14832var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif"; 14833 14834var 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"; 14835 14836var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; 14837 14838var begin_vertex = "vec3 transformed = vec3( position );"; 14839 14840var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif"; 14841 14842var 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 );
14842\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 >
14842 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"; 14843 14844var 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}
14844\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"; 14845 14846var 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"; 14847 14848var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; 14849 14850var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif"; 14851 14852var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif"; 14853 14854var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif"; 14855 14856var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; 14857 14858var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; 14859 14860var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif"; 14861 14862var common = "#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n return m[ 2 ][ 3 ] == - 1.0;\n}"; 14863 14864var 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);\n } else if (face == 1.0) {\n uv = vec2(direction.x, -direction.z) / abs(direction.y);\n } else if (face == 2.0) {\n uv = direction.xy / abs(direction.z);\n } else if (face == 3.0) {\n uv = vec2(direction.z, direction.y) / abs(direction.x);\n } else if (face == 4.0) {\n uv = direction.xz / abs(direction.y);\n } else {\n uv = vec2(-direction.x, direction.y) / abs(direction.z);\n }\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) {\
14864n 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"; 14865 14866var 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"; 14867 14868var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif"; 14869 14870var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif"; 14871 14872var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif"; 14873 14874var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif"; 14875 14876var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; 14877 14878var 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}
14878\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}"; 14879 14880var 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\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\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"; 14881 14882var 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"; 14883 14884var 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"; 14885 14886var 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"; 14887 14888var 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}
14888 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"; 14889 14890var fog_vertex = "#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif"; 14891 14892var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif"; 14893 14894var 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"; 14895 14896var 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"; 14897 14898var 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}"; 14899 14900var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\treflectedLight.indirectDiffuse += PI * lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n#endif"; 14901 14902var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif"; 14903 14904var 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"; 14905 14906var 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\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\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\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\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\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\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}
14906\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\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\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\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"; 14907 14908var 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;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif"; 14909 14910var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; 14911 14912var lights_toon_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct ToonMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\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\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\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)"; 14913 14914var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; 14915 14916var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot
14916( 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)"; 14917 14918var 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;
14918\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"; 14919 14920var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n#ifdef CLEARCOAT\n\tfloat clearcoat;\n\tfloat clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tvec3 sheenColor;\n#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearcoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen(\n\t\t\tmaterial.specularRoughness,\n\t\t\tdirectLight.direction,\n\t\t\tgeometry,\n\t\t\tmaterial.sheenColor\n\t\t);\n\t#else\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness);\n\t#endif\n\treflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNV = saturate( dot
14920( 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}"; 14921 14922var 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"; 14923 14924var 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"; 14925 14926var 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"; 14927 14928var 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"; 14929 14930var 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"; 14931 14932var 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"; 14933 14934var 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"; 14935 14936var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif"; 14937 14938var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif"; 14939 14940var 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"; 14941 14942var 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"; 14943 14944var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif"; 14945 14946var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif"; 14947 14948var 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"; 14949 14950var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\tuniform float morphTargetBaseInfluence;\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif"; 14951 14952var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t#endif\n#endif"; 14953 14954var 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;"; 14955 14956var 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 );
14956\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"; 14957 14958var 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"; 14959 14960var clearcoat_normal_fragment_begin = "#ifdef CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif"; 14961 14962var 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"; 14963 14964var 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"; 14965 14966var 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}"; 14967 14968var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif"; 14969 14970var 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;"; 14971 14972var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; 14973 14974var 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"; 14975 14976var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif"; 14977 14978var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; 14979 14980var 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 ];
14980\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#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#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 );
14980\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"; 14981 14982var 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#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#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#endif\n#endif"; 14983 14984var shadowmap_vertex = "#ifdef USE_SHADOWMAP\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\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\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\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\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\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n#endif"; 14985 14986var 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}"; 14987 14988var 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"; 14989 14990var 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"; 14991 14992var 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"; 14993 14994var 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;
14994\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"; 14995 14996var 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"; 14997 14998var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif"; 14999 15000var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif"; 15001 15002var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}"; 15003 15004var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif"; 15005 15006var 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"; 15007 15008var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; 15009 15010var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; 15011 15012var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n\tuniform mat3 uv2Transform;\n#endif"; 15013 15014var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif"; 15015 15016var 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"; 15017 15018var 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}"; 15019 15020var 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}"; 15021 15022var 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}"; 15023 15024var 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}"; 15025 15026var 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}"; 15027 15028var 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}"; 15029 15030var 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}"; 15031 15032var 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}"; 15033 15034var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}"; 15035 15036var 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}"; 15037 15038var 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}"; 15039 15040var 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 <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 <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}"; 15041 15042var 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}"; 15043 15044var 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}"; 15045 15046var 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}"; 15047 15048var 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}"; 15049 15050var 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 +
15050 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}"; 15051 15052var 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}"; 15053 15054var meshtoon_frag = "#define TOON\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 <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 <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_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 + reflectedLight.directSpecular + reflectedLight.indirectSpecular + 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}"; 15055 15056var 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}"; 15057 15058var 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}"; 15059 15060var 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}"; 15061 15062var meshphysical_frag = "#define STANDARD\n#ifdef PHYSICAL\n\t#define REFLECTIVITY\n\t#define CLEARCOAT\n\t#define TRANSPARENCY\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef TRANSPARENCY\n\tuniform float transparency;\n#endif\n#ifdef REFLECTIVITY\n\tuniform float reflectivity;\n#endif\n#ifdef CLEARCOAT\n\tuniform float clearcoat;
15062\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheen;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <clearcoat_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <clearcoat_normal_fragment_begin>\n\t#include <clearcoat_normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#ifdef TRANSPARENCY\n\t\tdiffuseColor.a *= saturate( 1. - transparency + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) );\n\t#endif\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}"; 15063 15064var 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}"; 15065 15066var 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}"; 15067 15068var 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}"; 15069 15070var 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}"; 15071 15072var 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}"; 15073 15074var 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}"; 15075 15076var shadow_vert = "#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 <shadowmap_vertex>\n\t#include <fog_vertex>\n}"; 15077 15078var 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}"; 15079 15080var 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}"; 15081 15082var ShaderChunk = { 15083 alphamap_fragment: alphamap_fragment, 15084 alphamap_pars_fragment: alphamap_pars_fragment, 15085 alphatest_fragment: alphatest_fragment, 15086 aomap_fragment: aomap_fragment, 15087 aomap_pars_fragment: aomap_pars_fragment, 15088 begin_vertex: begin_vertex, 15089 beginnormal_vertex: beginnormal_vertex, 15090 bsdfs: bsdfs, 15091 bumpmap_pars_fragment: bumpmap_pars_fragment, 15092 clipping_planes_fragment: clipping_planes_fragment, 15093 clipping_planes_pars_fragment: clipping_planes_pars_fragment, 15094 clipping_planes_pars_vertex: clipping_planes_pars_vertex, 15095 clipping_planes_vertex: clipping_planes_vertex, 15096 color_fragment: color_fragment, 15097 color_pars_fragment: color_pars_fragment, 15098 color_pars_vertex: color_pars_vertex, 15099 color_vertex: color_vertex, 15100 common: common, 15101 cube_uv_reflection_fragment: cube_uv_reflection_fragment, 15102 defaultnormal_vertex: defaultnormal_vertex, 15103 displacementmap_pars_vertex: displacementmap_pars_vertex, 15104 displacementmap_vertex: displacementmap_vertex, 15105 emissivemap_fragment: emissivemap_fragment, 15106 emissivemap_pars_fragment: emissivemap_pars_fragment, 15107 encodings_fragment: encodings_fragment, 15108 encodings_pars_fragment: encodings_pars_fragment, 15109 envmap_fragment: envmap_fragment, 15110 envmap_common_pars_fragment: envmap_common_pars_fragment, 15111 envmap_pars_fragment: envmap_pars_fragment, 15112 envmap_pars_vertex: envmap_pars_vertex, 15113 envmap_physical_pars_fragment: envmap_physical_pars_fragment, 15114 envmap_vertex: envmap_vertex, 15115 fog_vertex: fog_vertex, 15116 fog_pars_vertex: fog_pars_vertex, 15117 fog_fragment: fog_fragment, 15118 fog_pars_fragment: fog_pars_fragment, 15119 gradientmap_pars_fragment: gradientmap_pars_fragment, 15120 lightmap_fragment: lightmap_fragment, 15121 lightmap_pars_fragment: lightmap_pars_fragment, 15122 lights_lambert_vertex: lights_lambert_vertex, 15123 lights_pars_begin: lights_pars_begin, 15124 lights_toon_fragment: lights_toon_fragment, 15125 lights_toon_pars_fragment: lights_toon_pars_fragment, 15126 lights_phong_fragment: lights_phong_fragment, 15127 lights_phong_pars_fragment: lights_phong_pars_fragment, 15128 lights_physical_fragment: lights_physical_fragment, 15129 lights_physical_pars_fragment: lights_physical_pars_fragment, 15130 lights_fragment_begin: lights_fragment_begin, 15131 lights_fragment_maps: lights_fragment_maps, 15132 lights_fragment_end: lights_fragment_end, 15133 logdepthbuf_fragment: logdepthbuf_fragment, 15134 logdepthbuf_pars_fragment: logdepthbuf_pars_fragment, 15135 logdepthbuf_pars_vertex: logdepthbuf_pars_vertex, 15136 logdepthbuf_vertex: logdepthbuf_vertex, 15137 map_fragment: map_fragment, 15138 map_pars_fragment: map_pars_fragment, 15139 map_particle_fragment: map_particle_fragment, 15140 map_particle_pars_fragment: map_particle_pars_fragment, 15141 metalnessmap_fragment: metalnessmap_fragment, 15142 metalnessmap_pars_fragment: metalnessmap_pars_fragment, 15143 morphnormal_vertex: morphnormal_vertex, 15144 morphtarget_pars_vertex: morphtarget_pars_vertex, 15145 morphtarget_vertex: morphtarget_vertex, 15146 normal_fragment_begin: normal_fragment_begin, 15147 normal_fragment_maps: normal_fragment_maps, 15148 normalmap_pars_fragment: normalmap_pars_fragment, 15149 clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin, 15150 clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps, 15151 clearcoat_pars_fragment: clearcoat_pars_fragment, 15152 packing: packing, 15153 premultiplied_alpha_fragment: premultiplied_alpha_fragment, 15154 project_vertex: project_vertex, 15155 dithering_fragment: dithering_fragment, 15156 dithering_pars_fragment: dithering_pars_fragment, 15157 roughnessmap_fragment: roughnessmap_fragment, 15158 roughnessmap_pars_fragment: roughnessmap_pars_fragment, 15159 shadowmap_pars_fragment: shadowmap_pars_fragment, 15160 shadowmap_pars_vertex: shadowmap_pars_vertex, 15161 shadowmap_vertex: shadowmap_vertex, 15162 shadowmask_pars_fragment: shadowmask_pars_fragment, 15163 skinbase_vertex: skinbase_vertex, 15164 skinning_pars_vertex: skinning_pars_vertex, 15165 skinning_vertex: skinning_vertex, 15166 skinnormal_vertex: skinnormal_vertex, 15167 specularmap_fragment: specularmap_fragment, 15168 specularmap_pars_fragment: specularmap_pars_fragment, 15169 tonemapping_fragment: tonemapping_fragment, 15170 tonemapping_pars_fragment: tonemapping_pars_fragment, 15171 uv_pars_fragment: uv_pars_fragment, 15172 uv_pars_vertex: uv_pars_vertex, 15173 uv_vertex: uv_vertex, 15174 uv2_pars_fragment: uv2_pars_fragment, 15175 uv2_pars_vertex: uv2_pars_vertex, 15176 uv2_vertex: uv2_vertex, 15177 worldpos_vertex: worldpos_vertex, 15178 15179 background_frag: background_frag, 15180 background_vert: background_vert, 15181 cube_frag: cube_frag, 15182 cube_vert: cube_vert, 15183 depth_frag: depth_frag, 15184 depth_vert: depth_vert, 15185 distanceRGBA_frag: distanceRGBA_frag, 15186 distanceRGBA_vert: distanceRGBA_vert, 15187 equirect_frag: equirect_frag, 15188 equirect_vert: equirect_vert, 15189 linedashed_frag: linedashed_frag, 15190 linedashed_vert: linedashed_vert, 15191 meshbasic_frag: meshbasic_frag, 15192 meshbasic_vert: meshbasic_vert, 15193 meshlambert_frag: meshlambert_frag, 15194 meshlambert_vert: meshlambert_vert, 15195 meshmatcap_frag: meshmatcap_frag, 15196 meshmatcap_vert: meshmatcap_vert, 15197 meshtoon_frag: meshtoon_frag, 15198 meshtoon_vert: meshtoon_vert, 15199 meshphong_frag: meshphong_frag, 15200 meshphong_vert: meshphong_vert, 15201 meshphysical_frag: meshphysical_frag, 15202 meshphysical_vert: meshphysical_vert, 15203 normal_frag: normal_frag, 15204 normal_vert: normal_vert, 15205 points_frag: points_frag, 15206 points_vert: points_vert, 15207 shadow_frag: shadow_frag, 15208 shadow_vert: shadow_vert, 15209 sprite_frag: sprite_frag, 15210 sprite_vert: sprite_vert 15211}; 15212 15213/** 15214 * @author alteredq / http://alteredqualia.com/ 15215 * @author mrdoob / http://mrdoob.com/ 15216 * @author mikael emtinger / http://gomo.se/ 15217 */ 15218 15219var ShaderLib = { 15220 15221 basic: { 15222 15223 uniforms: mergeUniforms( [ 15224 UniformsLib.common, 15225 UniformsLib.specularmap, 15226 UniformsLib.envmap, 15227 UniformsLib.aomap, 15228 UniformsLib.lightmap, 15229 UniformsLib.fog 15230 ] ), 15231 15232 vertexShader: ShaderChunk.meshbasic_vert, 15233 fragmentShader: ShaderChunk.meshbasic_frag 15234 15235 }, 15236 15237 lambert: { 15238 15239 uniforms: mergeUniforms( [ 15240 UniformsLib.common, 15241 UniformsLib.specularmap, 15242 UniformsLib.envmap, 15243 UniformsLib.aomap, 15244 UniformsLib.lightmap, 15245 UniformsLib.emissivemap, 15246 UniformsLib.fog, 15247 UniformsLib.lights, 15248 { 15249 emissive: { value: new Color( 0x000000 ) } 15250 } 15251 ] ), 15252 15253 vertexShader: ShaderChunk.meshlambert_vert, 15254 fragmentShader: ShaderChunk.meshlambert_frag 15255 15256 }, 15257 15258 phong: { 15259 15260 uniforms: mergeUniforms( [ 15261 UniformsLib.common, 15262 UniformsLib.specularmap, 15263 UniformsLib.envmap, 15264 UniformsLib.
vendor: 4,907 bytes, lines 15264-15525
15264aomap, 15265 UniformsLib.lightmap, 15266 UniformsLib.emissivemap, 15267 UniformsLib.bumpmap, 15268 UniformsLib.normalmap, 15269 UniformsLib.displacementmap, 15270 UniformsLib.fog, 15271 UniformsLib.lights, 15272 { 15273 emissive: { value: new Color( 0x000000 ) }, 15274 specular: { value: new Color( 0x111111 ) }, 15275 shininess: { value: 30 } 15276 } 15277 ] ), 15278 15279 vertexShader: ShaderChunk.meshphong_vert, 15280 fragmentShader: ShaderChunk.meshphong_frag 15281 15282 }, 15283 15284 standard: { 15285 15286 uniforms: mergeUniforms( [ 15287 UniformsLib.common, 15288 UniformsLib.envmap, 15289 UniformsLib.aomap, 15290 UniformsLib.lightmap, 15291 UniformsLib.emissivemap, 15292 UniformsLib.bumpmap, 15293 UniformsLib.normalmap, 15294 UniformsLib.displacementmap, 15295 UniformsLib.roughnessmap, 15296 UniformsLib.metalnessmap, 15297 UniformsLib.fog, 15298 UniformsLib.lights, 15299 { 15300 emissive: { value: new Color( 0x000000 ) }, 15301 roughness: { value: 1.0 }, 15302 metalness: { value: 0.0 }, 15303 envMapIntensity: { value: 1 } // temporary 15304 } 15305 ] ), 15306 15307 vertexShader: ShaderChunk.meshphysical_vert, 15308 fragmentShader: ShaderChunk.meshphysical_frag 15309 15310 }, 15311 15312 toon: { 15313 15314 uniforms: mergeUniforms( [ 15315 UniformsLib.common, 15316 UniformsLib.specularmap, 15317 UniformsLib.aomap, 15318 UniformsLib.lightmap, 15319 UniformsLib.emissivemap, 15320 UniformsLib.bumpmap, 15321 UniformsLib.normalmap, 15322 UniformsLib.displacementmap, 15323 UniformsLib.gradientmap, 15324 UniformsLib.fog, 15325 UniformsLib.lights, 15326 { 15327 emissive: { value: new Color( 0x000000 ) }, 15328 specular: { value: new Color( 0x111111 ) }, 15329 shininess: { value: 30 } 15330 } 15331 ] ), 15332 15333 vertexShader: ShaderChunk.meshtoon_vert, 15334 fragmentShader: ShaderChunk.meshtoon_frag 15335 15336 }, 15337 15338 matcap: { 15339 15340 uniforms: mergeUniforms( [ 15341 UniformsLib.common, 15342 UniformsLib.bumpmap, 15343 UniformsLib.normalmap, 15344 UniformsLib.displacementmap, 15345 UniformsLib.fog, 15346 { 15347 matcap: { value: null } 15348 } 15349 ] ), 15350 15351 vertexShader: ShaderChunk.meshmatcap_vert, 15352 fragmentShader: ShaderChunk.meshmatcap_frag 15353 15354 }, 15355 15356 points: { 15357 15358 uniforms: mergeUniforms( [ 15359 UniformsLib.points, 15360 UniformsLib.fog 15361 ] ), 15362 15363 vertexShader: ShaderChunk.points_vert, 15364 fragmentShader: ShaderChunk.points_frag 15365 15366 }, 15367 15368 dashed: { 15369 15370 uniforms: mergeUniforms( [ 15371 UniformsLib.common, 15372 UniformsLib.fog, 15373 { 15374 scale: { value: 1 }, 15375 dashSize: { value: 1 }, 15376 totalSize: { value: 2 } 15377 } 15378 ] ), 15379 15380 vertexShader: ShaderChunk.linedashed_vert, 15381 fragmentShader: ShaderChunk.linedashed_frag 15382 15383 }, 15384 15385 depth: { 15386 15387 uniforms: mergeUniforms( [ 15388 UniformsLib.common, 15389 UniformsLib.displacementmap 15390 ] ), 15391 15392 vertexShader: ShaderChunk.depth_vert, 15393 fragmentShader: ShaderChunk.depth_frag 15394 15395 }, 15396 15397 normal: { 15398 15399 uniforms: mergeUniforms( [ 15400 UniformsLib.common, 15401 UniformsLib.bumpmap, 15402 UniformsLib.normalmap, 15403 UniformsLib.displacementmap, 15404 { 15405 opacity: { value: 1.0 } 15406 } 15407 ] ), 15408 15409 vertexShader: ShaderChunk.normal_vert, 15410 fragmentShader: ShaderChunk.normal_frag 15411 15412 }, 15413 15414 sprite: { 15415 15416 uniforms: mergeUniforms( [ 15417 UniformsLib.sprite, 15418 UniformsLib.fog 15419 ] ), 15420 15421 vertexShader: ShaderChunk.sprite_vert, 15422 fragmentShader: ShaderChunk.sprite_frag 15423 15424 }, 15425 15426 background: { 15427 15428 uniforms: { 15429 uvTransform: { value: new Matrix3() }, 15430 t2D: { value: null }, 15431 }, 15432 15433 vertexShader: ShaderChunk.background_vert, 15434 fragmentShader: ShaderChunk.background_frag 15435 15436 }, 15437 /* ------------------------------------------------------------------------- 15438 // Cube map shader 15439 ------------------------------------------------------------------------- */ 15440 15441 cube: { 15442 15443 uniforms: mergeUniforms( [ 15444 UniformsLib.envmap, 15445 { 15446 opacity: { value: 1.0 } 15447 } 15448 ] ), 15449 15450 vertexShader: ShaderChunk.cube_vert, 15451 fragmentShader: ShaderChunk.cube_frag 15452 15453 }, 15454 15455 equirect: { 15456 15457 uniforms: { 15458 tEquirect: { value: null }, 15459 }, 15460 15461 vertexShader: ShaderChunk.equirect_vert, 15462 fragmentShader: ShaderChunk.equirect_frag 15463 15464 }, 15465 15466 distanceRGBA: { 15467 15468 uniforms: mergeUniforms( [ 15469 UniformsLib.common, 15470 UniformsLib.displacementmap, 15471 { 15472 referencePosition: { value: new Vector3() }, 15473 nearDistance: { value: 1 }, 15474 farDistance: { value: 1000 } 15475 } 15476 ] ), 15477 15478 vertexShader: ShaderChunk.distanceRGBA_vert, 15479 fragmentShader: ShaderChunk.distanceRGBA_frag 15480 15481 }, 15482 15483 shadow: { 15484 15485 uniforms: mergeUniforms( [ 15486 UniformsLib.lights, 15487 UniformsLib.fog, 15488 { 15489 color: { value: new Color( 0x00000 ) }, 15490 opacity: { value: 1.0 } 15491 }, 15492 ] ), 15493 15494 vertexShader: ShaderChunk.shadow_vert, 15495 fragmentShader: ShaderChunk.shadow_frag 15496 15497 } 15498 15499}; 15500 15501ShaderLib.physical = { 15502 15503 uniforms: mergeUniforms( [ 15504 ShaderLib.standard.uniforms, 15505 { 15506 clearcoat: { value: 0 }, 15507 clearcoatMap: { value: null }, 15508 clearcoatRoughness: { value: 0 }, 15509 clearcoatRoughnessMap: { value: null }, 15510 clearcoatNormalScale: { value: new Vector2( 1, 1 ) }, 15511 clearcoatNormalMap: { value: null }, 15512 sheen: { value: new Color( 0x000000 ) }, 15513 transparency: { value: 0 }, 15514 } 15515 ] ), 15516 15517 vertexShader: ShaderChunk.meshphysical_vert, 15518 fragmentShader: ShaderChunk.meshphysical_frag 15519 15520}; 15521 15522/** 15523 * @author mrdoob / http://mrdoob.com/ 15524 */ 15525
vendor: 17,557 bytes, lines 15526-16393
15526function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { 15527 15528 var clearColor = new Color( 0x000000 ); 15529 var clearAlpha = 0; 15530 15531 var planeMesh; 15532 var boxMesh; 15533 15534 var currentBackground = null; 15535 var currentBackgroundVersion = 0; 15536 var currentTonemapping = null; 15537 15538 function render( renderList, scene, camera, forceClear ) { 15539 15540 var background = scene.background; 15541 15542 // Ignore background in AR 15543 // TODO: Reconsider this. 15544 15545 var xr = renderer.xr; 15546 var session = xr.getSession && xr.getSession(); 15547 15548 if ( session && session.environmentBlendMode === 'additive' ) { 15549 15550 background = null; 15551 15552 } 15553 15554 if ( background === null ) { 15555 15556 setClear( clearColor, clearAlpha ); 15557 15558 } else if ( background && background.isColor ) { 15559 15560 setClear( background, 1 ); 15561 forceClear = true; 15562 15563 } 15564 15565 if ( renderer.autoClear || forceClear ) { 15566 15567 renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil ); 15568 15569 } 15570 15571 if ( background && ( background.isCubeTexture || background.isWebGLCubeRenderTarget || background.mapping === CubeUVReflectionMapping ) ) { 15572 15573 if ( boxMesh === undefined ) { 15574 15575 boxMesh = new Mesh( 15576 new BoxBufferGeometry( 1, 1, 1 ), 15577 new ShaderMaterial( { 15578 type: 'BackgroundCubeMaterial', 15579 uniforms: cloneUniforms( ShaderLib.cube.uniforms ), 15580 vertexShader: ShaderLib.cube.vertexShader, 15581 fragmentShader: ShaderLib.cube.fragmentShader, 15582 side: BackSide, 15583 depthTest: false, 15584 depthWrite: false, 15585 fog: false 15586 } ) 15587 ); 15588 15589 boxMesh.geometry.deleteAttribute( 'normal' ); 15590 boxMesh.geometry.deleteAttribute( 'uv' ); 15591 15592 boxMesh.onBeforeRender = function ( renderer, scene, camera ) { 15593 15594 this.matrixWorld.copyPosition( camera.matrixWorld ); 15595 15596 }; 15597 15598 // enable code injection for non-built-in material 15599 Object.defineProperty( boxMesh.material, 'envMap', { 15600 15601 get: function () { 15602 15603 return this.uniforms.envMap.value; 15604 15605 } 15606 15607 } ); 15608 15609 objects.update( boxMesh ); 15610 15611 } 15612 15613 var texture = background.isWebGLCubeRenderTarget ? background.texture : background; 15614 15615 boxMesh.material.uniforms.envMap.value = texture; 15616 boxMesh.material.uniforms.flipEnvMap.value = texture.isCubeTexture ? - 1 : 1; 15617 15618 if ( currentBackground !== background || 15619 currentBackgroundVersion !== texture.version || 15620 currentTonemapping !== renderer.toneMapping ) { 15621 15622 boxMesh.material.needsUpdate = true; 15623 15624 currentBackground = background; 15625 currentBackgroundVersion = texture.version; 15626 currentTonemapping = renderer.toneMapping; 15627 15628 } 15629 15630 // push to the pre-sorted opaque render list 15631 renderList.unshift( boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null ); 15632 15633 } else if ( background && background.isTexture ) { 15634 15635 if ( planeMesh === undefined ) { 15636 15637 planeMesh = new Mesh( 15638 new PlaneBufferGeometry( 2, 2 ), 15639 new ShaderMaterial( { 15640 type: 'BackgroundMaterial', 15641 uniforms: cloneUniforms( ShaderLib.background.uniforms ), 15642 vertexShader: ShaderLib.background.vertexShader, 15643 fragmentShader: ShaderLib.background.fragmentShader, 15644 side: FrontSide, 15645 depthTest: false, 15646 depthWrite: false, 15647 fog: false 15648 } ) 15649 ); 15650 15651 planeMesh.geometry.deleteAttribute( 'normal' ); 15652 15653 // enable code injection for non-built-in material 15654 Object.defineProperty( planeMesh.material, 'map', { 15655 15656 get: function () { 15657 15658 return this.uniforms.t2D.value; 15659 15660 } 15661 15662 } ); 15663 15664 objects.update( planeMesh ); 15665 15666 } 15667 15668 planeMesh.material.uniforms.t2D.value = background; 15669 15670 if ( background.matrixAutoUpdate === true ) { 15671 15672 background.updateMatrix(); 15673 15674 } 15675 15676 planeMesh.material.uniforms.uvTransform.value.copy( background.matrix ); 15677 15678 if ( currentBackground !== background || 15679 currentBackgroundVersion !== background.version || 15680 currentTonemapping !== renderer.toneMapping ) { 15681 15682 planeMesh.material.needsUpdate = true; 15683 15684 currentBackground = background; 15685 currentBackgroundVersion = background.version; 15686 currentTonemapping = renderer.toneMapping; 15687 15688 } 15689 15690 15691 // push to the pre-sorted opaque render list 15692 renderList.unshift( planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null ); 15693 15694 } 15695 15696 } 15697 15698 function setClear( color, alpha ) { 15699 15700 state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha ); 15701 15702 } 15703 15704 return { 15705 15706 getClearColor: function () { 15707 15708 return clearColor; 15709 15710 }, 15711 setClearColor: function ( color, alpha ) { 15712 15713 clearColor.set( color ); 15714 clearAlpha = alpha !== undefined ? alpha : 1; 15715 setClear( clearColor, clearAlpha ); 15716 15717 }, 15718 getClearAlpha: function () { 15719 15720 return clearAlpha; 15721 15722 }, 15723 setClearAlpha: function ( alpha ) { 15724 15725 clearAlpha = alpha; 15726 setClear( clearColor, clearAlpha ); 15727 15728 }, 15729 render: render 15730 15731 }; 15732 15733} 15734 15735/** 15736 * @author mrdoob / http://mrdoob.com/ 15737 */ 15738 15739function WebGLBufferRenderer( gl, extensions, info, capabilities ) { 15740 15741 var isWebGL2 = capabilities.isWebGL2; 15742 15743 var mode; 15744 15745 function setMode( value ) { 15746 15747 mode = value; 15748 15749 } 15750 15751 function render( start, count ) { 15752 15753 gl.drawArrays( mode, start, count ); 15754 15755 info.update( count, mode ); 15756 15757 } 15758 15759 function renderInstances( geometry, start, count, primcount ) { 15760 15761 if ( primcount === 0 ) return; 15762 15763 var extension, methodName; 15764 15765 if ( isWebGL2 ) { 15766 15767 extension = gl; 15768 methodName = 'drawArraysInstanced'; 15769 15770 } else { 15771 15772 extension = extensions.get( 'ANGLE_instanced_arrays' ); 15773 methodName = 'drawArraysInstancedANGLE'; 15774 15775 if ( extension === null ) { 15776 15777 console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); 15778 return; 15779 15780 } 15781 15782 } 15783 15784 extension[ methodName ]( mode, start, count, primcount ); 15785 15786 info.update( count, mode, primcount ); 15787 15788 } 15789 15790 // 15791 15792 this.setMode = setMode; 15793 this.render = render; 15794 this.renderInstances = renderInstances; 15795 15796} 15797 15798/** 15799 * @author mrdoob / http://mrdoob.com/ 15800 */ 15801 15802function WebGLCapabilities( gl, extensions, parameters ) { 15803 15804 var maxAnisotropy; 15805 15806 function getMaxAnisotropy() { 15807 15808 if ( maxAnisotropy !== undefined ) return maxAnisotropy; 15809 15810 var extension = extensions.get( 'EXT_texture_filter_anisotropic' ); 15811 15812 if ( extension !== null ) { 15813 15814 maxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT ); 15815 15816 } else { 15817 15818 maxAnisotropy = 0; 15819 15820 } 15821 15822 return maxAnisotropy; 15823 15824 } 15825 15826 function getMaxPrecision( precision ) { 15827 15828 if ( precision === 'highp' ) { 15829 15830 if ( gl.getShaderPrecisionFormat( 35633, 36338 ).precision > 0 && 15831 gl.getShaderPrecisionFormat( 35632, 36338 ).precision > 0 ) { 15832 15833 return 'highp'; 15834 15835 } 15836 15837 precision = 'mediump'; 15838 15839 } 15840 15841 if ( precision === 'mediump' ) { 15842 15843 if ( gl.getShaderPrecisionFormat( 35633, 36337 ).precision > 0 && 15844 gl.getShaderPrecisionFormat( 35632, 36337 ).precision > 0 ) { 15845 15846 return 'mediump'; 15847 15848 } 15849 15850 } 15851 15852 return 'lowp'; 15853 15854 } 15855 15856 /* eslint-disable no-undef */ 15857 var isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext ) || 15858 ( typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext ); 15859 /* eslint-enable no-undef */ 15860 15861 var precision = parameters.precision !== undefined ? parameters.precision : 'highp'; 15862 var maxPrecision = getMaxPrecision( precision ); 15863 15864 if ( maxPrecision !== precision ) { 15865 15866 console.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' ); 15867 precision = maxPrecision; 15868 15869 } 15870 15871 var logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; 15872 15873 var maxTextures = gl.getParameter( 34930 ); 15874 var maxVertexTextures = gl.getParameter( 35660 ); 15875 var maxTextureSize = gl.getParameter( 3379 ); 15876 var maxCubemapSize = gl.getParameter( 34076 ); 15877 15878 var maxAttributes = gl.getParameter( 34921 ); 15879 var maxVertexUniforms = gl.getParameter( 36347 ); 15880 var maxVaryings = gl.getParameter( 36348 ); 15881 var maxFragmentUniforms = gl.getParameter( 36349 ); 15882 15883 var vertexTextures = maxVertexTextures > 0; 15884 var floatFragmentTextures = isWebGL2 || !! extensions.get( 'OES_texture_float' ); 15885 var floatVertexTextures = vertexTextures && floatFragmentTextures; 15886 15887 var maxSamples = isWebGL2 ? gl.getParameter( 36183 ) : 0; 15888 15889 return { 15890 15891 isWebGL2: isWebGL2, 15892 15893 getMaxAnisotropy: getMaxAnisotropy, 15894 getMaxPrecision: getMaxPrecision, 15895 15896 precision: precision, 15897 logarithmicDepthBuffer: logarithmicDepthBuffer, 15898 15899 maxTextures: maxTextures, 15900 maxVertexTextures: maxVertexTextures, 15901 maxTextureSize: maxTextureSize, 15902 maxCubemapSize: maxCubemapSize, 15903 15904 maxAttributes: maxAttributes, 15905 maxVertexUniforms: maxVertexUniforms, 15906 maxVaryings: maxVaryings, 15907 maxFragmentUniforms: maxFragmentUniforms, 15908 15909 vertexTextures: vertexTextures, 15910 floatFragmentTextures: floatFragmentTextures, 15911 floatVertexTextures: floatVertexTextures, 15912 15913 maxSamples: maxSamples 15914 15915 }; 15916 15917} 15918 15919/** 15920 * @author tschw 15921 */ 15922 15923function WebGLClipping() { 15924 15925 var scope = this, 15926 15927 globalState = null, 15928 numGlobalPlanes = 0, 15929 localClippingEnabled = false, 15930 renderingShadows = false, 15931 15932 plane = new Plane(), 15933 viewNormalMatrix = new Matrix3(), 15934 15935 uniform = { value: null, needsUpdate: false }; 15936 15937 this.uniform = uniform; 15938 this.numPlanes = 0; 15939 this.numIntersection = 0; 15940 15941 this.init = function ( planes, enableLocalClipping, camera ) { 15942 15943 var enabled = 15944 planes.length !== 0 || 15945 enableLocalClipping || 15946 // enable state of previous frame - the clipping code has to 15947 // run another frame in order to reset the state: 15948 numGlobalPlanes !== 0 || 15949 localClippingEnabled; 15950 15951 localClippingEnabled = enableLocalClipping; 15952 15953 globalState = projectPlanes( planes, camera, 0 ); 15954 numGlobalPlanes = planes.length; 15955 15956 return enabled; 15957 15958 }; 15959 15960 this.beginShadows = function () { 15961 15962 renderingShadows = true; 15963 projectPlanes( null ); 15964 15965 }; 15966 15967 this.endShadows = function () { 15968 15969 renderingShadows = false; 15970 resetGlobalState(); 15971 15972 }; 15973 15974 this.setState = function ( planes, clipIntersection, clipShadows, camera, cache, fromCache ) { 15975 15976 if ( ! localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && ! clipShadows ) { 15977 15978 // there's no local clipping 15979 15980 if ( renderingShadows ) { 15981 15982 // there's no global clipping 15983 15984 projectPlanes( null ); 15985 15986 } else { 15987 15988 resetGlobalState(); 15989 15990 } 15991 15992 } else { 15993 15994 var nGlobal = renderingShadows ? 0 : numGlobalPlanes, 15995 lGlobal = nGlobal * 4, 15996 15997 dstArray = cache.clippingState || null; 15998 15999 uniform.value = dstArray; // ensure unique state 16000 16001 dstArray = projectPlanes( planes, camera, lGlobal, fromCache ); 16002 16003 for ( var i = 0; i !== lGlobal; ++ i ) { 16004 16005 dstArray[ i ] = globalState[ i ]; 16006 16007 } 16008 16009 cache.clippingState = dstArray; 16010 this.numIntersection = clipIntersection ? this.numPlanes : 0; 16011 this.numPlanes += nGlobal; 16012 16013 } 16014 16015 16016 }; 16017 16018 function resetGlobalState() { 16019 16020 if ( uniform.value !== globalState ) { 16021 16022 uniform.value = globalState; 16023 uniform.needsUpdate = numGlobalPlanes > 0; 16024 16025 } 16026 16027 scope.numPlanes = numGlobalPlanes; 16028 scope.numIntersection = 0; 16029 16030 } 16031 16032 function projectPlanes( planes, camera, dstOffset, skipTransform ) { 16033 16034 var nPlanes = planes !== null ? planes.length : 0, 16035 dstArray = null; 16036 16037 if ( nPlanes !== 0 ) { 16038 16039 dstArray = uniform.value; 16040 16041 if ( skipTransform !== true || dstArray === null ) { 16042 16043 var flatSize = dstOffset + nPlanes * 4, 16044 viewMatrix = camera.matrixWorldInverse; 16045 16046 viewNormalMatrix.getNormalMatrix( viewMatrix ); 16047 16048 if ( dstArray === null || dstArray.length < flatSize ) { 16049 16050 dstArray = new Float32Array( flatSize ); 16051 16052 } 16053 16054 for ( var i = 0, i4 = dstOffset; i !== nPlanes; ++ i, i4 += 4 ) { 16055 16056 plane.copy( planes[ i ] ).applyMatrix4( viewMatrix, viewNormalMatrix ); 16057 16058 plane.normal.toArray( dstArray, i4 ); 16059 dstArray[ i4 + 3 ] = plane.constant; 16060 16061 } 16062 16063 } 16064 16065 uniform.value = dstArray; 16066 uniform.needsUpdate = true; 16067 16068 } 16069 16070 scope.numPlanes = nPlanes; 16071 scope.numIntersection = 0; 16072 16073 return dstArray; 16074 16075 } 16076 16077} 16078 16079/** 16080 * @author mrdoob / http://mrdoob.com/ 16081 */ 16082 16083function WebGLExtensions( gl ) { 16084 16085 var extensions = {}; 16086 16087 return { 16088 16089 get: function ( name ) { 16090 16091 if ( extensions[ name ] !== undefined ) { 16092 16093 return extensions[ name ]; 16094 16095 } 16096 16097 var extension; 16098 16099 switch ( name ) { 16100 16101 case 'WEBGL_depth_texture': 16102 extension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' ); 16103 break; 16104 16105 case 'EXT_texture_filter_anisotropic': 16106 extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' ); 16107 break; 16108 16109 case 'WEBGL_compressed_texture_s3tc': 16110 extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' ); 16111 break; 16112 16113 case 'WEBGL_compressed_texture_pvrtc': 16114 extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' ); 16115 break; 16116 16117 default: 16118 extension = gl.getExtension( name ); 16119 16120 } 16121 16122 if ( extension === null ) { 16123 16124 console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' ); 16125 16126 } 16127 16128 extensions[ name ] = extension; 16129 16130 return extension; 16131 16132 } 16133 16134 }; 16135 16136} 16137 16138/** 16139 * @author mrdoob / http://mrdoob.com/ 16140 */ 16141 16142function WebGLGeometries( gl, attributes, info ) { 16143 16144 var geometries = new WeakMap(); 16145 var wireframeAttributes = new WeakMap(); 16146 16147 function onGeometryDispose( event ) { 16148 16149 var geometry = event.target; 16150 var buffergeometry = geometries.get( geometry ); 16151 16152 if ( buffergeometry.index !== null ) { 16153 16154 attributes.remove( buffergeometry.index ); 16155 16156 } 16157 16158 for ( var name in buffergeometry.attributes ) { 16159 16160 attributes.remove( buffergeometry.attributes[ name ] ); 16161 16162 } 16163 16164 geometry.removeEventListener( 'dispose', onGeometryDispose ); 16165 16166 geometries.delete( geometry ); 16167 16168 var attribute = wireframeAttributes.get( buffergeometry ); 16169 16170 if ( attribute ) { 16171 16172 attributes.remove( attribute ); 16173 wireframeAttributes.delete( buffergeometry ); 16174 16175 } 16176 16177 // 16178 16179 info.memory.geometries --; 16180 16181 } 16182 16183 function get( object, geometry ) { 16184 16185 var buffergeometry = geometries.get( geometry ); 16186 16187 if ( buffergeometry ) return buffergeometry; 16188 16189 geometry.addEventListener( 'dispose', onGeometryDispose ); 16190 16191 if ( geometry.isBufferGeometry ) { 16192 16193 buffergeometry = geometry; 16194 16195 } else if ( geometry.isGeometry ) { 16196 16197 if ( geometry._bufferGeometry === undefined ) { 16198 16199 geometry._bufferGeometry = new BufferGeometry().setFromObject( object ); 16200 16201 } 16202 16203 buffergeometry = geometry._bufferGeometry; 16204 16205 } 16206 16207 geometries.set( geometry, buffergeometry ); 16208 16209 info.memory.geometries ++; 16210 16211 return buffergeometry; 16212 16213 } 16214 16215 function update( geometry ) { 16216 16217 var index = geometry.index; 16218 var geometryAttributes = geometry.attributes; 16219 16220 if ( index !== null ) { 16221 16222 attributes.update( index, 34963 ); 16223 16224 } 16225 16226 for ( var name in geometryAttributes ) { 16227 16228 attributes.update( geometryAttributes[ name ], 34962 ); 16229 16230 } 16231 16232 // morph targets 16233 16234 var morphAttributes = geometry.morphAttributes; 16235 16236 for ( var name in morphAttributes ) { 16237 16238 var array = morphAttributes[ name ]; 16239 16240 for ( var i = 0, l = array.length; i < l; i ++ ) { 16241 16242 attributes.update( array[ i ], 34962 ); 16243 16244 } 16245 16246 } 16247 16248 } 16249 16250 function updateWireframeAttribute( geometry ) { 16251 16252 var indices = []; 16253 16254 var geometryIndex = geometry.index; 16255 var geometryPosition = geometry.attributes.position; 16256 var version = 0; 16257 16258 if ( geometryIndex !== null ) { 16259 16260 var array = geometryIndex.array; 16261 version = geometryIndex.version; 16262 16263 for ( var i = 0, l = array.length; i < l; i += 3 ) { 16264 16265 var a = array[ i + 0 ]; 16266 var b = array[ i + 1 ]; 16267 var c = array[ i + 2 ]; 16268 16269 indices.push( a, b, b, c, c, a ); 16270 16271 } 16272 16273 } else { 16274 16275 var array = geometryPosition.array; 16276 version = geometryPosition.version; 16277 16278 for ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) { 16279 16280 var a = i + 0; 16281 var b = i + 1; 16282 var c = i + 2; 16283 16284 indices.push( a, b, b, c, c, a ); 16285 16286 } 16287 16288 } 16289 16290 var attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 ); 16291 attribute.version = version; 16292 16293 attributes.update( attribute, 34963 ); 16294 16295 // 16296 16297 var previousAttribute = wireframeAttributes.get( geometry ); 16298 16299 if ( previousAttribute ) attributes.remove( previousAttribute ); 16300 16301 // 16302 16303 wireframeAttributes.set( geometry, attribute ); 16304 16305 } 16306 16307 function getWireframeAttribute( geometry ) { 16308 16309 var currentAttribute = wireframeAttributes.get( geometry ); 16310 16311 if ( currentAttribute ) { 16312 16313 var geometryIndex = geometry.index; 16314 16315 if ( geometryIndex !== null ) { 16316 16317 // if the attribute is obsolete, create a new one 16318 16319 if ( currentAttribute.version < geometryIndex.version ) { 16320 16321 updateWireframeAttribute( geometry ); 16322 16323 } 16324 16325 } 16326 16327 } else { 16328 16329 updateWireframeAttribute( geometry ); 16330 16331 } 16332 16333 return wireframeAttributes.get( geometry ); 16334 16335 } 16336 16337 return { 16338 16339 get: get, 16340 update: update, 16341 16342 getWireframeAttribute: getWireframeAttribute 16343 16344 }; 16345 16346} 16347 16348/** 16349 * @author mrdoob / http://mrdoob.com/ 16350 */ 16351 16352function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) { 16353 16354 var isWebGL2 = capabilities.isWebGL2; 16355 16356 var mode; 16357 16358 function setMode( value ) { 16359 16360 mode = value; 16361 16362 } 16363 16364 var type, bytesPerElement; 16365 16366 function setIndex( value ) { 16367 16368 type = value.type; 16369 bytesPerElement = value.bytesPerElement; 16370 16371 } 16372 16373 function render( start, count ) { 16374 16375 gl.drawElements( mode, count, type, start * bytesPerElement ); 16376 16377 info.update( count, mode ); 16378 16379 } 16380 16381 function renderInstances( geometry, start, count, primcount ) { 16382 16383 if ( primcount === 0 ) return; 16384 16385 var extension, methodName; 16386 16387 if ( isWebGL2 ) { 16388 16389 extension = gl; 16390 methodName = 'drawElementsInstanced'; 16391 16392 } else { 16393
16394 extension = extensions.get( 'ANGLE_instanced_arrays' ); 16395 methodName = 'drawElementsInstancedANGLE'; 16396 16397 if ( extension === null ) { 16398 16399 console.error( 'THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); 16400 return; 16401 16402 } 16403 16404 } 16405 16406 extension[ methodName ]( mode, count, type, start * bytesPerElement, primcount ); 16407 16408 info.update( count, mode, primcount ); 16409 16410 } 16411 16412 // 16413 16414 this.setMode = setMode; 16415 this.setIndex = setIndex; 16416 this.render = render; 16417 this.renderInstances = renderInstances; 16418 16419} 16420 16421/** 16422 * @author Mugen87 / https://github.com/Mugen87 16423 */ 16424 16425function WebGLInfo( gl ) { 16426 16427 var memory = { 16428 geometries: 0, 16429 textures: 0 16430 }; 16431 16432 var render = { 16433 frame: 0, 16434 calls: 0, 16435 triangles: 0, 16436 points: 0, 16437 lines: 0 16438 }; 16439 16440 function update( count, mode, instanceCount ) { 16441 16442 instanceCount = instanceCount || 1; 16443 16444 render.calls ++; 16445 16446 switch ( mode ) { 16447 16448 case 4: 16449 render.triangles += instanceCount * ( count / 3 ); 16450 break; 16451 16452 case 1: 16453 render.lines += instanceCount * ( count / 2 ); 16454 break; 16455 16456 case 3: 16457 render.lines += instanceCount * ( count - 1 ); 16458 break; 16459 16460 case 2: 16461 render.lines += instanceCount * count; 16462 break; 16463 16464 case 0: 16465 render.points += instanceCount * count; 16466 break; 16467 16468 default: 16469 console.error( 'THREE.WebGLInfo: Unknown draw mode:', mode ); 16470 break; 16471 16472 } 16473 16474 } 16475 16476 function reset() { 16477 16478 render.frame ++; 16479 render.calls = 0; 16480 render.triangles = 0; 16481 render.points = 0; 16482 render.lines = 0; 16483 16484 } 16485 16486 return { 16487 memory: memory, 16488 render: render, 16489 programs: null, 16490 autoReset: true, 16491 reset: reset, 16492 update: update 16493 }; 16494 16495} 16496 16497/** 16498 * @author mrdoob / http://mrdoob.com/ 16499 */ 16500 16501function absNumericalSort( a, b ) { 16502 16503 return Math.abs( b[ 1 ] ) - Math.abs( a[ 1 ] ); 16504 16505} 16506 16507function WebGLMorphtargets( gl ) { 16508 16509 var influencesList = {}; 16510 var morphInfluences = new Float32Array( 8 ); 16511 16512 function update( object, geometry, material, program ) { 16513 16514 var objectInfluences = object.morphTargetInfluences; 16515 16516 // When object doesn't have morph target influences defined, we treat it as a 0-length array 16517 // This is important to make sure we set up morphTargetBaseInfluence / morphTargetInfluences 16518 16519 var length = objectInfluences === undefined ? 0 : objectInfluences.length; 16520 16521 var influences = influencesList[ geometry.id ]; 16522 16523 if ( influences === undefined ) { 16524 16525 // initialise list 16526 16527 influences = []; 16528 16529 for ( var i = 0; i < length; i ++ ) { 16530 16531 influences[ i ] = [ i, 0 ]; 16532 16533 } 16534 16535 influencesList[ geometry.id ] = influences; 16536 16537 } 16538 16539 var morphTargets = material.morphTargets && geometry.morphAttributes.position; 16540 var morphNormals = material.morphNormals && geometry.morphAttributes.normal; 16541 16542 // Remove current morphAttributes 16543 16544 for ( var i = 0; i < length; i ++ ) { 16545 16546 var influence = influences[ i ]; 16547 16548 if ( influence[ 1 ] !== 0 ) { 16549 16550 if ( morphTargets ) geometry.deleteAttribute( 'morphTarget' + i ); 16551 if ( morphNormals ) geometry.deleteAttribute( 'morphNormal' + i ); 16552 16553 } 16554 16555 } 16556 16557 // Collect influences 16558 16559 for ( var i = 0; i < length; i ++ ) { 16560 16561 var influence = influences[ i ]; 16562 16563 influence[ 0 ] = i; 16564 influence[ 1 ] = objectInfluences[ i ]; 16565 16566 } 16567 16568 influences.sort( absNumericalSort ); 16569 16570 // Add morphAttributes 16571 16572 var morphInfluencesSum = 0; 16573 16574 for ( var i = 0; i < 8; i ++ ) { 16575 16576 var influence = influences[ i ]; 16577 16578 if ( influence ) { 16579 16580 var index = influence[ 0 ]; 16581 var value = influence[ 1 ]; 16582 16583 if ( value ) { 16584 16585 if ( morphTargets ) geometry.setAttribute( 'morphTarget' + i, morphTargets[ index ] ); 16586 if ( morphNormals ) geometry.setAttribute( 'morphNormal' + i, morphNormals[ index ] ); 16587 16588 morphInfluences[ i ] = value; 16589 morphInfluencesSum += value; 16590 continue; 16591 16592 } 16593 16594 } 16595 16596 morphInfluences[ i ] = 0; 16597 16598 } 16599 16600 // GLSL shader uses formula baseinfluence * base + sum(target * influence) 16601 // This allows us to switch between absolute morphs and relative morphs without changing shader code 16602 // When baseinfluence = 1 - sum(influence), the above is equivalent to sum((target - base) * influence) 16603 var morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; 16604 16605 program.getUniforms().setValue( gl, 'morphTargetBaseInfluence', morphBaseInfluence ); 16606 program.getUniforms().setValue( gl, 'morphTargetInfluences', morphInfluences ); 16607 16608 } 16609 16610 return { 16611 16612 update: update 16613 16614 }; 16615 16616} 16617 16618/** 16619 * @author mrdoob / http://mrdoob.com/ 16620 */ 16621 16622function WebGLObjects( gl, geometries, attributes, info ) { 16623 16624 var updateMap = new WeakMap(); 16625 16626 function update( object ) { 16627 16628 var frame = info.render.frame; 16629 16630 var geometry = object.geometry; 16631 var buffergeometry = geometries.get( object, geometry ); 16632 16633 // Update once per frame 16634 16635 if ( updateMap.get( buffergeometry ) !== frame ) { 16636 16637 if ( geometry.isGeometry ) { 16638 16639 buffergeometry.updateFromObject( object ); 16640 16641 } 16642 16643 geometries.update( buffergeometry ); 16644 16645 updateMap.set( buffergeometry, frame ); 16646 16647 } 16648 16649 if ( object.isInstancedMesh ) { 16650 16651 attributes.update( object.instanceMatrix, 34962 ); 16652 16653 } 16654 16655 return buffergeometry; 16656 16657 } 16658 16659 function dispose() { 16660 16661 updateMap = new WeakMap(); 16662 16663 } 16664 16665 return { 16666 16667 update: update,
vendor: 33,199 bytes, lines 16668-18252
16668 dispose: dispose 16669 16670 }; 16671 16672} 16673 16674/** 16675 * @author mrdoob / http://mrdoob.com/ 16676 */ 16677 16678function CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { 16679 16680 images = images !== undefined ? images : []; 16681 mapping = mapping !== undefined ? mapping : CubeReflectionMapping; 16682 format = format !== undefined ? format : RGBFormat; 16683 16684 Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); 16685 16686 this.flipY = false; 16687 16688} 16689 16690CubeTexture.prototype = Object.create( Texture.prototype ); 16691CubeTexture.prototype.constructor = CubeTexture; 16692 16693CubeTexture.prototype.isCubeTexture = true; 16694 16695Object.defineProperty( CubeTexture.prototype, 'images', { 16696 16697 get: function () { 16698 16699 return this.image; 16700 16701 }, 16702 16703 set: function ( value ) { 16704 16705 this.image = value; 16706 16707 } 16708 16709} ); 16710 16711/** 16712 * @author Takahiro https://github.com/takahirox 16713 */ 16714 16715function DataTexture2DArray( data, width, height, depth ) { 16716 16717 Texture.call( this, null ); 16718 16719 this.image = { data: data || null, width: width || 1, height: height || 1, depth: depth || 1 }; 16720 16721 this.magFilter = NearestFilter; 16722 this.minFilter = NearestFilter; 16723 16724 this.wrapR = ClampToEdgeWrapping; 16725 16726 this.generateMipmaps = false; 16727 this.flipY = false; 16728 16729 this.needsUpdate = true; 16730 16731} 16732 16733DataTexture2DArray.prototype = Object.create( Texture.prototype ); 16734DataTexture2DArray.prototype.constructor = DataTexture2DArray; 16735DataTexture2DArray.prototype.isDataTexture2DArray = true; 16736 16737/** 16738 * @author Artur Trzesiok 16739 */ 16740 16741function DataTexture3D( data, width, height, depth ) { 16742 16743 // We're going to add .setXXX() methods for setting properties later. 16744 // Users can still set in DataTexture3D directly. 16745 // 16746 // var texture = new THREE.DataTexture3D( data, width, height, depth ); 16747 // texture.anisotropy = 16; 16748 // 16749 // See #14839 16750 16751 Texture.call( this, null ); 16752 16753 this.image = { data: data || null, width: width || 1, height: height || 1, depth: depth || 1 }; 16754 16755 this.magFilter = NearestFilter; 16756 this.minFilter = NearestFilter; 16757 16758 this.wrapR = ClampToEdgeWrapping; 16759 16760 this.generateMipmaps = false; 16761 this.flipY = false; 16762 16763 this.needsUpdate = true; 16764 16765 16766} 16767 16768DataTexture3D.prototype = Object.create( Texture.prototype ); 16769DataTexture3D.prototype.constructor = DataTexture3D; 16770DataTexture3D.prototype.isDataTexture3D = true; 16771 16772/** 16773 * @author tschw 16774 * @author Mugen87 / https://github.com/Mugen87 16775 * @author mrdoob / http://mrdoob.com/ 16776 * 16777 * Uniforms of a program. 16778 * Those form a tree structure with a special top-level container for the root, 16779 * which you get by calling 'new WebGLUniforms( gl, program )'. 16780 * 16781 * 16782 * Properties of inner nodes including the top-level container: 16783 * 16784 * .seq - array of nested uniforms 16785 * .map - nested uniforms by name 16786 * 16787 * 16788 * Methods of all nodes except the top-level container: 16789 * 16790 * .setValue( gl, value, [textures] ) 16791 * 16792 * uploads a uniform value(s) 16793 * the 'textures' parameter is needed for sampler uniforms 16794 * 16795 * 16796 * Static methods of the top-level container (textures factorizations): 16797 * 16798 * .upload( gl, seq, values, textures ) 16799 * 16800 * sets uniforms in 'seq' to 'values[id].value' 16801 * 16802 * .seqWithValue( seq, values ) : filteredSeq 16803 * 16804 * filters 'seq' entries with corresponding entry in values 16805 * 16806 * 16807 * Methods of the top-level container (textures factorizations): 16808 * 16809 * .setValue( gl, name, value, textures ) 16810 * 16811 * sets uniform with name 'name' to 'value' 16812 * 16813 * .setOptional( gl, obj, prop ) 16814 * 16815 * like .set for an optional property of the object 16816 * 16817 */ 16818 16819var emptyTexture = new Texture(); 16820var emptyTexture2dArray = new DataTexture2DArray(); 16821var emptyTexture3d = new DataTexture3D(); 16822var emptyCubeTexture = new CubeTexture(); 16823 16824// --- Utilities --- 16825 16826// Array Caches (provide typed arrays for temporary by size) 16827 16828var arrayCacheF32 = []; 16829var arrayCacheI32 = []; 16830 16831// Float32Array caches used for uploading Matrix uniforms 16832 16833var mat4array = new Float32Array( 16 ); 16834var mat3array = new Float32Array( 9 ); 16835var mat2array = new Float32Array( 4 ); 16836 16837// Flattening for arrays of vectors and matrices 16838 16839function flatten( array, nBlocks, blockSize ) { 16840 16841 var firstElem = array[ 0 ]; 16842 16843 if ( firstElem <= 0 || firstElem > 0 ) return array; 16844 // unoptimized: ! isNaN( firstElem ) 16845 // see http://jacksondunstan.com/articles/983 16846 16847 var n = nBlocks * blockSize, 16848 r = arrayCacheF32[ n ]; 16849 16850 if ( r === undefined ) { 16851 16852 r = new Float32Array( n ); 16853 arrayCacheF32[ n ] = r; 16854 16855 } 16856 16857 if ( nBlocks !== 0 ) { 16858 16859 firstElem.toArray( r, 0 ); 16860 16861 for ( var i = 1, offset = 0; i !== nBlocks; ++ i ) { 16862 16863 offset += blockSize; 16864 array[ i ].toArray( r, offset ); 16865 16866 } 16867 16868 } 16869 16870 return r; 16871 16872} 16873 16874function arraysEqual( a, b ) { 16875 16876 if ( a.length !== b.length ) return false; 16877 16878 for ( var i = 0, l = a.length; i < l; i ++ ) { 16879 16880 if ( a[ i ] !== b[ i ] ) return false; 16881 16882 } 16883 16884 return true; 16885 16886} 16887 16888function copyArray( a, b ) { 16889 16890 for ( var i = 0, l = b.length; i < l; i ++ ) { 16891 16892 a[ i ] = b[ i ]; 16893 16894 } 16895 16896} 16897 16898// Texture unit allocation 16899 16900function allocTexUnits( textures, n ) { 16901 16902 var r = arrayCacheI32[ n ]; 16903 16904 if ( r === undefined ) { 16905 16906 r = new Int32Array( n ); 16907 arrayCacheI32[ n ] = r; 16908 16909 } 16910 16911 for ( var i = 0; i !== n; ++ i ) 16912 r[ i ] = textures.allocateTextureUnit(); 16913 16914 return r; 16915 16916} 16917 16918// --- Setters --- 16919 16920// Note: Defining these methods externally, because they come in a bunch 16921// and this way their names minify. 16922 16923// Single scalar 16924 16925function setValueV1f( gl, v ) { 16926 16927 var cache = this.cache; 16928 16929 if ( cache[ 0 ] === v ) return; 16930 16931 gl.uniform1f( this.addr, v ); 16932 16933 cache[ 0 ] = v; 16934 16935} 16936 16937// Single float vector (from flat array or THREE.VectorN) 16938 16939function setValueV2f( gl, v ) { 16940 16941 var cache = this.cache; 16942 16943 if ( v.x !== undefined ) { 16944 16945 if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) { 16946 16947 gl.uniform2f( this.addr, v.x, v.y ); 16948 16949 cache[ 0 ] = v.x; 16950 cache[ 1 ] = v.y; 16951 16952 } 16953 16954 } else { 16955 16956 if ( arraysEqual( cache, v ) ) return; 16957 16958 gl.uniform2fv( this.addr, v ); 16959 16960 copyArray( cache, v ); 16961 16962 } 16963 16964} 16965 16966function setValueV3f( gl, v ) { 16967 16968 var cache = this.cache; 16969 16970 if ( v.x !== undefined ) { 16971 16972 if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) { 16973 16974 gl.uniform3f( this.addr, v.x, v.y, v.z ); 16975 16976 cache[ 0 ] = v.x; 16977 cache[ 1 ] = v.y; 16978 cache[ 2 ] = v.z; 16979 16980 } 16981 16982 } else if ( v.r !== undefined ) { 16983 16984 if ( cache[ 0 ] !== v.r || cache[ 1 ] !== v.g || cache[ 2 ] !== v.b ) { 16985 16986 gl.uniform3f( this.addr, v.r, v.g, v.b ); 16987 16988 cache[ 0 ] = v.r; 16989 cache[ 1 ] = v.g; 16990 cache[ 2 ] = v.b; 16991 16992 } 16993 16994 } else { 16995 16996 if ( arraysEqual( cache, v ) ) return; 16997 16998 gl.uniform3fv( this.addr, v ); 16999 17000 copyArray( cache, v ); 17001 17002 } 17003 17004} 17005 17006function setValueV4f( gl, v ) { 17007 17008 var cache = this.cache; 17009 17010 if ( v.x !== undefined ) { 17011 17012 if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) { 17013 17014 gl.uniform4f( this.addr, v.x, v.y, v.z, v.w ); 17015 17016 cache[ 0 ] = v.x; 17017 cache[ 1 ] = v.y; 17018 cache[ 2 ] = v.z; 17019 cache[ 3 ] = v.w; 17020 17021 } 17022 17023 } else { 17024 17025 if ( arraysEqual( cache, v ) ) return; 17026 17027 gl.uniform4fv( this.addr, v ); 17028 17029 copyArray( cache, v ); 17030 17031 } 17032 17033} 17034 17035// Single matrix (from flat array or MatrixN) 17036 17037function setValueM2( gl, v ) { 17038 17039 var cache = this.cache; 17040 var elements = v.elements; 17041 17042 if ( elements === undefined ) { 17043 17044 if ( arraysEqual( cache, v ) ) return; 17045 17046 gl.uniformMatrix2fv( this.addr, false, v ); 17047 17048 copyArray( cache, v ); 17049 17050 } else { 17051 17052 if ( arraysEqual( cache, elements ) ) return; 17053 17054 mat2array.set( elements ); 17055 17056 gl.uniformMatrix2fv( this.addr, false, mat2array ); 17057 17058 copyArray( cache, elements ); 17059 17060 } 17061 17062} 17063 17064function setValueM3( gl, v ) { 17065 17066 var cache = this.cache; 17067 var elements = v.elements; 17068 17069 if ( elements === undefined ) { 17070 17071 if ( arraysEqual( cache, v ) ) return; 17072 17073 gl.uniformMatrix3fv( this.addr, false, v ); 17074 17075 copyArray( cache, v ); 17076 17077 } else { 17078 17079 if ( arraysEqual( cache, elements ) ) return; 17080 17081 mat3array.set( elements ); 17082 17083 gl.uniformMatrix3fv( this.addr, false, mat3array ); 17084 17085 copyArray( cache, elements ); 17086 17087 } 17088 17089} 17090 17091function setValueM4( gl, v ) { 17092 17093 var cache = this.cache; 17094 var elements = v.elements; 17095 17096 if ( elements === undefined ) { 17097 17098 if ( arraysEqual( cache, v ) ) return; 17099 17100 gl.uniformMatrix4fv( this.addr, false, v ); 17101 17102 copyArray( cache, v ); 17103 17104 } else { 17105 17106 if ( arraysEqual( cache, elements ) ) return; 17107 17108 mat4array.set( elements ); 17109 17110 gl.uniformMatrix4fv( this.addr, false, mat4array ); 17111 17112 copyArray( cache, elements ); 17113 17114 } 17115 17116} 17117 17118// Single texture (2D / Cube) 17119 17120function setValueT1( gl, v, textures ) { 17121 17122 var cache = this.cache; 17123 var unit = textures.allocateTextureUnit(); 17124 17125 if ( cache[ 0 ] !== unit ) { 17126 17127 gl.uniform1i( this.addr, unit ); 17128 cache[ 0 ] = unit; 17129 17130 } 17131 17132 textures.safeSetTexture2D( v || emptyTexture, unit ); 17133 17134} 17135 17136function setValueT2DArray1( gl, v, textures ) { 17137 17138 var cache = this.cache; 17139 var unit = textures.allocateTextureUnit(); 17140 17141 if ( cache[ 0 ] !== unit ) { 17142 17143 gl.uniform1i( this.addr, unit ); 17144 cache[ 0 ] = unit; 17145 17146 } 17147 17148 textures.setTexture2DArray( v || emptyTexture2dArray, unit ); 17149 17150} 17151 17152function setValueT3D1( gl, v, textures ) { 17153 17154 var cache = this.cache; 17155 var unit = textures.allocateTextureUnit(); 17156 17157 if ( cache[ 0 ] !== unit ) { 17158 17159 gl.uniform1i( this.addr, unit ); 17160 cache[ 0 ] = unit; 17161 17162 } 17163 17164 textures.setTexture3D( v || emptyTexture3d, unit ); 17165 17166} 17167 17168function setValueT6( gl, v, textures ) { 17169 17170 var cache = this.cache; 17171 var unit = textures.allocateTextureUnit(); 17172 17173 if ( cache[ 0 ] !== unit ) { 17174 17175 gl.uniform1i( this.addr, unit ); 17176 cache[ 0 ] = unit; 17177 17178 } 17179 17180 textures.safeSetTextureCube( v || emptyCubeTexture, unit ); 17181 17182} 17183 17184// Integer / Boolean vectors or arrays thereof (always flat arrays) 17185 17186function setValueV1i( gl, v ) { 17187 17188 var cache = this.cache; 17189 17190 if ( cache[ 0 ] === v ) return; 17191 17192 gl.uniform1i( this.addr, v ); 17193 17194 cache[ 0 ] = v; 17195 17196} 17197 17198function setValueV2i( gl, v ) { 17199 17200 var cache = this.cache; 17201 17202 if ( arraysEqual( cache, v ) ) return; 17203 17204 gl.uniform2iv( this.addr, v ); 17205 17206 copyArray( cache, v ); 17207 17208} 17209 17210function setValueV3i( gl, v ) { 17211 17212 var cache = this.cache; 17213 17214 if ( arraysEqual( cache, v ) ) return; 17215 17216 gl.uniform3iv( this.addr, v ); 17217 17218 copyArray( cache, v ); 17219 17220} 17221 17222function setValueV4i( gl, v ) { 17223 17224 var cache = this.cache; 17225 17226 if ( arraysEqual( cache, v ) ) return; 17227 17228 gl.uniform4iv( this.addr, v ); 17229 17230 copyArray( cache, v ); 17231 17232} 17233 17234// uint 17235 17236function setValueV1ui( gl, v ) { 17237 17238 var cache = this.cache; 17239 17240 if ( cache[ 0 ] === v ) return; 17241 17242 gl.uniform1ui( this.addr, v ); 17243 17244 cache[ 0 ] = v; 17245 17246} 17247 17248// Helper to pick the right setter for the singular case 17249 17250function getSingularSetter( type ) { 17251 17252 switch ( type ) { 17253 17254 case 0x1406: return setValueV1f; // FLOAT 17255 case 0x8b50: return setValueV2f; // _VEC2 17256 case 0x8b51: return setValueV3f; // _VEC3 17257 case 0x8b52: return setValueV4f; // _VEC4 17258 17259 case 0x8b5a: return setValueM2; // _MAT2 17260 case 0x8b5b: return setValueM3; // _MAT3 17261 case 0x8b5c: return setValueM4; // _MAT4 17262 17263 case 0x1404: case 0x8b56: return setValueV1i; // INT, BOOL 17264 case 0x8b53: case 0x8b57: return setValueV2i; // _VEC2 17265 case 0x8b54: case 0x8b58: return setValueV3i; // _VEC3 17266 case 0x8b55: case 0x8b59: return setValueV4i; // _VEC4 17267 17268 case 0x1405: return setValueV1ui; // UINT 17269 17270 case 0x8b5e: // SAMPLER_2D 17271 case 0x8d66: // SAMPLER_EXTERNAL_OES 17272 case 0x8dca: // INT_SAMPLER_2D 17273 case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D 17274 case 0x8b62: // SAMPLER_2D_SHADOW 17275 return setValueT1; 17276 17277 case 0x8b5f: // SAMPLER_3D 17278 case 0x8dcb: // INT_SAMPLER_3D 17279 case 0x8dd3: // UNSIGNED_INT_SAMPLER_3D 17280 return setValueT3D1; 17281 17282 case 0x8b60: // SAMPLER_CUBE 17283 case 0x8dcc: // INT_SAMPLER_CUBE 17284 case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE 17285 case 0x8dc5: // SAMPLER_CUBE_SHADOW 17286 return setValueT6; 17287 17288 case 0x8dc1: // SAMPLER_2D_ARRAY 17289 case 0x8dcf: // INT_SAMPLER_2D_ARRAY 17290 case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY 17291 case 0x8dc4: // SAMPLER_2D_ARRAY_SHADOW 17292 return setValueT2DArray1; 17293 17294 } 17295 17296} 17297 17298// Array of scalars 17299function setValueV1fArray( gl, v ) { 17300 17301 gl.uniform1fv( this.addr, v ); 17302 17303} 17304 17305// Integer / Boolean vectors or arrays thereof (always flat arrays) 17306function setValueV1iArray( gl, v ) { 17307 17308 gl.uniform1iv( this.addr, v ); 17309 17310} 17311 17312function setValueV2iArray( gl, v ) { 17313 17314 gl.uniform2iv( this.addr, v ); 17315 17316} 17317 17318function setValueV3iArray( gl, v ) { 17319 17320 gl.uniform3iv( this.addr, v ); 17321 17322} 17323 17324function setValueV4iArray( gl, v ) { 17325 17326 gl.uniform4iv( this.addr, v ); 17327 17328} 17329 17330 17331// Array of vectors (flat or from THREE classes) 17332 17333function setValueV2fArray( gl, v ) { 17334 17335 var data = flatten( v, this.size, 2 ); 17336 17337 gl.uniform2fv( this.addr, data ); 17338 17339} 17340 17341function setValueV3fArray( gl, v ) { 17342 17343 var data = flatten( v, this.size, 3 ); 17344 17345 gl.uniform3fv( this.addr, data ); 17346 17347} 17348 17349function setValueV4fArray( gl, v ) { 17350 17351 var data = flatten( v, this.size, 4 ); 17352 17353 gl.uniform4fv( this.addr, data ); 17354 17355} 17356 17357// Array of matrices (flat or from THREE clases) 17358 17359function setValueM2Array( gl, v ) { 17360 17361 var data = flatten( v, this.size, 4 ); 17362 17363 gl.uniformMatrix2fv( this.addr, false, data ); 17364 17365} 17366 17367function setValueM3Array( gl, v ) { 17368 17369 var data = flatten( v, this.size, 9 ); 17370 17371 gl.uniformMatrix3fv( this.addr, false, data ); 17372 17373} 17374 17375function setValueM4Array( gl, v ) { 17376 17377 var data = flatten( v, this.size, 16 ); 17378 17379 gl.uniformMatrix4fv( this.addr, false, data ); 17380 17381} 17382 17383// Array of textures (2D / Cube) 17384 17385function setValueT1Array( gl, v, textures ) { 17386 17387 var n = v.length; 17388 17389 var units = allocTexUnits( textures, n ); 17390 17391 gl.uniform1iv( this.addr, units ); 17392 17393 for ( var i = 0; i !== n; ++ i ) { 17394 17395 textures.safeSetTexture2D( v[ i ] || emptyTexture, units[ i ] ); 17396 17397 } 17398 17399} 17400 17401function setValueT6Array( gl, v, textures ) { 17402 17403 var n = v.length; 17404 17405 var units = allocTexUnits( textures, n ); 17406 17407 gl.uniform1iv( this.addr, units ); 17408 17409 for ( var i = 0; i !== n; ++ i ) { 17410 17411 textures.safeSetTextureCube( v[ i ] || emptyCubeTexture, units[ i ] ); 17412 17413 } 17414 17415} 17416 17417// Helper to pick the right setter for a pure (bottom-level) array 17418 17419function getPureArraySetter( type ) { 17420 17421 switch ( type ) { 17422 17423 case 0x1406: return setValueV1fArray; // FLOAT 17424 case 0x8b50: return setValueV2fArray; // _VEC2 17425 case 0x8b51: return setValueV3fArray; // _VEC3 17426 case 0x8b52: return setValueV4fArray; // _VEC4 17427 17428 case 0x8b5a: return setValueM2Array; // _MAT2 17429 case 0x8b5b: return setValueM3Array; // _MAT3 17430 case 0x8b5c: return setValueM4Array; // _MAT4 17431 17432 case 0x1404: case 0x8b56: return setValueV1iArray; // INT, BOOL 17433 case 0x8b53: case 0x8b57: return setValueV2iArray; // _VEC2 17434 case 0x8b54: case 0x8b58: return setValueV3iArray; // _VEC3 17435 case 0x8b55: case 0x8b59: return setValueV4iArray; // _VEC4 17436 17437 case 0x8b5e: // SAMPLER_2D 17438 case 0x8d66: // SAMPLER_EXTERNAL_OES 17439 case 0x8dca: // INT_SAMPLER_2D 17440 case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D 17441 case 0x8b62: // SAMPLER_2D_SHADOW 17442 return setValueT1Array; 17443 17444 case 0x8b60: // SAMPLER_CUBE 17445 case 0x8dcc: // INT_SAMPLER_CUBE 17446 case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE 17447 case 0x8dc5: // SAMPLER_CUBE_SHADOW 17448 return setValueT6Array; 17449 17450 } 17451 17452} 17453 17454// --- Uniform Classes --- 17455 17456function SingleUniform( id, activeInfo, addr ) { 17457 17458 this.id = id; 17459 this.addr = addr; 17460 this.cache = []; 17461 this.setValue = getSingularSetter( activeInfo.type ); 17462 17463 // this.path = activeInfo.name; // DEBUG 17464 17465} 17466 17467function PureArrayUniform( id, activeInfo, addr ) { 17468 17469 this.id = id; 17470 this.addr = addr; 17471 this.cache = []; 17472 this.size = activeInfo.size; 17473 this.setValue = getPureArraySetter( activeInfo.type ); 17474 17475 // this.path = activeInfo.name; // DEBUG 17476 17477} 17478 17479PureArrayUniform.prototype.updateCache = function ( data ) { 17480 17481 var cache = this.cache; 17482 17483 if ( data instanceof Float32Array && cache.length !== data.length ) { 17484 17485 this.cache = new Float32Array( data.length ); 17486 17487 } 17488 17489 copyArray( cache, data ); 17490 17491}; 17492 17493function StructuredUniform( id ) { 17494 17495 this.id = id; 17496 17497 this.seq = []; 17498 this.map = {}; 17499 17500} 17501 17502StructuredUniform.prototype.setValue = function ( gl, value, textures ) { 17503 17504 var seq = this.seq; 17505 17506 for ( var i = 0, n = seq.length; i !== n; ++ i ) { 17507 17508 var u = seq[ i ]; 17509 u.setValue( gl, value[ u.id ], textures ); 17510 17511 } 17512 17513}; 17514 17515// --- Top-level --- 17516 17517// Parser - builds up the property tree from the path strings 17518 17519var RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g; 17520 17521// extracts 17522// - the identifier (member name or array index) 17523// - followed by an optional right bracket (found when array index) 17524// - followed by an optional left bracket or dot (type of subscript) 17525// 17526// Note: These portions can be read in a non-overlapping fashion and 17527// allow straightforward parsing of the hierarchy that WebGL encodes 17528// in the uniform names. 17529 17530function addUniform( container, uniformObject ) { 17531 17532 container.seq.push( uniformObject ); 17533 container.map[ uniformObject.id ] = uniformObject; 17534 17535} 17536 17537function parseUniform( activeInfo, addr, container ) { 17538 17539 var path = activeInfo.name, 17540 pathLength = path.length; 17541 17542 // reset RegExp object, because of the early exit of a previous run 17543 RePathPart.lastIndex = 0; 17544 17545 while ( true ) { 17546 17547 var match = RePathPart.exec( path ), 17548 matchEnd = RePathPart.lastIndex, 17549 17550 id = match[ 1 ], 17551 idIsIndex = match[ 2 ] === ']', 17552 subscript = match[ 3 ]; 17553 17554 if ( idIsIndex ) id = id | 0; // convert to integer 17555 17556 if ( subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength ) { 17557 17558 // bare name or "pure" bottom-level array "[0]" suffix 17559 17560 addUniform( container, subscript === undefined ? 17561 new SingleUniform( id, activeInfo, addr ) : 17562 new PureArrayUniform( id, activeInfo, addr ) ); 17563 17564 break; 17565 17566 } else { 17567 17568 // step into inner node / create it in case it doesn't exist 17569 17570 var map = container.map, next = map[ id ]; 17571 17572 if ( next === undefined ) { 17573 17574 next = new StructuredUniform( id ); 17575 addUniform( container, next ); 17576 17577 } 17578 17579 container = next; 17580 17581 } 17582 17583 } 17584 17585} 17586 17587// Root Container 17588 17589function WebGLUniforms( gl, program ) { 17590 17591 this.seq = []; 17592 this.map = {}; 17593 17594 var n = gl.getProgramParameter( program, 35718 ); 17595 17596 for ( var i = 0; i < n; ++ i ) { 17597 17598 var info = gl.getActiveUniform( program, i ), 17599 addr = gl.getUniformLocation( program, info.name ); 17600 17601 parseUniform( info, addr, this ); 17602 17603 } 17604 17605} 17606 17607WebGLUniforms.prototype.setValue = function ( gl, name, value, textures ) { 17608 17609 var u = this.map[ name ]; 17610 17611 if ( u !== undefined ) u.setValue( gl, value, textures ); 17612 17613}; 17614 17615WebGLUniforms.prototype.setOptional = function ( gl, object, name ) { 17616 17617 var v = object[ name ]; 17618 17619 if ( v !== undefined ) this.setValue( gl, name, v ); 17620 17621}; 17622 17623 17624// Static interface 17625 17626WebGLUniforms.upload = function ( gl, seq, values, textures ) { 17627 17628 for ( var i = 0, n = seq.length; i !== n; ++ i ) { 17629 17630 var u = seq[ i ], 17631 v = values[ u.id ]; 17632 17633 if ( v.needsUpdate !== false ) { 17634 17635 // note: always updating when .needsUpdate is undefined 17636 u.setValue( gl, v.value, textures ); 17637 17638 } 17639 17640 } 17641 17642}; 17643 17644WebGLUniforms.seqWithValue = function ( seq, values ) { 17645 17646 var r = []; 17647 17648 for ( var i = 0, n = seq.length; i !== n; ++ i ) { 17649 17650 var u = seq[ i ]; 17651 if ( u.id in values ) r.push( u ); 17652 17653 } 17654 17655 return r; 17656 17657}; 17658 17659/** 17660 * @author mrdoob / http://mrdoob.com/ 17661 */ 17662 17663function WebGLShader( gl, type, string ) { 17664 17665 var shader = gl.createShader( type ); 17666 17667 gl.shaderSource( shader, string ); 17668 gl.compileShader( shader ); 17669 17670 return shader; 17671 17672} 17673 17674/** 17675 * @author mrdoob / http://mrdoob.com/ 17676 */ 17677 17678var programIdCount = 0; 17679 17680function addLineNumbers( string ) { 17681 17682 var lines = string.split( '\n' ); 17683 17684 for ( var i = 0; i < lines.length; i ++ ) { 17685 17686 lines[ i ] = ( i + 1 ) + ': ' + lines[ i ]; 17687 17688 } 17689 17690 return lines.join( '\n' ); 17691 17692} 17693 17694function getEncodingComponents( encoding ) { 17695 17696 switch ( encoding ) { 17697 17698 case LinearEncoding: 17699 return [ 'Linear', '( value )' ]; 17700 case sRGBEncoding: 17701 return [ 'sRGB', '( value )' ]; 17702 case RGBEEncoding: 17703 return [ 'RGBE', '( value )' ]; 17704 case RGBM7Encoding: 17705 return [ 'RGBM', '( value, 7.0 )' ]; 17706 case RGBM16Encoding: 17707 return [ 'RGBM', '( value, 16.0 )' ]; 17708 case RGBDEncoding: 17709 return [ 'RGBD', '( value, 256.0 )' ]; 17710 case GammaEncoding: 17711 return [ 'Gamma', '( value, float( GAMMA_FACTOR ) )' ]; 17712 case LogLuvEncoding: 17713 return [ 'LogLuv', '( value )' ]; 17714 default: 17715 throw new Error( 'unsupported encoding: ' + encoding ); 17716 17717 } 17718 17719} 17720 17721function getShaderErrors( gl, shader, type ) { 17722 17723 var status = gl.getShaderParameter( shader, 35713 ); 17724 var log = gl.getShaderInfoLog( shader ).trim(); 17725 17726 if ( status && log === '' ) return ''; 17727 17728 // --enable-privileged-webgl-extension 17729 // console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); 17730 17731 var source = gl.getShaderSource( shader ); 17732 17733 return 'THREE.WebGLShader: gl.getShaderInfoLog() ' + type + '\n' + log + addLineNumbers( source ); 17734 17735} 17736 17737function getTexelDecodingFunction( functionName, encoding ) { 17738 17739 var components = getEncodingComponents( encoding ); 17740 return 'vec4 ' + functionName + '( vec4 value ) { return ' + components[ 0 ] + 'ToLinear' + components[ 1 ] + '; }'; 17741 17742} 17743 17744function getTexelEncodingFunction( functionName, encoding ) { 17745 17746 var components = getEncodingComponents( encoding ); 17747 return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[ 0 ] + components[ 1 ] + '; }'; 17748 17749} 17750 17751function getToneMappingFunction( functionName, toneMapping ) { 17752 17753 var toneMappingName; 17754 17755 switch ( toneMapping ) { 17756 17757 case LinearToneMapping: 17758 toneMappingName = 'Linear'; 17759 break; 17760 17761 case ReinhardToneMapping: 17762 toneMappingName = 'Reinhard'; 17763 break; 17764 17765 case Uncharted2ToneMapping: 17766 toneMappingName = 'Uncharted2'; 17767 break; 17768 17769 case CineonToneMapping: 17770 toneMappingName = 'OptimizedCineon'; 17771 break; 17772 17773 case ACESFilmicToneMapping: 17774 toneMappingName = 'ACESFilmic'; 17775 break; 17776 17777 default: 17778 throw new Error( 'unsupported toneMapping: ' + toneMapping ); 17779 17780 } 17781 17782 return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }'; 17783 17784} 17785 17786function generateExtensions( parameters ) { 17787 17788 var chunks = [ 17789 ( parameters.extensionDerivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.tangentSpaceNormalMap || parameters.clearcoatNormalMap || parameters.flatShading || parameters.shaderID === 'physical' ) ? '#extension GL_OES_standard_derivatives : enable' : '', 17790 ( parameters.extensionFragDepth || parameters.logarithmicDepthBuffer ) && parameters.rendererExtensionFragDepth ? '#extension GL_EXT_frag_depth : enable' : '', 17791 ( parameters.extensionDrawBuffers && parameters.rendererExtensionDrawBuffers ) ? '#extension GL_EXT_draw_buffers : require' : '', 17792 ( parameters.extensionShaderTextureLOD || parameters.envMap ) && parameters.rendererExtensionShaderTextureLod ? '#extension GL_EXT_shader_texture_lod : enable' : '' 17793 ]; 17794 17795 return chunks.filter( filterEmptyLine ).join( '\n' ); 17796 17797} 17798 17799function generateDefines( defines ) { 17800 17801 var chunks = []; 17802 17803 for ( var name in defines ) { 17804 17805 var value = defines[ name ]; 17806 17807 if ( value === false ) continue; 17808 17809 chunks.push( '#define ' + name + ' ' + value ); 17810 17811 } 17812 17813 return chunks.join( '\n' ); 17814 17815} 17816 17817function fetchAttributeLocations( gl, program ) { 17818 17819 var attributes = {}; 17820 17821 var n = gl.getProgramParameter( program, 35721 ); 17822 17823 for ( var i = 0; i < n; i ++ ) { 17824 17825 var info = gl.getActiveAttrib( program, i ); 17826 var name = info.name; 17827 17828 // console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i ); 17829 17830 attributes[ name ] = gl.getAttribLocation( program, name ); 17831 17832 } 17833 17834 return attributes; 17835 17836} 17837 17838function filterEmptyLine( string ) { 17839 17840 return string !== ''; 17841 17842} 17843 17844function replaceLightNums( string, parameters ) { 17845 17846 return string 17847 .replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights ) 17848 .replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights ) 17849 .replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights ) 17850 .replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights ) 17851 .replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights ) 17852 .replace( /NUM_DIR_LIGHT_SHADOWS/g, parameters.numDirLightShadows ) 17853 .replace( /NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows ) 17854 .replace( /NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows ); 17855 17856} 17857 17858function replaceClippingPlaneNums( string, parameters ) { 17859 17860 return string 17861 .replace( /NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes ) 17862 .replace( /UNION_CLIPPING_PLANES/g, ( parameters.numClippingPlanes - parameters.numClipIntersection ) ); 17863 17864} 17865 17866// Resolve Includes 17867 17868var includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm; 17869 17870function resolveIncludes( string ) { 17871 17872 return string.replace( includePattern, includeReplacer ); 17873 17874} 17875 17876function includeReplacer( match, include ) { 17877 17878 var string = ShaderChunk[ include ]; 17879 17880 if ( string === undefined ) { 17881 17882 throw new Error( 'Can not resolve #include <' + include + '>' ); 17883 17884 } 17885 17886 return resolveIncludes( string ); 17887 17888} 17889 17890// Unroll Loops 17891 17892var deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; 17893var unrollLoopPattern = /#pragma unroll_loop_start[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}[\s]+?#pragma unroll_loop_end/g; 17894 17895function unrollLoops( string ) { 17896 17897 return string 17898 .replace( unrollLoopPattern, loopReplacer ) 17899 .replace( deprecatedUnrollLoopPattern, deprecatedLoopReplacer ); 17900 17901} 17902 17903function deprecatedLoopReplacer( match, start, end, snippet ) { 17904 17905 console.warn( 'WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead.' ); 17906 return loopReplacer( match, start, end, snippet ); 17907 17908} 17909 17910function loopReplacer( match, start, end, snippet ) { 17911 17912 var string = ''; 17913 17914 for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) { 17915 17916 string += snippet 17917 .replace( /\[ i \]/g, '[ ' + i + ' ]' ) 17918 .replace( /UNROLLED_LOOP_INDEX/g, i ); 17919 17920 } 17921 17922 return string; 17923 17924} 17925 17926// 17927 17928function generatePrecision( parameters ) { 17929 17930 var precisionstring = "precision " + parameters.precision + " float;\nprecision " + parameters.precision + " int;"; 17931 17932 if ( parameters.precision === "highp" ) { 17933 17934 precisionstring += "\n#define HIGH_PRECISION"; 17935 17936 } else if ( parameters.precision === "mediump" ) { 17937 17938 precisionstring += "\n#define MEDIUM_PRECISION"; 17939 17940 } else if ( parameters.precision === "lowp" ) { 17941 17942 precisionstring += "\n#define LOW_PRECISION"; 17943 17944 } 17945 17946 return precisionstring; 17947 17948} 17949 17950function generateShadowMapTypeDefine( parameters ) { 17951 17952 var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; 17953 17954 if ( parameters.shadowMapType === PCFShadowMap ) { 17955 17956 shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF'; 17957 17958 } else if ( parameters.shadowMapType === PCFSoftShadowMap ) { 17959 17960 shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT'; 17961 17962 } else if ( parameters.shadowMapType === VSMShadowMap ) { 17963 17964 shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM'; 17965 17966 } 17967 17968 return shadowMapTypeDefine; 17969 17970} 17971 17972function generateEnvMapTypeDefine( parameters ) { 17973 17974 var envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; 17975 17976 if ( parameters.envMap ) { 17977 17978 switch ( parameters.envMapMode ) { 17979 17980 case CubeReflectionMapping: 17981 case CubeRefractionMapping: 17982 envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; 17983 break; 17984 17985 case CubeUVReflectionMapping: 17986 case CubeUVRefractionMapping: 17987 envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV'; 17988 break; 17989 17990 case EquirectangularReflectionMapping: 17991 case EquirectangularRefractionMapping: 17992 envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC'; 17993 break; 17994 17995 case SphericalReflectionMapping: 17996 envMapTypeDefine = 'ENVMAP_TYPE_SPHERE'; 17997 break; 17998 17999 } 18000 18001 } 18002 18003 return envMapTypeDefine; 18004 18005} 18006 18007function generateEnvMapModeDefine( parameters ) { 18008 18009 var envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; 18010 18011 if ( parameters.envMap ) { 18012 18013 switch ( parameters.envMapMode ) { 18014 18015 case CubeRefractionMapping: 18016 case EquirectangularRefractionMapping: 18017 envMapModeDefine = 'ENVMAP_MODE_REFRACTION'; 18018 break; 18019 18020 } 18021 18022 } 18023 18024 return envMapModeDefine; 18025 18026} 18027 18028function generateEnvMapBlendingDefine( parameters ) { 18029 18030 var envMapBlendingDefine = 'ENVMAP_BLENDING_NONE'; 18031 18032 if ( parameters.envMap ) { 18033 18034 switch ( parameters.combine ) { 18035 18036 case MultiplyOperation: 18037 envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; 18038 break; 18039 18040 case MixOperation: 18041 envMapBlendingDefine = 'ENVMAP_BLENDING_MIX'; 18042 break; 18043 18044 case AddOperation: 18045 envMapBlendingDefine = 'ENVMAP_BLENDING_ADD'; 18046 break; 18047 18048 } 18049 18050 } 18051 18052 return envMapBlendingDefine; 18053 18054} 18055 18056function WebGLProgram( renderer, cacheKey, parameters ) { 18057 18058 var gl = renderer.getContext(); 18059 18060 var defines = parameters.defines; 18061 18062 var vertexShader = parameters.vertexShader; 18063 var fragmentShader = parameters.fragmentShader; 18064 var shadowMapTypeDefine = generateShadowMapTypeDefine( parameters ); 18065 var envMapTypeDefine = generateEnvMapTypeDefine( parameters ); 18066 var envMapModeDefine = generateEnvMapModeDefine( parameters ); 18067 var envMapBlendingDefine = generateEnvMapBlendingDefine( parameters ); 18068 18069 18070 var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0; 18071 18072 var customExtensions = parameters.isWebGL2 ? '' : generateExtensions( parameters ); 18073 18074 var customDefines = generateDefines( defines ); 18075 18076 var program = gl.createProgram(); 18077 18078 var prefixVertex, prefixFragment; 18079 18080 if ( parameters.isRawShaderMaterial ) { 18081 18082 prefixVertex = [ 18083 18084 customDefines 18085 18086 ].filter( filterEmptyLine ).join( '\n' ); 18087 18088 if ( prefixVertex.length > 0 ) { 18089 18090 prefixVertex += '\n'; 18091 18092 } 18093 18094 prefixFragment = [ 18095 18096 customExtensions, 18097 customDefines 18098 18099 ].filter( filterEmptyLine ).join( '\n' ); 18100 18101 if ( prefixFragment.length > 0 ) { 18102 18103 prefixFragment += '\n'; 18104 18105 } 18106 18107 } else { 18108 18109 prefixVertex = [ 18110 18111 generatePrecision( parameters ), 18112 18113 '#define SHADER_NAME ' + parameters.shaderName, 18114 18115 customDefines, 18116 18117 parameters.instancing ? '#define USE_INSTANCING' : '', 18118 parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '', 18119 18120 '#define GAMMA_FACTOR ' + gammaFactorDefine, 18121 18122 '#define MAX_BONES ' + parameters.maxBones, 18123 ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', 18124 ( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '', 18125 18126 parameters.map ? '#define USE_MAP' : '', 18127 parameters.envMap ? '#define USE_ENVMAP' : '', 18128 parameters.envMap ? '#define ' + envMapModeDefine : '', 18129 parameters.lightMap ? '#define USE_LIGHTMAP' : '', 18130 parameters.aoMap ? '#define USE_AOMAP' : '', 18131 parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', 18132 parameters.bumpMap ? '#define USE_BUMPMAP' : '', 18133 parameters.normalMap ? '#define USE_NORMALMAP' : '', 18134 ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '', 18135 ( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '', 18136 18137 parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', 18138 parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', 18139 parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', 18140 parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '', 18141 parameters.specularMap ? '#define USE_SPECULARMAP' : '', 18142 parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', 18143 parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', 18144 parameters.alphaMap ? '#define USE_ALPHAMAP' : '', 18145 18146 parameters.vertexTangents ? '#define USE_TANGENT' : '', 18147 parameters.vertexColors ? '#define USE_COLOR' : '', 18148 parameters.vertexUvs ? '#define USE_UV' : '', 18149 parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', 18150 18151 parameters.flatShading ? '#define FLAT_SHADED' : '', 18152 18153 parameters.skinning ? '#define USE_SKINNING' : '', 18154 parameters.useVertexTexture ? '#define BONE_TEXTURE' : '', 18155 18156 parameters.morphTargets ? '#define USE_MORPHTARGETS' : '', 18157 parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '', 18158 parameters.doubleSided ? '#define DOUBLE_SIDED' : '', 18159 parameters.flipSided ? '#define FLIP_SIDED' : '', 18160 18161 parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', 18162 parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', 18163 18164 parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '', 18165 18166 parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', 18167 ( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '', 18168 18169 'uniform mat4 modelMatrix;', 18170 'uniform mat4 modelViewMatrix;', 18171 'uniform mat4 projectionMatrix;', 18172 'uniform mat4 viewMatrix;', 18173 'uniform mat3 normalMatrix;', 18174 'uniform vec3 cameraPosition;', 18175 'uniform bool isOrthographic;', 18176 18177 '#ifdef USE_INSTANCING', 18178 18179 ' attribute mat4 instanceMatrix;', 18180 18181 '#endif', 18182 18183 'attribute vec3 position;', 18184 'attribute vec3 normal;', 18185 'attribute vec2 uv;', 18186 18187 '#ifdef USE_TANGENT', 18188 18189 ' attribute vec4 tangent;', 18190 18191 '#endif', 18192 18193 '#ifdef USE_COLOR', 18194 18195 ' attribute vec3 color;', 18196 18197 '#endif', 18198 18199 '#ifdef USE_MORPHTARGETS', 18200 18201 ' attribute vec3 morphTarget0;', 18202 ' attribute vec3 morphTarget1;', 18203 ' attribute vec3 morphTarget2;', 18204 ' attribute vec3 morphTarget3;', 18205 18206 ' #ifdef USE_MORPHNORMALS', 18207 18208 ' attribute vec3 morphNormal0;', 18209 ' attribute vec3 morphNormal1;', 18210 ' attribute vec3 morphNormal2;', 18211 ' attribute vec3 morphNormal3;', 18212 18213 ' #else', 18214 18215 ' attribute vec3 morphTarget4;', 18216 ' attribute vec3 morphTarget5;', 18217 ' attribute vec3 morphTarget6;', 18218 ' attribute vec3 morphTarget7;', 18219 18220 ' #endif', 18221 18222 '#endif', 18223 18224 '#ifdef USE_SKINNING', 18225 18226 ' attribute vec4 skinIndex;', 18227 ' attribute vec4 skinWeight;', 18228 18229 '#endif', 18230 18231 '\n' 18232 18233 ].filter( filterEmptyLine ).join( '\n' ); 18234 18235 prefixFragment = [ 18236 18237 customExtensions, 18238 18239 generatePrecision( parameters ), 18240 18241 '#define SHADER_NAME ' + parameters.shaderName, 18242 18243 customDefines, 18244 18245 parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest + ( parameters.alphaTest % 1 ? '' : '.0' ) : '', // add '.0' if integer 18246 18247 '#define GAMMA_FACTOR ' + gammaFactorDefine, 18248 18249 ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', 18250 ( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '', 18251 18252 parameters.map ? '#define USE_MAP' : '',
18253 parameters.matcap ? '#define USE_MATCAP' : '', 18254 parameters.envMap ? '#define USE_ENVMAP' : '', 18255 parameters.envMap ? '#define ' + envMapTypeDefine : '', 18256 parameters.envMap ? '#define ' + envMapModeDefine : '', 18257 parameters.envMap ? '#define ' + envMapBlendingDefine : '', 18258 parameters.lightMap ? '#define USE_LIGHTMAP' : '', 18259 parameters.aoMap ? '#define USE_AOMAP' : '', 18260 parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', 18261 parameters.bumpMap ? '#define USE_BUMPMAP' : '', 18262 parameters.normalMap ? '#define USE_NORMALMAP' : '', 18263 ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '', 18264 ( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '', 18265 parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', 18266 parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', 18267 parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', 18268 parameters.specularMap ? '#define USE_SPECULARMAP' : '', 18269 parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', 18270 parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', 18271 parameters.alphaMap ? '#define USE_ALPHAMAP' : '', 18272 18273 parameters.sheen ? '#define USE_SHEEN' : '', 18274 18275 parameters.vertexTangents ? '#define USE_TANGENT' : '', 18276 parameters.vertexColors ? '#define USE_COLOR' : '', 18277 parameters.vertexUvs ? '#define USE_UV' : '', 18278 parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', 18279 18280 parameters.gradientMap ? '#define USE_GRADIENTMAP' : '', 18281 18282 parameters.flatShading ? '#define FLAT_SHADED' : '', 18283 18284 parameters.doubleSided ? '#define DOUBLE_SIDED' : '', 18285 parameters.flipSided ? '#define FLIP_SIDED' : '', 18286 18287 parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', 18288 parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', 18289 18290 parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '', 18291 18292 parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '', 18293 18294 parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', 18295 ( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '', 18296 18297 ( ( parameters.extensionShaderTextureLOD || parameters.envMap ) && parameters.rendererExtensionShaderTextureLod ) ? '#define TEXTURE_LOD_EXT' : '', 18298 18299 'uniform mat4 viewMatrix;', 18300 'uniform vec3 cameraPosition;', 18301 'uniform bool isOrthographic;', 18302 18303 ( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '', 18304 ( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below 18305 ( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( 'toneMapping', parameters.toneMapping ) : '', 18306 18307 parameters.dithering ? '#define DITHERING' : '', 18308 18309 ( parameters.outputEncoding || parameters.mapEncoding || parameters.matcapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding || parameters.lightMapEncoding ) ? 18310 ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below 18311 parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '', 18312 parameters.matcapEncoding ? getTexelDecodingFunction( 'matcapTexelToLinear', parameters.matcapEncoding ) : '', 18313 parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '', 18314 parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '', 18315 parameters.lightMapEncoding ? getTexelDecodingFunction( 'lightMapTexelToLinear', parameters.lightMapEncoding ) : '', 18316 parameters.outputEncoding ? getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ) : '', 18317 18318 parameters.depthPacking ? '#define DEPTH_PACKING ' + parameters.depthPacking : '', 18319 18320 '\n' 18321 18322 ].filter( filterEmptyLine ).join( '\n' ); 18323 18324 } 18325 18326 vertexShader = resolveIncludes( vertexShader ); 18327 vertexShader = replaceLightNums( vertexShader, parameters ); 18328 vertexShader = replaceClippingPlaneNums( vertexShader, parameters ); 18329 18330 fragmentShader = resolveIncludes( fragmentShader ); 18331 fragmentShader = replaceLightNums( fragmentShader, parameters ); 18332 fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters ); 18333 18334 vertexShader = unrollLoops( vertexShader ); 18335 fragmentShader = unrollLoops( fragmentShader ); 18336 18337 if ( parameters.isWebGL2 && ! parameters.isRawShaderMaterial ) { 18338 18339 var isGLSL3ShaderMaterial = false;
18340 18341 var versionRegex = /^\s*#version\s+300\s+es\s*\n/; 18342 18343 if ( parameters.isShaderMaterial && 18344 vertexShader.match( versionRegex ) !== null && 18345 fragmentShader.match( versionRegex ) !== null ) { 18346 18347 isGLSL3ShaderMaterial = true; 18348 18349 vertexShader = vertexShader.replace( versionRegex, '' ); 18350 fragmentShader = fragmentShader.replace( versionRegex, '' ); 18351 18352 } 18353 18354 // GLSL 3.0 conversion 18355 18356 prefixVertex = [ 18357 '#version 300 es\n', 18358 '#define attribute in', 18359 '#define varying out', 18360 '#define texture2D texture' 18361 ].join( '\n' ) + '\n' + prefixVertex; 18362 18363 prefixFragment = [ 18364 '#version 300 es\n', 18365 '#define varying in', 18366 isGLSL3ShaderMaterial ? '' : 'out highp vec4 pc_fragColor;', 18367 isGLSL3ShaderMaterial ? '' : '#define gl_FragColor pc_fragColor', 18368 '#define gl_FragDepthEXT gl_FragDepth', 18369 '#define texture2D texture', 18370 '#define textureCube texture', 18371 '#define texture2DProj textureProj', 18372 '#define texture2DLodEXT textureLod', 18373 '#define texture2DProjLodEXT textureProjLod', 18374 '#define textureCubeLodEXT textureLod', 18375 '#define texture2DGradEXT textureGrad', 18376 '#define texture2DProjGradEXT textureProjGrad', 18377 '#define textureCubeGradEXT textureGrad' 18378 ].join( '\n' ) + '\n' + prefixFragment; 18379 18380 } 18381 18382 var vertexGlsl = prefixVertex + vertexShader; 18383 var fragmentGlsl = prefixFragment + fragmentShader; 18384 18385 // console.log( '*VERTEX*', vertexGlsl ); 18386 // console.log( '*FRAGMENT*', fragmentGlsl ); 18387 18388 var glVertexShader = WebGLShader( gl, 35633, vertexGlsl ); 18389 var glFragmentShader = WebGLShader( gl, 35632, fragmentGlsl ); 18390 18391 gl.attachShader( program, glVertexShader ); 18392 gl.attachShader( program, glFragmentShader ); 18393 18394 // Force a particular attribute to index 0. 18395 18396 if ( parameters.index0AttributeName !== undefined ) { 18397 18398 gl.bindAttribLocation( program, 0, parameters.index0AttributeName ); 18399 18400 } else if ( parameters.morphTargets === true ) { 18401 18402 // programs with morphTargets displace position out of attribute 0 18403 gl.bindAttribLocation( program, 0, 'position' ); 18404 18405 } 18406 18407 gl.linkProgram( program ); 18408 18409 // check for link errors 18410 if ( renderer.debug.checkShaderErrors ) { 18411 18412 var programLog = gl.getProgramInfoLog( program ).trim(); 18413 var vertexLog = gl.getShaderInfoLog( glVertexShader ).trim(); 18414 var fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim(); 18415 18416 var runnable = true; 18417 var haveDiagnostics = true; 18418 18419 if ( gl.getProgramParameter( program, 35714 ) === false ) { 18420 18421 runnable = false; 18422 18423 var vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' ); 18424 var fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' ); 18425 18426 console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), '35715', gl.getProgramParameter( program, 35715 ), 'gl.getProgramInfoLog', programLog, vertexErrors, fragmentErrors ); 18427 18428 } else if ( programLog !== '' ) { 18429 18430 console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog ); 18431 18432 } else if ( vertexLog === '' || fragmentLog === '' ) { 18433 18434 haveDiagnostics = false; 18435 18436 } 18437 18438 if ( haveDiagnostics ) { 18439 18440 this.diagnostics = { 18441 18442 runnable: runnable, 18443 18444 programLog: programLog, 18445 18446 vertexShader: { 18447 18448 log: vertexLog, 18449 prefix: prefixVertex 18450 18451 }, 18452 18453 fragmentShader: { 18454 18455 log: fragmentLog, 18456 prefix: prefixFragment 18457 18458 } 18459 18460 }; 18461 18462 } 18463 18464 } 18465 18466 // Clean up 18467 18468 // Crashes in iOS9 and iOS10. #18402 18469 // gl.detachShader( program, glVertexShader ); 18470 // gl.detachShader( program, glFragmentShader ); 18471 18472 gl.deleteShader( glVertexShader ); 18473 gl.deleteShader( glFragmentShader ); 18474 18475 // set up caching for uniform locations 18476 18477 var cachedUniforms; 18478 18479 this.getUniforms = function () { 18480 18481 if ( cachedUniforms === undefined ) { 18482 18483 cachedUniforms = new WebGLUniforms( gl, program ); 18484 18485 } 18486 18487 return cachedUniforms; 18488 18489 }; 18490 18491 // set up caching for attribute locations 18492 18493 var cachedAttributes; 18494 18495 this.getAttributes = function () { 18496 18497 if ( cachedAttributes === undefined ) { 18498 18499 cachedAttributes = fetchAttributeLocations( gl, program ); 18500 18501 } 18502 18503 return cachedAttributes; 18504 18505 }; 18506 18507 // free resource 18508 18509 this.destroy = function () { 18510 18511 gl.deleteProgram( program ); 18512 this.program = undefined; 18513 18514 }; 18515 18516 // 18517 18518 this.name = parameters.shaderName; 18519 this.id = programIdCount ++; 18520 this.cacheKey = cacheKey; 18521 this.usedTimes = 1; 18522 this.program = program; 18523 this.vertexShader = glVertexShader; 18524 this.fragmentShader = glFragmentShader; 18525 18526 return this; 18527 18528} 18529 18530/** 18531 * @author mrdoob / http://mrdoob.com/ 18532 */ 18533 18534function WebGLPrograms( renderer, extensions, capabilities ) { 18535 18536 var programs = []; 18537 18538 var isWebGL2 = capabilities.isWebGL2; 18539 var logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer; 18540 var floatVertexTextures = capabilities.floatVertexTextures; 18541 var precision = capabilities.precision; 18542 var maxVertexUniforms = capabilities.maxVertexUniforms; 18543 var vertexTextures = capabilities.vertexTextures; 18544 18545 var shaderIDs = { 18546 MeshDepthMaterial: 'depth', 18547 MeshDistanceMaterial: 'distanceRGBA', 18548 MeshNormalMaterial: 'normal', 18549 MeshBasicMaterial: 'basic', 18550 MeshLambertMaterial: 'lambert', 18551 MeshPhongMaterial: 'phong', 18552 MeshToonMaterial: 'toon', 18553 MeshStandardMaterial: 'physical', 18554 MeshPhysicalMaterial: 'physical', 18555 MeshMatcapMaterial: 'matcap', 18556 LineBasicMaterial: 'basic', 18557 LineDashedMaterial: 'dashed', 18558 PointsMaterial: 'points', 18559 ShadowMaterial: 'shadow', 18560 SpriteMaterial: 'sprite' 18561 }; 18562 18563 var parameterNames = [ 18564 "precision", "isWebGL2", "supportsVertexTextures", "outputEncoding", "instancing", 18565 "map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding", "envMapCubeUV", 18566 "lightMap", "lightMapEncoding", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "tangentSpaceNormalMap", "clearcoatMap", "clearcoatRoughnessMap", "clearcoatNormalMap", "displacementMap", "specularMap", 18567 "roughnessMap", "metalnessMap", "gradientMap", 18568 "alphaMap", "combine", "vertexColors", "vertexTangents", "vertexUvs", "uvsVertexOnly", "fog", "useFog", "fogExp2", 18569 "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning", 18570 "maxBones", "useVertexTexture", "morphTargets", "morphNormals", 18571 "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha", 18572 "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights", 18573 "numDirLightShadows", "numPointLightShadows", "numSpotLightShadows", 18574 "shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights', 18575 "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering", 18576 "sheen" 18577 ]; 18578 18579 function getShaderObject( material, shaderID ) { 18580 18581 var shaderobject; 18582 18583 if ( shaderID ) { 18584 18585 var shader = ShaderLib[ shaderID ]; 18586 18587 shaderobject = { 18588 name: material.type, 18589 uniforms: UniformsUtils.clone( shader.uniforms ), 18590 vertexShader: shader.vertexShader, 18591 fragmentShader: shader.fragmentShader 18592 }; 18593 18594 } else { 18595 18596 shaderobject = { 18597 name: material.type, 18598 uniforms: material.uniforms, 18599 vertexShader: material.vertexShader, 18600 fragmentShader: material.fragmentShader 18601 }; 18602 18603 } 18604 18605 return shaderobject; 18606 18607 } 18608 18609 function allocateBones( object ) { 18610 18611 var skeleton = object.skeleton; 18612 var bones = skeleton.bones; 18613 18614 if ( floatVertexTextures ) { 18615 18616 return 1024; 18617 18618 } else { 18619 18620 // default for when object is not specified 18621 // ( for example when prebuilding shader to be used with multiple objects ) 18622 // 18623 // - leave some extra space for other uniforms 18624 // - limit here is ANGLE's 254 max uniform vectors 18625 // (up to 54 should be safe) 18626 18627 var nVertexUniforms = maxVertexUniforms; 18628 var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 ); 18629 18630 var maxBones = Math.min( nVertexMatrices, bones.length ); 18631
18632 if ( maxBones < bones.length ) { 18633 18634 console.warn( 'THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.' ); 18635 return 0; 18636 18637 } 18638 18639 return maxBones; 18640 18641 } 18642 18643 } 18644 18645 function getTextureEncodingFromMap( map ) { 18646 18647 var encoding; 18648 18649 if ( ! map ) { 18650 18651 encoding = LinearEncoding; 18652 18653 } else if ( map.isTexture ) { 18654 18655 encoding = map.encoding; 18656 18657 } else if ( map.isWebGLRenderTarget ) { 18658 18659 console.warn( "THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead." ); 18660 encoding = map.texture.encoding; 18661 18662 } 18663 18664 return encoding; 18665 18666 } 18667 18668 this.getParameters = function ( material, lights, shadows, scene, nClipPlanes, nClipIntersection, object ) { 18669 18670 var fog = scene.fog; 18671 var environment = material.isMeshStandardMaterial ? scene.environment : null; 18672 18673 var envMap = material.envMap || environment; 18674 18675 var shaderID = shaderIDs[ material.type ]; 18676 18677 // heuristics to create shader parameters according to lights in the scene 18678 // (not to blow over maxLights budget) 18679 18680 var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0; 18681 18682 if ( material.precision !== null ) { 18683 18684 precision = capabilities.getMaxPrecision( material.precision ); 18685 18686 if ( precision !== material.precision ) { 18687 18688 console.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' ); 18689 18690 } 18691 18692 } 18693 18694 var shaderobject = getShaderObject( material, shaderID ); 18695 material.onBeforeCompile( shaderobject, renderer ); 18696 18697 var currentRenderTarget = renderer.getRenderTarget(); 18698 18699 var parameters = { 18700 18701 isWebGL2: isWebGL2, 18702 18703 shaderID: shaderID, 18704 shaderName: shaderobject.name, 18705 18706 uniforms: shaderobject.uniforms, 18707 vertexShader: shaderobject.vertexShader, 18708 fragmentShader: shaderobject.fragmentShader, 18709 defines: material.defines, 18710 18711 isRawShaderMaterial: material.isRawShaderMaterial, 18712 isShaderMaterial: material.isShaderMaterial, 18713 18714 precision: precision, 18715 18716 instancing: object.isInstancedMesh === true, 18717 18718 supportsVertexTextures: vertexTextures, 18719 outputEncoding: ( currentRenderTarget !== null ) ? getTextureEncodingFromMap( currentRenderTarget.texture ) : renderer.outputEncoding, 18720 map: !! material.map, 18721 mapEncoding: getTextureEncodingFromMap( material.map ), 18722 matcap: !! material.matcap, 18723 matcapEncoding: getTextureEncodingFromMap( material.matcap ), 18724 envMap: !! envMap, 18725 envMapMode: envMap && envMap.mapping, 18726 envMapEncoding: getTextureEncodingFromMap( envMap ), 18727 envMapCubeUV: ( !! envMap ) && ( ( envMap.mapping === CubeUVReflectionMapping ) || ( envMap.mapping === CubeUVRefractionMapping ) ), 18728 lightMap: !! material.lightMap, 18729 lightMapEncoding: getTextureEncodingFromMap( material.lightMap ), 18730 aoMap: !! material.aoMap, 18731 emissiveMap: !! material.emissiveMap, 18732 emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap ), 18733 bumpMap: !! material.bumpMap, 18734 normalMap: !! material.normalMap, 18735 objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap, 18736 tangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap, 18737 clearcoatMap: !! material.clearcoatMap, 18738 clearcoatRoughnessMap: !! material.clearcoatRoughnessMap, 18739 clearcoatNormalMap: !! material.clearcoatNormalMap, 18740 displacementMap: !! material.displacementMap, 18741 roughnessMap: !! material.roughnessMap, 18742 metalnessMap: !! material.metalnessMap, 18743 specularMap: !! material.specularMap, 18744 alphaMap: !! material.alphaMap, 18745 18746 gradientMap: !! material.gradientMap, 18747 18748 sheen: !! material.sheen, 18749 18750 combine: material.combine, 18751 18752 vertexTangents: ( material.normalMap && material.vertexTangents ), 18753 vertexColors: material.vertexColors, 18754 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, 18755 uvsVertexOnly: ! ( !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap ) && !! material.displacementMap, 18756 18757 fog: !! fog, 18758 useFog: material.fog, 18759 fogExp2: ( fog && fog.isFogExp2 ), 18760 18761 flatShading: material.flatShading, 18762 18763 sizeAttenuation: material.sizeAttenuation, 18764 logarithmicDepthBuffer: logarithmicDepthBuffer, 18765 18766 skinning: material.skinning && maxBones > 0, 18767 maxBones: maxBones, 18768 useVertexTexture: floatVertexTextures, 18769 18770 morphTargets: material.morphTargets, 18771 morphNormals: material.morphNormals, 18772 maxMorphTargets: renderer.maxMorphTargets, 18773 maxMorphNormals: renderer.maxMorphNormals, 18774 18775 numDirLights: lights.directional.length, 18776 numPointLights: lights.point.length, 18777 numSpotLights: lights.spot.length, 18778 numRectAreaLights: lights.rectArea.length, 18779 numHemiLights: lights.hemi.length, 18780 18781 numDirLightShadows: lights.directionalShadowMap.length, 18782 numPointLightShadows: lights.pointShadowMap.length, 18783 numSpotLightShadows: lights.spotShadowMap.length, 18784 18785 numClippingPlanes: nClipPlanes, 18786 numClipIntersection: nClipIntersection, 18787 18788 dithering: material.dithering, 18789 18790 shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0, 18791 shadowMapType: renderer.shadowMap.type, 18792 18793 toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping, 18794 physicallyCorrectLights: renderer.physicallyCorrectLights, 18795 18796 premultipliedAlpha: material.premultipliedAlpha, 18797 18798 alphaTest: material.alphaTest, 18799 doubleSided: material.side === DoubleSide, 18800 flipSided: material.side === BackSide, 18801 18802 depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false, 18803 18804 index0AttributeName: material.index0AttributeName, 18805 18806 extensionDerivatives: material.extensions && material.extensions.derivatives, 18807 extensionFragDepth: material.extensions && material.extensions.fragDepth, 18808 extensionDrawBuffers: material.extensions && material.extensions.drawBuffers, 18809 extensionShaderTextureLOD: material.extensions && material.extensions.shaderTextureLOD, 18810 18811 rendererExtensionFragDepth: isWebGL2 || extensions.get( 'EXT_frag_depth' ) !== null, 18812 rendererExtensionDrawBuffers: isWebGL2 || extensions.get( 'WEBGL_draw_buffers' ) !== null, 18813 rendererExtensionShaderTextureLod: isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) !== null, 18814 18815 onBeforeCompile: material.onBeforeCompile 18816 18817 }; 18818 18819 return parameters; 18820 18821 }; 18822 18823 this.getProgramCacheKey = function ( parameters ) { 18824 18825 var array = []; 18826 18827 if ( parameters.shaderID ) { 18828 18829 array.push( parameters.shaderID ); 18830 18831 } else { 18832 18833 array.push( parameters.fragmentShader ); 18834 array.push( parameters.vertexShader ); 18835 18836 } 18837 18838 if ( parameters.defines !== undefined ) { 18839 18840 for ( var name in parameters.defines ) { 18841 18842 array.push( name ); 18843 array.push( parameters.defines[ name ] ); 18844 18845 } 18846 18847 } 18848 18849 if ( parameters.isRawShaderMaterial === undefined ) { 18850 18851 for ( var i = 0; i < parameterNames.length; i ++ ) { 18852 18853 array.push( parameters[ parameterNames[ i ] ] ); 18854 18855 } 18856 18857 array.push( renderer.outputEncoding ); 18858 array.push( renderer.gammaFactor ); 18859 18860 } 18861 18862 array.push( parameters.onBeforeCompile.toString() ); 18863 18864 return array.join(); 18865 18866 }; 18867 18868 this.acquireProgram = function ( parameters, cacheKey ) { 18869 18870 var program; 18871 18872 // Check if code has been already compiled 18873 for ( var p = 0, pl = programs.length; p < pl; p ++ ) { 18874 18875 var preexistingProgram = programs[ p ]; 18876 18877 if ( preexistingProgram.cacheKey === cacheKey ) { 18878 18879 program = preexistingProgram; 18880 ++ program.usedTimes; 18881 18882 break; 18883 18884 } 18885 18886 } 18887 18888 if ( program === undefined ) { 18889 18890 program = new WebGLProgram( renderer, cacheKey, parameters ); 18891 programs.push( program ); 18892 18893 } 18894 18895 return program; 18896 18897 }; 18898 18899 this.releaseProgram = function ( program ) { 18900 18901 if ( -- program.usedTimes === 0 ) { 18902 18903 // Remove from unordered set 18904 var i = programs.indexOf( program ); 18905 programs[ i ] = programs[ programs.length - 1 ]; 18906 programs.pop(); 18907 18908 // Free WebGL resources 18909 program.destroy(); 18910 18911 } 18912 18913 }; 18914 18915 // Exposed for resource monitoring & error feedback via renderer.info: 18916 this.programs = programs; 18917 18918} 18919 18920/** 18921 * @author fordacious / fordacious.github.io 18922 */ 18923 18924function WebGLProperties() { 18925 18926 var properties = new WeakMap(); 18927 18928 function get( object ) { 18929 18930 var map = properties.get( object ); 18931 18932 if ( map === undefined ) { 18933 18934 map = {}; 18935 properties.set( object, map ); 18936 18937 } 18938 18939 return map; 18940 18941 } 18942 18943 function remove( object ) { 18944 18945 properties.delete( object ); 18946 18947 } 18948 18949 function update( object, key, value ) { 18950 18951 properties.get( object )[ key ] = value; 18952 18953 } 18954 18955 function dispose() { 18956 18957 properties = new WeakMap(); 18958 18959 } 18960 18961 return { 18962 get: get, 18963 remove: remove, 18964 update: update,
vendor: 27,895 bytes, lines 18965-20236
18965 dispose: dispose 18966 }; 18967 18968} 18969 18970/** 18971 * @author mrdoob / http://mrdoob.com/ 18972 */ 18973 18974function painterSortStable( a, b ) { 18975 18976 if ( a.groupOrder !== b.groupOrder ) { 18977 18978 return a.groupOrder - b.groupOrder; 18979 18980 } else if ( a.renderOrder !== b.renderOrder ) { 18981 18982 return a.renderOrder - b.renderOrder; 18983 18984 } else if ( a.program !== b.program ) { 18985 18986 return a.program.id - b.program.id; 18987 18988 } else if ( a.material.id !== b.material.id ) { 18989 18990 return a.material.id - b.material.id; 18991 18992 } else if ( a.z !== b.z ) { 18993 18994 return a.z - b.z; 18995 18996 } else { 18997 18998 return a.id - b.id; 18999 19000 } 19001 19002} 19003 19004function reversePainterSortStable( a, b ) { 19005 19006 if ( a.groupOrder !== b.groupOrder ) { 19007 19008 return a.groupOrder - b.groupOrder; 19009 19010 } else if ( a.renderOrder !== b.renderOrder ) { 19011 19012 return a.renderOrder - b.renderOrder; 19013 19014 } else if ( a.z !== b.z ) { 19015 19016 return b.z - a.z; 19017 19018 } else { 19019 19020 return a.id - b.id; 19021 19022 } 19023 19024} 19025 19026 19027function WebGLRenderList() { 19028 19029 var renderItems = []; 19030 var renderItemsIndex = 0; 19031 19032 var opaque = []; 19033 var transparent = []; 19034 19035 var defaultProgram = { id: - 1 }; 19036 19037 function init() { 19038 19039 renderItemsIndex = 0; 19040 19041 opaque.length = 0; 19042 transparent.length = 0; 19043 19044 } 19045 19046 function getNextRenderItem( object, geometry, material, groupOrder, z, group ) { 19047 19048 var renderItem = renderItems[ renderItemsIndex ]; 19049 19050 if ( renderItem === undefined ) { 19051 19052 renderItem = { 19053 id: object.id, 19054 object: object, 19055 geometry: geometry, 19056 material: material, 19057 program: material.program || defaultProgram, 19058 groupOrder: groupOrder, 19059 renderOrder: object.renderOrder, 19060 z: z, 19061 group: group 19062 }; 19063 19064 renderItems[ renderItemsIndex ] = renderItem; 19065 19066 } else { 19067 19068 renderItem.id = object.id; 19069 renderItem.object = object; 19070 renderItem.geometry = geometry; 19071 renderItem.material = material; 19072 renderItem.program = material.program || defaultProgram; 19073 renderItem.groupOrder = groupOrder; 19074 renderItem.renderOrder = object.renderOrder; 19075 renderItem.z = z; 19076 renderItem.group = group; 19077 19078 } 19079 19080 renderItemsIndex ++; 19081 19082 return renderItem; 19083 19084 } 19085 19086 function push( object, geometry, material, groupOrder, z, group ) { 19087 19088 var renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group ); 19089 19090 ( material.transparent === true ? transparent : opaque ).push( renderItem ); 19091 19092 } 19093 19094 function unshift( object, geometry, material, groupOrder, z, group ) { 19095 19096 var renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group ); 19097 19098 ( material.transparent === true ? transparent : opaque ).unshift( renderItem ); 19099 19100 } 19101 19102 function sort( customOpaqueSort, customTransparentSort ) { 19103 19104 if ( opaque.length > 1 ) opaque.sort( customOpaqueSort || painterSortStable ); 19105 if ( transparent.length > 1 ) transparent.sort( customTransparentSort || reversePainterSortStable ); 19106 19107 } 19108 19109 function finish() { 19110 19111 // Clear references from inactive renderItems in the list 19112 19113 for ( var i = renderItemsIndex, il = renderItems.length; i < il; i ++ ) { 19114 19115 var renderItem = renderItems[ i ]; 19116 19117 if ( renderItem.id === null ) break; 19118 19119 renderItem.id = null; 19120 renderItem.object = null; 19121 renderItem.geometry = null; 19122 renderItem.material = null; 19123 renderItem.program = null; 19124 renderItem.group = null; 19125 19126 } 19127 19128 } 19129 19130 return { 19131 opaque: opaque, 19132 transparent: transparent, 19133 19134 init: init, 19135 push: push, 19136 unshift: unshift, 19137 finish: finish, 19138 19139 sort: sort 19140 }; 19141 19142} 19143 19144function WebGLRenderLists() { 19145 19146 var lists = new WeakMap(); 19147 19148 function onSceneDispose( event ) { 19149 19150 var scene = event.target; 19151 19152 scene.removeEventListener( 'dispose', onSceneDispose ); 19153 19154 lists.delete( scene ); 19155 19156 } 19157 19158 function get( scene, camera ) { 19159 19160 var cameras = lists.get( scene ); 19161 var list; 19162 if ( cameras === undefined ) { 19163 19164 list = new WebGLRenderList(); 19165 lists.set( scene, new WeakMap() ); 19166 lists.get( scene ).set( camera, list ); 19167 19168 scene.addEventListener( 'dispose', onSceneDispose ); 19169 19170 } else { 19171 19172 list = cameras.get( camera ); 19173 if ( list === undefined ) { 19174 19175 list = new WebGLRenderList(); 19176 cameras.set( camera, list ); 19177 19178 } 19179 19180 } 19181 19182 return list; 19183 19184 } 19185 19186 function dispose() { 19187 19188 lists = new WeakMap(); 19189 19190 } 19191 19192 return { 19193 get: get, 19194 dispose: dispose 19195 }; 19196 19197} 19198 19199/** 19200 * @author mrdoob / http://mrdoob.com/ 19201 */ 19202 19203function UniformsCache() { 19204 19205 var lights = {}; 19206 19207 return { 19208 19209 get: function ( light ) { 19210 19211 if ( lights[ light.id ] !== undefined ) { 19212 19213 return lights[ light.id ]; 19214 19215 } 19216 19217 var uniforms; 19218 19219 switch ( light.type ) { 19220 19221 case 'DirectionalLight': 19222 uniforms = { 19223 direction: new Vector3(), 19224 color: new Color() 19225 }; 19226 break; 19227 19228 case 'SpotLight': 19229 uniforms = { 19230 position: new Vector3(), 19231 direction: new Vector3(), 19232 color: new Color(), 19233 distance: 0, 19234 coneCos: 0, 19235 penumbraCos: 0, 19236 decay: 0 19237 }; 19238 break; 19239 19240 case 'PointLight': 19241 uniforms = { 19242 position: new Vector3(), 19243 color: new Color(), 19244 distance: 0, 19245 decay: 0 19246 }; 19247 break; 19248 19249 case 'HemisphereLight': 19250 uniforms = { 19251 direction: new Vector3(), 19252 skyColor: new Color(), 19253 groundColor: new Color() 19254 }; 19255 break; 19256 19257 case 'RectAreaLight': 19258 uniforms = { 19259 color: new Color(), 19260 position: new Vector3(), 19261 halfWidth: new Vector3(), 19262 halfHeight: new Vector3() 19263 }; 19264 break; 19265 19266 } 19267 19268 lights[ light.id ] = uniforms; 19269 19270 return uniforms; 19271 19272 } 19273 19274 }; 19275 19276} 19277 19278function ShadowUniformsCache() { 19279 19280 var lights = {}; 19281 19282 return { 19283 19284 get: function ( light ) { 19285 19286 if ( lights[ light.id ] !== undefined ) { 19287 19288 return lights[ light.id ]; 19289 19290 } 19291 19292 var uniforms; 19293 19294 switch ( light.type ) { 19295 19296 case 'DirectionalLight': 19297 uniforms = { 19298 shadowBias: 0, 19299 shadowRadius: 1, 19300 shadowMapSize: new Vector2() 19301 }; 19302 break; 19303 19304 case 'SpotLight': 19305 uniforms = { 19306 shadowBias: 0, 19307 shadowRadius: 1, 19308 shadowMapSize: new Vector2() 19309 }; 19310 break; 19311 19312 case 'PointLight': 19313 uniforms = { 19314 shadowBias: 0, 19315 shadowRadius: 1, 19316 shadowMapSize: new Vector2(), 19317 shadowCameraNear: 1, 19318 shadowCameraFar: 1000 19319 }; 19320 break; 19321 19322 // TODO (abelnation): set RectAreaLight shadow uniforms 19323 19324 } 19325 19326 lights[ light.id ] = uniforms; 19327 19328 return uniforms; 19329 19330 } 19331 19332 }; 19333 19334} 19335 19336 19337 19338var nextVersion = 0; 19339 19340function shadowCastingLightsFirst( lightA, lightB ) { 19341 19342 return ( lightB.castShadow ? 1 : 0 ) - ( lightA.castShadow ? 1 : 0 ); 19343 19344} 19345 19346function WebGLLights() { 19347 19348 var cache = new UniformsCache(); 19349 19350 var shadowCache = ShadowUniformsCache(); 19351 19352 var state = { 19353 19354 version: 0, 19355 19356 hash: { 19357 directionalLength: - 1, 19358 pointLength: - 1, 19359 spotLength: - 1, 19360 rectAreaLength: - 1, 19361 hemiLength: - 1, 19362 19363 numDirectionalShadows: - 1, 19364 numPointShadows: - 1, 19365 numSpotShadows: - 1 19366 }, 19367 19368 ambient: [ 0, 0, 0 ], 19369 probe: [], 19370 directional: [], 19371 directionalShadow: [], 19372 directionalShadowMap: [], 19373 directionalShadowMatrix: [], 19374 spot: [], 19375 spotShadow: [], 19376 spotShadowMap: [], 19377 spotShadowMatrix: [], 19378 rectArea: [], 19379 point: [], 19380 pointShadow: [], 19381 pointShadowMap: [], 19382 pointShadowMatrix: [], 19383 hemi: [] 19384 19385 }; 19386 19387 for ( var i = 0; i < 9; i ++ ) state.probe.push( new Vector3() ); 19388 19389 var vector3 = new Vector3(); 19390 var matrix4 = new Matrix4(); 19391 var matrix42 = new Matrix4(); 19392 19393 function setup( lights, shadows, camera ) { 19394 19395 var r = 0, g = 0, b = 0; 19396 19397 for ( var i = 0; i < 9; i ++ ) state.probe[ i ].set( 0, 0, 0 ); 19398 19399 var directionalLength = 0; 19400 var pointLength = 0; 19401 var spotLength = 0; 19402 var rectAreaLength = 0; 19403 var hemiLength = 0; 19404 19405 var numDirectionalShadows = 0; 19406 var numPointShadows = 0; 19407 var numSpotShadows = 0; 19408 19409 var viewMatrix = camera.matrixWorldInverse; 19410 19411 lights.sort( shadowCastingLightsFirst ); 19412 19413 for ( var i = 0, l = lights.length; i < l; i ++ ) { 19414 19415 var light = lights[ i ]; 19416 19417 var color = light.color; 19418 var intensity = light.intensity; 19419 var distance = light.distance; 19420 19421 var shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null; 19422 19423 if ( light.isAmbientLight ) { 19424 19425 r += color.r * intensity; 19426 g += color.g * intensity; 19427 b += color.b * intensity; 19428 19429 } else if ( light.isLightProbe ) { 19430 19431 for ( var j = 0; j < 9; j ++ ) { 19432 19433 state.probe[ j ].addScaledVector( light.sh.coefficients[ j ], intensity ); 19434 19435 } 19436 19437 } else if ( light.isDirectionalLight ) { 19438 19439 var uniforms = cache.get( light ); 19440 19441 uniforms.color.copy( light.color ).multiplyScalar( light.intensity ); 19442 uniforms.direction.setFromMatrixPosition( light.matrixWorld ); 19443 vector3.setFromMatrixPosition( light.target.matrixWorld ); 19444 uniforms.direction.sub( vector3 ); 19445 uniforms.direction.transformDirection( viewMatrix ); 19446 19447 if ( light.castShadow ) { 19448 19449 var shadow = light.shadow; 19450 19451 var shadowUniforms = shadowCache.get( light ); 19452 19453 shadowUniforms.shadowBias = shadow.bias; 19454 shadowUniforms.shadowRadius = shadow.radius; 19455 shadowUniforms.shadowMapSize = shadow.mapSize; 19456 19457 state.directionalShadow[ directionalLength ] = shadowUniforms; 19458 state.directionalShadowMap[ directionalLength ] = shadowMap; 19459 state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix; 19460 19461 numDirectionalShadows ++; 19462 19463 } 19464 19465 state.directional[ directionalLength ] = uniforms; 19466 19467 directionalLength ++; 19468 19469 } else if ( light.isSpotLight ) { 19470 19471 var uniforms = cache.get( light ); 19472 19473 uniforms.position.setFromMatrixPosition( light.matrixWorld ); 19474 uniforms.position.applyMatrix4( viewMatrix ); 19475 19476 uniforms.color.copy( color ).multiplyScalar( intensity ); 19477 uniforms.distance = distance; 19478 19479 uniforms.direction.setFromMatrixPosition( light.matrixWorld ); 19480 vector3.setFromMatrixPosition( light.target.matrixWorld ); 19481 uniforms.direction.sub( vector3 ); 19482 uniforms.direction.transformDirection( viewMatrix ); 19483 19484 uniforms.coneCos = Math.cos( light.angle ); 19485 uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) ); 19486 uniforms.decay = light.decay; 19487 19488 if ( light.castShadow ) { 19489 19490 var shadow = light.shadow; 19491 19492 var shadowUniforms = shadowCache.get( light ); 19493 19494 shadowUniforms.shadowBias = shadow.bias; 19495 shadowUniforms.shadowRadius = shadow.radius; 19496 shadowUniforms.shadowMapSize = shadow.mapSize; 19497 19498 state.spotShadow[ spotLength ] = shadowUniforms; 19499 state.spotShadowMap[ spotLength ] = shadowMap; 19500 state.spotShadowMatrix[ spotLength ] = light.shadow.matrix; 19501 19502 numSpotShadows ++; 19503 19504 } 19505 19506 state.spot[ spotLength ] = uniforms; 19507 19508 spotLength ++; 19509 19510 } else if ( light.isRectAreaLight ) { 19511 19512 var uniforms = cache.get( light ); 19513 19514 // (a) intensity is the total visible light emitted 19515 //uniforms.color.copy( color ).multiplyScalar( intensity / ( light.width * light.height * Math.PI ) ); 19516 19517 // (b) intensity is the brightness of the light 19518 uniforms.color.copy( color ).multiplyScalar( intensity ); 19519 19520 uniforms.position.setFromMatrixPosition( light.matrixWorld ); 19521 uniforms.position.applyMatrix4( viewMatrix ); 19522 19523 // extract local rotation of light to derive width/height half vectors 19524 matrix42.identity(); 19525 matrix4.copy( light.matrixWorld ); 19526 matrix4.premultiply( viewMatrix ); 19527 matrix42.extractRotation( matrix4 ); 19528 19529 uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 ); 19530 uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 ); 19531 19532 uniforms.halfWidth.applyMatrix4( matrix42 ); 19533 uniforms.halfHeight.applyMatrix4( matrix42 ); 19534 19535 // TODO (abelnation): RectAreaLight distance? 19536 // uniforms.distance = distance; 19537 19538 state.rectArea[ rectAreaLength ] = uniforms; 19539 19540 rectAreaLength ++; 19541 19542 } else if ( light.isPointLight ) { 19543 19544 var uniforms = cache.get( light ); 19545 19546 uniforms.position.setFromMatrixPosition( light.matrixWorld ); 19547 uniforms.position.applyMatrix4( viewMatrix ); 19548 19549 uniforms.color.copy( light.color ).multiplyScalar( light.intensity ); 19550 uniforms.distance = light.distance; 19551 uniforms.decay = light.decay; 19552 19553 if ( light.castShadow ) { 19554 19555 var shadow = light.shadow; 19556 19557 var shadowUniforms = shadowCache.get( light ); 19558 19559 shadowUniforms.shadowBias = shadow.bias; 19560 shadowUniforms.shadowRadius = shadow.radius; 19561 shadowUniforms.shadowMapSize = shadow.mapSize; 19562 shadowUniforms.shadowCameraNear = shadow.camera.near; 19563 shadowUniforms.shadowCameraFar = shadow.camera.far; 19564 19565 state.pointShadow[ pointLength ] = shadowUniforms; 19566 state.pointShadowMap[ pointLength ] = shadowMap; 19567 state.pointShadowMatrix[ pointLength ] = light.shadow.matrix; 19568 19569 numPointShadows ++; 19570 19571 } 19572 19573 state.point[ pointLength ] = uniforms; 19574 19575 pointLength ++; 19576 19577 } else if ( light.isHemisphereLight ) { 19578 19579 var uniforms = cache.get( light ); 19580 19581 uniforms.direction.setFromMatrixPosition( light.matrixWorld ); 19582 uniforms.direction.transformDirection( viewMatrix ); 19583 uniforms.direction.normalize(); 19584 19585 uniforms.skyColor.copy( light.color ).multiplyScalar( intensity ); 19586 uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity ); 19587 19588 state.hemi[ hemiLength ] = uniforms; 19589 19590 hemiLength ++; 19591 19592 } 19593 19594 } 19595 19596 state.ambient[ 0 ] = r; 19597 state.ambient[ 1 ] = g; 19598 state.ambient[ 2 ] = b; 19599 19600 var hash = state.hash; 19601 19602 if ( hash.directionalLength !== directionalLength || 19603 hash.pointLength !== pointLength || 19604 hash.spotLength !== spotLength || 19605 hash.rectAreaLength !== rectAreaLength || 19606 hash.hemiLength !== hemiLength || 19607 hash.numDirectionalShadows !== numDirectionalShadows || 19608 hash.numPointShadows !== numPointShadows || 19609 hash.numSpotShadows !== numSpotShadows ) { 19610 19611 state.directional.length = directionalLength; 19612 state.spot.length = spotLength; 19613 state.rectArea.length = rectAreaLength; 19614 state.point.length = pointLength; 19615 state.hemi.length = hemiLength; 19616 19617 state.directionalShadow.length = numDirectionalShadows; 19618 state.directionalShadowMap.length = numDirectionalShadows; 19619 state.pointShadow.length = numPointShadows; 19620 state.pointShadowMap.length = numPointShadows; 19621 state.spotShadow.length = numSpotShadows; 19622 state.spotShadowMap.length = numSpotShadows; 19623 state.directionalShadowMatrix.length = numDirectionalShadows; 19624 state.pointShadowMatrix.length = numPointShadows; 19625 state.spotShadowMatrix.length = numSpotShadows; 19626 19627 hash.directionalLength = directionalLength; 19628 hash.pointLength = pointLength; 19629 hash.spotLength = spotLength; 19630 hash.rectAreaLength = rectAreaLength; 19631 hash.hemiLength = hemiLength; 19632 19633 hash.numDirectionalShadows = numDirectionalShadows; 19634 hash.numPointShadows = numPointShadows; 19635 hash.numSpotShadows = numSpotShadows; 19636 19637 state.version = nextVersion ++; 19638 19639 } 19640 19641 } 19642 19643 return { 19644 setup: setup, 19645 state: state 19646 }; 19647 19648} 19649 19650/** 19651 * @author Mugen87 / https://github.com/Mugen87 19652 */ 19653 19654function WebGLRenderState() { 19655 19656 var lights = new WebGLLights(); 19657 19658 var lightsArray = []; 19659 var shadowsArray = []; 19660 19661 function init() { 19662 19663 lightsArray.length = 0; 19664 shadowsArray.length = 0; 19665 19666 } 19667 19668 function pushLight( light ) { 19669 19670 lightsArray.push( light ); 19671 19672 } 19673 19674 function pushShadow( shadowLight ) { 19675 19676 shadowsArray.push( shadowLight ); 19677 19678 } 19679 19680 function setupLights( camera ) { 19681 19682 lights.setup( lightsArray, shadowsArray, camera ); 19683 19684 } 19685 19686 var state = { 19687 lightsArray: lightsArray, 19688 shadowsArray: shadowsArray, 19689 19690 lights: lights 19691 }; 19692 19693 return { 19694 init: init, 19695 state: state, 19696 setupLights: setupLights, 19697 19698 pushLight: pushLight, 19699 pushShadow: pushShadow 19700 }; 19701 19702} 19703 19704function WebGLRenderStates() { 19705 19706 var renderStates = new WeakMap(); 19707 19708 function onSceneDispose( event ) { 19709 19710 var scene = event.target; 19711 19712 scene.removeEventListener( 'dispose', onSceneDispose ); 19713 19714 renderStates.delete( scene ); 19715 19716 } 19717 19718 function get( scene, camera ) { 19719 19720 var renderState; 19721 19722 if ( renderStates.has( scene ) === false ) { 19723 19724 renderState = new WebGLRenderState(); 19725 renderStates.set( scene, new WeakMap() ); 19726 renderStates.get( scene ).set( camera, renderState ); 19727 19728 scene.addEventListener( 'dispose', onSceneDispose ); 19729 19730 } else { 19731 19732 if ( renderStates.get( scene ).has( camera ) === false ) { 19733 19734 renderState = new WebGLRenderState(); 19735 renderStates.get( scene ).set( camera, renderState ); 19736 19737 } else { 19738 19739 renderState = renderStates.get( scene ).get( camera ); 19740 19741 } 19742 19743 } 19744 19745 return renderState; 19746 19747 } 19748 19749 function dispose() { 19750 19751 renderStates = new WeakMap(); 19752 19753 } 19754 19755 return { 19756 get: get, 19757 dispose: dispose 19758 }; 19759 19760} 19761 19762/** 19763 * @author mrdoob / http://mrdoob.com/ 19764 * @author alteredq / http://alteredqualia.com/ 19765 * @author bhouston / https://clara.io 19766 * @author WestLangley / http://github.com/WestLangley 19767 * 19768 * parameters = { 19769 * 19770 * opacity: <float>, 19771 * 19772 * map: new THREE.Texture( <Image> ), 19773 * 19774 * alphaMap: new THREE.Texture( <Image> ), 19775 * 19776 * displacementMap: new THREE.Texture( <Image> ), 19777 * displacementScale: <float>, 19778 * displacementBias: <float>, 19779 * 19780 * wireframe: <boolean>, 19781 * wireframeLinewidth: <float> 19782 * } 19783 */ 19784 19785function MeshDepthMaterial( parameters ) { 19786 19787 Material.call( this ); 19788 19789 this.type = 'MeshDepthMaterial'; 19790 19791 this.depthPacking = BasicDepthPacking; 19792 19793 this.skinning = false; 19794 this.morphTargets = false; 19795 19796 this.map = null; 19797 19798 this.alphaMap = null; 19799 19800 this.displacementMap = null; 19801 this.displacementScale = 1; 19802 this.displacementBias = 0; 19803 19804 this.wireframe = false; 19805 this.wireframeLinewidth = 1; 19806 19807 this.fog = false; 19808 19809 this.setValues( parameters ); 19810 19811} 19812 19813MeshDepthMaterial.prototype = Object.create( Material.prototype ); 19814MeshDepthMaterial.prototype.constructor = MeshDepthMaterial; 19815 19816MeshDepthMaterial.prototype.isMeshDepthMaterial = true; 19817 19818MeshDepthMaterial.prototype.copy = function ( source ) { 19819 19820 Material.prototype.copy.call( this, source ); 19821 19822 this.depthPacking = source.depthPacking; 19823 19824 this.skinning = source.skinning; 19825 this.morphTargets = source.morphTargets; 19826 19827 this.map = source.map; 19828 19829 this.alphaMap = source.alphaMap; 19830 19831 this.displacementMap = source.displacementMap; 19832 this.displacementScale = source.displacementScale; 19833 this.displacementBias = source.displacementBias; 19834 19835 this.wireframe = source.wireframe; 19836 this.wireframeLinewidth = source.wireframeLinewidth; 19837 19838 return this; 19839 19840}; 19841 19842/** 19843 * @author WestLangley / http://github.com/WestLangley 19844 * 19845 * parameters = { 19846 * 19847 * referencePosition: <float>, 19848 * nearDistance: <float>, 19849 * farDistance: <float>, 19850 * 19851 * skinning: <bool>, 19852 * morphTargets: <bool>, 19853 * 19854 * map: new THREE.Texture( <Image> ), 19855 * 19856 * alphaMap: new THREE.Texture( <Image> ), 19857 * 19858 * displacementMap: new THREE.Texture( <Image> ), 19859 * displacementScale: <float>, 19860 * displacementBias: <float> 19861 * 19862 * } 19863 */ 19864 19865function MeshDistanceMaterial( parameters ) { 19866 19867 Material.call( this ); 19868 19869 this.type = 'MeshDistanceMaterial'; 19870 19871 this.referencePosition = new Vector3(); 19872 this.nearDistance = 1; 19873 this.farDistance = 1000; 19874 19875 this.skinning = false; 19876 this.morphTargets = false; 19877 19878 this.map = null; 19879 19880 this.alphaMap = null; 19881 19882 this.displacementMap = null; 19883 this.displacementScale = 1; 19884 this.displacementBias = 0; 19885 19886 this.fog = false; 19887 19888 this.setValues( parameters ); 19889 19890} 19891 19892MeshDistanceMaterial.prototype = Object.create( Material.prototype ); 19893MeshDistanceMaterial.prototype.constructor = MeshDistanceMaterial; 19894 19895MeshDistanceMaterial.prototype.isMeshDistanceMaterial = true; 19896 19897MeshDistanceMaterial.prototype.copy = function ( source ) { 19898 19899 Material.prototype.copy.call( this, source ); 19900 19901 this.referencePosition.copy( source.referencePosition ); 19902 this.nearDistance = source.nearDistance; 19903 this.farDistance = source.farDistance; 19904 19905 this.skinning = source.skinning; 19906 this.morphTargets = source.morphTargets; 19907 19908 this.map = source.map; 19909 19910 this.alphaMap = source.alphaMap; 19911 19912 this.displacementMap = source.displacementMap; 19913 this.displacementScale = source.displacementScale; 19914 this.displacementBias = source.displacementBias; 19915 19916 return this; 19917 19918}; 19919 19920var 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}"; 19921 19922var vsm_vert = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}"; 19923 19924/** 19925 * @author alteredq / http://alteredqualia.com/ 19926 * @author mrdoob / http://mrdoob.com/ 19927 */ 19928 19929function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { 19930 19931 var _frustum = new Frustum(), 19932 19933 _shadowMapSize = new Vector2(), 19934 _viewportSize = new Vector2(), 19935 19936 _viewport = new Vector4(), 19937 19938 _depthMaterials = [], 19939 _distanceMaterials = [], 19940 19941 _materialCache = {}; 19942 19943 var shadowSide = { 0: BackSide, 1: FrontSide, 2: DoubleSide }; 19944 19945 var shadowMaterialVertical = new ShaderMaterial( { 19946 19947 defines: { 19948 SAMPLE_RATE: 2.0 / 8.0, 19949 HALF_SAMPLE_RATE: 1.0 / 8.0 19950 }, 19951 19952 uniforms: { 19953 shadow_pass: { value: null }, 19954 resolution: { value: new Vector2() }, 19955 radius: { value: 4.0 } 19956 }, 19957 19958 vertexShader: vsm_vert, 19959 19960 fragmentShader: vsm_frag 19961 19962 } ); 19963 19964 var shadowMaterialHorizonal = shadowMaterialVertical.clone(); 19965 shadowMaterialHorizonal.defines.HORIZONAL_PASS = 1; 19966 19967 var fullScreenTri = new BufferGeometry(); 19968 fullScreenTri.setAttribute( 19969 "position", 19970 new BufferAttribute( 19971 new Float32Array( [ - 1, - 1, 0.5, 3, - 1, 0.5, - 1, 3, 0.5 ] ), 19972 3 19973 ) 19974 ); 19975 19976 var fullScreenMesh = new Mesh( fullScreenTri, shadowMaterialVertical ); 19977 19978 var scope = this; 19979 19980 this.enabled = false; 19981 19982 this.autoUpdate = true; 19983 this.needsUpdate = false; 19984 19985 this.type = PCFShadowMap; 19986 19987 this.render = function ( lights, scene, camera ) { 19988 19989 if ( scope.enabled === false ) return; 19990 if ( scope.autoUpdate === false && scope.needsUpdate === false ) return; 19991 19992 if ( lights.length === 0 ) return; 19993 19994 var currentRenderTarget = _renderer.getRenderTarget(); 19995 var activeCubeFace = _renderer.getActiveCubeFace(); 19996 var activeMipmapLevel = _renderer.getActiveMipmapLevel(); 19997 19998 var _state = _renderer.state; 19999 20000 // Set GL state for depth map. 20001 _state.setBlending( NoBlending ); 20002 _state.buffers.color.setClear( 1, 1, 1, 1 ); 20003 _state.buffers.depth.setTest( true ); 20004 _state.setScissorTest( false ); 20005 20006 // render depth map 20007 20008 for ( var i = 0, il = lights.length; i < il; i ++ ) { 20009 20010 var light = lights[ i ]; 20011 var shadow = light.shadow; 20012 20013 if ( shadow === undefined ) { 20014 20015 console.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' ); 20016 continue; 20017 20018 } 20019 20020 _shadowMapSize.copy( shadow.mapSize ); 20021 20022 var shadowFrameExtents = shadow.getFrameExtents(); 20023 20024 _shadowMapSize.multiply( shadowFrameExtents ); 20025 20026 _viewportSize.copy( shadow.mapSize ); 20027 20028 if ( _shadowMapSize.x > maxTextureSize || _shadowMapSize.y > maxTextureSize ) { 20029 20030 if ( _shadowMapSize.x > maxTextureSize ) { 20031 20032 _viewportSize.x = Math.floor( maxTextureSize / shadowFrameExtents.x ); 20033 _shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x; 20034 shadow.mapSize.x = _viewportSize.x; 20035 20036 } 20037 20038 if ( _shadowMapSize.y > maxTextureSize ) { 20039 20040 _viewportSize.y = Math.floor( maxTextureSize / shadowFrameExtents.y ); 20041 _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y; 20042 shadow.mapSize.y = _viewportSize.y; 20043 20044 } 20045 20046 } 20047 20048 if ( shadow.map === null && ! shadow.isPointLightShadow && this.type === VSMShadowMap ) { 20049 20050 var pars = { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat }; 20051 20052 shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); 20053 shadow.map.texture.name = light.name + ".shadowMap"; 20054 20055 shadow.mapPass = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); 20056 20057 shadow.camera.updateProjectionMatrix(); 20058 20059 } 20060 20061 if ( shadow.map === null ) { 20062 20063 var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat }; 20064 20065 shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); 20066 shadow.map.texture.name = light.name + ".shadowMap"; 20067 20068 shadow.camera.updateProjectionMatrix(); 20069 20070 } 20071 20072 _renderer.setRenderTarget( shadow.map ); 20073 _renderer.clear(); 20074 20075 var viewportCount = shadow.getViewportCount(); 20076 20077 for ( var vp = 0; vp < viewportCount; vp ++ ) { 20078 20079 var viewport = shadow.getViewport( vp ); 20080 20081 _viewport.set( 20082 _viewportSize.x * viewport.x, 20083 _viewportSize.y * viewport.y, 20084 _viewportSize.x * viewport.z, 20085 _viewportSize.y * viewport.w 20086 ); 20087 20088 _state.viewport( _viewport ); 20089 20090 shadow.updateMatrices( light, vp ); 20091 20092 _frustum = shadow.getFrustum(); 20093 20094 renderObject( scene, camera, shadow.camera, light, this.type ); 20095 20096 } 20097 20098 // do blur pass for VSM 20099 20100 if ( ! shadow.isPointLightShadow && this.type === VSMShadowMap ) { 20101 20102 VSMPass( shadow, camera ); 20103 20104 } 20105 20106 } 20107 20108 scope.needsUpdate = false; 20109 20110 _renderer.setRenderTarget( currentRenderTarget, activeCubeFace, activeMipmapLevel ); 20111 20112 }; 20113 20114 function VSMPass( shadow, camera ) { 20115 20116 var geometry = _objects.update( fullScreenMesh ); 20117 20118 // vertical pass 20119 20120 shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture; 20121 shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize; 20122 shadowMaterialVertical.uniforms.radius.value = shadow.radius; 20123 _renderer.setRenderTarget( shadow.mapPass ); 20124 _renderer.clear(); 20125 _renderer.renderBufferDirect( camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null ); 20126 20127 // horizonal pass 20128 20129 shadowMaterialHorizonal.uniforms.shadow_pass.value = shadow.mapPass.texture; 20130 shadowMaterialHorizonal.uniforms.resolution.value = shadow.mapSize; 20131 shadowMaterialHorizonal.uniforms.radius.value = shadow.radius; 20132 _renderer.setRenderTarget( shadow.map ); 20133 _renderer.clear(); 20134 _renderer.renderBufferDirect( camera, null, geometry, shadowMaterialHorizonal, fullScreenMesh, null ); 20135 20136 } 20137 20138 function getDepthMaterialVariant( useMorphing, useSkinning, useInstancing ) { 20139 20140 var index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2; 20141 20142 var material = _depthMaterials[ index ]; 20143 20144 if ( material === undefined ) { 20145 20146 material = new MeshDepthMaterial( { 20147 20148 depthPacking: RGBADepthPacking, 20149 20150 morphTargets: useMorphing, 20151 skinning: useSkinning 20152 20153 } ); 20154 20155 _depthMaterials[ index ] = material; 20156 20157 } 20158 20159 return material; 20160 20161 } 20162 20163 function getDistanceMaterialVariant( useMorphing, useSkinning, useInstancing ) { 20164 20165 var index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2; 20166 20167 var material = _distanceMaterials[ index ]; 20168 20169 if ( material === undefined ) { 20170 20171 material = new MeshDistanceMaterial( { 20172 20173 morphTargets: useMorphing, 20174 skinning: useSkinning 20175 20176 } ); 20177 20178 _distanceMaterials[ index ] = material; 20179 20180 } 20181 20182 return material; 20183 20184 } 20185 20186 function getDepthMaterial( object, geometry, material, light, shadowCameraNear, shadowCameraFar, type ) { 20187 20188 var result = null; 20189 20190 var getMaterialVariant = getDepthMaterialVariant; 20191 var customMaterial = object.customDepthMaterial; 20192 20193 if ( light.isPointLight === true ) { 20194 20195 getMaterialVariant = getDistanceMaterialVariant; 20196 customMaterial = object.customDistanceMaterial; 20197 20198 } 20199 20200 if ( customMaterial === undefined ) { 20201 20202 var useMorphing = false; 20203 20204 if ( material.morphTargets === true ) { 20205 20206 useMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0; 20207 20208 } 20209 20210 var useSkinning = false; 20211 20212 if ( object.isSkinnedMesh === true ) { 20213 20214 if ( material.skinning === true ) { 20215 20216 useSkinning = true; 20217 20218 } else { 20219 20220 console.warn( 'THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:', object ); 20221 20222 } 20223 20224 } 20225 20226 var useInstancing = object.isInstancedMesh === true; 20227 20228 result = getMaterialVariant( useMorphing, useSkinning, useInstancing ); 20229 20230 } else { 20231 20232 result = customMaterial; 20233 20234 } 20235 20236 if ( _renderer.localClippingEnabled &&
20237 material.clipShadows === true && 20238 material.clippingPlanes.length !== 0 ) { 20239 20240 // in this case we need a unique material instance reflecting the 20241 // appropriate state 20242 20243 var keyA = result.uuid, keyB = material.uuid; 20244 20245 var materialsForVariant = _materialCache[ keyA ]; 20246 20247 if ( materialsForVariant === undefined ) { 20248 20249 materialsForVariant = {}; 20250 _materialCache[ keyA ] = materialsForVariant; 20251 20252 } 20253 20254 var cachedMaterial = materialsForVariant[ keyB ]; 20255 20256 if ( cachedMaterial === undefined ) { 20257 20258 cachedMaterial = result.clone(); 20259 materialsForVariant[ keyB ] = cachedMaterial; 20260 20261 } 20262 20263 result = cachedMaterial; 20264 20265 } 20266 20267 result.visible = material.visible; 20268 result.wireframe = material.wireframe; 20269 20270 if ( type === VSMShadowMap ) { 20271 20272 result.side = ( material.shadowSide !== null ) ? material.shadowSide : material.side; 20273 20274 } else { 20275 20276 result.side = ( material.shadowSide !== null ) ? material.shadowSide : shadowSide[ material.side ]; 20277 20278 } 20279 20280 result.clipShadows = material.clipShadows; 20281 result.clippingPlanes = material.clippingPlanes; 20282 result.clipIntersection = material.clipIntersection; 20283 20284 result.wireframeLinewidth = material.wireframeLinewidth; 20285 result.linewidth = material.linewidth; 20286 20287 if ( light.isPointLight === true && result.isMeshDistanceMaterial === true ) { 20288 20289 result.referencePosition.setFromMatrixPosition( light.matrixWorld ); 20290 result.nearDistance = shadowCameraNear; 20291 result.farDistance = shadowCameraFar; 20292 20293 } 20294 20295 return result; 20296 20297 } 20298 20299 function renderObject( object, camera, shadowCamera, light, type ) { 20300 20301 if ( object.visible === false ) return; 20302 20303 var visible = object.layers.test( camera.layers ); 20304 20305 if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) { 20306 20307 if ( ( object.castShadow || ( object.receiveShadow && type === VSMShadowMap ) ) && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) { 20308 20309 object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld ); 20310 20311 var geometry = _objects.update( object ); 20312 var material = object.material; 20313 20314 if ( Array.isArray( material ) ) { 20315 20316 var groups = geometry.groups; 20317 20318 for ( var k = 0, kl = groups.length; k < kl; k ++ ) { 20319 20320 var group = groups[ k ]; 20321 var groupMaterial = material[ group.materialIndex ]; 20322 20323 if ( groupMaterial && groupMaterial.visible ) { 20324 20325 var depthMaterial = getDepthMaterial( object, geometry, groupMaterial, light, shadowCamera.near, shadowCamera.far, type ); 20326 20327 _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group ); 20328 20329 } 20330 20331 } 20332 20333 } else if ( material.visible ) { 20334 20335 var depthMaterial = getDepthMaterial( object, geometry, material, light, shadowCamera.near, shadowCamera.far, type ); 20336 20337 _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null ); 20338 20339 } 20340 20341 } 20342 20343 } 20344 20345 var children = object.children; 20346 20347 for ( var i = 0, l = children.length; i < l; i ++ ) { 20348 20349 renderObject( children[ i ], camera, shadowCamera, light, type ); 20350 20351 } 20352 20353 } 20354 20355} 20356 20357/** 20358 * @author mrdoob / http://mrdoob.com/ 20359 */ 20360 20361function WebGLState( gl, extensions, capabilities ) { 20362 20363 var isWebGL2 = capabilities.isWebGL2; 20364 20365 function ColorBuffer() { 20366 20367 var locked = false; 20368 20369 var color = new Vector4(); 20370 var currentColorMask = null; 20371 var currentColorClear = new Vector4( 0, 0, 0, 0 ); 20372 20373 return { 20374 20375 setMask: function ( colorMask ) { 20376 20377 if ( currentColorMask !== colorMask && ! locked ) { 20378 20379 gl.colorMask( colorMask, colorMask, colorMask, colorMask ); 20380 currentColorMask = colorMask; 20381 20382 } 20383 20384 }, 20385 20386 setLocked: function ( lock ) { 20387 20388 locked = lock; 20389 20390 }, 20391 20392 setClear: function ( r, g, b, a, premultipliedAlpha ) { 20393 20394 if ( premultipliedAlpha === true ) { 20395 20396 r *= a; g *= a; b *= a; 20397 20398 } 20399 20400 color.set( r, g, b, a ); 20401 20402 if ( currentColorClear.equals( color ) === false ) { 20403 20404 gl.clearColor( r, g, b, a ); 20405 currentColorClear.copy( color ); 20406 20407 } 20408 20409 }, 20410 20411 reset: function () { 20412 20413 locked = false; 20414 20415 currentColorMask = null; 20416 currentColorClear.set( - 1, 0, 0, 0 ); // set to invalid state 20417 20418 } 20419 20420 }; 20421 20422 } 20423 20424 function DepthBuffer() { 20425 20426 var locked = false;
20427 20428 var currentDepthMask = null; 20429 var currentDepthFunc = null; 20430 var currentDepthClear = null; 20431 20432 return { 20433 20434 setTest: function ( depthTest ) { 20435 20436 if ( depthTest ) { 20437 20438 enable( 2929 ); 20439 20440 } else { 20441 20442 disable( 2929 ); 20443 20444 } 20445 20446 }, 20447 20448 setMask: function ( depthMask ) { 20449 20450 if ( currentDepthMask !== depthMask && ! locked ) { 20451 20452 gl.depthMask( depthMask ); 20453 currentDepthMask = depthMask; 20454 20455 } 20456 20457 }, 20458 20459 setFunc: function ( depthFunc ) { 20460 20461 if ( currentDepthFunc !== depthFunc ) { 20462 20463 if ( depthFunc ) { 20464 20465 switch ( depthFunc ) { 20466 20467 case NeverDepth: 20468 20469 gl.depthFunc( 512 ); 20470 break; 20471 20472 case AlwaysDepth: 20473 20474 gl.depthFunc( 519 ); 20475 break; 20476 20477 case LessDepth: 20478 20479 gl.depthFunc( 513 ); 20480 break; 20481 20482 case LessEqualDepth: 20483 20484 gl.depthFunc( 515 ); 20485 break; 20486 20487 case EqualDepth: 20488 20489 gl.depthFunc( 514 ); 20490 break; 20491 20492 case GreaterEqualDepth: 20493 20494 gl.depthFunc( 518 ); 20495 break; 20496 20497 case GreaterDepth: 20498 20499 gl.depthFunc( 516 ); 20500 break; 20501 20502 case NotEqualDepth: 20503 20504 gl.depthFunc( 517 ); 20505 break; 20506 20507 default: 20508 20509 gl.depthFunc( 515 ); 20510 20511 } 20512 20513 } else { 20514 20515 gl.depthFunc( 515 ); 20516 20517 } 20518 20519 currentDepthFunc = depthFunc; 20520 20521 } 20522 20523 }, 20524 20525 setLocked: function ( lock ) { 20526 20527 locked = lock; 20528 20529 }, 20530 20531 setClear: function ( depth ) { 20532 20533 if ( currentDepthClear !== depth ) { 20534 20535 gl.clearDepth( depth ); 20536 currentDepthClear = depth; 20537 20538 } 20539 20540 }, 20541 20542 reset: function () { 20543 20544 locked = false; 20545 20546 currentDepthMask = null; 20547 currentDepthFunc = null; 20548 currentDepthClear = null; 20549 20550 } 20551 20552 }; 20553 20554 } 20555 20556 function StencilBuffer() { 20557 20558 var locked = false; 20559 20560 var currentStencilMask = null; 20561 var currentStencilFunc = null; 20562 var currentStencilRef = null; 20563 var currentStencilFuncMask = null; 20564 var currentStencilFail = null; 20565 var currentStencilZFail = null; 20566 var currentStencilZPass = null; 20567 var currentStencilClear = null; 20568 20569 return { 20570 20571 setTest: function ( stencilTest ) { 20572 20573 if ( ! locked ) { 20574 20575 if ( stencilTest ) { 20576 20577 enable( 2960 ); 20578 20579 } else { 20580 20581 disable( 2960 ); 20582 20583 } 20584 20585 } 20586 20587 }, 20588 20589 setMask: function ( stencilMask ) { 20590 20591 if ( currentStencilMask !== stencilMask && ! locked ) { 20592 20593 gl.stencilMask( stencilMask ); 20594 currentStencilMask = stencilMask; 20595 20596 } 20597 20598 }, 20599 20600 setFunc: function ( stencilFunc, stencilRef, stencilMask ) { 20601 20602 if ( currentStencilFunc !== stencilFunc || 20603 currentStencilRef !== stencilRef || 20604 currentStencilFuncMask !== stencilMask ) { 20605 20606 gl.stencilFunc( stencilFunc, stencilRef, stencilMask ); 20607 20608 currentStencilFunc = stencilFunc; 20609 currentStencilRef = stencilRef; 20610 currentStencilFuncMask = stencilMask; 20611 20612 } 20613 20614 }, 20615 20616 setOp: function ( stencilFail, stencilZFail, stencilZPass ) { 20617 20618 if ( currentStencilFail !== stencilFail || 20619 currentStencilZFail !== stencilZFail || 20620 currentStencilZPass !== stencilZPass ) { 20621 20622 gl.stencilOp( stencilFail, stencilZFail, stencilZPass ); 20623 20624 currentStencilFail = stencilFail; 20625 currentStencilZFail = stencilZFail; 20626 currentStencilZPass = stencilZPass; 20627 20628 } 20629 20630 }, 20631 20632 setLocked: function ( lock ) { 20633 20634 locked = lock; 20635 20636 }, 20637 20638 setClear: function ( stencil ) { 20639 20640 if ( currentStencilClear !== stencil ) { 20641 20642 gl.clearStencil( stencil ); 20643 currentStencilClear = stencil; 20644 20645 } 20646 20647 }, 20648 20649 reset: function () { 20650 20651 locked = false; 20652 20653 currentStencilMask = null; 20654 currentStencilFunc = null; 20655 currentStencilRef = null; 20656 currentStencilFuncMask = null; 20657 currentStencilFail = null; 20658 currentStencilZFail = null; 20659 currentStencilZPass = null; 20660 currentStencilClear = null; 20661 20662 } 20663 20664 }; 20665 20666 } 20667 20668 // 20669 20670 var colorBuffer = new ColorBuffer(); 20671 var depthBuffer = new DepthBuffer(); 20672 var stencilBuffer = new StencilBuffer(); 20673 20674 var maxVertexAttributes = gl.getParameter( 34921 ); 20675 var newAttributes = new Uint8Array( maxVertexAttributes ); 20676 var enabledAttributes = new Uint8Array( maxVertexAttributes ); 20677 var attributeDivisors = new Uint8Array( maxVertexAttributes ); 20678 20679 var enabledCapabilities = {}; 20680 20681 var currentProgram = null; 20682 20683 var currentBlendingEnabled = null; 20684 var currentBlending = null; 20685 var currentBlendEquation = null; 20686 var currentBlendSrc = null; 20687 var currentBlendDst = null; 20688 var currentBlendEquationAlpha = null; 20689 var currentBlendSrcAlpha = null; 20690 var currentBlendDstAlpha = null; 20691 var currentPremultipledAlpha = false;
20692 20693 var currentFlipSided = null; 20694 var currentCullFace = null; 20695 20696 var currentLineWidth = null; 20697 20698 var currentPolygonOffsetFactor = null; 20699 var currentPolygonOffsetUnits = null; 20700 20701 var maxTextures = gl.getParameter( 35661 ); 20702 20703 var lineWidthAvailable = false; 20704 var version = 0; 20705 var glVersion = gl.getParameter( 7938 ); 20706 20707 if ( glVersion.indexOf( 'WebGL' ) !== - 1 ) { 20708 20709 version = parseFloat( /^WebGL\ ([0-9])/.exec( glVersion )[ 1 ] ); 20710 lineWidthAvailable = ( version >= 1.0 ); 20711 20712 } else if ( glVersion.indexOf( 'OpenGL ES' ) !== - 1 ) { 20713 20714 version = parseFloat( /^OpenGL\ ES\ ([0-9])/.exec( glVersion )[ 1 ] ); 20715 lineWidthAvailable = ( version >= 2.0 ); 20716 20717 } 20718 20719 var currentTextureSlot = null; 20720 var currentBoundTextures = {}; 20721 20722 var currentScissor = new Vector4(); 20723 var currentViewport = new Vector4(); 20724 20725 function createTexture( type, target, count ) { 20726 20727 var data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4. 20728 var texture = gl.createTexture(); 20729 20730 gl.bindTexture( type, texture ); 20731 gl.texParameteri( type, 10241, 9728 ); 20732 gl.texParameteri( type, 10240, 9728 ); 20733 20734 for ( var i = 0; i < count; i ++ ) { 20735 20736 gl.texImage2D( target + i, 0, 6408, 1, 1, 0, 6408, 5121, data ); 20737 20738 } 20739 20740 return texture; 20741 20742 } 20743 20744 var emptyTextures = {}; 20745 emptyTextures[ 3553 ] = createTexture( 3553, 3553, 1 ); 20746 emptyTextures[ 34067 ] = createTexture( 34067, 34069, 6 ); 20747 20748 // init 20749 20750 colorBuffer.setClear( 0, 0, 0, 1 ); 20751 depthBuffer.setClear( 1 ); 20752 stencilBuffer.setClear( 0 ); 20753 20754 enable( 2929 ); 20755 depthBuffer.setFunc( LessEqualDepth ); 20756 20757 setFlipSided( false ); 20758 setCullFace( CullFaceBack ); 20759 enable( 2884 ); 20760 20761 setBlending( NoBlending ); 20762 20763 // 20764 20765 function initAttributes() { 20766 20767 for ( var i = 0, l = newAttributes.length; i < l; i ++ ) { 20768 20769 newAttributes[ i ] = 0; 20770 20771 } 20772 20773 } 20774 20775 function enableAttribute( attribute ) { 20776 20777 enableAttributeAndDivisor( attribute, 0 ); 20778 20779 } 20780 20781 function enableAttributeAndDivisor( attribute, meshPerAttribute ) { 20782 20783 newAttributes[ attribute ] = 1; 20784 20785 if ( enabledAttributes[ attribute ] === 0 ) { 20786 20787 gl.enableVertexAttribArray( attribute ); 20788 enabledAttributes[ attribute ] = 1; 20789 20790 } 20791 20792 if ( attributeDivisors[ attribute ] !== meshPerAttribute ) { 20793 20794 var extension = isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' ); 20795 20796 extension[ isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute ); 20797 attributeDivisors[ attribute ] = meshPerAttribute; 20798 20799 } 20800 20801 } 20802 20803 function disableUnusedAttributes() { 20804 20805 for ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) { 20806 20807 if ( enabledAttributes[ i ] !== newAttributes[ i ] ) { 20808 20809 gl.disableVertexAttribArray( i ); 20810 enabledAttributes[ i ] = 0; 20811 20812 } 20813 20814 } 20815 20816 } 20817 20818 function vertexAttribPointer( index, size, type, normalized, stride, offset ) { 20819 20820 if ( isWebGL2 === true && ( type === 5124 || type === 5125 ) ) { 20821 20822 gl.vertexAttribIPointer( index, size, type, normalized, stride, offset ); 20823 20824 } else { 20825 20826 gl.vertexAttribPointer( index, size, type, normalized, stride, offset ); 20827 20828 } 20829 20830 } 20831 20832 function enable( id ) { 20833 20834 if ( enabledCapabilities[ id ] !== true ) { 20835 20836 gl.enable( id ); 20837 enabledCapabilities[ id ] = true; 20838 20839 } 20840 20841 } 20842 20843 function disable( id ) { 20844 20845 if ( enabledCapabilities[ id ] !== false ) { 20846 20847 gl.disable( id ); 20848 enabledCapabilities[ id ] = false; 20849 20850 } 20851 20852 } 20853 20854 function useProgram( program ) { 20855 20856 if ( currentProgram !== program ) { 20857 20858 gl.useProgram( program ); 20859 20860 currentProgram = program; 20861 20862 return true; 20863 20864 } 20865 20866 return false; 20867 20868 } 20869 20870 var equationToGL = { 20871 [ AddEquation ]: 32774, 20872 [ SubtractEquation ]: 32778, 20873 [ ReverseSubtractEquation ]: 32779 20874 }; 20875 20876 if ( isWebGL2 ) { 20877 20878 equationToGL[ MinEquation ] = 32775; 20879 equationToGL[ MaxEquation ] = 32776; 20880 20881 } else { 20882 20883 var extension = extensions.get( 'EXT_blend_minmax' ); 20884 20885 if ( extension !== null ) { 20886 20887 equationToGL[ MinEquation ] = extension.MIN_EXT; 20888 equationToGL[ MaxEquation ] = extension.MAX_EXT; 20889 20890 } 20891 20892 } 20893 20894 var factorToGL = { 20895 [ ZeroFactor ]: 0, 20896 [ OneFactor ]: 1, 20897 [ SrcColorFactor ]: 768, 20898 [ SrcAlphaFactor ]: 770, 20899 [ SrcAlphaSaturateFactor ]: 776, 20900 [ DstColorFactor ]: 774, 20901 [ DstAlphaFactor ]: 772, 20902 [ OneMinusSrcColorFactor ]: 769, 20903 [ OneMinusSrcAlphaFactor ]: 771, 20904 [ OneMinusDstColorFactor ]: 775, 20905 [ OneMinusDstAlphaFactor ]: 773 20906 }; 20907 20908 function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) { 20909 20910 if ( blending === NoBlending ) { 20911 20912 if ( currentBlendingEnabled ) { 20913 20914 disable( 3042 ); 20915 currentBlendingEnabled = false;
vendor: 62,457 bytes, lines 20916-23546
20916 20917 } 20918 20919 return; 20920 20921 } 20922 20923 if ( ! currentBlendingEnabled ) { 20924 20925 enable( 3042 ); 20926 currentBlendingEnabled = true; 20927 20928 } 20929 20930 if ( blending !== CustomBlending ) { 20931 20932 if ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) { 20933 20934 if ( currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation ) { 20935 20936 gl.blendEquation( 32774 ); 20937 20938 currentBlendEquation = AddEquation; 20939 currentBlendEquationAlpha = AddEquation; 20940 20941 } 20942 20943 if ( premultipliedAlpha ) { 20944 20945 switch ( blending ) { 20946 20947 case NormalBlending: 20948 gl.blendFuncSeparate( 1, 771, 1, 771 ); 20949 break; 20950 20951 case AdditiveBlending: 20952 gl.blendFunc( 1, 1 ); 20953 break; 20954 20955 case SubtractiveBlending: 20956 gl.blendFuncSeparate( 0, 0, 769, 771 ); 20957 break; 20958 20959 case MultiplyBlending: 20960 gl.blendFuncSeparate( 0, 768, 0, 770 ); 20961 break; 20962 20963 default: 20964 console.error( 'THREE.WebGLState: Invalid blending: ', blending ); 20965 break; 20966 20967 } 20968 20969 } else { 20970 20971 switch ( blending ) { 20972 20973 case NormalBlending: 20974 gl.blendFuncSeparate( 770, 771, 1, 771 ); 20975 break; 20976 20977 case AdditiveBlending: 20978 gl.blendFunc( 770, 1 ); 20979 break; 20980 20981 case SubtractiveBlending: 20982 gl.blendFunc( 0, 769 ); 20983 break; 20984 20985 case MultiplyBlending: 20986 gl.blendFunc( 0, 768 ); 20987 break; 20988 20989 default: 20990 console.error( 'THREE.WebGLState: Invalid blending: ', blending ); 20991 break; 20992 20993 } 20994 20995 } 20996 20997 currentBlendSrc = null; 20998 currentBlendDst = null; 20999 currentBlendSrcAlpha = null; 21000 currentBlendDstAlpha = null; 21001 21002 currentBlending = blending; 21003 currentPremultipledAlpha = premultipliedAlpha; 21004 21005 } 21006 21007 return; 21008 21009 } 21010 21011 // custom blending 21012 21013 blendEquationAlpha = blendEquationAlpha || blendEquation; 21014 blendSrcAlpha = blendSrcAlpha || blendSrc; 21015 blendDstAlpha = blendDstAlpha || blendDst; 21016 21017 if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) { 21018 21019 gl.blendEquationSeparate( equationToGL[ blendEquation ], equationToGL[ blendEquationAlpha ] ); 21020 21021 currentBlendEquation = blendEquation; 21022 currentBlendEquationAlpha = blendEquationAlpha; 21023 21024 } 21025 21026 if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) { 21027 21028 gl.blendFuncSeparate( factorToGL[ blendSrc ], factorToGL[ blendDst ], factorToGL[ blendSrcAlpha ], factorToGL[ blendDstAlpha ] ); 21029 21030 currentBlendSrc = blendSrc; 21031 currentBlendDst = blendDst; 21032 currentBlendSrcAlpha = blendSrcAlpha; 21033 currentBlendDstAlpha = blendDstAlpha; 21034 21035 } 21036 21037 currentBlending = blending; 21038 currentPremultipledAlpha = null; 21039 21040 } 21041 21042 function setMaterial( material, frontFaceCW ) { 21043 21044 material.side === DoubleSide 21045 ? disable( 2884 ) 21046 : enable( 2884 ); 21047 21048 var flipSided = ( material.side === BackSide ); 21049 if ( frontFaceCW ) flipSided = ! flipSided; 21050 21051 setFlipSided( flipSided ); 21052 21053 ( material.blending === NormalBlending && material.transparent === false ) 21054 ? setBlending( NoBlending ) 21055 : setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha ); 21056 21057 depthBuffer.setFunc( material.depthFunc ); 21058 depthBuffer.setTest( material.depthTest ); 21059 depthBuffer.setMask( material.depthWrite ); 21060 colorBuffer.setMask( material.colorWrite ); 21061 21062 var stencilWrite = material.stencilWrite; 21063 stencilBuffer.setTest( stencilWrite ); 21064 if ( stencilWrite ) { 21065 21066 stencilBuffer.setMask( material.stencilWriteMask ); 21067 stencilBuffer.setFunc( material.stencilFunc, material.stencilRef, material.stencilFuncMask ); 21068 stencilBuffer.setOp( material.stencilFail, material.stencilZFail, material.stencilZPass ); 21069 21070 } 21071 21072 setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); 21073 21074 } 21075 21076 // 21077 21078 function setFlipSided( flipSided ) { 21079 21080 if ( currentFlipSided !== flipSided ) { 21081 21082 if ( flipSided ) { 21083 21084 gl.frontFace( 2304 ); 21085 21086 } else { 21087 21088 gl.frontFace( 2305 ); 21089 21090 } 21091 21092 currentFlipSided = flipSided; 21093 21094 } 21095 21096 } 21097 21098 function setCullFace( cullFace ) { 21099 21100 if ( cullFace !== CullFaceNone ) { 21101 21102 enable( 2884 ); 21103 21104 if ( cullFace !== currentCullFace ) { 21105 21106 if ( cullFace === CullFaceBack ) { 21107 21108 gl.cullFace( 1029 ); 21109 21110 } else if ( cullFace === CullFaceFront ) { 21111 21112 gl.cullFace( 1028 ); 21113 21114 } else { 21115 21116 gl.cullFace( 1032 ); 21117 21118 } 21119 21120 } 21121 21122 } else { 21123 21124 disable( 2884 ); 21125 21126 } 21127 21128 currentCullFace = cullFace; 21129 21130 } 21131 21132 function setLineWidth( width ) { 21133 21134 if ( width !== currentLineWidth ) { 21135 21136 if ( lineWidthAvailable ) gl.lineWidth( width ); 21137 21138 currentLineWidth = width; 21139 21140 } 21141 21142 } 21143 21144 function setPolygonOffset( polygonOffset, factor, units ) { 21145 21146 if ( polygonOffset ) { 21147 21148 enable( 32823 ); 21149 21150 if ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) { 21151 21152 gl.polygonOffset( factor, units ); 21153 21154 currentPolygonOffsetFactor = factor; 21155 currentPolygonOffsetUnits = units; 21156 21157 } 21158 21159 } else { 21160 21161 disable( 32823 ); 21162 21163 } 21164 21165 } 21166 21167 function setScissorTest( scissorTest ) { 21168 21169 if ( scissorTest ) { 21170 21171 enable( 3089 ); 21172 21173 } else { 21174 21175 disable( 3089 ); 21176 21177 } 21178 21179 } 21180 21181 // texture 21182 21183 function activeTexture( webglSlot ) { 21184 21185 if ( webglSlot === undefined ) webglSlot = 33984 + maxTextures - 1; 21186 21187 if ( currentTextureSlot !== webglSlot ) { 21188 21189 gl.activeTexture( webglSlot ); 21190 currentTextureSlot = webglSlot; 21191 21192 } 21193 21194 } 21195 21196 function bindTexture( webglType, webglTexture ) { 21197 21198 if ( currentTextureSlot === null ) { 21199 21200 activeTexture(); 21201 21202 } 21203 21204 var boundTexture = currentBoundTextures[ currentTextureSlot ]; 21205 21206 if ( boundTexture === undefined ) { 21207 21208 boundTexture = { type: undefined, texture: undefined }; 21209 currentBoundTextures[ currentTextureSlot ] = boundTexture; 21210 21211 } 21212 21213 if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) { 21214 21215 gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] ); 21216 21217 boundTexture.type = webglType; 21218 boundTexture.texture = webglTexture; 21219 21220 } 21221 21222 } 21223 21224 function unbindTexture() { 21225 21226 var boundTexture = currentBoundTextures[ currentTextureSlot ]; 21227 21228 if ( boundTexture !== undefined && boundTexture.type !== undefined ) { 21229 21230 gl.bindTexture( boundTexture.type, null ); 21231 21232 boundTexture.type = undefined; 21233 boundTexture.texture = undefined; 21234 21235 } 21236 21237 } 21238 21239 function compressedTexImage2D() { 21240 21241 try { 21242 21243 gl.compressedTexImage2D.apply( gl, arguments ); 21244 21245 } catch ( error ) { 21246 21247 console.error( 'THREE.WebGLState:', error ); 21248 21249 } 21250 21251 } 21252 21253 function texImage2D() { 21254 21255 try { 21256 21257 gl.texImage2D.apply( gl, arguments ); 21258 21259 } catch ( error ) { 21260 21261 console.error( 'THREE.WebGLState:', error ); 21262 21263 } 21264 21265 } 21266 21267 function texImage3D() { 21268 21269 try { 21270 21271 gl.texImage3D.apply( gl, arguments ); 21272 21273 } catch ( error ) { 21274 21275 console.error( 'THREE.WebGLState:', error ); 21276 21277 } 21278 21279 } 21280 21281 // 21282 21283 function scissor( scissor ) { 21284 21285 if ( currentScissor.equals( scissor ) === false ) { 21286 21287 gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w ); 21288 currentScissor.copy( scissor ); 21289 21290 } 21291 21292 } 21293 21294 function viewport( viewport ) { 21295 21296 if ( currentViewport.equals( viewport ) === false ) { 21297 21298 gl.viewport( viewport.x, viewport.y, viewport.z, viewport.w ); 21299 currentViewport.copy( viewport ); 21300 21301 } 21302 21303 } 21304 21305 // 21306 21307 function reset() { 21308 21309 for ( var i = 0; i < enabledAttributes.length; i ++ ) { 21310 21311 if ( enabledAttributes[ i ] === 1 ) { 21312 21313 gl.disableVertexAttribArray( i ); 21314 enabledAttributes[ i ] = 0; 21315 21316 } 21317 21318 } 21319 21320 enabledCapabilities = {}; 21321 21322 currentTextureSlot = null; 21323 currentBoundTextures = {}; 21324 21325 currentProgram = null; 21326 21327 currentBlending = null; 21328 21329 currentFlipSided = null; 21330 currentCullFace = null; 21331 21332 colorBuffer.reset(); 21333 depthBuffer.reset(); 21334 stencilBuffer.reset(); 21335 21336 } 21337 21338 return { 21339 21340 buffers: { 21341 color: colorBuffer, 21342 depth: depthBuffer, 21343 stencil: stencilBuffer 21344 }, 21345 21346 initAttributes: initAttributes, 21347 enableAttribute: enableAttribute, 21348 enableAttributeAndDivisor: enableAttributeAndDivisor, 21349 disableUnusedAttributes: disableUnusedAttributes, 21350 vertexAttribPointer: vertexAttribPointer, 21351 enable: enable, 21352 disable: disable, 21353 21354 useProgram: useProgram, 21355 21356 setBlending: setBlending, 21357 setMaterial: setMaterial, 21358 21359 setFlipSided: setFlipSided, 21360 setCullFace: setCullFace, 21361 21362 setLineWidth: setLineWidth, 21363 setPolygonOffset: setPolygonOffset, 21364 21365 setScissorTest: setScissorTest, 21366 21367 activeTexture: activeTexture, 21368 bindTexture: bindTexture, 21369 unbindTexture: unbindTexture, 21370 compressedTexImage2D: compressedTexImage2D, 21371 texImage2D: texImage2D, 21372 texImage3D: texImage3D, 21373 21374 scissor: scissor, 21375 viewport: viewport, 21376 21377 reset: reset 21378 21379 }; 21380 21381} 21382 21383/** 21384 * @author mrdoob / http://mrdoob.com/ 21385 */ 21386 21387function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) { 21388 21389 var isWebGL2 = capabilities.isWebGL2; 21390 var maxTextures = capabilities.maxTextures; 21391 var maxCubemapSize = capabilities.maxCubemapSize; 21392 var maxTextureSize = capabilities.maxTextureSize; 21393 var maxSamples = capabilities.maxSamples; 21394 21395 var _videoTextures = new WeakMap(); 21396 var _canvas; 21397 21398 // cordova iOS (as of 5.0) still uses UIWebView, which provides OffscreenCanvas, 21399 // also OffscreenCanvas.getContext("webgl"), but not OffscreenCanvas.getContext("2d")! 21400 // Some implementations may only implement OffscreenCanvas partially (e.g. lacking 2d). 21401 21402 var useOffscreenCanvas = false; 21403 21404 try { 21405 21406 useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' 21407 && ( new OffscreenCanvas( 1, 1 ).getContext( "2d" ) ) !== null; 21408 21409 } catch ( err ) { 21410 21411 // Ignore any errors 21412 21413 } 21414 21415 function createCanvas( width, height ) { 21416 21417 // Use OffscreenCanvas when available. Specially needed in web workers 21418 21419 return useOffscreenCanvas ? 21420 new OffscreenCanvas( width, height ) : 21421 document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); 21422 21423 } 21424 21425 function resizeImage( image, needsPowerOfTwo, needsNewCanvas, maxSize ) { 21426 21427 var scale = 1; 21428 21429 // handle case if texture exceeds max size 21430 21431 if ( image.width > maxSize || image.height > maxSize ) { 21432 21433 scale = maxSize / Math.max( image.width, image.height ); 21434 21435 } 21436 21437 // only perform resize if necessary 21438 21439 if ( scale < 1 || needsPowerOfTwo === true ) { 21440 21441 // only perform resize for certain image types 21442 21443 if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) || 21444 ( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) || 21445 ( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) { 21446 21447 var floor = needsPowerOfTwo ? MathUtils.floorPowerOfTwo : Math.floor; 21448 21449 var width = floor( scale * image.width ); 21450 var height = floor( scale * image.height ); 21451 21452 if ( _canvas === undefined ) _canvas = createCanvas( width, height ); 21453 21454 // cube textures can't reuse the same canvas 21455 21456 var canvas = needsNewCanvas ? createCanvas( width, height ) : _canvas; 21457 21458 canvas.width = width; 21459 canvas.height = height; 21460 21461 var context = canvas.getContext( '2d' ); 21462 context.drawImage( image, 0, 0, width, height ); 21463 21464 console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').' ); 21465 21466 return canvas; 21467 21468 } else { 21469 21470 if ( 'data' in image ) { 21471 21472 console.warn( 'THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').' ); 21473 21474 } 21475 21476 return image; 21477 21478 } 21479 21480 } 21481 21482 return image; 21483 21484 } 21485 21486 function isPowerOfTwo( image ) { 21487 21488 return MathUtils.isPowerOfTwo( image.width ) && MathUtils.isPowerOfTwo( image.height ); 21489 21490 } 21491 21492 function textureNeedsPowerOfTwo( texture ) { 21493 21494 if ( isWebGL2 ) return false; 21495 21496 return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) || 21497 ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ); 21498 21499 } 21500 21501 function textureNeedsGenerateMipmaps( texture, supportsMips ) { 21502 21503 return texture.generateMipmaps && supportsMips && 21504 texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; 21505 21506 } 21507 21508 function generateMipmap( target, texture, width, height ) { 21509 21510 _gl.generateMipmap( target ); 21511 21512 var textureProperties = properties.get( texture ); 21513 21514 // Note: Math.log( x ) * Math.LOG2E used instead of Math.log2( x ) which is not supported by IE11 21515 textureProperties.__maxMipLevel = Math.log( Math.max( width, height ) ) * Math.LOG2E; 21516 21517 } 21518 21519 function getInternalFormat( internalFormatName, glFormat, glType ) { 21520 21521 if ( isWebGL2 === false ) return glFormat; 21522 21523 if ( internalFormatName !== null ) { 21524 21525 if ( _gl[ internalFormatName ] !== undefined ) return _gl[ internalFormatName ]; 21526 21527 console.warn( 'THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\'' ); 21528 21529 } 21530 21531 var internalFormat = glFormat; 21532 21533 if ( glFormat === 6403 ) { 21534 21535 if ( glType === 5126 ) internalFormat = 33326; 21536 if ( glType === 5131 ) internalFormat = 33325; 21537 if ( glType === 5121 ) internalFormat = 33321; 21538 21539 } 21540 21541 if ( glFormat === 6407 ) { 21542 21543 if ( glType === 5126 ) internalFormat = 34837; 21544 if ( glType === 5131 ) internalFormat = 34843; 21545 if ( glType === 5121 ) internalFormat = 32849; 21546 21547 } 21548 21549 if ( glFormat === 6408 ) { 21550 21551 if ( glType === 5126 ) internalFormat = 34836; 21552 if ( glType === 5131 ) internalFormat = 34842; 21553 if ( glType === 5121 ) internalFormat = 32856; 21554 21555 } 21556 21557 if ( internalFormat === 33325 || internalFormat === 33326 || 21558 internalFormat === 34842 || internalFormat === 34836 ) { 21559 21560 extensions.get( 'EXT_color_buffer_float' ); 21561 21562 } 21563 21564 return internalFormat; 21565 21566 } 21567 21568 // Fallback filters for non-power-of-2 textures 21569 21570 function filterFallback( f ) { 21571 21572 if ( f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter ) { 21573 21574 return 9728; 21575 21576 } 21577 21578 return 9729; 21579 21580 } 21581 21582 // 21583 21584 function onTextureDispose( event ) { 21585 21586 var texture = event.target; 21587 21588 texture.removeEventListener( 'dispose', onTextureDispose ); 21589 21590 deallocateTexture( texture ); 21591 21592 if ( texture.isVideoTexture ) { 21593 21594 _videoTextures.delete( texture ); 21595 21596 } 21597 21598 info.memory.textures --; 21599 21600 } 21601 21602 function onRenderTargetDispose( event ) { 21603 21604 var renderTarget = event.target; 21605 21606 renderTarget.removeEventListener( 'dispose', onRenderTargetDispose ); 21607 21608 deallocateRenderTarget( renderTarget ); 21609 21610 info.memory.textures --; 21611 21612 } 21613 21614 // 21615 21616 function deallocateTexture( texture ) { 21617 21618 var textureProperties = properties.get( texture ); 21619 21620 if ( textureProperties.__webglInit === undefined ) return; 21621 21622 _gl.deleteTexture( textureProperties.__webglTexture ); 21623 21624 properties.remove( texture ); 21625 21626 } 21627 21628 function deallocateRenderTarget( renderTarget ) { 21629 21630 var renderTargetProperties = properties.get( renderTarget ); 21631 var textureProperties = properties.get( renderTarget.texture ); 21632 21633 if ( ! renderTarget ) return; 21634 21635 if ( textureProperties.__webglTexture !== undefined ) { 21636 21637 _gl.deleteTexture( textureProperties.__webglTexture ); 21638 21639 } 21640 21641 if ( renderTarget.depthTexture ) { 21642 21643 renderTarget.depthTexture.dispose(); 21644 21645 } 21646 21647 if ( renderTarget.isWebGLCubeRenderTarget ) { 21648 21649 for ( var i = 0; i < 6; i ++ ) { 21650 21651 _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] ); 21652 if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] ); 21653 21654 } 21655 21656 } else { 21657 21658 _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer ); 21659 if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer ); 21660 if ( renderTargetProperties.__webglMultisampledFramebuffer ) _gl.deleteFramebuffer( renderTargetProperties.__webglMultisampledFramebuffer ); 21661 if ( renderTargetProperties.__webglColorRenderbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglColorRenderbuffer ); 21662 if ( renderTargetProperties.__webglDepthRenderbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthRenderbuffer ); 21663 21664 } 21665 21666 properties.remove( renderTarget.texture ); 21667 properties.remove( renderTarget ); 21668 21669 } 21670 21671 // 21672 21673 var textureUnits = 0; 21674 21675 function resetTextureUnits() { 21676 21677 textureUnits = 0; 21678 21679 } 21680 21681 function allocateTextureUnit() { 21682 21683 var textureUnit = textureUnits; 21684 21685 if ( textureUnit >= maxTextures ) { 21686 21687 console.warn( 'THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures ); 21688 21689 } 21690 21691 textureUnits += 1; 21692 21693 return textureUnit; 21694 21695 } 21696 21697 // 21698 21699 function setTexture2D( texture, slot ) { 21700 21701 var textureProperties = properties.get( texture ); 21702 21703 if ( texture.isVideoTexture ) updateVideoTexture( texture ); 21704 21705 if ( texture.version > 0 && textureProperties.__version !== texture.version ) { 21706 21707 var image = texture.image; 21708 21709 if ( image === undefined ) { 21710 21711 console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined' ); 21712 21713 } else if ( image.complete === false ) { 21714 21715 console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete' ); 21716 21717 } else { 21718 21719 uploadTexture( textureProperties, texture, slot ); 21720 return; 21721 21722 } 21723 21724 } 21725 21726 state.activeTexture( 33984 + slot ); 21727 state.bindTexture( 3553, textureProperties.__webglTexture ); 21728 21729 } 21730 21731 function setTexture2DArray( texture, slot ) { 21732 21733 var textureProperties = properties.get( texture ); 21734 21735 if ( texture.version > 0 && textureProperties.__version !== texture.version ) { 21736 21737 uploadTexture( textureProperties, texture, slot ); 21738 return; 21739 21740 } 21741 21742 state.activeTexture( 33984 + slot ); 21743 state.bindTexture( 35866, textureProperties.__webglTexture ); 21744 21745 } 21746 21747 function setTexture3D( texture, slot ) { 21748 21749 var textureProperties = properties.get( texture ); 21750 21751 if ( texture.version > 0 && textureProperties.__version !== texture.version ) { 21752 21753 uploadTexture( textureProperties, texture, slot ); 21754 return; 21755 21756 } 21757 21758 state.activeTexture( 33984 + slot ); 21759 state.bindTexture( 32879, textureProperties.__webglTexture ); 21760 21761 } 21762 21763 function setTextureCube( texture, slot ) { 21764 21765 if ( texture.image.length !== 6 ) return; 21766 21767 var textureProperties = properties.get( texture ); 21768 21769 if ( texture.version > 0 && textureProperties.__version !== texture.version ) { 21770 21771 initTexture( textureProperties, texture ); 21772 21773 state.activeTexture( 33984 + slot ); 21774 state.bindTexture( 34067, textureProperties.__webglTexture ); 21775 21776 _gl.pixelStorei( 37440, texture.flipY ); 21777 21778 var isCompressed = ( texture && ( texture.isCompressedTexture || texture.image[ 0 ].isCompressedTexture ) ); 21779 var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture ); 21780 21781 var cubeImage = []; 21782 21783 for ( var i = 0; i < 6; i ++ ) { 21784 21785 if ( ! isCompressed && ! isDataTexture ) { 21786 21787 cubeImage[ i ] = resizeImage( texture.image[ i ], false, true, maxCubemapSize ); 21788 21789 } else { 21790 21791 cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ]; 21792 21793 } 21794 21795 } 21796 21797 var image = cubeImage[ 0 ], 21798 supportsMips = isPowerOfTwo( image ) || isWebGL2, 21799 glFormat = utils.convert( texture.format ), 21800 glType = utils.convert( texture.type ), 21801 glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType ); 21802 21803 setTextureParameters( 34067, texture, supportsMips ); 21804 21805 var mipmaps; 21806 21807 if ( isCompressed ) { 21808 21809 for ( var i = 0; i < 6; i ++ ) { 21810 21811 mipmaps = cubeImage[ i ].mipmaps; 21812 21813 for ( var j = 0; j < mipmaps.length; j ++ ) { 21814 21815 var mipmap = mipmaps[ j ]; 21816 21817 if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { 21818 21819 if ( glFormat !== null ) { 21820 21821 state.compressedTexImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); 21822 21823 } else { 21824 21825 console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' ); 21826 21827 } 21828 21829 } else { 21830 21831 state.texImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); 21832 21833 } 21834 21835 } 21836 21837 } 21838 21839 textureProperties.__maxMipLevel = mipmaps.length - 1; 21840 21841 } else { 21842 21843 mipmaps = texture.mipmaps; 21844 21845 for ( var i = 0; i < 6; i ++ ) { 21846 21847 if ( isDataTexture ) { 21848 21849 state.texImage2D( 34069 + i, 0, glInternalFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data ); 21850 21851 for ( var j = 0; j < mipmaps.length; j ++ ) { 21852 21853 var mipmap = mipmaps[ j ]; 21854 var mipmapImage = mipmap.image[ i ].image; 21855 21856 state.texImage2D( 34069 + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data ); 21857 21858 } 21859 21860 } else { 21861 21862 state.texImage2D( 34069 + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] ); 21863 21864 for ( var j = 0; j < mipmaps.length; j ++ ) { 21865 21866 var mipmap = mipmaps[ j ]; 21867 21868 state.texImage2D( 34069 + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[ i ] ); 21869 21870 } 21871 21872 } 21873 21874 } 21875 21876 textureProperties.__maxMipLevel = mipmaps.length; 21877 21878 } 21879 21880 if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { 21881 21882 // We assume images for cube map have the same size. 21883 generateMipmap( 34067, texture, image.width, image.height ); 21884 21885 } 21886 21887 textureProperties.__version = texture.version; 21888 21889 if ( texture.onUpdate ) texture.onUpdate( texture ); 21890 21891 } else { 21892 21893 state.activeTexture( 33984 + slot ); 21894 state.bindTexture( 34067, textureProperties.__webglTexture ); 21895 21896 } 21897 21898 } 21899 21900 function setTextureCubeDynamic( texture, slot ) { 21901 21902 state.activeTexture( 33984 + slot ); 21903 state.bindTexture( 34067, properties.get( texture ).__webglTexture ); 21904 21905 } 21906 21907 var wrappingToGL = { 21908 [ RepeatWrapping ]: 10497, 21909 [ ClampToEdgeWrapping ]: 33071, 21910 [ MirroredRepeatWrapping ]: 33648 21911 }; 21912 21913 var filterToGL = { 21914 [ NearestFilter ]: 9728, 21915 [ NearestMipmapNearestFilter ]: 9984, 21916 [ NearestMipmapLinearFilter ]: 9986, 21917 21918 [ LinearFilter ]: 9729, 21919 [ LinearMipmapNearestFilter ]: 9985, 21920 [ LinearMipmapLinearFilter ]: 9987 21921 }; 21922 21923 function setTextureParameters( textureType, texture, supportsMips ) { 21924 21925 if ( supportsMips ) { 21926 21927 _gl.texParameteri( textureType, 10242, wrappingToGL[ texture.wrapS ] ); 21928 _gl.texParameteri( textureType, 10243, wrappingToGL[ texture.wrapT ] ); 21929 21930 if ( textureType === 32879 || textureType === 35866 ) { 21931 21932 _gl.texParameteri( textureType, 32882, wrappingToGL[ texture.wrapR ] ); 21933 21934 } 21935 21936 _gl.texParameteri( textureType, 10240, filterToGL[ texture.magFilter ] ); 21937 _gl.texParameteri( textureType, 10241, filterToGL[ texture.minFilter ] ); 21938 21939 } else { 21940 21941 _gl.texParameteri( textureType, 10242, 33071 ); 21942 _gl.texParameteri( textureType, 10243, 33071 ); 21943 21944 if ( textureType === 32879 || textureType === 35866 ) { 21945 21946 _gl.texParameteri( textureType, 32882, 33071 ); 21947 21948 } 21949 21950 if ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) { 21951 21952 console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.' ); 21953 21954 } 21955 21956 _gl.texParameteri( textureType, 10240, filterFallback( texture.magFilter ) ); 21957 _gl.texParameteri( textureType, 10241, filterFallback( texture.minFilter ) ); 21958 21959 if ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) { 21960 21961 console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.' ); 21962 21963 } 21964 21965 } 21966 21967 var extension = extensions.get( 'EXT_texture_filter_anisotropic' ); 21968 21969 if ( extension ) { 21970 21971 if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return; 21972 if ( texture.type === HalfFloatType && ( isWebGL2 || extensions.get( 'OES_texture_half_float_linear' ) ) === null ) return; 21973 21974 if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) { 21975 21976 _gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) ); 21977 properties.get( texture ).__currentAnisotropy = texture.anisotropy; 21978 21979 } 21980 21981 } 21982 21983 } 21984 21985 function initTexture( textureProperties, texture ) { 21986 21987 if ( textureProperties.__webglInit === undefined ) { 21988 21989 textureProperties.__webglInit = true; 21990 21991 texture.addEventListener( 'dispose', onTextureDispose ); 21992 21993 textureProperties.__webglTexture = _gl.createTexture(); 21994 21995 info.memory.textures ++; 21996 21997 } 21998 21999 } 22000 22001 function uploadTexture( textureProperties, texture, slot ) { 22002 22003 var textureType = 3553; 22004 22005 if ( texture.isDataTexture2DArray ) textureType = 35866; 22006 if ( texture.isDataTexture3D ) textureType = 32879; 22007 22008 initTexture( textureProperties, texture ); 22009 22010 state.activeTexture( 33984 + slot ); 22011 state.bindTexture( textureType, textureProperties.__webglTexture ); 22012 22013 _gl.pixelStorei( 37440, texture.flipY ); 22014 _gl.pixelStorei( 37441, texture.premultiplyAlpha ); 22015 _gl.pixelStorei( 3317, texture.unpackAlignment ); 22016 22017 var needsPowerOfTwo = textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false; 22018 var image = resizeImage( texture.image, needsPowerOfTwo, false, maxTextureSize ); 22019 22020 var supportsMips = isPowerOfTwo( image ) || isWebGL2, 22021 glFormat = utils.convert( texture.format ), 22022 glType = utils.convert( texture.type ), 22023 glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType ); 22024 22025 setTextureParameters( textureType, texture, supportsMips ); 22026 22027 var mipmap, mipmaps = texture.mipmaps; 22028 22029 if ( texture.isDepthTexture ) { 22030 22031 // populate depth texture with dummy data 22032 22033 glInternalFormat = 6402; 22034 22035 if ( isWebGL2 ) { 22036 22037 if ( texture.type === FloatType ) { 22038 22039 glInternalFormat = 36012; 22040 22041 } else if ( texture.type === UnsignedIntType ) { 22042 22043 glInternalFormat = 33190; 22044 22045 } else if ( texture.type === UnsignedInt248Type ) { 22046 22047 glInternalFormat = 35056; 22048 22049 } else { 22050 22051 glInternalFormat = 33189; // WebGL2 requires sized internalformat for glTexImage2D 22052 22053 } 22054 22055 } else { 22056 22057 if ( texture.type === FloatType ) { 22058 22059 console.error( 'WebGLRenderer: Floating point depth texture requires WebGL2.' ); 22060 22061 } 22062 22063 } 22064 22065 // validation checks for WebGL 1 22066 22067 if ( texture.format === DepthFormat && glInternalFormat === 6402 ) { 22068 22069 // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are 22070 // DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT 22071 // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) 22072 if ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) { 22073 22074 console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' ); 22075 22076 texture.type = UnsignedShortType; 22077 glType = utils.convert( texture.type ); 22078 22079 } 22080 22081 } 22082 22083 if ( texture.format === DepthStencilFormat && glInternalFormat === 6402 ) { 22084 22085 // Depth stencil textures need the DEPTH_STENCIL internal format 22086 // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) 22087 glInternalFormat = 34041; 22088 22089 // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are 22090 // DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL. 22091 // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) 22092 if ( texture.type !== UnsignedInt248Type ) { 22093 22094 console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' ); 22095 22096 texture.type = UnsignedInt248Type; 22097 glType = utils.convert( texture.type ); 22098 22099 } 22100 22101 } 22102 22103 // 22104 22105 state.texImage2D( 3553, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null ); 22106 22107 } else if ( texture.isDataTexture ) { 22108 22109 // use manually created mipmaps if available 22110 // if there are no manual mipmaps 22111 // set 0 level mipmap and then use GL to generate other mipmap levels 22112 22113 if ( mipmaps.length > 0 && supportsMips ) { 22114 22115 for ( var i = 0, il = mipmaps.length; i < il; i ++ ) { 22116 22117 mipmap = mipmaps[ i ]; 22118 state.texImage2D( 3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); 22119 22120 } 22121 22122 texture.generateMipmaps = false; 22123 textureProperties.__maxMipLevel = mipmaps.length - 1; 22124 22125 } else { 22126 22127 state.texImage2D( 3553, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data ); 22128 textureProperties.__maxMipLevel = 0; 22129 22130 } 22131 22132 } else if ( texture.isCompressedTexture ) { 22133 22134 for ( var i = 0, il = mipmaps.length; i < il; i ++ ) { 22135 22136 mipmap = mipmaps[ i ]; 22137 22138 if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { 22139 22140 if ( glFormat !== null ) { 22141 22142 state.compressedTexImage2D( 3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); 22143 22144 } else { 22145 22146 console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' ); 22147 22148 } 22149 22150 } else { 22151 22152 state.texImage2D( 3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); 22153 22154 } 22155 22156 } 22157 22158 textureProperties.__maxMipLevel = mipmaps.length - 1; 22159 22160 } else if ( texture.isDataTexture2DArray ) { 22161 22162 state.texImage3D( 35866, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data ); 22163 textureProperties.__maxMipLevel = 0; 22164 22165 } else if ( texture.isDataTexture3D ) { 22166 22167 state.texImage3D( 32879, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data ); 22168 textureProperties.__maxMipLevel = 0; 22169 22170 } else { 22171 22172 // regular Texture (image, video, canvas) 22173 22174 // use manually created mipmaps if available 22175 // if there are no manual mipmaps 22176 // set 0 level mipmap and then use GL to generate other mipmap levels 22177 22178 if ( mipmaps.length > 0 && supportsMips ) { 22179 22180 for ( var i = 0, il = mipmaps.length; i < il; i ++ ) { 22181 22182 mipmap = mipmaps[ i ]; 22183 state.texImage2D( 3553, i, glInternalFormat, glFormat, glType, mipmap ); 22184 22185 } 22186 22187 texture.generateMipmaps = false; 22188 textureProperties.__maxMipLevel = mipmaps.length - 1; 22189 22190 } else { 22191 22192 state.texImage2D( 3553, 0, glInternalFormat, glFormat, glType, image ); 22193 textureProperties.__maxMipLevel = 0; 22194 22195 } 22196 22197 } 22198 22199 if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { 22200 22201 generateMipmap( textureType, texture, image.width, image.height ); 22202 22203 } 22204 22205 textureProperties.__version = texture.version; 22206 22207 if ( texture.onUpdate ) texture.onUpdate( texture ); 22208 22209 } 22210 22211 // Render targets 22212 22213 // Setup storage for target texture and bind it to correct framebuffer 22214 function setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) { 22215 22216 var glFormat = utils.convert( renderTarget.texture.format ); 22217 var glType = utils.convert( renderTarget.texture.type ); 22218 var glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType ); 22219 state.texImage2D( textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null ); 22220 _gl.bindFramebuffer( 36160, framebuffer ); 22221 _gl.framebufferTexture2D( 36160, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 ); 22222 _gl.bindFramebuffer( 36160, null ); 22223 22224 } 22225 22226 // Setup storage for internal depth/stencil buffers and bind to correct framebuffer 22227 function setupRenderBufferStorage( renderbuffer, renderTarget, isMultisample ) { 22228 22229 _gl.bindRenderbuffer( 36161, renderbuffer ); 22230 22231 if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) { 22232 22233 var glInternalFormat = 33189; 22234 22235 if ( isMultisample ) { 22236 22237 var depthTexture = renderTarget.depthTexture; 22238 22239 if ( depthTexture && depthTexture.isDepthTexture ) { 22240 22241 if ( depthTexture.type === FloatType ) { 22242 22243 glInternalFormat = 36012; 22244 22245 } else if ( depthTexture.type === UnsignedIntType ) { 22246 22247 glInternalFormat = 33190; 22248 22249 } 22250 22251 } 22252 22253 var samples = getRenderTargetSamples( renderTarget ); 22254 22255 _gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height ); 22256 22257 } else { 22258 22259 _gl.renderbufferStorage( 36161, glInternalFormat, renderTarget.width, renderTarget.height ); 22260 22261 } 22262 22263 _gl.framebufferRenderbuffer( 36160, 36096, 36161, renderbuffer ); 22264 22265 } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) { 22266 22267 if ( isMultisample ) { 22268 22269 var samples = getRenderTargetSamples( renderTarget ); 22270 22271 _gl.renderbufferStorageMultisample( 36161, samples, 35056, renderTarget.width, renderTarget.height ); 22272 22273 } else { 22274 22275 _gl.renderbufferStorage( 36161, 34041, renderTarget.width, renderTarget.height ); 22276 22277 } 22278 22279 22280 _gl.framebufferRenderbuffer( 36160, 33306, 36161, renderbuffer ); 22281 22282 } else { 22283 22284 var glFormat = utils.convert( renderTarget.texture.format ); 22285 var glType = utils.convert( renderTarget.texture.type ); 22286 var glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType ); 22287 22288 if ( isMultisample ) { 22289 22290 var samples = getRenderTargetSamples( renderTarget ); 22291 22292 _gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height ); 22293 22294 } else { 22295 22296 _gl.renderbufferStorage( 36161, glInternalFormat, renderTarget.width, renderTarget.height ); 22297 22298 } 22299 22300 } 22301 22302 _gl.bindRenderbuffer( 36161, null ); 22303 22304 } 22305 22306 // Setup resources for a Depth Texture for a FBO (needs an extension) 22307 function setupDepthTexture( framebuffer, renderTarget ) { 22308 22309 var isCube = ( renderTarget && renderTarget.isWebGLCubeRenderTarget ); 22310 if ( isCube ) throw new Error( 'Depth Texture with cube render targets is not supported' ); 22311 22312 _gl.bindFramebuffer( 36160, framebuffer ); 22313 22314 if ( ! ( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) { 22315 22316 throw new Error( 'renderTarget.depthTexture must be an instance of THREE.DepthTexture' ); 22317 22318 } 22319 22320 // upload an empty depth texture with framebuffer size 22321 if ( ! properties.get( renderTarget.depthTexture ).__webglTexture || 22322 renderTarget.depthTexture.image.width !== renderTarget.width || 22323 renderTarget.depthTexture.image.height !== renderTarget.height ) { 22324 22325 renderTarget.depthTexture.image.width = renderTarget.width; 22326 renderTarget.depthTexture.image.height = renderTarget.height; 22327 renderTarget.depthTexture.needsUpdate = true; 22328 22329 } 22330 22331 setTexture2D( renderTarget.depthTexture, 0 ); 22332 22333 var webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture; 22334 22335 if ( renderTarget.depthTexture.format === DepthFormat ) { 22336 22337 _gl.framebufferTexture2D( 36160, 36096, 3553, webglDepthTexture, 0 ); 22338 22339 } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) { 22340 22341 _gl.framebufferTexture2D( 36160, 33306, 3553, webglDepthTexture, 0 ); 22342 22343 } else { 22344 22345 throw new Error( 'Unknown depthTexture format' ); 22346 22347 } 22348 22349 } 22350 22351 // Setup GL resources for a non-texture depth buffer 22352 function setupDepthRenderbuffer( renderTarget ) { 22353 22354 var renderTargetProperties = properties.get( renderTarget ); 22355 22356 var isCube = ( renderTarget.isWebGLCubeRenderTarget === true ); 22357 22358 if ( renderTarget.depthTexture ) { 22359 22360 if ( isCube ) throw new Error( 'target.depthTexture not supported in Cube render targets' ); 22361 22362 setupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget ); 22363 22364 } else { 22365 22366 if ( isCube ) { 22367 22368 renderTargetProperties.__webglDepthbuffer = []; 22369 22370 for ( var i = 0; i < 6; i ++ ) { 22371 22372 _gl.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer[ i ] ); 22373 renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer(); 22374 setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget, false ); 22375 22376 } 22377 22378 } else { 22379 22380 _gl.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer ); 22381 renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); 22382 setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget, false ); 22383 22384 } 22385 22386 } 22387 22388 _gl.bindFramebuffer( 36160, null ); 22389 22390 } 22391 22392 // Set up GL resources for the render target 22393 function setupRenderTarget( renderTarget ) { 22394 22395 var renderTargetProperties = properties.get( renderTarget ); 22396 var textureProperties = properties.get( renderTarget.texture ); 22397 22398 renderTarget.addEventListener( 'dispose', onRenderTargetDispose ); 22399 22400 textureProperties.__webglTexture = _gl.createTexture(); 22401 22402 info.memory.textures ++; 22403 22404 var isCube = ( renderTarget.isWebGLCubeRenderTarget === true ); 22405 var isMultisample = ( renderTarget.isWebGLMultisampleRenderTarget === true ); 22406 var supportsMips = isPowerOfTwo( renderTarget ) || isWebGL2; 22407 22408 // Handles WebGL2 RGBFormat fallback - #18858 22409 22410 if ( isWebGL2 && renderTarget.texture.format === RGBFormat && ( renderTarget.texture.type === FloatType || renderTarget.texture.type === HalfFloatType ) ) { 22411 22412 renderTarget.texture.format = RGBAFormat; 22413 22414 console.warn( 'THREE.WebGLRenderer: Rendering to textures with RGB format is not supported. Using RGBA format instead.' ); 22415 22416 } 22417 22418 // Setup framebuffer 22419 22420 if ( isCube ) { 22421 22422 renderTargetProperties.__webglFramebuffer = []; 22423 22424 for ( var i = 0; i < 6; i ++ ) { 22425 22426 renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer(); 22427 22428 } 22429 22430 } else { 22431 22432 renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer(); 22433 22434 if ( isMultisample ) { 22435 22436 if ( isWebGL2 ) { 22437 22438 renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer(); 22439 renderTargetProperties.__webglColorRenderbuffer = _gl.createRenderbuffer(); 22440 22441 _gl.bindRenderbuffer( 36161, renderTargetProperties.__webglColorRenderbuffer ); 22442 22443 var glFormat = utils.convert( renderTarget.texture.format ); 22444 var glType = utils.convert( renderTarget.texture.type ); 22445 var glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType ); 22446 var samples = getRenderTargetSamples( renderTarget ); 22447 _gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height ); 22448 22449 _gl.bindFramebuffer( 36160, renderTargetProperties.__webglMultisampledFramebuffer ); 22450 _gl.framebufferRenderbuffer( 36160, 36064, 36161, renderTargetProperties.__webglColorRenderbuffer ); 22451 _gl.bindRenderbuffer( 36161, null ); 22452 22453 if ( renderTarget.depthBuffer ) { 22454 22455 renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer(); 22456 setupRenderBufferStorage( renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true ); 22457 22458 } 22459 22460 _gl.bindFramebuffer( 36160, null ); 22461 22462 22463 } else { 22464 22465 console.warn( 'THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.' ); 22466 22467 } 22468 22469 } 22470 22471 } 22472 22473 // Setup color buffer 22474 22475 if ( isCube ) { 22476 22477 state.bindTexture( 34067, textureProperties.__webglTexture ); 22478 setTextureParameters( 34067, renderTarget.texture, supportsMips ); 22479 22480 for ( var i = 0; i < 6; i ++ ) { 22481 22482 setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, 36064, 34069 + i ); 22483 22484 } 22485 22486 if ( textureNeedsGenerateMipmaps( renderTarget.texture, supportsMips ) ) { 22487 22488 generateMipmap( 34067, renderTarget.texture, renderTarget.width, renderTarget.height ); 22489 22490 } 22491 22492 state.bindTexture( 34067, null ); 22493 22494 } else { 22495 22496 state.bindTexture( 3553, textureProperties.__webglTexture ); 22497 setTextureParameters( 3553, renderTarget.texture, supportsMips ); 22498 setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, 36064, 3553 ); 22499 22500 if ( textureNeedsGenerateMipmaps( renderTarget.texture, supportsMips ) ) { 22501 22502 generateMipmap( 3553, renderTarget.texture, renderTarget.width, renderTarget.height ); 22503 22504 } 22505 22506 state.bindTexture( 3553, null ); 22507 22508 } 22509 22510 // Setup depth and stencil buffers 22511 22512 if ( renderTarget.depthBuffer ) { 22513 22514 setupDepthRenderbuffer( renderTarget ); 22515 22516 } 22517 22518 } 22519 22520 function updateRenderTargetMipmap( renderTarget ) { 22521 22522 var texture = renderTarget.texture; 22523 var supportsMips = isPowerOfTwo( renderTarget ) || isWebGL2; 22524 22525 if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { 22526 22527 var target = renderTarget.isWebGLCubeRenderTarget ? 34067 : 3553; 22528 var webglTexture = properties.get( texture ).__webglTexture; 22529 22530 state.bindTexture( target, webglTexture ); 22531 generateMipmap( target, texture, renderTarget.width, renderTarget.height ); 22532 state.bindTexture( target, null ); 22533 22534 } 22535 22536 } 22537 22538 function updateMultisampleRenderTarget( renderTarget ) { 22539 22540 if ( renderTarget.isWebGLMultisampleRenderTarget ) { 22541 22542 if ( isWebGL2 ) { 22543 22544 var renderTargetProperties = properties.get( renderTarget ); 22545 22546 _gl.bindFramebuffer( 36008, renderTargetProperties.__webglMultisampledFramebuffer ); 22547 _gl.bindFramebuffer( 36009, renderTargetProperties.__webglFramebuffer ); 22548 22549 var width = renderTarget.width; 22550 var height = renderTarget.height; 22551 var mask = 16384; 22552 22553 if ( renderTarget.depthBuffer ) mask |= 256; 22554 if ( renderTarget.stencilBuffer ) mask |= 1024; 22555 22556 _gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, mask, 9728 ); 22557 22558 _gl.bindFramebuffer( 36160, renderTargetProperties.__webglMultisampledFramebuffer ); // see #18905 22559 22560 } else { 22561 22562 console.warn( 'THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.' ); 22563 22564 } 22565 22566 } 22567 22568 } 22569 22570 function getRenderTargetSamples( renderTarget ) { 22571 22572 return ( isWebGL2 && renderTarget.isWebGLMultisampleRenderTarget ) ? 22573 Math.min( maxSamples, renderTarget.samples ) : 0; 22574 22575 } 22576 22577 function updateVideoTexture( texture ) { 22578 22579 var frame = info.render.frame; 22580 22581 // Check the last frame we updated the VideoTexture 22582 22583 if ( _videoTextures.get( texture ) !== frame ) { 22584 22585 _videoTextures.set( texture, frame ); 22586 texture.update(); 22587 22588 } 22589 22590 } 22591 22592 // backwards compatibility 22593 22594 var warnedTexture2D = false; 22595 var warnedTextureCube = false; 22596 22597 function safeSetTexture2D( texture, slot ) { 22598 22599 if ( texture && texture.isWebGLRenderTarget ) { 22600 22601 if ( warnedTexture2D === false ) { 22602 22603 console.warn( "THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead." ); 22604 warnedTexture2D = true; 22605 22606 } 22607 22608 texture = texture.texture; 22609 22610 } 22611 22612 setTexture2D( texture, slot ); 22613 22614 } 22615 22616 function safeSetTextureCube( texture, slot ) { 22617 22618 if ( texture && texture.isWebGLCubeRenderTarget ) { 22619 22620 if ( warnedTextureCube === false ) { 22621 22622 console.warn( "THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead." ); 22623 warnedTextureCube = true; 22624 22625 } 22626 22627 texture = texture.texture; 22628 22629 } 22630 22631 // currently relying on the fact that WebGLCubeRenderTarget.texture is a Texture and NOT a CubeTexture 22632 // TODO: unify these code paths 22633 if ( ( texture && texture.isCubeTexture ) || 22634 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) { 22635 22636 // CompressedTexture can have Array in image :/ 22637 22638 // this function alone should take care of cube textures 22639 setTextureCube( texture, slot ); 22640 22641 } else { 22642 22643 // assumed: texture property of THREE.WebGLCubeRenderTarget 22644 setTextureCubeDynamic( texture, slot ); 22645 22646 } 22647 22648 } 22649 22650 // 22651 22652 this.allocateTextureUnit = allocateTextureUnit; 22653 this.resetTextureUnits = resetTextureUnits; 22654 22655 this.setTexture2D = setTexture2D; 22656 this.setTexture2DArray = setTexture2DArray; 22657 this.setTexture3D = setTexture3D; 22658 this.setTextureCube = setTextureCube; 22659 this.setTextureCubeDynamic = setTextureCubeDynamic; 22660 this.setupRenderTarget = setupRenderTarget; 22661 this.updateRenderTargetMipmap = updateRenderTargetMipmap; 22662 this.updateMultisampleRenderTarget = updateMultisampleRenderTarget; 22663 22664 this.safeSetTexture2D = safeSetTexture2D; 22665 this.safeSetTextureCube = safeSetTextureCube; 22666 22667} 22668 22669/** 22670 * @author thespite / http://www.twitter.com/thespite 22671 */ 22672 22673function WebGLUtils( gl, extensions, capabilities ) { 22674 22675 var isWebGL2 = capabilities.isWebGL2; 22676 22677 function convert( p ) { 22678 22679 var extension; 22680 22681 if ( p === UnsignedByteType ) return 5121; 22682 if ( p === UnsignedShort4444Type ) return 32819; 22683 if ( p === UnsignedShort5551Type ) return 32820; 22684 if ( p === UnsignedShort565Type ) return 33635; 22685 22686 if ( p === ByteType ) return 5120; 22687 if ( p === ShortType ) return 5122; 22688 if ( p === UnsignedShortType ) return 5123; 22689 if ( p === IntType ) return 5124; 22690 if ( p === UnsignedIntType ) return 5125; 22691 if ( p === FloatType ) return 5126; 22692 22693 if ( p === HalfFloatType ) { 22694 22695 if ( isWebGL2 ) return 5131; 22696 22697 extension = extensions.get( 'OES_texture_half_float' ); 22698 22699 if ( extension !== null ) { 22700 22701 return extension.HALF_FLOAT_OES; 22702 22703 } else { 22704 22705 return null; 22706 22707 } 22708 22709 } 22710 22711 if ( p === AlphaFormat ) return 6406; 22712 if ( p === RGBFormat ) return 6407; 22713 if ( p === RGBAFormat ) return 6408; 22714 if ( p === LuminanceFormat ) return 6409; 22715 if ( p === LuminanceAlphaFormat ) return 6410; 22716 if ( p === DepthFormat ) return 6402; 22717 if ( p === DepthStencilFormat ) return 34041; 22718 if ( p === RedFormat ) return 6403; 22719 22720 // WebGL2 formats. 22721 22722 if ( p === RedIntegerFormat ) return 36244; 22723 if ( p === RGFormat ) return 33319; 22724 if ( p === RGIntegerFormat ) return 33320; 22725 if ( p === RGBIntegerFormat ) return 36248; 22726 if ( p === RGBAIntegerFormat ) return 36249; 22727 22728 if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || 22729 p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) { 22730 22731 extension = extensions.get( 'WEBGL_compressed_texture_s3tc' ); 22732 22733 if ( extension !== null ) { 22734 22735 if ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT; 22736 if ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT; 22737 if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; 22738 if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; 22739 22740 } else { 22741 22742 return null; 22743 22744 } 22745 22746 } 22747 22748 if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || 22749 p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) { 22750 22751 extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' ); 22752 22753 if ( extension !== null ) { 22754 22755 if ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; 22756 if ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; 22757 if ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; 22758 if ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; 22759 22760 } else { 22761 22762 return null; 22763 22764 } 22765 22766 } 22767 22768 if ( p === RGB_ETC1_Format ) { 22769 22770 extension = extensions.get( 'WEBGL_compressed_texture_etc1' ); 22771 22772 if ( extension !== null ) { 22773 22774 return extension.COMPRESSED_RGB_ETC1_WEBGL; 22775 22776 } else { 22777 22778 return null; 22779 22780 } 22781 22782 } 22783 22784 if ( p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format ) { 22785 22786 extension = extensions.get( 'WEBGL_compressed_texture_etc' ); 22787 22788 if ( extension !== null ) { 22789 22790 if ( p === RGB_ETC2_Format ) return extension.COMPRESSED_RGB8_ETC2; 22791 if ( p === RGBA_ETC2_EAC_Format ) return extension.COMPRESSED_RGBA8_ETC2_EAC; 22792 22793 } 22794 22795 } 22796 22797 if ( p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format || 22798 p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format || 22799 p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format || 22800 p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format || 22801 p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format || 22802 p === SRGB8_ALPHA8_ASTC_4x4_Format || p === SRGB8_ALPHA8_ASTC_5x4_Format || p === SRGB8_ALPHA8_ASTC_5x5_Format || 22803 p === SRGB8_ALPHA8_ASTC_6x5_Format || p === SRGB8_ALPHA8_ASTC_6x6_Format || p === SRGB8_ALPHA8_ASTC_8x5_Format || 22804 p === SRGB8_ALPHA8_ASTC_8x6_Format || p === SRGB8_ALPHA8_ASTC_8x8_Format || p === SRGB8_ALPHA8_ASTC_10x5_Format || 22805 p === SRGB8_ALPHA8_ASTC_10x6_Format || p === SRGB8_ALPHA8_ASTC_10x8_Format || p === SRGB8_ALPHA8_ASTC_10x10_Format || 22806 p === SRGB8_ALPHA8_ASTC_12x10_Format || p === SRGB8_ALPHA8_ASTC_12x12_Format ) { 22807 22808 extension = extensions.get( 'WEBGL_compressed_texture_astc' ); 22809 22810 if ( extension !== null ) { 22811 22812 // TODO Complete? 22813 22814 return p; 22815 22816 } else { 22817 22818 return null; 22819 22820 } 22821 22822 } 22823 22824 if ( p === RGBA_BPTC_Format ) { 22825 22826 extension = extensions.get( 'EXT_texture_compression_bptc' ); 22827 22828 if ( extension !== null ) { 22829 22830 // TODO Complete? 22831 22832 return p; 22833 22834 } else { 22835 22836 return null; 22837 22838 } 22839 22840 } 22841 22842 if ( p === UnsignedInt248Type ) { 22843 22844 if ( isWebGL2 ) return 34042; 22845 22846 extension = extensions.get( 'WEBGL_depth_texture' ); 22847 22848 if ( extension !== null ) { 22849 22850 return extension.UNSIGNED_INT_24_8_WEBGL; 22851 22852 } else { 22853 22854 return null; 22855 22856 } 22857 22858 } 22859 22860 } 22861 22862 return { convert: convert }; 22863 22864} 22865 22866/** 22867 * @author mrdoob / http://mrdoob.com/ 22868 */ 22869 22870function ArrayCamera( array ) { 22871 22872 PerspectiveCamera.call( this ); 22873 22874 this.cameras = array || []; 22875 22876} 22877 22878ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototype ), { 22879 22880 constructor: ArrayCamera, 22881 22882 isArrayCamera: true 22883 22884} ); 22885 22886/** 22887 * @author mrdoob / http://mrdoob.com/ 22888 */ 22889 22890function Group() { 22891 22892 Object3D.call( this ); 22893 22894 this.type = 'Group'; 22895 22896} 22897 22898Group.prototype = Object.assign( Object.create( Object3D.prototype ), { 22899 22900 constructor: Group, 22901 22902 isGroup: true 22903 22904} ); 22905 22906/** 22907 * @author Mugen87 / https://github.com/Mugen87 22908 */ 22909 22910function WebXRController() { 22911 22912 this._targetRay = null; 22913 this._grip = null; 22914 22915} 22916 22917Object.assign( WebXRController.prototype, { 22918 22919 constructor: WebXRController, 22920 22921 getTargetRaySpace: function () { 22922 22923 if ( this._targetRay === null ) { 22924 22925 this._targetRay = new Group(); 22926 this._targetRay.matrixAutoUpdate = false; 22927 this._targetRay.visible = false; 22928 22929 } 22930 22931 return this._targetRay; 22932 22933 }, 22934 22935 getGripSpace: function () { 22936 22937 if ( this._grip === null ) { 22938 22939 this._grip = new Group(); 22940 this._grip.matrixAutoUpdate = false; 22941 this._grip.visible = false; 22942 22943 } 22944 22945 return this._grip; 22946 22947 }, 22948 22949 dispatchEvent: function ( event ) { 22950 22951 if ( this._targetRay !== null ) { 22952 22953 this._targetRay.dispatchEvent( event ); 22954 22955 } 22956 22957 if ( this._grip !== null ) { 22958 22959 this._grip.dispatchEvent( event ); 22960 22961 } 22962 22963 return this; 22964 22965 }, 22966 22967 disconnect: function ( inputSource ) { 22968 22969 this.dispatchEvent( { type: 'disconnected', data: inputSource } ); 22970 22971 if ( this._targetRay !== null ) { 22972 22973 this._targetRay.visible = false; 22974 22975 } 22976 22977 if ( this._grip !== null ) { 22978 22979 this._grip.visible = false; 22980 22981 } 22982 22983 return this; 22984 22985 }, 22986 22987 update: function ( inputSource, frame, referenceSpace ) { 22988 22989 var inputPose = null; 22990 var gripPose = null; 22991 22992 var targetRay = this._targetRay; 22993 var grip = this._grip; 22994 22995 if ( inputSource ) { 22996 22997 if ( targetRay !== null ) { 22998 22999 inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace ); 23000 23001 if ( inputPose !== null ) { 23002 23003 targetRay.matrix.fromArray( inputPose.transform.matrix ); 23004 targetRay.matrix.decompose( targetRay.position, targetRay.rotation, targetRay.scale ); 23005 23006 } 23007 23008 } 23009 23010 if ( grip !== null && inputSource.gripSpace ) { 23011 23012 gripPose = frame.getPose( inputSource.gripSpace, referenceSpace ); 23013 23014 if ( gripPose !== null ) { 23015 23016 grip.matrix.fromArray( gripPose.transform.matrix ); 23017 grip.matrix.decompose( grip.position, grip.rotation, grip.scale ); 23018 23019 } 23020 23021 } 23022 23023 } 23024 23025 if ( targetRay !== null ) { 23026 23027 targetRay.visible = ( inputPose !== null ); 23028 23029 } 23030 23031 if ( grip !== null ) { 23032 23033 grip.visible = ( gripPose !== null ); 23034 23035 } 23036 23037 return this; 23038 23039 } 23040 23041} ); 23042 23043/** 23044 * @author mrdoob / http://mrdoob.com/ 23045 */ 23046 23047function WebXRManager( renderer, gl ) { 23048 23049 var scope = this; 23050 23051 var session = null; 23052 23053 var framebufferScaleFactor = 1.0; 23054 23055 var referenceSpace = null; 23056 var referenceSpaceType = 'local-floor'; 23057 23058 var pose = null; 23059 23060 var controllers = []; 23061 var inputSourcesMap = new Map(); 23062 23063 // 23064 23065 var cameraL = new PerspectiveCamera(); 23066 cameraL.layers.enable( 1 ); 23067 cameraL.viewport = new Vector4(); 23068 23069 var cameraR = new PerspectiveCamera(); 23070 cameraR.layers.enable( 2 ); 23071 cameraR.viewport = new Vector4(); 23072 23073 var cameras = [ cameraL, cameraR ]; 23074 23075 var cameraVR = new ArrayCamera(); 23076 cameraVR.layers.enable( 1 ); 23077 cameraVR.layers.enable( 2 ); 23078 23079 var _currentDepthNear = null; 23080 var _currentDepthFar = null; 23081 23082 // 23083 23084 this.enabled = false; 23085 23086 this.isPresenting = false; 23087 23088 this.getController = function ( index ) { 23089 23090 var controller = controllers[ index ]; 23091 23092 if ( controller === undefined ) { 23093 23094 controller = new WebXRController(); 23095 controllers[ index ] = controller; 23096 23097 } 23098 23099 return controller.getTargetRaySpace(); 23100 23101 }; 23102 23103 this.getControllerGrip = function ( index ) { 23104 23105 var controller = controllers[ index ]; 23106 23107 if ( controller === undefined ) { 23108 23109 controller = new WebXRController(); 23110 controllers[ index ] = controller; 23111 23112 } 23113 23114 return controller.getGripSpace(); 23115 23116 }; 23117 23118 // 23119 23120 function onSessionEvent( event ) { 23121 23122 var controller = inputSourcesMap.get( event.inputSource ); 23123 23124 if ( controller ) { 23125 23126 controller.dispatchEvent( { type: event.type } ); 23127 23128 } 23129 23130 } 23131 23132 function onSessionEnd() { 23133 23134 inputSourcesMap.forEach( function ( controller, inputSource ) { 23135 23136 controller.disconnect( inputSource ); 23137 23138 } ); 23139 23140 inputSourcesMap.clear(); 23141 23142 // 23143 23144 renderer.setFramebuffer( null ); 23145 renderer.setRenderTarget( renderer.getRenderTarget() ); // Hack #15830 23146 animation.stop(); 23147 23148 scope.isPresenting = false; 23149 23150 scope.dispatchEvent( { type: 'sessionend' } ); 23151 23152 } 23153 23154 function onRequestReferenceSpace( value ) { 23155 23156 referenceSpace = value; 23157 23158 animation.setContext( session ); 23159 animation.start(); 23160 23161 scope.isPresenting = true; 23162 23163 scope.dispatchEvent( { type: 'sessionstart' } ); 23164 23165 } 23166 23167 this.setFramebufferScaleFactor = function ( value ) { 23168 23169 framebufferScaleFactor = value; 23170 23171 if ( scope.isPresenting === true ) { 23172 23173 console.warn( 'THREE.WebXRManager: Cannot change framebuffer scale while presenting.' ); 23174 23175 } 23176 23177 }; 23178 23179 this.setReferenceSpaceType = function ( value ) { 23180 23181 referenceSpaceType = value; 23182 23183 if ( scope.isPresenting === true ) { 23184 23185 console.warn( 'THREE.WebXRManager: Cannot change reference space type while presenting.' ); 23186 23187 } 23188 23189 }; 23190 23191 this.getReferenceSpace = function () { 23192 23193 return referenceSpace; 23194 23195 }; 23196 23197 this.getSession = function () { 23198 23199 return session; 23200 23201 }; 23202 23203 this.setSession = function ( value ) { 23204 23205 session = value; 23206 23207 if ( session !== null ) { 23208 23209 session.addEventListener( 'select', onSessionEvent ); 23210 session.addEventListener( 'selectstart', onSessionEvent ); 23211 session.addEventListener( 'selectend', onSessionEvent ); 23212 session.addEventListener( 'squeeze', onSessionEvent ); 23213 session.addEventListener( 'squeezestart', onSessionEvent ); 23214 session.addEventListener( 'squeezeend', onSessionEvent ); 23215 session.addEventListener( 'end', onSessionEnd ); 23216 23217 var attributes = gl.getContextAttributes(); 23218 23219 var layerInit = { 23220 antialias: attributes.antialias, 23221 alpha: attributes.alpha, 23222 depth: attributes.depth, 23223 stencil: attributes.stencil, 23224 framebufferScaleFactor: framebufferScaleFactor 23225 }; 23226 23227 // eslint-disable-next-line no-undef 23228 var baseLayer = new XRWebGLLayer( session, gl, layerInit ); 23229 23230 session.updateRenderState( { baseLayer: baseLayer } ); 23231 23232 session.requestReferenceSpace( referenceSpaceType ).then( onRequestReferenceSpace ); 23233 23234 // 23235 23236 session.addEventListener( 'inputsourceschange', updateInputSources ); 23237 23238 } 23239 23240 }; 23241 23242 function updateInputSources( event ) { 23243 23244 var inputSources = session.inputSources; 23245 23246 // Assign inputSources to available controllers 23247 23248 for ( var i = 0; i < controllers.length; i ++ ) { 23249 23250 inputSourcesMap.set( inputSources[ i ], controllers[ i ] ); 23251 23252 } 23253 23254 // Notify disconnected 23255 23256 for ( var i = 0; i < event.removed.length; i ++ ) { 23257 23258 var inputSource = event.removed[ i ]; 23259 var controller = inputSourcesMap.get( inputSource ); 23260 23261 if ( controller ) { 23262 23263 controller.dispatchEvent( { type: 'disconnected', data: inputSource } ); 23264 inputSourcesMap.delete( inputSource ); 23265 23266 } 23267 23268 } 23269 23270 // Notify connected 23271 23272 for ( var i = 0; i < event.added.length; i ++ ) { 23273 23274 var inputSource = event.added[ i ]; 23275 var controller = inputSourcesMap.get( inputSource ); 23276 23277 if ( controller ) { 23278 23279 controller.dispatchEvent( { type: 'connected', data: inputSource } ); 23280 23281 } 23282 23283 } 23284 23285 } 23286 23287 // 23288 23289 var cameraLPos = new Vector3(); 23290 var cameraRPos = new Vector3(); 23291 23292 /** 23293 * @author jsantell / https://www.jsantell.com/ 23294 * 23295 * Assumes 2 cameras that are parallel and share an X-axis, and that 23296 * the cameras' projection and world matrices have already been set. 23297 * And that near and far planes are identical for both cameras. 23298 * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765 23299 */ 23300 function setProjectionFromUnion( camera, cameraL, cameraR ) { 23301 23302 cameraLPos.setFromMatrixPosition( cameraL.matrixWorld ); 23303 cameraRPos.setFromMatrixPosition( cameraR.matrixWorld ); 23304 23305 var ipd = cameraLPos.distanceTo( cameraRPos ); 23306 23307 var projL = cameraL.projectionMatrix.elements; 23308 var projR = cameraR.projectionMatrix.elements; 23309 23310 // VR systems will have identical far and near planes, and 23311 // most likely identical top and bottom frustum extents. 23312 // Use the left camera for these values. 23313 var near = projL[ 14 ] / ( projL[ 10 ] - 1 ); 23314 var far = projL[ 14 ] / ( projL[ 10 ] + 1 ); 23315 var topFov = ( projL[ 9 ] + 1 ) / projL[ 5 ]; 23316 var bottomFov = ( projL[ 9 ] - 1 ) / projL[ 5 ]; 23317 23318 var leftFov = ( projL[ 8 ] - 1 ) / projL[ 0 ]; 23319 var rightFov = ( projR[ 8 ] + 1 ) / projR[ 0 ]; 23320 var left = near * leftFov; 23321 var right = near * rightFov; 23322 23323 // Calculate the new camera's position offset from the 23324 // left camera. xOffset should be roughly half `ipd`. 23325 var zOffset = ipd / ( - leftFov + rightFov ); 23326 var xOffset = zOffset * - leftFov; 23327 23328 // TODO: Better way to apply this offset? 23329 cameraL.matrixWorld.decompose( camera.position, camera.quaternion, camera.scale ); 23330 camera.translateX( xOffset ); 23331 camera.translateZ( zOffset ); 23332 camera.matrixWorld.compose( camera.position, camera.quaternion, camera.scale ); 23333 camera.matrixWorldInverse.getInverse( camera.matrixWorld ); 23334 23335 // Find the union of the frustum values of the cameras and scale 23336 // the values so that the near plane's position does not change in world space, 23337 // although must now be relative to the new union camera. 23338 var near2 = near + zOffset; 23339 var far2 = far + zOffset; 23340 var left2 = left - xOffset; 23341 var right2 = right + ( ipd - xOffset ); 23342 var top2 = topFov * far / far2 * near2; 23343 var bottom2 = bottomFov * far / far2 * near2; 23344 23345 camera.projectionMatrix.makePerspective( left2, right2, top2, bottom2, near2, far2 ); 23346 23347 } 23348 23349 function updateCamera( camera, parent ) { 23350 23351 if ( parent === null ) { 23352 23353 camera.matrixWorld.copy( camera.matrix ); 23354 23355 } else { 23356 23357 camera.matrixWorld.multiplyMatrices( parent.matrixWorld, camera.matrix ); 23358 23359 } 23360 23361 camera.matrixWorldInverse.getInverse( camera.matrixWorld ); 23362 23363 } 23364 23365 this.getCamera = function ( camera ) { 23366 23367 cameraVR.near = cameraR.near = cameraL.near = camera.near; 23368 cameraVR.far = cameraR.far = cameraL.far = camera.far; 23369 23370 if ( _currentDepthNear !== cameraVR.near || _currentDepthFar !== cameraVR.far ) { 23371 23372 // Note that the new renderState won't apply until the next frame. See #18320 23373 23374 session.updateRenderState( { 23375 depthNear: cameraVR.near, 23376 depthFar: cameraVR.far 23377 } ); 23378 23379 _currentDepthNear = cameraVR.near; 23380 _currentDepthFar = cameraVR.far; 23381 23382 } 23383 23384 var parent = camera.parent; 23385 var cameras = cameraVR.cameras; 23386 23387 updateCamera( cameraVR, parent ); 23388 23389 for ( var i = 0; i < cameras.length; i ++ ) { 23390 23391 updateCamera( cameras[ i ], parent ); 23392 23393 } 23394 23395 // update camera and its children 23396 23397 camera.matrixWorld.copy( cameraVR.matrixWorld ); 23398 23399 var children = camera.children; 23400 23401 for ( var i = 0, l = children.length; i < l; i ++ ) { 23402 23403 children[ i ].updateMatrixWorld( true ); 23404 23405 } 23406 23407 // update projection matrix for proper view frustum culling 23408 23409 if ( cameras.length === 2 ) { 23410 23411 setProjectionFromUnion( cameraVR, cameraL, cameraR ); 23412 23413 } else { 23414 23415 // assume single camera setup (AR) 23416 23417 cameraVR.projectionMatrix.copy( cameraL.projectionMatrix ); 23418 23419 } 23420 23421 return cameraVR; 23422 23423 }; 23424 23425 // Animation Loop 23426 23427 var onAnimationFrameCallback = null; 23428 23429 function onAnimationFrame( time, frame ) { 23430 23431 pose = frame.getViewerPose( referenceSpace ); 23432 23433 if ( pose !== null ) { 23434 23435 var views = pose.views; 23436 var baseLayer = session.renderState.baseLayer; 23437 23438 renderer.setFramebuffer( baseLayer.framebuffer ); 23439 23440 var cameraVRNeedsUpdate = false; 23441 23442 // check if it's necessary to rebuild cameraVR's camera list 23443 23444 if ( views.length !== cameraVR.cameras.length ) { 23445 23446 cameraVR.cameras.length = 0; 23447 cameraVRNeedsUpdate = true; 23448 23449 } 23450 23451 for ( var i = 0; i < views.length; i ++ ) { 23452 23453 var view = views[ i ]; 23454 var viewport = baseLayer.getViewport( view ); 23455 23456 var camera = cameras[ i ]; 23457 camera.matrix.fromArray( view.transform.matrix ); 23458 camera.projectionMatrix.fromArray( view.projectionMatrix ); 23459 camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height ); 23460 23461 if ( i === 0 ) { 23462 23463 cameraVR.matrix.copy( camera.matrix ); 23464 23465 } 23466 23467 if ( cameraVRNeedsUpdate === true ) { 23468 23469 cameraVR.cameras.push( camera ); 23470 23471 } 23472 23473 } 23474 23475 } 23476 23477 // 23478 23479 var inputSources = session.inputSources; 23480 23481 for ( var i = 0; i < controllers.length; i ++ ) { 23482 23483 var controller = controllers[ i ]; 23484 var inputSource = inputSources[ i ]; 23485 23486 controller.update( inputSource, frame, referenceSpace ); 23487 23488 } 23489 23490 if ( onAnimationFrameCallback ) onAnimationFrameCallback( time, frame ); 23491 23492 } 23493 23494 var animation = new WebGLAnimation(); 23495 animation.setAnimationLoop( onAnimationFrame ); 23496 23497 this.setAnimationLoop = function ( callback ) { 23498 23499 onAnimationFrameCallback = callback; 23500 23501 }; 23502 23503 this.dispose = function () {}; 23504 23505} 23506 23507Object.assign( WebXRManager.prototype, EventDispatcher.prototype ); 23508 23509/** 23510 * @author supereggbert / http://www.paulbrunt.co.uk/ 23511 * @author mrdoob / http://mrdoob.com/ 23512 * @author alteredq / http://alteredqualia.com/ 23513 * @author szimek / https://github.com/szimek/ 23514 * @author tschw 23515 */ 23516 23517function WebGLRenderer( parameters ) { 23518 23519 parameters = parameters || {}; 23520 23521 var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ), 23522 _context = parameters.context !== undefined ? parameters.context : null, 23523 23524 _alpha = parameters.alpha !== undefined ? parameters.alpha : false, 23525 _depth = parameters.depth !== undefined ? parameters.depth : true, 23526 _stencil = parameters.stencil !== undefined ? parameters.stencil : true, 23527 _antialias = parameters.antialias !== undefined ? parameters.antialias : false, 23528 _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true, 23529 _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false, 23530 _powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default', 23531 _failIfMajorPerformanceCaveat = parameters.failIfMajorPerformanceCaveat !== undefined ? parameters.failIfMajorPerformanceCaveat : false; 23532 23533 var currentRenderList = null; 23534 var currentRenderState = null; 23535 23536 // public properties 23537 23538 this.domElement = _canvas; 23539 23540 // Debug configuration container 23541 this.debug = { 23542 23543 /** 23544 * Enables error checking and reporting when shader programs are being compiled 23545 * @type {boolean} 23546 */
23547 checkShaderErrors: true 23548 }; 23549 23550 // clearing 23551 23552 this.autoClear = true; 23553 this.autoClearColor = true; 23554 this.autoClearDepth = true; 23555 this.autoClearStencil = true; 23556 23557 // scene graph 23558 23559 this.sortObjects = true; 23560 23561 // user-defined clipping 23562 23563 this.clippingPlanes = []; 23564 this.localClippingEnabled = false; 23565 23566 // physically based shading 23567 23568 this.gammaFactor = 2.0; // for backwards compatibility 23569 this.outputEncoding = LinearEncoding; 23570 23571 // physical lights 23572 23573 this.physicallyCorrectLights = false; 23574 23575 // tone mapping 23576 23577 this.toneMapping = NoToneMapping; 23578 this.toneMappingExposure = 1.0; 23579 this.toneMappingWhitePoint = 1.0; 23580 23581 // morphs 23582 23583 this.maxMorphTargets = 8; 23584 this.maxMorphNormals = 4; 23585 23586 // internal properties 23587 23588 var _this = this, 23589 23590 _isContextLost = false, 23591 23592 // internal state cache 23593 23594 _framebuffer = null, 23595 23596 _currentActiveCubeFace = 0, 23597 _currentActiveMipmapLevel = 0, 23598 _currentRenderTarget = null, 23599 _currentFramebuffer = null, 23600 _currentMaterialId = - 1, 23601 23602 // geometry and program caching 23603 23604 _currentGeometryProgram = { 23605 geometry: null, 23606 program: null, 23607 wireframe: false 23608 }, 23609 23610 _currentCamera = null, 23611 _currentArrayCamera = null, 23612 23613 _currentViewport = new Vector4(), 23614 _currentScissor = new Vector4(), 23615 _currentScissorTest = null, 23616 23617 // 23618 23619 _width = _canvas.width, 23620 _height = _canvas.height, 23621 23622 _pixelRatio = 1, 23623 _opaqueSort = null, 23624 _transparentSort = null, 23625 23626 _viewport = new Vector4( 0, 0, _width, _height ), 23627 _scissor = new Vector4( 0, 0, _width, _height ), 23628 _scissorTest = false, 23629 23630 // frustum 23631 23632 _frustum = new Frustum(), 23633 23634 // clipping 23635 23636 _clipping = new WebGLClipping(), 23637 _clippingEnabled = false, 23638 _localClippingEnabled = false, 23639 23640 // camera matrices cache 23641 23642 _projScreenMatrix = new Matrix4(), 23643 23644 _vector3 = new Vector3(); 23645 23646 function getTargetPixelRatio() { 23647 23648 return _currentRenderTarget === null ? _pixelRatio : 1; 23649 23650 } 23651 23652 // initialize 23653 23654 var _gl; 23655 23656 try { 23657 23658 var contextAttributes = { 23659 alpha: _alpha, 23660 depth: _depth, 23661 stencil: _stencil, 23662 antialias: _antialias, 23663 premultipliedAlpha: _premultipliedAlpha, 23664 preserveDrawingBuffer: _preserveDrawingBuffer, 23665 powerPreference: _powerPreference, 23666 failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat, 23667 xrCompatible: true 23668 }; 23669 23670 // event listeners must be registered before WebGL context is created, see #12753 23671 23672 _canvas.addEventListener( 'webglcontextlost', onContextLost, false ); 23673 _canvas.addEventListener( 'webglcontextrestored', onContextRestore, false ); 23674 23675 _gl = _context || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes ); 23676 23677 if ( _gl === null ) { 23678 23679 if ( _canvas.getContext( 'webgl' ) !== null ) { 23680 23681 throw new Error( 'Error creating WebGL context with your selected attributes.' ); 23682 23683 } else { 23684 23685 throw new Error( 'Error creating WebGL context.' ); 23686 23687 } 23688 23689 } 23690 23691 // Some experimental-webgl implementations do not have getShaderPrecisionFormat 23692 23693 if ( _gl.getShaderPrecisionFormat === undefined ) { 23694 23695 _gl.getShaderPrecisionFormat = function () { 23696 23697 return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 }; 23698 23699 }; 23700 23701 } 23702 23703 } catch ( error ) { 23704 23705 console.error( 'THREE.WebGLRenderer: ' + error.message ); 23706 throw error; 23707 23708 } 23709 23710 var extensions, capabilities, state, info; 23711 var properties, textures, attributes, geometries, objects; 23712 var programCache, renderLists, renderStates; 23713 23714 var background, morphtargets, bufferRenderer, indexedBufferRenderer; 23715 23716 var utils; 23717 23718 function initGLContext() { 23719 23720 extensions = new WebGLExtensions( _gl ); 23721 23722 capabilities = new WebGLCapabilities( _gl, extensions, parameters ); 23723 23724 if ( capabilities.isWebGL2 === false ) { 23725 23726 extensions.get( 'WEBGL_depth_texture' ); 23727 extensions.get( 'OES_texture_float' ); 23728 extensions.get( 'OES_texture_half_float' ); 23729 extensions.get( 'OES_texture_half_float_linear' ); 23730 extensions.get( 'OES_standard_derivatives' ); 23731 extensions.get( 'OES_element_index_uint' ); 23732 extensions.get( 'ANGLE_instanced_arrays' ); 23733 23734 } 23735 23736 extensions.get( 'OES_texture_float_linear' ); 23737 23738 utils = new WebGLUtils( _gl, extensions, capabilities ); 23739 23740 state = new WebGLState( _gl, extensions, capabilities ); 23741 state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() ); 23742 state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() ); 23743 23744 info = new WebGLInfo( _gl ); 23745 properties = new WebGLProperties(); 23746 textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ); 23747 attributes = new WebGLAttributes( _gl, capabilities ); 23748 geometries = new WebGLGeometries( _gl, attributes, info ); 23749 objects = new WebGLObjects( _gl, geometries, attributes, info ); 23750 morphtargets = new WebGLMorphtargets( _gl ); 23751 programCache = new WebGLPrograms( _this, extensions, capabilities ); 23752 renderLists = new WebGLRenderLists(); 23753 renderStates = new WebGLRenderStates(); 23754
vendor: 15,437 bytes, lines 23755-24505
23755 background = new WebGLBackground( _this, state, objects, _premultipliedAlpha ); 23756 23757 bufferRenderer = new WebGLBufferRenderer( _gl, extensions, info, capabilities ); 23758 indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info, capabilities ); 23759 23760 info.programs = programCache.programs; 23761 23762 _this.capabilities = capabilities; 23763 _this.extensions = extensions; 23764 _this.properties = properties; 23765 _this.renderLists = renderLists; 23766 _this.state = state; 23767 _this.info = info; 23768 23769 } 23770 23771 initGLContext(); 23772 23773 // xr 23774 23775 var xr = new WebXRManager( _this, _gl ); 23776 23777 this.xr = xr; 23778 23779 // shadow map 23780 23781 var shadowMap = new WebGLShadowMap( _this, objects, capabilities.maxTextureSize ); 23782 23783 this.shadowMap = shadowMap; 23784 23785 // API 23786 23787 this.getContext = function () { 23788 23789 return _gl; 23790 23791 }; 23792 23793 this.getContextAttributes = function () { 23794 23795 return _gl.getContextAttributes(); 23796 23797 }; 23798 23799 this.forceContextLoss = function () { 23800 23801 var extension = extensions.get( 'WEBGL_lose_context' ); 23802 if ( extension ) extension.loseContext(); 23803 23804 }; 23805 23806 this.forceContextRestore = function () { 23807 23808 var extension = extensions.get( 'WEBGL_lose_context' ); 23809 if ( extension ) extension.restoreContext(); 23810 23811 }; 23812 23813 this.getPixelRatio = function () { 23814 23815 return _pixelRatio; 23816 23817 }; 23818 23819 this.setPixelRatio = function ( value ) { 23820 23821 if ( value === undefined ) return; 23822 23823 _pixelRatio = value; 23824 23825 this.setSize( _width, _height, false ); 23826 23827 }; 23828 23829 this.getSize = function ( target ) { 23830 23831 if ( target === undefined ) { 23832 23833 console.warn( 'WebGLRenderer: .getsize() now requires a Vector2 as an argument' ); 23834 23835 target = new Vector2(); 23836 23837 } 23838 23839 return target.set( _width, _height ); 23840 23841 }; 23842 23843 this.setSize = function ( width, height, updateStyle ) { 23844 23845 if ( xr.isPresenting ) { 23846 23847 console.warn( 'THREE.WebGLRenderer: Can\'t change size while VR device is presenting.' ); 23848 return; 23849 23850 } 23851 23852 _width = width; 23853 _height = height; 23854 23855 _canvas.width = Math.floor( width * _pixelRatio ); 23856 _canvas.height = Math.floor( height * _pixelRatio ); 23857 23858 if ( updateStyle !== false ) { 23859 23860 _canvas.style.width = width + 'px'; 23861 _canvas.style.height = height + 'px'; 23862 23863 } 23864 23865 this.setViewport( 0, 0, width, height ); 23866 23867 }; 23868 23869 this.getDrawingBufferSize = function ( target ) { 23870 23871 if ( target === undefined ) { 23872 23873 console.warn( 'WebGLRenderer: .getdrawingBufferSize() now requires a Vector2 as an argument' ); 23874 23875 target = new Vector2(); 23876 23877 } 23878 23879 return target.set( _width * _pixelRatio, _height * _pixelRatio ).floor(); 23880 23881 }; 23882 23883 this.setDrawingBufferSize = function ( width, height, pixelRatio ) { 23884 23885 _width = width; 23886 _height = height; 23887 23888 _pixelRatio = pixelRatio; 23889 23890 _canvas.width = Math.floor( width * pixelRatio ); 23891 _canvas.height = Math.floor( height * pixelRatio ); 23892 23893 this.setViewport( 0, 0, width, height ); 23894 23895 }; 23896 23897 this.getCurrentViewport = function ( target ) { 23898 23899 if ( target === undefined ) { 23900 23901 console.warn( 'WebGLRenderer: .getCurrentViewport() now requires a Vector4 as an argument' ); 23902 23903 target = new Vector4(); 23904 23905 } 23906 23907 return target.copy( _currentViewport ); 23908 23909 }; 23910 23911 this.getViewport = function ( target ) { 23912 23913 return target.copy( _viewport ); 23914 23915 }; 23916 23917 this.setViewport = function ( x, y, width, height ) { 23918 23919 if ( x.isVector4 ) { 23920 23921 _viewport.set( x.x, x.y, x.z, x.w ); 23922 23923 } else { 23924 23925 _viewport.set( x, y, width, height ); 23926 23927 } 23928 23929 state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() ); 23930 23931 }; 23932 23933 this.getScissor = function ( target ) { 23934 23935 return target.copy( _scissor ); 23936 23937 }; 23938 23939 this.setScissor = function ( x, y, width, height ) { 23940 23941 if ( x.isVector4 ) { 23942 23943 _scissor.set( x.x, x.y, x.z, x.w ); 23944 23945 } else { 23946 23947 _scissor.set( x, y, width, height ); 23948 23949 } 23950 23951 state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() ); 23952 23953 }; 23954 23955 this.getScissorTest = function () { 23956 23957 return _scissorTest; 23958 23959 }; 23960 23961 this.setScissorTest = function ( boolean ) { 23962 23963 state.setScissorTest( _scissorTest = boolean ); 23964 23965 }; 23966 23967 this.setOpaqueSort = function ( method ) { 23968 23969 _opaqueSort = method; 23970 23971 }; 23972 23973 this.setTransparentSort = function ( method ) { 23974 23975 _transparentSort = method; 23976 23977 }; 23978 23979 // Clearing 23980 23981 this.getClearColor = function () { 23982 23983 return background.getClearColor(); 23984 23985 }; 23986 23987 this.setClearColor = function () { 23988 23989 background.setClearColor.apply( background, arguments ); 23990 23991 }; 23992 23993 this.getClearAlpha = function () { 23994 23995 return background.getClearAlpha(); 23996 23997 }; 23998 23999 this.setClearAlpha = function () { 24000 24001 background.setClearAlpha.apply( background, arguments ); 24002 24003 }; 24004 24005 this.clear = function ( color, depth, stencil ) { 24006 24007 var bits = 0; 24008 24009 if ( color === undefined || color ) bits |= 16384; 24010 if ( depth === undefined || depth ) bits |= 256; 24011 if ( stencil === undefined || stencil ) bits |= 1024; 24012 24013 _gl.clear( bits ); 24014 24015 }; 24016 24017 this.clearColor = function () { 24018 24019 this.clear( true, false, false ); 24020 24021 }; 24022 24023 this.clearDepth = function () { 24024 24025 this.clear( false, true, false ); 24026 24027 }; 24028 24029 this.clearStencil = function () { 24030 24031 this.clear( false, false, true ); 24032 24033 }; 24034 24035 // 24036 24037 this.dispose = function () { 24038 24039 _canvas.removeEventListener( 'webglcontextlost', onContextLost, false ); 24040 _canvas.removeEventListener( 'webglcontextrestored', onContextRestore, false ); 24041 24042 renderLists.dispose(); 24043 renderStates.dispose(); 24044 properties.dispose(); 24045 objects.dispose(); 24046 24047 xr.dispose(); 24048 24049 animation.stop(); 24050 24051 }; 24052 24053 // Events 24054 24055 function onContextLost( event ) { 24056 24057 event.preventDefault(); 24058 24059 console.log( 'THREE.WebGLRenderer: Context Lost.' ); 24060 24061 _isContextLost = true; 24062 24063 } 24064 24065 function onContextRestore( /* event */ ) { 24066 24067 console.log( 'THREE.WebGLRenderer: Context Restored.' ); 24068 24069 _isContextLost = false; 24070 24071 initGLContext(); 24072 24073 } 24074 24075 function onMaterialDispose( event ) { 24076 24077 var material = event.target; 24078 24079 material.removeEventListener( 'dispose', onMaterialDispose ); 24080 24081 deallocateMaterial( material ); 24082 24083 } 24084 24085 // Buffer deallocation 24086 24087 function deallocateMaterial( material ) { 24088 24089 releaseMaterialProgramReference( material ); 24090 24091 properties.remove( material ); 24092 24093 } 24094 24095 24096 function releaseMaterialProgramReference( material ) { 24097 24098 var programInfo = properties.get( material ).program; 24099 24100 material.program = undefined; 24101 24102 if ( programInfo !== undefined ) { 24103 24104 programCache.releaseProgram( programInfo ); 24105 24106 } 24107 24108 } 24109 24110 // Buffer rendering 24111 24112 function renderObjectImmediate( object, program ) { 24113 24114 object.render( function ( object ) { 24115 24116 _this.renderBufferImmediate( object, program ); 24117 24118 } ); 24119 24120 } 24121 24122 this.renderBufferImmediate = function ( object, program ) { 24123 24124 state.initAttributes(); 24125 24126 var buffers = properties.get( object ); 24127 24128 if ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer(); 24129 if ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer(); 24130 if ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer(); 24131 if ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer(); 24132 24133 var programAttributes = program.getAttributes(); 24134 24135 if ( object.hasPositions ) { 24136 24137 _gl.bindBuffer( 34962, buffers.position ); 24138 _gl.bufferData( 34962, object.positionArray, 35048 ); 24139 24140 state.enableAttribute( programAttributes.position ); 24141 _gl.vertexAttribPointer( programAttributes.position, 3, 5126, false, 0, 0 ); 24142 24143 } 24144 24145 if ( object.hasNormals ) { 24146 24147 _gl.bindBuffer( 34962, buffers.normal ); 24148 _gl.bufferData( 34962, object.normalArray, 35048 ); 24149 24150 state.enableAttribute( programAttributes.normal ); 24151 _gl.vertexAttribPointer( programAttributes.normal, 3, 5126, false, 0, 0 ); 24152 24153 } 24154 24155 if ( object.hasUvs ) { 24156 24157 _gl.bindBuffer( 34962, buffers.uv ); 24158 _gl.bufferData( 34962, object.uvArray, 35048 ); 24159 24160 state.enableAttribute( programAttributes.uv ); 24161 _gl.vertexAttribPointer( programAttributes.uv, 2, 5126, false, 0, 0 ); 24162 24163 } 24164 24165 if ( object.hasColors ) { 24166 24167 _gl.bindBuffer( 34962, buffers.color ); 24168 _gl.bufferData( 34962, object.colorArray, 35048 ); 24169 24170 state.enableAttribute( programAttributes.color ); 24171 _gl.vertexAttribPointer( programAttributes.color, 3, 5126, false, 0, 0 ); 24172 24173 } 24174 24175 state.disableUnusedAttributes(); 24176 24177 _gl.drawArrays( 4, 0, object.count ); 24178 24179 object.count = 0; 24180 24181 }; 24182 24183 var tempScene = new Scene(); 24184 24185 this.renderBufferDirect = function ( camera, scene, geometry, material, object, group ) { 24186 24187 if ( scene === null ) scene = tempScene; // renderBufferDirect second parameter used to be fog (could be null) 24188 24189 var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 ); 24190 24191 var program = setProgram( camera, scene, material, object ); 24192 24193 state.setMaterial( material, frontFaceCW ); 24194 24195 var updateBuffers = false; 24196 24197 if ( _currentGeometryProgram.geometry !== geometry.id || 24198 _currentGeometryProgram.program !== program.id || 24199 _currentGeometryProgram.wireframe !== ( material.wireframe === true ) ) { 24200 24201 _currentGeometryProgram.geometry = geometry.id; 24202 _currentGeometryProgram.program = program.id; 24203 _currentGeometryProgram.wireframe = material.wireframe === true; 24204 updateBuffers = true; 24205 24206 } 24207 24208 if ( material.morphTargets || material.morphNormals ) { 24209 24210 morphtargets.update( object, geometry, material, program ); 24211 24212 updateBuffers = true; 24213 24214 } 24215 24216 if ( object.isInstancedMesh === true ) { 24217 24218 updateBuffers = true; 24219 24220 } 24221 24222 // 24223 24224 var index = geometry.index; 24225 var position = geometry.attributes.position; 24226 24227 // 24228 24229 if ( index === null ) { 24230 24231 if ( position === undefined || position.count === 0 ) return; 24232 24233 } else if ( index.count === 0 ) { 24234 24235 return; 24236 24237 } 24238 24239 // 24240 24241 var rangeFactor = 1; 24242 24243 if ( material.wireframe === true ) { 24244 24245 index = geometries.getWireframeAttribute( geometry ); 24246 rangeFactor = 2; 24247 24248 } 24249 24250 var attribute; 24251 var renderer = bufferRenderer; 24252 24253 if ( index !== null ) { 24254 24255 attribute = attributes.get( index ); 24256 24257 renderer = indexedBufferRenderer; 24258 renderer.setIndex( attribute ); 24259 24260 } 24261 24262 if ( updateBuffers ) { 24263 24264 setupVertexAttributes( object, geometry, material, program ); 24265 24266 if ( index !== null ) { 24267 24268 _gl.bindBuffer( 34963, attribute.buffer ); 24269 24270 } 24271 24272 } 24273 24274 // 24275 24276 var dataCount = ( index !== null ) ? index.count : position.count; 24277 24278 var rangeStart = geometry.drawRange.start * rangeFactor; 24279 var rangeCount = geometry.drawRange.count * rangeFactor; 24280 24281 var groupStart = group !== null ? group.start * rangeFactor : 0; 24282 var groupCount = group !== null ? group.count * rangeFactor : Infinity; 24283 24284 var drawStart = Math.max( rangeStart, groupStart ); 24285 var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1; 24286 24287 var drawCount = Math.max( 0, drawEnd - drawStart + 1 ); 24288 24289 if ( drawCount === 0 ) return; 24290 24291 // 24292 24293 if ( object.isMesh ) { 24294 24295 if ( material.wireframe === true ) { 24296 24297 state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() ); 24298 renderer.setMode( 1 ); 24299 24300 } else { 24301 24302 renderer.setMode( 4 ); 24303 24304 } 24305 24306 } else if ( object.isLine ) { 24307 24308 var lineWidth = material.linewidth; 24309 24310 if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material 24311 24312 state.setLineWidth( lineWidth * getTargetPixelRatio() ); 24313 24314 if ( object.isLineSegments ) { 24315 24316 renderer.setMode( 1 ); 24317 24318 } else if ( object.isLineLoop ) { 24319 24320 renderer.setMode( 2 ); 24321 24322 } else { 24323 24324 renderer.setMode( 3 ); 24325 24326 } 24327 24328 } else if ( object.isPoints ) { 24329 24330 renderer.setMode( 0 ); 24331 24332 } else if ( object.isSprite ) { 24333 24334 renderer.setMode( 4 ); 24335 24336 } 24337 24338 if ( object.isInstancedMesh ) { 24339 24340 renderer.renderInstances( geometry, drawStart, drawCount, object.count ); 24341 24342 } else if ( geometry.isInstancedBufferGeometry ) { 24343 24344 renderer.renderInstances( geometry, drawStart, drawCount, geometry.maxInstancedCount ); 24345 24346 } else { 24347 24348 renderer.render( drawStart, drawCount ); 24349 24350 } 24351 24352 }; 24353 24354 function setupVertexAttributes( object, geometry, material, program ) { 24355 24356 if ( capabilities.isWebGL2 === false && ( object.isInstancedMesh || geometry.isInstancedBufferGeometry ) ) { 24357 24358 if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) return; 24359 24360 } 24361 24362 state.initAttributes(); 24363 24364 var geometryAttributes = geometry.attributes; 24365 24366 var programAttributes = program.getAttributes(); 24367 24368 var materialDefaultAttributeValues = material.defaultAttributeValues; 24369 24370 for ( var name in programAttributes ) { 24371 24372 var programAttribute = programAttributes[ name ]; 24373 24374 if ( programAttribute >= 0 ) { 24375 24376 var geometryAttribute = geometryAttributes[ name ]; 24377 24378 if ( geometryAttribute !== undefined ) { 24379 24380 var normalized = geometryAttribute.normalized; 24381 var size = geometryAttribute.itemSize; 24382 24383 var attribute = attributes.get( geometryAttribute ); 24384 24385 // TODO Attribute may not be available on context restore 24386 24387 if ( attribute === undefined ) continue; 24388 24389 var buffer = attribute.buffer; 24390 var type = attribute.type; 24391 var bytesPerElement = attribute.bytesPerElement; 24392 24393 if ( geometryAttribute.isInterleavedBufferAttribute ) { 24394 24395 var data = geometryAttribute.data; 24396 var stride = data.stride; 24397 var offset = geometryAttribute.offset; 24398 24399 if ( data && data.isInstancedInterleavedBuffer ) { 24400 24401 state.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute ); 24402 24403 if ( geometry.maxInstancedCount === undefined ) { 24404 24405 geometry.maxInstancedCount = data.meshPerAttribute * data.count; 24406 24407 } 24408 24409 } else { 24410 24411 state.enableAttribute( programAttribute ); 24412 24413 } 24414 24415 _gl.bindBuffer( 34962, buffer ); 24416 state.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, offset * bytesPerElement ); 24417 24418 } else { 24419 24420 if ( geometryAttribute.isInstancedBufferAttribute ) { 24421 24422 state.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute ); 24423 24424 if ( geometry.maxInstancedCount === undefined ) { 24425 24426 geometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count; 24427 24428 } 24429 24430 } else { 24431 24432 state.enableAttribute( programAttribute ); 24433 24434 } 24435 24436 _gl.bindBuffer( 34962, buffer ); 24437 state.vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 ); 24438 24439 } 24440 24441 } else if ( name === 'instanceMatrix' ) { 24442 24443 var attribute = attributes.get( object.instanceMatrix ); 24444 24445 // TODO Attribute may not be available on context restore 24446 24447 if ( attribute === undefined ) continue; 24448 24449 var buffer = attribute.buffer; 24450 var type = attribute.type; 24451 24452 state.enableAttributeAndDivisor( programAttribute + 0, 1 ); 24453 state.enableAttributeAndDivisor( programAttribute + 1, 1 ); 24454 state.enableAttributeAndDivisor( programAttribute + 2, 1 ); 24455 state.enableAttributeAndDivisor( programAttribute + 3, 1 ); 24456 24457 _gl.bindBuffer( 34962, buffer ); 24458 24459 _gl.vertexAttribPointer( programAttribute + 0, 4, type, false, 64, 0 ); 24460 _gl.vertexAttribPointer( programAttribute + 1, 4, type, false, 64, 16 ); 24461 _gl.vertexAttribPointer( programAttribute + 2, 4, type, false, 64, 32 ); 24462 _gl.vertexAttribPointer( programAttribute + 3, 4, type, false, 64, 48 ); 24463 24464 } else if ( materialDefaultAttributeValues !== undefined ) { 24465 24466 var value = materialDefaultAttributeValues[ name ]; 24467 24468 if ( value !== undefined ) { 24469 24470 switch ( value.length ) { 24471 24472 case 2: 24473 _gl.vertexAttrib2fv( programAttribute, value ); 24474 break; 24475 24476 case 3: 24477 _gl.vertexAttrib3fv( programAttribute, value ); 24478 break; 24479 24480 case 4: 24481 _gl.vertexAttrib4fv( programAttribute, value ); 24482 break; 24483 24484 default: 24485 _gl.vertexAttrib1fv( programAttribute, value ); 24486 24487 } 24488 24489 } 24490 24491 } 24492 24493 } 24494 24495 } 24496 24497 state.disableUnusedAttributes(); 24498 24499 } 24500 24501 // Compile 24502 24503 this.compile = function ( scene, camera ) { 24504 24505 currentRenderState = renderStates.get( scene, camera );
24506 currentRenderState.init(); 24507 24508 scene.traverse( function ( object ) { 24509 24510 if ( object.isLight ) { 24511 24512 currentRenderState.pushLight( object ); 24513 24514 if ( object.castShadow ) { 24515 24516 currentRenderState.pushShadow( object ); 24517 24518 } 24519 24520 } 24521 24522 } ); 24523 24524 currentRenderState.setupLights( camera ); 24525 24526 var compiled = {}; 24527 24528 scene.traverse( function ( object ) { 24529 24530 if ( object.material ) { 24531 24532 if ( Array.isArray( object.material ) ) { 24533 24534 for ( var i = 0; i < object.material.length; i ++ ) { 24535 24536 if ( object.material[ i ].uuid in compiled === false ) { 24537 24538 initMaterial( object.material[ i ], scene, object ); 24539 compiled[ object.material[ i ].uuid ] = true; 24540 24541 } 24542 24543 } 24544 24545 } else if ( object.material.uuid in compiled === false ) { 24546 24547 initMaterial( object.material, scene, object ); 24548 compiled[ object.material.uuid ] = true; 24549 24550 } 24551 24552 } 24553 24554 } ); 24555 24556 }; 24557 24558 // Animation Loop 24559 24560 var onAnimationFrameCallback = null; 24561 24562 function onAnimationFrame( time ) { 24563 24564 if ( xr.isPresenting ) return; 24565 if ( onAnimationFrameCallback ) onAnimationFrameCallback( time ); 24566 24567 } 24568 24569 var animation = new WebGLAnimation(); 24570 animation.setAnimationLoop( onAnimationFrame ); 24571 24572 if ( typeof window !== 'undefined' ) animation.setContext( window ); 24573 24574 this.setAnimationLoop = function ( callback ) { 24575 24576 onAnimationFrameCallback = callback; 24577 xr.setAnimationLoop( callback ); 24578 24579 animation.start(); 24580 24581 }; 24582 24583 // Rendering 24584 24585 this.render = function ( scene, camera ) { 24586 24587 var renderTarget, forceClear; 24588 24589 if ( arguments[ 2 ] !== undefined ) { 24590 24591 console.warn( 'THREE.WebGLRenderer.render(): the renderTarget argument has been removed. Use .setRenderTarget() instead.' ); 24592 renderTarget = arguments[ 2 ]; 24593 24594 } 24595 24596 if ( arguments[ 3 ] !== undefined ) { 24597 24598 console.warn( 'THREE.WebGLRenderer.render(): the forceClear argument has been removed. Use .clear() instead.' ); 24599 forceClear = arguments[ 3 ]; 24600 24601 } 24602 24603 if ( ! ( camera && camera.isCamera ) ) { 24604 24605 console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' ); 24606 return; 24607 24608 } 24609 24610 if ( _isContextLost ) return; 24611 24612 // reset caching for this frame 24613 24614 _currentGeometryProgram.geometry = null; 24615 _currentGeometryProgram.program = null; 24616 _currentGeometryProgram.wireframe = false; 24617 _currentMaterialId = - 1; 24618 _currentCamera = null; 24619 24620 // update scene graph 24621 24622 if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); 24623 24624 // update camera matrices and frustum 24625 24626 if ( camera.parent === null ) camera.updateMatrixWorld(); 24627 24628 if ( xr.enabled && xr.isPresenting ) { 24629 24630 camera = xr.getCamera( camera ); 24631 24632 } 24633 24634 // 24635 scene.onBeforeRender( _this, scene, camera, renderTarget || _currentRenderTarget ); 24636 24637 currentRenderState = renderStates.get( scene, camera ); 24638 currentRenderState.init(); 24639 24640 _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); 24641 _frustum.setFromProjectionMatrix( _projScreenMatrix ); 24642 24643 _localClippingEnabled = this.localClippingEnabled; 24644 _clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera ); 24645 24646 currentRenderList = renderLists.get( scene, camera ); 24647 currentRenderList.init(); 24648 24649 projectObject( scene, camera, 0, _this.sortObjects ); 24650 24651 currentRenderList.finish(); 24652 24653 if ( _this.sortObjects === true ) { 24654 24655 currentRenderList.sort( _opaqueSort, _transparentSort ); 24656 24657 } 24658 24659 // 24660 24661 if ( _clippingEnabled ) _clipping.beginShadows(); 24662 24663 var shadowsArray = currentRenderState.state.shadowsArray; 24664 24665 shadowMap.render( shadowsArray, scene, camera ); 24666 24667 currentRenderState.setupLights( camera ); 24668 24669 if ( _clippingEnabled ) _clipping.endShadows(); 24670 24671 // 24672 24673 if ( this.info.autoReset ) this.info.reset(); 24674 24675 if ( renderTarget !== undefined ) { 24676 24677 this.setRenderTarget( renderTarget ); 24678 24679 } 24680 24681 // 24682 24683 background.render( currentRenderList, scene, camera, forceClear ); 24684 24685 // render scene 24686 24687 var opaqueObjects = currentRenderList.opaque; 24688 var transparentObjects = currentRenderList.transparent; 24689 24690 if ( scene.overrideMaterial ) { 24691 24692 var overrideMaterial = scene.overrideMaterial; 24693 24694 if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial ); 24695 if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial ); 24696 24697 } else { 24698 24699 // opaque pass (front-to-back order) 24700 24701 if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera ); 24702 24703 // transparent pass (back-to-front order) 24704 24705 if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera ); 24706 24707 } 24708 24709 // 24710 24711 scene.onAfterRender( _this, scene, camera ); 24712 24713 // 24714 24715 if ( _currentRenderTarget !== null ) { 24716 24717 // Generate mipmap if we're using any kind of mipmap filtering 24718 24719 textures.updateRenderTargetMipmap( _currentRenderTarget ); 24720
vendor: 4,701 bytes, lines 24721-24928
24721 // resolve multisample renderbuffers to a single-sample texture if necessary 24722 24723 textures.updateMultisampleRenderTarget( _currentRenderTarget ); 24724 24725 } 24726 24727 // Ensure depth buffer writing is enabled so it can be cleared on next render 24728 24729 state.buffers.depth.setTest( true ); 24730 state.buffers.depth.setMask( true ); 24731 state.buffers.color.setMask( true ); 24732 24733 state.setPolygonOffset( false ); 24734 24735 // _gl.finish(); 24736 24737 currentRenderList = null; 24738 currentRenderState = null; 24739 24740 }; 24741 24742 function projectObject( object, camera, groupOrder, sortObjects ) { 24743 24744 if ( object.visible === false ) return; 24745 24746 var visible = object.layers.test( camera.layers ); 24747 24748 if ( visible ) { 24749 24750 if ( object.isGroup ) { 24751 24752 groupOrder = object.renderOrder; 24753 24754 } else if ( object.isLOD ) { 24755 24756 if ( object.autoUpdate === true ) object.update( camera ); 24757 24758 } else if ( object.isLight ) { 24759 24760 currentRenderState.pushLight( object ); 24761 24762 if ( object.castShadow ) { 24763 24764 currentRenderState.pushShadow( object ); 24765 24766 } 24767 24768 } else if ( object.isSprite ) { 24769 24770 if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) { 24771 24772 if ( sortObjects ) { 24773 24774 _vector3.setFromMatrixPosition( object.matrixWorld ) 24775 .applyMatrix4( _projScreenMatrix ); 24776 24777 } 24778 24779 var geometry = objects.update( object ); 24780 var material = object.material; 24781 24782 if ( material.visible ) { 24783 24784 currentRenderList.push( object, geometry, material, groupOrder, _vector3.z, null ); 24785 24786 } 24787 24788 } 24789 24790 } else if ( object.isImmediateRenderObject ) { 24791 24792 if ( sortObjects ) { 24793 24794 _vector3.setFromMatrixPosition( object.matrixWorld ) 24795 .applyMatrix4( _projScreenMatrix ); 24796 24797 } 24798 24799 currentRenderList.push( object, null, object.material, groupOrder, _vector3.z, null ); 24800 24801 } else if ( object.isMesh || object.isLine || object.isPoints ) { 24802 24803 if ( object.isSkinnedMesh ) { 24804 24805 // update skeleton only once in a frame 24806 24807 if ( object.skeleton.frame !== info.render.frame ) { 24808 24809 object.skeleton.update(); 24810 object.skeleton.frame = info.render.frame; 24811 24812 } 24813 24814 } 24815 24816 if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) { 24817 24818 if ( sortObjects ) { 24819 24820 _vector3.setFromMatrixPosition( object.matrixWorld ) 24821 .applyMatrix4( _projScreenMatrix ); 24822 24823 } 24824 24825 var geometry = objects.update( object ); 24826 var material = object.material; 24827 24828 if ( Array.isArray( material ) ) { 24829 24830 var groups = geometry.groups; 24831 24832 for ( var i = 0, l = groups.length; i < l; i ++ ) { 24833 24834 var group = groups[ i ]; 24835 var groupMaterial = material[ group.materialIndex ]; 24836 24837 if ( groupMaterial && groupMaterial.visible ) { 24838 24839 currentRenderList.push( object, geometry, groupMaterial, groupOrder, _vector3.z, group ); 24840 24841 } 24842 24843 } 24844 24845 } else if ( material.visible ) { 24846 24847 currentRenderList.push( object, geometry, material, groupOrder, _vector3.z, null ); 24848 24849 } 24850 24851 } 24852 24853 } 24854 24855 } 24856 24857 var children = object.children; 24858 24859 for ( var i = 0, l = children.length; i < l; i ++ ) { 24860 24861 projectObject( children[ i ], camera, groupOrder, sortObjects ); 24862 24863 } 24864 24865 } 24866 24867 function renderObjects( renderList, scene, camera, overrideMaterial ) { 24868 24869 for ( var i = 0, l = renderList.length; i < l; i ++ ) { 24870 24871 var renderItem = renderList[ i ]; 24872 24873 var object = renderItem.object; 24874 var geometry = renderItem.geometry; 24875 var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial; 24876 var group = renderItem.group; 24877 24878 if ( camera.isArrayCamera ) { 24879 24880 _currentArrayCamera = camera; 24881 24882 var cameras = camera.cameras; 24883 24884 for ( var j = 0, jl = cameras.length; j < jl; j ++ ) { 24885 24886 var camera2 = cameras[ j ]; 24887 24888 if ( object.layers.test( camera2.layers ) ) { 24889 24890 state.viewport( _currentViewport.copy( camera2.viewport ) ); 24891 24892 currentRenderState.setupLights( camera2 ); 24893 24894 renderObject( object, scene, camera2, geometry, material, group ); 24895 24896 } 24897 24898 } 24899 24900 } else { 24901 24902 _currentArrayCamera = null; 24903 24904 renderObject( object, scene, camera, geometry, material, group ); 24905 24906 } 24907 24908 } 24909 24910 } 24911 24912 function renderObject( object, scene, camera, geometry, material, group ) { 24913 24914 object.onBeforeRender( _this, scene, camera, geometry, material, group ); 24915 currentRenderState = renderStates.get( scene, _currentArrayCamera || camera ); 24916 24917 object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld ); 24918 object.normalMatrix.getNormalMatrix( object.modelViewMatrix ); 24919 24920 if ( object.isImmediateRenderObject ) { 24921 24922 var program = setProgram( camera, scene, material, object ); 24923 24924 state.setMaterial( material ); 24925 24926 _currentGeometryProgram.geometry = null; 24927 _currentGeometryProgram.program = null; 24928 _currentGeometryProgram.wireframe = false;
24929 24930 renderObjectImmediate( object, program ); 24931 24932 } else { 24933 24934 _this.renderBufferDirect( camera, scene, geometry, material, object, group ); 24935 24936 } 24937 24938 object.onAfterRender( _this, scene, camera, geometry, material, group ); 24939 currentRenderState = renderStates.get( scene, _currentArrayCamera || camera ); 24940 24941 } 24942 24943 function initMaterial( material, scene, object ) { 24944 24945 var materialProperties = properties.get( material ); 24946 24947 var lights = currentRenderState.state.lights; 24948 var shadowsArray = currentRenderState.state.shadowsArray; 24949 24950 var lightsStateVersion = lights.state.version; 24951 24952 var parameters = programCache.getParameters( material, lights.state, shadowsArray, scene, _clipping.numPlanes, _clipping.numIntersection, object ); 24953 var programCacheKey = programCache.getProgramCacheKey( parameters ); 24954 24955 var program = materialProperties.program; 24956 var programChange = true; 24957 24958 if ( program === undefined ) { 24959 24960 // new material 24961 material.addEventListener( 'dispose', onMaterialDispose ); 24962 24963 } else if ( program.cacheKey !== programCacheKey ) { 24964 24965 // changed glsl or parameters 24966 releaseMaterialProgramReference( material ); 24967 24968 } else if ( materialProperties.lightsStateVersion !== lightsStateVersion ) { 24969 24970 materialProperties.lightsStateVersion = lightsStateVersion; 24971 24972 programChange = false; 24973 24974 } else if ( parameters.shaderID !== undefined ) { 24975 24976 // same glsl and uniform list 24977 return; 24978 24979 } else { 24980 24981 // only rebuild uniform list 24982 programChange = false; 24983 24984 } 24985 24986 if ( programChange ) { 24987 24988 program = programCache.acquireProgram( parameters, programCacheKey ); 24989 24990 materialProperties.program = program; 24991 materialProperties.uniforms = parameters.uniforms; 24992 materialProperties.outputEncoding = parameters.outputEncoding; 24993 material.program = program; 24994 24995 } 24996 24997 var programAttributes = program.getAttributes(); 24998 24999 if ( material.morphTargets ) { 25000 25001 material.numSupportedMorphTargets = 0; 25002 25003 for ( var i = 0; i < _this.maxMorphTargets; i ++ ) { 25004 25005 if ( programAttributes[ 'morphTarget' + i ] >= 0 ) { 25006 25007 material.numSupportedMorphTargets ++; 25008 25009 } 25010 25011 } 25012 25013 } 25014 25015 if ( material.morphNormals ) { 25016 25017 material.numSupportedMorphNormals = 0; 25018 25019 for ( var i = 0; i < _this.maxMorphNormals; i ++ ) { 25020 25021 if ( programAttributes[ 'morphNormal' + i ] >= 0 ) { 25022 25023 material.numSupportedMorphNormals ++; 25024 25025 } 25026 25027 } 25028 25029 } 25030 25031 var uniforms = materialProperties.uniforms; 25032 25033 if ( ! material.isShaderMaterial && 25034 ! material.isRawShaderMaterial || 25035 material.clipping === true ) { 25036 25037 materialProperties.numClippingPlanes = _clipping.numPlanes; 25038 materialProperties.numIntersection = _clipping.numIntersection; 25039 uniforms.clippingPlanes = _clipping.uniform; 25040 25041 } 25042 25043 materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null; 25044 materialProperties.fog = scene.fog; 25045 25046 // store the light setup it was created for 25047 25048 materialProperties.needsLights = materialNeedsLights( material ); 25049 materialProperties.lightsStateVersion = lightsStateVersion; 25050 25051 if ( materialProperties.needsLights ) { 25052 25053 // wire up the material to this renderer's lighting state 25054 25055 uniforms.ambientLightColor.value = lights.state.ambient; 25056 uniforms.lightProbe.value = lights.state.probe; 25057 uniforms.directionalLights.value = lights.state.directional; 25058 uniforms.directionalLightShadows.value = lights.state.directionalShadow; 25059 uniforms.spotLights.value = lights.state.spot; 25060 uniforms.spotLightShadows.value = lights.state.spotShadow; 25061 uniforms.rectAreaLights.value = lights.state.rectArea; 25062 uniforms.pointLights.value = lights.state.point; 25063 uniforms.pointLightShadows.value = lights.state.pointShadow; 25064 uniforms.hemisphereLights.value = lights.state.hemi; 25065 25066 uniforms.directionalShadowMap.value = lights.state.directionalShadowMap; 25067 uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix; 25068 uniforms.spotShadowMap.value = lights.state.spotShadowMap; 25069 uniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix; 25070 uniforms.pointShadowMap.value = lights.state.pointShadowMap; 25071 uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; 25072 // TODO (abelnation): add area lights shadow info to uniforms 25073 25074 } 25075 25076 var progUniforms = materialProperties.program.getUniforms(), 25077 uniformsList = 25078 WebGLUniforms.seqWithValue( progUniforms.seq, uniforms ); 25079 25080 materialProperties.uniformsList = uniformsList; 25081 25082 } 25083 25084 function setProgram( camera, scene, material, object ) { 25085 25086 textures.resetTextureUnits(); 25087 25088 var fog = scene.fog; 25089 var environment = material.isMeshStandardMaterial ? scene.environment : null; 25090 var encoding = ( _currentRenderTarget === null ) ? _this.outputEncoding : _currentRenderTarget.texture.encoding; 25091 25092 var materialProperties = properties.get( material ); 25093 var lights = currentRenderState.state.lights; 25094 25095 if ( _clippingEnabled ) { 25096 25097 if ( _localClippingEnabled || camera !== _currentCamera ) { 25098 25099 var useCache = 25100 camera === _currentCamera && 25101 material.id === _currentMaterialId; 25102
25103 // we might want to call this function with some ClippingGroup 25104 // object instead of the material, once it becomes feasible 25105 // (#8465, #8379) 25106 _clipping.setState( 25107 material.clippingPlanes, material.clipIntersection, material.clipShadows, 25108 camera, materialProperties, useCache ); 25109 25110 } 25111 25112 } 25113 25114 if ( material.version === materialProperties.__version ) { 25115 25116 if ( materialProperties.program === undefined ) { 25117 25118 initMaterial( material, scene, object ); 25119 25120 } else if ( material.fog && materialProperties.fog !== fog ) { 25121 25122 initMaterial( material, scene, object ); 25123 25124 } else if ( materialProperties.environment !== environment ) { 25125 25126 initMaterial( material, scene, object ); 25127 25128 } else if ( materialProperties.needsLights && ( materialProperties.lightsStateVersion !== lights.state.version ) ) { 25129 25130 initMaterial( material, scene, object ); 25131 25132 } else if ( materialProperties.numClippingPlanes !== undefined && 25133 ( materialProperties.numClippingPlanes !== _clipping.numPlanes || 25134 materialProperties.numIntersection !== _clipping.numIntersection ) ) { 25135 25136 initMaterial( material, scene, object ); 25137 25138 } else if ( materialProperties.outputEncoding !== encoding ) { 25139 25140 initMaterial( material, scene, object ); 25141 25142 } 25143 25144 } else { 25145 25146 initMaterial( material, scene, object ); 25147 materialProperties.__version = material.version; 25148 25149 } 25150 25151 var refreshProgram = false; 25152 var refreshMaterial = false; 25153 var refreshLights = false; 25154 25155 var program = materialProperties.program, 25156 p_uniforms = program.getUniforms(), 25157 m_uniforms = materialProperties.uniforms; 25158 25159 if ( state.useProgram( program.program ) ) { 25160 25161 refreshProgram = true; 25162 refreshMaterial = true; 25163 refreshLights = true; 25164 25165 } 25166 25167 if ( material.id !== _currentMaterialId ) { 25168 25169 _currentMaterialId = material.id; 25170 25171 refreshMaterial = true; 25172 25173 } 25174 25175 if ( refreshProgram || _currentCamera !== camera ) { 25176 25177 p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix ); 25178 25179 if ( capabilities.logarithmicDepthBuffer ) { 25180 25181 p_uniforms.setValue( _gl, 'logDepthBufFC', 25182 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) ); 25183 25184 } 25185
vendor: 41,417 bytes, lines 25186-27123
25186 if ( _currentCamera !== camera ) { 25187 25188 _currentCamera = camera; 25189 25190 // lighting uniforms depend on the camera so enforce an update 25191 // now, in case this material supports lights - or later, when 25192 // the next material that does gets activated: 25193 25194 refreshMaterial = true; // set to true on material change 25195 refreshLights = true; // remains set until update done 25196 25197 } 25198 25199 // load material specific uniforms 25200 // (shader material also gets them for the sake of genericity) 25201 25202 if ( material.isShaderMaterial || 25203 material.isMeshPhongMaterial || 25204 material.isMeshToonMaterial || 25205 material.isMeshStandardMaterial || 25206 material.envMap ) { 25207 25208 var uCamPos = p_uniforms.map.cameraPosition; 25209 25210 if ( uCamPos !== undefined ) { 25211 25212 uCamPos.setValue( _gl, 25213 _vector3.setFromMatrixPosition( camera.matrixWorld ) ); 25214 25215 } 25216 25217 } 25218 25219 if ( material.isMeshPhongMaterial || 25220 material.isMeshToonMaterial || 25221 material.isMeshLambertMaterial || 25222 material.isMeshBasicMaterial || 25223 material.isMeshStandardMaterial || 25224 material.isShaderMaterial ) { 25225 25226 p_uniforms.setValue( _gl, 'isOrthographic', camera.isOrthographicCamera === true ); 25227 25228 } 25229 25230 if ( material.isMeshPhongMaterial || 25231 material.isMeshToonMaterial || 25232 material.isMeshLambertMaterial || 25233 material.isMeshBasicMaterial || 25234 material.isMeshStandardMaterial || 25235 material.isShaderMaterial || 25236 material.skinning ) { 25237 25238 p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse ); 25239 25240 } 25241 25242 } 25243 25244 // skinning uniforms must be set even if material didn't change 25245 // auto-setting of texture unit for bone texture must go before other textures 25246 // otherwise textures used for skinning can take over texture units reserved for other material textures 25247 25248 if ( material.skinning ) { 25249 25250 p_uniforms.setOptional( _gl, object, 'bindMatrix' ); 25251 p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' ); 25252 25253 var skeleton = object.skeleton; 25254 25255 if ( skeleton ) { 25256 25257 var bones = skeleton.bones; 25258 25259 if ( capabilities.floatVertexTextures ) { 25260 25261 if ( skeleton.boneTexture === undefined ) { 25262 25263 // layout (1 matrix = 4 pixels) 25264 // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4) 25265 // with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8) 25266 // 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16) 25267 // 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32) 25268 // 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64) 25269 25270 25271 var size = Math.sqrt( bones.length * 4 ); // 4 pixels needed for 1 matrix 25272 size = MathUtils.ceilPowerOfTwo( size ); 25273 size = Math.max( size, 4 ); 25274 25275 var boneMatrices = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel 25276 boneMatrices.set( skeleton.boneMatrices ); // copy current values 25277 25278 var boneTexture = new DataTexture( boneMatrices, size, size, RGBAFormat, FloatType ); 25279 25280 skeleton.boneMatrices = boneMatrices; 25281 skeleton.boneTexture = boneTexture; 25282 skeleton.boneTextureSize = size; 25283 25284 } 25285 25286 p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture, textures ); 25287 p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize ); 25288 25289 } else { 25290 25291 p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' ); 25292 25293 } 25294 25295 } 25296 25297 } 25298 25299 if ( refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow ) { 25300 25301 materialProperties.receiveShadow = object.receiveShadow; 25302 p_uniforms.setValue( _gl, 'receiveShadow', object.receiveShadow ); 25303 25304 } 25305 25306 if ( refreshMaterial ) { 25307 25308 p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure ); 25309 p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint ); 25310 25311 if ( materialProperties.needsLights ) { 25312 25313 // the current material requires lighting info 25314 25315 // note: all lighting uniforms are always set correctly 25316 // they simply reference the renderer's state for their 25317 // values 25318 // 25319 // use the current material's .needsUpdate flags to set 25320 // the GL state when required 25321 25322 markUniformsLightsNeedsUpdate( m_uniforms, refreshLights ); 25323 25324 } 25325 25326 // refresh uniforms common to several materials 25327 25328 if ( fog && material.fog ) { 25329 25330 refreshUniformsFog( m_uniforms, fog ); 25331 25332 } 25333 25334 if ( material.isMeshBasicMaterial ) { 25335 25336 refreshUniformsCommon( m_uniforms, material ); 25337 25338 } else if ( material.isMeshLambertMaterial ) { 25339 25340 refreshUniformsCommon( m_uniforms, material ); 25341 refreshUniformsLambert( m_uniforms, material ); 25342 25343 } else if ( material.isMeshToonMaterial ) { 25344 25345 refreshUniformsCommon( m_uniforms, material ); 25346 refreshUniformsToon( m_uniforms, material ); 25347 25348 } else if ( material.isMeshPhongMaterial ) { 25349 25350 refreshUniformsCommon( m_uniforms, material ); 25351 refreshUniformsPhong( m_uniforms, material ); 25352 25353 } else if ( material.isMeshStandardMaterial ) { 25354 25355 refreshUniformsCommon( m_uniforms, material, environment ); 25356 25357 if ( material.isMeshPhysicalMaterial ) { 25358 25359 refreshUniformsPhysical( m_uniforms, material, environment ); 25360 25361 } else { 25362 25363 refreshUniformsStandard( m_uniforms, material, environment ); 25364 25365 } 25366 25367 } else if ( material.isMeshMatcapMaterial ) { 25368 25369 refreshUniformsCommon( m_uniforms, material ); 25370 refreshUniformsMatcap( m_uniforms, material ); 25371 25372 } else if ( material.isMeshDepthMaterial ) { 25373 25374 refreshUniformsCommon( m_uniforms, material ); 25375 refreshUniformsDepth( m_uniforms, material ); 25376 25377 } else if ( material.isMeshDistanceMaterial ) { 25378 25379 refreshUniformsCommon( m_uniforms, material ); 25380 refreshUniformsDistance( m_uniforms, material ); 25381 25382 } else if ( material.isMeshNormalMaterial ) { 25383 25384 refreshUniformsCommon( m_uniforms, material ); 25385 refreshUniformsNormal( m_uniforms, material ); 25386 25387 } else if ( material.isLineBasicMaterial ) { 25388 25389 refreshUniformsLine( m_uniforms, material ); 25390 25391 if ( material.isLineDashedMaterial ) { 25392 25393 refreshUniformsDash( m_uniforms, material ); 25394 25395 } 25396 25397 } else if ( material.isPointsMaterial ) { 25398 25399 refreshUniformsPoints( m_uniforms, material ); 25400 25401 } else if ( material.isSpriteMaterial ) { 25402 25403 refreshUniformsSprites( m_uniforms, material ); 25404 25405 } else if ( material.isShadowMaterial ) { 25406 25407 m_uniforms.color.value.copy( material.color ); 25408 m_uniforms.opacity.value = material.opacity; 25409 25410 } 25411 25412 // RectAreaLight Texture 25413 // TODO (mrdoob): Find a nicer implementation 25414 25415 if ( m_uniforms.ltc_1 !== undefined ) m_uniforms.ltc_1.value = UniformsLib.LTC_1; 25416 if ( m_uniforms.ltc_2 !== undefined ) m_uniforms.ltc_2.value = UniformsLib.LTC_2; 25417 25418 WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures ); 25419 25420 if ( material.isShaderMaterial ) { 25421 25422 material.uniformsNeedUpdate = false; // #15581 25423 25424 } 25425 25426 } 25427 25428 if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) { 25429 25430 WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures ); 25431 material.uniformsNeedUpdate = false; 25432 25433 } 25434 25435 if ( material.isSpriteMaterial ) { 25436 25437 p_uniforms.setValue( _gl, 'center', object.center ); 25438 25439 } 25440 25441 // common matrices 25442 25443 p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix ); 25444 p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix ); 25445 p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld ); 25446 25447 return program; 25448 25449 } 25450 25451 // Uniforms (refresh uniforms objects) 25452 25453 function refreshUniformsCommon( uniforms, material, environment ) { 25454 25455 uniforms.opacity.value = material.opacity; 25456 25457 if ( material.color ) { 25458 25459 uniforms.diffuse.value.copy( material.color ); 25460 25461 } 25462 25463 if ( material.emissive ) { 25464 25465 uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity ); 25466 25467 } 25468 25469 if ( material.map ) { 25470 25471 uniforms.map.value = material.map; 25472 25473 } 25474 25475 if ( material.alphaMap ) { 25476 25477 uniforms.alphaMap.value = material.alphaMap; 25478 25479 } 25480 25481 if ( material.specularMap ) { 25482 25483 uniforms.specularMap.value = material.specularMap; 25484 25485 } 25486 25487 var envMap = material.envMap || environment; 25488 25489 if ( envMap ) { 25490 25491 uniforms.envMap.value = envMap; 25492 25493 uniforms.flipEnvMap.value = envMap.isCubeTexture ? - 1 : 1; 25494 25495 uniforms.reflectivity.value = material.reflectivity; 25496 uniforms.refractionRatio.value = material.refractionRatio; 25497 25498 uniforms.maxMipLevel.value = properties.get( envMap ).__maxMipLevel; 25499 25500 } 25501 25502 if ( material.lightMap ) { 25503 25504 uniforms.lightMap.value = material.lightMap; 25505 uniforms.lightMapIntensity.value = material.lightMapIntensity; 25506 25507 } 25508 25509 if ( material.aoMap ) { 25510 25511 uniforms.aoMap.value = material.aoMap; 25512 uniforms.aoMapIntensity.value = material.aoMapIntensity; 25513 25514 } 25515 25516 // uv repeat and offset setting priorities 25517 // 1. color map 25518 // 2. specular map 25519 // 3. normal map 25520 // 4. bump map 25521 // 5. alpha map 25522 // 6. emissive map 25523 25524 var uvScaleMap; 25525 25526 if ( material.map ) { 25527 25528 uvScaleMap = material.map; 25529 25530 } else if ( material.specularMap ) { 25531 25532 uvScaleMap = material.specularMap; 25533 25534 } else if ( material.displacementMap ) { 25535 25536 uvScaleMap = material.displacementMap; 25537 25538 } else if ( material.normalMap ) { 25539 25540 uvScaleMap = material.normalMap; 25541 25542 } else if ( material.bumpMap ) { 25543 25544 uvScaleMap = material.bumpMap; 25545 25546 } else if ( material.roughnessMap ) { 25547 25548 uvScaleMap = material.roughnessMap; 25549 25550 } else if ( material.metalnessMap ) { 25551 25552 uvScaleMap = material.metalnessMap; 25553 25554 } else if ( material.alphaMap ) { 25555 25556 uvScaleMap = material.alphaMap; 25557 25558 } else if ( material.emissiveMap ) { 25559 25560 uvScaleMap = material.emissiveMap; 25561 25562 } 25563 25564 if ( uvScaleMap !== undefined ) { 25565 25566 // backwards compatibility 25567 if ( uvScaleMap.isWebGLRenderTarget ) { 25568 25569 uvScaleMap = uvScaleMap.texture; 25570 25571 } 25572 25573 if ( uvScaleMap.matrixAutoUpdate === true ) { 25574 25575 uvScaleMap.updateMatrix(); 25576 25577 } 25578 25579 uniforms.uvTransform.value.copy( uvScaleMap.matrix ); 25580 25581 } 25582 25583 // uv repeat and offset setting priorities for uv2 25584 // 1. ao map 25585 // 2. light map 25586 25587 var uv2ScaleMap; 25588 25589 if ( material.aoMap ) { 25590 25591 uv2ScaleMap = material.aoMap; 25592 25593 } else if ( material.lightMap ) { 25594 25595 uv2ScaleMap = material.lightMap; 25596 25597 } 25598 25599 if ( uv2ScaleMap !== undefined ) { 25600 25601 // backwards compatibility 25602 if ( uv2ScaleMap.isWebGLRenderTarget ) { 25603 25604 uv2ScaleMap = uv2ScaleMap.texture; 25605 25606 } 25607 25608 if ( uv2ScaleMap.matrixAutoUpdate === true ) { 25609 25610 uv2ScaleMap.updateMatrix(); 25611 25612 } 25613 25614 uniforms.uv2Transform.value.copy( uv2ScaleMap.matrix ); 25615 25616 } 25617 25618 } 25619 25620 function refreshUniformsLine( uniforms, material ) { 25621 25622 uniforms.diffuse.value.copy( material.color ); 25623 uniforms.opacity.value = material.opacity; 25624 25625 } 25626 25627 function refreshUniformsDash( uniforms, material ) { 25628 25629 uniforms.dashSize.value = material.dashSize; 25630 uniforms.totalSize.value = material.dashSize + material.gapSize; 25631 uniforms.scale.value = material.scale; 25632 25633 } 25634 25635 function refreshUniformsPoints( uniforms, material ) { 25636 25637 uniforms.diffuse.value.copy( material.color ); 25638 uniforms.opacity.value = material.opacity; 25639 uniforms.size.value = material.size * _pixelRatio; 25640 uniforms.scale.value = _height * 0.5; 25641 25642 if ( material.map ) { 25643 25644 uniforms.map.value = material.map; 25645 25646 } 25647 25648 if ( material.alphaMap ) { 25649 25650 uniforms.alphaMap.value = material.alphaMap; 25651 25652 } 25653 25654 // uv repeat and offset setting priorities 25655 // 1. color map 25656 // 2. alpha map 25657 25658 var uvScaleMap; 25659 25660 if ( material.map ) { 25661 25662 uvScaleMap = material.map; 25663 25664 } else if ( material.alphaMap ) { 25665 25666 uvScaleMap = material.alphaMap; 25667 25668 } 25669 25670 if ( uvScaleMap !== undefined ) { 25671 25672 if ( uvScaleMap.matrixAutoUpdate === true ) { 25673 25674 uvScaleMap.updateMatrix(); 25675 25676 } 25677 25678 uniforms.uvTransform.value.copy( uvScaleMap.matrix ); 25679 25680 } 25681 25682 } 25683 25684 function refreshUniformsSprites( uniforms, material ) { 25685 25686 uniforms.diffuse.value.copy( material.color ); 25687 uniforms.opacity.value = material.opacity; 25688 uniforms.rotation.value = material.rotation; 25689 25690 if ( material.map ) { 25691 25692 uniforms.map.value = material.map; 25693 25694 } 25695 25696 if ( material.alphaMap ) { 25697 25698 uniforms.alphaMap.value = material.alphaMap; 25699 25700 } 25701 25702 // uv repeat and offset setting priorities 25703 // 1. color map 25704 // 2. alpha map 25705 25706 var uvScaleMap; 25707 25708 if ( material.map ) { 25709 25710 uvScaleMap = material.map; 25711 25712 } else if ( material.alphaMap ) { 25713 25714 uvScaleMap = material.alphaMap; 25715 25716 } 25717 25718 if ( uvScaleMap !== undefined ) { 25719 25720 if ( uvScaleMap.matrixAutoUpdate === true ) { 25721 25722 uvScaleMap.updateMatrix(); 25723 25724 } 25725 25726 uniforms.uvTransform.value.copy( uvScaleMap.matrix ); 25727 25728 } 25729 25730 } 25731 25732 function refreshUniformsFog( uniforms, fog ) { 25733 25734 uniforms.fogColor.value.copy( fog.color ); 25735 25736 if ( fog.isFog ) { 25737 25738 uniforms.fogNear.value = fog.near; 25739 uniforms.fogFar.value = fog.far; 25740 25741 } else if ( fog.isFogExp2 ) { 25742 25743 uniforms.fogDensity.value = fog.density; 25744 25745 } 25746 25747 } 25748 25749 function refreshUniformsLambert( uniforms, material ) { 25750 25751 if ( material.emissiveMap ) { 25752 25753 uniforms.emissiveMap.value = material.emissiveMap; 25754 25755 } 25756 25757 } 25758 25759 function refreshUniformsPhong( uniforms, material ) { 25760 25761 uniforms.specular.value.copy( material.specular ); 25762 uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 ) 25763 25764 if ( material.emissiveMap ) { 25765 25766 uniforms.emissiveMap.value = material.emissiveMap; 25767 25768 } 25769 25770 if ( material.bumpMap ) { 25771 25772 uniforms.bumpMap.value = material.bumpMap; 25773 uniforms.bumpScale.value = material.bumpScale; 25774 if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; 25775 25776 } 25777 25778 if ( material.normalMap ) { 25779 25780 uniforms.normalMap.value = material.normalMap; 25781 uniforms.normalScale.value.copy( material.normalScale ); 25782 if ( material.side === BackSide ) uniforms.normalScale.value.negate(); 25783 25784 } 25785 25786 if ( material.displacementMap ) { 25787 25788 uniforms.displacementMap.value = material.displacementMap; 25789 uniforms.displacementScale.value = material.displacementScale; 25790 uniforms.displacementBias.value = material.displacementBias; 25791 25792 } 25793 25794 } 25795 25796 function refreshUniformsToon( uniforms, material ) { 25797 25798 uniforms.specular.value.copy( material.specular ); 25799 uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 ) 25800 25801 if ( material.gradientMap ) { 25802 25803 uniforms.gradientMap.value = material.gradientMap; 25804 25805 } 25806 25807 if ( material.emissiveMap ) { 25808 25809 uniforms.emissiveMap.value = material.emissiveMap; 25810 25811 } 25812 25813 if ( material.bumpMap ) { 25814 25815 uniforms.bumpMap.value = material.bumpMap; 25816 uniforms.bumpScale.value = material.bumpScale; 25817 if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; 25818 25819 } 25820 25821 if ( material.normalMap ) { 25822 25823 uniforms.normalMap.value = material.normalMap; 25824 uniforms.normalScale.value.copy( material.normalScale ); 25825 if ( material.side === BackSide ) uniforms.normalScale.value.negate(); 25826 25827 } 25828 25829 if ( material.displacementMap ) { 25830 25831 uniforms.displacementMap.value = material.displacementMap; 25832 uniforms.displacementScale.value = material.displacementScale; 25833 uniforms.displacementBias.value = material.displacementBias; 25834 25835 } 25836 25837 } 25838 25839 function refreshUniformsStandard( uniforms, material, environment ) { 25840 25841 uniforms.roughness.value = material.roughness; 25842 uniforms.metalness.value = material.metalness; 25843 25844 if ( material.roughnessMap ) { 25845 25846 uniforms.roughnessMap.value = material.roughnessMap; 25847 25848 } 25849 25850 if ( material.metalnessMap ) { 25851 25852 uniforms.metalnessMap.value = material.metalnessMap; 25853 25854 } 25855 25856 if ( material.emissiveMap ) { 25857 25858 uniforms.emissiveMap.value = material.emissiveMap; 25859 25860 } 25861 25862 if ( material.bumpMap ) { 25863 25864 uniforms.bumpMap.value = material.bumpMap; 25865 uniforms.bumpScale.value = material.bumpScale; 25866 if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; 25867 25868 } 25869 25870 if ( material.normalMap ) { 25871 25872 uniforms.normalMap.value = material.normalMap; 25873 uniforms.normalScale.value.copy( material.normalScale ); 25874 if ( material.side === BackSide ) uniforms.normalScale.value.negate(); 25875 25876 } 25877 25878 if ( material.displacementMap ) { 25879 25880 uniforms.displacementMap.value = material.displacementMap; 25881 uniforms.displacementScale.value = material.displacementScale; 25882 uniforms.displacementBias.value = material.displacementBias; 25883 25884 } 25885 25886 if ( material.envMap || environment ) { 25887 25888 //uniforms.envMap.value = material.envMap; // part of uniforms common 25889 uniforms.envMapIntensity.value = material.envMapIntensity; 25890 25891 } 25892 25893 } 25894 25895 function refreshUniformsPhysical( uniforms, material, environment ) { 25896 25897 refreshUniformsStandard( uniforms, material, environment ); 25898 25899 uniforms.reflectivity.value = material.reflectivity; // also part of uniforms common 25900 25901 uniforms.clearcoat.value = material.clearcoat; 25902 uniforms.clearcoatRoughness.value = material.clearcoatRoughness; 25903 if ( material.sheen ) uniforms.sheen.value.copy( material.sheen ); 25904 25905 if ( material.clearcoatMap ) { 25906 25907 uniforms.clearcoatMap.value = material.clearcoatMap; 25908 25909 } 25910 25911 if ( material.clearcoatRoughnessMap ) { 25912 25913 uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap; 25914 25915 } 25916 25917 if ( material.clearcoatNormalMap ) { 25918 25919 uniforms.clearcoatNormalScale.value.copy( material.clearcoatNormalScale ); 25920 uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap; 25921 25922 if ( material.side === BackSide ) { 25923 25924 uniforms.clearcoatNormalScale.value.negate(); 25925 25926 } 25927 25928 } 25929 25930 uniforms.transparency.value = material.transparency; 25931 25932 } 25933 25934 function refreshUniformsMatcap( uniforms, material ) { 25935 25936 if ( material.matcap ) { 25937 25938 uniforms.matcap.value = material.matcap; 25939 25940 } 25941 25942 if ( material.bumpMap ) { 25943 25944 uniforms.bumpMap.value = material.bumpMap; 25945 uniforms.bumpScale.value = material.bumpScale; 25946 if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; 25947 25948 } 25949 25950 if ( material.normalMap ) { 25951 25952 uniforms.normalMap.value = material.normalMap; 25953 uniforms.normalScale.value.copy( material.normalScale ); 25954 if ( material.side === BackSide ) uniforms.normalScale.value.negate(); 25955 25956 } 25957 25958 if ( material.displacementMap ) { 25959 25960 uniforms.displacementMap.value = material.displacementMap; 25961 uniforms.displacementScale.value = material.displacementScale; 25962 uniforms.displacementBias.value = material.displacementBias; 25963 25964 } 25965 25966 } 25967 25968 function refreshUniformsDepth( uniforms, material ) { 25969 25970 if ( material.displacementMap ) { 25971 25972 uniforms.displacementMap.value = material.displacementMap; 25973 uniforms.displacementScale.value = material.displacementScale; 25974 uniforms.displacementBias.value = material.displacementBias; 25975 25976 } 25977 25978 } 25979 25980 function refreshUniformsDistance( uniforms, material ) { 25981 25982 if ( material.displacementMap ) { 25983 25984 uniforms.displacementMap.value = material.displacementMap; 25985 uniforms.displacementScale.value = material.displacementScale; 25986 uniforms.displacementBias.value = material.displacementBias; 25987 25988 } 25989 25990 uniforms.referencePosition.value.copy( material.referencePosition ); 25991 uniforms.nearDistance.value = material.nearDistance; 25992 uniforms.farDistance.value = material.farDistance; 25993 25994 } 25995 25996 function refreshUniformsNormal( uniforms, material ) { 25997 25998 if ( material.bumpMap ) { 25999 26000 uniforms.bumpMap.value = material.bumpMap; 26001 uniforms.bumpScale.value = material.bumpScale; 26002 if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; 26003 26004 } 26005 26006 if ( material.normalMap ) { 26007 26008 uniforms.normalMap.value = material.normalMap; 26009 uniforms.normalScale.value.copy( material.normalScale ); 26010 if ( material.side === BackSide ) uniforms.normalScale.value.negate(); 26011 26012 } 26013 26014 if ( material.displacementMap ) { 26015 26016 uniforms.displacementMap.value = material.displacementMap; 26017 uniforms.displacementScale.value = material.displacementScale; 26018 uniforms.displacementBias.value = material.displacementBias; 26019 26020 } 26021 26022 } 26023 26024 // If uniforms are marked as clean, they don't need to be loaded to the GPU. 26025 26026 function markUniformsLightsNeedsUpdate( uniforms, value ) { 26027 26028 uniforms.ambientLightColor.needsUpdate = value; 26029 uniforms.lightProbe.needsUpdate = value; 26030 26031 uniforms.directionalLights.needsUpdate = value; 26032 uniforms.directionalLightShadows.needsUpdate = value; 26033 uniforms.pointLights.needsUpdate = value; 26034 uniforms.pointLightShadows.needsUpdate = value; 26035 uniforms.spotLights.needsUpdate = value; 26036 uniforms.spotLightShadows.needsUpdate = value; 26037 uniforms.rectAreaLights.needsUpdate = value; 26038 uniforms.hemisphereLights.needsUpdate = value; 26039 26040 } 26041 26042 function materialNeedsLights( material ) { 26043 26044 return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial || 26045 material.isMeshStandardMaterial || material.isShadowMaterial || 26046 ( material.isShaderMaterial && material.lights === true ); 26047 26048 } 26049 26050 // 26051 this.setFramebuffer = function ( value ) { 26052 26053 if ( _framebuffer !== value && _currentRenderTarget === null ) _gl.bindFramebuffer( 36160, value ); 26054 26055 _framebuffer = value; 26056 26057 }; 26058 26059 this.getActiveCubeFace = function () { 26060 26061 return _currentActiveCubeFace; 26062 26063 }; 26064 26065 this.getActiveMipmapLevel = function () { 26066 26067 return _currentActiveMipmapLevel; 26068 26069 }; 26070 26071 this.getRenderTarget = function () { 26072 26073 return _currentRenderTarget; 26074 26075 }; 26076 26077 this.setRenderTarget = function ( renderTarget, activeCubeFace, activeMipmapLevel ) { 26078 26079 _currentRenderTarget = renderTarget; 26080 _currentActiveCubeFace = activeCubeFace; 26081 _currentActiveMipmapLevel = activeMipmapLevel; 26082 26083 if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) { 26084 26085 textures.setupRenderTarget( renderTarget ); 26086 26087 } 26088 26089 var framebuffer = _framebuffer; 26090 var isCube = false; 26091 26092 if ( renderTarget ) { 26093 26094 var __webglFramebuffer = properties.get( renderTarget ).__webglFramebuffer; 26095 26096 if ( renderTarget.isWebGLCubeRenderTarget ) { 26097 26098 framebuffer = __webglFramebuffer[ activeCubeFace || 0 ]; 26099 isCube = true; 26100 26101 } else if ( renderTarget.isWebGLMultisampleRenderTarget ) { 26102 26103 framebuffer = properties.get( renderTarget ).__webglMultisampledFramebuffer; 26104 26105 } else { 26106 26107 framebuffer = __webglFramebuffer; 26108 26109 } 26110 26111 _currentViewport.copy( renderTarget.viewport ); 26112 _currentScissor.copy( renderTarget.scissor ); 26113 _currentScissorTest = renderTarget.scissorTest; 26114 26115 } else { 26116 26117 _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor(); 26118 _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor(); 26119 _currentScissorTest = _scissorTest; 26120 26121 } 26122 26123 if ( _currentFramebuffer !== framebuffer ) { 26124 26125 _gl.bindFramebuffer( 36160, framebuffer ); 26126 _currentFramebuffer = framebuffer; 26127 26128 } 26129 26130 state.viewport( _currentViewport ); 26131 state.scissor( _currentScissor ); 26132 state.setScissorTest( _currentScissorTest ); 26133 26134 if ( isCube ) { 26135 26136 var textureProperties = properties.get( renderTarget.texture ); 26137 _gl.framebufferTexture2D( 36160, 36064, 34069 + ( activeCubeFace || 0 ), textureProperties.__webglTexture, activeMipmapLevel || 0 ); 26138 26139 } 26140 26141 }; 26142 26143 this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer, activeCubeFaceIndex ) { 26144 26145 if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) { 26146 26147 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' ); 26148 return; 26149 26150 } 26151 26152 var framebuffer = properties.get( renderTarget ).__webglFramebuffer; 26153 26154 if ( renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined ) { 26155 26156 framebuffer = framebuffer[ activeCubeFaceIndex ]; 26157 26158 } 26159 26160 if ( framebuffer ) { 26161 26162 var restore = false; 26163 26164 if ( framebuffer !== _currentFramebuffer ) { 26165 26166 _gl.bindFramebuffer( 36160, framebuffer ); 26167 26168 restore = true; 26169 26170 } 26171 26172 try { 26173 26174 var texture = renderTarget.texture; 26175 var textureFormat = texture.format; 26176 var textureType = texture.type; 26177 26178 if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( 35739 ) ) { 26179 26180 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' ); 26181 return; 26182 26183 } 26184 26185 if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( 35738 ) && // IE11, Edge and Chrome Mac < 52 (#9513) 26186 ! ( textureType === FloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox 26187 ! ( textureType === HalfFloatType && ( capabilities.isWebGL2 ? extensions.get( 'EXT_color_buffer_float' ) : extensions.get( 'EXT_color_buffer_half_float' ) ) ) ) { 26188 26189 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' ); 26190 return; 26191 26192 } 26193 26194 if ( _gl.checkFramebufferStatus( 36160 ) === 36053 ) { 26195 26196 // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604) 26197 26198 if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) { 26199 26200 _gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer ); 26201 26202 } 26203 26204 } else { 26205 26206 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' ); 26207 26208 } 26209 26210 } finally { 26211 26212 if ( restore ) { 26213 26214 _gl.bindFramebuffer( 36160, _currentFramebuffer ); 26215 26216 } 26217 26218 } 26219 26220 } 26221 26222 }; 26223 26224 this.copyFramebufferToTexture = function ( position, texture, level ) { 26225 26226 if ( level === undefined ) level = 0; 26227 26228 var levelScale = Math.pow( 2, - level ); 26229 var width = Math.floor( texture.image.width * levelScale ); 26230 var height = Math.floor( texture.image.height * levelScale ); 26231 var glFormat = utils.convert( texture.format ); 26232 26233 textures.setTexture2D( texture, 0 ); 26234 26235 _gl.copyTexImage2D( 3553, level, glFormat, position.x, position.y, width, height, 0 ); 26236 26237 state.unbindTexture(); 26238 26239 }; 26240 26241 this.copyTextureToTexture = function ( position, srcTexture, dstTexture, level ) { 26242 26243 if ( level === undefined ) level = 0; 26244 26245 var width = srcTexture.image.width; 26246 var height = srcTexture.image.height; 26247 var glFormat = utils.convert( dstTexture.format ); 26248 var glType = utils.convert( dstTexture.type ); 26249 26250 textures.setTexture2D( dstTexture, 0 ); 26251 26252 if ( srcTexture.isDataTexture ) { 26253 26254 _gl.texSubImage2D( 3553, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data ); 26255 26256 } else { 26257 26258 if ( srcTexture.isCompressedTexture ) { 26259 26260 _gl.compressedTexSubImage2D( 3553, level, position.x, position.y, srcTexture.mipmaps[ 0 ].width, srcTexture.mipmaps[ 0 ].height, glFormat, srcTexture.mipmaps[ 0 ].data ); 26261 26262 } else { 26263 26264 _gl.texSubImage2D( 3553, level, position.x, position.y, glFormat, glType, srcTexture.image ); 26265 26266 } 26267 26268 } 26269 26270 // Generate mipmaps only when copying level 0 26271 if ( level === 0 && dstTexture.generateMipmaps ) _gl.generateMipmap( 3553 ); 26272 26273 state.unbindTexture(); 26274 26275 }; 26276 26277 this.initTexture = function ( texture ) { 26278 26279 textures.setTexture2D( texture, 0 ); 26280 26281 state.unbindTexture(); 26282 26283 }; 26284 26285 if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { 26286 26287 __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); // eslint-disable-line no-undef 26288 26289 } 26290 26291} 26292 26293/** 26294 * @author mrdoob / http://mrdoob.com/ 26295 * @author alteredq / http://alteredqualia.com/ 26296 */ 26297 26298function FogExp2( color, density ) { 26299 26300 this.name = ''; 26301 26302 this.color = new Color( color ); 26303 this.density = ( density !== undefined ) ? density : 0.00025; 26304 26305} 26306 26307Object.assign( FogExp2.prototype, { 26308 26309 isFogExp2: true, 26310 26311 clone: function () { 26312 26313 return new FogExp2( this.color, this.density ); 26314 26315 }, 26316 26317 toJSON: function ( /* meta */ ) { 26318 26319 return { 26320 type: 'FogExp2', 26321 color: this.color.getHex(), 26322 density: this.density 26323 }; 26324 26325 } 26326 26327} ); 26328 26329/** 26330 * @author mrdoob / http://mrdoob.com/ 26331 * @author alteredq / http://alteredqualia.com/ 26332 */ 26333 26334function Fog( color, near, far ) { 26335 26336 this.name = ''; 26337 26338 this.color = new Color( color ); 26339 26340 this.near = ( near !== undefined ) ? near : 1; 26341 this.far = ( far !== undefined ) ? far : 1000; 26342 26343} 26344 26345Object.assign( Fog.prototype, { 26346 26347 isFog: true, 26348 26349 clone: function () { 26350 26351 return new Fog( this.color, this.near, this.far ); 26352 26353 }, 26354 26355 toJSON: function ( /* meta */ ) { 26356 26357 return { 26358 type: 'Fog', 26359 color: this.color.getHex(), 26360 near: this.near, 26361 far: this.far 26362 }; 26363 26364 } 26365 26366} ); 26367 26368/** 26369 * @author benaadams / https://twitter.com/ben_a_adams 26370 */ 26371 26372function InterleavedBuffer( array, stride ) { 26373 26374 this.array = array; 26375 this.stride = stride; 26376 this.count = array !== undefined ? array.length / stride : 0; 26377 26378 this.usage = StaticDrawUsage; 26379 this.updateRange = { offset: 0, count: - 1 }; 26380 26381 this.version = 0; 26382 26383} 26384 26385Object.defineProperty( InterleavedBuffer.prototype, 'needsUpdate', { 26386 26387 set: function ( value ) { 26388 26389 if ( value === true ) this.version ++; 26390 26391 } 26392 26393} ); 26394 26395Object.assign( InterleavedBuffer.prototype, { 26396 26397 isInterleavedBuffer: true, 26398 26399 onUploadCallback: function () {}, 26400 26401 setUsage: function ( value ) { 26402 26403 this.usage = value; 26404 26405 return this; 26406 26407 }, 26408 26409 copy: function ( source ) { 26410 26411 this.array = new source.array.constructor( source.array ); 26412 this.count = source.count; 26413 this.stride = source.stride; 26414 this.usage = source.usage; 26415 26416 return this; 26417 26418 }, 26419 26420 copyAt: function ( index1, attribute, index2 ) { 26421 26422 index1 *= this.stride; 26423 index2 *= attribute.stride; 26424 26425 for ( var i = 0, l = this.stride; i < l; i ++ ) { 26426 26427 this.array[ index1 + i ] = attribute.array[ index2 + i ]; 26428 26429 } 26430 26431 return this; 26432 26433 }, 26434 26435 set: function ( value, offset ) { 26436 26437 if ( offset === undefined ) offset = 0; 26438 26439 this.array.set( value, offset ); 26440 26441 return this; 26442 26443 }, 26444 26445 clone: function () { 26446 26447 return new this.constructor().copy( this ); 26448 26449 }, 26450 26451 onUpload: function ( callback ) { 26452 26453 this.onUploadCallback = callback; 26454 26455 return this; 26456 26457 } 26458 26459} ); 26460 26461/** 26462 * @author benaadams / https://twitter.com/ben_a_adams 26463 */ 26464 26465var _vector$6 = new Vector3(); 26466 26467function InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) { 26468 26469 this.data = interleavedBuffer; 26470 this.itemSize = itemSize; 26471 this.offset = offset; 26472 26473 this.normalized = normalized === true; 26474 26475} 26476 26477Object.defineProperties( InterleavedBufferAttribute.prototype, { 26478 26479 count: { 26480 26481 get: function () { 26482 26483 return this.data.count; 26484 26485 } 26486 26487 }, 26488 26489 array: { 26490 26491 get: function () { 26492 26493 return this.data.array; 26494 26495 } 26496 26497 } 26498 26499} ); 26500 26501Object.assign( InterleavedBufferAttribute.prototype, { 26502 26503 isInterleavedBufferAttribute: true, 26504 26505 applyMatrix4: function ( m ) { 26506 26507 for ( var i = 0, l = this.data.count; i < l; i ++ ) { 26508 26509 _vector$6.x = this.getX( i ); 26510 _vector$6.y = this.getY( i ); 26511 _vector$6.z = this.getZ( i ); 26512 26513 _vector$6.applyMatrix4( m ); 26514 26515 this.setXYZ( i, _vector$6.x, _vector$6.y, _vector$6.z ); 26516 26517 } 26518 26519 return this; 26520 26521 }, 26522 26523 setX: function ( index, x ) { 26524 26525 this.data.array[ index * this.data.stride + this.offset ] = x; 26526 26527 return this; 26528 26529 }, 26530 26531 setY: function ( index, y ) { 26532 26533 this.data.array[ index * this.data.stride + this.offset + 1 ] = y; 26534 26535 return this; 26536 26537 }, 26538 26539 setZ: function ( index, z ) { 26540 26541 this.data.array[ index * this.data.stride + this.offset + 2 ] = z; 26542 26543 return this; 26544 26545 }, 26546 26547 setW: function ( index, w ) { 26548 26549 this.data.array[ index * this.data.stride + this.offset + 3 ] = w; 26550 26551 return this; 26552 26553 }, 26554 26555 getX: function ( index ) { 26556 26557 return this.data.array[ index * this.data.stride + this.offset ]; 26558 26559 }, 26560 26561 getY: function ( index ) { 26562 26563 return this.data.array[ index * this.data.stride + this.offset + 1 ]; 26564 26565 }, 26566 26567 getZ: function ( index ) { 26568 26569 return this.data.array[ index * this.data.stride + this.offset + 2 ]; 26570 26571 }, 26572 26573 getW: function ( index ) { 26574 26575 return this.data.array[ index * this.data.stride + this.offset + 3 ]; 26576 26577 }, 26578 26579 setXY: function ( index, x, y ) { 26580 26581 index = index * this.data.stride + this.offset; 26582 26583 this.data.array[ index + 0 ] = x; 26584 this.data.array[ index + 1 ] = y; 26585 26586 return this; 26587 26588 }, 26589 26590 setXYZ: function ( index, x, y, z ) { 26591 26592 index = index * this.data.stride + this.offset; 26593 26594 this.data.array[ index + 0 ] = x; 26595 this.data.array[ index + 1 ] = y; 26596 this.data.array[ index + 2 ] = z; 26597 26598 return this; 26599 26600 }, 26601 26602 setXYZW: function ( index, x, y, z, w ) { 26603 26604 index = index * this.data.stride + this.offset; 26605 26606 this.data.array[ index + 0 ] = x; 26607 this.data.array[ index + 1 ] = y; 26608 this.data.array[ index + 2 ] = z; 26609 this.data.array[ index + 3 ] = w; 26610 26611 return this; 26612 26613 } 26614 26615} ); 26616 26617/** 26618 * @author alteredq / http://alteredqualia.com/ 26619 * 26620 * parameters = { 26621 * color: <hex>, 26622 * map: new THREE.Texture( <Image> ), 26623 * alphaMap: new THREE.Texture( <Image> ), 26624 * rotation: <float>, 26625 * sizeAttenuation: <bool> 26626 * } 26627 */ 26628 26629function SpriteMaterial( parameters ) { 26630 26631 Material.call( this ); 26632 26633 this.type = 'SpriteMaterial'; 26634 26635 this.color = new Color( 0xffffff ); 26636 26637 this.map = null; 26638 26639 this.alphaMap = null; 26640 26641 this.rotation = 0; 26642 26643 this.sizeAttenuation = true; 26644 26645 this.transparent = true; 26646 26647 this.setValues( parameters ); 26648 26649} 26650 26651SpriteMaterial.prototype = Object.create( Material.prototype ); 26652SpriteMaterial.prototype.constructor = SpriteMaterial; 26653SpriteMaterial.prototype.isSpriteMaterial = true; 26654 26655SpriteMaterial.prototype.copy = function ( source ) { 26656 26657 Material.prototype.copy.call( this, source ); 26658 26659 this.color.copy( source.color ); 26660 26661 this.map = source.map; 26662 26663 this.alphaMap = source.alphaMap; 26664 26665 this.rotation = source.rotation; 26666 26667 this.sizeAttenuation = source.sizeAttenuation; 26668 26669 return this; 26670 26671}; 26672 26673/** 26674 * @author mikael emtinger / http://gomo.se/ 26675 * @author alteredq / http://alteredqualia.com/ 26676 */ 26677 26678var _geometry; 26679 26680var _intersectPoint = new Vector3(); 26681var _worldScale = new Vector3(); 26682var _mvPosition = new Vector3(); 26683 26684var _alignedPosition = new Vector2(); 26685var _rotatedPosition = new Vector2(); 26686var _viewWorldMatrix = new Matrix4(); 26687 26688var _vA$1 = new Vector3(); 26689var _vB$1 = new Vector3(); 26690var _vC$1 = new Vector3(); 26691 26692var _uvA$1 = new Vector2(); 26693var _uvB$1 = new Vector2(); 26694var _uvC$1 = new Vector2(); 26695 26696function Sprite( material ) { 26697 26698 Object3D.call( this ); 26699 26700 this.type = 'Sprite'; 26701 26702 if ( _geometry === undefined ) { 26703 26704 _geometry = new BufferGeometry(); 26705 26706 var float32Array = new Float32Array( [ 26707 - 0.5, - 0.5, 0, 0, 0, 26708 0.5, - 0.5, 0, 1, 0, 26709 0.5, 0.5, 0, 1, 1, 26710 - 0.5, 0.5, 0, 0, 1 26711 ] ); 26712 26713 var interleavedBuffer = new InterleavedBuffer( float32Array, 5 ); 26714 26715 _geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] ); 26716 _geometry.setAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); 26717 _geometry.setAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); 26718 26719 } 26720 26721 this.geometry = _geometry; 26722 this.material = ( material !== undefined ) ? material : new SpriteMaterial(); 26723 26724 this.center = new Vector2( 0.5, 0.5 ); 26725 26726} 26727 26728Sprite.prototype = Object.assign( Object.create( Object3D.prototype ), { 26729 26730 constructor: Sprite, 26731 26732 isSprite: true, 26733 26734 raycast: function ( raycaster, intersects ) { 26735 26736 if ( raycaster.camera === null ) { 26737 26738 console.error( 'THREE.Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.' ); 26739 26740 } 26741 26742 _worldScale.setFromMatrixScale( this.matrixWorld ); 26743 26744 _viewWorldMatrix.copy( raycaster.camera.matrixWorld ); 26745 this.modelViewMatrix.multiplyMatrices( raycaster.camera.matrixWorldInverse, this.matrixWorld ); 26746 26747 _mvPosition.setFromMatrixPosition( this.modelViewMatrix ); 26748 26749 if ( raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false ) { 26750 26751 _worldScale.multiplyScalar( - _mvPosition.z ); 26752 26753 } 26754 26755 var rotation = this.material.rotation; 26756 var sin, cos; 26757 if ( rotation !== 0 ) { 26758 26759 cos = Math.cos( rotation ); 26760 sin = Math.sin( rotation ); 26761 26762 } 26763 26764 var center = this.center; 26765 26766 transformVertex( _vA$1.set( - 0.5, - 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); 26767 transformVertex( _vB$1.set( 0.5, - 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); 26768 transformVertex( _vC$1.set( 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); 26769 26770 _uvA$1.set( 0, 0 ); 26771 _uvB$1.set( 1, 0 ); 26772 _uvC$1.set( 1, 1 ); 26773 26774 // check first triangle 26775 var intersect = raycaster.ray.intersectTriangle( _vA$1, _vB$1, _vC$1, false, _intersectPoint ); 26776 26777 if ( intersect === null ) { 26778 26779 // check second triangle 26780 transformVertex( _vB$1.set( - 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); 26781 _uvB$1.set( 0, 1 ); 26782 26783 intersect = raycaster.ray.intersectTriangle( _vA$1, _vC$1, _vB$1, false, _intersectPoint ); 26784 if ( intersect === null ) { 26785 26786 return; 26787 26788 } 26789 26790 } 26791 26792 var distance = raycaster.ray.origin.distanceTo( _intersectPoint ); 26793 26794 if ( distance < raycaster.near || distance > raycaster.far ) return; 26795 26796 intersects.push( { 26797 26798 distance: distance, 26799 point: _intersectPoint.clone(), 26800 uv: Triangle.getUV( _intersectPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2() ), 26801 face: null, 26802 object: this 26803 26804 } ); 26805 26806 }, 26807 26808 clone: function () { 26809 26810 return new this.constructor( this.material ).copy( this ); 26811 26812 }, 26813 26814 copy: function ( source ) { 26815 26816 Object3D.prototype.copy.call( this, source ); 26817 26818 if ( source.center !== undefined ) this.center.copy( source.center ); 26819 26820 return this; 26821 26822 } 26823 26824 26825} ); 26826 26827function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) { 26828 26829 // compute position in camera space 26830 _alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale ); 26831 26832 // to check if rotation is not zero 26833 if ( sin !== undefined ) { 26834 26835 _rotatedPosition.x = ( cos * _alignedPosition.x ) - ( sin * _alignedPosition.y ); 26836 _rotatedPosition.y = ( sin * _alignedPosition.x ) + ( cos * _alignedPosition.y ); 26837 26838 } else { 26839 26840 _rotatedPosition.copy( _alignedPosition ); 26841 26842 } 26843 26844 26845 vertexPosition.copy( mvPosition ); 26846 vertexPosition.x += _rotatedPosition.x; 26847 vertexPosition.y += _rotatedPosition.y; 26848 26849 // transform to world space 26850 vertexPosition.applyMatrix4( _viewWorldMatrix ); 26851 26852} 26853 26854/** 26855 * @author mikael emtinger / http://gomo.se/ 26856 * @author alteredq / http://alteredqualia.com/ 26857 * @author mrdoob / http://mrdoob.com/ 26858 */ 26859 26860var _v1$4 = new Vector3(); 26861var _v2$2 = new Vector3(); 26862 26863function LOD() { 26864 26865 Object3D.call( this ); 26866 26867 this._currentLevel = 0; 26868 26869 this.type = 'LOD'; 26870 26871 Object.defineProperties( this, { 26872 levels: { 26873 enumerable: true, 26874 value: [] 26875 } 26876 } ); 26877 26878 this.autoUpdate = true; 26879 26880} 26881 26882LOD.prototype = Object.assign( Object.create( Object3D.prototype ), { 26883 26884 constructor: LOD, 26885 26886 isLOD: true, 26887 26888 copy: function ( source ) { 26889 26890 Object3D.prototype.copy.call( this, source, false ); 26891 26892 var levels = source.levels; 26893 26894 for ( var i = 0, l = levels.length; i < l; i ++ ) { 26895 26896 var level = levels[ i ]; 26897 26898 this.addLevel( level.object.clone(), level.distance ); 26899 26900 } 26901 26902 this.autoUpdate = source.autoUpdate; 26903 26904 return this; 26905 26906 }, 26907 26908 addLevel: function ( object, distance ) { 26909 26910 if ( distance === undefined ) distance = 0; 26911 26912 distance = Math.abs( distance ); 26913 26914 var levels = this.levels; 26915 26916 for ( var l = 0; l < levels.length; l ++ ) { 26917 26918 if ( distance < levels[ l ].distance ) { 26919 26920 break; 26921 26922 } 26923 26924 } 26925 26926 levels.splice( l, 0, { distance: distance, object: object } ); 26927 26928 this.add( object ); 26929 26930 return this; 26931 26932 }, 26933 26934 getCurrentLevel: function () { 26935 26936 return this._currentLevel; 26937 26938 }, 26939 26940 getObjectForDistance: function ( distance ) { 26941 26942 var levels = this.levels; 26943 26944 if ( levels.length > 0 ) { 26945 26946 for ( var i = 1, l = levels.length; i < l; i ++ ) { 26947 26948 if ( distance < levels[ i ].distance ) { 26949 26950 break; 26951 26952 } 26953 26954 } 26955 26956 return levels[ i - 1 ].object; 26957 26958 } 26959 26960 return null; 26961 26962 }, 26963 26964 raycast: function ( raycaster, intersects ) { 26965 26966 var levels = this.levels; 26967 26968 if ( levels.length > 0 ) { 26969 26970 _v1$4.setFromMatrixPosition( this.matrixWorld ); 26971 26972 var distance = raycaster.ray.origin.distanceTo( _v1$4 ); 26973 26974 this.getObjectForDistance( distance ).raycast( raycaster, intersects ); 26975 26976 } 26977 26978 }, 26979 26980 update: function ( camera ) { 26981 26982 var levels = this.levels; 26983 26984 if ( levels.length > 1 ) { 26985 26986 _v1$4.setFromMatrixPosition( camera.matrixWorld ); 26987 _v2$2.setFromMatrixPosition( this.matrixWorld ); 26988 26989 var distance = _v1$4.distanceTo( _v2$2 ) / camera.zoom; 26990 26991 levels[ 0 ].object.visible = true; 26992 26993 for ( var i = 1, l = levels.length; i < l; i ++ ) { 26994 26995 if ( distance >= levels[ i ].distance ) { 26996 26997 levels[ i - 1 ].object.visible = false; 26998 levels[ i ].object.visible = true; 26999 27000 } else { 27001 27002 break; 27003 27004 } 27005 27006 } 27007 27008 this._currentLevel = i - 1; 27009 27010 for ( ; i < l; i ++ ) { 27011 27012 levels[ i ].object.visible = false; 27013 27014 } 27015 27016 } 27017 27018 }, 27019 27020 toJSON: function ( meta ) { 27021 27022 var data = Object3D.prototype.toJSON.call( this, meta ); 27023 27024 if ( this.autoUpdate === false ) data.object.autoUpdate = false; 27025 27026 data.object.levels = []; 27027 27028 var levels = this.levels; 27029 27030 for ( var i = 0, l = levels.length; i < l; i ++ ) { 27031 27032 var level = levels[ i ]; 27033 27034 data.object.levels.push( { 27035 object: level.object.uuid, 27036 distance: level.distance 27037 } ); 27038 27039 } 27040 27041 return data; 27042 27043 } 27044 27045} ); 27046 27047/** 27048 * @author mikael emtinger / http://gomo.se/ 27049 * @author alteredq / http://alteredqualia.com/ 27050 * @author ikerr / http://verold.com 27051 */ 27052 27053function SkinnedMesh( geometry, material ) { 27054 27055 if ( geometry && geometry.isGeometry ) { 27056 27057 console.error( 'THREE.SkinnedMesh no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' ); 27058 27059 } 27060 27061 Mesh.call( this, geometry, material ); 27062 27063 this.type = 'SkinnedMesh'; 27064 27065 this.bindMode = 'attached'; 27066 this.bindMatrix = new Matrix4(); 27067 this.bindMatrixInverse = new Matrix4(); 27068 27069} 27070 27071SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), { 27072 27073 constructor: SkinnedMesh, 27074 27075 isSkinnedMesh: true, 27076 27077 bind: function ( skeleton, bindMatrix ) { 27078 27079 this.skeleton = skeleton; 27080 27081 if ( bindMatrix === undefined ) { 27082 27083 this.updateMatrixWorld( true ); 27084 27085 this.skeleton.calculateInverses(); 27086 27087 bindMatrix = this.matrixWorld; 27088 27089 } 27090 27091 this.bindMatrix.copy( bindMatrix ); 27092 this.bindMatrixInverse.getInverse( bindMatrix ); 27093 27094 }, 27095 27096 pose: function () { 27097 27098 this.skeleton.pose(); 27099 27100 }, 27101 27102 normalizeSkinWeights: function () { 27103 27104 var vector = new Vector4(); 27105 27106 var skinWeight = this.geometry.attributes.skinWeight; 27107 27108 for ( var i = 0, l = skinWeight.count; i < l; i ++ ) { 27109 27110 vector.x = skinWeight.getX( i ); 27111 vector.y = skinWeight.getY( i ); 27112 vector.z = skinWeight.getZ( i ); 27113 vector.w = skinWeight.getW( i ); 27114 27115 var scale = 1.0 / vector.manhattanLength(); 27116 27117 if ( scale !== Infinity ) { 27118 27119 vector.multiplyScalar( scale ); 27120 27121 } else { 27122 27123 vector.set( 1, 0, 0, 0 );
27123 // do something reasonable 27124 27125 } 27126 27127 skinWeight.setXYZW( i, vector.x, vector.y, vector.z, vector.w ); 27128 27129 } 27130 27131 }, 27132 27133 updateMatrixWorld: function ( force ) { 27134 27135 Mesh.prototype.updateMatrixWorld.call( this, force ); 27136 27137 if ( this.bindMode === 'attached' ) { 27138 27139 this.bindMatrixInverse.getInverse( this.matrixWorld ); 27140 27141 } else if ( this.bindMode === 'detached' ) { 27142 27143 this.bindMatrixInverse.getInverse( this.bindMatrix ); 27144 27145 } else { 27146 27147 console.warn( 'THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode ); 27148 27149 } 27150 27151 }, 27152 27153 clone: function () { 27154 27155 return new this.constructor( this.geometry, this.material ).copy( this ); 27156 27157 }, 27158 27159 boneTransform: ( function () { 27160 27161 var basePosition = new Vector3(); 27162 27163 var skinIndex = new Vector4(); 27164 var skinWeight = new Vector4(); 27165 27166 var vector = new Vector3(); 27167 var matrix = new Matrix4(); 27168 27169 return function ( index, target ) { 27170 27171 var skeleton = this.skeleton; 27172 var geometry = this.geometry; 27173 27174 skinIndex.fromBufferAttribute( geometry.attributes.skinIndex, index ); 27175 skinWeight.fromBufferAttribute( geometry.attributes.skinWeight, index ); 27176 27177 basePosition.fromBufferAttribute( geometry.attributes.position, index ).applyMatrix4( this.bindMatrix ); 27178 27179 target.set( 0, 0, 0 ); 27180 27181 for ( var i = 0; i < 4; i ++ ) { 27182 27183 var weight = skinWeight.getComponent( i ); 27184 27185 if ( weight !== 0 ) { 27186 27187 var boneIndex = skinIndex.getComponent( i ); 27188 27189 matrix.multiplyMatrices( skeleton.bones[ boneIndex ].matrixWorld, skeleton.boneInverses[ boneIndex ] ); 27190 27191 target.addScaledVector( vector.copy( basePosition ).applyMatrix4( matrix ), weight ); 27192 27193 } 27194 27195 } 27196 27197 return target.applyMatrix4( this.bindMatrixInverse ); 27198 27199 }; 27200 27201 }() ) 27202 27203} ); 27204 27205/** 27206 * @author mikael emtinger / http://gomo.se/ 27207 * @author alteredq / http://alteredqualia.com/ 27208 * @author michael guerrero / http://realitymeltdown.com 27209 * @author ikerr / http://verold.com 27210 */ 27211 27212var _offsetMatrix = new Matrix4(); 27213var _identityMatrix = new Matrix4(); 27214 27215function Skeleton( bones, boneInverses ) { 27216 27217 // copy the bone array 27218 27219 bones = bones || []; 27220 27221 this.bones = bones.slice( 0 ); 27222 this.boneMatrices = new Float32Array( this.bones.length * 16 ); 27223 27224 this.frame = - 1; 27225 27226 // use the supplied bone inverses or calculate the inverses 27227 27228 if ( boneInverses === undefined ) { 27229 27230 this.calculateInverses(); 27231 27232 } else { 27233 27234 if ( this.bones.length === boneInverses.length ) { 27235 27236 this.boneInverses = boneInverses.slice( 0 ); 27237 27238 } else { 27239 27240 console.warn( 'THREE.Skeleton boneInverses is the wrong length.' ); 27241 27242 this.boneInverses = []; 27243 27244 for ( var i = 0, il = this.bones.length; i < il; i ++ ) { 27245 27246 this.boneInverses.push( new Matrix4() ); 27247 27248 } 27249 27250 } 27251 27252 } 27253 27254} 27255 27256Object.assign( Skeleton.prototype, { 27257 27258 calculateInverses: function () { 27259 27260 this.boneInverses = []; 27261 27262 for ( var i = 0, il = this.bones.length; i < il; i ++ ) { 27263 27264 var inverse = new Matrix4(); 27265 27266 if ( this.bones[ i ] ) { 27267 27268 inverse.getInverse( this.bones[ i ].matrixWorld ); 27269 27270 } 27271 27272 this.boneInverses.push( inverse ); 27273 27274 } 27275 27276 }, 27277 27278 pose: function () { 27279 27280 var bone, i, il; 27281 27282 // recover the bind-time world matrices 27283 27284 for ( i = 0, il = this.bones.length; i < il; i ++ ) { 27285 27286 bone = this.bones[ i ]; 27287 27288 if ( bone ) { 27289 27290 bone.matrixWorld.getInverse( this.boneInverses[ i ] ); 27291 27292 } 27293 27294 } 27295 27296 // compute the local matrices, positions, rotations and scales 27297 27298 for ( i = 0, il = this.bones.length; i < il; i ++ ) { 27299 27300 bone = this.bones[ i ]; 27301 27302 if ( bone ) { 27303 27304 if ( bone.parent && bone.parent.isBone ) { 27305 27306 bone.matrix.getInverse( bone.parent.matrixWorld ); 27307 bone.matrix.multiply( bone.matrixWorld ); 27308 27309 } else { 27310 27311 bone.matrix.copy( bone.matrixWorld ); 27312 27313 } 27314 27315 bone.matrix.decompose( bone.position, bone.quaternion, bone.scale ); 27316 27317 } 27318 27319 } 27320 27321 }, 27322 27323 update: function () { 27324 27325 var bones = this.bones; 27326 var boneInverses = this.boneInverses; 27327 var boneMatrices = this.boneMatrices; 27328 var boneTexture = this.boneTexture; 27329 27330 // flatten bone matrices to array 27331 27332 for ( var i = 0, il = bones.length; i < il; i ++ ) { 27333 27334 // compute the offset between the current and the original transform 27335 27336 var matrix = bones[ i ] ? bones[ i ].matrixWorld : _identityMatrix; 27337
vendor: 5,869 bytes, lines 27338-27642
27338 _offsetMatrix.multiplyMatrices( matrix, boneInverses[ i ] ); 27339 _offsetMatrix.toArray( boneMatrices, i * 16 ); 27340 27341 } 27342 27343 if ( boneTexture !== undefined ) { 27344 27345 boneTexture.needsUpdate = true; 27346 27347 } 27348 27349 }, 27350 27351 clone: function () { 27352 27353 return new Skeleton( this.bones, this.boneInverses ); 27354 27355 }, 27356 27357 getBoneByName: function ( name ) { 27358 27359 for ( var i = 0, il = this.bones.length; i < il; i ++ ) { 27360 27361 var bone = this.bones[ i ]; 27362 27363 if ( bone.name === name ) { 27364 27365 return bone; 27366 27367 } 27368 27369 } 27370 27371 return undefined; 27372 27373 }, 27374 27375 dispose: function ( ) { 27376 27377 if ( this.boneTexture ) { 27378 27379 this.boneTexture.dispose(); 27380 27381 this.boneTexture = undefined; 27382 27383 } 27384 27385 } 27386 27387} ); 27388 27389/** 27390 * @author mikael emtinger / http://gomo.se/ 27391 * @author alteredq / http://alteredqualia.com/ 27392 * @author ikerr / http://verold.com 27393 */ 27394 27395function Bone() { 27396 27397 Object3D.call( this ); 27398 27399 this.type = 'Bone'; 27400 27401} 27402 27403Bone.prototype = Object.assign( Object.create( Object3D.prototype ), { 27404 27405 constructor: Bone, 27406 27407 isBone: true 27408 27409} ); 27410 27411/** 27412 * @author mrdoob / http://mrdoob.com/ 27413 */ 27414 27415var _instanceLocalMatrix = new Matrix4(); 27416var _instanceWorldMatrix = new Matrix4(); 27417 27418var _instanceIntersects = []; 27419 27420var _mesh = new Mesh(); 27421 27422function InstancedMesh( geometry, material, count ) { 27423 27424 Mesh.call( this, geometry, material ); 27425 27426 this.instanceMatrix = new BufferAttribute( new Float32Array( count * 16 ), 16 ); 27427 27428 this.count = count; 27429 27430 this.frustumCulled = false; 27431 27432} 27433 27434InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), { 27435 27436 constructor: InstancedMesh, 27437 27438 isInstancedMesh: true, 27439 27440 getMatrixAt: function ( index, matrix ) { 27441 27442 matrix.fromArray( this.instanceMatrix.array, index * 16 ); 27443 27444 }, 27445 27446 raycast: function ( raycaster, intersects ) { 27447 27448 var matrixWorld = this.matrixWorld; 27449 var raycastTimes = this.count; 27450 27451 _mesh.geometry = this.geometry; 27452 _mesh.material = this.material; 27453 27454 if ( _mesh.material === undefined ) return; 27455 27456 for ( var instanceId = 0; instanceId < raycastTimes; instanceId ++ ) { 27457 27458 // calculate the world matrix for each instance 27459 27460 this.getMatrixAt( instanceId, _instanceLocalMatrix ); 27461 27462 _instanceWorldMatrix.multiplyMatrices( matrixWorld, _instanceLocalMatrix ); 27463 27464 // the mesh represents this single instance 27465 27466 _mesh.matrixWorld = _instanceWorldMatrix; 27467 27468 _mesh.raycast( raycaster, _instanceIntersects ); 27469 27470 // process the result of raycast 27471 27472 for ( var i = 0, l = _instanceIntersects.length; i < l; i ++ ) { 27473 27474 var intersect = _instanceIntersects[ i ]; 27475 intersect.instanceId = instanceId; 27476 intersect.object = this; 27477 intersects.push( intersect ); 27478 27479 } 27480 27481 _instanceIntersects.length = 0; 27482 27483 } 27484 27485 }, 27486 27487 setMatrixAt: function ( index, matrix ) { 27488 27489 matrix.toArray( this.instanceMatrix.array, index * 16 ); 27490 27491 }, 27492 27493 updateMorphTargets: function () { 27494 27495 } 27496 27497} ); 27498 27499/** 27500 * @author mrdoob / http://mrdoob.com/ 27501 * @author alteredq / http://alteredqualia.com/ 27502 * 27503 * parameters = { 27504 * color: <hex>, 27505 * opacity: <float>, 27506 * 27507 * linewidth: <float>, 27508 * linecap: "round", 27509 * linejoin: "round" 27510 * } 27511 */ 27512 27513function LineBasicMaterial( parameters ) { 27514 27515 Material.call( this ); 27516 27517 this.type = 'LineBasicMaterial'; 27518 27519 this.color = new Color( 0xffffff ); 27520 27521 this.linewidth = 1; 27522 this.linecap = 'round'; 27523 this.linejoin = 'round'; 27524 27525 this.setValues( parameters ); 27526 27527} 27528 27529LineBasicMaterial.prototype = Object.create( Material.prototype ); 27530LineBasicMaterial.prototype.constructor = LineBasicMaterial; 27531 27532LineBasicMaterial.prototype.isLineBasicMaterial = true; 27533 27534LineBasicMaterial.prototype.copy = function ( source ) { 27535 27536 Material.prototype.copy.call( this, source ); 27537 27538 this.color.copy( source.color ); 27539 27540 this.linewidth = source.linewidth; 27541 this.linecap = source.linecap; 27542 this.linejoin = source.linejoin; 27543 27544 return this; 27545 27546}; 27547 27548/** 27549 * @author mrdoob / http://mrdoob.com/ 27550 */ 27551 27552var _start = new Vector3(); 27553var _end = new Vector3(); 27554var _inverseMatrix$1 = new Matrix4(); 27555var _ray$1 = new Ray(); 27556var _sphere$2 = new Sphere(); 27557 27558function Line( geometry, material, mode ) { 27559 27560 if ( mode === 1 ) { 27561 27562 console.error( 'THREE.Line: parameter THREE.LinePieces no longer supported. Use THREE.LineSegments instead.' ); 27563 27564 } 27565 27566 Object3D.call( this ); 27567 27568 this.type = 'Line'; 27569 27570 this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); 27571 this.material = material !== undefined ? material : new LineBasicMaterial(); 27572 27573} 27574 27575Line.prototype = Object.assign( Object.create( Object3D.prototype ), { 27576 27577 constructor: Line, 27578 27579 isLine: true, 27580 27581 computeLineDistances: function () { 27582 27583 var geometry = this.geometry; 27584 27585 if ( geometry.isBufferGeometry ) { 27586 27587 // we assume non-indexed geometry 27588 27589 if ( geometry.index === null ) { 27590 27591 var positionAttribute = geometry.attributes.position; 27592 var lineDistances = [ 0 ]; 27593 27594 for ( var i = 1, l = positionAttribute.count; i < l; i ++ ) { 27595 27596 _start.fromBufferAttribute( positionAttribute, i - 1 ); 27597 _end.fromBufferAttribute( positionAttribute, i ); 27598 27599 lineDistances[ i ] = lineDistances[ i - 1 ]; 27600 lineDistances[ i ] += _start.distanceTo( _end ); 27601 27602 } 27603 27604 geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); 27605 27606 } else { 27607 27608 console.warn( 'THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' ); 27609 27610 } 27611 27612 } else if ( geometry.isGeometry ) { 27613 27614 var vertices = geometry.vertices; 27615 var lineDistances = geometry.lineDistances; 27616 27617 lineDistances[ 0 ] = 0; 27618 27619 for ( var i = 1, l = vertices.length; i < l; i ++ ) { 27620 27621 lineDistances[ i ] = lineDistances[ i - 1 ]; 27622 lineDistances[ i ] += vertices[ i - 1 ].distanceTo( vertices[ i ] ); 27623 27624 } 27625 27626 } 27627 27628 return this; 27629 27630 }, 27631 27632 raycast: function ( raycaster, intersects ) { 27633 27634 var geometry = this.geometry; 27635 var matrixWorld = this.matrixWorld; 27636 var threshold = raycaster.params.Line.threshold; 27637 27638 // Checking boundingSphere distance to ray 27639 27640 if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); 27641 27642 _sphere$2.copy( geometry.boundingSphere );
27643 _sphere$2.applyMatrix4( matrixWorld ); 27644 _sphere$2.radius += threshold; 27645 27646 if ( raycaster.ray.intersectsSphere( _sphere$2 ) === false ) return; 27647 27648 // 27649 27650 _inverseMatrix$1.getInverse( matrixWorld ); 27651 _ray$1.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$1 ); 27652 27653 var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); 27654 var localThresholdSq = localThreshold * localThreshold; 27655 27656 var vStart = new Vector3(); 27657 var vEnd = new Vector3(); 27658 var interSegment = new Vector3(); 27659 var interRay = new Vector3(); 27660 var step = ( this && this.isLineSegments ) ? 2 : 1; 27661 27662 if ( geometry.isBufferGeometry ) { 27663 27664 var index = geometry.index; 27665 var attributes = geometry.attributes; 27666 var positions = attributes.position.array; 27667 27668 if ( index !== null ) { 27669 27670 var indices = index.array; 27671 27672 for ( var i = 0, l = indices.length - 1; i < l; i += step ) { 27673 27674 var a = indices[ i ]; 27675 var b = indices[ i + 1 ]; 27676 27677 vStart.fromArray( positions, a * 3 ); 27678 vEnd.fromArray( positions, b * 3 ); 27679 27680 var distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); 27681 27682 if ( distSq > localThresholdSq ) continue; 27683 27684 interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation 27685 27686 var distance = raycaster.ray.origin.distanceTo( interRay ); 27687 27688 if ( distance < raycaster.near || distance > raycaster.far ) continue; 27689 27690 intersects.push( { 27691 27692 distance: distance, 27693 // What do we want? intersection point on the ray or on the segment?? 27694 // point: raycaster.ray.at( distance ), 27695 point: interSegment.clone().applyMatrix4( this.matrixWorld ), 27696 index: i, 27697 face: null, 27698 faceIndex: null, 27699 object: this 27700 27701 } ); 27702 27703 } 27704 27705 } else { 27706 27707 for ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) { 27708 27709 vStart.fromArray( positions, 3 * i ); 27710 vEnd.fromArray( positions, 3 * i + 3 ); 27711 27712 var distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); 27713 27714 if ( distSq > localThresholdSq ) continue; 27715 27716 interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation 27717 27718 var distance = raycaster.ray.origin.distanceTo( interRay ); 27719 27720 if ( distance < raycaster.near || distance > raycaster.far ) continue; 27721 27722 intersects.push( { 27723 27724 distance: distance, 27725 // What do we want? intersection point on the ray or on the segment?? 27726 // point: raycaster.ray.at( distance ), 27727 point: interSegment.clone().applyMatrix4( this.matrixWorld ), 27728 index: i, 27729 face: null, 27730 faceIndex: null, 27731 object: this 27732 27733 } ); 27734 27735 } 27736 27737 } 27738 27739 } else if ( geometry.isGeometry ) { 27740 27741 var vertices = geometry.vertices; 27742 var nbVertices = vertices.length; 27743 27744 for ( var i = 0; i < nbVertices - 1; i += step ) { 27745 27746 var distSq = _ray$1.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment ); 27747 27748 if ( distSq > localThresholdSq ) continue; 27749 27750 interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation 27751 27752 var distance = raycaster.ray.origin.distanceTo( interRay ); 27753 27754 if ( distance < raycaster.near || distance > raycaster.far ) continue; 27755 27756 intersects.push( { 27757 27758 distance: distance, 27759 // What do we want? intersection point on the ray or on the segment?? 27760 // point: raycaster.ray.at( distance ), 27761 point: interSegment.clone().applyMatrix4( this.matrixWorld ), 27762 index: i, 27763 face: null, 27764 faceIndex: null, 27765 object: this 27766 27767 } ); 27768 27769 } 27770 27771 } 27772 27773 }, 27774 27775 clone: function () { 27776 27777 return new this.constructor( this.geometry, this.material ).copy( this ); 27778 27779 } 27780 27781} ); 27782 27783/** 27784 * @author mrdoob / http://mrdoob.com/ 27785 */ 27786 27787var _start$1 = new Vector3(); 27788var _end$1 = new Vector3(); 27789 27790function LineSegments( geometry, material ) { 27791 27792 Line.call( this, geometry, material ); 27793 27794 this.type = 'LineSegments'; 27795 27796} 27797 27798LineSegments.prototype = Object.assign( Object.create( Line.prototype ), { 27799 27800 constructor: LineSegments, 27801 27802 isLineSegments: true, 27803 27804 computeLineDistances: function () { 27805 27806 var geometry = this.geometry; 27807 27808 if ( geometry.isBufferGeometry ) { 27809 27810 // we assume non-indexed geometry 27811 27812 if ( geometry.index === null ) { 27813 27814 var positionAttribute = geometry.attributes.position; 27815 var lineDistances = []; 27816 27817 for ( var i = 0, l = positionAttribute.count; i < l; i += 2 ) { 27818 27819 _start$1.fromBufferAttribute( positionAttribute, i ); 27820 _end$1.fromBufferAttribute( positionAttribute, i + 1 ); 27821 27822 lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ]; 27823 lineDistances[ i + 1 ] = lineDistances[ i ] + _start$1.distanceTo( _end$1 ); 27824 27825 } 27826 27827 geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); 27828 27829 } else { 27830 27831 console.warn( 'THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' ); 27832 27833 } 27834 27835 } else if ( geometry.isGeometry ) { 27836 27837 var vertices = geometry.vertices; 27838 var lineDistances = geometry.lineDistances; 27839 27840 for ( var i = 0, l = vertices.length; i < l; i += 2 ) { 27841 27842 _start$1.copy( vertices[ i ] ); 27843 _end$1.copy( vertices[ i + 1 ] ); 27844 27845 lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ]; 27846 lineDistances[ i + 1 ] = lineDistances[ i ] + _start$1.distanceTo( _end$1 ); 27847 27848 } 27849 27850 } 27851 27852 return this; 27853 27854 } 27855 27856} ); 27857 27858/** 27859 * @author mgreter / http://github.com/mgreter 27860 */ 27861 27862function LineLoop( geometry, material ) { 27863 27864 Line.call( this, geometry, material ); 27865 27866 this.type = 'LineLoop'; 27867 27868} 27869 27870LineLoop.prototype = Object.assign( Object.create( Line.prototype ), { 27871 27872 constructor: LineLoop, 27873 27874 isLineLoop: true, 27875 27876} ); 27877 27878/** 27879 * @author mrdoob / http://mrdoob.com/ 27880 * @author alteredq / http://alteredqualia.com/ 27881 * 27882 * parameters = { 27883 * color: <hex>, 27884 * opacity: <float>, 27885 * map: new THREE.Texture( <Image> ), 27886 * alphaMap: new THREE.Texture( <Image> ), 27887 * 27888 * size: <float>, 27889 * sizeAttenuation: <bool> 27890 * 27891 * morphTargets: <bool> 27892 * } 27893 */ 27894 27895function PointsMaterial( parameters ) { 27896 27897 Material.call( this ); 27898 27899 this.type = 'PointsMaterial'; 27900 27901 this.color = new Color( 0xffffff ); 27902 27903 this.map = null; 27904 27905 this.alphaMap = null; 27906 27907 this.size = 1; 27908 this.sizeAttenuation = true; 27909 27910 this.morphTargets = false;
vendor: 7,961 bytes, lines 27911-28255
27911 27912 this.setValues( parameters ); 27913 27914} 27915 27916PointsMaterial.prototype = Object.create( Material.prototype ); 27917PointsMaterial.prototype.constructor = PointsMaterial; 27918 27919PointsMaterial.prototype.isPointsMaterial = true; 27920 27921PointsMaterial.prototype.copy = function ( source ) { 27922 27923 Material.prototype.copy.call( this, source ); 27924 27925 this.color.copy( source.color ); 27926 27927 this.map = source.map; 27928 27929 this.alphaMap = source.alphaMap; 27930 27931 this.size = source.size; 27932 this.sizeAttenuation = source.sizeAttenuation; 27933 27934 this.morphTargets = source.morphTargets; 27935 27936 return this; 27937 27938}; 27939 27940/** 27941 * @author alteredq / http://alteredqualia.com/ 27942 */ 27943 27944var _inverseMatrix$2 = new Matrix4(); 27945var _ray$2 = new Ray(); 27946var _sphere$3 = new Sphere(); 27947var _position$1 = new Vector3(); 27948 27949function Points( geometry, material ) { 27950 27951 Object3D.call( this ); 27952 27953 this.type = 'Points'; 27954 27955 this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); 27956 this.material = material !== undefined ? material : new PointsMaterial(); 27957 27958 this.updateMorphTargets(); 27959 27960} 27961 27962Points.prototype = Object.assign( Object.create( Object3D.prototype ), { 27963 27964 constructor: Points, 27965 27966 isPoints: true, 27967 27968 raycast: function ( raycaster, intersects ) { 27969 27970 var geometry = this.geometry; 27971 var matrixWorld = this.matrixWorld; 27972 var threshold = raycaster.params.Points.threshold; 27973 27974 // Checking boundingSphere distance to ray 27975 27976 if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); 27977 27978 _sphere$3.copy( geometry.boundingSphere ); 27979 _sphere$3.applyMatrix4( matrixWorld ); 27980 _sphere$3.radius += threshold; 27981 27982 if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) return; 27983 27984 // 27985 27986 _inverseMatrix$2.getInverse( matrixWorld ); 27987 _ray$2.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$2 ); 27988 27989 var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); 27990 var localThresholdSq = localThreshold * localThreshold; 27991 27992 if ( geometry.isBufferGeometry ) { 27993 27994 var index = geometry.index; 27995 var attributes = geometry.attributes; 27996 var positions = attributes.position.array; 27997 27998 if ( index !== null ) { 27999 28000 var indices = index.array; 28001 28002 for ( var i = 0, il = indices.length; i < il; i ++ ) { 28003 28004 var a = indices[ i ]; 28005 28006 _position$1.fromArray( positions, a * 3 ); 28007 28008 testPoint( _position$1, a, localThresholdSq, matrixWorld, raycaster, intersects, this ); 28009 28010 } 28011 28012 } else { 28013 28014 for ( var i = 0, l = positions.length / 3; i < l; i ++ ) { 28015 28016 _position$1.fromArray( positions, i * 3 ); 28017 28018 testPoint( _position$1, i, localThresholdSq, matrixWorld, raycaster, intersects, this ); 28019 28020 } 28021 28022 } 28023 28024 } else { 28025 28026 var vertices = geometry.vertices; 28027 28028 for ( var i = 0, l = vertices.length; i < l; i ++ ) { 28029 28030 testPoint( vertices[ i ], i, localThresholdSq, matrixWorld, raycaster, intersects, this ); 28031 28032 } 28033 28034 } 28035 28036 }, 28037 28038 updateMorphTargets: function () { 28039 28040 var geometry = this.geometry; 28041 var m, ml, name; 28042 28043 if ( geometry.isBufferGeometry ) { 28044 28045 var morphAttributes = geometry.morphAttributes; 28046 var keys = Object.keys( morphAttributes ); 28047 28048 if ( keys.length > 0 ) { 28049 28050 var morphAttribute = morphAttributes[ keys[ 0 ] ]; 28051 28052 if ( morphAttribute !== undefined ) { 28053 28054 this.morphTargetInfluences = []; 28055 this.morphTargetDictionary = {}; 28056 28057 for ( m = 0, ml = morphAttribute.length; m < ml; m ++ ) { 28058 28059 name = morphAttribute[ m ].name || String( m ); 28060 28061 this.morphTargetInfluences.push( 0 ); 28062 this.morphTargetDictionary[ name ] = m; 28063 28064 } 28065 28066 } 28067 28068 } 28069 28070 } else { 28071 28072 var morphTargets = geometry.morphTargets; 28073 28074 if ( morphTargets !== undefined && morphTargets.length > 0 ) { 28075 28076 console.error( 'THREE.Points.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.' ); 28077 28078 } 28079 28080 } 28081 28082 }, 28083 28084 clone: function () { 28085 28086 return new this.constructor( this.geometry, this.material ).copy( this ); 28087 28088 } 28089 28090} ); 28091 28092function testPoint( point, index, localThresholdSq, matrixWorld, raycaster, intersects, object ) { 28093 28094 var rayPointDistanceSq = _ray$2.distanceSqToPoint( point ); 28095 28096 if ( rayPointDistanceSq < localThresholdSq ) { 28097 28098 var intersectPoint = new Vector3(); 28099 28100 _ray$2.closestPointToPoint( point, intersectPoint ); 28101 intersectPoint.applyMatrix4( matrixWorld ); 28102 28103 var distance = raycaster.ray.origin.distanceTo( intersectPoint ); 28104 28105 if ( distance < raycaster.near || distance > raycaster.far ) return; 28106 28107 intersects.push( { 28108 28109 distance: distance, 28110 distanceToRay: Math.sqrt( rayPointDistanceSq ), 28111 point: intersectPoint, 28112 index: index, 28113 face: null, 28114 object: object 28115 28116 } ); 28117 28118 } 28119 28120} 28121 28122/** 28123 * @author mrdoob / http://mrdoob.com/ 28124 */ 28125 28126function VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { 28127 28128 Texture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); 28129 28130 this.format = format !== undefined ? format : RGBFormat; 28131 28132 this.minFilter = minFilter !== undefined ? minFilter : LinearFilter; 28133 this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; 28134 28135 this.generateMipmaps = false; 28136 28137} 28138 28139VideoTexture.prototype = Object.assign( Object.create( Texture.prototype ), { 28140 28141 constructor: VideoTexture, 28142 28143 isVideoTexture: true, 28144 28145 update: function () { 28146 28147 var video = this.image; 28148 28149 if ( video.readyState >= video.HAVE_CURRENT_DATA ) { 28150 28151 this.needsUpdate = true; 28152 28153 } 28154 28155 } 28156 28157} ); 28158 28159/** 28160 * @author alteredq / http://alteredqualia.com/ 28161 */ 28162 28163function CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) { 28164 28165 Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); 28166 28167 this.image = { width: width, height: height }; 28168 this.mipmaps = mipmaps; 28169 28170 // no flipping for cube textures 28171 // (also flipping doesn't work for compressed textures ) 28172 28173 this.flipY = false; 28174 28175 // can't generate mipmaps for compressed textures 28176 // mips must be embedded in DDS files 28177 28178 this.generateMipmaps = false; 28179 28180} 28181 28182CompressedTexture.prototype = Object.create( Texture.prototype ); 28183CompressedTexture.prototype.constructor = CompressedTexture; 28184 28185CompressedTexture.prototype.isCompressedTexture = true; 28186 28187/** 28188 * @author mrdoob / http://mrdoob.com/ 28189 */ 28190 28191function CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { 28192 28193 Texture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); 28194 28195 this.needsUpdate = true; 28196 28197} 28198 28199CanvasTexture.prototype = Object.create( Texture.prototype ); 28200CanvasTexture.prototype.constructor = CanvasTexture; 28201CanvasTexture.prototype.isCanvasTexture = true; 28202 28203/** 28204 * @author Matt DesLauriers / @mattdesl 28205 * @author atix / arthursilber.de 28206 */ 28207 28208function DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) { 28209 28210 format = format !== undefined ? format : DepthFormat; 28211 28212 if ( format !== DepthFormat && format !== DepthStencilFormat ) { 28213 28214 throw new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' ); 28215 28216 } 28217 28218 if ( type === undefined && format === DepthFormat ) type = UnsignedShortType; 28219 if ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type; 28220 28221 Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); 28222 28223 this.image = { width: width, height: height }; 28224 28225 this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; 28226 this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; 28227 28228 this.flipY = false; 28229 this.generateMipmaps = false; 28230 28231} 28232 28233DepthTexture.prototype = Object.create( Texture.prototype ); 28234DepthTexture.prototype.constructor = DepthTexture; 28235DepthTexture.prototype.isDepthTexture = true; 28236 28237/** 28238 * @author mrdoob / http://mrdoob.com/ 28239 * @author Mugen87 / https://github.com/Mugen87 28240 */ 28241 28242function WireframeGeometry( geometry ) { 28243 28244 BufferGeometry.call( this ); 28245 28246 this.type = 'WireframeGeometry'; 28247 28248 // buffer 28249 28250 var vertices = []; 28251 28252 // helper variables 28253 28254 var i, j, l, o, ol; 28255 var edge = [ 0, 0 ], edges = {}, e, edge1, edge2;
28256 var key, keys = [ 'a', 'b', 'c' ]; 28257 var vertex; 28258 28259 // different logic for Geometry and BufferGeometry 28260 28261 if ( geometry && geometry.isGeometry ) { 28262 28263 // create a data structure that contains all edges without duplicates 28264 28265 var faces = geometry.faces; 28266 28267 for ( i = 0, l = faces.length; i < l; i ++ ) { 28268 28269 var face = faces[ i ]; 28270 28271 for ( j = 0; j < 3; j ++ ) { 28272 28273 edge1 = face[ keys[ j ] ]; 28274 edge2 = face[ keys[ ( j + 1 ) % 3 ] ]; 28275 edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates 28276 edge[ 1 ] = Math.max( edge1, edge2 ); 28277 28278 key = edge[ 0 ] + ',' + edge[ 1 ]; 28279 28280 if ( edges[ key ] === undefined ) { 28281 28282 edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] }; 28283 28284 } 28285 28286 } 28287 28288 } 28289 28290 // generate vertices 28291 28292 for ( key in edges ) { 28293 28294 e = edges[ key ]; 28295 28296 vertex = geometry.vertices[ e.index1 ]; 28297 vertices.push( vertex.x, vertex.y, vertex.z ); 28298 28299 vertex = geometry.vertices[ e.index2 ]; 28300 vertices.push( vertex.x, vertex.y, vertex.z ); 28301 28302 } 28303 28304 } else if ( geometry && geometry.isBufferGeometry ) { 28305 28306 var position, indices, groups; 28307 var group, start, count; 28308 var index1, index2; 28309 28310 vertex = new Vector3(); 28311 28312 if ( geometry.index !== null ) { 28313 28314 // indexed BufferGeometry 28315 28316 position = geometry.attributes.position; 28317 indices = geometry.index; 28318 groups = geometry.groups; 28319 28320 if ( groups.length === 0 ) { 28321 28322 groups = [ { start: 0, count: indices.count, materialIndex: 0 } ]; 28323 28324 } 28325 28326 // create a data structure that contains all eges without duplicates 28327 28328 for ( o = 0, ol = groups.length; o < ol; ++ o ) { 28329 28330 group = groups[ o ]; 28331 28332 start = group.start; 28333 count = group.count; 28334 28335 for ( i = start, l = ( start + count ); i < l; i += 3 ) { 28336 28337 for ( j = 0; j < 3; j ++ ) { 28338 28339 edge1 = indices.getX( i + j ); 28340 edge2 = indices.getX( i + ( j + 1 ) % 3 ); 28341 edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates 28342 edge[ 1 ] = Math.max( edge1, edge2 ); 28343 28344 key = edge[ 0 ] + ',' + edge[ 1 ]; 28345 28346 if ( edges[ key ] === undefined ) { 28347 28348 edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] }; 28349 28350 } 28351 28352 } 28353 28354 } 28355 28356 } 28357 28358 // generate vertices 28359 28360 for ( key in edges ) { 28361 28362 e = edges[ key ]; 28363 28364 vertex.fromBufferAttribute( position, e.index1 ); 28365 vertices.push( vertex.x, vertex.y, vertex.z ); 28366 28367 vertex.fromBufferAttribute( position, e.index2 ); 28368 vertices.push( vertex.x, vertex.y, vertex.z ); 28369 28370 } 28371 28372 } else { 28373 28374 // non-indexed BufferGeometry 28375 28376 position = geometry.attributes.position; 28377 28378 for ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) { 28379 28380 for ( j = 0; j < 3; j ++ ) { 28381 28382 // three edges per triangle, an edge is represented as (index1, index2) 28383 // e.g. the first triangle has the following edges: (0,1),(1,2),(2,0) 28384 28385 index1 = 3 * i + j; 28386 vertex.fromBufferAttribute( position, index1 ); 28387 vertices.push( vertex.x, vertex.y, vertex.z ); 28388 28389 index2 = 3 * i + ( ( j + 1 ) % 3 ); 28390 vertex.fromBufferAttribute( position, index2 ); 28391 vertices.push( vertex.x, vertex.y, vertex.z ); 28392 28393 } 28394 28395 } 28396 28397 } 28398 28399 } 28400 28401 // build geometry 28402 28403 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 28404 28405} 28406 28407WireframeGeometry.prototype = Object.create( BufferGeometry.prototype ); 28408WireframeGeometry.prototype.constructor = WireframeGeometry; 28409 28410/** 28411 * @author zz85 / https://github.com/zz85 28412 * @author Mugen87 / https://github.com/Mugen87 28413 * 28414 * Parametric Surfaces Geometry 28415 * based on the brilliant article by @prideout https://prideout.net/blog/old/blog/index.html@p=44.html 28416 */ 28417 28418// ParametricGeometry 28419 28420function ParametricGeometry( func, slices, stacks ) { 28421 28422 Geometry.call( this ); 28423 28424 this.type = 'ParametricGeometry'; 28425 28426 this.parameters = { 28427 func: func, 28428 slices: slices, 28429 stacks: stacks 28430 }; 28431 28432 this.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) ); 28433 this.mergeVertices(); 28434 28435} 28436 28437ParametricGeometry.prototype = Object.create( Geometry.prototype ); 28438ParametricGeometry.prototype.constructor = ParametricGeometry; 28439 28440// ParametricBufferGeometry 28441 28442function ParametricBufferGeometry( func, slices, stacks ) { 28443 28444 BufferGeometry.call( this ); 28445 28446 this.type = 'ParametricBufferGeometry'; 28447 28448 this.parameters = { 28449 func: func,
28450 slices: slices, 28451 stacks: stacks 28452 }; 28453 28454 // buffers 28455 28456 var indices = []; 28457 var vertices = []; 28458 var normals = []; 28459 var uvs = []; 28460 28461 var EPS = 0.00001; 28462 28463 var normal = new Vector3(); 28464 28465 var p0 = new Vector3(), p1 = new Vector3(); 28466 var pu = new Vector3(), pv = new Vector3(); 28467 28468 var i, j; 28469 28470 if ( func.length < 3 ) { 28471 28472 console.error( 'THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.' ); 28473 28474 } 28475 28476 // generate vertices, normals and uvs 28477 28478 var sliceCount = slices + 1; 28479 28480 for ( i = 0; i <= stacks; i ++ ) { 28481 28482 var v = i / stacks; 28483 28484 for ( j = 0; j <= slices; j ++ ) { 28485 28486 var u = j / slices; 28487 28488 // vertex 28489 28490 func( u, v, p0 ); 28491 vertices.push( p0.x, p0.y, p0.z ); 28492 28493 // normal 28494 28495 // approximate tangent vectors via finite differences 28496 28497 if ( u - EPS >= 0 ) { 28498 28499 func( u - EPS, v, p1 ); 28500 pu.subVectors( p0, p1 ); 28501 28502 } else { 28503 28504 func( u + EPS, v, p1 ); 28505 pu.subVectors( p1, p0 ); 28506 28507 } 28508 28509 if ( v - EPS >= 0 ) { 28510 28511 func( u, v - EPS, p1 ); 28512 pv.subVectors( p0, p1 ); 28513 28514 } else { 28515 28516 func( u, v + EPS, p1 ); 28517 pv.subVectors( p1, p0 ); 28518 28519 } 28520 28521 // cross product of tangent vectors returns surface normal 28522 28523 normal.crossVectors( pu, pv ).normalize(); 28524 normals.push( normal.x, normal.y, normal.z ); 28525 28526 // uv 28527 28528 uvs.push( u, v ); 28529 28530 } 28531 28532 } 28533 28534 // generate indices 28535 28536 for ( i = 0; i < stacks; i ++ ) { 28537 28538 for ( j = 0; j < slices; j ++ ) { 28539 28540 var a = i * sliceCount + j; 28541 var b = i * sliceCount + j + 1; 28542 var c = ( i + 1 ) * sliceCount + j + 1; 28543 var d = ( i + 1 ) * sliceCount + j; 28544 28545 // faces one and two 28546 28547 indices.push( a, b, d ); 28548 indices.push( b, c, d ); 28549 28550 } 28551 28552 } 28553 28554 // build geometry 28555 28556 this.setIndex( indices ); 28557 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 28558 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 28559 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 28560 28561} 28562 28563ParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 28564ParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry; 28565 28566/** 28567 * @author clockworkgeek / https://github.com/clockworkgeek 28568 * @author timothypratley / https://github.com/timothypratley 28569 * @author WestLangley / http://github.com/WestLangley 28570 * @author Mugen87 / https://github.com/Mugen87 28571 */ 28572 28573// PolyhedronGeometry 28574 28575function PolyhedronGeometry( vertices, indices, radius, detail ) { 28576 28577 Geometry.call( this ); 28578 28579 this.type = 'PolyhedronGeometry'; 28580 28581 this.parameters = { 28582 vertices: vertices, 28583 indices: indices, 28584 radius: radius, 28585 detail: detail 28586 }; 28587 28588 this.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) ); 28589 this.mergeVertices(); 28590 28591} 28592 28593PolyhedronGeometry.prototype = Object.create( Geometry.prototype ); 28594PolyhedronGeometry.prototype.constructor = PolyhedronGeometry; 28595 28596// PolyhedronBufferGeometry 28597 28598function PolyhedronBufferGeometry( vertices, indices, radius, detail ) { 28599 28600 BufferGeometry.call( this ); 28601 28602 this.type = 'PolyhedronBufferGeometry'; 28603 28604 this.parameters = { 28605 vertices: vertices, 28606 indices: indices, 28607 radius: radius, 28608 detail: detail 28609 }; 28610 28611 radius = radius || 1; 28612 detail = detail || 0; 28613 28614 // default buffer data 28615 28616 var vertexBuffer = []; 28617 var uvBuffer = []; 28618 28619 // the subdivision creates the vertex buffer data 28620 28621 subdivide( detail ); 28622 28623 // all vertices should lie on a conceptual sphere with a given radius 28624 28625 applyRadius( radius ); 28626 28627 // finally, create the uv data 28628 28629 generateUVs(); 28630 28631 // build non-indexed geometry 28632 28633 this.setAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) ); 28634 this.setAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) ); 28635 this.setAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) ); 28636 28637 if ( detail === 0 ) { 28638 28639 this.computeVertexNormals(); // flat normals 28640 28641 } else { 28642 28643 this.normalizeNormals(); // smooth normals 28644 28645 } 28646 28647 // helper functions 28648 28649 function subdivide( detail ) { 28650 28651 var a = new Vector3(); 28652 var b = new Vector3(); 28653 var c = new Vector3(); 28654 28655 // iterate over all faces and apply a subdivison with the given detail value 28656 28657 for ( var i = 0; i < indices.length; i += 3 ) { 28658 28659 // get the vertices of the face 28660 28661 getVertexByIndex( indices[ i + 0 ], a ); 28662 getVertexByIndex( indices[ i + 1 ], b ); 28663 getVertexByIndex( indices[ i + 2 ], c ); 28664 28665 // perform subdivision 28666 28667 subdivideFace( a, b, c, detail ); 28668 28669 } 28670 28671 } 28672 28673 function subdivideFace( a, b, c, detail ) { 28674 28675 var cols = Math.pow( 2, detail ); 28676 28677 // we use this multidimensional array as a data structure for creating the subdivision 28678 28679 var v = []; 28680 28681 var i, j; 28682 28683 // construct all of the vertices for this subdivision 28684 28685 for ( i = 0; i <= cols; i ++ ) { 28686 28687 v[ i ] = []; 28688 28689 var aj = a.clone().lerp( c, i / cols ); 28690 var bj = b.clone().lerp( c, i / cols ); 28691 28692 var rows = cols - i; 28693 28694 for ( j = 0; j <= rows; j ++ ) { 28695 28696 if ( j === 0 && i === cols ) { 28697 28698 v[ i ][ j ] = aj; 28699 28700 } else { 28701 28702 v[ i ][ j ] = aj.clone().lerp( bj, j / rows ); 28703 28704 } 28705 28706 } 28707 28708 } 28709 28710 // construct all of the faces 28711 28712 for ( i = 0; i < cols; i ++ ) { 28713 28714 for ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) { 28715 28716 var k = Math.floor( j / 2 ); 28717 28718 if ( j % 2 === 0 ) { 28719 28720 pushVertex( v[ i ][ k + 1 ] ); 28721 pushVertex( v[ i + 1 ][ k ] ); 28722 pushVertex( v[ i ][ k ] ); 28723 28724 } else { 28725 28726 pushVertex( v[ i ][ k + 1 ] ); 28727 pushVertex( v[ i + 1 ][ k + 1 ] ); 28728 pushVertex( v[ i + 1 ][ k ] ); 28729 28730 } 28731 28732 } 28733 28734 } 28735 28736 } 28737 28738 function applyRadius( radius ) { 28739 28740 var vertex = new Vector3(); 28741 28742 // iterate over the entire buffer and apply the radius to each vertex 28743 28744 for ( var i = 0; i < vertexBuffer.length; i += 3 ) { 28745 28746 vertex.x = vertexBuffer[ i + 0 ]; 28747 vertex.y = vertexBuffer[ i + 1 ]; 28748 vertex.z = vertexBuffer[ i + 2 ]; 28749
28750 vertex.normalize().multiplyScalar( radius ); 28751 28752 vertexBuffer[ i + 0 ] = vertex.x; 28753 vertexBuffer[ i + 1 ] = vertex.y; 28754 vertexBuffer[ i + 2 ] = vertex.z; 28755 28756 } 28757 28758 } 28759 28760 function generateUVs() { 28761 28762 var vertex = new Vector3(); 28763 28764 for ( var i = 0; i < vertexBuffer.length; i += 3 ) { 28765 28766 vertex.x = vertexBuffer[ i + 0 ]; 28767 vertex.y = vertexBuffer[ i + 1 ]; 28768 vertex.z = vertexBuffer[ i + 2 ]; 28769 28770 var u = azimuth( vertex ) / 2 / Math.PI + 0.5; 28771 var v = inclination( vertex ) / Math.PI + 0.5; 28772 uvBuffer.push( u, 1 - v ); 28773 28774 } 28775 28776 correctUVs(); 28777 28778 correctSeam(); 28779 28780 } 28781 28782 function correctSeam() { 28783 28784 // handle case when face straddles the seam, see #3269 28785 28786 for ( var i = 0; i < uvBuffer.length; i += 6 ) { 28787 28788 // uv data of a single face 28789 28790 var x0 = uvBuffer[ i + 0 ]; 28791 var x1 = uvBuffer[ i + 2 ]; 28792 var x2 = uvBuffer[ i + 4 ]; 28793 28794 var max = Math.max( x0, x1, x2 ); 28795 var min = Math.min( x0, x1, x2 ); 28796 28797 // 0.9 is somewhat arbitrary 28798 28799 if ( max > 0.9 && min < 0.1 ) { 28800 28801 if ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1; 28802 if ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1; 28803 if ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1; 28804 28805 } 28806 28807 } 28808 28809 } 28810 28811 function pushVertex( vertex ) { 28812 28813 vertexBuffer.push( vertex.x, vertex.y, vertex.z ); 28814 28815 } 28816 28817 function getVertexByIndex( index, vertex ) { 28818 28819 var stride = index * 3; 28820 28821 vertex.x = vertices[ stride + 0 ]; 28822 vertex.y = vertices[ stride + 1 ]; 28823 vertex.z = vertices[ stride + 2 ]; 28824 28825 } 28826 28827 function correctUVs() { 28828 28829 var a = new Vector3(); 28830 var b = new Vector3(); 28831 var c = new Vector3(); 28832 28833 var centroid = new Vector3(); 28834 28835 var uvA = new Vector2(); 28836 var uvB = new Vector2(); 28837 var uvC = new Vector2(); 28838 28839 for ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) { 28840 28841 a.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] ); 28842 b.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] ); 28843 c.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] ); 28844 28845 uvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] ); 28846 uvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] ); 28847 uvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] ); 28848 28849 centroid.copy( a ).add( b ).add( c ).divideScalar( 3 ); 28850 28851 var azi = azimuth( centroid ); 28852 28853 correctUV( uvA, j + 0, a, azi ); 28854 correctUV( uvB, j + 2, b, azi ); 28855 correctUV( uvC, j + 4, c, azi ); 28856 28857 } 28858 28859 } 28860 28861 function correctUV( uv, stride, vector, azimuth ) { 28862 28863 if ( ( azimuth < 0 ) && ( uv.x === 1 ) ) { 28864 28865 uvBuffer[ stride ] = uv.x - 1; 28866 28867 } 28868 28869 if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) { 28870 28871 uvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5; 28872 28873 } 28874 28875 } 28876 28877 // Angle around the Y axis, counter-clockwise when looking from above. 28878 28879 function azimuth( vector ) { 28880 28881 return Math.atan2( vector.z, - vector.x ); 28882 28883 } 28884 28885 28886 // Angle above the XZ plane. 28887 28888 function inclination( vector ) { 28889 28890 return Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) ); 28891 28892 } 28893 28894} 28895 28896PolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 28897PolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry; 28898 28899/** 28900 * @author timothypratley / https://github.com/timothypratley 28901 * @author Mugen87 / https://github.com/Mugen87 28902 */ 28903 28904// TetrahedronGeometry 28905 28906function TetrahedronGeometry( radius, detail ) { 28907 28908 Geometry.call( this ); 28909 28910 this.type = 'TetrahedronGeometry'; 28911 28912 this.parameters = { 28913 radius: radius, 28914 detail: detail 28915 }; 28916 28917 this.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) ); 28918 this.mergeVertices(); 28919 28920} 28921 28922TetrahedronGeometry.prototype = Object.create( Geometry.prototype ); 28923TetrahedronGeometry.prototype.constructor = TetrahedronGeometry; 28924 28925// TetrahedronBufferGeometry 28926 28927function TetrahedronBufferGeometry( radius, detail ) { 28928 28929 var vertices = [ 28930 1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1 28931 ]; 28932 28933 var indices = [ 28934 2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1 28935 ]; 28936 28937 PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); 28938 28939 this.type = 'TetrahedronBufferGeometry'; 28940 28941 this.parameters = { 28942 radius: radius, 28943 detail: detail 28944 }; 28945 28946} 28947 28948TetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); 28949TetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry; 28950 28951/** 28952 * @author timothypratley / https://github.com/timothypratley 28953 * @author Mugen87 / https://github.com/Mugen87 28954 */ 28955 28956// OctahedronGeometry 28957 28958function OctahedronGeometry( radius, detail ) { 28959 28960 Geometry.call( this ); 28961 28962 this.type = 'OctahedronGeometry'; 28963 28964 this.parameters = { 28965 radius: radius, 28966 detail: detail 28967 }; 28968 28969 this.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) ); 28970 this.mergeVertices(); 28971 28972} 28973 28974OctahedronGeometry.prototype = Object.create( Geometry.prototype ); 28975OctahedronGeometry.prototype.constructor = OctahedronGeometry; 28976 28977// OctahedronBufferGeometry 28978 28979function OctahedronBufferGeometry( radius, detail ) { 28980 28981 var vertices = [ 28982 1, 0, 0, - 1, 0, 0, 0, 1, 0, 28983 0, - 1, 0, 0, 0, 1, 0, 0, - 1 28984 ]; 28985 28986 var indices = [ 28987 0, 2, 4, 0, 4, 3, 0, 3, 5, 28988 0, 5, 2, 1, 2, 5, 1, 5, 3, 28989 1, 3, 4, 1, 4, 2 28990 ]; 28991 28992 PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); 28993 28994 this.type = 'OctahedronBufferGeometry'; 28995 28996 this.parameters = { 28997 radius: radius, 28998 detail: detail 28999 }; 29000 29001} 29002 29003OctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); 29004OctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry; 29005 29006/** 29007 * @author timothypratley / https://github.com/timothypratley 29008 * @author Mugen87 / https://github.com/Mugen87 29009 */ 29010 29011// IcosahedronGeometry 29012 29013function IcosahedronGeometry( radius, detail ) { 29014 29015 Geometry.call( this ); 29016 29017 this.type = 'IcosahedronGeometry'; 29018 29019 this.parameters = { 29020 radius: radius, 29021 detail: detail 29022 }; 29023 29024 this.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) ); 29025 this.mergeVertices(); 29026 29027} 29028 29029IcosahedronGeometry.prototype = Object.create( Geometry.prototype ); 29030IcosahedronGeometry.prototype.constructor = IcosahedronGeometry; 29031 29032// IcosahedronBufferGeometry 29033 29034function IcosahedronBufferGeometry( radius, detail ) { 29035 29036 var t = ( 1 + Math.sqrt( 5 ) ) / 2; 29037 29038 var vertices = [ 29039 - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0, 29040 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 29041 t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1 29042 ]; 29043 29044 var indices = [ 29045 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, 29046 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, 29047 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, 29048 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1 29049 ]; 29050 29051 PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); 29052 29053 this.type = 'IcosahedronBufferGeometry'; 29054 29055 this.parameters = { 29056 radius: radius, 29057 detail: detail 29058 }; 29059 29060} 29061 29062IcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); 29063IcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry; 29064 29065/** 29066 * @author Abe Pazos / https://hamoid.com 29067 * @author Mugen87 / https://github.com/Mugen87 29068 */ 29069 29070// DodecahedronGeometry 29071 29072function DodecahedronGeometry( radius, detail ) { 29073 29074 Geometry.call( this ); 29075 29076 this.type = 'DodecahedronGeometry'; 29077 29078 this.parameters = { 29079 radius: radius, 29080 detail: detail 29081 }; 29082 29083 this.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) ); 29084 this.mergeVertices(); 29085 29086} 29087 29088DodecahedronGeometry.prototype = Object.create( Geometry.prototype ); 29089DodecahedronGeometry.prototype.constructor = DodecahedronGeometry; 29090 29091// DodecahedronBufferGeometry 29092 29093function DodecahedronBufferGeometry( radius, detail ) { 29094 29095 var t = ( 1 + Math.sqrt( 5 ) ) / 2; 29096 var r = 1 / t; 29097 29098 var vertices = [ 29099 29100 // (±1, ±1, ±1) 29101 - 1, - 1, - 1, - 1, - 1, 1, 29102 - 1, 1, - 1, - 1, 1, 1, 29103 1, - 1, - 1, 1, - 1, 1, 29104 1, 1, - 1, 1, 1, 1, 29105 29106 // (0, ±1/Ï, ±Ï) 29107 0, - r, - t, 0, - r, t, 29108 0, r, - t, 0, r, t, 29109 29110 // (±1/Ï, ±Ï, 0) 29111 - r, - t, 0, - r, t, 0, 29112 r, - t, 0, r, t, 0, 29113 29114 // (±Ï, 0, ±1/Ï) 29115 - t, 0, - r, t, 0, - r, 29116 - t, 0, r, t, 0, r 29117 ]; 29118 29119 var indices = [ 29120 3, 11, 7, 3, 7, 15, 3, 15, 13, 29121 7, 19, 17, 7, 17, 6, 7, 6, 15, 29122 17, 4, 8, 17, 8, 10, 17, 10, 6, 29123 8, 0, 16, 8, 16, 2, 8, 2, 10, 29124 0, 12, 1, 0, 1, 18, 0, 18, 16, 29125 6, 10, 2, 6, 2, 13, 6, 13, 15, 29126 2, 16, 18, 2, 18, 3, 2, 3, 13, 29127 18, 1, 9, 18, 9, 11, 18, 11, 3,
29128 4, 14, 12, 4, 12, 0, 4, 0, 8, 29129 11, 9, 5, 11, 5, 19, 11, 19, 7, 29130 19, 5, 14, 19, 14, 4, 19, 4, 17, 29131 1, 12, 14, 1, 14, 5, 1, 5, 9 29132 ]; 29133 29134 PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); 29135 29136 this.type = 'DodecahedronBufferGeometry'; 29137 29138 this.parameters = { 29139 radius: radius, 29140 detail: detail 29141 }; 29142 29143} 29144 29145DodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); 29146DodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry; 29147 29148/** 29149 * @author oosmoxiecode / https://github.com/oosmoxiecode 29150 * @author WestLangley / https://github.com/WestLangley 29151 * @author zz85 / https://github.com/zz85 29152 * @author miningold / https://github.com/miningold 29153 * @author jonobr1 / https://github.com/jonobr1 29154 * @author Mugen87 / https://github.com/Mugen87 29155 * 29156 */ 29157 29158// TubeGeometry 29159 29160function TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) { 29161 29162 Geometry.call( this ); 29163 29164 this.type = 'TubeGeometry'; 29165 29166 this.parameters = { 29167 path: path, 29168 tubularSegments: tubularSegments, 29169 radius: radius, 29170 radialSegments: radialSegments, 29171 closed: closed 29172 }; 29173 29174 if ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' ); 29175 29176 var bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ); 29177 29178 // expose internals 29179 29180 this.tangents = bufferGeometry.tangents; 29181 this.normals = bufferGeometry.normals; 29182 this.binormals = bufferGeometry.binormals; 29183 29184 // create geometry 29185 29186 this.fromBufferGeometry( bufferGeometry ); 29187 this.mergeVertices(); 29188 29189} 29190 29191TubeGeometry.prototype = Object.create( Geometry.prototype ); 29192TubeGeometry.prototype.constructor = TubeGeometry; 29193 29194// TubeBufferGeometry 29195 29196function TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) { 29197 29198 BufferGeometry.call( this ); 29199 29200 this.type = 'TubeBufferGeometry'; 29201 29202 this.parameters = { 29203 path: path, 29204 tubularSegments: tubularSegments, 29205 radius: radius, 29206 radialSegments: radialSegments, 29207 closed: closed 29208 }; 29209 29210 tubularSegments = tubularSegments || 64; 29211 radius = radius || 1; 29212 radialSegments = radialSegments || 8; 29213 closed = closed || false; 29214 29215 var frames = path.computeFrenetFrames( tubularSegments, closed ); 29216 29217 // expose internals 29218 29219 this.tangents = frames.tangents; 29220 this.normals = frames.normals; 29221 this.binormals = frames.binormals; 29222 29223 // helper variables 29224 29225 var vertex = new Vector3(); 29226 var normal = new Vector3(); 29227 var uv = new Vector2(); 29228 var P = new Vector3(); 29229 29230 var i, j; 29231 29232 // buffer 29233 29234 var vertices = []; 29235 var normals = []; 29236 var uvs = []; 29237 var indices = []; 29238 29239 // create buffer data 29240 29241 generateBufferData(); 29242 29243 // build geometry 29244 29245 this.setIndex( indices ); 29246 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 29247 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 29248 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 29249 29250 // functions 29251 29252 function generateBufferData() { 29253 29254 for ( i = 0; i < tubularSegments; i ++ ) { 29255 29256 generateSegment( i ); 29257 29258 } 29259 29260 // if the geometry is not closed, generate the last row of vertices and normals 29261 // at the regular position on the given path 29262 // 29263 // if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ) 29264 29265 generateSegment( ( closed === false ) ? tubularSegments : 0 ); 29266 29267 // uvs are generated in a separate function. 29268 // this makes it easy compute correct values for closed geometries 29269 29270 generateUVs(); 29271 29272 // finally create faces 29273 29274 generateIndices(); 29275 29276 } 29277 29278 function generateSegment( i ) { 29279 29280 // we use getPointAt to sample evenly distributed points from the given path 29281 29282 P = path.getPointAt( i / tubularSegments, P ); 29283 29284 // retrieve corresponding normal and binormal 29285 29286 var N = frames.normals[ i ]; 29287 var B = frames.binormals[ i ]; 29288 29289 // generate normals and vertices for the current segment 29290 29291 for ( j = 0; j <= radialSegments; j ++ ) { 29292 29293 var v = j / radialSegments * Math.PI * 2; 29294 29295 var sin = Math.sin( v ); 29296 var cos = - Math.cos( v ); 29297 29298 // normal 29299 29300 normal.x = ( cos * N.x + sin * B.x ); 29301 normal.y = ( cos * N.y + sin * B.y ); 29302 normal.z = ( cos * N.z + sin * B.z ); 29303 normal.normalize(); 29304 29305 normals.push( normal.x, normal.y, normal.z ); 29306 29307 // vertex 29308 29309 vertex.x = P.x + radius * normal.x; 29310 vertex.y = P.y + radius * normal.y;
29311 vertex.z = P.z + radius * normal.z; 29312 29313 vertices.push( vertex.x, vertex.y, vertex.z ); 29314 29315 } 29316 29317 } 29318 29319 function generateIndices() { 29320 29321 for ( j = 1; j <= tubularSegments; j ++ ) { 29322 29323 for ( i = 1; i <= radialSegments; i ++ ) { 29324 29325 var a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 ); 29326 var b = ( radialSegments + 1 ) * j + ( i - 1 ); 29327 var c = ( radialSegments + 1 ) * j + i; 29328 var d = ( radialSegments + 1 ) * ( j - 1 ) + i; 29329 29330 // faces 29331 29332 indices.push( a, b, d ); 29333 indices.push( b, c, d ); 29334 29335 } 29336 29337 } 29338 29339 } 29340 29341 function generateUVs() { 29342 29343 for ( i = 0; i <= tubularSegments; i ++ ) { 29344 29345 for ( j = 0; j <= radialSegments; j ++ ) { 29346 29347 uv.x = i / tubularSegments; 29348 uv.y = j / radialSegments; 29349 29350 uvs.push( uv.x, uv.y ); 29351 29352 } 29353 29354 } 29355 29356 } 29357 29358} 29359 29360TubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 29361TubeBufferGeometry.prototype.constructor = TubeBufferGeometry; 29362 29363TubeBufferGeometry.prototype.toJSON = function () { 29364 29365 var data = BufferGeometry.prototype.toJSON.call( this ); 29366 29367 data.path = this.parameters.path.toJSON(); 29368 29369 return data; 29370 29371}; 29372 29373/** 29374 * @author oosmoxiecode 29375 * @author Mugen87 / https://github.com/Mugen87 29376 * 29377 * based on http://www.blackpawn.com/texts/pqtorus/ 29378 */ 29379 29380// TorusKnotGeometry 29381 29382function TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) { 29383 29384 Geometry.call( this ); 29385 29386 this.type = 'TorusKnotGeometry'; 29387 29388 this.parameters = { 29389 radius: radius, 29390 tube: tube, 29391 tubularSegments: tubularSegments, 29392 radialSegments: radialSegments, 29393 p: p, 29394 q: q 29395 }; 29396 29397 if ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' ); 29398 29399 this.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) ); 29400 this.mergeVertices(); 29401 29402} 29403 29404TorusKnotGeometry.prototype = Object.create( Geometry.prototype ); 29405TorusKnotGeometry.prototype.constructor = TorusKnotGeometry; 29406 29407// TorusKnotBufferGeometry 29408 29409function TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) { 29410 29411 BufferGeometry.call( this ); 29412 29413 this.type = 'TorusKnotBufferGeometry'; 29414 29415 this.parameters = { 29416 radius: radius, 29417 tube: tube, 29418 tubularSegments: tubularSegments, 29419 radialSegments: radialSegments, 29420 p: p, 29421 q: q 29422 }; 29423 29424 radius = radius || 1; 29425 tube = tube || 0.4; 29426 tubularSegments = Math.floor( tubularSegments ) || 64; 29427 radialSegments = Math.floor( radialSegments ) || 8; 29428 p = p || 2; 29429 q = q || 3; 29430 29431 // buffers 29432 29433 var indices = []; 29434 var vertices = []; 29435 var normals = []; 29436 var uvs = []; 29437 29438 // helper variables 29439 29440 var i, j; 29441 29442 var vertex = new Vector3(); 29443 var normal = new Vector3(); 29444 29445 var P1 = new Vector3(); 29446 var P2 = new Vector3(); 29447 29448 var B = new Vector3(); 29449 var T = new Vector3(); 29450 var N = new Vector3(); 29451 29452 // generate vertices, normals and uvs 29453 29454 for ( i = 0; i <= tubularSegments; ++ i ) { 29455 29456 // the radian "u" is used to calculate the position on the torus curve of the current tubular segement 29457 29458 var u = i / tubularSegments * p * Math.PI * 2; 29459 29460 // now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead. 29461 // these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions 29462 29463 calculatePositionOnCurve( u, p, q, radius, P1 ); 29464 calculatePositionOnCurve( u + 0.01, p, q, radius, P2 ); 29465 29466 // calculate orthonormal basis 29467 29468 T.subVectors( P2, P1 ); 29469 N.addVectors( P2, P1 ); 29470 B.crossVectors( T, N ); 29471 N.crossVectors( B, T ); 29472 29473 // normalize B, N. T can be ignored, we don't use it 29474 29475 B.normalize(); 29476 N.normalize(); 29477 29478 for ( j = 0; j <= radialSegments; ++ j ) { 29479 29480 // now calculate the vertices. they are nothing more than an extrusion of the torus curve. 29481 // because we extrude a shape in the xy-plane, there is no need to calculate a z-value. 29482 29483 var v = j / radialSegments * Math.PI * 2; 29484 var cx = - tube * Math.cos( v ); 29485 var cy = tube * Math.sin( v ); 29486 29487 // now calculate the final vertex position. 29488 // first we orient the extrusion with our basis vectos, then we add it to the current position on the curve 29489 29490 vertex.x = P1.x + ( cx * N.x + cy * B.x ); 29491 vertex.y = P1.y + ( cx * N.y + cy * B.y ); 29492 vertex.z = P1.z + ( cx * N.z + cy * B.z ); 29493 29494 vertices.push( vertex.x, vertex.y, vertex.z ); 29495 29496 // normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal) 29497 29498 normal.subVectors( vertex, P1 ).normalize(); 29499 29500 normals.push( normal.x, normal.y, normal.z ); 29501 29502 // uv 29503 29504 uvs.push( i / tubularSegments ); 29505 uvs.push( j / radialSegments ); 29506 29507 } 29508 29509 } 29510 29511 // generate indices 29512 29513 for ( j = 1; j <= tubularSegments; j ++ ) { 29514 29515 for ( i = 1; i <= radialSegments; i ++ ) { 29516 29517 // indices 29518 29519 var a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 ); 29520 var b = ( radialSegments + 1 ) * j + ( i - 1 ); 29521 var c = ( radialSegments + 1 ) * j + i; 29522 var d = ( radialSegments + 1 ) * ( j - 1 ) + i; 29523 29524 // faces 29525 29526 indices.push( a, b, d ); 29527 indices.push( b, c, d ); 29528 29529 } 29530 29531 } 29532 29533 // build geometry 29534 29535 this.setIndex( indices ); 29536 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
29537 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 29538 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 29539 29540 // this function calculates the current position on the torus curve 29541 29542 function calculatePositionOnCurve( u, p, q, radius, position ) { 29543 29544 var cu = Math.cos( u ); 29545 var su = Math.sin( u ); 29546 var quOverP = q / p * u; 29547 var cs = Math.cos( quOverP ); 29548 29549 position.x = radius * ( 2 + cs ) * 0.5 * cu; 29550 position.y = radius * ( 2 + cs ) * su * 0.5; 29551 position.z = radius * Math.sin( quOverP ) * 0.5; 29552 29553 } 29554 29555} 29556 29557TorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 29558TorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry; 29559 29560/** 29561 * @author oosmoxiecode 29562 * @author mrdoob / http://mrdoob.com/ 29563 * @author Mugen87 / https://github.com/Mugen87 29564 */ 29565 29566// TorusGeometry 29567 29568function TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) { 29569 29570 Geometry.call( this ); 29571 29572 this.type = 'TorusGeometry'; 29573 29574 this.parameters = { 29575 radius: radius, 29576 tube: tube, 29577 radialSegments: radialSegments, 29578 tubularSegments: tubularSegments, 29579 arc: arc 29580 }; 29581 29582 this.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) ); 29583 this.mergeVertices(); 29584 29585} 29586 29587TorusGeometry.prototype = Object.create( Geometry.prototype ); 29588TorusGeometry.prototype.constructor = TorusGeometry; 29589 29590// TorusBufferGeometry 29591 29592function TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) { 29593 29594 BufferGeometry.call( this ); 29595 29596 this.type = 'TorusBufferGeometry'; 29597 29598 this.parameters = { 29599 radius: radius, 29600 tube: tube, 29601 radialSegments: radialSegments, 29602 tubularSegments: tubularSegments, 29603 arc: arc 29604 }; 29605 29606 radius = radius || 1; 29607 tube = tube || 0.4; 29608 radialSegments = Math.floor( radialSegments ) || 8; 29609 tubularSegments = Math.floor( tubularSegments ) || 6; 29610 arc = arc || Math.PI * 2; 29611 29612 // buffers 29613 29614 var indices = []; 29615 var vertices = []; 29616 var normals = []; 29617 var uvs = []; 29618 29619 // helper variables 29620 29621 var center = new Vector3(); 29622 var vertex = new Vector3(); 29623 var normal = new Vector3(); 29624 29625 var j, i; 29626 29627 // generate vertices, normals and uvs 29628 29629 for ( j = 0; j <= radialSegments; j ++ ) { 29630 29631 for ( i = 0; i <= tubularSegments; i ++ ) { 29632 29633 var u = i / tubularSegments * arc; 29634 var v = j / radialSegments * Math.PI * 2; 29635 29636 // vertex 29637 29638 vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u ); 29639 vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u ); 29640 vertex.z = tube * Math.sin( v ); 29641 29642 vertices.push( vertex.x, vertex.y, vertex.z ); 29643 29644 // normal 29645 29646 center.x = radius * Math.cos( u ); 29647 center.y = radius * Math.sin( u ); 29648 normal.subVectors( vertex, center ).normalize(); 29649 29650 normals.push( normal.x, normal.y, normal.z ); 29651 29652 // uv 29653 29654 uvs.push( i / tubularSegments ); 29655 uvs.push( j / radialSegments ); 29656 29657 } 29658 29659 } 29660 29661 // generate indices 29662 29663 for ( j = 1; j <= radialSegments; j ++ ) { 29664 29665 for ( i = 1; i <= tubularSegments; i ++ ) { 29666 29667 // indices 29668 29669 var a = ( tubularSegments + 1 ) * j + i - 1; 29670 var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1; 29671 var c = ( tubularSegments + 1 ) * ( j - 1 ) + i; 29672 var d = ( tubularSegments + 1 ) * j + i; 29673 29674 // faces 29675 29676 indices.push( a, b, d ); 29677 indices.push( b, c, d ); 29678 29679 } 29680 29681 } 29682 29683 // build geometry 29684 29685 this.setIndex( indices ); 29686 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 29687 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 29688 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 29689 29690} 29691 29692TorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 29693TorusBufferGeometry.prototype.constructor = TorusBufferGeometry; 29694 29695/** 29696 * @author Mugen87 / https://github.com/Mugen87 29697 * Port from https://github.com/mapbox/earcut (v2.2.2) 29698 */ 29699 29700var Earcut = { 29701 29702 triangulate: function ( data, holeIndices, dim ) { 29703 29704 dim = dim || 2; 29705 29706 var hasHoles = holeIndices && holeIndices.length, 29707 outerLen = hasHoles ? holeIndices[ 0 ] * dim : data.length, 29708 outerNode = linkedList( data, 0, outerLen, dim, true ), 29709 triangles = []; 29710 29711 if ( ! outerNode || outerNode.next === outerNode.prev ) return triangles; 29712 29713 var minX, minY, maxX, maxY, x, y, invSize; 29714 29715 if ( hasHoles ) outerNode = eliminateHoles( data, holeIndices, outerNode, dim ); 29716 29717 // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox 29718 if ( data.length > 80 * dim ) { 29719 29720 minX = maxX = data[ 0 ]; 29721 minY = maxY = data[ 1 ]; 29722 29723 for ( var i = dim; i < outerLen; i += dim ) { 29724 29725 x = data[ i ]; 29726 y = data[ i + 1 ]; 29727 if ( x < minX ) minX = x; 29728 if ( y < minY ) minY = y; 29729 if ( x > maxX ) maxX = x; 29730 if ( y > maxY ) maxY = y; 29731 29732 } 29733 29734 // minX, minY and invSize are later used to transform coords into integers for z-order calculation 29735 invSize = Math.max( maxX - minX, maxY - minY ); 29736 invSize = invSize !== 0 ? 1 / invSize : 0; 29737 29738 } 29739 29740 earcutLinked( outerNode, triangles, dim, minX, minY, invSize ); 29741 29742 return triangles; 29743 29744 } 29745 29746}; 29747 29748// create a circular doubly linked list from polygon points in the specified winding order 29749function linkedList( data, start, end, dim, clockwise ) { 29750 29751 var i, last; 29752 29753 if ( clockwise === ( signedArea( data, start, end, dim ) > 0 ) ) { 29754 29755 for ( i = start; i < end;
29755 i += dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last ); 29756 29757 } else { 29758 29759 for ( i = end - dim; i >= start; i -= dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last ); 29760 29761 } 29762 29763 if ( last && equals( last, last.next ) ) { 29764 29765 removeNode( last ); 29766 last = last.next; 29767 29768 } 29769 29770 return last; 29771 29772} 29773 29774// eliminate colinear or duplicate points 29775function filterPoints( start, end ) { 29776 29777 if ( ! start ) return start; 29778 if ( ! end ) end = start; 29779 29780 var p = start, 29781 again; 29782 do { 29783 29784 again = false; 29785 29786 if ( ! p.steiner && ( equals( p, p.next ) || area( p.prev, p, p.next ) === 0 ) ) { 29787 29788 removeNode( p ); 29789 p = end = p.prev; 29790 if ( p === p.next ) break; 29791 again = true; 29792 29793 } else { 29794 29795 p = p.next; 29796 29797 } 29798 29799 } while ( again || p !== end ); 29800 29801 return end; 29802 29803} 29804 29805// main ear slicing loop which triangulates a polygon (given as a linked list) 29806function earcutLinked( ear, triangles, dim, minX, minY, invSize, pass ) { 29807 29808 if ( ! ear ) return; 29809 29810 // interlink polygon nodes in z-order 29811 if ( ! pass && invSize ) indexCurve( ear, minX, minY, invSize ); 29812 29813 var stop = ear, 29814 prev, next; 29815 29816 // iterate through ears, slicing them one by one 29817 while ( ear.prev !== ear.next ) { 29818 29819 prev = ear.prev; 29820 next = ear.next; 29821 29822 if ( invSize ? isEarHashed( ear, minX, minY, invSize ) : isEar( ear ) ) { 29823 29824 // cut off the triangle 29825 triangles.push( prev.i / dim ); 29826 triangles.push( ear.i / dim ); 29827 triangles.push( next.i / dim ); 29828 29829 removeNode( ear ); 29830 29831 // skipping the next vertex leads to less sliver triangles 29832 ear = next.next; 29833 stop = next.next; 29834 29835 continue; 29836 29837 } 29838 29839 ear = next; 29840 29841 // if we looped through the whole remaining polygon and can't find any more ears 29842 if ( ear === stop ) { 29843 29844 // try filtering points and slicing again 29845 if ( ! pass ) { 29846 29847 earcutLinked( filterPoints( ear ), triangles, dim, minX, minY, invSize, 1 ); 29848 29849 // if this didn't work, try curing all small self-intersections locally 29850 29851 } else if ( pass === 1 ) { 29852 29853 ear = cureLocalIntersections( filterPoints( ear ), triangles, dim ); 29854 earcutLinked( ear, triangles, dim, minX, minY, invSize, 2 ); 29855 29856 // as a last resort, try splitting the remaining polygon into two 29857 29858 } else if ( pass === 2 ) { 29859 29860 splitEarcut( ear, triangles, dim, minX, minY, invSize ); 29861 29862 } 29863 29864 break; 29865 29866 } 29867 29868 } 29869 29870} 29871 29872// check whether a polygon node forms a valid ear with adjacent nodes 29873function isEar( ear ) { 29874 29875 var a = ear.prev, 29876 b = ear, 29877 c = ear.next; 29878 29879 if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear 29880 29881 // now make sure we don't have other points inside the potential ear 29882 var p = ear.next.next; 29883 29884 while ( p !== ear.prev ) { 29885 29886 if ( pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && 29887 area( p.prev, p, p.next ) >= 0 ) return false; 29888 p = p.next; 29889 29890 } 29891 29892 return true; 29893 29894} 29895 29896function isEarHashed( ear, minX, minY, invSize ) { 29897 29898 var a = ear.prev, 29899 b = ear, 29900 c = ear.next; 29901 29902 if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear 29903 29904 // triangle bbox; min & max are calculated like this for speed 29905 var minTX = a.x < b.x ? ( a.x < c.x ? a.x : c.x ) : ( b.x < c.x ? b.x : c.x ), 29906 minTY = a.y < b.y ? ( a.y < c.y ? a.y : c.y ) : ( b.y < c.y ? b.y : c.y ), 29907 maxTX = a.x > b.x ? ( a.x > c.x ? a.x : c.x ) : ( b.x > c.x ? b.x : c.x ), 29908 maxTY = a.y > b.y ? ( a.y > c.y ? a.y : c.y ) : ( b.y > c.y ? b.y : c.y ); 29909 29910 // z-order range for the current triangle bbox; 29911 var minZ = zOrder( minTX, minTY, minX, minY, invSize ), 29912 maxZ = zOrder( maxTX, maxTY, minX, minY, invSize ); 29913 29914 var p = ear.prevZ, 29915 n = ear.nextZ; 29916 29917 // look for points inside the triangle in both directions 29918 while ( p && p.z >= minZ && n && n.z <= maxZ ) { 29919 29920 if ( p !== ear.prev && p !== ear.next && 29921 pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && 29922 area( p.prev, p, p.next ) >= 0 ) return false; 29923 p = p.prevZ; 29924 29925 if ( n !== ear.prev && n !== ear.next && 29926 pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y ) && 29927 area( n.prev, n, n.next ) >= 0 ) return false; 29928 n = n.nextZ; 29929 29930 } 29931 29932 // look for remaining points in decreasing z-order 29933 while ( p && p.z >= minZ ) { 29934 29935 if ( p !== ear.prev && p !== ear.next && 29936 pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && 29937 area( p.prev, p, p.next ) >= 0 ) return false;
vendor: 16,168 bytes, lines 29938-30704
29938 p = p.prevZ; 29939 29940 } 29941 29942 // look for remaining points in increasing z-order 29943 while ( n && n.z <= maxZ ) { 29944 29945 if ( n !== ear.prev && n !== ear.next && 29946 pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y ) && 29947 area( n.prev, n, n.next ) >= 0 ) return false; 29948 n = n.nextZ; 29949 29950 } 29951 29952 return true; 29953 29954} 29955 29956// go through all polygon nodes and cure small local self-intersections 29957function cureLocalIntersections( start, triangles, dim ) { 29958 29959 var p = start; 29960 do { 29961 29962 var a = p.prev, 29963 b = p.next.next; 29964 29965 if ( ! equals( a, b ) && intersects( a, p, p.next, b ) && locallyInside( a, b ) && locallyInside( b, a ) ) { 29966 29967 triangles.push( a.i / dim ); 29968 triangles.push( p.i / dim ); 29969 triangles.push( b.i / dim ); 29970 29971 // remove two nodes involved 29972 removeNode( p ); 29973 removeNode( p.next ); 29974 29975 p = start = b; 29976 29977 } 29978 29979 p = p.next; 29980 29981 } while ( p !== start ); 29982 29983 return filterPoints( p ); 29984 29985} 29986 29987// try splitting polygon into two and triangulate them independently 29988function splitEarcut( start, triangles, dim, minX, minY, invSize ) { 29989 29990 // look for a valid diagonal that divides the polygon into two 29991 var a = start; 29992 do { 29993 29994 var b = a.next.next; 29995 while ( b !== a.prev ) { 29996 29997 if ( a.i !== b.i && isValidDiagonal( a, b ) ) { 29998 29999 // split the polygon in two by the diagonal 30000 var c = splitPolygon( a, b ); 30001 30002 // filter colinear points around the cuts 30003 a = filterPoints( a, a.next ); 30004 c = filterPoints( c, c.next ); 30005 30006 // run earcut on each half 30007 earcutLinked( a, triangles, dim, minX, minY, invSize ); 30008 earcutLinked( c, triangles, dim, minX, minY, invSize ); 30009 return; 30010 30011 } 30012 30013 b = b.next; 30014 30015 } 30016 30017 a = a.next; 30018 30019 } while ( a !== start ); 30020 30021} 30022 30023// link every hole into the outer loop, producing a single-ring polygon without holes 30024function eliminateHoles( data, holeIndices, outerNode, dim ) { 30025 30026 var queue = [], 30027 i, len, start, end, list; 30028 30029 for ( i = 0, len = holeIndices.length; i < len; i ++ ) { 30030 30031 start = holeIndices[ i ] * dim; 30032 end = i < len - 1 ? holeIndices[ i + 1 ] * dim : data.length; 30033 list = linkedList( data, start, end, dim, false ); 30034 if ( list === list.next ) list.steiner = true; 30035 queue.push( getLeftmost( list ) ); 30036 30037 } 30038 30039 queue.sort( compareX ); 30040 30041 // process holes from left to right 30042 for ( i = 0; i < queue.length; i ++ ) { 30043 30044 eliminateHole( queue[ i ], outerNode ); 30045 outerNode = filterPoints( outerNode, outerNode.next ); 30046 30047 } 30048 30049 return outerNode; 30050 30051} 30052 30053function compareX( a, b ) { 30054 30055 return a.x - b.x; 30056 30057} 30058 30059// find a bridge between vertices that connects hole with an outer ring and and link it 30060function eliminateHole( hole, outerNode ) { 30061 30062 outerNode = findHoleBridge( hole, outerNode ); 30063 if ( outerNode ) { 30064 30065 var b = splitPolygon( outerNode, hole ); 30066 30067 // filter collinear points around the cuts 30068 filterPoints( outerNode, outerNode.next ); 30069 filterPoints( b, b.next ); 30070 30071 } 30072 30073} 30074 30075// David Eberly's algorithm for finding a bridge between hole and outer polygon 30076function findHoleBridge( hole, outerNode ) { 30077 30078 var p = outerNode, 30079 hx = hole.x, 30080 hy = hole.y, 30081 qx = - Infinity, 30082 m; 30083 30084 // find a segment intersected by a ray from the hole's leftmost point to the left; 30085 // segment's endpoint with lesser x will be potential connection point 30086 do { 30087 30088 if ( hy <= p.y && hy >= p.next.y && p.next.y !== p.y ) { 30089 30090 var x = p.x + ( hy - p.y ) * ( p.next.x - p.x ) / ( p.next.y - p.y ); 30091 if ( x <= hx && x > qx ) { 30092 30093 qx = x; 30094 if ( x === hx ) { 30095 30096 if ( hy === p.y ) return p; 30097 if ( hy === p.next.y ) return p.next; 30098 30099 } 30100 30101 m = p.x < p.next.x ? p : p.next; 30102 30103 } 30104 30105 } 30106 30107 p = p.next; 30108 30109 } while ( p !== outerNode ); 30110 30111 if ( ! m ) return null; 30112 30113 if ( hx === qx ) return m; // hole touches outer segment; pick leftmost endpoint 30114 30115 // look for points inside the triangle of hole point, segment intersection and endpoint; 30116 // if there are no points found, we have a valid connection; 30117 // otherwise choose the point of the minimum angle with the ray as connection point 30118 30119 var stop = m, 30120 mx = m.x, 30121 my = m.y, 30122 tanMin = Infinity, 30123 tan; 30124 30125 p = m; 30126 30127 do { 30128 30129 if ( hx >= p.x && p.x >= mx && hx !== p.x && 30130 pointInTriangle( hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y ) ) { 30131 30132 tan = Math.abs( hy - p.y ) / ( hx - p.x ); // tangential 30133 30134 if ( locallyInside( p, hole ) && ( tan < tanMin || ( tan === tanMin && ( p.x > m.x || ( p.x === m.x && sectorContainsSector( m, p ) ) ) ) ) ) { 30135 30136 m = p; 30137 tanMin = tan; 30138 30139 } 30140 30141 } 30142 30143 p = p.next; 30144 30145 } while ( p !== stop ); 30146 30147 return m; 30148 30149} 30150 30151// whether sector in vertex m contains sector in vertex p in the same coordinates 30152function sectorContainsSector( m, p ) { 30153 30154 return area( m.prev, m, p.prev ) < 0 && area( p.next, m, m.next ) < 0; 30155 30156} 30157 30158// interlink polygon nodes in z-order 30159function indexCurve( start, minX, minY, invSize ) { 30160 30161 var p = start; 30162 do { 30163 30164 if ( p.z === null ) p.z = zOrder( p.x, p.y, minX, minY, invSize ); 30165 p.prevZ = p.prev; 30166 p.nextZ = p.next; 30167 p = p.next; 30168 30169 } while ( p !== start ); 30170 30171 p.prevZ.nextZ = null; 30172 p.prevZ = null; 30173 30174 sortLinked( p ); 30175 30176} 30177 30178// Simon Tatham's linked list merge sort algorithm 30179// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html 30180function sortLinked( list ) { 30181 30182 var i, p, q, e, tail, numMerges, pSize, qSize, 30183 inSize = 1; 30184 30185 do { 30186 30187 p = list; 30188 list = null; 30189 tail = null; 30190 numMerges = 0; 30191 30192 while ( p ) { 30193 30194 numMerges ++; 30195 q = p; 30196 pSize = 0; 30197 for ( i = 0; i < inSize; i ++ ) { 30198 30199 pSize ++; 30200 q = q.nextZ; 30201 if ( ! q ) break; 30202 30203 } 30204 30205 qSize = inSize; 30206 30207 while ( pSize > 0 || ( qSize > 0 && q ) ) { 30208 30209 if ( pSize !== 0 && ( qSize === 0 || ! q || p.z <= q.z ) ) { 30210 30211 e = p; 30212 p = p.nextZ; 30213 pSize --; 30214 30215 } else { 30216 30217 e = q; 30218 q = q.nextZ; 30219 qSize --; 30220 30221 } 30222 30223 if ( tail ) tail.nextZ = e; 30224 else list = e; 30225 30226 e.prevZ = tail; 30227 tail = e; 30228 30229 } 30230 30231 p = q; 30232 30233 } 30234 30235 tail.nextZ = null; 30236 inSize *= 2; 30237 30238 } while ( numMerges > 1 ); 30239 30240 return list; 30241 30242} 30243 30244// z-order of a point given coords and inverse of the longer side of data bbox 30245function zOrder( x, y, minX, minY, invSize ) { 30246 30247 // coords are transformed into non-negative 15-bit integer range 30248 x = 32767 * ( x - minX ) * invSize; 30249 y = 32767 * ( y - minY ) * invSize; 30250 30251 x = ( x | ( x << 8 ) ) & 0x00FF00FF; 30252 x = ( x | ( x << 4 ) ) & 0x0F0F0F0F; 30253 x = ( x | ( x << 2 ) ) & 0x33333333; 30254 x = ( x | ( x << 1 ) ) & 0x55555555; 30255 30256 y = ( y | ( y << 8 ) ) & 0x00FF00FF; 30257 y = ( y | ( y << 4 ) ) & 0x0F0F0F0F; 30258 y = ( y | ( y << 2 ) ) & 0x33333333; 30259 y = ( y | ( y << 1 ) ) & 0x55555555; 30260 30261 return x | ( y << 1 ); 30262 30263} 30264 30265// find the leftmost node of a polygon ring 30266function getLeftmost( start ) { 30267 30268 var p = start, 30269 leftmost = start; 30270 do { 30271 30272 if ( p.x < leftmost.x || ( p.x === leftmost.x && p.y < leftmost.y ) ) leftmost = p; 30273 p = p.next; 30274 30275 } while ( p !== start ); 30276 30277 return leftmost; 30278 30279} 30280 30281// check if a point lies within a convex triangle 30282function pointInTriangle( ax, ay, bx, by, cx, cy, px, py ) { 30283 30284 return ( cx - px ) * ( ay - py ) - ( ax - px ) * ( cy - py ) >= 0 && 30285 ( ax - px ) * ( by - py ) - ( bx - px ) * ( ay - py ) >= 0 && 30286 ( bx - px ) * ( cy - py ) - ( cx - px ) * ( by - py ) >= 0; 30287 30288} 30289 30290// check if a diagonal between two polygon nodes is valid (lies in polygon interior) 30291function isValidDiagonal( a, b ) { 30292 30293 return a.next.i !== b.i && a.prev.i !== b.i && ! intersectsPolygon( a, b ) && // dones't intersect other edges 30294 ( locallyInside( a, b ) && locallyInside( b, a ) && middleInside( a, b ) && // locally visible 30295 ( area( a.prev, a, b.prev ) || area( a, b.prev, b ) ) || // does not create opposite-facing sectors 30296 equals( a, b ) && area( a.prev, a, a.next ) > 0 && area( b.prev, b, b.next ) > 0 ); // special zero-length case 30297 30298} 30299 30300// signed area of a triangle 30301function area( p, q, r ) { 30302 30303 return ( q.y - p.y ) * ( r.x - q.x ) - ( q.x - p.x ) * ( r.y - q.y ); 30304 30305} 30306 30307// check if two points are equal 30308function equals( p1, p2 ) { 30309 30310 return p1.x === p2.x && p1.y === p2.y; 30311 30312} 30313 30314// check if two segments intersect 30315function intersects( p1, q1, p2, q2 ) { 30316 30317 var o1 = sign( area( p1, q1, p2 ) ); 30318 var o2 = sign( area( p1, q1, q2 ) ); 30319 var o3 = sign( area( p2, q2, p1 ) ); 30320 var o4 = sign( area( p2, q2, q1 ) ); 30321 30322 if ( o1 !== o2 && o3 !== o4 ) return true; // general case 30323 30324 if ( o1 === 0 && onSegment( p1, p2, q1 ) ) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1 30325 if ( o2 === 0 && onSegment( p1, q2, q1 ) ) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1 30326 if ( o3 === 0 && onSegment( p2, p1, q2 ) ) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2 30327 if ( o4 === 0 && onSegment( p2, q1, q2 ) ) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2 30328 30329 return false; 30330 30331} 30332 30333// for collinear points p, q, r, check if point q lies on segment pr 30334function onSegment( p, q, r ) { 30335 30336 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 ); 30337 30338} 30339 30340function sign( num ) { 30341 30342 return num > 0 ? 1 : num < 0 ? - 1 : 0; 30343 30344} 30345 30346// check if a polygon diagonal intersects any polygon segments 30347function intersectsPolygon( a, b ) { 30348 30349 var p = a; 30350 do { 30351 30352 if ( p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && 30353 intersects( p, p.next, a, b ) ) return true; 30354 p = p.next; 30355 30356 } while ( p !== a ); 30357 30358 return false; 30359 30360} 30361 30362// check if a polygon diagonal is locally inside the polygon 30363function locallyInside( a, b ) { 30364 30365 return area( a.prev, a, a.next ) < 0 ? 30366 area( a, b, a.next ) >= 0 && area( a, a.prev, b ) >= 0 : 30367 area( a, b, a.prev ) < 0 || area( a, a.next, b ) < 0; 30368 30369} 30370 30371// check if the middle point of a polygon diagonal is inside the polygon 30372function middleInside( a, b ) { 30373 30374 var p = a, 30375 inside = false, 30376 px = ( a.x + b.x ) / 2, 30377 py = ( a.y + b.y ) / 2; 30378 do { 30379 30380 if ( ( ( p.y > py ) !== ( p.next.y > py ) ) && p.next.y !== p.y && 30381 ( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) ) 30382 inside = ! inside; 30383 p = p.next; 30384 30385 } while ( p !== a ); 30386 30387 return inside; 30388 30389} 30390 30391// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; 30392// if one belongs to the outer ring and another to a hole, it merges it into a single ring 30393function splitPolygon( a, b ) { 30394 30395 var a2 = new Node( a.i, a.x, a.y ), 30396 b2 = new Node( b.i, b.x, b.y ), 30397 an = a.next, 30398 bp = b.prev; 30399 30400 a.next = b; 30401 b.prev = a; 30402 30403 a2.next = an; 30404 an.prev = a2; 30405 30406 b2.next = a2; 30407 a2.prev = b2; 30408 30409 bp.next = b2; 30410 b2.prev = bp; 30411 30412 return b2; 30413 30414} 30415 30416// create a node and optionally link it with previous one (in a circular doubly linked list) 30417function insertNode( i, x, y, last ) { 30418 30419 var p = new Node( i, x, y ); 30420 30421 if ( ! last ) { 30422 30423 p.prev = p; 30424 p.next = p; 30425 30426 } else { 30427 30428 p.next = last.next; 30429 p.prev = last; 30430 last.next.prev = p; 30431 last.next = p; 30432 30433 } 30434 30435 return p; 30436 30437} 30438 30439function removeNode( p ) { 30440 30441 p.next.prev = p.prev; 30442 p.prev.next = p.next; 30443 30444 if ( p.prevZ ) p.prevZ.nextZ = p.nextZ; 30445 if ( p.nextZ ) p.nextZ.prevZ = p.prevZ; 30446 30447} 30448 30449function Node( i, x, y ) { 30450 30451 // vertex index in coordinates array 30452 this.i = i; 30453 30454 // vertex coordinates 30455 this.x = x; 30456 this.y = y; 30457 30458 // previous and next vertex nodes in a polygon ring 30459 this.prev = null; 30460 this.next = null; 30461 30462 // z-order curve value 30463 this.z = null; 30464 30465 // previous and next nodes in z-order 30466 this.prevZ = null; 30467 this.nextZ = null; 30468 30469 // indicates whether this is a steiner point 30470 this.steiner = false; 30471 30472} 30473 30474function signedArea( data, start, end, dim ) { 30475 30476 var sum = 0; 30477 for ( var i = start, j = end - dim; i < end; i += dim ) { 30478 30479 sum += ( data[ j ] - data[ i ] ) * ( data[ i + 1 ] + data[ j + 1 ] ); 30480 j = i; 30481 30482 } 30483 30484 return sum; 30485 30486} 30487 30488/** 30489 * @author zz85 / http://www.lab4games.net/zz85/blog 30490 */ 30491 30492var ShapeUtils = { 30493 30494 // calculate area of the contour polygon 30495 30496 area: function ( contour ) { 30497 30498 var n = contour.length; 30499 var a = 0.0; 30500 30501 for ( var p = n - 1, q = 0; q < n; p = q ++ ) { 30502 30503 a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y; 30504 30505 } 30506 30507 return a * 0.5; 30508 30509 }, 30510 30511 isClockWise: function ( pts ) { 30512 30513 return ShapeUtils.area( pts ) < 0; 30514 30515 }, 30516 30517 triangulateShape: function ( contour, holes ) { 30518 30519 var vertices = []; // flat array of vertices like [ x0,y0, x1,y1, x2,y2, ... ] 30520 var holeIndices = []; // array of hole indices 30521 var faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ] 30522 30523 removeDupEndPts( contour ); 30524 addContour( vertices, contour ); 30525 30526 // 30527 30528 var holeIndex = contour.length; 30529 30530 holes.forEach( removeDupEndPts ); 30531 30532 for ( var i = 0; i < holes.length; i ++ ) { 30533 30534 holeIndices.push( holeIndex ); 30535 holeIndex += holes[ i ].length; 30536 addContour( vertices, holes[ i ] ); 30537 30538 } 30539 30540 // 30541 30542 var triangles = Earcut.triangulate( vertices, holeIndices ); 30543 30544 // 30545 30546 for ( var i = 0; i < triangles.length; i += 3 ) { 30547 30548 faces.push( triangles.slice( i, i + 3 ) ); 30549 30550 } 30551 30552 return faces; 30553 30554 } 30555 30556}; 30557 30558function removeDupEndPts( points ) { 30559 30560 var l = points.length; 30561 30562 if ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) { 30563 30564 points.pop(); 30565 30566 } 30567 30568} 30569 30570function addContour( vertices, contour ) { 30571 30572 for ( var i = 0; i < contour.length; i ++ ) { 30573 30574 vertices.push( contour[ i ].x ); 30575 vertices.push( contour[ i ].y ); 30576 30577 } 30578 30579} 30580 30581/** 30582 * @author zz85 / http://www.lab4games.net/zz85/blog 30583 * 30584 * Creates extruded geometry from a path shape. 30585 * 30586 * parameters = { 30587 * 30588 * curveSegments: <int>, // number of points on the curves 30589 * steps: <int>, // number of points for z-side extrusions / used for subdividing segments of extrude spline too 30590 * depth: <float>, // Depth to extrude the shape 30591 * 30592 * bevelEnabled: <bool>, // turn on bevel 30593 * bevelThickness: <float>, // how deep into the original shape bevel goes 30594 * bevelSize: <float>, // how far from shape outline (including bevelOffset) is bevel 30595 * bevelOffset: <float>, // how far from shape outline does bevel start 30596 * bevelSegments: <int>, // number of bevel layers 30597 * 30598 * extrudePath: <THREE.Curve> // curve to extrude shape along 30599 * 30600 * UVGenerator: <Object> // object that provides UV generator functions 30601 * 30602 * } 30603 */ 30604 30605// ExtrudeGeometry 30606 30607function ExtrudeGeometry( shapes, options ) { 30608 30609 Geometry.call( this ); 30610 30611 this.type = 'ExtrudeGeometry'; 30612 30613 this.parameters = { 30614 shapes: shapes, 30615 options: options 30616 }; 30617 30618 this.fromBufferGeometry( new ExtrudeBufferGeometry( shapes, options ) ); 30619 this.mergeVertices(); 30620 30621} 30622 30623ExtrudeGeometry.prototype = Object.create( Geometry.prototype ); 30624ExtrudeGeometry.prototype.constructor = ExtrudeGeometry; 30625 30626ExtrudeGeometry.prototype.toJSON = function () { 30627 30628 var data = Geometry.prototype.toJSON.call( this ); 30629 30630 var shapes = this.parameters.shapes; 30631 var options = this.parameters.options; 30632 30633 return toJSON( shapes, options, data ); 30634 30635}; 30636 30637// ExtrudeBufferGeometry 30638 30639function ExtrudeBufferGeometry( shapes, options ) { 30640 30641 BufferGeometry.call( this ); 30642 30643 this.type = 'ExtrudeBufferGeometry'; 30644 30645 this.parameters = { 30646 shapes: shapes, 30647 options: options 30648 }; 30649 30650 shapes = Array.isArray( shapes ) ? shapes : [ shapes ]; 30651 30652 var scope = this; 30653 30654 var verticesArray = []; 30655 var uvArray = []; 30656 30657 for ( var i = 0, l = shapes.length; i < l; i ++ ) { 30658 30659 var shape = shapes[ i ]; 30660 addShape( shape ); 30661 30662 } 30663 30664 // build geometry 30665 30666 this.setAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) ); 30667 this.setAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) ); 30668 30669 this.computeVertexNormals(); 30670 30671 // functions 30672 30673 function addShape( shape ) { 30674 30675 var placeholder = []; 30676 30677 // options 30678 30679 var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; 30680 var steps = options.steps !== undefined ? options.steps : 1; 30681 var depth = options.depth !== undefined ? options.depth : 100; 30682 30683 var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; 30684 var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; 30685 var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; 30686 var bevelOffset = options.bevelOffset !== undefined ? options.bevelOffset : 0; 30687 var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3; 30688 30689 var extrudePath = options.extrudePath; 30690 30691 var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator; 30692 30693 // deprecated options 30694 30695 if ( options.amount !== undefined ) { 30696 30697 console.warn( 'THREE.ExtrudeBufferGeometry: amount has been renamed to depth.' ); 30698 depth = options.amount; 30699 30700 } 30701 30702 // 30703 30704 var extrudePts, extrudeByPath = false;
30705 var splineTube, binormal, normal, position2; 30706 30707 if ( extrudePath ) { 30708 30709 extrudePts = extrudePath.getSpacedPoints( steps ); 30710 30711 extrudeByPath = true; 30712 bevelEnabled = false; // bevels not supported for path extrusion 30713 30714 // SETUP TNB variables 30715 30716 // TODO1 - have a .isClosed in spline? 30717 30718 splineTube = extrudePath.computeFrenetFrames( steps, false ); 30719 30720 // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length); 30721 30722 binormal = new Vector3(); 30723 normal = new Vector3(); 30724 position2 = new Vector3(); 30725 30726 } 30727 30728 // Safeguards if bevels are not enabled 30729 30730 if ( ! bevelEnabled ) { 30731 30732 bevelSegments = 0; 30733 bevelThickness = 0; 30734 bevelSize = 0; 30735 bevelOffset = 0; 30736 30737 } 30738 30739 // Variables initialization 30740 30741 var ahole, h, hl; // looping of holes 30742 30743 var shapePoints = shape.extractPoints( curveSegments ); 30744 30745 var vertices = shapePoints.shape; 30746 var holes = shapePoints.holes; 30747 30748 var reverse = ! ShapeUtils.isClockWise( vertices ); 30749 30750 if ( reverse ) { 30751 30752 vertices = vertices.reverse(); 30753 30754 // Maybe we should also check if holes are in the opposite direction, just to be safe ... 30755 30756 for ( h = 0, hl = holes.length; h < hl; h ++ ) { 30757 30758 ahole = holes[ h ]; 30759 30760 if ( ShapeUtils.isClockWise( ahole ) ) { 30761 30762 holes[ h ] = ahole.reverse(); 30763 30764 } 30765 30766 } 30767 30768 } 30769 30770 30771 var faces = ShapeUtils.triangulateShape( vertices, holes ); 30772 30773 /* Vertices */ 30774 30775 var contour = vertices; // vertices has all points but contour has only points of circumference 30776 30777 for ( h = 0, hl = holes.length; h < hl; h ++ ) { 30778 30779 ahole = holes[ h ]; 30780 30781 vertices = vertices.concat( ahole ); 30782 30783 } 30784 30785 30786 function scalePt2( pt, vec, size ) { 30787 30788 if ( ! vec ) console.error( "THREE.ExtrudeGeometry: vec does not exist" ); 30789 30790 return vec.clone().multiplyScalar( size ).add( pt ); 30791 30792 } 30793 30794 var b, bs, t, z, 30795 vert, vlen = vertices.length, 30796 face, flen = faces.length; 30797 30798 30799 // Find directions for point movement 30800 30801 30802 function getBevelVec( inPt, inPrev, inNext ) { 30803 30804 // computes for inPt the corresponding point inPt' on a new contour 30805 // shifted by 1 unit (length of normalized vector) to the left 30806 // if we walk along contour clockwise, this new contour is outside the old one 30807 // 30808 // inPt' is the intersection of the two lines parallel to the two 30809 // adjacent edges of inPt at a distance of 1 unit on the left side. 30810 30811 var v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt 30812 30813 // good reading for geometry algorithms (here: line-line intersection) 30814 // http://geomalgorithms.com/a05-_intersect-1.html 30815 30816 var v_prev_x = inPt.x - inPrev.x, 30817 v_prev_y = inPt.y - inPrev.y; 30818 var v_next_x = inNext.x - inPt.x, 30819 v_next_y = inNext.y - inPt.y; 30820 30821 var v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y ); 30822
30823 // check for collinear edges 30824 var collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x ); 30825 30826 if ( Math.abs( collinear0 ) > Number.EPSILON ) { 30827 30828 // not collinear 30829 30830 // length of vectors for normalizing 30831 30832 var v_prev_len = Math.sqrt( v_prev_lensq ); 30833 var v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y ); 30834 30835 // shift adjacent points by unit vectors to the left 30836 30837 var ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len ); 30838 var ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len ); 30839 30840 var ptNextShift_x = ( inNext.x - v_next_y / v_next_len ); 30841 var ptNextShift_y = ( inNext.y + v_next_x / v_next_len ); 30842 30843 // scaling factor for v_prev to intersection point 30844 30845 var sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y - 30846 ( ptNextShift_y - ptPrevShift_y ) * v_next_x ) / 30847 ( v_prev_x * v_next_y - v_prev_y * v_next_x ); 30848 30849 // vector from inPt to intersection point 30850 30851 v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x ); 30852 v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y ); 30853 30854 // Don't normalize!, otherwise sharp corners become ugly 30855 // but prevent crazy spikes 30856 var v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y ); 30857 if ( v_trans_lensq <= 2 ) { 30858 30859 return new Vector2( v_trans_x, v_trans_y ); 30860 30861 } else { 30862 30863 shrink_by = Math.sqrt( v_trans_lensq / 2 ); 30864 30865 } 30866 30867 } else { 30868 30869 // handle special case of collinear edges 30870 30871 var direction_eq = false; // assumes: opposite 30872 if ( v_prev_x > Number.EPSILON ) { 30873 30874 if ( v_next_x > Number.EPSILON ) { 30875 30876 direction_eq = true; 30877 30878 } 30879 30880 } else { 30881 30882 if ( v_prev_x < - Number.EPSILON ) { 30883 30884 if ( v_next_x < - Number.EPSILON ) { 30885 30886 direction_eq = true; 30887 30888 } 30889 30890 } else { 30891 30892 if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) { 30893 30894 direction_eq = true; 30895 30896 } 30897 30898 } 30899 30900 } 30901 30902 if ( direction_eq ) { 30903 30904 // console.log("Warning: lines are a straight sequence"); 30905 v_trans_x = - v_prev_y; 30906 v_trans_y = v_prev_x; 30907 shrink_by = Math.sqrt( v_prev_lensq ); 30908 30909 } else { 30910 30911 // console.log("Warning: lines are a straight spike"); 30912 v_trans_x = v_prev_x; 30913 v_trans_y = v_prev_y; 30914 shrink_by = Math.sqrt( v_prev_lensq / 2 ); 30915 30916 } 30917 30918 } 30919 30920 return new Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by ); 30921 30922 } 30923 30924 30925 var contourMovements = []; 30926 30927 for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) { 30928 30929 if ( j === il ) j = 0; 30930 if ( k === il ) k = 0; 30931 30932 // (j)---(i)---(k) 30933 // console.log('i,j,k', i, j , k) 30934 30935 contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] ); 30936 30937 } 30938 30939 var holesMovements = [], 30940 oneHoleMovements, verticesMovements = contourMovements.concat(); 30941 30942 for ( h = 0, hl = holes.length; h < hl; h ++ ) { 30943 30944 ahole = holes[ h ]; 30945 30946 oneHoleMovements = []; 30947 30948 for ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) { 30949 30950 if ( j === il ) j = 0; 30951 if ( k === il ) k = 0; 30952 30953 // (j)---(i)---(k) 30954 oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] ); 30955 30956 } 30957 30958 holesMovements.push( oneHoleMovements ); 30959 verticesMovements = verticesMovements.concat( oneHoleMovements ); 30960 30961 } 30962 30963 30964 // Loop bevelSegments, 1 for the front, 1 for the back 30965 30966 for ( b = 0; b < bevelSegments; b ++ ) { 30967 30968 //for ( b = bevelSegments; b > 0; b -- ) { 30969 30970 t = b / bevelSegments; 30971 z = bevelThickness * Math.cos( t * Math.PI / 2 ); 30972 bs = bevelSize * Math.sin( t * Math.PI / 2 ) + bevelOffset; 30973 30974 // contract shape 30975 30976 for ( i = 0, il = contour.length; i < il; i ++ ) { 30977 30978 vert = scalePt2( contour[ i ], contourMovements[ i ], bs ); 30979 30980 v( vert.x, vert.y, - z ); 30981 30982 } 30983 30984 // expand holes 30985 30986 for ( h = 0, hl = holes.length; h < hl; h ++ ) { 30987 30988 ahole = holes[ h ]; 30989 oneHoleMovements = holesMovements[ h ]; 30990 30991 for ( i = 0, il = ahole.length; i < il; i ++ ) { 30992 30993 vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs ); 30994 30995 v( vert.x, vert.y, - z ); 30996 30997 } 30998 30999 } 31000 31001 } 31002 31003 bs = bevelSize + bevelOffset; 31004 31005 // Back facing vertices 31006 31007 for ( i = 0; i < vlen; i ++ ) { 31008 31009 vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ]; 31010 31011 if ( ! extrudeByPath ) { 31012 31013 v( vert.x, vert.y, 0 ); 31014 31015 } else { 31016 31017 // v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x ); 31018 31019 normal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x ); 31020 binormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y ); 31021 31022 position2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal ); 31023 31024 v( position2.x, position2.y, position2.z ); 31025 31026 } 31027 31028 } 31029 31030 // Add stepped vertices... 31031 // Including front facing vertices 31032 31033 var s; 31034 31035 for ( s = 1; s <= steps; s ++ ) { 31036 31037 for ( i = 0; i < vlen; i ++ ) { 31038 31039 vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ]; 31040 31041 if ( ! extrudeByPath ) { 31042 31043 v( vert.x, vert.y, depth / steps * s ); 31044 31045 } else { 31046 31047 // v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x ); 31048 31049 normal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x ); 31050 binormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y ); 31051 31052 position2.copy( extrudePts[ s ] ).add( normal ).add( binormal ); 31053 31054 v( position2.x, position2.y, position2.z ); 31055 31056 } 31057 31058 } 31059 31060 } 31061 31062
31063 // Add bevel segments planes 31064 31065 //for ( b = 1; b <= bevelSegments; b ++ ) { 31066 for ( b = bevelSegments - 1; b >= 0; b -- ) { 31067 31068 t = b / bevelSegments; 31069 z = bevelThickness * Math.cos( t * Math.PI / 2 ); 31070 bs = bevelSize * Math.sin( t * Math.PI / 2 ) + bevelOffset; 31071 31072 // contract shape 31073 31074 for ( i = 0, il = contour.length; i < il; i ++ ) { 31075 31076 vert = scalePt2( contour[ i ], contourMovements[ i ], bs ); 31077 v( vert.x, vert.y, depth + z ); 31078 31079 } 31080 31081 // expand holes 31082 31083 for ( h = 0, hl = holes.length; h < hl; h ++ ) { 31084 31085 ahole = holes[ h ]; 31086 oneHoleMovements = holesMovements[ h ]; 31087 31088 for ( i = 0, il = ahole.length; i < il; i ++ ) { 31089 31090 vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs ); 31091 31092 if ( ! extrudeByPath ) { 31093 31094 v( vert.x, vert.y, depth + z ); 31095 31096 } else { 31097 31098 v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z ); 31099 31100 } 31101 31102 } 31103 31104 } 31105 31106 } 31107 31108 /* Faces */ 31109 31110 // Top and bottom faces 31111 31112 buildLidFaces(); 31113 31114 // Sides faces 31115 31116 buildSideFaces(); 31117 31118 31119 ///// Internal functions 31120 31121 function buildLidFaces() { 31122 31123 var start = verticesArray.length / 3; 31124 31125 if ( bevelEnabled ) { 31126 31127 var layer = 0; // steps + 1 31128 var offset = vlen * layer; 31129 31130 // Bottom faces 31131 31132 for ( i = 0; i < flen; i ++ ) { 31133 31134 face = faces[ i ]; 31135 f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset ); 31136 31137 } 31138 31139 layer = steps + bevelSegments * 2; 31140 offset = vlen * layer; 31141 31142 // Top faces 31143 31144 for ( i = 0; i < flen; i ++ ) { 31145 31146 face = faces[ i ]; 31147 f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset ); 31148 31149 } 31150 31151 } else { 31152 31153 // Bottom faces 31154 31155 for ( i = 0; i < flen; i ++ ) { 31156 31157 face = faces[ i ]; 31158 f3( face[ 2 ], face[ 1 ], face[ 0 ] ); 31159 31160 } 31161 31162 // Top faces 31163 31164 for ( i = 0; i < flen; i ++ ) { 31165 31166 face = faces[ i ]; 31167 f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps ); 31168 31169 } 31170 31171 } 31172 31173 scope.addGroup( start, verticesArray.length / 3 - start, 0 ); 31174 31175 } 31176 31177 // Create faces for the z-sides of the shape 31178 31179 function buildSideFaces() { 31180 31181 var start = verticesArray.length / 3; 31182 var layeroffset = 0; 31183 sidewalls( contour, layeroffset ); 31184 layeroffset += contour.length; 31185 31186 for ( h = 0, hl = holes.length; h < hl; h ++ ) { 31187 31188 ahole = holes[ h ]; 31189 sidewalls( ahole, layeroffset ); 31190 31191 //, true 31192 layeroffset += ahole.length; 31193 31194 } 31195 31196 31197 scope.addGroup( start, verticesArray.length / 3 - start, 1 ); 31198 31199 31200 } 31201 31202 function sidewalls( contour, layeroffset ) { 31203 31204 var j, k; 31205 i = contour.length; 31206 31207 while ( -- i >= 0 ) { 31208 31209 j = i; 31210 k = i - 1; 31211 if ( k < 0 ) k = contour.length - 1; 31212 31213 //console.log('b', i,j, i-1, k,vertices.length); 31214 31215 var s = 0, 31216 sl = steps + bevelSegments * 2; 31217 31218 for ( s = 0; s < sl; s ++ ) { 31219 31220 var slen1 = vlen * s; 31221 var slen2 = vlen * ( s + 1 ); 31222 31223 var a = layeroffset + j + slen1, 31224 b = layeroffset + k + slen1, 31225 c = layeroffset + k + slen2, 31226 d = layeroffset + j + slen2; 31227 31228 f4( a, b, c, d ); 31229 31230 } 31231 31232 } 31233 31234 } 31235 31236 function v( x, y, z ) { 31237 31238 placeholder.push( x ); 31239 placeholder.push( y ); 31240 placeholder.push( z ); 31241 31242 } 31243 31244 31245 function f3( a, b, c ) { 31246 31247 addVertex( a ); 31248 addVertex( b ); 31249 addVertex( c ); 31250 31251 var nextIndex = verticesArray.length / 3; 31252 var uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 ); 31253 31254 addUV( uvs[ 0 ] ); 31255 addUV( uvs[ 1 ] ); 31256 addUV( uvs[ 2 ] ); 31257 31258 } 31259 31260 function f4( a, b, c, d ) { 31261 31262 addVertex( a ); 31263 addVertex( b ); 31264 addVertex( d ); 31265 31266 addVertex( b ); 31267 addVertex( c ); 31268 addVertex( d ); 31269 31270 31271 var nextIndex = verticesArray.length / 3; 31272 var uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 ); 31273 31274 addUV( uvs[ 0 ] ); 31275 addUV( uvs[ 1 ] ); 31276 addUV( uvs[ 3 ] ); 31277 31278 addUV( uvs[ 1 ] ); 31279 addUV( uvs[ 2 ] ); 31280 addUV( uvs[ 3 ] ); 31281 31282 } 31283 31284 function addVertex( index ) { 31285 31286 verticesArray.push( placeholder[ index * 3 + 0 ] ); 31287 verticesArray.push( placeholder[ index * 3 + 1 ] ); 31288 verticesArray.push( placeholder[ index * 3 + 2 ] ); 31289 31290 } 31291 31292 31293 function addUV( vector2 ) { 31294 31295 uvArray.push( vector2.x ); 31296 uvArray.push( vector2.y ); 31297 31298 } 31299 31300 } 31301 31302} 31303 31304ExtrudeBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 31305ExtrudeBufferGeometry.prototype.constructor = ExtrudeBufferGeometry; 31306 31307ExtrudeBufferGeometry.prototype.toJSON = function () { 31308 31309 var data = BufferGeometry.prototype.toJSON.call( this ); 31310 31311 var shapes = this.parameters.shapes; 31312 var options = this.parameters.options; 31313 31314 return toJSON( shapes, options, data ); 31315 31316}; 31317 31318// 31319 31320var WorldUVGenerator = { 31321 31322 generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) { 31323 31324 var a_x = vertices[ indexA * 3 ]; 31325 var a_y = vertices[ indexA * 3 + 1 ]; 31326 var b_x = vertices[ indexB * 3 ]; 31327 var b_y = vertices[ indexB * 3 + 1 ]; 31328 var c_x = vertices[ indexC * 3 ]; 31329 var c_y = vertices[ indexC * 3 + 1 ]; 31330 31331 return [ 31332 new Vector2( a_x, a_y ), 31333 new Vector2( b_x, b_y ), 31334 new Vector2( c_x, c_y ) 31335 ]; 31336 31337 }, 31338 31339 generateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) { 31340 31341 var a_x = vertices[ indexA * 3 ]; 31342 var a_y = vertices[ indexA * 3 + 1 ]; 31343 var a_z = vertices[ indexA * 3 + 2 ]; 31344 var b_x = vertices[ indexB * 3 ]; 31345 var b_y = vertices[ indexB * 3 + 1 ]; 31346 var b_z = vertices[ indexB * 3 + 2 ]; 31347 var c_x = vertices[ indexC * 3 ]; 31348 var c_y = vertices[ indexC * 3 + 1 ]; 31349 var c_z = vertices[ indexC * 3 + 2 ]; 31350 var d_x = vertices[ indexD * 3 ]; 31351 var d_y = vertices[ indexD * 3 + 1 ]; 31352 var d_z = vertices[ indexD * 3 + 2 ]; 31353 31354 if ( Math.abs( a_y - b_y ) < 0.01 ) { 31355 31356 return [ 31357 new Vector2( a_x, 1 - a_z ), 31358 new Vector2( b_x, 1 - b_z ), 31359 new Vector2( c_x, 1 - c_z ), 31360 new Vector2( d_x, 1 - d_z ) 31361 ]; 31362 31363 } else { 31364 31365 return [ 31366 new Vector2( a_y, 1 - a_z ), 31367 new Vector2( b_y, 1 - b_z ), 31368 new Vector2( c_y, 1 - c_z ), 31369 new Vector2( d_y, 1 - d_z ) 31370 ]; 31371 31372 } 31373 31374 } 31375}; 31376 31377function toJSON( shapes, options, data ) { 31378 31379 // 31380 31381 data.shapes = []; 31382 31383 if ( Array.isArray( shapes ) ) { 31384 31385 for ( var i = 0, l = shapes.length; i < l; i ++ ) { 31386 31387 var shape = shapes[ i ]; 31388 31389 data.shapes.push( shape.uuid ); 31390 31391 } 31392 31393 } else { 31394 31395 data.shapes.push( shapes.uuid ); 31396 31397 } 31398 31399 // 31400 31401 if ( options.extrudePath !== undefined ) data.options.extrudePath = options.extrudePath.toJSON(); 31402 31403 return data; 31404 31405} 31406 31407/** 31408 * @author zz85 / http://www.lab4games.net/zz85/blog 31409 * @author alteredq / http://alteredqualia.com/ 31410 * 31411 * Text = 3D Text 31412 * 31413 * parameters = { 31414 * font: <THREE.Font>, // font 31415 * 31416 * size: <float>, // size of the text 31417 * height: <float>, // thickness to extrude text 31418 * curveSegments: <int>, // number of points on the curves 31419 * 31420 * bevelEnabled: <bool>, // turn on bevel 31421 * bevelThickness: <float>, // how deep into text bevel goes 31422 * bevelSize: <float>, // how far from text outline (including bevelOffset) is bevel 31423 * bevelOffset: <float> // how far from text outline does bevel start 31424 * } 31425 */ 31426 31427// TextGeometry 31428 31429function TextGeometry( text, parameters ) { 31430 31431 Geometry.call( this ); 31432 31433 this.type = 'TextGeometry'; 31434 31435 this.parameters = { 31436 text: text, 31437 parameters: parameters 31438 }; 31439 31440 this.fromBufferGeometry( new TextBufferGeometry( text, parameters ) ); 31441 this.mergeVertices(); 31442 31443} 31444 31445TextGeometry.prototype = Object.create( Geometry.prototype ); 31446TextGeometry.prototype.constructor = TextGeometry; 31447 31448// TextBufferGeometry 31449 31450function TextBufferGeometry( text, parameters ) { 31451 31452 parameters = parameters || {}; 31453 31454 var font = parameters.font; 31455 31456 if ( ! ( font && font.isFont ) ) { 31457 31458 console.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' ); 31459 return new Geometry(); 31460 31461 } 31462 31463 var shapes = font.generateShapes( text, parameters.size ); 31464 31465 // translate parameters to ExtrudeGeometry API 31466 31467 parameters.depth = parameters.height !== undefined ? parameters.height : 50; 31468 31469 // defaults 31470 31471 if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10; 31472 if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8; 31473 if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;
31474 31475 ExtrudeBufferGeometry.call( this, shapes, parameters ); 31476 31477 this.type = 'TextBufferGeometry'; 31478 31479} 31480 31481TextBufferGeometry.prototype = Object.create( ExtrudeBufferGeometry.prototype ); 31482TextBufferGeometry.prototype.constructor = TextBufferGeometry; 31483 31484/** 31485 * @author mrdoob / http://mrdoob.com/ 31486 * @author benaadams / https://twitter.com/ben_a_adams 31487 * @author Mugen87 / https://github.com/Mugen87 31488 */ 31489 31490// SphereGeometry 31491 31492function SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) { 31493 31494 Geometry.call( this ); 31495 31496 this.type = 'SphereGeometry'; 31497 31498 this.parameters = { 31499 radius: radius, 31500 widthSegments: widthSegments, 31501 heightSegments: heightSegments, 31502 phiStart: phiStart, 31503 phiLength: phiLength, 31504 thetaStart: thetaStart, 31505 thetaLength: thetaLength 31506 }; 31507 31508 this.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) ); 31509 this.mergeVertices(); 31510 31511} 31512 31513SphereGeometry.prototype = Object.create( Geometry.prototype ); 31514SphereGeometry.prototype.constructor = SphereGeometry; 31515 31516// SphereBufferGeometry 31517 31518function SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) { 31519 31520 BufferGeometry.call( this ); 31521 31522 this.type = 'SphereBufferGeometry'; 31523 31524 this.parameters = { 31525 radius: radius, 31526 widthSegments: widthSegments, 31527 heightSegments: heightSegments, 31528 phiStart: phiStart, 31529 phiLength: phiLength, 31530 thetaStart: thetaStart, 31531 thetaLength: thetaLength 31532 }; 31533 31534 radius = radius || 1; 31535 31536 widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 ); 31537 heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 ); 31538 31539 phiStart = phiStart !== undefined ? phiStart : 0; 31540 phiLength = phiLength !== undefined ? phiLength : Math.PI * 2; 31541 31542 thetaStart = thetaStart !== undefined ? thetaStart : 0; 31543 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI; 31544 31545 var thetaEnd = Math.min( thetaStart + thetaLength, Math.PI ); 31546 31547 var ix, iy; 31548 31549 var index = 0; 31550 var grid = []; 31551 31552 var vertex = new Vector3(); 31553 var normal = new Vector3(); 31554 31555 // buffers 31556 31557 var indices = []; 31558 var vertices = []; 31559 var normals = []; 31560 var uvs = []; 31561 31562 // generate vertices, normals and uvs 31563 31564 for ( iy = 0; iy <= heightSegments; iy ++ ) { 31565 31566 var verticesRow = []; 31567 31568 var v = iy / heightSegments; 31569 31570 // special case for the poles 31571 31572 var uOffset = 0; 31573 31574 if ( iy == 0 && thetaStart == 0 ) { 31575 31576 uOffset = 0.5 / widthSegments; 31577 31578 } else if ( iy == heightSegments && thetaEnd == Math.PI ) { 31579 31580 uOffset = - 0.5 / widthSegments; 31581 31582 } 31583 31584 for ( ix = 0; ix <= widthSegments; ix ++ ) { 31585 31586 var u = ix / widthSegments; 31587 31588 // vertex 31589 31590 vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ); 31591 vertex.y = radius * Math.cos( thetaStart + v * thetaLength ); 31592 vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ); 31593 31594 vertices.push( vertex.x, vertex.y, vertex.z ); 31595 31596 // normal 31597 31598 normal.copy( vertex ).normalize(); 31599 normals.push( normal.x, normal.y, normal.z ); 31600 31601 // uv 31602 31603 uvs.push( u + uOffset, 1 - v ); 31604 31605 verticesRow.push( index ++ ); 31606 31607 } 31608 31609 grid.push( verticesRow ); 31610 31611 } 31612 31613 // indices 31614 31615 for ( iy = 0; iy < heightSegments; iy ++ ) { 31616 31617 for ( ix = 0; ix < widthSegments; ix ++ ) { 31618 31619 var a = grid[ iy ][ ix + 1 ]; 31620 var b = grid[ iy ][ ix ]; 31621 var c = grid[ iy + 1 ][ ix ]; 31622 var d = grid[ iy + 1 ][ ix + 1 ]; 31623 31624 if ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d ); 31625 if ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d ); 31626 31627 } 31628 31629 } 31630 31631 // build geometry 31632 31633 this.setIndex( indices ); 31634 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 31635 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 31636 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 31637 31638} 31639 31640SphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 31641SphereBufferGeometry.prototype.constructor = SphereBufferGeometry; 31642 31643/** 31644 * @author Kaleb Murphy 31645 * @author Mugen87 / https://github.com/Mugen87 31646 */ 31647 31648// RingGeometry 31649 31650function RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) { 31651 31652 Geometry.call( this ); 31653 31654 this.type = 'RingGeometry'; 31655 31656 this.parameters = { 31657 innerRadius: innerRadius, 31658 outerRadius: outerRadius, 31659 thetaSegments: thetaSegments, 31660 phiSegments: phiSegments, 31661 thetaStart: thetaStart, 31662 thetaLength: thetaLength 31663 }; 31664 31665 this.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) ); 31666 this.mergeVertices(); 31667 31668} 31669 31670RingGeometry.prototype = Object.create( Geometry.prototype ); 31671RingGeometry.prototype.constructor = RingGeometry; 31672 31673// RingBufferGeometry 31674 31675function RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) { 31676 31677 BufferGeometry.call( this ); 31678 31679 this.type = 'RingBufferGeometry'; 31680 31681 this.parameters = { 31682 innerRadius: innerRadius, 31683 outerRadius: outerRadius, 31684 thetaSegments: thetaSegments, 31685 phiSegments: phiSegments, 31686 thetaStart: thetaStart, 31687 thetaLength: thetaLength 31688 }; 31689 31690 innerRadius = innerRadius || 0.5; 31691 outerRadius = outerRadius || 1; 31692 31693 thetaStart = thetaStart !== undefined ? thetaStart : 0; 31694 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; 31695 31696 thetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8; 31697 phiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1; 31698 31699 // buffers 31700 31701 var indices = []; 31702 var vertices = []; 31703 var normals = []; 31704 var uvs = []; 31705
31706 // some helper variables 31707 31708 var segment; 31709 var radius = innerRadius; 31710 var radiusStep = ( ( outerRadius - innerRadius ) / phiSegments ); 31711 var vertex = new Vector3(); 31712 var uv = new Vector2(); 31713 var j, i; 31714 31715 // generate vertices, normals and uvs 31716 31717 for ( j = 0; j <= phiSegments; j ++ ) { 31718 31719 for ( i = 0; i <= thetaSegments; i ++ ) { 31720 31721 // values are generate from the inside of the ring to the outside 31722 31723 segment = thetaStart + i / thetaSegments * thetaLength; 31724 31725 // vertex 31726 31727 vertex.x = radius * Math.cos( segment ); 31728 vertex.y = radius * Math.sin( segment ); 31729 31730 vertices.push( vertex.x, vertex.y, vertex.z ); 31731 31732 // normal 31733 31734 normals.push( 0, 0, 1 ); 31735 31736 // uv 31737 31738 uv.x = ( vertex.x / outerRadius + 1 ) / 2; 31739 uv.y = ( vertex.y / outerRadius + 1 ) / 2; 31740 31741 uvs.push( uv.x, uv.y ); 31742 31743 } 31744 31745 // increase the radius for next row of vertices 31746 31747 radius += radiusStep; 31748 31749 } 31750 31751 // indices 31752 31753 for ( j = 0; j < phiSegments; j ++ ) { 31754 31755 var thetaSegmentLevel = j * ( thetaSegments + 1 ); 31756 31757 for ( i = 0; i < thetaSegments; i ++ ) { 31758 31759 segment = i + thetaSegmentLevel; 31760 31761 var a = segment; 31762 var b = segment + thetaSegments + 1; 31763 var c = segment + thetaSegments + 2; 31764 var d = segment + 1; 31765 31766 // faces 31767 31768 indices.push( a, b, d ); 31769 indices.push( b, c, d ); 31770 31771 } 31772 31773 } 31774 31775 // build geometry 31776 31777 this.setIndex( indices ); 31778 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 31779 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 31780 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 31781 31782} 31783 31784RingBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 31785RingBufferGeometry.prototype.constructor = RingBufferGeometry; 31786 31787/** 31788 * @author zz85 / https://github.com/zz85 31789 * @author bhouston / http://clara.io 31790 * @author Mugen87 / https://github.com/Mugen87 31791 */ 31792 31793// LatheGeometry 31794 31795function LatheGeometry( points, segments, phiStart, phiLength ) { 31796 31797 Geometry.call( this ); 31798 31799 this.type = 'LatheGeometry'; 31800 31801 this.parameters = { 31802 points: points, 31803 segments: segments, 31804 phiStart: phiStart, 31805 phiLength: phiLength 31806 }; 31807 31808 this.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) ); 31809 this.mergeVertices(); 31810 31811} 31812 31813LatheGeometry.prototype = Object.create( Geometry.prototype ); 31814LatheGeometry.prototype.constructor = LatheGeometry; 31815 31816// LatheBufferGeometry 31817 31818function LatheBufferGeometry( points, segments, phiStart, phiLength ) { 31819 31820 BufferGeometry.call( this ); 31821 31822 this.type = 'LatheBufferGeometry'; 31823 31824 this.parameters = { 31825 points: points, 31826 segments: segments, 31827 phiStart: phiStart, 31828 phiLength: phiLength 31829 }; 31830 31831 segments = Math.floor( segments ) || 12; 31832 phiStart = phiStart || 0; 31833 phiLength = phiLength || Math.PI * 2; 31834 31835 // clamp phiLength so it's in range of [ 0, 2PI ] 31836 31837 phiLength = MathUtils.clamp( phiLength, 0, Math.PI * 2 ); 31838 31839 31840 // buffers 31841 31842 var indices = []; 31843 var vertices = []; 31844 var uvs = []; 31845 31846 // helper variables 31847 31848 var base; 31849 var inverseSegments = 1.0 / segments; 31850 var vertex = new Vector3(); 31851 var uv = new Vector2(); 31852 var i, j; 31853 31854 // generate vertices and uvs 31855 31856 for ( i = 0; i <= segments; i ++ ) { 31857 31858 var phi = phiStart + i * inverseSegments * phiLength; 31859 31860 var sin = Math.sin( phi ); 31861 var cos = Math.cos( phi ); 31862 31863 for ( j = 0; j <= ( points.length - 1 ); j ++ ) { 31864 31865 // vertex 31866 31867 vertex.x = points[ j ].x * sin; 31868 vertex.y = points[ j ].y; 31869 vertex.z = points[ j ].x * cos; 31870 31871 vertices.push( vertex.x, vertex.y, vertex.z ); 31872 31873 // uv 31874 31875 uv.x = i / segments; 31876 uv.y = j / ( points.length - 1 ); 31877 31878 uvs.push( uv.x, uv.y ); 31879 31880 31881 } 31882 31883 } 31884 31885 // indices 31886 31887 for ( i = 0; i < segments; i ++ ) { 31888 31889 for ( j = 0; j < ( points.length - 1 ); j ++ ) { 31890 31891 base = j + i * points.length; 31892 31893 var a = base; 31894 var b = base + points.length; 31895 var c = base + points.length + 1; 31896 var d = base + 1; 31897 31898 // faces 31899 31900 indices.push( a, b, d ); 31901 indices.push( b, c, d ); 31902 31903 } 31904 31905 } 31906 31907 // build geometry 31908 31909 this.setIndex( indices ); 31910 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 31911 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 31912 31913 // generate normals 31914 31915 this.computeVertexNormals(); 31916 31917 // if the geometry is closed, we need to average the normals along the seam. 31918 // because the corresponding vertices are identical (but still have different UVs). 31919 31920 if ( phiLength === Math.PI * 2 ) { 31921 31922 var normals = this.attributes.normal.array; 31923 var n1 = new Vector3(); 31924 var n2 = new Vector3(); 31925 var n = new Vector3(); 31926 31927 // this is the buffer offset for the last line of vertices 31928 31929 base = segments * points.length * 3; 31930 31931 for ( i = 0, j = 0; i < points.length; i ++, j += 3 ) { 31932 31933 // select the normal of the vertex in the first line 31934 31935 n1.x = normals[ j + 0 ]; 31936 n1.y = normals[ j + 1 ]; 31937 n1.z = normals[ j + 2 ]; 31938 31939 // select the normal of the vertex in the last line 31940 31941 n2.x = normals[ base + j + 0 ]; 31942 n2.y = normals[ base + j + 1 ]; 31943 n2.z = normals[ base + j + 2 ]; 31944 31945 // average normals 31946 31947 n.addVectors( n1, n2 ).normalize(); 31948 31949 // assign the new values to both normals 31950 31951 normals[ j + 0 ] = normals[ base + j + 0 ] = n.x; 31952 normals[ j + 1 ] = normals[ base + j + 1 ] = n.y; 31953 normals[ j + 2 ] = normals[ base + j + 2 ] = n.z; 31954 31955 } 31956 31957 } 31958 31959} 31960 31961LatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 31962LatheBufferGeometry.prototype.constructor = LatheBufferGeometry; 31963 31964/** 31965 * @author jonobr1 / http://jonobr1.com 31966 * @author Mugen87 / https://github.com/Mugen87 31967 */ 31968 31969// ShapeGeometry 31970 31971function ShapeGeometry( shapes, curveSegments ) { 31972 31973 Geometry.call( this ); 31974 31975 this.type = 'ShapeGeometry'; 31976 31977 if ( typeof curveSegments === 'object' ) { 31978 31979 console.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' ); 31980 31981 curveSegments = curveSegments.curveSegments; 31982 31983 } 31984 31985 this.parameters = { 31986 shapes: shapes, 31987 curveSegments: curveSegments 31988 }; 31989 31990 this.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) ); 31991 this.mergeVertices(); 31992 31993} 31994 31995ShapeGeometry.prototype = Object.create( Geometry.prototype ); 31996ShapeGeometry.prototype.constructor = ShapeGeometry; 31997 31998ShapeGeometry.prototype.toJSON = function () { 31999 32000 var data = Geometry.prototype.toJSON.call( this ); 32001 32002 var shapes = this.parameters.shapes; 32003 32004 return toJSON$1( shapes, data ); 32005 32006}; 32007 32008// ShapeBufferGeometry 32009 32010function ShapeBufferGeometry( shapes, curveSegments ) { 32011 32012 BufferGeometry.call( this ); 32013 32014 this.type = 'ShapeBufferGeometry'; 32015 32016 this.parameters = { 32017 shapes: shapes, 32018 curveSegments: curveSegments 32019 }; 32020 32021 curveSegments = curveSegments || 12; 32022 32023 // buffers 32024 32025 var indices = []; 32026 var vertices = []; 32027 var normals = []; 32028 var uvs = []; 32029 32030 // helper variables 32031 32032 var groupStart = 0; 32033 var groupCount = 0; 32034 32035 // allow single and array values for "shapes" parameter 32036 32037 if ( Array.isArray( shapes ) === false ) { 32038 32039 addShape( shapes ); 32040 32041 } else { 32042 32043 for ( var i = 0; i < shapes.length; i ++ ) { 32044 32045 addShape( shapes[ i ] ); 32046 32047 this.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support 32048 32049 groupStart += groupCount; 32050 groupCount = 0; 32051 32052 } 32053 32054 } 32055 32056 // build geometry 32057 32058 this.setIndex( indices ); 32059 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
32060 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 32061 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 32062 32063 32064 // helper functions 32065 32066 function addShape( shape ) { 32067 32068 var i, l, shapeHole; 32069 32070 var indexOffset = vertices.length / 3; 32071 var points = shape.extractPoints( curveSegments ); 32072 32073 var shapeVertices = points.shape; 32074 var shapeHoles = points.holes; 32075 32076 // check direction of vertices 32077 32078 if ( ShapeUtils.isClockWise( shapeVertices ) === false ) { 32079 32080 shapeVertices = shapeVertices.reverse(); 32081 32082 } 32083 32084 for ( i = 0, l = shapeHoles.length; i < l; i ++ ) { 32085 32086 shapeHole = shapeHoles[ i ]; 32087 32088 if ( ShapeUtils.isClockWise( shapeHole ) === true ) { 32089 32090 shapeHoles[ i ] = shapeHole.reverse(); 32091 32092 } 32093 32094 } 32095 32096 var faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles ); 32097 32098 // join vertices of inner and outer paths to a single array 32099 32100 for ( i = 0, l = shapeHoles.length; i < l; i ++ ) { 32101 32102 shapeHole = shapeHoles[ i ]; 32103 shapeVertices = shapeVertices.concat( shapeHole ); 32104 32105 } 32106 32107 // vertices, normals, uvs 32108 32109 for ( i = 0, l = shapeVertices.length; i < l; i ++ ) { 32110 32111 var vertex = shapeVertices[ i ]; 32112 32113 vertices.push( vertex.x, vertex.y, 0 ); 32114 normals.push( 0, 0, 1 ); 32115 uvs.push( vertex.x, vertex.y ); // world uvs 32116 32117 } 32118 32119 // incides 32120 32121 for ( i = 0, l = faces.length; i < l; i ++ ) { 32122 32123 var face = faces[ i ]; 32124 32125 var a = face[ 0 ] + indexOffset; 32126 var b = face[ 1 ] + indexOffset; 32127 var c = face[ 2 ] + indexOffset; 32128 32129 indices.push( a, b, c ); 32130 groupCount += 3; 32131 32132 } 32133 32134 } 32135 32136} 32137 32138ShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 32139ShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry; 32140 32141ShapeBufferGeometry.prototype.toJSON = function () { 32142 32143 var data = BufferGeometry.prototype.toJSON.call( this ); 32144 32145 var shapes = this.parameters.shapes; 32146 32147 return toJSON$1( shapes, data ); 32148 32149}; 32150 32151// 32152 32153function toJSON$1( shapes, data ) { 32154 32155 data.shapes = []; 32156 32157 if ( Array.isArray( shapes ) ) { 32158 32159 for ( var i = 0, l = shapes.length; i < l; i ++ ) { 32160 32161 var shape = shapes[ i ]; 32162 32163 data.shapes.push( shape.uuid ); 32164 32165 } 32166 32167 } else { 32168 32169 data.shapes.push( shapes.uuid ); 32170 32171 } 32172 32173 return data; 32174 32175} 32176 32177/** 32178 * @author WestLangley / http://github.com/WestLangley 32179 * @author Mugen87 / https://github.com/Mugen87 32180 */ 32181 32182function EdgesGeometry( geometry, thresholdAngle ) { 32183 32184 BufferGeometry.call( this ); 32185 32186 this.type = 'EdgesGeometry'; 32187 32188 this.parameters = { 32189 thresholdAngle: thresholdAngle 32190 }; 32191 32192 thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1; 32193 32194 // buffer 32195 32196 var vertices = []; 32197 32198 // helper variables 32199 32200 var thresholdDot = Math.cos( MathUtils.DEG2RAD * thresholdAngle ); 32201 var edge = [ 0, 0 ], edges = {}, edge1, edge2;
32202 var key, keys = [ 'a', 'b', 'c' ]; 32203 32204 // prepare source geometry 32205 32206 var geometry2; 32207 32208 if ( geometry.isBufferGeometry ) { 32209 32210 geometry2 = new Geometry(); 32211 geometry2.fromBufferGeometry( geometry ); 32212 32213 } else { 32214 32215 geometry2 = geometry.clone(); 32216 32217 } 32218 32219 geometry2.mergeVertices(); 32220 geometry2.computeFaceNormals(); 32221 32222 var sourceVertices = geometry2.vertices; 32223 var faces = geometry2.faces; 32224 32225 // now create a data structure where each entry represents an edge with its adjoining faces 32226 32227 for ( var i = 0, l = faces.length; i < l; i ++ ) { 32228 32229 var face = faces[ i ]; 32230 32231 for ( var j = 0; j < 3; j ++ ) { 32232 32233 edge1 = face[ keys[ j ] ]; 32234 edge2 = face[ keys[ ( j + 1 ) % 3 ] ]; 32235 edge[ 0 ] = Math.min( edge1, edge2 ); 32236 edge[ 1 ] = Math.max( edge1, edge2 ); 32237 32238 key = edge[ 0 ] + ',' + edge[ 1 ]; 32239 32240 if ( edges[ key ] === undefined ) { 32241 32242 edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined }; 32243 32244 } else { 32245 32246 edges[ key ].face2 = i; 32247 32248 } 32249 32250 } 32251 32252 } 32253 32254 // generate vertices 32255 32256 for ( key in edges ) { 32257 32258 var e = edges[ key ]; 32259 32260 // an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree. 32261 32262 if ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) { 32263 32264 var vertex = sourceVertices[ e.index1 ]; 32265 vertices.push( vertex.x, vertex.y, vertex.z ); 32266 32267 vertex = sourceVertices[ e.index2 ]; 32268 vertices.push( vertex.x, vertex.y, vertex.z ); 32269 32270 } 32271 32272 } 32273 32274 // build geometry 32275 32276 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 32277 32278} 32279 32280EdgesGeometry.prototype = Object.create( BufferGeometry.prototype ); 32281EdgesGeometry.prototype.constructor = EdgesGeometry; 32282 32283/** 32284 * @author mrdoob / http://mrdoob.com/ 32285 * @author Mugen87 / https://github.com/Mugen87 32286 */ 32287 32288// CylinderGeometry 32289 32290function CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { 32291 32292 Geometry.call( this ); 32293 32294 this.type = 'CylinderGeometry'; 32295 32296 this.parameters = { 32297 radiusTop: radiusTop, 32298 radiusBottom: radiusBottom, 32299 height: height, 32300 radialSegments: radialSegments, 32301 heightSegments: heightSegments, 32302 openEnded: openEnded, 32303 thetaStart: thetaStart, 32304 thetaLength: thetaLength 32305 }; 32306 32307 this.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) ); 32308 this.mergeVertices(); 32309 32310} 32311 32312CylinderGeometry.prototype = Object.create( Geometry.prototype ); 32313CylinderGeometry.prototype.constructor = CylinderGeometry; 32314 32315// CylinderBufferGeometry 32316 32317function CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { 32318 32319 BufferGeometry.call( this ); 32320 32321 this.type = 'CylinderBufferGeometry'; 32322 32323 this.parameters = { 32324 radiusTop: radiusTop, 32325 radiusBottom: radiusBottom, 32326 height: height, 32327 radialSegments: radialSegments, 32328 heightSegments: heightSegments, 32329 openEnded: openEnded, 32330 thetaStart: thetaStart, 32331 thetaLength: thetaLength 32332 }; 32333 32334 var scope = this; 32335 32336 radiusTop = radiusTop !== undefined ? radiusTop : 1; 32337 radiusBottom = radiusBottom !== undefined ? radiusBottom : 1; 32338 height = height || 1; 32339 32340 radialSegments = Math.floor( radialSegments ) || 8; 32341 heightSegments = Math.floor( heightSegments ) || 1; 32342 32343 openEnded = openEnded !== undefined ? openEnded : false; 32344 thetaStart = thetaStart !== undefined ? thetaStart : 0.0; 32345 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; 32346 32347 // buffers 32348 32349 var indices = []; 32350 var vertices = []; 32351 var normals = []; 32352 var uvs = []; 32353 32354 // helper variables 32355 32356 var index = 0; 32357 var indexArray = []; 32358 var halfHeight = height / 2; 32359 var groupStart = 0; 32360 32361 // generate geometry 32362 32363 generateTorso(); 32364 32365 if ( openEnded === false ) { 32366 32367 if ( radiusTop > 0 ) generateCap( true ); 32368 if ( radiusBottom > 0 ) generateCap( false ); 32369 32370 } 32371 32372 // build geometry 32373 32374 this.setIndex( indices ); 32375 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 32376 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 32377 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 32378 32379 function generateTorso() { 32380 32381 var x, y; 32382 var normal = new Vector3(); 32383 var vertex = new Vector3(); 32384 32385 var groupCount = 0; 32386 32387 // this will be used to calculate the normal 32388 var slope = ( radiusBottom - radiusTop ) / height; 32389 32390 // generate vertices, normals and uvs 32391 32392 for ( y = 0; y <= heightSegments; y ++ ) { 32393 32394 var indexRow = []; 32395 32396 var v = y / heightSegments; 32397 32398 // calculate the radius of the current row 32399 32400 var radius = v * ( radiusBottom - radiusTop ) + radiusTop; 32401 32402 for ( x = 0; x <= radialSegments; x ++ ) { 32403 32404 var u = x / radialSegments; 32405 32406 var theta = u * thetaLength + thetaStart; 32407 32408 var sinTheta = Math.sin( theta ); 32409 var cosTheta = Math.cos( theta ); 32410 32411 // vertex 32412
32413 vertex.x = radius * sinTheta; 32414 vertex.y = - v * height + halfHeight; 32415 vertex.z = radius * cosTheta; 32416 vertices.push( vertex.x, vertex.y, vertex.z ); 32417 32418 // normal 32419 32420 normal.set( sinTheta, slope, cosTheta ).normalize(); 32421 normals.push( normal.x, normal.y, normal.z ); 32422 32423 // uv 32424 32425 uvs.push( u, 1 - v ); 32426 32427 // save index of vertex in respective row 32428 32429 indexRow.push( index ++ ); 32430 32431 } 32432 32433 // now save vertices of the row in our index array 32434 32435 indexArray.push( indexRow ); 32436 32437 } 32438 32439 // generate indices 32440 32441 for ( x = 0; x < radialSegments; x ++ ) { 32442 32443 for ( y = 0; y < heightSegments; y ++ ) { 32444 32445 // we use the index array to access the correct indices 32446 32447 var a = indexArray[ y ][ x ]; 32448 var b = indexArray[ y + 1 ][ x ]; 32449 var c = indexArray[ y + 1 ][ x + 1 ]; 32450 var d = indexArray[ y ][ x + 1 ]; 32451 32452 // faces 32453 32454 indices.push( a, b, d ); 32455 indices.push( b, c, d ); 32456 32457 // update group counter 32458 32459 groupCount += 6; 32460 32461 } 32462 32463 } 32464 32465 // add a group to the geometry. this will ensure multi material support 32466 32467 scope.addGroup( groupStart, groupCount, 0 ); 32468 32469 // calculate new start value for groups 32470 32471 groupStart += groupCount; 32472 32473 } 32474 32475 function generateCap( top ) { 32476 32477 var x, centerIndexStart, centerIndexEnd; 32478 32479 var uv = new Vector2(); 32480 var vertex = new Vector3(); 32481 32482 var groupCount = 0; 32483 32484 var radius = ( top === true ) ? radiusTop : radiusBottom; 32485 var sign = ( top === true ) ? 1 : - 1; 32486 32487 // save the index of the first center vertex 32488 centerIndexStart = index; 32489 32490 // first we generate the center vertex data of the cap. 32491 // because the geometry needs one set of uvs per face, 32492 // we must generate a center vertex per face/segment 32493 32494 for ( x = 1; x <= radialSegments; x ++ ) { 32495 32496 // vertex 32497 32498 vertices.push( 0, halfHeight * sign, 0 ); 32499 32500 // normal 32501 32502 normals.push( 0, sign, 0 ); 32503 32504 // uv 32505 32506 uvs.push( 0.5, 0.5 ); 32507 32508 // increase index 32509 32510 index ++; 32511 32512 } 32513 32514 // save the index of the last center vertex 32515 32516 centerIndexEnd = index; 32517 32518 // now we generate the surrounding vertices, normals and uvs 32519 32520 for ( x = 0; x <= radialSegments; x ++ ) { 32521 32522 var u = x / radialSegments; 32523 var theta = u * thetaLength + thetaStart; 32524 32525 var cosTheta = Math.cos( theta ); 32526 var sinTheta = Math.sin( theta ); 32527 32528 // vertex 32529 32530 vertex.x = radius * sinTheta; 32531 vertex.y = halfHeight * sign; 32532 vertex.z = radius * cosTheta; 32533 vertices.push( vertex.x, vertex.y, vertex.z ); 32534 32535 // normal 32536 32537 normals.push( 0, sign, 0 ); 32538 32539 // uv 32540 32541 uv.x = ( cosTheta * 0.5 ) + 0.5; 32542 uv.y = ( sinTheta * 0.5 * sign ) + 0.5; 32543 uvs.push( uv.x, uv.y ); 32544 32545 // increase index 32546 32547 index ++; 32548 32549 } 32550 32551 // generate indices 32552 32553 for ( x = 0; x < radialSegments; x ++ ) { 32554 32555 var c = centerIndexStart + x; 32556 var i = centerIndexEnd + x; 32557 32558 if ( top === true ) { 32559 32560 // face top 32561 32562 indices.push( i, i + 1, c ); 32563 32564 } else { 32565 32566 // face bottom 32567 32568 indices.push( i + 1, i, c ); 32569 32570 } 32571 32572 groupCount += 3; 32573 32574 } 32575 32576 // add a group to the geometry. this will ensure multi material support 32577 32578 scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 ); 32579 32580 // calculate new start value for groups 32581 32582 groupStart += groupCount; 32583 32584 } 32585 32586} 32587 32588CylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 32589CylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry; 32590 32591/** 32592 * @author abelnation / http://github.com/abelnation 32593 */ 32594 32595// ConeGeometry 32596 32597function ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { 32598 32599 CylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); 32600 32601 this.type = 'ConeGeometry'; 32602 32603 this.parameters = { 32604 radius: radius, 32605 height: height, 32606 radialSegments: radialSegments, 32607 heightSegments: heightSegments, 32608 openEnded: openEnded, 32609 thetaStart: thetaStart, 32610 thetaLength: thetaLength 32611 }; 32612 32613} 32614 32615ConeGeometry.prototype = Object.create( CylinderGeometry.prototype ); 32616ConeGeometry.prototype.constructor = ConeGeometry; 32617 32618// ConeBufferGeometry 32619 32620function ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { 32621 32622 CylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); 32623 32624 this.type = 'ConeBufferGeometry'; 32625 32626 this.parameters = { 32627 radius: radius, 32628 height: height, 32629 radialSegments: radialSegments, 32630 heightSegments: heightSegments, 32631 openEnded: openEnded, 32632 thetaStart: thetaStart, 32633 thetaLength: thetaLength 32634 }; 32635 32636} 32637 32638ConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype ); 32639ConeBufferGeometry.prototype.constructor = ConeBufferGeometry; 32640 32641/** 32642 * @author benaadams / https://twitter.com/ben_a_adams 32643 * @author Mugen87 / https://github.com/Mugen87 32644 * @author hughes 32645 */ 32646 32647// CircleGeometry 32648 32649function CircleGeometry( radius, segments, thetaStart, thetaLength ) { 32650 32651 Geometry.call( this ); 32652
32653 this.type = 'CircleGeometry'; 32654 32655 this.parameters = { 32656 radius: radius, 32657 segments: segments, 32658 thetaStart: thetaStart, 32659 thetaLength: thetaLength 32660 }; 32661 32662 this.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) ); 32663 this.mergeVertices(); 32664 32665} 32666 32667CircleGeometry.prototype = Object.create( Geometry.prototype ); 32668CircleGeometry.prototype.constructor = CircleGeometry; 32669 32670// CircleBufferGeometry 32671 32672function CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) { 32673 32674 BufferGeometry.call( this ); 32675 32676 this.type = 'CircleBufferGeometry'; 32677 32678 this.parameters = { 32679 radius: radius, 32680 segments: segments, 32681 thetaStart: thetaStart, 32682 thetaLength: thetaLength 32683 }; 32684 32685 radius = radius || 1; 32686 segments = segments !== undefined ? Math.max( 3, segments ) : 8; 32687 32688 thetaStart = thetaStart !== undefined ? thetaStart : 0; 32689 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; 32690 32691 // buffers 32692 32693 var indices = []; 32694 var vertices = []; 32695 var normals = []; 32696 var uvs = []; 32697 32698 // helper variables 32699 32700 var i, s; 32701 var vertex = new Vector3(); 32702 var uv = new Vector2(); 32703 32704 // center point 32705 32706 vertices.push( 0, 0, 0 ); 32707 normals.push( 0, 0, 1 ); 32708 uvs.push( 0.5, 0.5 ); 32709 32710 for ( s = 0, i = 3; s <= segments; s ++, i += 3 ) { 32711 32712 var segment = thetaStart + s / segments * thetaLength; 32713 32714 // vertex 32715 32716 vertex.x = radius * Math.cos( segment ); 32717 vertex.y = radius * Math.sin( segment ); 32718 32719 vertices.push( vertex.x, vertex.y, vertex.z ); 32720 32721 // normal 32722 32723 normals.push( 0, 0, 1 ); 32724 32725 // uvs 32726 32727 uv.x = ( vertices[ i ] / radius + 1 ) / 2; 32728 uv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2; 32729 32730 uvs.push( uv.x, uv.y ); 32731 32732 } 32733 32734 // indices 32735 32736 for ( i = 1; i <= segments; i ++ ) { 32737 32738 indices.push( i, i + 1, 0 ); 32739 32740 } 32741 32742 // build geometry 32743 32744 this.setIndex( indices ); 32745 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 32746 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 32747 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 32748 32749} 32750 32751CircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 32752CircleBufferGeometry.prototype.constructor = CircleBufferGeometry; 32753 32754var Geometries = /*#__PURE__*/Object.freeze({ 32755 __proto__: null, 32756 WireframeGeometry: WireframeGeometry, 32757 ParametricGeometry: ParametricGeometry, 32758 ParametricBufferGeometry: ParametricBufferGeometry, 32759 TetrahedronGeometry: TetrahedronGeometry, 32760 TetrahedronBufferGeometry: TetrahedronBufferGeometry, 32761 OctahedronGeometry: OctahedronGeometry, 32762 OctahedronBufferGeometry: OctahedronBufferGeometry, 32763 IcosahedronGeometry: IcosahedronGeometry, 32764 IcosahedronBufferGeometry: IcosahedronBufferGeometry, 32765 DodecahedronGeometry: DodecahedronGeometry, 32766 DodecahedronBufferGeometry: DodecahedronBufferGeometry, 32767 PolyhedronGeometry: PolyhedronGeometry, 32768 PolyhedronBufferGeometry: PolyhedronBufferGeometry, 32769 TubeGeometry: TubeGeometry, 32770 TubeBufferGeometry: TubeBufferGeometry, 32771 TorusKnotGeometry: TorusKnotGeometry, 32772 TorusKnotBufferGeometry: TorusKnotBufferGeometry, 32773 TorusGeometry: TorusGeometry, 32774 TorusBufferGeometry: TorusBufferGeometry, 32775 TextGeometry: TextGeometry, 32776 TextBufferGeometry: TextBufferGeometry, 32777 SphereGeometry: SphereGeometry, 32778 SphereBufferGeometry: SphereBufferGeometry, 32779 RingGeometry: RingGeometry, 32780 RingBufferGeometry: RingBufferGeometry, 32781 PlaneGeometry: PlaneGeometry, 32782 PlaneBufferGeometry: PlaneBufferGeometry, 32783 LatheGeometry: LatheGeometry, 32784 LatheBufferGeometry: LatheBufferGeometry, 32785 ShapeGeometry: ShapeGeometry, 32786 ShapeBufferGeometry: ShapeBufferGeometry, 32787 ExtrudeGeometry: ExtrudeGeometry, 32788 ExtrudeBufferGeometry: ExtrudeBufferGeometry, 32789 EdgesGeometry: EdgesGeometry, 32790 ConeGeometry: ConeGeometry, 32791 ConeBufferGeometry: ConeBufferGeometry, 32792 CylinderGeometry: CylinderGeometry, 32793 CylinderBufferGeometry: CylinderBufferGeometry, 32794 CircleGeometry: CircleGeometry, 32795 CircleBufferGeometry: CircleBufferGeometry, 32796 BoxGeometry: BoxGeometry, 32797 BoxBufferGeometry: BoxBufferGeometry 32798}); 32799 32800/** 32801 * @author mrdoob / http://mrdoob.com/ 32802 * 32803 * parameters = { 32804 * color: <THREE.Color> 32805 * } 32806 */ 32807 32808function ShadowMaterial( parameters ) { 32809 32810 Material.call( this ); 32811 32812 this.type = 'ShadowMaterial'; 32813 32814 this.color = new Color( 0x000000 ); 32815 this.transparent = true; 32816 32817 this.setValues( parameters ); 32818 32819} 32820 32821ShadowMaterial.prototype = Object.create( Material.prototype ); 32822ShadowMaterial.prototype.constructor = ShadowMaterial; 32823
vendor: 11,188 bytes, lines 32824-33310
32824ShadowMaterial.prototype.isShadowMaterial = true; 32825 32826ShadowMaterial.prototype.copy = function ( source ) { 32827 32828 Material.prototype.copy.call( this, source ); 32829 32830 this.color.copy( source.color ); 32831 32832 return this; 32833 32834}; 32835 32836/** 32837 * @author mrdoob / http://mrdoob.com/ 32838 */ 32839 32840function RawShaderMaterial( parameters ) { 32841 32842 ShaderMaterial.call( this, parameters ); 32843 32844 this.type = 'RawShaderMaterial'; 32845 32846} 32847 32848RawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype ); 32849RawShaderMaterial.prototype.constructor = RawShaderMaterial; 32850 32851RawShaderMaterial.prototype.isRawShaderMaterial = true; 32852 32853/** 32854 * @author WestLangley / http://github.com/WestLangley 32855 * 32856 * parameters = { 32857 * color: <hex>, 32858 * roughness: <float>, 32859 * metalness: <float>, 32860 * opacity: <float>, 32861 * 32862 * map: new THREE.Texture( <Image> ), 32863 * 32864 * lightMap: new THREE.Texture( <Image> ), 32865 * lightMapIntensity: <float> 32866 * 32867 * aoMap: new THREE.Texture( <Image> ), 32868 * aoMapIntensity: <float> 32869 * 32870 * emissive: <hex>, 32871 * emissiveIntensity: <float> 32872 * emissiveMap: new THREE.Texture( <Image> ), 32873 * 32874 * bumpMap: new THREE.Texture( <Image> ), 32875 * bumpScale: <float>, 32876 * 32877 * normalMap: new THREE.Texture( <Image> ), 32878 * normalMapType: THREE.TangentSpaceNormalMap, 32879 * normalScale: <Vector2>, 32880 * 32881 * displacementMap: new THREE.Texture( <Image> ), 32882 * displacementScale: <float>, 32883 * displacementBias: <float>, 32884 * 32885 * roughnessMap: new THREE.Texture( <Image> ), 32886 * 32887 * metalnessMap: new THREE.Texture( <Image> ), 32888 * 32889 * alphaMap: new THREE.Texture( <Image> ), 32890 * 32891 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), 32892 * envMapIntensity: <float> 32893 * 32894 * refractionRatio: <float>, 32895 * 32896 * wireframe: <boolean>, 32897 * wireframeLinewidth: <float>, 32898 * 32899 * skinning: <bool>, 32900 * morphTargets: <bool>, 32901 * morphNormals: <bool> 32902 * } 32903 */ 32904 32905function MeshStandardMaterial( parameters ) { 32906 32907 Material.call( this ); 32908 32909 this.defines = { 'STANDARD': '' }; 32910 32911 this.type = 'MeshStandardMaterial'; 32912 32913 this.color = new Color( 0xffffff ); // diffuse 32914 this.roughness = 1.0; 32915 this.metalness = 0.0; 32916 32917 this.map = null; 32918 32919 this.lightMap = null; 32920 this.lightMapIntensity = 1.0; 32921 32922 this.aoMap = null; 32923 this.aoMapIntensity = 1.0; 32924 32925 this.emissive = new Color( 0x000000 ); 32926 this.emissiveIntensity = 1.0; 32927 this.emissiveMap = null; 32928 32929 this.bumpMap = null; 32930 this.bumpScale = 1; 32931 32932 this.normalMap = null; 32933 this.normalMapType = TangentSpaceNormalMap; 32934 this.normalScale = new Vector2( 1, 1 ); 32935 32936 this.displacementMap = null; 32937 this.displacementScale = 1; 32938 this.displacementBias = 0; 32939 32940 this.roughnessMap = null; 32941 32942 this.metalnessMap = null; 32943 32944 this.alphaMap = null; 32945 32946 this.envMap = null; 32947 this.envMapIntensity = 1.0; 32948 32949 this.refractionRatio = 0.98; 32950 32951 this.wireframe = false; 32952 this.wireframeLinewidth = 1; 32953 this.wireframeLinecap = 'round'; 32954 this.wireframeLinejoin = 'round'; 32955 32956 this.skinning = false; 32957 this.morphTargets = false; 32958 this.morphNormals = false; 32959 32960 this.vertexTangents = false; 32961 32962 this.setValues( parameters ); 32963 32964} 32965 32966MeshStandardMaterial.prototype = Object.create( Material.prototype ); 32967MeshStandardMaterial.prototype.constructor = MeshStandardMaterial; 32968 32969MeshStandardMaterial.prototype.isMeshStandardMaterial = true; 32970 32971MeshStandardMaterial.prototype.copy = function ( source ) { 32972 32973 Material.prototype.copy.call( this, source ); 32974 32975 this.defines = { 'STANDARD': '' }; 32976 32977 this.color.copy( source.color ); 32978 this.roughness = source.roughness; 32979 this.metalness = source.metalness; 32980 32981 this.map = source.map; 32982 32983 this.lightMap = source.lightMap; 32984 this.lightMapIntensity = source.lightMapIntensity; 32985 32986 this.aoMap = source.aoMap; 32987 this.aoMapIntensity = source.aoMapIntensity; 32988 32989 this.emissive.copy( source.emissive ); 32990 this.emissiveMap = source.emissiveMap; 32991 this.emissiveIntensity = source.emissiveIntensity; 32992 32993 this.bumpMap = source.bumpMap; 32994 this.bumpScale = source.bumpScale; 32995 32996 this.normalMap = source.normalMap; 32997 this.normalMapType = source.normalMapType; 32998 this.normalScale.copy( source.normalScale ); 32999 33000 this.displacementMap = source.displacementMap; 33001 this.displacementScale = source.displacementScale; 33002 this.displacementBias = source.displacementBias; 33003 33004 this.roughnessMap = source.roughnessMap; 33005 33006 this.metalnessMap = source.metalnessMap; 33007 33008 this.alphaMap = source.alphaMap; 33009 33010 this.envMap = source.envMap; 33011 this.envMapIntensity = source.envMapIntensity; 33012 33013 this.refractionRatio = source.refractionRatio; 33014 33015 this.wireframe = source.wireframe; 33016 this.wireframeLinewidth = source.wireframeLinewidth; 33017 this.wireframeLinecap = source.wireframeLinecap; 33018 this.wireframeLinejoin = source.wireframeLinejoin; 33019 33020 this.skinning = source.skinning; 33021 this.morphTargets = source.morphTargets; 33022 this.morphNormals = source.morphNormals; 33023 33024 this.vertexTangents = source.vertexTangents; 33025 33026 return this; 33027 33028}; 33029 33030/** 33031 * @author WestLangley / http://github.com/WestLangley 33032 * 33033 * parameters = { 33034 * clearcoat: <float>, 33035 * clearcoatMap: new THREE.Texture( <Image> ), 33036 * clearcoatRoughness: <float>, 33037 * clearcoatRoughnessMap: new THREE.Texture( <Image> ), 33038 * clearcoatNormalScale: <Vector2>, 33039 * clearcoatNormalMap: new THREE.Texture( <Image> ), 33040 * 33041 * reflectivity: <float>, 33042 * 33043 * sheen: <Color>, 33044 * 33045 * transparency: <float> 33046 * } 33047 */ 33048 33049function MeshPhysicalMaterial( parameters ) { 33050 33051 MeshStandardMaterial.call( this ); 33052 33053 this.defines = { 33054 33055 'STANDARD': '', 33056 'PHYSICAL': '' 33057 33058 }; 33059 33060 this.type = 'MeshPhysicalMaterial'; 33061 33062 this.clearcoat = 0.0; 33063 this.clearcoatMap = null; 33064 this.clearcoatRoughness = 0.0; 33065 this.clearcoatRoughnessMap = null; 33066 this.clearcoatNormalScale = new Vector2( 1, 1 ); 33067 this.clearcoatNormalMap = null; 33068 33069 this.reflectivity = 0.5; // maps to F0 = 0.04 33070 33071 this.sheen = null; // null will disable sheen bsdf 33072 33073 this.transparency = 0.0; 33074 33075 this.setValues( parameters ); 33076 33077} 33078 33079MeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype ); 33080MeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial; 33081 33082MeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true; 33083 33084MeshPhysicalMaterial.prototype.copy = function ( source ) { 33085 33086 MeshStandardMaterial.prototype.copy.call( this, source ); 33087 33088 this.defines = { 33089 33090 'STANDARD': '', 33091 'PHYSICAL': '' 33092 33093 }; 33094 33095 this.clearcoat = source.clearcoat; 33096 this.clearcoatMap = source.clearcoatMap; 33097 this.clearcoatRoughness = source.clearcoatRoughness; 33098 this.clearcoatRoughnessMap = source.clearcoatRoughnessMap; 33099 this.clearcoatNormalMap = source.clearcoatNormalMap; 33100 this.clearcoatNormalScale.copy( source.clearcoatNormalScale ); 33101 33102 this.reflectivity = source.reflectivity; 33103 33104 if ( source.sheen ) { 33105 33106 this.sheen = ( this.sheen || new Color() ).copy( source.sheen ); 33107 33108 } else { 33109 33110 this.sheen = null; 33111 33112 } 33113 33114 this.transparency = source.transparency; 33115 33116 return this; 33117 33118}; 33119 33120/** 33121 * @author mrdoob / http://mrdoob.com/ 33122 * @author alteredq / http://alteredqualia.com/ 33123 * 33124 * parameters = { 33125 * color: <hex>, 33126 * specular: <hex>, 33127 * shininess: <float>, 33128 * opacity: <float>, 33129 * 33130 * map: new THREE.Texture( <Image> ), 33131 * 33132 * lightMap: new THREE.Texture( <Image> ), 33133 * lightMapIntensity: <float> 33134 * 33135 * aoMap: new THREE.Texture( <Image> ), 33136 * aoMapIntensity: <float> 33137 * 33138 * emissive: <hex>, 33139 * emissiveIntensity: <float> 33140 * emissiveMap: new THREE.Texture( <Image> ), 33141 * 33142 * bumpMap: new THREE.Texture( <Image> ), 33143 * bumpScale: <float>, 33144 * 33145 * normalMap: new THREE.Texture( <Image> ), 33146 * normalMapType: THREE.TangentSpaceNormalMap, 33147 * normalScale: <Vector2>, 33148 * 33149 * displacementMap: new THREE.Texture( <Image> ), 33150 * displacementScale: <float>, 33151 * displacementBias: <float>, 33152 * 33153 * specularMap: new THREE.Texture( <Image> ), 33154 * 33155 * alphaMap: new THREE.Texture( <Image> ), 33156 * 33157 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), 33158 * combine: THREE.MultiplyOperation, 33159 * reflectivity: <float>, 33160 * refractionRatio: <float>, 33161 * 33162 * wireframe: <boolean>, 33163 * wireframeLinewidth: <float>, 33164 * 33165 * skinning: <bool>, 33166 * morphTargets: <bool>, 33167 * morphNormals: <bool> 33168 * } 33169 */ 33170 33171function MeshPhongMaterial( parameters ) { 33172 33173 Material.call( this ); 33174 33175 this.type = 'MeshPhongMaterial'; 33176 33177 this.color = new Color( 0xffffff ); // diffuse 33178 this.specular = new Color( 0x111111 ); 33179 this.shininess = 30; 33180 33181 this.map = null; 33182 33183 this.lightMap = null; 33184 this.lightMapIntensity = 1.0; 33185 33186 this.aoMap = null; 33187 this.aoMapIntensity = 1.0; 33188 33189 this.emissive = new Color( 0x000000 ); 33190 this.emissiveIntensity = 1.0; 33191 this.emissiveMap = null; 33192 33193 this.bumpMap = null; 33194 this.bumpScale = 1; 33195 33196 this.normalMap = null; 33197 this.normalMapType = TangentSpaceNormalMap; 33198 this.normalScale = new Vector2( 1, 1 ); 33199 33200 this.displacementMap = null; 33201 this.displacementScale = 1; 33202 this.displacementBias = 0; 33203 33204 this.specularMap = null; 33205 33206 this.alphaMap = null; 33207 33208 this.envMap = null; 33209 this.combine = MultiplyOperation; 33210 this.reflectivity = 1; 33211 this.refractionRatio = 0.98; 33212 33213 this.wireframe = false; 33214 this.wireframeLinewidth = 1; 33215 this.wireframeLinecap = 'round'; 33216 this.wireframeLinejoin = 'round'; 33217 33218 this.skinning = false; 33219 this.morphTargets = false; 33220 this.morphNormals = false; 33221 33222 this.setValues( parameters ); 33223 33224} 33225 33226MeshPhongMaterial.prototype = Object.create( Material.prototype ); 33227MeshPhongMaterial.prototype.constructor = MeshPhongMaterial; 33228 33229MeshPhongMaterial.prototype.isMeshPhongMaterial = true; 33230 33231MeshPhongMaterial.prototype.copy = function ( source ) { 33232 33233 Material.prototype.copy.call( this, source ); 33234 33235 this.color.copy( source.color ); 33236 this.specular.copy( source.specular ); 33237 this.shininess = source.shininess; 33238 33239 this.map = source.map; 33240 33241 this.lightMap = source.lightMap; 33242 this.lightMapIntensity = source.lightMapIntensity; 33243 33244 this.aoMap = source.aoMap; 33245 this.aoMapIntensity = source.aoMapIntensity; 33246 33247 this.emissive.copy( source.emissive ); 33248 this.emissiveMap = source.emissiveMap; 33249 this.emissiveIntensity = source.emissiveIntensity; 33250 33251 this.bumpMap = source.bumpMap; 33252 this.bumpScale = source.bumpScale; 33253 33254 this.normalMap = source.normalMap; 33255 this.normalMapType = source.normalMapType; 33256 this.normalScale.copy( source.normalScale ); 33257 33258 this.displacementMap = source.displacementMap; 33259 this.displacementScale = source.displacementScale; 33260 this.displacementBias = source.displacementBias; 33261 33262 this.specularMap = source.specularMap; 33263 33264 this.alphaMap = source.alphaMap; 33265 33266 this.envMap = source.envMap; 33267 this.combine = source.combine; 33268 this.reflectivity = source.reflectivity; 33269 this.refractionRatio = source.refractionRatio; 33270 33271 this.wireframe = source.wireframe; 33272 this.wireframeLinewidth = source.wireframeLinewidth; 33273 this.wireframeLinecap = source.wireframeLinecap; 33274 this.wireframeLinejoin = source.wireframeLinejoin; 33275 33276 this.skinning = source.skinning; 33277 this.morphTargets = source.morphTargets; 33278 this.morphNormals = source.morphNormals; 33279 33280 return this; 33281 33282}; 33283 33284/** 33285 * @author takahirox / http://github.com/takahirox 33286 * 33287 * parameters = { 33288 * color: <hex>, 33289 * specular: <hex>, 33290 * shininess: <float>, 33291 * 33292 * map: new THREE.Texture( <Image> ), 33293 * gradientMap: new THREE.Texture( <Image> ), 33294 * 33295 * lightMap: new THREE.Texture( <Image> ), 33296 * lightMapIntensity: <float> 33297 * 33298 * aoMap: new THREE.Texture( <Image> ), 33299 * aoMapIntensity: <float> 33300 * 33301 * emissive: <hex>, 33302 * emissiveIntensity: <float> 33303 * emissiveMap: new THREE.Texture( <Image> ), 33304 * 33305 * bumpMap: new THREE.Texture( <Image> ), 33306 * bumpScale: <float>, 33307 * 33308 * normalMap: new THREE.Texture( <Image> ), 33309 * normalMapType: THREE.TangentSpaceNormalMap, 33310 * normalScale: <Vector2>,
33311 * 33312 * displacementMap: new THREE.Texture( <Image> ), 33313 * displacementScale: <float>, 33314 * displacementBias: <float>, 33315 * 33316 * specularMap: new THREE.Texture( <Image> ), 33317 * 33318 * alphaMap: new THREE.Texture( <Image> ), 33319 * 33320 * wireframe: <boolean>, 33321 * wireframeLinewidth: <float>, 33322 * 33323 * skinning: <bool>, 33324 * morphTargets: <bool>, 33325 * morphNormals: <bool> 33326 * } 33327 */ 33328 33329function MeshToonMaterial( parameters ) { 33330 33331 Material.call( this ); 33332 33333 this.defines = { 'TOON': '' }; 33334 33335 this.type = 'MeshToonMaterial'; 33336 33337 this.color = new Color( 0xffffff ); 33338 this.specular = new Color( 0x111111 ); 33339 this.shininess = 30; 33340 33341 this.map = null; 33342 this.gradientMap = null; 33343 33344 this.lightMap = null; 33345 this.lightMapIntensity = 1.0; 33346 33347 this.aoMap = null; 33348 this.aoMapIntensity = 1.0; 33349 33350 this.emissive = new Color( 0x000000 ); 33351 this.emissiveIntensity = 1.0; 33352 this.emissiveMap = null; 33353 33354 this.bumpMap = null; 33355 this.bumpScale = 1; 33356 33357 this.normalMap = null; 33358 this.normalMapType = TangentSpaceNormalMap; 33359 this.normalScale = new Vector2( 1, 1 ); 33360 33361 this.displacementMap = null; 33362 this.displacementScale = 1; 33363 this.displacementBias = 0; 33364 33365 this.specularMap = null; 33366 33367 this.alphaMap = null; 33368 33369 this.wireframe = false; 33370 this.wireframeLinewidth = 1; 33371 this.wireframeLinecap = 'round'; 33372 this.wireframeLinejoin = 'round'; 33373 33374 this.skinning = false; 33375 this.morphTargets = false; 33376 this.morphNormals = false; 33377 33378 this.setValues( parameters ); 33379 33380} 33381 33382MeshToonMaterial.prototype = Object.create( Material.prototype ); 33383MeshToonMaterial.prototype.constructor = MeshToonMaterial; 33384 33385MeshToonMaterial.prototype.isMeshToonMaterial = true; 33386 33387MeshToonMaterial.prototype.copy = function ( source ) { 33388 33389 Material.prototype.copy.call( this, source ); 33390 33391 this.color.copy( source.color ); 33392 this.specular.copy( source.specular ); 33393 this.shininess = source.shininess; 33394 33395 this.map = source.map; 33396 this.gradientMap = source.gradientMap; 33397 33398 this.lightMap = source.lightMap; 33399 this.lightMapIntensity = source.lightMapIntensity; 33400 33401 this.aoMap = source.aoMap; 33402 this.aoMapIntensity = source.aoMapIntensity; 33403 33404 this.emissive.copy( source.emissive ); 33405 this.emissiveMap = source.emissiveMap; 33406 this.emissiveIntensity = source.emissiveIntensity; 33407 33408 this.bumpMap = source.bumpMap; 33409 this.bumpScale = source.bumpScale; 33410 33411 this.normalMap = source.normalMap; 33412 this.normalMapType = source.normalMapType; 33413 this.normalScale.copy( source.normalScale ); 33414 33415 this.displacementMap = source.displacementMap; 33416 this.displacementScale = source.displacementScale; 33417 this.displacementBias = source.displacementBias; 33418 33419 this.specularMap = source.specularMap; 33420 33421 this.alphaMap = source.alphaMap; 33422 33423 this.wireframe = source.wireframe; 33424 this.wireframeLinewidth = source.wireframeLinewidth; 33425 this.wireframeLinecap = source.wireframeLinecap; 33426 this.wireframeLinejoin = source.wireframeLinejoin; 33427 33428 this.skinning = source.skinning; 33429 this.morphTargets = source.morphTargets; 33430 this.morphNormals = source.morphNormals; 33431 33432 return this; 33433 33434}; 33435 33436/** 33437 * @author mrdoob / http://mrdoob.com/ 33438 * @author WestLangley / http://github.com/WestLangley 33439 * 33440 * parameters = { 33441 * opacity: <float>, 33442 * 33443 * bumpMap: new THREE.Texture( <Image> ), 33444 * bumpScale: <float>, 33445 * 33446 * normalMap: new THREE.Texture( <Image> ), 33447 * normalMapType: THREE.TangentSpaceNormalMap, 33448 * normalScale: <Vector2>, 33449 * 33450 * displacementMap: new THREE.Texture( <Image> ), 33451 * displacementScale: <float>, 33452 * displacementBias: <float>, 33453 * 33454 * wireframe: <boolean>, 33455 * wireframeLinewidth: <float> 33456 * 33457 * skinning: <bool>, 33458 * morphTargets: <bool>, 33459 * morphNormals: <bool> 33460 * } 33461 */ 33462 33463function MeshNormalMaterial( parameters ) { 33464 33465 Material.call( this ); 33466 33467 this.type = 'MeshNormalMaterial'; 33468 33469 this.bumpMap = null; 33470 this.bumpScale = 1; 33471 33472 this.normalMap = null; 33473 this.normalMapType = TangentSpaceNormalMap; 33474 this.normalScale = new Vector2( 1, 1 ); 33475 33476 this.displacementMap = null; 33477 this.displacementScale = 1; 33478 this.displacementBias = 0; 33479 33480 this.wireframe = false; 33481 this.wireframeLinewidth = 1; 33482 33483 this.fog = false; 33484 33485 this.skinning = false; 33486 this.morphTargets = false; 33487 this.morphNormals = false; 33488 33489 this.setValues( parameters ); 33490 33491} 33492 33493MeshNormalMaterial.prototype = Object.create( Material.prototype ); 33494MeshNormalMaterial.prototype.constructor = MeshNormalMaterial; 33495 33496MeshNormalMaterial.prototype.isMeshNormalMaterial = true; 33497 33498MeshNormalMaterial.prototype.copy = function ( source ) { 33499 33500 Material.prototype.copy.call( this, source ); 33501 33502 this.bumpMap = source.bumpMap; 33503 this.bumpScale = source.bumpScale; 33504 33505 this.normalMap = source.normalMap; 33506 this.normalMapType = source.normalMapType; 33507 this.normalScale.copy( source.normalScale ); 33508 33509 this.displacementMap = source.displacementMap; 33510 this.displacementScale = source.displacementScale; 33511 this.displacementBias = source.displacementBias; 33512 33513 this.wireframe = source.wireframe; 33514 this.wireframeLinewidth = source.wireframeLinewidth; 33515 33516 this.skinning = source.skinning; 33517 this.morphTargets = source.morphTargets; 33518 this.morphNormals = source.morphNormals; 33519 33520 return this; 33521 33522}; 33523 33524/** 33525 * @author mrdoob / http://mrdoob.com/ 33526 * @author alteredq / http://alteredqualia.com/ 33527 * 33528 * parameters = { 33529 * color: <hex>, 33530 * opacity: <float>, 33531 * 33532 * map: new THREE.Texture( <Image> ), 33533 * 33534 * lightMap: new THREE.Texture( <Image> ), 33535 * lightMapIntensity: <float> 33536 * 33537 * aoMap: new THREE.Texture( <Image> ), 33538 * aoMapIntensity: <float> 33539 * 33540 * emissive: <hex>, 33541 * emissiveIntensity: <float> 33542 * emissiveMap: new THREE.Texture( <Image> ), 33543 * 33544 * specularMap: new THREE.Texture( <Image> ), 33545 * 33546 * alphaMap: new THREE.Texture( <Image> ), 33547 * 33548 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), 33549 * combine: THREE.Multiply, 33550 * reflectivity: <float>, 33551 * refractionRatio: <float>, 33552 * 33553 * wireframe: <boolean>, 33554 * wireframeLinewidth: <float>, 33555 * 33556 * skinning: <bool>, 33557 * morphTargets: <bool>, 33558 * morphNormals: <bool> 33559 * } 33560 */ 33561 33562function MeshLambertMaterial( parameters ) { 33563 33564 Material.call( this ); 33565 33566 this.type = 'MeshLambertMaterial'; 33567 33568 this.color = new Color( 0xffffff ); // diffuse 33569 33570 this.map = null; 33571 33572 this.lightMap = null; 33573 this.lightMapIntensity = 1.0; 33574 33575 this.aoMap = null; 33576 this.aoMapIntensity = 1.0; 33577 33578 this.emissive = new Color( 0x000000 ); 33579 this.emissiveIntensity = 1.0; 33580 this.emissiveMap = null; 33581 33582 this.specularMap = null; 33583 33584 this.alphaMap = null; 33585 33586 this.envMap = null; 33587 this.combine = MultiplyOperation; 33588 this.reflectivity = 1; 33589 this.refractionRatio = 0.98; 33590 33591 this.wireframe = false;
vendor: 5,982 bytes, lines 33592-33846
33592 this.wireframeLinewidth = 1; 33593 this.wireframeLinecap = 'round'; 33594 this.wireframeLinejoin = 'round'; 33595 33596 this.skinning = false; 33597 this.morphTargets = false; 33598 this.morphNormals = false; 33599 33600 this.setValues( parameters ); 33601 33602} 33603 33604MeshLambertMaterial.prototype = Object.create( Material.prototype ); 33605MeshLambertMaterial.prototype.constructor = MeshLambertMaterial; 33606 33607MeshLambertMaterial.prototype.isMeshLambertMaterial = true; 33608 33609MeshLambertMaterial.prototype.copy = function ( source ) { 33610 33611 Material.prototype.copy.call( this, source ); 33612 33613 this.color.copy( source.color ); 33614 33615 this.map = source.map; 33616 33617 this.lightMap = source.lightMap; 33618 this.lightMapIntensity = source.lightMapIntensity; 33619 33620 this.aoMap = source.aoMap; 33621 this.aoMapIntensity = source.aoMapIntensity; 33622 33623 this.emissive.copy( source.emissive ); 33624 this.emissiveMap = source.emissiveMap; 33625 this.emissiveIntensity = source.emissiveIntensity; 33626 33627 this.specularMap = source.specularMap; 33628 33629 this.alphaMap = source.alphaMap; 33630 33631 this.envMap = source.envMap; 33632 this.combine = source.combine; 33633 this.reflectivity = source.reflectivity; 33634 this.refractionRatio = source.refractionRatio; 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 * @author WestLangley / http://github.com/WestLangley 33651 * 33652 * parameters = { 33653 * color: <hex>, 33654 * opacity: <float>, 33655 * 33656 * matcap: new THREE.Texture( <Image> ), 33657 * 33658 * map: new THREE.Texture( <Image> ), 33659 * 33660 * bumpMap: new THREE.Texture( <Image> ), 33661 * bumpScale: <float>, 33662 * 33663 * normalMap: new THREE.Texture( <Image> ), 33664 * normalMapType: THREE.TangentSpaceNormalMap, 33665 * normalScale: <Vector2>, 33666 * 33667 * displacementMap: new THREE.Texture( <Image> ), 33668 * displacementScale: <float>, 33669 * displacementBias: <float>, 33670 * 33671 * alphaMap: new THREE.Texture( <Image> ), 33672 * 33673 * skinning: <bool>, 33674 * morphTargets: <bool>, 33675 * morphNormals: <bool> 33676 * } 33677 */ 33678 33679function MeshMatcapMaterial( parameters ) { 33680 33681 Material.call( this ); 33682 33683 this.defines = { 'MATCAP': '' }; 33684 33685 this.type = 'MeshMatcapMaterial'; 33686 33687 this.color = new Color( 0xffffff ); // diffuse 33688 33689 this.matcap = null; 33690 33691 this.map = null; 33692 33693 this.bumpMap = null; 33694 this.bumpScale = 1; 33695 33696 this.normalMap = null; 33697 this.normalMapType = TangentSpaceNormalMap; 33698 this.normalScale = new Vector2( 1, 1 ); 33699 33700 this.displacementMap = null; 33701 this.displacementScale = 1; 33702 this.displacementBias = 0; 33703 33704 this.alphaMap = null; 33705 33706 this.skinning = false; 33707 this.morphTargets = false; 33708 this.morphNormals = false; 33709 33710 this.setValues( parameters ); 33711 33712} 33713 33714MeshMatcapMaterial.prototype = Object.create( Material.prototype ); 33715MeshMatcapMaterial.prototype.constructor = MeshMatcapMaterial; 33716 33717MeshMatcapMaterial.prototype.isMeshMatcapMaterial = true; 33718 33719MeshMatcapMaterial.prototype.copy = function ( source ) { 33720 33721 Material.prototype.copy.call( this, source ); 33722 33723 this.defines = { 'MATCAP': '' }; 33724 33725 this.color.copy( source.color ); 33726 33727 this.matcap = source.matcap; 33728 33729 this.map = source.map; 33730 33731 this.bumpMap = source.bumpMap; 33732 this.bumpScale = source.bumpScale; 33733 33734 this.normalMap = source.normalMap; 33735 this.normalMapType = source.normalMapType; 33736 this.normalScale.copy( source.normalScale ); 33737 33738 this.displacementMap = source.displacementMap; 33739 this.displacementScale = source.displacementScale; 33740 this.displacementBias = source.displacementBias; 33741 33742 this.alphaMap = source.alphaMap; 33743 33744 this.skinning = source.skinning; 33745 this.morphTargets = source.morphTargets; 33746 this.morphNormals = source.morphNormals; 33747 33748 return this; 33749 33750}; 33751 33752/** 33753 * @author alteredq / http://alteredqualia.com/ 33754 * 33755 * parameters = { 33756 * color: <hex>, 33757 * opacity: <float>, 33758 * 33759 * linewidth: <float>, 33760 * 33761 * scale: <float>, 33762 * dashSize: <float>, 33763 * gapSize: <float> 33764 * } 33765 */ 33766 33767function LineDashedMaterial( parameters ) { 33768 33769 LineBasicMaterial.call( this ); 33770 33771 this.type = 'LineDashedMaterial'; 33772 33773 this.scale = 1; 33774 this.dashSize = 3; 33775 this.gapSize = 1; 33776 33777 this.setValues( parameters ); 33778 33779} 33780 33781LineDashedMaterial.prototype = Object.create( LineBasicMaterial.prototype ); 33782LineDashedMaterial.prototype.constructor = LineDashedMaterial; 33783 33784LineDashedMaterial.prototype.isLineDashedMaterial = true; 33785 33786LineDashedMaterial.prototype.copy = function ( source ) { 33787 33788 LineBasicMaterial.prototype.copy.call( this, source ); 33789 33790 this.scale = source.scale; 33791 this.dashSize = source.dashSize; 33792 this.gapSize = source.gapSize; 33793 33794 return this; 33795 33796}; 33797 33798var Materials = /*#__PURE__*/Object.freeze({ 33799 __proto__: null, 33800 ShadowMaterial: ShadowMaterial, 33801 SpriteMaterial: SpriteMaterial, 33802 RawShaderMaterial: RawShaderMaterial, 33803 ShaderMaterial: ShaderMaterial, 33804 PointsMaterial: PointsMaterial, 33805 MeshPhysicalMaterial: MeshPhysicalMaterial, 33806 MeshStandardMaterial: MeshStandardMaterial, 33807 MeshPhongMaterial: MeshPhongMaterial, 33808 MeshToonMaterial: MeshToonMaterial, 33809 MeshNormalMaterial: MeshNormalMaterial, 33810 MeshLambertMaterial: MeshLambertMaterial, 33811 MeshDepthMaterial: MeshDepthMaterial, 33812 MeshDistanceMaterial: MeshDistanceMaterial, 33813 MeshBasicMaterial: MeshBasicMaterial, 33814 MeshMatcapMaterial: MeshMatcapMaterial, 33815 LineDashedMaterial: LineDashedMaterial, 33816 LineBasicMaterial: LineBasicMaterial, 33817 Material: Material 33818}); 33819 33820/** 33821 * @author tschw 33822 * @author Ben Houston / http://clara.io/ 33823 * @author David Sarno / http://lighthaus.us/ 33824 */ 33825 33826var AnimationUtils = { 33827 33828 // same as Array.prototype.slice, but also works on typed arrays 33829 arraySlice: function ( array, from, to ) { 33830 33831 if ( AnimationUtils.isTypedArray( array ) ) { 33832 33833 // in ios9 array.subarray(from, undefined) will return empty array 33834 // but array.subarray(from) or array.subarray(from, len) is correct 33835 return new array.constructor( array.subarray( from, to !== undefined ? to : array.length ) ); 33836 33837 } 33838 33839 return array.slice( from, to ); 33840 33841 }, 33842 33843 // converts an array to a specific type 33844 convertArray: function ( array, type, forceClone ) { 33845 33846 if ( ! array || // let 'undefined' and 'null' pass
vendor: 5,877 bytes, lines 33847-34113
33847 ! forceClone && array.constructor === type ) return array; 33848 33849 if ( typeof type.BYTES_PER_ELEMENT === 'number' ) { 33850 33851 return new type( array ); // create typed array 33852 33853 } 33854 33855 return Array.prototype.slice.call( array ); // create Array 33856 33857 }, 33858 33859 isTypedArray: function ( object ) { 33860 33861 return ArrayBuffer.isView( object ) && 33862 ! ( object instanceof DataView ); 33863 33864 }, 33865 33866 // returns an array by which times and values can be sorted 33867 getKeyframeOrder: function ( times ) { 33868 33869 function compareTime( i, j ) { 33870 33871 return times[ i ] - times[ j ]; 33872 33873 } 33874 33875 var n = times.length; 33876 var result = new Array( n ); 33877 for ( var i = 0; i !== n; ++ i ) result[ i ] = i; 33878 33879 result.sort( compareTime ); 33880 33881 return result; 33882 33883 }, 33884 33885 // uses the array previously returned by 'getKeyframeOrder' to sort data 33886 sortedArray: function ( values, stride, order ) { 33887 33888 var nValues = values.length; 33889 var result = new values.constructor( nValues ); 33890 33891 for ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) { 33892 33893 var srcOffset = order[ i ] * stride; 33894 33895 for ( var j = 0; j !== stride; ++ j ) { 33896 33897 result[ dstOffset ++ ] = values[ srcOffset + j ]; 33898 33899 } 33900 33901 } 33902 33903 return result; 33904 33905 }, 33906 33907 // function for parsing AOS keyframe formats 33908 flattenJSON: function ( jsonKeys, times, values, valuePropertyName ) { 33909 33910 var i = 1, key = jsonKeys[ 0 ]; 33911 33912 while ( key !== undefined && key[ valuePropertyName ] === undefined ) { 33913 33914 key = jsonKeys[ i ++ ]; 33915 33916 } 33917 33918 if ( key === undefined ) return; // no data 33919 33920 var value = key[ valuePropertyName ]; 33921 if ( value === undefined ) return; // no data 33922 33923 if ( Array.isArray( value ) ) { 33924 33925 do { 33926 33927 value = key[ valuePropertyName ]; 33928 33929 if ( value !== undefined ) { 33930 33931 times.push( key.time ); 33932 values.push.apply( values, value ); // push all elements 33933 33934 } 33935 33936 key = jsonKeys[ i ++ ]; 33937 33938 } while ( key !== undefined ); 33939 33940 } else if ( value.toArray !== undefined ) { 33941 33942 // ...assume THREE.Math-ish 33943 33944 do { 33945 33946 value = key[ valuePropertyName ]; 33947 33948 if ( value !== undefined ) { 33949 33950 times.push( key.time ); 33951 value.toArray( values, values.length ); 33952 33953 } 33954 33955 key = jsonKeys[ i ++ ]; 33956 33957 } while ( key !== undefined ); 33958 33959 } else { 33960 33961 // otherwise push as-is 33962 33963 do { 33964 33965 value = key[ valuePropertyName ]; 33966 33967 if ( value !== undefined ) { 33968 33969 times.push( key.time ); 33970 values.push( value ); 33971 33972 } 33973 33974 key = jsonKeys[ i ++ ]; 33975 33976 } while ( key !== undefined ); 33977 33978 } 33979 33980 }, 33981 33982 subclip: function ( sourceClip, name, startFrame, endFrame, fps ) { 33983 33984 fps = fps || 30; 33985 33986 var clip = sourceClip.clone(); 33987 33988 clip.name = name; 33989 33990 var tracks = []; 33991 33992 for ( var i = 0; i < clip.tracks.length; ++ i ) { 33993 33994 var track = clip.tracks[ i ]; 33995 var valueSize = track.getValueSize(); 33996 33997 var times = []; 33998 var values = []; 33999 34000 for ( var j = 0; j < track.times.length; ++ j ) { 34001 34002 var frame = track.times[ j ] * fps; 34003 34004 if ( frame < startFrame || frame >= endFrame ) continue; 34005 34006 times.push( track.times[ j ] ); 34007 34008 for ( var k = 0; k < valueSize; ++ k ) { 34009 34010 values.push( track.values[ j * valueSize + k ] ); 34011 34012 } 34013 34014 } 34015 34016 if ( times.length === 0 ) continue; 34017 34018 track.times = AnimationUtils.convertArray( times, track.times.constructor ); 34019 track.values = AnimationUtils.convertArray( values, track.values.constructor ); 34020 34021 tracks.push( track ); 34022 34023 } 34024 34025 clip.tracks = tracks; 34026 34027 // find minimum .times value across all tracks in the trimmed clip 34028 34029 var minStartTime = Infinity; 34030 34031 for ( var i = 0; i < clip.tracks.length; ++ i ) { 34032 34033 if ( minStartTime > clip.tracks[ i ].times[ 0 ] ) { 34034 34035 minStartTime = clip.tracks[ i ].times[ 0 ]; 34036 34037 } 34038 34039 } 34040 34041 // shift all tracks such that clip begins at t=0 34042 34043 for ( var i = 0; i < clip.tracks.length; ++ i ) { 34044 34045 clip.tracks[ i ].shift( - 1 * minStartTime ); 34046 34047 } 34048 34049 clip.resetDuration(); 34050 34051 return clip; 34052 34053 }, 34054 34055 makeClipAdditive: function ( targetClip, referenceFrame, referenceClip, fps ) { 34056 34057 if ( referenceFrame === undefined ) referenceFrame = 0; 34058 if ( referenceClip === undefined ) referenceClip = targetClip; 34059 if ( fps === undefined || fps <= 0 ) fps = 30; 34060 34061 var numTracks = targetClip.tracks.length; 34062 var referenceTime = referenceFrame / fps; 34063 34064 // Make each track's values relative to the values at the reference frame 34065 for ( var i = 0; i < numTracks; ++ i ) { 34066 34067 var referenceTrack = referenceClip.tracks[ i ]; 34068 var referenceTrackType = referenceTrack.ValueTypeName; 34069 34070 // Skip this track if it's non-numeric 34071 if ( referenceTrackType === 'bool' || referenceTrackType === 'string' ) continue; 34072 34073 // Find the track in the target clip whose name and type matches the reference track 34074 var targetTrack = targetClip.tracks.find( function ( track ) { 34075 34076 return track.name === referenceTrack.name 34077 && track.ValueTypeName === referenceTrackType; 34078 34079 } ); 34080 34081 if ( targetTrack === undefined ) continue; 34082 34083 var valueSize = referenceTrack.getValueSize(); 34084 var lastIndex = referenceTrack.times.length - 1; 34085 var referenceValue; 34086 34087 // Find the value to subtract out of the track 34088 if ( referenceTime <= referenceTrack.times[ 0 ] ) { 34089 34090 // Reference frame is earlier than the first keyframe, so just use the first keyframe 34091 referenceValue = AnimationUtils.arraySlice( referenceTrack.values, 0, referenceTrack.valueSize ); 34092 34093 } else if ( referenceTime >= referenceTrack.times[ lastIndex ] ) { 34094 34095 // Reference frame is after the last keyframe, so just use the last keyframe 34096 var startIndex = lastIndex * valueSize; 34097 referenceValue = AnimationUtils.arraySlice( referenceTrack.values, startIndex ); 34098 34099 } else { 34100 34101 // Interpolate to the reference value 34102 var interpolant = referenceTrack.createInterpolant(); 34103 interpolant.evaluate( referenceTime ); 34104 referenceValue = interpolant.resultBuffer; 34105 34106 } 34107 34108 // Conjugate the quaternion 34109 if ( referenceTrackType === 'quaternion' ) { 34110 34111 var referenceQuat = new Quaternion( 34112 referenceValue[ 0 ], 34113 referenceValue[ 1 ],
34114 referenceValue[ 2 ], 34115 referenceValue[ 3 ] 34116 ).normalize().conjugate(); 34117 referenceQuat.toArray( referenceValue ); 34118 34119 } 34120 34121 // Subtract the reference value from all of the track values 34122 34123 var numTimes = targetTrack.times.length; 34124 for ( var j = 0; j < numTimes; ++ j ) { 34125 34126 var valueStart = j * valueSize; 34127 34128 if ( referenceTrackType === 'quaternion' ) { 34129 34130 // Multiply the conjugate for quaternion track types 34131 Quaternion.multiplyQuaternionsFlat( 34132 targetTrack.values, 34133 valueStart, 34134 referenceValue, 34135 0, 34136 targetTrack.values, 34137 valueStart 34138 ); 34139 34140 } else { 34141 34142 // Subtract each value for all other numeric track types 34143 for ( var k = 0; k < valueSize; ++ k ) { 34144 34145 targetTrack.values[ valueStart + k ] -= referenceValue[ k ]; 34146 34147 } 34148 34149 } 34150 34151 } 34152 34153 } 34154 34155 targetClip.blendMode = AdditiveAnimationBlendMode; 34156 34157 return targetClip; 34158 34159 } 34160 34161}; 34162 34163/** 34164 * Abstract base class of interpolants over parametric samples. 34165 * 34166 * The parameter domain is one dimensional, typically the time or a path 34167 * along a curve defined by the data. 34168 * 34169 * The sample values can have any dimensionality and derived classes may 34170 * apply special interpretations to the data. 34171 * 34172 * This class provides the interval seek in a Template Method, deferring 34173 * the actual interpolation to derived classes. 34174 * 34175 * Time complexity is O(1) for linear access crossing at most two points 34176 * and O(log N) for random access, where N is the number of positions. 34177 * 34178 * References: 34179 * 34180 * http://www.oodesign.com/template-method-pattern.html 34181 * 34182 * @author tschw 34183 */ 34184 34185function Interpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { 34186 34187 this.parameterPositions = parameterPositions; 34188 this._cachedIndex = 0; 34189 34190 this.resultBuffer = resultBuffer !== undefined ? 34191 resultBuffer : new sampleValues.constructor( sampleSize ); 34192 this.sampleValues = sampleValues; 34193 this.valueSize = sampleSize; 34194 34195} 34196 34197Object.assign( Interpolant.prototype, { 34198 34199 evaluate: function ( t ) { 34200 34201 var pp = this.parameterPositions, 34202 i1 = this._cachedIndex, 34203 34204 t1 = pp[ i1 ], 34205 t0 = pp[ i1 - 1 ]; 34206 34207 validate_interval: { 34208 34209 seek: { 34210 34211 var right; 34212 34213 linear_scan: { 34214
vendor: 48,911 bytes, lines 34215-36813
34215 //- See http://jsperf.com/comparison-to-undefined/3 34216 //- slower code: 34217 //- 34218 //- if ( t >= t1 || t1 === undefined ) { 34219 forward_scan: if ( ! ( t < t1 ) ) { 34220 34221 for ( var giveUpAt = i1 + 2; ; ) { 34222 34223 if ( t1 === undefined ) { 34224 34225 if ( t < t0 ) break forward_scan; 34226 34227 // after end 34228 34229 i1 = pp.length; 34230 this._cachedIndex = i1; 34231 return this.afterEnd_( i1 - 1, t, t0 ); 34232 34233 } 34234 34235 if ( i1 === giveUpAt ) break; // this loop 34236 34237 t0 = t1; 34238 t1 = pp[ ++ i1 ]; 34239 34240 if ( t < t1 ) { 34241 34242 // we have arrived at the sought interval 34243 break seek; 34244 34245 } 34246 34247 } 34248 34249 // prepare binary search on the right side of the index 34250 right = pp.length; 34251 break linear_scan; 34252 34253 } 34254 34255 //- slower code: 34256 //- if ( t < t0 || t0 === undefined ) { 34257 if ( ! ( t >= t0 ) ) { 34258 34259 // looping? 34260 34261 var t1global = pp[ 1 ]; 34262 34263 if ( t < t1global ) { 34264 34265 i1 = 2; // + 1, using the scan for the details 34266 t0 = t1global; 34267 34268 } 34269 34270 // linear reverse scan 34271 34272 for ( var giveUpAt = i1 - 2; ; ) { 34273 34274 if ( t0 === undefined ) { 34275 34276 // before start 34277 34278 this._cachedIndex = 0; 34279 return this.beforeStart_( 0, t, t1 ); 34280 34281 } 34282 34283 if ( i1 === giveUpAt ) break; // this loop 34284 34285 t1 = t0; 34286 t0 = pp[ -- i1 - 1 ]; 34287 34288 if ( t >= t0 ) { 34289 34290 // we have arrived at the sought interval 34291 break seek; 34292 34293 } 34294 34295 } 34296 34297 // prepare binary search on the left side of the index 34298 right = i1; 34299 i1 = 0; 34300 break linear_scan; 34301 34302 } 34303 34304 // the interval is valid 34305 34306 break validate_interval; 34307 34308 } // linear scan 34309 34310 // binary search 34311 34312 while ( i1 < right ) { 34313 34314 var mid = ( i1 + right ) >>> 1; 34315 34316 if ( t < pp[ mid ] ) { 34317 34318 right = mid; 34319 34320 } else { 34321 34322 i1 = mid + 1; 34323 34324 } 34325 34326 } 34327 34328 t1 = pp[ i1 ]; 34329 t0 = pp[ i1 - 1 ]; 34330 34331 // check boundary cases, again 34332 34333 if ( t0 === undefined ) { 34334 34335 this._cachedIndex = 0; 34336 return this.beforeStart_( 0, t, t1 ); 34337 34338 } 34339 34340 if ( t1 === undefined ) { 34341 34342 i1 = pp.length; 34343 this._cachedIndex = i1; 34344 return this.afterEnd_( i1 - 1, t0, t ); 34345 34346 } 34347 34348 } // seek 34349 34350 this._cachedIndex = i1; 34351 34352 this.intervalChanged_( i1, t0, t1 ); 34353 34354 } // validate_interval 34355 34356 return this.interpolate_( i1, t0, t, t1 ); 34357 34358 }, 34359 34360 settings: null, // optional, subclass-specific settings structure 34361 // Note: The indirection allows central control of many interpolants. 34362 34363 // --- Protected interface 34364 34365 DefaultSettings_: {}, 34366 34367 getSettings_: function () { 34368 34369 return this.settings || this.DefaultSettings_; 34370 34371 }, 34372 34373 copySampleValue_: function ( index ) { 34374 34375 // copies a sample value to the result buffer 34376 34377 var result = this.resultBuffer, 34378 values = this.sampleValues, 34379 stride = this.valueSize, 34380 offset = index * stride; 34381 34382 for ( var i = 0; i !== stride; ++ i ) { 34383 34384 result[ i ] = values[ offset + i ]; 34385 34386 } 34387 34388 return result; 34389 34390 }, 34391 34392 // Template methods for derived classes: 34393 34394 interpolate_: function ( /* i1, t0, t, t1 */ ) { 34395 34396 throw new Error( 'call to abstract method' ); 34397 // implementations shall return this.resultBuffer 34398 34399 }, 34400 34401 intervalChanged_: function ( /* i1, t0, t1 */ ) { 34402 34403 // empty 34404 34405 } 34406 34407} ); 34408 34409// DECLARE ALIAS AFTER assign prototype 34410Object.assign( Interpolant.prototype, { 34411 34412 //( 0, t, t0 ), returns this.resultBuffer 34413 beforeStart_: Interpolant.prototype.copySampleValue_, 34414 34415 //( N-1, tN-1, t ), returns this.resultBuffer 34416 afterEnd_: Interpolant.prototype.copySampleValue_, 34417 34418} ); 34419 34420/** 34421 * Fast and simple cubic spline interpolant. 34422 * 34423 * It was derived from a Hermitian construction setting the first derivative 34424 * at each sample position to the linear slope between neighboring positions 34425 * over their parameter interval. 34426 * 34427 * @author tschw 34428 */ 34429 34430function CubicInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { 34431 34432 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); 34433 34434 this._weightPrev = - 0; 34435 this._offsetPrev = - 0; 34436 this._weightNext = - 0; 34437 this._offsetNext = - 0; 34438 34439} 34440 34441CubicInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { 34442 34443 constructor: CubicInterpolant, 34444 34445 DefaultSettings_: { 34446 34447 endingStart: ZeroCurvatureEnding, 34448 endingEnd: ZeroCurvatureEnding 34449 34450 }, 34451 34452 intervalChanged_: function ( i1, t0, t1 ) { 34453 34454 var pp = this.parameterPositions, 34455 iPrev = i1 - 2, 34456 iNext = i1 + 1, 34457 34458 tPrev = pp[ iPrev ], 34459 tNext = pp[ iNext ]; 34460 34461 if ( tPrev === undefined ) { 34462 34463 switch ( this.getSettings_().endingStart ) { 34464 34465 case ZeroSlopeEnding: 34466 34467 // f'(t0) = 0 34468 iPrev = i1; 34469 tPrev = 2 * t0 - t1; 34470 34471 break; 34472 34473 case WrapAroundEnding: 34474 34475 // use the other end of the curve 34476 iPrev = pp.length - 2; 34477 tPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ]; 34478 34479 break; 34480 34481 default: // ZeroCurvatureEnding 34482 34483 // f''(t0) = 0 a.k.a. Natural Spline 34484 iPrev = i1; 34485 tPrev = t1; 34486 34487 } 34488 34489 } 34490 34491 if ( tNext === undefined ) { 34492 34493 switch ( this.getSettings_().endingEnd ) { 34494 34495 case ZeroSlopeEnding: 34496 34497 // f'(tN) = 0 34498 iNext = i1; 34499 tNext = 2 * t1 - t0; 34500 34501 break; 34502 34503 case WrapAroundEnding: 34504 34505 // use the other end of the curve 34506 iNext = 1; 34507 tNext = t1 + pp[ 1 ] - pp[ 0 ]; 34508 34509 break; 34510 34511 default: // ZeroCurvatureEnding 34512 34513 // f''(tN) = 0, a.k.a. Natural Spline 34514 iNext = i1 - 1; 34515 tNext = t0; 34516 34517 } 34518 34519 } 34520 34521 var halfDt = ( t1 - t0 ) * 0.5, 34522 stride = this.valueSize; 34523 34524 this._weightPrev = halfDt / ( t0 - tPrev ); 34525 this._weightNext = halfDt / ( tNext - t1 ); 34526 this._offsetPrev = iPrev * stride; 34527 this._offsetNext = iNext * stride; 34528 34529 }, 34530 34531 interpolate_: function ( i1, t0, t, t1 ) { 34532 34533 var result = this.resultBuffer, 34534 values = this.sampleValues, 34535 stride = this.valueSize, 34536 34537 o1 = i1 * stride, o0 = o1 - stride, 34538 oP = this._offsetPrev, oN = this._offsetNext, 34539 wP = this._weightPrev, wN = this._weightNext, 34540 34541 p = ( t - t0 ) / ( t1 - t0 ), 34542 pp = p * p, 34543 ppp = pp * p; 34544 34545 // evaluate polynomials 34546 34547 var sP = - wP * ppp + 2 * wP * pp - wP * p; 34548 var s0 = ( 1 + wP ) * ppp + ( - 1.5 - 2 * wP ) * pp + ( - 0.5 + wP ) * p + 1; 34549 var s1 = ( - 1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p; 34550 var sN = wN * ppp - wN * pp; 34551 34552 // combine data linearly 34553 34554 for ( var i = 0; i !== stride; ++ i ) { 34555 34556 result[ i ] = 34557 sP * values[ oP + i ] + 34558 s0 * values[ o0 + i ] + 34559 s1 * values[ o1 + i ] + 34560 sN * values[ oN + i ]; 34561 34562 } 34563 34564 return result; 34565 34566 } 34567 34568} ); 34569 34570/** 34571 * @author tschw 34572 */ 34573 34574function LinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { 34575 34576 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); 34577 34578} 34579 34580LinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { 34581 34582 constructor: LinearInterpolant, 34583 34584 interpolate_: function ( i1, t0, t, t1 ) { 34585 34586 var result = this.resultBuffer, 34587 values = this.sampleValues, 34588 stride = this.valueSize, 34589 34590 offset1 = i1 * stride, 34591 offset0 = offset1 - stride, 34592 34593 weight1 = ( t - t0 ) / ( t1 - t0 ), 34594 weight0 = 1 - weight1; 34595 34596 for ( var i = 0; i !== stride; ++ i ) { 34597 34598 result[ i ] = 34599 values[ offset0 + i ] * weight0 + 34600 values[ offset1 + i ] * weight1; 34601 34602 } 34603 34604 return result; 34605 34606 } 34607 34608} ); 34609 34610/** 34611 * 34612 * Interpolant that evaluates to the sample value at the position preceeding 34613 * the parameter. 34614 * 34615 * @author tschw 34616 */ 34617 34618function DiscreteInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { 34619 34620 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); 34621 34622} 34623 34624DiscreteInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { 34625 34626 constructor: DiscreteInterpolant, 34627 34628 interpolate_: function ( i1 /*, t0, t, t1 */ ) { 34629 34630 return this.copySampleValue_( i1 - 1 ); 34631 34632 } 34633 34634} ); 34635 34636/** 34637 * 34638 * A timed sequence of keyframes for a specific property. 34639 * 34640 * 34641 * @author Ben Houston / http://clara.io/ 34642 * @author David Sarno / http://lighthaus.us/ 34643 * @author tschw 34644 */ 34645 34646function KeyframeTrack( name, times, values, interpolation ) { 34647 34648 if ( name === undefined ) throw new Error( 'THREE.KeyframeTrack: track name is undefined' ); 34649 if ( times === undefined || times.length === 0 ) throw new Error( 'THREE.KeyframeTrack: no keyframes in track named ' + name ); 34650 34651 this.name = name; 34652 34653 this.times = AnimationUtils.convertArray( times, this.TimeBufferType ); 34654 this.values = AnimationUtils.convertArray( values, this.ValueBufferType ); 34655 34656 this.setInterpolation( interpolation || this.DefaultInterpolation ); 34657 34658} 34659 34660// Static methods 34661 34662Object.assign( KeyframeTrack, { 34663 34664 // Serialization (in static context, because of constructor invocation 34665 // and automatic invocation of .toJSON): 34666 34667 toJSON: function ( track ) { 34668 34669 var trackType = track.constructor; 34670 34671 var json; 34672 34673 // derived classes can define a static toJSON method 34674 if ( trackType.toJSON !== undefined ) { 34675 34676 json = trackType.toJSON( track ); 34677 34678 } else { 34679 34680 // by default, we assume the data can be serialized as-is 34681 json = { 34682 34683 'name': track.name, 34684 'times': AnimationUtils.convertArray( track.times, Array ), 34685 'values': AnimationUtils.convertArray( track.values, Array ) 34686 34687 }; 34688 34689 var interpolation = track.getInterpolation(); 34690 34691 if ( interpolation !== track.DefaultInterpolation ) { 34692 34693 json.interpolation = interpolation; 34694 34695 } 34696 34697 } 34698 34699 json.type = track.ValueTypeName; // mandatory 34700 34701 return json; 34702 34703 } 34704 34705} ); 34706 34707Object.assign( KeyframeTrack.prototype, { 34708 34709 constructor: KeyframeTrack, 34710 34711 TimeBufferType: Float32Array, 34712 34713 ValueBufferType: Float32Array, 34714 34715 DefaultInterpolation: InterpolateLinear, 34716 34717 InterpolantFactoryMethodDiscrete: function ( result ) { 34718 34719 return new DiscreteInterpolant( this.times, this.values, this.getValueSize(), result ); 34720 34721 }, 34722 34723 InterpolantFactoryMethodLinear: function ( result ) { 34724 34725 return new LinearInterpolant( this.times, this.values, this.getValueSize(), result ); 34726 34727 }, 34728 34729 InterpolantFactoryMethodSmooth: function ( result ) { 34730 34731 return new CubicInterpolant( this.times, this.values, this.getValueSize(), result ); 34732 34733 }, 34734 34735 setInterpolation: function ( interpolation ) { 34736 34737 var factoryMethod; 34738 34739 switch ( interpolation ) { 34740 34741 case InterpolateDiscrete: 34742 34743 factoryMethod = this.InterpolantFactoryMethodDiscrete; 34744 34745 break; 34746 34747 case InterpolateLinear: 34748 34749 factoryMethod = this.InterpolantFactoryMethodLinear; 34750 34751 break; 34752 34753 case InterpolateSmooth: 34754 34755 factoryMethod = this.InterpolantFactoryMethodSmooth; 34756 34757 break; 34758 34759 } 34760 34761 if ( factoryMethod === undefined ) { 34762 34763 var message = "unsupported interpolation for " + 34764 this.ValueTypeName + " keyframe track named " + this.name; 34765 34766 if ( this.createInterpolant === undefined ) { 34767 34768 // fall back to default, unless the default itself is messed up 34769 if ( interpolation !== this.DefaultInterpolation ) { 34770 34771 this.setInterpolation( this.DefaultInterpolation ); 34772 34773 } else { 34774 34775 throw new Error( message ); // fatal, in this case 34776 34777 } 34778 34779 } 34780 34781 console.warn( 'THREE.KeyframeTrack:', message ); 34782 return this; 34783 34784 } 34785 34786 this.createInterpolant = factoryMethod; 34787 34788 return this; 34789 34790 }, 34791 34792 getInterpolation: function () { 34793 34794 switch ( this.createInterpolant ) { 34795 34796 case this.InterpolantFactoryMethodDiscrete: 34797 34798 return InterpolateDiscrete; 34799 34800 case this.InterpolantFactoryMethodLinear: 34801 34802 return InterpolateLinear; 34803 34804 case this.InterpolantFactoryMethodSmooth: 34805 34806 return InterpolateSmooth; 34807 34808 } 34809 34810 }, 34811 34812 getValueSize: function () { 34813 34814 return this.values.length / this.times.length; 34815 34816 }, 34817 34818 // move all keyframes either forwards or backwards in time 34819 shift: function ( timeOffset ) { 34820 34821 if ( timeOffset !== 0.0 ) { 34822 34823 var times = this.times; 34824 34825 for ( var i = 0, n = times.length; i !== n; ++ i ) { 34826 34827 times[ i ] += timeOffset; 34828 34829 } 34830 34831 } 34832 34833 return this; 34834 34835 }, 34836 34837 // scale all keyframe times by a factor (useful for frame <-> seconds conversions) 34838 scale: function ( timeScale ) { 34839 34840 if ( timeScale !== 1.0 ) { 34841 34842 var times = this.times; 34843 34844 for ( var i = 0, n = times.length; i !== n; ++ i ) { 34845 34846 times[ i ] *= timeScale; 34847 34848 } 34849 34850 } 34851 34852 return this; 34853 34854 }, 34855 34856 // removes keyframes before and after animation without changing any values within the range [startTime, endTime]. 34857 // IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values 34858 trim: function ( startTime, endTime ) { 34859 34860 var times = this.times, 34861 nKeys = times.length, 34862 from = 0, 34863 to = nKeys - 1; 34864 34865 while ( from !== nKeys && times[ from ] < startTime ) { 34866 34867 ++ from; 34868 34869 } 34870 34871 while ( to !== - 1 && times[ to ] > endTime ) { 34872 34873 -- to; 34874 34875 } 34876 34877 ++ to; // inclusive -> exclusive bound 34878 34879 if ( from !== 0 || to !== nKeys ) { 34880 34881 // empty tracks are forbidden, so keep at least one keyframe 34882 if ( from >= to ) { 34883 34884 to = Math.max( to, 1 ); 34885 from = to - 1; 34886 34887 } 34888 34889 var stride = this.getValueSize(); 34890 this.times = AnimationUtils.arraySlice( times, from, to ); 34891 this.values = AnimationUtils.arraySlice( this.values, from * stride, to * stride ); 34892 34893 } 34894 34895 return this; 34896 34897 }, 34898 34899 // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable 34900 validate: function () { 34901 34902 var valid = true; 34903 34904 var valueSize = this.getValueSize(); 34905 if ( valueSize - Math.floor( valueSize ) !== 0 ) { 34906 34907 console.error( 'THREE.KeyframeTrack: Invalid value size in track.', this ); 34908 valid = false; 34909 34910 } 34911 34912 var times = this.times, 34913 values = this.values, 34914 34915 nKeys = times.length; 34916 34917 if ( nKeys === 0 ) { 34918 34919 console.error( 'THREE.KeyframeTrack: Track is empty.', this ); 34920 valid = false; 34921 34922 } 34923 34924 var prevTime = null; 34925 34926 for ( var i = 0; i !== nKeys; i ++ ) { 34927 34928 var currTime = times[ i ]; 34929 34930 if ( typeof currTime === 'number' && isNaN( currTime ) ) { 34931 34932 console.error( 'THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime ); 34933 valid = false; 34934 break; 34935 34936 } 34937 34938 if ( prevTime !== null && prevTime > currTime ) { 34939 34940 console.error( 'THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime ); 34941 valid = false; 34942 break; 34943 34944 } 34945 34946 prevTime = currTime; 34947 34948 } 34949 34950 if ( values !== undefined ) { 34951 34952 if ( AnimationUtils.isTypedArray( values ) ) { 34953 34954 for ( var i = 0, n = values.length; i !== n; ++ i ) { 34955 34956 var value = values[ i ]; 34957 34958 if ( isNaN( value ) ) { 34959 34960 console.error( 'THREE.KeyframeTrack: Value is not a valid number.', this, i, value ); 34961 valid = false; 34962 break; 34963 34964 } 34965 34966 } 34967 34968 } 34969 34970 } 34971 34972 return valid; 34973 34974 }, 34975 34976 // removes equivalent sequential keys as common in morph target sequences 34977 // (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0) 34978 optimize: function () { 34979 34980 // times or values may be shared with other tracks, so overwriting is unsafe 34981 var times = AnimationUtils.arraySlice( this.times ), 34982 values = AnimationUtils.arraySlice( this.values ), 34983 stride = this.getValueSize(), 34984 34985 smoothInterpolation = this.getInterpolation() === InterpolateSmooth, 34986 34987 writeIndex = 1, 34988 lastIndex = times.length - 1; 34989 34990 for ( var i = 1; i < lastIndex; ++ i ) { 34991 34992 var keep = false; 34993 34994 var time = times[ i ]; 34995 var timeNext = times[ i + 1 ]; 34996 34997 // remove adjacent keyframes scheduled at the same time 34998 34999 if ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) { 35000 35001 if ( ! smoothInterpolation ) { 35002 35003 // remove unnecessary keyframes same as their neighbors 35004 35005 var offset = i * stride, 35006 offsetP = offset - stride, 35007 offsetN = offset + stride; 35008 35009 for ( var j = 0; j !== stride; ++ j ) { 35010 35011 var value = values[ offset + j ]; 35012 35013 if ( value !== values[ offsetP + j ] || 35014 value !== values[ offsetN + j ] ) { 35015 35016 keep = true; 35017 break; 35018 35019 } 35020 35021 } 35022 35023 } else { 35024 35025 keep = true; 35026 35027 } 35028 35029 } 35030 35031 // in-place compaction 35032 35033 if ( keep ) { 35034 35035 if ( i !== writeIndex ) { 35036 35037 times[ writeIndex ] = times[ i ]; 35038 35039 var readOffset = i * stride, 35040 writeOffset = writeIndex * stride; 35041 35042 for ( var j = 0; j !== stride; ++ j ) { 35043 35044 values[ writeOffset + j ] = values[ readOffset + j ]; 35045 35046 } 35047 35048 } 35049 35050 ++ writeIndex; 35051 35052 } 35053 35054 } 35055 35056 // flush last keyframe (compaction looks ahead) 35057 35058 if ( lastIndex > 0 ) { 35059 35060 times[ writeIndex ] = times[ lastIndex ]; 35061 35062 for ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j ) { 35063 35064 values[ writeOffset + j ] = values[ readOffset + j ]; 35065 35066 } 35067 35068 ++ writeIndex; 35069 35070 } 35071 35072 if ( writeIndex !== times.length ) { 35073 35074 this.times = AnimationUtils.arraySlice( times, 0, writeIndex ); 35075 this.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride ); 35076 35077 } else { 35078 35079 this.times = times; 35080 this.values = values; 35081 35082 } 35083 35084 return this; 35085 35086 }, 35087 35088 clone: function () { 35089 35090 var times = AnimationUtils.arraySlice( this.times, 0 ); 35091 var values = AnimationUtils.arraySlice( this.values, 0 ); 35092 35093 var TypedKeyframeTrack = this.constructor; 35094 var track = new TypedKeyframeTrack( this.name, times, values ); 35095 35096 // Interpolant argument to constructor is not saved, so copy the factory method directly. 35097 track.createInterpolant = this.createInterpolant; 35098 35099 return track; 35100 35101 } 35102 35103} ); 35104 35105/** 35106 * 35107 * A Track of Boolean keyframe values. 35108 * 35109 * 35110 * @author Ben Houston / http://clara.io/ 35111 * @author David Sarno / http://lighthaus.us/ 35112 * @author tschw 35113 */ 35114 35115function BooleanKeyframeTrack( name, times, values ) { 35116 35117 KeyframeTrack.call( this, name, times, values ); 35118 35119} 35120 35121BooleanKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { 35122 35123 constructor: BooleanKeyframeTrack, 35124 35125 ValueTypeName: 'bool', 35126 ValueBufferType: Array, 35127 35128 DefaultInterpolation: InterpolateDiscrete, 35129 35130 InterpolantFactoryMethodLinear: undefined, 35131 InterpolantFactoryMethodSmooth: undefined 35132 35133 // Note: Actually this track could have a optimized / compressed 35134 // representation of a single value and a custom interpolant that 35135 // computes "firstValue ^ isOdd( index )". 35136 35137} ); 35138 35139/** 35140 * 35141 * A Track of keyframe values that represent color. 35142 * 35143 * 35144 * @author Ben Houston / http://clara.io/ 35145 * @author David Sarno / http://lighthaus.us/ 35146 * @author tschw 35147 */ 35148 35149function ColorKeyframeTrack( name, times, values, interpolation ) { 35150 35151 KeyframeTrack.call( this, name, times, values, interpolation ); 35152 35153} 35154 35155ColorKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { 35156 35157 constructor: ColorKeyframeTrack, 35158 35159 ValueTypeName: 'color' 35160 35161 // ValueBufferType is inherited 35162 35163 // DefaultInterpolation is inherited 35164 35165 // Note: Very basic implementation and nothing special yet. 35166 // However, this is the place for color space parameterization. 35167 35168} ); 35169 35170/** 35171 * 35172 * A Track of numeric keyframe values. 35173 * 35174 * @author Ben Houston / http://clara.io/ 35175 * @author David Sarno / http://lighthaus.us/ 35176 * @author tschw 35177 */ 35178 35179function NumberKeyframeTrack( name, times, values, interpolation ) { 35180 35181 KeyframeTrack.call( this, name, times, values, interpolation ); 35182 35183} 35184 35185NumberKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { 35186 35187 constructor: NumberKeyframeTrack, 35188 35189 ValueTypeName: 'number' 35190 35191 // ValueBufferType is inherited 35192 35193 // DefaultInterpolation is inherited 35194 35195} ); 35196 35197/** 35198 * Spherical linear unit quaternion interpolant. 35199 * 35200 * @author tschw 35201 */ 35202 35203function QuaternionLinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { 35204 35205 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); 35206 35207} 35208 35209QuaternionLinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { 35210 35211 constructor: QuaternionLinearInterpolant, 35212 35213 interpolate_: function ( i1, t0, t, t1 ) { 35214 35215 var result = this.resultBuffer, 35216 values = this.sampleValues, 35217 stride = this.valueSize, 35218 35219 offset = i1 * stride, 35220 35221 alpha = ( t - t0 ) / ( t1 - t0 ); 35222 35223 for ( var end = offset + stride; offset !== end; offset += 4 ) { 35224 35225 Quaternion.slerpFlat( result, 0, values, offset - stride, values, offset, alpha ); 35226 35227 } 35228 35229 return result; 35230 35231 } 35232 35233} ); 35234 35235/** 35236 * 35237 * A Track of quaternion keyframe values. 35238 * 35239 * @author Ben Houston / http://clara.io/ 35240 * @author David Sarno / http://lighthaus.us/ 35241 * @author tschw 35242 */ 35243 35244function QuaternionKeyframeTrack( name, times, values, interpolation ) { 35245 35246 KeyframeTrack.call( this, name, times, values, interpolation ); 35247 35248} 35249 35250QuaternionKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { 35251 35252 constructor: QuaternionKeyframeTrack, 35253 35254 ValueTypeName: 'quaternion', 35255 35256 // ValueBufferType is inherited 35257 35258 DefaultInterpolation: InterpolateLinear, 35259 35260 InterpolantFactoryMethodLinear: function ( result ) { 35261 35262 return new QuaternionLinearInterpolant( this.times, this.values, this.getValueSize(), result ); 35263 35264 }, 35265 35266 InterpolantFactoryMethodSmooth: undefined // not yet implemented 35267 35268} ); 35269 35270/** 35271 * 35272 * A Track that interpolates Strings 35273 * 35274 * 35275 * @author Ben Houston / http://clara.io/ 35276 * @author David Sarno / http://lighthaus.us/ 35277 * @author tschw 35278 */ 35279 35280function StringKeyframeTrack( name, times, values, interpolation ) { 35281 35282 KeyframeTrack.call( this, name, times, values, interpolation ); 35283 35284} 35285 35286StringKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { 35287 35288 constructor: StringKeyframeTrack, 35289 35290 ValueTypeName: 'string', 35291 ValueBufferType: Array, 35292 35293 DefaultInterpolation: InterpolateDiscrete, 35294 35295 InterpolantFactoryMethodLinear: undefined, 35296 35297 InterpolantFactoryMethodSmooth: undefined 35298 35299} ); 35300 35301/** 35302 * 35303 * A Track of vectored keyframe values. 35304 * 35305 * 35306 * @author Ben Houston / http://clara.io/ 35307 * @author David Sarno / http://lighthaus.us/ 35308 * @author tschw 35309 */ 35310 35311function VectorKeyframeTrack( name, times, values, interpolation ) { 35312 35313 KeyframeTrack.call( this, name, times, values, interpolation ); 35314 35315} 35316 35317VectorKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { 35318 35319 constructor: VectorKeyframeTrack, 35320 35321 ValueTypeName: 'vector' 35322 35323 // ValueBufferType is inherited 35324 35325 // DefaultInterpolation is inherited 35326 35327} ); 35328 35329/** 35330 * 35331 * Reusable set of Tracks that represent an animation. 35332 * 35333 * @author Ben Houston / http://clara.io/ 35334 * @author David Sarno / http://lighthaus.us/ 35335 */ 35336 35337function AnimationClip( name, duration, tracks, blendMode ) { 35338 35339 this.name = name; 35340 this.tracks = tracks; 35341 this.duration = ( duration !== undefined ) ? duration : - 1; 35342 this.blendMode = ( blendMode !== undefined ) ? blendMode : NormalAnimationBlendMode; 35343 35344 this.uuid = MathUtils.generateUUID(); 35345 35346 // this means it should figure out its duration by scanning the tracks 35347 if ( this.duration < 0 ) { 35348 35349 this.resetDuration(); 35350 35351 } 35352 35353} 35354 35355function getTrackTypeForValueTypeName( typeName ) { 35356 35357 switch ( typeName.toLowerCase() ) { 35358 35359 case 'scalar': 35360 case 'double': 35361 case 'float': 35362 case 'number': 35363 case 'integer': 35364 35365 return NumberKeyframeTrack; 35366 35367 case 'vector': 35368 case 'vector2': 35369 case 'vector3': 35370 case 'vector4': 35371 35372 return VectorKeyframeTrack; 35373 35374 case 'color': 35375 35376 return ColorKeyframeTrack; 35377 35378 case 'quaternion': 35379 35380 return QuaternionKeyframeTrack; 35381 35382 case 'bool': 35383 case 'boolean': 35384 35385 return BooleanKeyframeTrack; 35386 35387 case 'string': 35388 35389 return StringKeyframeTrack; 35390 35391 } 35392 35393 throw new Error( 'THREE.KeyframeTrack: Unsupported typeName: ' + typeName ); 35394 35395} 35396 35397function parseKeyframeTrack( json ) { 35398 35399 if ( json.type === undefined ) { 35400 35401 throw new Error( 'THREE.KeyframeTrack: track type undefined, can not parse' ); 35402 35403 } 35404 35405 var trackType = getTrackTypeForValueTypeName( json.type ); 35406 35407 if ( json.times === undefined ) { 35408 35409 var times = [], values = []; 35410 35411 AnimationUtils.flattenJSON( json.keys, times, values, 'value' ); 35412 35413 json.times = times; 35414 json.values = values; 35415 35416 } 35417 35418 // derived classes can define a static parse method 35419 if ( trackType.parse !== undefined ) { 35420 35421 return trackType.parse( json ); 35422 35423 } else { 35424 35425 // by default, we assume a constructor compatible with the base 35426 return new trackType( json.name, json.times, json.values, json.interpolation ); 35427 35428 } 35429 35430} 35431 35432Object.assign( AnimationClip, { 35433 35434 parse: function ( json ) { 35435 35436 var tracks = [], 35437 jsonTracks = json.tracks, 35438 frameTime = 1.0 / ( json.fps || 1.0 ); 35439 35440 for ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) { 35441 35442 tracks.push( parseKeyframeTrack( jsonTracks[ i ] ).scale( frameTime ) ); 35443 35444 } 35445 35446 return new AnimationClip( json.name, json.duration, tracks, json.blendMode ); 35447 35448 }, 35449 35450 toJSON: function ( clip ) { 35451 35452 var tracks = [], 35453 clipTracks = clip.tracks; 35454 35455 var json = { 35456 35457 'name': clip.name, 35458 'duration': clip.duration, 35459 'tracks': tracks, 35460 'uuid': clip.uuid, 35461 'blendMode': clip.blendMode 35462 35463 }; 35464 35465 for ( var i = 0, n = clipTracks.length; i !== n; ++ i ) { 35466 35467 tracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) ); 35468 35469 } 35470 35471 return json; 35472 35473 }, 35474 35475 CreateFromMorphTargetSequence: function ( name, morphTargetSequence, fps, noLoop ) { 35476 35477 var numMorphTargets = morphTargetSequence.length; 35478 var tracks = []; 35479 35480 for ( var i = 0; i < numMorphTargets; i ++ ) { 35481 35482 var times = []; 35483 var values = []; 35484 35485 times.push( 35486 ( i + numMorphTargets - 1 ) % numMorphTargets, 35487 i, 35488 ( i + 1 ) % numMorphTargets ); 35489 35490 values.push( 0, 1, 0 ); 35491 35492 var order = AnimationUtils.getKeyframeOrder( times ); 35493 times = AnimationUtils.sortedArray( times, 1, order ); 35494 values = AnimationUtils.sortedArray( values, 1, order ); 35495 35496 // if there is a key at the first frame, duplicate it as the 35497 // last frame as well for perfect loop. 35498 if ( ! noLoop && times[ 0 ] === 0 ) { 35499 35500 times.push( numMorphTargets ); 35501 values.push( values[ 0 ] ); 35502 35503 } 35504 35505 tracks.push( 35506 new NumberKeyframeTrack( 35507 '.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']', 35508 times, values 35509 ).scale( 1.0 / fps ) ); 35510 35511 } 35512 35513 return new AnimationClip( name, - 1, tracks ); 35514 35515 }, 35516 35517 findByName: function ( objectOrClipArray, name ) { 35518 35519 var clipArray = objectOrClipArray; 35520 35521 if ( ! Array.isArray( objectOrClipArray ) ) { 35522 35523 var o = objectOrClipArray; 35524 clipArray = o.geometry && o.geometry.animations || o.animations; 35525 35526 } 35527 35528 for ( var i = 0; i < clipArray.length; i ++ ) { 35529 35530 if ( clipArray[ i ].name === name ) { 35531 35532 return clipArray[ i ]; 35533 35534 } 35535 35536 } 35537 35538 return null; 35539 35540 }, 35541 35542 CreateClipsFromMorphTargetSequences: function ( morphTargets, fps, noLoop ) { 35543 35544 var animationToMorphTargets = {}; 35545 35546 // tested with https://regex101.com/ on trick sequences 35547 // such flamingo_flyA_003, flamingo_run1_003, crdeath0059 35548 var pattern = /^([\w-]*?)([\d]+)$/; 35549 35550 // sort morph target names into animation groups based 35551 // patterns like Walk_001, Walk_002, Run_001, Run_002 35552 for ( var i = 0, il = morphTargets.length; i < il; i ++ ) { 35553 35554 var morphTarget = morphTargets[ i ]; 35555 var parts = morphTarget.name.match( pattern ); 35556 35557 if ( parts && parts.length > 1 ) { 35558 35559 var name = parts[ 1 ]; 35560 35561 var animationMorphTargets = animationToMorphTargets[ name ]; 35562 if ( ! animationMorphTargets ) { 35563 35564 animationToMorphTargets[ name ] = animationMorphTargets = []; 35565 35566 } 35567 35568 animationMorphTargets.push( morphTarget ); 35569 35570 } 35571 35572 } 35573 35574 var clips = []; 35575 35576 for ( var name in animationToMorphTargets ) { 35577 35578 clips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) ); 35579 35580 } 35581 35582 return clips; 35583 35584 }, 35585 35586 // parse the animation.hierarchy format 35587 parseAnimation: function ( animation, bones ) { 35588 35589 if ( ! animation ) { 35590 35591 console.error( 'THREE.AnimationClip: No animation in JSONLoader data.' ); 35592 return null; 35593 35594 } 35595 35596 var addNonemptyTrack = function ( trackType, trackName, animationKeys, propertyName, destTracks ) { 35597 35598 // only return track if there are actually keys. 35599 if ( animationKeys.length !== 0 ) { 35600 35601 var times = []; 35602 var values = []; 35603 35604 AnimationUtils.flattenJSON( animationKeys, times, values, propertyName ); 35605 35606 // empty keys are filtered out, so check again 35607 if ( times.length !== 0 ) { 35608 35609 destTracks.push( new trackType( trackName, times, values ) ); 35610 35611 } 35612 35613 } 35614 35615 }; 35616 35617 var tracks = []; 35618 35619 var clipName = animation.name || 'default'; 35620 // automatic length determination in AnimationClip. 35621 var duration = animation.length || - 1; 35622 var fps = animation.fps || 30; 35623 var blendMode = animation.blendMode; 35624 35625 var hierarchyTracks = animation.hierarchy || []; 35626 35627 for ( var h = 0; h < hierarchyTracks.length; h ++ ) { 35628 35629 var animationKeys = hierarchyTracks[ h ].keys; 35630 35631 // skip empty tracks 35632 if ( ! animationKeys || animationKeys.length === 0 ) continue; 35633 35634 // process morph targets 35635 if ( animationKeys[ 0 ].morphTargets ) { 35636 35637 // figure out all morph targets used in this track 35638 var morphTargetNames = {}; 35639 35640 for ( var k = 0; k < animationKeys.length; k ++ ) { 35641 35642 if ( animationKeys[ k ].morphTargets ) { 35643 35644 for ( var m = 0; m < animationKeys[ k ].morphTargets.length; m ++ ) { 35645 35646 morphTargetNames[ animationKeys[ k ].morphTargets[ m ] ] = - 1; 35647 35648 } 35649 35650 } 35651 35652 } 35653 35654 // create a track for each morph target with all zero 35655 // morphTargetInfluences except for the keys in which 35656 // the morphTarget is named. 35657 for ( var morphTargetName in morphTargetNames ) { 35658 35659 var times = []; 35660 var values = []; 35661 35662 for ( var m = 0; m !== animationKeys[ k ].morphTargets.length; ++ m ) { 35663 35664 var animationKey = animationKeys[ k ]; 35665 35666 times.push( animationKey.time ); 35667 values.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 ); 35668 35669 } 35670 35671 tracks.push( new NumberKeyframeTrack( '.morphTargetInfluence[' + morphTargetName + ']', times, values ) ); 35672 35673 } 35674 35675 duration = morphTargetNames.length * ( fps || 1.0 ); 35676 35677 } else { 35678 35679 // ...assume skeletal animation 35680 35681 var boneName = '.bones[' + bones[ h ].name + ']'; 35682 35683 addNonemptyTrack( 35684 VectorKeyframeTrack, boneName + '.position', 35685 animationKeys, 'pos', tracks ); 35686 35687 addNonemptyTrack( 35688 QuaternionKeyframeTrack, boneName + '.quaternion', 35689 animationKeys, 'rot', tracks ); 35690 35691 addNonemptyTrack( 35692 VectorKeyframeTrack, boneName + '.scale', 35693 animationKeys, 'scl', tracks ); 35694 35695 } 35696 35697 } 35698 35699 if ( tracks.length === 0 ) { 35700 35701 return null; 35702 35703 } 35704 35705 var clip = new AnimationClip( clipName, duration, tracks, blendMode ); 35706 35707 return clip; 35708 35709 } 35710 35711} ); 35712 35713Object.assign( AnimationClip.prototype, { 35714 35715 resetDuration: function () { 35716 35717 var tracks = this.tracks, duration = 0; 35718 35719 for ( var i = 0, n = tracks.length; i !== n; ++ i ) { 35720 35721 var track = this.tracks[ i ]; 35722 35723 duration = Math.max( duration, track.times[ track.times.length - 1 ] ); 35724 35725 } 35726 35727 this.duration = duration; 35728 35729 return this; 35730 35731 }, 35732 35733 trim: function () { 35734 35735 for ( var i = 0; i < this.tracks.length; i ++ ) { 35736 35737 this.tracks[ i ].trim( 0, this.duration ); 35738 35739 } 35740 35741 return this; 35742 35743 }, 35744 35745 validate: function () { 35746 35747 var valid = true; 35748 35749 for ( var i = 0; i < this.tracks.length; i ++ ) { 35750 35751 valid = valid && this.tracks[ i ].validate(); 35752 35753 } 35754 35755 return valid; 35756 35757 }, 35758 35759 optimize: function () { 35760 35761 for ( var i = 0; i < this.tracks.length; i ++ ) { 35762 35763 this.tracks[ i ].optimize(); 35764 35765 } 35766 35767 return this; 35768 35769 }, 35770 35771 clone: function () { 35772 35773 var tracks = []; 35774 35775 for ( var i = 0; i < this.tracks.length; i ++ ) { 35776 35777 tracks.push( this.tracks[ i ].clone() ); 35778 35779 } 35780 35781 return new AnimationClip( this.name, this.duration, tracks, this.blendMode ); 35782 35783 } 35784 35785} ); 35786 35787/** 35788 * @author mrdoob / http://mrdoob.com/ 35789 */ 35790 35791var Cache = { 35792 35793 enabled: false, 35794 35795 files: {}, 35796 35797 add: function ( key, file ) { 35798 35799 if ( this.enabled === false ) return; 35800 35801 // console.log( 'THREE.Cache', 'Adding key:', key ); 35802 35803 this.files[ key ] = file; 35804 35805 }, 35806 35807 get: function ( key ) { 35808 35809 if ( this.enabled === false ) return; 35810 35811 // console.log( 'THREE.Cache', 'Checking key:', key ); 35812 35813 return this.files[ key ]; 35814 35815 }, 35816 35817 remove: function ( key ) { 35818 35819 delete this.files[ key ]; 35820 35821 }, 35822 35823 clear: function () { 35824 35825 this.files = {}; 35826 35827 } 35828 35829}; 35830 35831/** 35832 * @author mrdoob / http://mrdoob.com/ 35833 */ 35834 35835function LoadingManager( onLoad, onProgress, onError ) { 35836 35837 var scope = this; 35838 35839 var isLoading = false; 35840 var itemsLoaded = 0; 35841 var itemsTotal = 0; 35842 var urlModifier = undefined; 35843 var handlers = []; 35844 35845 // Refer to #5689 for the reason why we don't set .onStart 35846 // in the constructor 35847 35848 this.onStart = undefined; 35849 this.onLoad = onLoad; 35850 this.onProgress = onProgress; 35851 this.onError = onError; 35852 35853 this.itemStart = function ( url ) { 35854 35855 itemsTotal ++; 35856 35857 if ( isLoading === false ) { 35858 35859 if ( scope.onStart !== undefined ) { 35860 35861 scope.onStart( url, itemsLoaded, itemsTotal ); 35862 35863 } 35864 35865 } 35866 35867 isLoading = true; 35868 35869 }; 35870 35871 this.itemEnd = function ( url ) { 35872 35873 itemsLoaded ++; 35874 35875 if ( scope.onProgress !== undefined ) { 35876 35877 scope.onProgress( url, itemsLoaded, itemsTotal ); 35878 35879 } 35880 35881 if ( itemsLoaded === itemsTotal ) { 35882 35883 isLoading = false; 35884 35885 if ( scope.onLoad !== undefined ) { 35886 35887 scope.onLoad(); 35888 35889 } 35890 35891 } 35892 35893 }; 35894 35895 this.itemError = function ( url ) { 35896 35897 if ( scope.onError !== undefined ) { 35898 35899 scope.onError( url ); 35900 35901 } 35902 35903 }; 35904 35905 this.resolveURL = function ( url ) { 35906 35907 if ( urlModifier ) { 35908 35909 return urlModifier( url ); 35910 35911 } 35912 35913 return url; 35914 35915 }; 35916 35917 this.setURLModifier = function ( transform ) { 35918 35919 urlModifier = transform; 35920 35921 return this; 35922 35923 }; 35924 35925 this.addHandler = function ( regex, loader ) { 35926 35927 handlers.push( regex, loader ); 35928 35929 return this; 35930 35931 }; 35932 35933 this.removeHandler = function ( regex ) { 35934 35935 var index = handlers.indexOf( regex ); 35936 35937 if ( index !== - 1 ) { 35938 35939 handlers.splice( index, 2 ); 35940 35941 } 35942 35943 return this; 35944 35945 }; 35946 35947 this.getHandler = function ( file ) { 35948 35949 for ( var i = 0, l = handlers.length; i < l; i += 2 ) { 35950 35951 var regex = handlers[ i ]; 35952 var loader = handlers[ i + 1 ]; 35953 35954 if ( regex.global ) regex.lastIndex = 0; // see #17920 35955 35956 if ( regex.test( file ) ) { 35957 35958 return loader; 35959 35960 } 35961 35962 } 35963 35964 return null; 35965 35966 }; 35967 35968} 35969 35970var DefaultLoadingManager = new LoadingManager(); 35971 35972/** 35973 * @author alteredq / http://alteredqualia.com/ 35974 */ 35975 35976function Loader( manager ) { 35977 35978 this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; 35979 35980 this.crossOrigin = 'anonymous'; 35981 this.path = ''; 35982 this.resourcePath = ''; 35983 35984} 35985 35986Object.assign( Loader.prototype, { 35987 35988 load: function ( /* url, onLoad, onProgress, onError */ ) {}, 35989 35990 loadAsync: function ( url, onProgress ) { 35991 35992 var scope = this; 35993 35994 return new Promise( function ( resolve, reject ) { 35995 35996 scope.load( url, resolve, onProgress, reject ); 35997 35998 } ); 35999 36000 }, 36001 36002 parse: function ( /* data */ ) {}, 36003 36004 setCrossOrigin: function ( crossOrigin ) { 36005 36006 this.crossOrigin = crossOrigin; 36007 return this; 36008 36009 }, 36010 36011 setPath: function ( path ) { 36012 36013 this.path = path; 36014 return this; 36015 36016 }, 36017 36018 setResourcePath: function ( resourcePath ) { 36019 36020 this.resourcePath = resourcePath; 36021 return this; 36022 36023 } 36024 36025} ); 36026 36027/** 36028 * @author mrdoob / http://mrdoob.com/ 36029 */ 36030 36031var loading = {}; 36032 36033function FileLoader( manager ) { 36034 36035 Loader.call( this, manager ); 36036 36037} 36038 36039FileLoader.prototype = Object.assign( Object.create( Loader.prototype ), { 36040 36041 constructor: FileLoader, 36042 36043 load: function ( url, onLoad, onProgress, onError ) { 36044 36045 if ( url === undefined ) url = ''; 36046 36047 if ( this.path !== undefined ) url = this.path + url; 36048 36049 url = this.manager.resolveURL( url ); 36050 36051 var scope = this; 36052 36053 var cached = Cache.get( url ); 36054 36055 if ( cached !== undefined ) { 36056 36057 scope.manager.itemStart( url ); 36058 36059 setTimeout( function () { 36060 36061 if ( onLoad ) onLoad( cached ); 36062 36063 scope.manager.itemEnd( url ); 36064 36065 }, 0 ); 36066 36067 return cached; 36068 36069 } 36070 36071 // Check if request is duplicate 36072 36073 if ( loading[ url ] !== undefined ) { 36074 36075 loading[ url ].push( { 36076 36077 onLoad: onLoad, 36078 onProgress: onProgress, 36079 onError: onError 36080 36081 } ); 36082 36083 return; 36084 36085 } 36086 36087 // Check for data: URI 36088 var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; 36089 var dataUriRegexResult = url.match( dataUriRegex ); 36090 36091 // Safari can not handle Data URIs through XMLHttpRequest so process manually 36092 if ( dataUriRegexResult ) { 36093 36094 var mimeType = dataUriRegexResult[ 1 ]; 36095 var isBase64 = !! dataUriRegexResult[ 2 ]; 36096 var data = dataUriRegexResult[ 3 ]; 36097 36098 data = decodeURIComponent( data ); 36099 36100 if ( isBase64 ) data = atob( data ); 36101 36102 try { 36103 36104 var response; 36105 var responseType = ( this.responseType || '' ).toLowerCase(); 36106 36107 switch ( responseType ) { 36108 36109 case 'arraybuffer': 36110 case 'blob': 36111 36112 var view = new Uint8Array( data.length ); 36113 36114 for ( var i = 0; i < data.length; i ++ ) { 36115 36116 view[ i ] = data.charCodeAt( i ); 36117 36118 } 36119 36120 if ( responseType === 'blob' ) { 36121 36122 response = new Blob( [ view.buffer ], { type: mimeType } ); 36123 36124 } else { 36125 36126 response = view.buffer; 36127 36128 } 36129 36130 break; 36131 36132 case 'document': 36133 36134 var parser = new DOMParser(); 36135 response = parser.parseFromString( data, mimeType ); 36136 36137 break; 36138 36139 case 'json': 36140 36141 response = JSON.parse( data ); 36142 36143 break; 36144 36145 default: // 'text' or other 36146 36147 response = data; 36148 36149 break; 36150 36151 } 36152 36153 // Wait for next browser tick like standard XMLHttpRequest event dispatching does 36154 setTimeout( function () { 36155 36156 if ( onLoad ) onLoad( response ); 36157 36158 scope.manager.itemEnd( url ); 36159 36160 }, 0 ); 36161 36162 } catch ( error ) { 36163 36164 // Wait for next browser tick like standard XMLHttpRequest event dispatching does 36165 setTimeout( function () { 36166 36167 if ( onError ) onError( error ); 36168 36169 scope.manager.itemError( url ); 36170 scope.manager.itemEnd( url ); 36171 36172 }, 0 ); 36173 36174 } 36175 36176 } else { 36177 36178 // Initialise array for duplicate requests 36179 36180 loading[ url ] = []; 36181 36182 loading[ url ].push( { 36183 36184 onLoad: onLoad, 36185 onProgress: onProgress, 36186 onError: onError 36187 36188 } ); 36189 36190 var request = new XMLHttpRequest(); 36191 36192 request.open( 'GET', url, true ); 36193 36194 request.addEventListener( 'load', function ( event ) { 36195 36196 var response = this.response; 36197 36198 var callbacks = loading[ url ]; 36199 36200 delete loading[ url ]; 36201 36202 if ( this.status === 200 || this.status === 0 ) { 36203 36204 // Some browsers return HTTP Status 0 when using non-http protocol 36205 // e.g. 'file://' or 'data://'. Handle as success. 36206 36207 if ( this.status === 0 ) console.warn( 'THREE.FileLoader: HTTP Status 0 received.' ); 36208 36209 // Add to cache only on HTTP success, so that we do not cache 36210 // error response bodies as proper responses to requests. 36211 Cache.add( url, response ); 36212 36213 for ( var i = 0, il = callbacks.length; i < il; i ++ ) { 36214 36215 var callback = callbacks[ i ]; 36216 if ( callback.onLoad ) callback.onLoad( response ); 36217 36218 } 36219 36220 scope.manager.itemEnd( url ); 36221 36222 } else { 36223 36224 for ( var i = 0, il = callbacks.length; i < il; i ++ ) { 36225 36226 var callback = callbacks[ i ]; 36227 if ( callback.onError ) callback.onError( event ); 36228 36229 } 36230 36231 scope.manager.itemError( url ); 36232 scope.manager.itemEnd( url ); 36233 36234 } 36235 36236 }, false ); 36237 36238 request.addEventListener( 'progress', function ( event ) { 36239 36240 var callbacks = loading[ url ]; 36241 36242 for ( var i = 0, il = callbacks.length; i < il; i ++ ) { 36243 36244 var callback = callbacks[ i ]; 36245 if ( callback.onProgress ) callback.onProgress( event ); 36246 36247 } 36248 36249 }, false ); 36250 36251 request.addEventListener( 'error', function ( event ) { 36252 36253 var callbacks = loading[ url ]; 36254 36255 delete loading[ url ]; 36256 36257 for ( var i = 0, il = callbacks.length; i < il; i ++ ) { 36258 36259 var callback = callbacks[ i ]; 36260 if ( callback.onError ) callback.onError( event ); 36261 36262 } 36263 36264 scope.manager.itemError( url ); 36265 scope.manager.itemEnd( url ); 36266 36267 }, false ); 36268 36269 request.addEventListener( 'abort', function ( event ) { 36270 36271 var callbacks = loading[ url ]; 36272 36273 delete loading[ url ]; 36274 36275 for ( var i = 0, il = callbacks.length; i < il; i ++ ) { 36276 36277 var callback = callbacks[ i ]; 36278 if ( callback.onError ) callback.onError( event ); 36279 36280 } 36281 36282 scope.manager.itemError( url ); 36283 scope.manager.itemEnd( url ); 36284 36285 }, false ); 36286 36287 if ( this.responseType !== undefined ) request.responseType = this.responseType; 36288 if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials; 36289 36290 if ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' ); 36291 36292 for ( var header in this.requestHeader ) { 36293 36294 request.setRequestHeader( header, this.requestHeader[ header ] ); 36295 36296 } 36297 36298 request.send( null ); 36299 36300 } 36301 36302 scope.manager.itemStart( url ); 36303 36304 return request; 36305 36306 }, 36307 36308 setResponseType: function ( value ) { 36309 36310 this.responseType = value; 36311 return this; 36312 36313 }, 36314 36315 setWithCredentials: function ( value ) { 36316 36317 this.withCredentials = value; 36318 return this; 36319 36320 }, 36321 36322 setMimeType: function ( value ) { 36323 36324 this.mimeType = value; 36325 return this; 36326 36327 }, 36328 36329 setRequestHeader: function ( value ) { 36330 36331 this.requestHeader = value; 36332 return this; 36333 36334 } 36335 36336} ); 36337 36338/** 36339 * @author bhouston / http://clara.io/ 36340 */ 36341 36342function AnimationLoader( manager ) { 36343 36344 Loader.call( this, manager ); 36345 36346} 36347 36348AnimationLoader.prototype = Object.assign( Object.create( Loader.prototype ), { 36349 36350 constructor: AnimationLoader, 36351 36352 load: function ( url, onLoad, onProgress, onError ) { 36353 36354 var scope = this; 36355 36356 var loader = new FileLoader( scope.manager ); 36357 loader.setPath( scope.path ); 36358 loader.load( url, function ( text ) { 36359 36360 onLoad( scope.parse( JSON.parse( text ) ) ); 36361 36362 }, onProgress, onError ); 36363 36364 }, 36365 36366 parse: function ( json ) { 36367 36368 var animations = []; 36369 36370 for ( var i = 0; i < json.length; i ++ ) { 36371 36372 var clip = AnimationClip.parse( json[ i ] ); 36373 36374 animations.push( clip ); 36375 36376 } 36377 36378 return animations; 36379 36380 } 36381 36382} ); 36383 36384/** 36385 * @author mrdoob / http://mrdoob.com/ 36386 * 36387 * Abstract Base class to block based textures loader (dds, pvr, ...) 36388 * 36389 * Sub classes have to implement the parse() method which will be used in load(). 36390 */ 36391 36392function CompressedTextureLoader( manager ) { 36393 36394 Loader.call( this, manager ); 36395 36396} 36397 36398CompressedTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { 36399 36400 constructor: CompressedTextureLoader, 36401 36402 load: function ( url, onLoad, onProgress, onError ) { 36403 36404 var scope = this; 36405 36406 var images = []; 36407 36408 var texture = new CompressedTexture(); 36409 texture.image = images; 36410 36411 var loader = new FileLoader( this.manager ); 36412 loader.setPath( this.path ); 36413 loader.setResponseType( 'arraybuffer' ); 36414 36415 function loadTexture( i ) { 36416 36417 loader.load( url[ i ], function ( buffer ) { 36418 36419 var texDatas = scope.parse( buffer, true ); 36420 36421 images[ i ] = { 36422 width: texDatas.width, 36423 height: texDatas.height, 36424 format: texDatas.format, 36425 mipmaps: texDatas.mipmaps 36426 }; 36427 36428 loaded += 1; 36429 36430 if ( loaded === 6 ) { 36431 36432 if ( texDatas.mipmapCount === 1 ) 36433 texture.minFilter = LinearFilter; 36434 36435 texture.format = texDatas.format; 36436 texture.needsUpdate = true; 36437 36438 if ( onLoad ) onLoad( texture ); 36439 36440 } 36441 36442 }, onProgress, onError ); 36443 36444 } 36445 36446 if ( Array.isArray( url ) ) { 36447 36448 var loaded = 0; 36449 36450 for ( var i = 0, il = url.length; i < il; ++ i ) { 36451 36452 loadTexture( i ); 36453 36454 } 36455 36456 } else { 36457 36458 // compressed cubemap texture stored in a single DDS file 36459 36460 loader.load( url, function ( buffer ) { 36461 36462 var texDatas = scope.parse( buffer, true ); 36463 36464 if ( texDatas.isCubemap ) { 36465 36466 var faces = texDatas.mipmaps.length / texDatas.mipmapCount; 36467 36468 for ( var f = 0; f < faces; f ++ ) { 36469 36470 images[ f ] = { mipmaps: [] }; 36471 36472 for ( var i = 0; i < texDatas.mipmapCount; i ++ ) { 36473 36474 images[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] ); 36475 images[ f ].format = texDatas.format; 36476 images[ f ].width = texDatas.width; 36477 images[ f ].height = texDatas.height; 36478 36479 } 36480 36481 } 36482 36483 } else { 36484 36485 texture.image.width = texDatas.width; 36486 texture.image.height = texDatas.height; 36487 texture.mipmaps = texDatas.mipmaps; 36488 36489 } 36490 36491 if ( texDatas.mipmapCount === 1 ) { 36492 36493 texture.minFilter = LinearFilter; 36494 36495 } 36496 36497 texture.format = texDatas.format; 36498 texture.needsUpdate = true; 36499 36500 if ( onLoad ) onLoad( texture ); 36501 36502 }, onProgress, onError ); 36503 36504 } 36505 36506 return texture; 36507 36508 } 36509 36510} ); 36511 36512/** 36513 * @author Nikos M. / https://github.com/foo123/ 36514 * 36515 * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...) 36516 * 36517 * Sub classes have to implement the parse() method which will be used in load(). 36518 */ 36519 36520function DataTextureLoader( manager ) { 36521 36522 Loader.call( this, manager ); 36523 36524} 36525 36526DataTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { 36527 36528 constructor: DataTextureLoader, 36529 36530 load: function ( url, onLoad, onProgress, onError ) { 36531 36532 var scope = this; 36533 36534 var texture = new DataTexture(); 36535 36536 var loader = new FileLoader( this.manager ); 36537 loader.setResponseType( 'arraybuffer' ); 36538 loader.setPath( this.path ); 36539 loader.load( url, function ( buffer ) { 36540 36541 var texData = scope.parse( buffer ); 36542 36543 if ( ! texData ) return; 36544 36545 if ( texData.image !== undefined ) { 36546 36547 texture.image = texData.image; 36548 36549 } else if ( texData.data !== undefined ) { 36550 36551 texture.image.width = texData.width; 36552 texture.image.height = texData.height; 36553 texture.image.data = texData.data; 36554 36555 } 36556 36557 texture.wrapS = texData.wrapS !== undefined ? texData.wrapS : ClampToEdgeWrapping; 36558 texture.wrapT = texData.wrapT !== undefined ? texData.wrapT : ClampToEdgeWrapping; 36559 36560 texture.magFilter = texData.magFilter !== undefined ? texData.magFilter : LinearFilter; 36561 texture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearFilter; 36562 36563 texture.anisotropy = texData.anisotropy !== undefined ? texData.anisotropy : 1; 36564 36565 if ( texData.format !== undefined ) { 36566 36567 texture.format = texData.format; 36568 36569 } 36570 36571 if ( texData.type !== undefined ) { 36572 36573 texture.type = texData.type; 36574 36575 } 36576 36577 if ( texData.mipmaps !== undefined ) { 36578 36579 texture.mipmaps = texData.mipmaps; 36580 texture.minFilter = LinearMipmapLinearFilter; // presumably... 36581 36582 } 36583 36584 if ( texData.mipmapCount === 1 ) { 36585 36586 texture.minFilter = LinearFilter; 36587 36588 } 36589 36590 texture.needsUpdate = true; 36591 36592 if ( onLoad ) onLoad( texture, texData ); 36593 36594 }, onProgress, onError ); 36595 36596 36597 return texture; 36598 36599 } 36600 36601} ); 36602 36603/** 36604 * @author mrdoob / http://mrdoob.com/ 36605 */ 36606 36607function ImageLoader( manager ) { 36608 36609 Loader.call( this, manager ); 36610 36611} 36612 36613ImageLoader.prototype = Object.assign( Object.create( Loader.prototype ), { 36614 36615 constructor: ImageLoader, 36616 36617 load: function ( url, onLoad, onProgress, onError ) { 36618 36619 if ( this.path !== undefined ) url = this.path + url; 36620 36621 url = this.manager.resolveURL( url ); 36622 36623 var scope = this; 36624 36625 var cached = Cache.get( url ); 36626 36627 if ( cached !== undefined ) { 36628 36629 scope.manager.itemStart( url ); 36630 36631 setTimeout( function () { 36632 36633 if ( onLoad ) onLoad( cached ); 36634 36635 scope.manager.itemEnd( url ); 36636 36637 }, 0 ); 36638 36639 return cached; 36640 36641 } 36642 36643 var image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' ); 36644 36645 function onImageLoad() { 36646 36647 image.removeEventListener( 'load', onImageLoad, false ); 36648 image.removeEventListener( 'error', onImageError, false ); 36649 36650 Cache.add( url, this ); 36651 36652 if ( onLoad ) onLoad( this ); 36653 36654 scope.manager.itemEnd( url ); 36655 36656 } 36657 36658 function onImageError( event ) { 36659 36660 image.removeEventListener( 'load', onImageLoad, false ); 36661 image.removeEventListener( 'error', onImageError, false ); 36662 36663 if ( onError ) onError( event ); 36664 36665 scope.manager.itemError( url ); 36666 scope.manager.itemEnd( url ); 36667 36668 } 36669 36670 image.addEventListener( 'load', onImageLoad, false ); 36671 image.addEventListener( 'error', onImageError, false ); 36672 36673 if ( url.substr( 0, 5 ) !== 'data:' ) { 36674 36675 if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin; 36676 36677 } 36678 36679 scope.manager.itemStart( url ); 36680 36681 image.src = url; 36682 36683 return image; 36684 36685 } 36686 36687} ); 36688 36689/** 36690 * @author mrdoob / http://mrdoob.com/ 36691 */ 36692 36693 36694function CubeTextureLoader( manager ) { 36695 36696 Loader.call( this, manager ); 36697 36698} 36699 36700CubeTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { 36701 36702 constructor: CubeTextureLoader, 36703 36704 load: function ( urls, onLoad, onProgress, onError ) { 36705 36706 var texture = new CubeTexture(); 36707 36708 var loader = new ImageLoader( this.manager ); 36709 loader.setCrossOrigin( this.crossOrigin ); 36710 loader.setPath( this.path ); 36711 36712 var loaded = 0; 36713 36714 function loadTexture( i ) { 36715 36716 loader.load( urls[ i ], function ( image ) { 36717 36718 texture.images[ i ] = image; 36719 36720 loaded ++; 36721 36722 if ( loaded === 6 ) { 36723 36724 texture.needsUpdate = true; 36725 36726 if ( onLoad ) onLoad( texture ); 36727 36728 } 36729 36730 }, undefined, onError ); 36731 36732 } 36733 36734 for ( var i = 0; i < urls.length; ++ i ) { 36735 36736 loadTexture( i ); 36737 36738 } 36739 36740 return texture; 36741 36742 } 36743 36744} ); 36745 36746/** 36747 * @author mrdoob / http://mrdoob.com/ 36748 */ 36749 36750function TextureLoader( manager ) { 36751 36752 Loader.call( this, manager ); 36753 36754} 36755 36756TextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { 36757 36758 constructor: TextureLoader, 36759 36760 load: function ( url, onLoad, onProgress, onError ) { 36761 36762 var texture = new Texture(); 36763 36764 var loader = new ImageLoader( this.manager ); 36765 loader.setCrossOrigin( this.crossOrigin ); 36766 loader.setPath( this.path ); 36767 36768 loader.load( url, function ( image ) { 36769 36770 texture.image = image; 36771 36772 // JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB. 36773 var isJPEG = url.search( /\.jpe?g($|\?)/i ) > 0 || url.search( /^data\:image\/jpeg/ ) === 0; 36774 36775 texture.format = isJPEG ? RGBFormat : RGBAFormat; 36776 texture.needsUpdate = true; 36777 36778 if ( onLoad !== undefined ) { 36779 36780 onLoad( texture ); 36781 36782 } 36783 36784 }, onProgress, onError ); 36785 36786 return texture; 36787 36788 } 36789 36790} ); 36791 36792/** 36793 * @author zz85 / http://www.lab4games.net/zz85/blog 36794 * Extensible curve object 36795 * 36796 * Some common of curve methods: 36797 * .getPoint( t, optionalTarget ), .getTangent( t, optionalTarget ) 36798 * .getPointAt( u, optionalTarget ), .getTangentAt( u, optionalTarget ) 36799 * .getPoints(), .getSpacedPoints() 36800 * .getLength() 36801 * .updateArcLengths() 36802 * 36803 * This following curves inherit from THREE.Curve: 36804 * 36805 * -- 2D curves -- 36806 * THREE.ArcCurve 36807 * THREE.CubicBezierCurve 36808 * THREE.EllipseCurve 36809 * THREE.LineCurve 36810 * THREE.QuadraticBezierCurve 36811 * THREE.SplineCurve 36812 * 36813 * -- 3D curves --
36814 * THREE.CatmullRomCurve3 36815 * THREE.CubicBezierCurve3 36816 * THREE.LineCurve3 36817 * THREE.QuadraticBezierCurve3 36818 * 36819 * A series of curves can be represented as a THREE.CurvePath. 36820 * 36821 **/ 36822 36823/************************************************************** 36824 * Abstract Curve base class 36825 **************************************************************/ 36826 36827function Curve() { 36828 36829 this.type = 'Curve'; 36830 36831 this.arcLengthDivisions = 200; 36832 36833} 36834 36835Object.assign( Curve.prototype, { 36836 36837 // Virtual base class method to overwrite and implement in subclasses 36838 // - t [0 .. 1] 36839 36840 getPoint: function ( /* t, optionalTarget */ ) { 36841 36842 console.warn( 'THREE.Curve: .getPoint() not implemented.' ); 36843 return null; 36844 36845 }, 36846 36847 // Get point at relative position in curve according to arc length 36848 // - u [0 .. 1] 36849 36850 getPointAt: function ( u, optionalTarget ) { 36851 36852 var t = this.getUtoTmapping( u ); 36853 return this.getPoint( t, optionalTarget ); 36854 36855 }, 36856 36857 // Get sequence of points using getPoint( t ) 36858 36859 getPoints: function ( divisions ) { 36860 36861 if ( divisions === undefined ) divisions = 5; 36862 36863 var points = []; 36864 36865 for ( var d = 0; d <= divisions; d ++ ) { 36866 36867 points.push( this.getPoint( d / divisions ) ); 36868 36869 } 36870 36871 return points; 36872 36873 }, 36874 36875 // Get sequence of points using getPointAt( u ) 36876 36877 getSpacedPoints: function ( divisions ) { 36878 36879 if ( divisions === undefined ) divisions = 5; 36880 36881 var points = []; 36882 36883 for ( var d = 0; d <= divisions; d ++ ) { 36884 36885 points.push( this.getPointAt( d / divisions ) ); 36886 36887 } 36888 36889 return points; 36890 36891 }, 36892 36893 // Get total curve arc length 36894 36895 getLength: function () { 36896 36897 var lengths = this.getLengths(); 36898 return lengths[ lengths.length - 1 ]; 36899 36900 }, 36901 36902 // Get list of cumulative segment lengths 36903 36904 getLengths: function ( divisions ) { 36905 36906 if ( divisions === undefined ) divisions = this.arcLengthDivisions; 36907 36908 if ( this.cacheArcLengths && 36909 ( this.cacheArcLengths.length === divisions + 1 ) && 36910 ! this.needsUpdate ) { 36911 36912 return this.cacheArcLengths; 36913 36914 } 36915 36916 this.needsUpdate = false; 36917 36918 var cache = []; 36919 var current, last = this.getPoint( 0 ); 36920 var p, sum = 0; 36921 36922 cache.push( 0 ); 36923 36924 for ( p = 1; p <= divisions; p ++ ) { 36925 36926 current = this.getPoint( p / divisions ); 36927 sum += current.distanceTo( last ); 36928 cache.push( sum ); 36929 last = current; 36930 36931 } 36932 36933 this.cacheArcLengths = cache; 36934 36935 return cache; // { sums: cache, sum: sum }; Sum is in the last element. 36936 36937 }, 36938 36939 updateArcLengths: function () { 36940 36941 this.needsUpdate = true; 36942 this.getLengths(); 36943 36944 }, 36945 36946 // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant 36947 36948 getUtoTmapping: function ( u, distance ) { 36949 36950 var arcLengths = this.getLengths(); 36951 36952 var i = 0, il = arcLengths.length; 36953 36954 var targetArcLength; // The targeted u distance value to get 36955 36956 if ( distance ) { 36957 36958 targetArcLength = distance; 36959 36960 } else { 36961 36962 targetArcLength = u * arcLengths[ il - 1 ]; 36963 36964 } 36965 36966 // binary search for the index with largest value smaller than target u distance 36967 36968 var low = 0, high = il - 1, comparison; 36969 36970 while ( low <= high ) { 36971 36972 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 36973 36974 comparison = arcLengths[ i ] - targetArcLength; 36975 36976 if ( comparison < 0 ) { 36977 36978 low = i + 1; 36979 36980 } else if ( comparison > 0 ) { 36981 36982 high = i - 1; 36983 36984 } else { 36985 36986 high = i; 36987 break; 36988 36989 // DONE 36990 36991 } 36992 36993 } 36994 36995 i = high; 36996 36997 if ( arcLengths[ i ] === targetArcLength ) { 36998 36999 return i / ( il - 1 ); 37000 37001 } 37002 37003 // we could get finer grain at lengths, or use simple interpolation between two points 37004 37005 var lengthBefore = arcLengths[ i ]; 37006 var lengthAfter = arcLengths[ i + 1 ]; 37007 37008 var segmentLength = lengthAfter - lengthBefore; 37009 37010 // determine where we are between the 'before' and 'after' points 37011 37012 var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength; 37013 37014 // add that fractional amount to t 37015 37016 var t = ( i + segmentFraction ) / ( il - 1 ); 37017 37018 return t; 37019 37020 }, 37021 37022 // Returns a unit vector tangent at t 37023 // In case any sub curve does not implement its tangent derivation, 37024 // 2 points a small delta apart will be used to find its gradient 37025 // which seems to give a reasonable approximation 37026 37027 getTangent: function ( t, optionalTarget ) { 37028 37029 var delta = 0.0001; 37030 var t1 = t - delta; 37031 var t2 = t + delta; 37032 37033 // Capping in case of danger 37034 37035 if ( t1 < 0 ) t1 = 0; 37036 if ( t2 > 1 ) t2 = 1; 37037 37038 var pt1 = this.getPoint( t1 ); 37039 var pt2 = this.getPoint( t2 ); 37040 37041 var tangent = optionalTarget || ( ( pt1.isVector2 ) ? new Vector2() : new Vector3() ); 37042 37043 tangent.copy( pt2 ).sub( pt1 ).normalize(); 37044 37045 return tangent; 37046 37047 },
vendor: 36,522 bytes, lines 37048-38953
37048 37049 getTangentAt: function ( u, optionalTarget ) { 37050 37051 var t = this.getUtoTmapping( u ); 37052 return this.getTangent( t, optionalTarget ); 37053 37054 }, 37055 37056 computeFrenetFrames: function ( segments, closed ) { 37057 37058 // see http://www.cs.indiana.edu/pub/techreports/TR425.pdf 37059 37060 var normal = new Vector3(); 37061 37062 var tangents = []; 37063 var normals = []; 37064 var binormals = []; 37065 37066 var vec = new Vector3(); 37067 var mat = new Matrix4(); 37068 37069 var i, u, theta; 37070 37071 // compute the tangent vectors for each segment on the curve 37072 37073 for ( i = 0; i <= segments; i ++ ) { 37074 37075 u = i / segments; 37076 37077 tangents[ i ] = this.getTangentAt( u, new Vector3() ); 37078 tangents[ i ].normalize(); 37079 37080 } 37081 37082 // select an initial normal vector perpendicular to the first tangent vector, 37083 // and in the direction of the minimum tangent xyz component 37084 37085 normals[ 0 ] = new Vector3(); 37086 binormals[ 0 ] = new Vector3(); 37087 var min = Number.MAX_VALUE; 37088 var tx = Math.abs( tangents[ 0 ].x ); 37089 var ty = Math.abs( tangents[ 0 ].y ); 37090 var tz = Math.abs( tangents[ 0 ].z ); 37091 37092 if ( tx <= min ) { 37093 37094 min = tx; 37095 normal.set( 1, 0, 0 ); 37096 37097 } 37098 37099 if ( ty <= min ) { 37100 37101 min = ty; 37102 normal.set( 0, 1, 0 ); 37103 37104 } 37105 37106 if ( tz <= min ) { 37107 37108 normal.set( 0, 0, 1 ); 37109 37110 } 37111 37112 vec.crossVectors( tangents[ 0 ], normal ).normalize(); 37113 37114 normals[ 0 ].crossVectors( tangents[ 0 ], vec ); 37115 binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] ); 37116 37117 37118 // compute the slowly-varying normal and binormal vectors for each segment on the curve 37119 37120 for ( i = 1; i <= segments; i ++ ) { 37121 37122 normals[ i ] = normals[ i - 1 ].clone(); 37123 37124 binormals[ i ] = binormals[ i - 1 ].clone(); 37125 37126 vec.crossVectors( tangents[ i - 1 ], tangents[ i ] ); 37127 37128 if ( vec.length() > Number.EPSILON ) { 37129 37130 vec.normalize(); 37131 37132 theta = Math.acos( MathUtils.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors 37133 37134 normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) ); 37135 37136 } 37137 37138 binormals[ i ].crossVectors( tangents[ i ], normals[ i ] ); 37139 37140 } 37141 37142 // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same 37143 37144 if ( closed === true ) { 37145 37146 theta = Math.acos( MathUtils.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) ); 37147 theta /= segments; 37148 37149 if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) { 37150 37151 theta = - theta; 37152 37153 } 37154 37155 for ( i = 1; i <= segments; i ++ ) { 37156 37157 // twist a little... 37158 normals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) ); 37159 binormals[ i ].crossVectors( tangents[ i ], normals[ i ] ); 37160 37161 } 37162 37163 } 37164 37165 return { 37166 tangents: tangents, 37167 normals: normals, 37168 binormals: binormals 37169 }; 37170 37171 }, 37172 37173 clone: function () { 37174 37175 return new this.constructor().copy( this ); 37176 37177 }, 37178 37179 copy: function ( source ) { 37180 37181 this.arcLengthDivisions = source.arcLengthDivisions; 37182 37183 return this; 37184 37185 }, 37186 37187 toJSON: function () { 37188 37189 var data = { 37190 metadata: { 37191 version: 4.5, 37192 type: 'Curve', 37193 generator: 'Curve.toJSON' 37194 } 37195 }; 37196 37197 data.arcLengthDivisions = this.arcLengthDivisions; 37198 data.type = this.type; 37199 37200 return data; 37201 37202 }, 37203 37204 fromJSON: function ( json ) { 37205 37206 this.arcLengthDivisions = json.arcLengthDivisions; 37207 37208 return this; 37209 37210 } 37211 37212} ); 37213 37214function EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { 37215 37216 Curve.call( this ); 37217 37218 this.type = 'EllipseCurve'; 37219 37220 this.aX = aX || 0; 37221 this.aY = aY || 0; 37222 37223 this.xRadius = xRadius || 1; 37224 this.yRadius = yRadius || 1; 37225 37226 this.aStartAngle = aStartAngle || 0; 37227 this.aEndAngle = aEndAngle || 2 * Math.PI; 37228 37229 this.aClockwise = aClockwise || false; 37230 37231 this.aRotation = aRotation || 0; 37232 37233} 37234 37235EllipseCurve.prototype = Object.create( Curve.prototype ); 37236EllipseCurve.prototype.constructor = EllipseCurve; 37237 37238EllipseCurve.prototype.isEllipseCurve = true; 37239 37240EllipseCurve.prototype.getPoint = function ( t, optionalTarget ) { 37241 37242 var point = optionalTarget || new Vector2(); 37243 37244 var twoPi = Math.PI * 2; 37245 var deltaAngle = this.aEndAngle - this.aStartAngle; 37246 var samePoints = Math.abs( deltaAngle ) < Number.EPSILON; 37247 37248 // ensures that deltaAngle is 0 .. 2 PI 37249 while ( deltaAngle < 0 ) deltaAngle += twoPi; 37250 while ( deltaAngle > twoPi ) deltaAngle -= twoPi; 37251 37252 if ( deltaAngle < Number.EPSILON ) { 37253 37254 if ( samePoints ) { 37255 37256 deltaAngle = 0; 37257 37258 } else { 37259 37260 deltaAngle = twoPi; 37261 37262 } 37263 37264 } 37265 37266 if ( this.aClockwise === true && ! samePoints ) { 37267 37268 if ( deltaAngle === twoPi ) { 37269 37270 deltaAngle = - twoPi; 37271 37272 } else { 37273 37274 deltaAngle = deltaAngle - twoPi; 37275 37276 } 37277 37278 } 37279 37280 var angle = this.aStartAngle + t * deltaAngle; 37281 var x = this.aX + this.xRadius * Math.cos( angle ); 37282 var y = this.aY + this.yRadius * Math.sin( angle ); 37283 37284 if ( this.aRotation !== 0 ) { 37285 37286 var cos = Math.cos( this.aRotation ); 37287 var sin = Math.sin( this.aRotation ); 37288 37289 var tx = x - this.aX; 37290 var ty = y - this.aY; 37291 37292 // Rotate the point about the center of the ellipse. 37293 x = tx * cos - ty * sin + this.aX; 37294 y = tx * sin + ty * cos + this.aY; 37295 37296 } 37297 37298 return point.set( x, y ); 37299 37300}; 37301 37302EllipseCurve.prototype.copy = function ( source ) { 37303 37304 Curve.prototype.copy.call( this, source ); 37305 37306 this.aX = source.aX; 37307 this.aY = source.aY; 37308 37309 this.xRadius = source.xRadius; 37310 this.yRadius = source.yRadius; 37311 37312 this.aStartAngle = source.aStartAngle; 37313 this.aEndAngle = source.aEndAngle; 37314 37315 this.aClockwise = source.aClockwise; 37316 37317 this.aRotation = source.aRotation; 37318 37319 return this; 37320 37321}; 37322 37323 37324EllipseCurve.prototype.toJSON = function () { 37325 37326 var data = Curve.prototype.toJSON.call( this ); 37327 37328 data.aX = this.aX; 37329 data.aY = this.aY; 37330 37331 data.xRadius = this.xRadius; 37332 data.yRadius = this.yRadius; 37333 37334 data.aStartAngle = this.aStartAngle; 37335 data.aEndAngle = this.aEndAngle; 37336 37337 data.aClockwise = this.aClockwise; 37338 37339 data.aRotation = this.aRotation; 37340 37341 return data; 37342 37343}; 37344 37345EllipseCurve.prototype.fromJSON = function ( json ) { 37346 37347 Curve.prototype.fromJSON.call( this, json ); 37348 37349 this.aX = json.aX; 37350 this.aY = json.aY; 37351 37352 this.xRadius = json.xRadius; 37353 this.yRadius = json.yRadius; 37354 37355 this.aStartAngle = json.aStartAngle; 37356 this.aEndAngle = json.aEndAngle; 37357 37358 this.aClockwise = json.aClockwise; 37359 37360 this.aRotation = json.aRotation; 37361 37362 return this; 37363 37364}; 37365 37366function ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { 37367 37368 EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise ); 37369 37370 this.type = 'ArcCurve'; 37371 37372} 37373 37374ArcCurve.prototype = Object.create( EllipseCurve.prototype ); 37375ArcCurve.prototype.constructor = ArcCurve; 37376 37377ArcCurve.prototype.isArcCurve = true; 37378 37379/** 37380 * @author zz85 https://github.com/zz85 37381 * 37382 * Centripetal CatmullRom Curve - which is useful for avoiding 37383 * cusps and self-intersections in non-uniform catmull rom curves. 37384 * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf 37385 * 37386 * curve.type accepts centripetal(default), chordal and catmullrom 37387 * curve.tension is used for catmullrom which defaults to 0.5 37388 */ 37389 37390 37391/* 37392Based on an optimized c++ solution in 37393 - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/ 37394 - http://ideone.com/NoEbVM 37395 37396This CubicPoly class could be used for reusing some variables and calculations, 37397but for three.js curve use, it could be possible inlined and flatten into a single function call 37398which can be placed in CurveUtils. 37399*/ 37400 37401function CubicPoly() { 37402 37403 var c0 = 0, c1 = 0, c2 = 0, c3 = 0; 37404 37405 /* 37406 * Compute coefficients for a cubic polynomial 37407 * p(s) = c0 + c1*s + c2*s^2 + c3*s^3 37408 * such that 37409 * p(0) = x0, p(1) = x1 37410 * and 37411 * p'(0) = t0, p'(1) = t1. 37412 */ 37413 function init( x0, x1, t0, t1 ) { 37414 37415 c0 = x0; 37416 c1 = t0; 37417 c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1; 37418 c3 = 2 * x0 - 2 * x1 + t0 + t1; 37419 37420 } 37421 37422 return { 37423 37424 initCatmullRom: function ( x0, x1, x2, x3, tension ) { 37425 37426 init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) ); 37427 37428 }, 37429 37430 initNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) { 37431 37432 // compute tangents when parameterized in [t1,t2] 37433 var t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1; 37434 var t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2; 37435 37436 // rescale tangents for parametrization in [0,1] 37437 t1 *= dt1; 37438 t2 *= dt1; 37439 37440 init( x1, x2, t1, t2 ); 37441 37442 }, 37443 37444 calc: function ( t ) { 37445 37446 var t2 = t * t; 37447 var t3 = t2 * t; 37448 return c0 + c1 * t + c2 * t2 + c3 * t3; 37449 37450 } 37451 37452 }; 37453 37454} 37455 37456// 37457 37458var tmp = new Vector3(); 37459var px = new CubicPoly(), py = new CubicPoly(), pz = new CubicPoly(); 37460 37461function CatmullRomCurve3( points, closed, curveType, tension ) { 37462 37463 Curve.call( this ); 37464 37465 this.type = 'CatmullRomCurve3'; 37466 37467 this.points = points || []; 37468 this.closed = closed || false; 37469 this.curveType = curveType || 'centripetal'; 37470 this.tension = tension || 0.5; 37471 37472} 37473 37474CatmullRomCurve3.prototype = Object.create( Curve.prototype ); 37475CatmullRomCurve3.prototype.constructor = CatmullRomCurve3; 37476 37477CatmullRomCurve3.prototype.isCatmullRomCurve3 = true; 37478 37479CatmullRomCurve3.prototype.getPoint = function ( t, optionalTarget ) { 37480 37481 var point = optionalTarget || new Vector3(); 37482 37483 var points = this.points; 37484 var l = points.length; 37485 37486 var p = ( l - ( this.closed ? 0 : 1 ) ) * t; 37487 var intPoint = Math.floor( p ); 37488 var weight = p - intPoint; 37489 37490 if ( this.closed ) { 37491 37492 intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / l ) + 1 ) * l; 37493 37494 } else if ( weight === 0 && intPoint === l - 1 ) { 37495 37496 intPoint = l - 2; 37497 weight = 1; 37498 37499 } 37500 37501 var p0, p1, p2, p3; // 4 points 37502 37503 if ( this.closed || intPoint > 0 ) { 37504 37505 p0 = points[ ( intPoint - 1 ) % l ]; 37506 37507 } else { 37508 37509 // extrapolate first point 37510 tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] ); 37511 p0 = tmp; 37512 37513 } 37514 37515 p1 = points[ intPoint % l ]; 37516 p2 = points[ ( intPoint + 1 ) % l ]; 37517 37518 if ( this.closed || intPoint + 2 < l ) { 37519 37520 p3 = points[ ( intPoint + 2 ) % l ]; 37521 37522 } else { 37523 37524 // extrapolate last point 37525 tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] ); 37526 p3 = tmp; 37527 37528 } 37529 37530 if ( this.curveType === 'centripetal' || this.curveType === 'chordal' ) { 37531 37532 // init Centripetal / Chordal Catmull-Rom 37533 var pow = this.curveType === 'chordal' ? 0.5 : 0.25; 37534 var dt0 = Math.pow( p0.distanceToSquared( p1 ), pow ); 37535 var dt1 = Math.pow( p1.distanceToSquared( p2 ), pow ); 37536 var dt2 = Math.pow( p2.distanceToSquared( p3 ), pow ); 37537 37538 // safety check for repeated points 37539 if ( dt1 < 1e-4 ) dt1 = 1.0; 37540 if ( dt0 < 1e-4 ) dt0 = dt1; 37541 if ( dt2 < 1e-4 ) dt2 = dt1; 37542 37543 px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 ); 37544 py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 ); 37545 pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 ); 37546 37547 } else if ( this.curveType === 'catmullrom' ) { 37548 37549 px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, this.tension ); 37550 py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, this.tension ); 37551 pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, this.tension ); 37552 37553 } 37554 37555 point.set( 37556 px.calc( weight ), 37557 py.calc( weight ), 37558 pz.calc( weight ) 37559 ); 37560 37561 return point; 37562 37563}; 37564 37565CatmullRomCurve3.prototype.copy = function ( source ) { 37566 37567 Curve.prototype.copy.call( this, source ); 37568 37569 this.points = []; 37570 37571 for ( var i = 0, l = source.points.length; i < l; i ++ ) { 37572 37573 var point = source.points[ i ]; 37574 37575 this.points.push( point.clone() ); 37576 37577 } 37578 37579 this.closed = source.closed; 37580 this.curveType = source.curveType; 37581 this.tension = source.tension; 37582 37583 return this; 37584 37585}; 37586 37587CatmullRomCurve3.prototype.toJSON = function () { 37588 37589 var data = Curve.prototype.toJSON.call( this ); 37590 37591 data.points = []; 37592 37593 for ( var i = 0, l = this.points.length; i < l; i ++ ) { 37594 37595 var point = this.points[ i ]; 37596 data.points.push( point.toArray() ); 37597 37598 } 37599 37600 data.closed = this.closed; 37601 data.curveType = this.curveType; 37602 data.tension = this.tension; 37603 37604 return data; 37605 37606}; 37607 37608CatmullRomCurve3.prototype.fromJSON = function ( json ) { 37609 37610 Curve.prototype.fromJSON.call( this, json ); 37611 37612 this.points = []; 37613 37614 for ( var i = 0, l = json.points.length; i < l; i ++ ) { 37615 37616 var point = json.points[ i ]; 37617 this.points.push( new Vector3().fromArray( point ) ); 37618 37619 } 37620 37621 this.closed = json.closed; 37622 this.curveType = json.curveType; 37623 this.tension = json.tension; 37624 37625 return this; 37626 37627}; 37628 37629/** 37630 * @author zz85 / http://www.lab4games.net/zz85/blog 37631 * 37632 * Bezier Curves formulas obtained from 37633 * http://en.wikipedia.org/wiki/Bézier_curve 37634 */ 37635 37636function CatmullRom( t, p0, p1, p2, p3 ) { 37637 37638 var v0 = ( p2 - p0 ) * 0.5; 37639 var v1 = ( p3 - p1 ) * 0.5; 37640 var t2 = t * t; 37641 var t3 = t * t2; 37642 return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1; 37643 37644} 37645 37646// 37647 37648function QuadraticBezierP0( t, p ) { 37649 37650 var k = 1 - t; 37651 return k * k * p; 37652 37653} 37654 37655function QuadraticBezierP1( t, p ) { 37656 37657 return 2 * ( 1 - t ) * t * p; 37658 37659} 37660 37661function QuadraticBezierP2( t, p ) { 37662 37663 return t * t * p; 37664 37665} 37666 37667function QuadraticBezier( t, p0, p1, p2 ) { 37668 37669 return QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) + 37670 QuadraticBezierP2( t, p2 ); 37671 37672} 37673 37674// 37675 37676function CubicBezierP0( t, p ) { 37677 37678 var k = 1 - t; 37679 return k * k * k * p; 37680 37681} 37682 37683function CubicBezierP1( t, p ) { 37684 37685 var k = 1 - t; 37686 return 3 * k * k * t * p; 37687 37688} 37689 37690function CubicBezierP2( t, p ) { 37691 37692 return 3 * ( 1 - t ) * t * t * p; 37693 37694} 37695 37696function CubicBezierP3( t, p ) { 37697 37698 return t * t * t * p; 37699 37700} 37701 37702function CubicBezier( t, p0, p1, p2, p3 ) { 37703 37704 return CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) + 37705 CubicBezierP3( t, p3 ); 37706 37707} 37708 37709function CubicBezierCurve( v0, v1, v2, v3 ) { 37710 37711 Curve.call( this ); 37712 37713 this.type = 'CubicBezierCurve'; 37714 37715 this.v0 = v0 || new Vector2(); 37716 this.v1 = v1 || new Vector2(); 37717 this.v2 = v2 || new Vector2(); 37718 this.v3 = v3 || new Vector2(); 37719 37720} 37721 37722CubicBezierCurve.prototype = Object.create( Curve.prototype ); 37723CubicBezierCurve.prototype.constructor = CubicBezierCurve; 37724 37725CubicBezierCurve.prototype.isCubicBezierCurve = true; 37726 37727CubicBezierCurve.prototype.getPoint = function ( t, optionalTarget ) { 37728 37729 var point = optionalTarget || new Vector2(); 37730 37731 var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3; 37732 37733 point.set( 37734 CubicBezier( t, v0.x, v1.x, v2.x, v3.x ), 37735 CubicBezier( t, v0.y, v1.y, v2.y, v3.y ) 37736 ); 37737 37738 return point; 37739 37740}; 37741 37742CubicBezierCurve.prototype.copy = function ( source ) { 37743 37744 Curve.prototype.copy.call( this, source ); 37745 37746 this.v0.copy( source.v0 ); 37747 this.v1.copy( source.v1 ); 37748 this.v2.copy( source.v2 ); 37749 this.v3.copy( source.v3 ); 37750 37751 return this; 37752 37753}; 37754 37755CubicBezierCurve.prototype.toJSON = function () { 37756 37757 var data = Curve.prototype.toJSON.call( this ); 37758 37759 data.v0 = this.v0.toArray(); 37760 data.v1 = this.v1.toArray(); 37761 data.v2 = this.v2.toArray(); 37762 data.v3 = this.v3.toArray(); 37763 37764 return data; 37765 37766}; 37767 37768CubicBezierCurve.prototype.fromJSON = function ( json ) { 37769 37770 Curve.prototype.fromJSON.call( this, json ); 37771 37772 this.v0.fromArray( json.v0 ); 37773 this.v1.fromArray( json.v1 ); 37774 this.v2.fromArray( json.v2 ); 37775 this.v3.fromArray( json.v3 ); 37776 37777 return this; 37778 37779}; 37780 37781function CubicBezierCurve3( v0, v1, v2, v3 ) { 37782 37783 Curve.call( this ); 37784 37785 this.type = 'CubicBezierCurve3'; 37786 37787 this.v0 = v0 || new Vector3(); 37788 this.v1 = v1 || new Vector3(); 37789 this.v2 = v2 || new Vector3(); 37790 this.v3 = v3 || new Vector3(); 37791 37792} 37793 37794CubicBezierCurve3.prototype = Object.create( Curve.prototype ); 37795CubicBezierCurve3.prototype.constructor = CubicBezierCurve3; 37796 37797CubicBezierCurve3.prototype.isCubicBezierCurve3 = true; 37798 37799CubicBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) { 37800 37801 var point = optionalTarget || new Vector3(); 37802 37803 var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3; 37804 37805 point.set( 37806 CubicBezier( t, v0.x, v1.x, v2.x, v3.x ), 37807 CubicBezier( t, v0.y, v1.y, v2.y, v3.y ), 37808 CubicBezier( t, v0.z, v1.z, v2.z, v3.z ) 37809 ); 37810 37811 return point; 37812 37813}; 37814 37815CubicBezierCurve3.prototype.copy = function ( source ) { 37816 37817 Curve.prototype.copy.call( this, source ); 37818 37819 this.v0.copy( source.v0 ); 37820 this.v1.copy( source.v1 ); 37821 this.v2.copy( source.v2 ); 37822 this.v3.copy( source.v3 ); 37823 37824 return this; 37825 37826}; 37827 37828CubicBezierCurve3.prototype.toJSON = function () { 37829 37830 var data = Curve.prototype.toJSON.call( this ); 37831 37832 data.v0 = this.v0.toArray(); 37833 data.v1 = this.v1.toArray(); 37834 data.v2 = this.v2.toArray(); 37835 data.v3 = this.v3.toArray(); 37836 37837 return data; 37838 37839}; 37840 37841CubicBezierCurve3.prototype.fromJSON = function ( json ) { 37842 37843 Curve.prototype.fromJSON.call( this, json ); 37844 37845 this.v0.fromArray( json.v0 ); 37846 this.v1.fromArray( json.v1 ); 37847 this.v2.fromArray( json.v2 ); 37848 this.v3.fromArray( json.v3 ); 37849 37850 return this; 37851 37852}; 37853 37854function LineCurve( v1, v2 ) { 37855 37856 Curve.call( this ); 37857 37858 this.type = 'LineCurve'; 37859 37860 this.v1 = v1 || new Vector2(); 37861 this.v2 = v2 || new Vector2(); 37862 37863} 37864 37865LineCurve.prototype = Object.create( Curve.prototype ); 37866LineCurve.prototype.constructor = LineCurve; 37867 37868LineCurve.prototype.isLineCurve = true; 37869 37870LineCurve.prototype.getPoint = function ( t, optionalTarget ) { 37871 37872 var point = optionalTarget || new Vector2(); 37873 37874 if ( t === 1 ) { 37875 37876 point.copy( this.v2 ); 37877 37878 } else { 37879 37880 point.copy( this.v2 ).sub( this.v1 ); 37881 point.multiplyScalar( t ).add( this.v1 ); 37882 37883 } 37884 37885 return point; 37886 37887}; 37888 37889// Line curve is linear, so we can overwrite default getPointAt 37890 37891LineCurve.prototype.getPointAt = function ( u, optionalTarget ) { 37892 37893 return this.getPoint( u, optionalTarget ); 37894 37895}; 37896 37897LineCurve.prototype.getTangent = function ( t, optionalTarget ) { 37898 37899 var tangent = optionalTarget || new Vector2(); 37900 37901 var tangent = tangent.copy( this.v2 ).sub( this.v1 ).normalize(); 37902 37903 return tangent; 37904 37905}; 37906 37907LineCurve.prototype.copy = function ( source ) { 37908 37909 Curve.prototype.copy.call( this, source ); 37910 37911 this.v1.copy( source.v1 ); 37912 this.v2.copy( source.v2 ); 37913 37914 return this; 37915 37916}; 37917 37918LineCurve.prototype.toJSON = function () { 37919 37920 var data = Curve.prototype.toJSON.call( this ); 37921 37922 data.v1 = this.v1.toArray(); 37923 data.v2 = this.v2.toArray(); 37924 37925 return data; 37926 37927}; 37928 37929LineCurve.prototype.fromJSON = function ( json ) { 37930 37931 Curve.prototype.fromJSON.call( this, json ); 37932 37933 this.v1.fromArray( json.v1 ); 37934 this.v2.fromArray( json.v2 ); 37935 37936 return this; 37937 37938}; 37939 37940function LineCurve3( v1, v2 ) { 37941 37942 Curve.call( this ); 37943 37944 this.type = 'LineCurve3'; 37945 37946 this.v1 = v1 || new Vector3(); 37947 this.v2 = v2 || new Vector3(); 37948 37949} 37950 37951LineCurve3.prototype = Object.create( Curve.prototype ); 37952LineCurve3.prototype.constructor = LineCurve3; 37953 37954LineCurve3.prototype.isLineCurve3 = true; 37955 37956LineCurve3.prototype.getPoint = function ( t, optionalTarget ) { 37957 37958 var point = optionalTarget || new Vector3(); 37959 37960 if ( t === 1 ) { 37961 37962 point.copy( this.v2 ); 37963 37964 } else { 37965 37966 point.copy( this.v2 ).sub( this.v1 ); 37967 point.multiplyScalar( t ).add( this.v1 ); 37968 37969 } 37970 37971 return point; 37972 37973}; 37974 37975// Line curve is linear, so we can overwrite default getPointAt 37976 37977LineCurve3.prototype.getPointAt = function ( u, optionalTarget ) { 37978 37979 return this.getPoint( u, optionalTarget ); 37980 37981}; 37982 37983LineCurve3.prototype.copy = function ( source ) { 37984 37985 Curve.prototype.copy.call( this, source ); 37986 37987 this.v1.copy( source.v1 ); 37988 this.v2.copy( source.v2 ); 37989 37990 return this; 37991 37992}; 37993 37994LineCurve3.prototype.toJSON = function () { 37995 37996 var data = Curve.prototype.toJSON.call( this ); 37997 37998 data.v1 = this.v1.toArray(); 37999 data.v2 = this.v2.toArray(); 38000 38001 return data; 38002 38003}; 38004 38005LineCurve3.prototype.fromJSON = function ( json ) { 38006 38007 Curve.prototype.fromJSON.call( this, json ); 38008 38009 this.v1.fromArray( json.v1 ); 38010 this.v2.fromArray( json.v2 ); 38011 38012 return this; 38013 38014}; 38015 38016function QuadraticBezierCurve( v0, v1, v2 ) { 38017 38018 Curve.call( this ); 38019 38020 this.type = 'QuadraticBezierCurve'; 38021 38022 this.v0 = v0 || new Vector2(); 38023 this.v1 = v1 || new Vector2(); 38024 this.v2 = v2 || new Vector2(); 38025 38026} 38027 38028QuadraticBezierCurve.prototype = Object.create( Curve.prototype ); 38029QuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve; 38030 38031QuadraticBezierCurve.prototype.isQuadraticBezierCurve = true; 38032 38033QuadraticBezierCurve.prototype.getPoint = function ( t, optionalTarget ) { 38034 38035 var point = optionalTarget || new Vector2(); 38036 38037 var v0 = this.v0, v1 = this.v1, v2 = this.v2; 38038 38039 point.set( 38040 QuadraticBezier( t, v0.x, v1.x, v2.x ), 38041 QuadraticBezier( t, v0.y, v1.y, v2.y ) 38042 ); 38043 38044 return point; 38045 38046}; 38047 38048QuadraticBezierCurve.prototype.copy = function ( source ) { 38049 38050 Curve.prototype.copy.call( this, source ); 38051 38052 this.v0.copy( source.v0 ); 38053 this.v1.copy( source.v1 ); 38054 this.v2.copy( source.v2 ); 38055 38056 return this; 38057 38058}; 38059 38060QuadraticBezierCurve.prototype.toJSON = function () { 38061 38062 var data = Curve.prototype.toJSON.call( this ); 38063 38064 data.v0 = this.v0.toArray(); 38065 data.v1 = this.v1.toArray(); 38066 data.v2 = this.v2.toArray(); 38067 38068 return data; 38069 38070}; 38071 38072QuadraticBezierCurve.prototype.fromJSON = function ( json ) { 38073 38074 Curve.prototype.fromJSON.call( this, json ); 38075 38076 this.v0.fromArray( json.v0 ); 38077 this.v1.fromArray( json.v1 ); 38078 this.v2.fromArray( json.v2 ); 38079 38080 return this; 38081 38082}; 38083 38084function QuadraticBezierCurve3( v0, v1, v2 ) { 38085 38086 Curve.call( this ); 38087 38088 this.type = 'QuadraticBezierCurve3'; 38089 38090 this.v0 = v0 || new Vector3(); 38091 this.v1 = v1 || new Vector3(); 38092 this.v2 = v2 || new Vector3(); 38093 38094} 38095 38096QuadraticBezierCurve3.prototype = Object.create( Curve.prototype ); 38097QuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3; 38098 38099QuadraticBezierCurve3.prototype.isQuadraticBezierCurve3 = true; 38100 38101QuadraticBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) { 38102 38103 var point = optionalTarget || new Vector3(); 38104 38105 var v0 = this.v0, v1 = this.v1, v2 = this.v2; 38106 38107 point.set( 38108 QuadraticBezier( t, v0.x, v1.x, v2.x ), 38109 QuadraticBezier( t, v0.y, v1.y, v2.y ), 38110 QuadraticBezier( t, v0.z, v1.z, v2.z ) 38111 ); 38112 38113 return point; 38114 38115}; 38116 38117QuadraticBezierCurve3.prototype.copy = function ( source ) { 38118 38119 Curve.prototype.copy.call( this, source ); 38120 38121 this.v0.copy( source.v0 ); 38122 this.v1.copy( source.v1 ); 38123 this.v2.copy( source.v2 ); 38124 38125 return this; 38126 38127}; 38128 38129QuadraticBezierCurve3.prototype.toJSON = function () { 38130 38131 var data = Curve.prototype.toJSON.call( this ); 38132 38133 data.v0 = this.v0.toArray(); 38134 data.v1 = this.v1.toArray(); 38135 data.v2 = this.v2.toArray(); 38136 38137 return data; 38138 38139}; 38140 38141QuadraticBezierCurve3.prototype.fromJSON = function ( json ) { 38142 38143 Curve.prototype.fromJSON.call( this, json ); 38144 38145 this.v0.fromArray( json.v0 ); 38146 this.v1.fromArray( json.v1 ); 38147 this.v2.fromArray( json.v2 ); 38148 38149 return this; 38150 38151}; 38152 38153function SplineCurve( points /* array of Vector2 */ ) { 38154 38155 Curve.call( this ); 38156 38157 this.type = 'SplineCurve'; 38158 38159 this.points = points || []; 38160 38161} 38162 38163SplineCurve.prototype = Object.create( Curve.prototype ); 38164SplineCurve.prototype.constructor = SplineCurve; 38165 38166SplineCurve.prototype.isSplineCurve = true; 38167 38168SplineCurve.prototype.getPoint = function ( t, optionalTarget ) { 38169 38170 var point = optionalTarget || new Vector2(); 38171 38172 var points = this.points; 38173 var p = ( points.length - 1 ) * t; 38174 38175 var intPoint = Math.floor( p ); 38176 var weight = p - intPoint; 38177 38178 var p0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ]; 38179 var p1 = points[ intPoint ]; 38180 var p2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ]; 38181 var p3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ]; 38182 38183 point.set( 38184 CatmullRom( weight, p0.x, p1.x, p2.x, p3.x ), 38185 CatmullRom( weight, p0.y, p1.y, p2.y, p3.y ) 38186 ); 38187 38188 return point; 38189 38190}; 38191 38192SplineCurve.prototype.copy = function ( source ) { 38193 38194 Curve.prototype.copy.call( this, source ); 38195 38196 this.points = []; 38197 38198 for ( var i = 0, l = source.points.length; i < l; i ++ ) { 38199 38200 var point = source.points[ i ]; 38201 38202 this.points.push( point.clone() ); 38203 38204 } 38205 38206 return this; 38207 38208}; 38209 38210SplineCurve.prototype.toJSON = function () { 38211 38212 var data = Curve.prototype.toJSON.call( this ); 38213 38214 data.points = []; 38215 38216 for ( var i = 0, l = this.points.length; i < l; i ++ ) { 38217 38218 var point = this.points[ i ]; 38219 data.points.push( point.toArray() ); 38220 38221 } 38222 38223 return data; 38224 38225}; 38226 38227SplineCurve.prototype.fromJSON = function ( json ) { 38228 38229 Curve.prototype.fromJSON.call( this, json ); 38230 38231 this.points = []; 38232 38233 for ( var i = 0, l = json.points.length; i < l; i ++ ) { 38234 38235 var point = json.points[ i ]; 38236 this.points.push( new Vector2().fromArray( point ) ); 38237 38238 } 38239 38240 return this; 38241 38242}; 38243 38244var Curves = /*#__PURE__*/Object.freeze({ 38245 __proto__: null, 38246 ArcCurve: ArcCurve, 38247 CatmullRomCurve3: CatmullRomCurve3, 38248 CubicBezierCurve: CubicBezierCurve, 38249 CubicBezierCurve3: CubicBezierCurve3, 38250 EllipseCurve: EllipseCurve, 38251 LineCurve: LineCurve, 38252 LineCurve3: LineCurve3, 38253 QuadraticBezierCurve: QuadraticBezierCurve, 38254 QuadraticBezierCurve3: QuadraticBezierCurve3, 38255 SplineCurve: SplineCurve 38256}); 38257 38258/** 38259 * @author zz85 / http://www.lab4games.net/zz85/blog 38260 * 38261 **/ 38262 38263/************************************************************** 38264 * Curved Path - a curve path is simply a array of connected 38265 * curves, but retains the api of a curve 38266 **************************************************************/ 38267 38268function CurvePath() { 38269 38270 Curve.call( this ); 38271 38272 this.type = 'CurvePath'; 38273 38274 this.curves = []; 38275 this.autoClose = false; // Automatically closes the path 38276 38277} 38278 38279CurvePath.prototype = Object.assign( Object.create( Curve.prototype ), { 38280 38281 constructor: CurvePath, 38282 38283 add: function ( curve ) { 38284 38285 this.curves.push( curve ); 38286 38287 }, 38288 38289 closePath: function () { 38290 38291 // Add a line curve if start and end of lines are not connected 38292 var startPoint = this.curves[ 0 ].getPoint( 0 ); 38293 var endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 ); 38294 38295 if ( ! startPoint.equals( endPoint ) ) { 38296 38297 this.curves.push( new LineCurve( endPoint, startPoint ) ); 38298 38299 } 38300 38301 }, 38302 38303 // To get accurate point with reference to 38304 // entire path distance at time t, 38305 // following has to be done: 38306 38307 // 1. Length of each sub path have to be known 38308 // 2. Locate and identify type of curve 38309 // 3. Get t for the curve 38310 // 4. Return curve.getPointAt(t') 38311 38312 getPoint: function ( t ) { 38313 38314 var d = t * this.getLength(); 38315 var curveLengths = this.getCurveLengths(); 38316 var i = 0; 38317 38318 // To think about boundaries points. 38319 38320 while ( i < curveLengths.length ) { 38321 38322 if ( curveLengths[ i ] >= d ) { 38323 38324 var diff = curveLengths[ i ] - d; 38325 var curve = this.curves[ i ]; 38326 38327 var segmentLength = curve.getLength(); 38328 var u = segmentLength === 0 ? 0 : 1 - diff / segmentLength; 38329 38330 return curve.getPointAt( u ); 38331 38332 } 38333 38334 i ++; 38335 38336 } 38337 38338 return null; 38339 38340 // loop where sum != 0, sum > d , sum+1 <d 38341 38342 }, 38343 38344 // We cannot use the default THREE.Curve getPoint() with getLength() because in 38345 // THREE.Curve, getLength() depends on getPoint() but in THREE.CurvePath 38346 // getPoint() depends on getLength 38347 38348 getLength: function () { 38349 38350 var lens = this.getCurveLengths(); 38351 return lens[ lens.length - 1 ]; 38352 38353 }, 38354 38355 // cacheLengths must be recalculated. 38356 updateArcLengths: function () { 38357 38358 this.needsUpdate = true; 38359 this.cacheLengths = null; 38360 this.getCurveLengths(); 38361 38362 }, 38363 38364 // Compute lengths and cache them 38365 // We cannot overwrite getLengths() because UtoT mapping uses it. 38366 38367 getCurveLengths: function () { 38368 38369 // We use cache values if curves and cache array are same length 38370 38371 if ( this.cacheLengths && this.cacheLengths.length === this.curves.length ) { 38372 38373 return this.cacheLengths; 38374 38375 } 38376 38377 // Get length of sub-curve 38378 // Push sums into cached array 38379 38380 var lengths = [], sums = 0; 38381 38382 for ( var i = 0, l = this.curves.length; i < l; i ++ ) { 38383 38384 sums += this.curves[ i ].getLength(); 38385 lengths.push( sums ); 38386 38387 } 38388 38389 this.cacheLengths = lengths; 38390 38391 return lengths; 38392 38393 }, 38394 38395 getSpacedPoints: function ( divisions ) { 38396 38397 if ( divisions === undefined ) divisions = 40; 38398 38399 var points = []; 38400 38401 for ( var i = 0; i <= divisions; i ++ ) { 38402 38403 points.push( this.getPoint( i / divisions ) ); 38404 38405 } 38406 38407 if ( this.autoClose ) { 38408 38409 points.push( points[ 0 ] ); 38410 38411 } 38412 38413 return points; 38414 38415 }, 38416 38417 getPoints: function ( divisions ) { 38418 38419 divisions = divisions || 12; 38420 38421 var points = [], last; 38422 38423 for ( var i = 0, curves = this.curves; i < curves.length; i ++ ) { 38424 38425 var curve = curves[ i ]; 38426 var resolution = ( curve && curve.isEllipseCurve ) ? divisions * 2 38427 : ( curve && ( curve.isLineCurve || curve.isLineCurve3 ) ) ? 1 38428 : ( curve && curve.isSplineCurve ) ? divisions * curve.points.length 38429 : divisions; 38430 38431 var pts = curve.getPoints( resolution ); 38432 38433 for ( var j = 0; j < pts.length; j ++ ) { 38434 38435 var point = pts[ j ]; 38436 38437 if ( last && last.equals( point ) ) continue; // ensures no consecutive points are duplicates 38438 38439 points.push( point ); 38440 last = point; 38441 38442 } 38443 38444 } 38445 38446 if ( this.autoClose && points.length > 1 && ! points[ points.length - 1 ].equals( points[ 0 ] ) ) { 38447 38448 points.push( points[ 0 ] ); 38449 38450 } 38451 38452 return points; 38453 38454 }, 38455 38456 copy: function ( source ) { 38457 38458 Curve.prototype.copy.call( this, source ); 38459 38460 this.curves = []; 38461 38462 for ( var i = 0, l = source.curves.length; i < l; i ++ ) { 38463 38464 var curve = source.curves[ i ]; 38465 38466 this.curves.push( curve.clone() ); 38467 38468 } 38469 38470 this.autoClose = source.autoClose; 38471 38472 return this; 38473 38474 }, 38475 38476 toJSON: function () { 38477 38478 var data = Curve.prototype.toJSON.call( this ); 38479 38480 data.autoClose = this.autoClose; 38481 data.curves = []; 38482 38483 for ( var i = 0, l = this.curves.length; i < l; i ++ ) { 38484 38485 var curve = this.curves[ i ]; 38486 data.curves.push( curve.toJSON() ); 38487 38488 } 38489 38490 return data; 38491 38492 }, 38493 38494 fromJSON: function ( json ) { 38495 38496 Curve.prototype.fromJSON.call( this, json ); 38497 38498 this.autoClose = json.autoClose; 38499 this.curves = []; 38500 38501 for ( var i = 0, l = json.curves.length; i < l; i ++ ) { 38502 38503 var curve = json.curves[ i ]; 38504 this.curves.push( new Curves[ curve.type ]().fromJSON( curve ) ); 38505 38506 } 38507 38508 return this; 38509 38510 } 38511 38512} ); 38513 38514/** 38515 * @author zz85 / http://www.lab4games.net/zz85/blog 38516 * Creates free form 2d path using series of points, lines or curves. 38517 **/ 38518 38519function Path( points ) { 38520 38521 CurvePath.call( this ); 38522 38523 this.type = 'Path'; 38524 38525 this.currentPoint = new Vector2(); 38526 38527 if ( points ) { 38528 38529 this.setFromPoints( points ); 38530 38531 } 38532 38533} 38534 38535Path.prototype = Object.assign( Object.create( CurvePath.prototype ), { 38536 38537 constructor: Path, 38538 38539 setFromPoints: function ( points ) { 38540 38541 this.moveTo( points[ 0 ].x, points[ 0 ].y ); 38542 38543 for ( var i = 1, l = points.length; i < l; i ++ ) { 38544 38545 this.lineTo( points[ i ].x, points[ i ].y ); 38546 38547 } 38548 38549 return this; 38550 38551 }, 38552 38553 moveTo: function ( x, y ) { 38554 38555 this.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying? 38556 38557 return this; 38558 38559 }, 38560 38561 lineTo: function ( x, y ) { 38562 38563 var curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) ); 38564 this.curves.push( curve ); 38565 38566 this.currentPoint.set( x, y ); 38567 38568 return this; 38569 38570 }, 38571 38572 quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) { 38573 38574 var curve = new QuadraticBezierCurve( 38575 this.currentPoint.clone(), 38576 new Vector2( aCPx, aCPy ), 38577 new Vector2( aX, aY ) 38578 ); 38579 38580 this.curves.push( curve ); 38581 38582 this.currentPoint.set( aX, aY ); 38583 38584 return this; 38585 38586 }, 38587 38588 bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) { 38589 38590 var curve = new CubicBezierCurve( 38591 this.currentPoint.clone(), 38592 new Vector2( aCP1x, aCP1y ), 38593 new Vector2( aCP2x, aCP2y ), 38594 new Vector2( aX, aY ) 38595 ); 38596 38597 this.curves.push( curve ); 38598 38599 this.currentPoint.set( aX, aY ); 38600 38601 return this; 38602 38603 }, 38604 38605 splineThru: function ( pts /*Array of Vector*/ ) { 38606 38607 var npts = [ this.currentPoint.clone() ].concat( pts ); 38608 38609 var curve = new SplineCurve( npts ); 38610 this.curves.push( curve ); 38611 38612 this.currentPoint.copy( pts[ pts.length - 1 ] ); 38613 38614 return this; 38615 38616 }, 38617 38618 arc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { 38619 38620 var x0 = this.currentPoint.x; 38621 var y0 = this.currentPoint.y; 38622 38623 this.absarc( aX + x0, aY + y0, aRadius, 38624 aStartAngle, aEndAngle, aClockwise ); 38625 38626 return this; 38627 38628 }, 38629 38630 absarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { 38631 38632 this.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise ); 38633 38634 return this; 38635 38636 }, 38637 38638 ellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { 38639 38640 var x0 = this.currentPoint.x; 38641 var y0 = this.currentPoint.y; 38642 38643 this.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ); 38644 38645 return this; 38646 38647 }, 38648 38649 absellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { 38650 38651 var curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ); 38652 38653 if ( this.curves.length > 0 ) { 38654 38655 // if a previous curve is present, attempt to join 38656 var firstPoint = curve.getPoint( 0 ); 38657 38658 if ( ! firstPoint.equals( this.currentPoint ) ) { 38659 38660 this.lineTo( firstPoint.x, firstPoint.y ); 38661 38662 } 38663 38664 } 38665 38666 this.curves.push( curve ); 38667 38668 var lastPoint = curve.getPoint( 1 ); 38669 this.currentPoint.copy( lastPoint ); 38670 38671 return this; 38672 38673 }, 38674 38675 copy: function ( source ) { 38676 38677 CurvePath.prototype.copy.call( this, source ); 38678 38679 this.currentPoint.copy( source.currentPoint ); 38680 38681 return this; 38682 38683 }, 38684 38685 toJSON: function () { 38686 38687 var data = CurvePath.prototype.toJSON.call( this ); 38688 38689 data.currentPoint = this.currentPoint.toArray(); 38690 38691 return data; 38692 38693 }, 38694 38695 fromJSON: function ( json ) { 38696 38697 CurvePath.prototype.fromJSON.call( this, json ); 38698 38699 this.currentPoint.fromArray( json.currentPoint ); 38700 38701 return this; 38702 38703 } 38704 38705} ); 38706 38707/** 38708 * @author zz85 / http://www.lab4games.net/zz85/blog 38709 * Defines a 2d shape plane using paths. 38710 **/ 38711 38712// STEP 1 Create a path. 38713// STEP 2 Turn path into shape. 38714// STEP 3 ExtrudeGeometry takes in Shape/Shapes 38715// STEP 3a - Extract points from each shape, turn to vertices 38716// STEP 3b - Triangulate each shape, add faces. 38717 38718function Shape( points ) { 38719 38720 Path.call( this, points ); 38721 38722 this.uuid = MathUtils.generateUUID(); 38723 38724 this.type = 'Shape'; 38725 38726 this.holes = []; 38727 38728} 38729 38730Shape.prototype = Object.assign( Object.create( Path.prototype ), { 38731 38732 constructor: Shape, 38733 38734 getPointsHoles: function ( divisions ) { 38735 38736 var holesPts = []; 38737 38738 for ( var i = 0, l = this.holes.length; i < l; i ++ ) { 38739 38740 holesPts[ i ] = this.holes[ i ].getPoints( divisions ); 38741 38742 } 38743 38744 return holesPts; 38745 38746 }, 38747 38748 // get points of shape and holes (keypoints based on segments parameter) 38749 38750 extractPoints: function ( divisions ) { 38751 38752 return { 38753 38754 shape: this.getPoints( divisions ), 38755 holes: this.getPointsHoles( divisions ) 38756 38757 }; 38758 38759 }, 38760 38761 copy: function ( source ) { 38762 38763 Path.prototype.copy.call( this, source ); 38764 38765 this.holes = []; 38766 38767 for ( var i = 0, l = source.holes.length; i < l; i ++ ) { 38768 38769 var hole = source.holes[ i ]; 38770 38771 this.holes.push( hole.clone() ); 38772 38773 } 38774 38775 return this; 38776 38777 }, 38778 38779 toJSON: function () { 38780 38781 var data = Path.prototype.toJSON.call( this ); 38782 38783 data.uuid = this.uuid; 38784 data.holes = []; 38785 38786 for ( var i = 0, l = this.holes.length; i < l; i ++ ) { 38787 38788 var hole = this.holes[ i ]; 38789 data.holes.push( hole.toJSON() ); 38790 38791 } 38792 38793 return data; 38794 38795 }, 38796 38797 fromJSON: function ( json ) { 38798 38799 Path.prototype.fromJSON.call( this, json ); 38800 38801 this.uuid = json.uuid; 38802 this.holes = []; 38803 38804 for ( var i = 0, l = json.holes.length; i < l; i ++ ) { 38805 38806 var hole = json.holes[ i ]; 38807 this.holes.push( new Path().fromJSON( hole ) ); 38808 38809 } 38810 38811 return this; 38812 38813 } 38814 38815} ); 38816 38817/** 38818 * @author mrdoob / http://mrdoob.com/ 38819 * @author alteredq / http://alteredqualia.com/ 38820 */ 38821 38822function Light( color, intensity ) { 38823 38824 Object3D.call( this ); 38825 38826 this.type = 'Light'; 38827 38828 this.color = new Color( color ); 38829 this.intensity = intensity !== undefined ? intensity : 1; 38830 38831 this.receiveShadow = undefined; 38832 38833} 38834 38835Light.prototype = Object.assign( Object.create( Object3D.prototype ), { 38836 38837 constructor: Light, 38838 38839 isLight: true, 38840 38841 copy: function ( source ) { 38842 38843 Object3D.prototype.copy.call( this, source ); 38844 38845 this.color.copy( source.color ); 38846 this.intensity = source.intensity; 38847 38848 return this; 38849 38850 }, 38851 38852 toJSON: function ( meta ) { 38853 38854 var data = Object3D.prototype.toJSON.call( this, meta ); 38855 38856 data.object.color = this.color.getHex(); 38857 data.object.intensity = this.intensity; 38858 38859 if ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex(); 38860 38861 if ( this.distance !== undefined ) data.object.distance = this.distance; 38862 if ( this.angle !== undefined ) data.object.angle = this.angle; 38863 if ( this.decay !== undefined ) data.object.decay = this.decay; 38864 if ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra; 38865 38866 if ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON(); 38867 38868 return data; 38869 38870 } 38871 38872} ); 38873 38874/** 38875 * @author alteredq / http://alteredqualia.com/ 38876 */ 38877 38878function HemisphereLight( skyColor, groundColor, intensity ) { 38879 38880 Light.call( this, skyColor, intensity ); 38881 38882 this.type = 'HemisphereLight'; 38883 38884 this.castShadow = undefined; 38885 38886 this.position.copy( Object3D.DefaultUp ); 38887 this.updateMatrix(); 38888 38889 this.groundColor = new Color( groundColor ); 38890 38891} 38892 38893HemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), { 38894 38895 constructor: HemisphereLight, 38896 38897 isHemisphereLight: true, 38898 38899 copy: function ( source ) { 38900 38901 Light.prototype.copy.call( this, source ); 38902 38903 this.groundColor.copy( source.groundColor ); 38904 38905 return this; 38906 38907 } 38908 38909} ); 38910 38911/** 38912 * @author mrdoob / http://mrdoob.com/ 38913 */ 38914 38915function LightShadow( camera ) { 38916 38917 this.camera = camera; 38918 38919 this.bias = 0; 38920 this.radius = 1; 38921 38922 this.mapSize = new Vector2( 512, 512 ); 38923 38924 this.map = null; 38925 this.mapPass = null; 38926 this.matrix = new Matrix4(); 38927 38928 this._frustum = new Frustum(); 38929 this._frameExtents = new Vector2( 1, 1 ); 38930 38931 this._viewportCount = 1; 38932 38933 this._viewports = [ 38934 38935 new Vector4( 0, 0, 1, 1 ) 38936 38937 ]; 38938 38939} 38940 38941Object.assign( LightShadow.prototype, { 38942 38943 _projScreenMatrix: new Matrix4(), 38944 38945 _lightPositionWorld: new Vector3(), 38946 38947 _lookTarget: new Vector3(), 38948 38949 getViewportCount: function () { 38950 38951 return this._viewportCount; 38952 38953 },
vendor: 6,365 bytes, lines 38954-39232
38954 38955 getFrustum: function () { 38956 38957 return this._frustum; 38958 38959 }, 38960 38961 updateMatrices: function ( light ) { 38962 38963 var shadowCamera = this.camera, 38964 shadowMatrix = this.matrix, 38965 projScreenMatrix = this._projScreenMatrix, 38966 lookTarget = this._lookTarget, 38967 lightPositionWorld = this._lightPositionWorld; 38968 38969 lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); 38970 shadowCamera.position.copy( lightPositionWorld ); 38971 38972 lookTarget.setFromMatrixPosition( light.target.matrixWorld ); 38973 shadowCamera.lookAt( lookTarget ); 38974 shadowCamera.updateMatrixWorld(); 38975 38976 projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse ); 38977 this._frustum.setFromProjectionMatrix( projScreenMatrix ); 38978 38979 shadowMatrix.set( 38980 0.5, 0.0, 0.0, 0.5, 38981 0.0, 0.5, 0.0, 0.5, 38982 0.0, 0.0, 0.5, 0.5, 38983 0.0, 0.0, 0.0, 1.0 38984 ); 38985 38986 shadowMatrix.multiply( shadowCamera.projectionMatrix ); 38987 shadowMatrix.multiply( shadowCamera.matrixWorldInverse ); 38988 38989 }, 38990 38991 getViewport: function ( viewportIndex ) { 38992 38993 return this._viewports[ viewportIndex ]; 38994 38995 }, 38996 38997 getFrameExtents: function () { 38998 38999 return this._frameExtents; 39000 39001 }, 39002 39003 copy: function ( source ) { 39004 39005 this.camera = source.camera.clone(); 39006 39007 this.bias = source.bias; 39008 this.radius = source.radius; 39009 39010 this.mapSize.copy( source.mapSize ); 39011 39012 return this; 39013 39014 }, 39015 39016 clone: function () { 39017 39018 return new this.constructor().copy( this ); 39019 39020 }, 39021 39022 toJSON: function () { 39023 39024 var object = {}; 39025 39026 if ( this.bias !== 0 ) object.bias = this.bias; 39027 if ( this.radius !== 1 ) object.radius = this.radius; 39028 if ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray(); 39029 39030 object.camera = this.camera.toJSON( false ).object; 39031 delete object.camera.matrix; 39032 39033 return object; 39034 39035 } 39036 39037} ); 39038 39039/** 39040 * @author mrdoob / http://mrdoob.com/ 39041 */ 39042 39043function SpotLightShadow() { 39044 39045 LightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) ); 39046 39047} 39048 39049SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), { 39050 39051 constructor: SpotLightShadow, 39052 39053 isSpotLightShadow: true, 39054 39055 updateMatrices: function ( light ) { 39056 39057 var camera = this.camera; 39058 39059 var fov = MathUtils.RAD2DEG * 2 * light.angle; 39060 var aspect = this.mapSize.width / this.mapSize.height; 39061 var far = light.distance || camera.far; 39062 39063 if ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) { 39064 39065 camera.fov = fov; 39066 camera.aspect = aspect; 39067 camera.far = far; 39068 camera.updateProjectionMatrix(); 39069 39070 } 39071 39072 LightShadow.prototype.updateMatrices.call( this, light ); 39073 39074 } 39075 39076} ); 39077 39078/** 39079 * @author alteredq / http://alteredqualia.com/ 39080 */ 39081 39082function SpotLight( color, intensity, distance, angle, penumbra, decay ) { 39083 39084 Light.call( this, color, intensity ); 39085 39086 this.type = 'SpotLight'; 39087 39088 this.position.copy( Object3D.DefaultUp ); 39089 this.updateMatrix(); 39090 39091 this.target = new Object3D(); 39092 39093 Object.defineProperty( this, 'power', { 39094 get: function () { 39095 39096 // intensity = power per solid angle. 39097 // ref: equation (17) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf 39098 return this.intensity * Math.PI; 39099 39100 }, 39101 set: function ( power ) { 39102 39103 // intensity = power per solid angle. 39104 // ref: equation (17) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf 39105 this.intensity = power / Math.PI; 39106 39107 } 39108 } ); 39109 39110 this.distance = ( distance !== undefined ) ? distance : 0; 39111 this.angle = ( angle !== undefined ) ? angle : Math.PI / 3; 39112 this.penumbra = ( penumbra !== undefined ) ? penumbra : 0; 39113 this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. 39114 39115 this.shadow = new SpotLightShadow(); 39116 39117} 39118 39119SpotLight.prototype = Object.assign( Object.create( Light.prototype ), { 39120 39121 constructor: SpotLight, 39122 39123 isSpotLight: true, 39124 39125 copy: function ( source ) { 39126 39127 Light.prototype.copy.call( this, source ); 39128 39129 this.distance = source.distance; 39130 this.angle = source.angle; 39131 this.penumbra = source.penumbra; 39132 this.decay = source.decay; 39133 39134 this.target = source.target.clone(); 39135 39136 this.shadow = source.shadow.clone(); 39137 39138 return this; 39139 39140 } 39141 39142} ); 39143 39144function PointLightShadow() { 39145 39146 LightShadow.call( this, new PerspectiveCamera( 90, 1, 0.5, 500 ) ); 39147 39148 this._frameExtents = new Vector2( 4, 2 ); 39149 39150 this._viewportCount = 6; 39151 39152 this._viewports = [ 39153 // These viewports map a cube-map onto a 2D texture with the 39154 // following orientation: 39155 // 39156 // xzXZ 39157 // y Y 39158 // 39159 // X - Positive x direction 39160 // x - Negative x direction 39161 // Y - Positive y direction 39162 // y - Negative y direction 39163 // Z - Positive z direction 39164 // z - Negative z direction 39165 39166 // positive X 39167 new Vector4( 2, 1, 1, 1 ), 39168 // negative X 39169 new Vector4( 0, 1, 1, 1 ), 39170 // positive Z 39171 new Vector4( 3, 1, 1, 1 ), 39172 // negative Z 39173 new Vector4( 1, 1, 1, 1 ), 39174 // positive Y 39175 new Vector4( 3, 0, 1, 1 ), 39176 // negative Y 39177 new Vector4( 1, 0, 1, 1 ) 39178 ]; 39179 39180 this._cubeDirections = [ 39181 new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ), 39182 new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 ) 39183 ]; 39184 39185 this._cubeUps = [ 39186 new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), 39187 new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 ) 39188 ]; 39189 39190} 39191 39192PointLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), { 39193 39194 constructor: PointLightShadow, 39195 39196 isPointLightShadow: true, 39197 39198 updateMatrices: function ( light, viewportIndex ) { 39199 39200 if ( viewportIndex === undefined ) viewportIndex = 0; 39201 39202 var camera = this.camera, 39203 shadowMatrix = this.matrix, 39204 lightPositionWorld = this._lightPositionWorld, 39205 lookTarget = this._lookTarget, 39206 projScreenMatrix = this._projScreenMatrix; 39207 39208 lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); 39209 camera.position.copy( lightPositionWorld ); 39210 39211 lookTarget.copy( camera.position ); 39212 lookTarget.add( this._cubeDirections[ viewportIndex ] ); 39213 camera.up.copy( this._cubeUps[ viewportIndex ] ); 39214 camera.lookAt( lookTarget ); 39215 camera.updateMatrixWorld(); 39216 39217 shadowMatrix.makeTranslation( - lightPositionWorld.x, - lightPositionWorld.y, - lightPositionWorld.z ); 39218 39219 projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); 39220 this._frustum.setFromProjectionMatrix( projScreenMatrix ); 39221 39222 } 39223 39224} ); 39225 39226/** 39227 * @author mrdoob / http://mrdoob.com/ 39228 */ 39229 39230 39231function PointLight( color, intensity, distance, decay ) { 39232
39233 Light.call( this, color, intensity ); 39234 39235 this.type = 'PointLight'; 39236 39237 Object.defineProperty( this, 'power', { 39238 get: function () { 39239 39240 // intensity = power per solid angle. 39241 // ref: equation (15) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf 39242 return this.intensity * 4 * Math.PI; 39243 39244 }, 39245 set: function ( power ) { 39246 39247 // intensity = power per solid angle. 39248 // ref: equation (15) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf 39249 this.intensity = power / ( 4 * Math.PI ); 39250 39251 } 39252 } ); 39253 39254 this.distance = ( distance !== undefined ) ? distance : 0; 39255 this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. 39256 39257 this.shadow = new PointLightShadow(); 39258 39259} 39260 39261PointLight.prototype = Object.assign( Object.create( Light.prototype ), { 39262 39263 constructor: PointLight, 39264 39265 isPointLight: true, 39266 39267 copy: function ( source ) { 39268 39269 Light.prototype.copy.call( this, source ); 39270 39271 this.distance = source.distance; 39272 this.decay = source.decay; 39273 39274 this.shadow = source.shadow.clone(); 39275 39276 return this; 39277 39278 } 39279 39280} ); 39281 39282/** 39283 * @author alteredq / http://alteredqualia.com/ 39284 * @author arose / http://github.com/arose 39285 */ 39286 39287function OrthographicCamera( left, right, top, bottom, near, far ) { 39288 39289 Camera.call( this ); 39290 39291 this.type = 'OrthographicCamera'; 39292 39293 this.zoom = 1; 39294 this.view = null; 39295 39296 this.left = ( left !== undefined ) ? left : - 1; 39297 this.right = ( right !== undefined ) ? right : 1; 39298 this.top = ( top !== undefined ) ? top : 1; 39299 this.bottom = ( bottom !== undefined ) ? bottom : - 1; 39300 39301 this.near = ( near !== undefined ) ? near : 0.1; 39302 this.far = ( far !== undefined ) ? far : 2000; 39303 39304 this.updateProjectionMatrix(); 39305 39306} 39307 39308OrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), { 39309 39310 constructor: OrthographicCamera, 39311 39312 isOrthographicCamera: true, 39313 39314 copy: function ( source, recursive ) { 39315 39316 Camera.prototype.copy.call( this, source, recursive ); 39317 39318 this.left = source.left; 39319 this.right = source.right; 39320 this.top = source.top; 39321 this.bottom = source.bottom; 39322 this.near = source.near; 39323 this.far = source.far; 39324 39325 this.zoom = source.zoom; 39326 this.view = source.view === null ? null : Object.assign( {}, source.view ); 39327 39328 return this; 39329 39330 }, 39331 39332 setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) { 39333 39334 if ( this.view === null ) { 39335 39336 this.view = { 39337 enabled: true, 39338 fullWidth: 1, 39339 fullHeight: 1, 39340 offsetX: 0, 39341 offsetY: 0, 39342 width: 1, 39343 height: 1 39344 }; 39345 39346 } 39347 39348 this.view.enabled = true; 39349 this.view.fullWidth = fullWidth; 39350 this.view.fullHeight = fullHeight; 39351 this.view.offsetX = x; 39352 this.view.offsetY = y; 39353 this.view.width = width; 39354 this.view.height = height; 39355 39356 this.updateProjectionMatrix(); 39357 39358 }, 39359 39360 clearViewOffset: function () { 39361 39362 if ( this.view !== null ) { 39363 39364 this.view.enabled = false; 39365 39366 } 39367 39368 this.updateProjectionMatrix(); 39369 39370 }, 39371 39372 updateProjectionMatrix: function () { 39373 39374 var dx = ( this.right - this.left ) / ( 2 * this.zoom ); 39375 var dy = ( this.top - this.bottom ) / ( 2 * this.zoom ); 39376 var cx = ( this.right + this.left ) / 2; 39377 var cy = ( this.top + this.bottom ) / 2; 39378 39379 var left = cx - dx; 39380 var right = cx + dx; 39381 var top = cy + dy; 39382 var bottom = cy - dy; 39383 39384 if ( this.view !== null && this.view.enabled ) { 39385 39386 var scaleW = ( this.right - this.left ) / this.view.fullWidth / this.zoom; 39387 var scaleH = ( this.top - this.bottom ) / this.view.fullHeight / this.zoom; 39388 39389 left += scaleW * this.view.offsetX; 39390 right = left + scaleW * this.view.width; 39391 top -= scaleH * this.view.offsetY; 39392 bottom = top - scaleH * this.view.height; 39393 39394 } 39395 39396 this.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far ); 39397 39398 this.projectionMatrixInverse.getInverse( this.projectionMatrix ); 39399 39400 }, 39401 39402 toJSON: function ( meta ) { 39403 39404 var data = Object3D.prototype.toJSON.call( this, meta ); 39405 39406 data.object.zoom = this.zoom; 39407 data.object.left = this.left; 39408 data.object.right = this.right; 39409 data.object.top = this.top; 39410 data.object.bottom = this.bottom; 39411 data.object.near = this.near; 39412 data.object.far = this.far; 39413 39414 if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); 39415 39416 return data; 39417 39418 } 39419 39420} ); 39421 39422/** 39423 * @author mrdoob / http://mrdoob.com/ 39424 */ 39425 39426function DirectionalLightShadow() { 39427
39428 LightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) ); 39429 39430} 39431 39432DirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), { 39433 39434 constructor: DirectionalLightShadow, 39435 39436 isDirectionalLightShadow: true, 39437 39438 updateMatrices: function ( light ) { 39439 39440 LightShadow.prototype.updateMatrices.call( this, light ); 39441 39442 } 39443 39444} ); 39445 39446/** 39447 * @author mrdoob / http://mrdoob.com/ 39448 * @author alteredq / http://alteredqualia.com/ 39449 */ 39450 39451function DirectionalLight( color, intensity ) { 39452 39453 Light.call( this, color, intensity ); 39454 39455 this.type = 'DirectionalLight'; 39456 39457 this.position.copy( Object3D.DefaultUp ); 39458 this.updateMatrix(); 39459 39460 this.target = new Object3D(); 39461 39462 this.shadow = new DirectionalLightShadow(); 39463 39464} 39465 39466DirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), { 39467 39468 constructor: DirectionalLight, 39469 39470 isDirectionalLight: true, 39471 39472 copy: function ( source ) { 39473 39474 Light.prototype.copy.call( this, source ); 39475 39476 this.target = source.target.clone(); 39477 39478 this.shadow = source.shadow.clone(); 39479 39480 return this; 39481 39482 } 39483 39484} ); 39485 39486/** 39487 * @author mrdoob / http://mrdoob.com/ 39488 */ 39489 39490function AmbientLight( color, intensity ) { 39491 39492 Light.call( this, color, intensity ); 39493 39494 this.type = 'AmbientLight'; 39495 39496 this.castShadow = undefined; 39497 39498} 39499 39500AmbientLight.prototype = Object.assign( Object.create( Light.prototype ), { 39501 39502 constructor: AmbientLight, 39503 39504 isAmbientLight: true 39505 39506} ); 39507 39508/** 39509 * @author abelnation / http://github.com/abelnation 39510 */ 39511 39512function RectAreaLight( color, intensity, width, height ) { 39513 39514 Light.call( this, color, intensity ); 39515 39516 this.type = 'RectAreaLight'; 39517 39518 this.width = ( width !== undefined ) ? width : 10; 39519 this.height = ( height !== undefined ) ? height : 10; 39520 39521} 39522 39523RectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), { 39524 39525 constructor: RectAreaLight, 39526 39527 isRectAreaLight: true, 39528 39529 copy: function ( source ) { 39530 39531 Light.prototype.copy.call( this, source ); 39532 39533 this.width = source.width; 39534 this.height = source.height; 39535 39536 return this; 39537 39538 }, 39539 39540 toJSON: function ( meta ) { 39541 39542 var data = Light.prototype.toJSON.call( this, meta ); 39543 39544 data.object.width = this.width; 39545 data.object.height = this.height; 39546 39547 return data; 39548 39549 } 39550 39551} ); 39552 39553/** 39554 * @author bhouston / http://clara.io 39555 * @author WestLangley / http://github.com/WestLangley 39556 * 39557 * Primary reference: 39558 * https://graphics.stanford.edu/papers/envmap/envmap.pdf 39559 * 39560 * Secondary reference: 39561 * https://www.ppsloan.org/publications/StupidSH36.pdf 39562 */ 39563 39564// 3-band SH defined by 9 coefficients 39565 39566function SphericalHarmonics3() { 39567 39568 this.coefficients = []; 39569 39570 for ( var i = 0; i < 9; i ++ ) { 39571 39572 this.coefficients.push( new Vector3() ); 39573 39574 } 39575 39576} 39577 39578Object.assign( SphericalHarmonics3.prototype, { 39579 39580 isSphericalHarmonics3: true, 39581 39582 set: function ( coefficients ) { 39583 39584 for ( var i = 0; i < 9; i ++ ) { 39585 39586 this.coefficients[ i ].copy( coefficients[ i ] ); 39587 39588 } 39589 39590 return this; 39591 39592 }, 39593 39594 zero: function () { 39595 39596 for ( var i = 0; i < 9; i ++ ) { 39597 39598 this.coefficients[ i ].set( 0, 0, 0 ); 39599 39600 } 39601 39602 return this; 39603 39604 }, 39605 39606 // get the radiance in the direction of the normal 39607 // target is a Vector3 39608 getAt: function ( normal, target ) { 39609 39610 // normal is assumed to be unit length 39611 39612 var x = normal.x, y = normal.y, z = normal.z; 39613 39614 var coeff = this.coefficients; 39615 39616 // band 0 39617 target.copy( coeff[ 0 ] ).multiplyScalar( 0.282095 ); 39618 39619 // band 1 39620 target.addScaledVector( coeff[ 1 ], 0.488603 * y ); 39621 target.addScaledVector( coeff[ 2 ], 0.488603 * z ); 39622 target.addScaledVector( coeff[ 3 ], 0.488603 * x ); 39623 39624 // band 2 39625 target.addScaledVector( coeff[ 4 ], 1.092548 * ( x * y ) ); 39626 target.addScaledVector( coeff[ 5 ], 1.092548 * ( y * z ) ); 39627 target.addScaledVector( coeff[ 6 ], 0.315392 * ( 3.0 * z * z - 1.0 ) ); 39628 target.addScaledVector( coeff[ 7 ], 1.092548 * ( x * z ) ); 39629 target.addScaledVector( coeff[ 8 ], 0.546274 * ( x * x - y * y ) ); 39630 39631 return target; 39632 39633 }, 39634 39635 // get the irradiance (radiance convolved with cosine lobe) in the direction of the normal 39636 // target is a Vector3 39637 // https://graphics.stanford.edu/papers/envmap/envmap.pdf 39638 getIrradianceAt: function ( normal, target ) { 39639 39640 // normal is assumed to be unit length 39641 39642 var x = normal.x, y = normal.y, z = normal.z; 39643 39644 var coeff = this.coefficients; 39645 39646 // band 0 39647 target.copy( coeff[ 0 ] ).multiplyScalar( 0.886227 ); // Ï * 0.282095 39648 39649 // band 1 39650 target.addScaledVector( coeff[ 1 ], 2.0 * 0.511664 * y ); // ( 2 * Ï / 3 ) * 0.488603 39651 target.addScaledVector( coeff[ 2 ], 2.0 * 0.511664 * z ); 39652 target.addScaledVector( coeff[ 3 ], 2.0 * 0.511664 * x ); 39653 39654 // band 2 39655 target.addScaledVector( coeff[ 4 ], 2.0 * 0.429043 * x * y ); // ( Ï / 4 ) * 1.092548 39656 target.addScaledVector( coeff[ 5 ], 2.0 * 0.429043 * y * z ); 39657 target.addScaledVector( coeff[ 6 ], 0.743125 * z * z - 0.247708 ); // ( Ï / 4 ) * 0.315392 * 3 39658 target.addScaledVector( coeff[ 7 ], 2.0 * 0.429043 * x * z ); 39659 target.addScaledVector( coeff[ 8 ], 0.429043 * ( x * x - y * y ) ); // ( Ï / 4 ) * 0.546274 39660 39661 return target; 39662 39663 }, 39664 39665 add: function ( sh ) { 39666 39667 for ( var i = 0; i < 9; i ++ ) { 39668 39669 this.coefficients[ i ].add( sh.coefficients[ i ] ); 39670 39671 } 39672 39673 return this; 39674 39675 }, 39676 39677 addScaledSH: function ( sh, s ) { 39678 39679 for ( var i = 0; i < 9; i ++ ) { 39680
39681 this.coefficients[ i ].addScaledVector( sh.coefficients[ i ], s ); 39682 39683 } 39684 39685 return this; 39686 39687 }, 39688 39689 scale: function ( s ) { 39690 39691 for ( var i = 0; i < 9; i ++ ) { 39692 39693 this.coefficients[ i ].multiplyScalar( s ); 39694 39695 } 39696 39697 return this; 39698 39699 }, 39700 39701 lerp: function ( sh, alpha ) { 39702 39703 for ( var i = 0; i < 9; i ++ ) { 39704 39705 this.coefficients[ i ].lerp( sh.coefficients[ i ], alpha ); 39706 39707 } 39708 39709 return this; 39710 39711 }, 39712 39713 equals: function ( sh ) { 39714 39715 for ( var i = 0; i < 9; i ++ ) { 39716 39717 if ( ! this.coefficients[ i ].equals( sh.coefficients[ i ] ) ) { 39718 39719 return false; 39720 39721 } 39722 39723 } 39724 39725 return true; 39726 39727 }, 39728 39729 copy: function ( sh ) { 39730 39731 return this.set( sh.coefficients ); 39732 39733 }, 39734 39735 clone: function () { 39736 39737 return new this.constructor().copy( this ); 39738 39739 }, 39740 39741 fromArray: function ( array, offset ) { 39742 39743 if ( offset === undefined ) offset = 0; 39744 39745 var coefficients = this.coefficients; 39746 39747 for ( var i = 0; i < 9; i ++ ) { 39748 39749 coefficients[ i ].fromArray( array, offset + ( i * 3 ) ); 39750 39751 } 39752 39753 return this; 39754 39755 }, 39756 39757 toArray: function ( array, offset ) { 39758 39759 if ( array === undefined ) array = []; 39760 if ( offset === undefined ) offset = 0; 39761 39762 var coefficients = this.coefficients; 39763 39764 for ( var i = 0; i < 9; i ++ ) { 39765 39766 coefficients[ i ].toArray( array, offset + ( i * 3 ) ); 39767 39768 } 39769 39770 return array; 39771 39772 } 39773 39774} ); 39775 39776Object.assign( SphericalHarmonics3, { 39777 39778 // evaluate the basis functions 39779 // shBasis is an Array[ 9 ] 39780 getBasisAt: function ( normal, shBasis ) { 39781 39782 // normal is assumed to be unit length 39783 39784 var x = normal.x, y = normal.y, z = normal.z; 39785 39786 // band 0 39787 shBasis[ 0 ] = 0.282095; 39788 39789 // band 1 39790 shBasis[ 1 ] = 0.488603 * y; 39791 shBasis[ 2 ] = 0.488603 * z; 39792 shBasis[ 3 ] = 0.488603 * x; 39793 39794 // band 2 39795 shBasis[ 4 ] = 1.092548 * x * y; 39796 shBasis[ 5 ] = 1.092548 * y * z; 39797 shBasis[ 6 ] = 0.315392 * ( 3 * z * z - 1 ); 39798 shBasis[ 7 ] = 1.092548 * x * z; 39799 shBasis[ 8 ] = 0.546274 * ( x * x - y * y ); 39800 39801 } 39802 39803} ); 39804 39805/** 39806 * @author WestLangley / http://github.com/WestLangley 39807 * 39808 * A LightProbe is a source of indirect-diffuse light 39809 */ 39810 39811function LightProbe( sh, intensity ) { 39812 39813 Light.call( this, undefined, intensity ); 39814 39815 this.type = 'LightProbe'; 39816 39817 this.sh = ( sh !== undefined ) ? sh : new SphericalHarmonics3(); 39818 39819} 39820 39821LightProbe.prototype = Object.assign( Object.create( Light.prototype ), { 39822 39823 constructor: LightProbe, 39824 39825 isLightProbe: true, 39826 39827 copy: function ( source ) { 39828 39829 Light.prototype.copy.call( this, source ); 39830 39831 this.sh.copy( source.sh ); 39832 39833 return this; 39834 39835 }, 39836 39837 fromJSON: function ( json ) { 39838 39839 this.intensity = json.intensity; // TODO: Move this bit to Light.fromJSON(); 39840 this.sh.fromArray( json.sh ); 39841 39842 return this; 39843 39844 }, 39845 39846 toJSON: function ( meta ) { 39847 39848 var data = Light.prototype.toJSON.call( this, meta ); 39849 39850 data.object.sh = this.sh.toArray(); 39851 39852 return data; 39853 39854 } 39855 39856} ); 39857 39858/** 39859 * @author mrdoob / http://mrdoob.com/ 39860 */ 39861 39862function MaterialLoader( manager ) { 39863 39864 Loader.call( this, manager ); 39865 39866 this.textures = {}; 39867 39868} 39869 39870MaterialLoader.prototype = Object.assign( Object.create( Loader.prototype ), { 39871 39872 constructor: MaterialLoader, 39873 39874 load: function ( url, onLoad, onProgress, onError ) { 39875 39876 var scope = this; 39877 39878 var loader = new FileLoader( scope.manager ); 39879 loader.setPath( scope.path ); 39880 loader.load( url, function ( text ) { 39881 39882 onLoad( scope.parse( JSON.parse( text ) ) ); 39883 39884 }, onProgress, onError ); 39885 39886 }, 39887 39888 parse: function ( json ) { 39889 39890 var textures = this.textures; 39891 39892 function getTexture( name ) { 39893 39894 if ( textures[ name ] === undefined ) { 39895 39896 console.warn( 'THREE.MaterialLoader: Undefined texture', name ); 39897 39898 } 39899 39900 return textures[ name ]; 39901 39902 } 39903 39904 var material = new Materials[ json.type ](); 39905 39906 if ( json.uuid !== undefined ) material.uuid = json.uuid; 39907 if ( json.name !== undefined ) material.name = json.name; 39908 if ( json.color !== undefined ) material.color.setHex( json.color ); 39909 if ( json.roughness !== undefined ) material.roughness = json.roughness; 39910 if ( json.metalness !== undefined ) material.metalness = json.metalness; 39911 if ( json.sheen !== undefined ) material.sheen = new Color().setHex( json.sheen ); 39912 if ( json.emissive !== undefined ) material.emissive.setHex( json.emissive ); 39913 if ( json.specular !== undefined ) material.specular.setHex( json.specular ); 39914 if ( json.shininess !== undefined ) material.shininess = json.shininess; 39915 if ( json.clearcoat !== undefined ) material.clearcoat = json.clearcoat; 39916 if ( json.clearcoatRoughness !== undefined ) material.clearcoatRoughness = json.clearcoatRoughness; 39917 if ( json.fog !== undefined ) material.fog = json.fog; 39918 if ( json.flatShading !== undefined ) material.flatShading = json.flatShading; 39919 if ( json.blending !== undefined ) material.blending = json.blending; 39920 if ( json.combine !== undefined ) material.combine = json.combine; 39921 if ( json.side !== undefined ) material.side = json.side; 39922 if ( json.opacity !== undefined ) material.opacity = json.opacity; 39923 if ( json.transparent !== undefined ) material.transparent = json.transparent; 39924 if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest; 39925 if ( json.depthTest !== undefined ) material.depthTest = json.depthTest; 39926 if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite; 39927 if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite; 39928 39929 if ( json.stencilWrite !== undefined ) material.stencilWrite = json.stencilWrite; 39930 if ( json.stencilWriteMask !== undefined ) material.stencilWriteMask = json.stencilWriteMask; 39931 if ( json.stencilFunc !== undefined ) material.stencilFunc = json.stencilFunc; 39932 if ( json.stencilRef !== undefined ) material.stencilRef = json.stencilRef; 39933 if ( json.stencilFuncMask !== undefined ) material.stencilFuncMask = json.stencilFuncMask;
vendor: 8,815 bytes, lines 39934-40232
39934 if ( json.stencilFail !== undefined ) material.stencilFail = json.stencilFail; 39935 if ( json.stencilZFail !== undefined ) material.stencilZFail = json.stencilZFail; 39936 if ( json.stencilZPass !== undefined ) material.stencilZPass = json.stencilZPass; 39937 39938 if ( json.wireframe !== undefined ) material.wireframe = json.wireframe; 39939 if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth; 39940 if ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap; 39941 if ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin; 39942 39943 if ( json.rotation !== undefined ) material.rotation = json.rotation; 39944 39945 if ( json.linewidth !== 1 ) material.linewidth = json.linewidth; 39946 if ( json.dashSize !== undefined ) material.dashSize = json.dashSize; 39947 if ( json.gapSize !== undefined ) material.gapSize = json.gapSize; 39948 if ( json.scale !== undefined ) material.scale = json.scale; 39949 39950 if ( json.polygonOffset !== undefined ) material.polygonOffset = json.polygonOffset; 39951 if ( json.polygonOffsetFactor !== undefined ) material.polygonOffsetFactor = json.polygonOffsetFactor; 39952 if ( json.polygonOffsetUnits !== undefined ) material.polygonOffsetUnits = json.polygonOffsetUnits; 39953 39954 if ( json.skinning !== undefined ) material.skinning = json.skinning; 39955 if ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets; 39956 if ( json.morphNormals !== undefined ) material.morphNormals = json.morphNormals; 39957 if ( json.dithering !== undefined ) material.dithering = json.dithering; 39958 39959 if ( json.vertexTangents !== undefined ) material.vertexTangents = json.vertexTangents; 39960 39961 if ( json.visible !== undefined ) material.visible = json.visible; 39962 39963 if ( json.toneMapped !== undefined ) material.toneMapped = json.toneMapped; 39964 39965 if ( json.userData !== undefined ) material.userData = json.userData; 39966 39967 if ( json.vertexColors !== undefined ) { 39968 39969 if ( typeof json.vertexColors === 'number' ) { 39970 39971 material.vertexColors = ( json.vertexColors > 0 ) ? true : false; 39972 39973 } else { 39974 39975 material.vertexColors = json.vertexColors; 39976 39977 } 39978 39979 } 39980 39981 // Shader Material 39982 39983 if ( json.uniforms !== undefined ) { 39984 39985 for ( var name in json.uniforms ) { 39986 39987 var uniform = json.uniforms[ name ]; 39988 39989 material.uniforms[ name ] = {}; 39990 39991 switch ( uniform.type ) { 39992 39993 case 't': 39994 material.uniforms[ name ].value = getTexture( uniform.value ); 39995 break; 39996 39997 case 'c': 39998 material.uniforms[ name ].value = new Color().setHex( uniform.value ); 39999 break; 40000 40001 case 'v2': 40002 material.uniforms[ name ].value = new Vector2().fromArray( uniform.value ); 40003 break; 40004 40005 case 'v3': 40006 material.uniforms[ name ].value = new Vector3().fromArray( uniform.value ); 40007 break; 40008 40009 case 'v4': 40010 material.uniforms[ name ].value = new Vector4().fromArray( uniform.value ); 40011 break; 40012 40013 case 'm3': 40014 material.uniforms[ name ].value = new Matrix3().fromArray( uniform.value ); 40015 40016 case 'm4': 40017 material.uniforms[ name ].value = new Matrix4().fromArray( uniform.value ); 40018 break; 40019 40020 default: 40021 material.uniforms[ name ].value = uniform.value; 40022 40023 } 40024 40025 } 40026 40027 } 40028 40029 if ( json.defines !== undefined ) material.defines = json.defines; 40030 if ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader; 40031 if ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader; 40032 40033 if ( json.extensions !== undefined ) { 40034 40035 for ( var key in json.extensions ) { 40036 40037 material.extensions[ key ] = json.extensions[ key ]; 40038 40039 } 40040 40041 } 40042 40043 // Deprecated 40044 40045 if ( json.shading !== undefined ) material.flatShading = json.shading === 1; // THREE.FlatShading 40046 40047 // for PointsMaterial 40048 40049 if ( json.size !== undefined ) material.size = json.size; 40050 if ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation; 40051 40052 // maps 40053 40054 if ( json.map !== undefined ) material.map = getTexture( json.map ); 40055 if ( json.matcap !== undefined ) material.matcap = getTexture( json.matcap ); 40056 40057 if ( json.alphaMap !== undefined ) material.alphaMap = getTexture( json.alphaMap ); 40058 40059 if ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap ); 40060 if ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale; 40061 40062 if ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap ); 40063 if ( json.normalMapType !== undefined ) material.normalMapType = json.normalMapType; 40064 if ( json.normalScale !== undefined ) { 40065 40066 var normalScale = json.normalScale; 40067 40068 if ( Array.isArray( normalScale ) === false ) { 40069 40070 // Blender exporter used to export a scalar. See #7459 40071 40072 normalScale = [ normalScale, normalScale ]; 40073 40074 } 40075 40076 material.normalScale = new Vector2().fromArray( normalScale ); 40077 40078 } 40079 40080 if ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap ); 40081 if ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale; 40082 if ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias; 40083 40084 if ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap ); 40085 if ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap ); 40086 40087 if ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap ); 40088 if ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity; 40089 40090 if ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap ); 40091 40092 if ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap ); 40093 if ( json.envMapIntensity !== undefined ) material.envMapIntensity = json.envMapIntensity; 40094 40095 if ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity; 40096 if ( json.refractionRatio !== undefined ) material.refractionRatio = json.refractionRatio; 40097 40098 if ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap ); 40099 if ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity; 40100 40101 if ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap ); 40102 if ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity; 40103 40104 if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap ); 40105 40106 if ( json.clearcoatMap !== undefined ) material.clearcoatMap = getTexture( json.clearcoatMap ); 40107 if ( json.clearcoatRoughnessMap !== undefined ) material.clearcoatRoughnessMap = getTexture( json.clearcoatRoughnessMap ); 40108 if ( json.clearcoatNormalMap !== undefined ) material.clearcoatNormalMap = getTexture( json.clearcoatNormalMap ); 40109 if ( json.clearcoatNormalScale !== undefined ) material.clearcoatNormalScale = new Vector2().fromArray( json.clearcoatNormalScale ); 40110 40111 return material; 40112 40113 }, 40114 40115 setTextures: function ( value ) { 40116 40117 this.textures = value; 40118 return this; 40119 40120 } 40121 40122} ); 40123 40124/** 40125 * @author Don McCurdy / https://www.donmccurdy.com 40126 */ 40127 40128var LoaderUtils = { 40129 40130 decodeText: function ( array ) { 40131 40132 if ( typeof TextDecoder !== 'undefined' ) { 40133 40134 return new TextDecoder().decode( array ); 40135 40136 } 40137 40138 // Avoid the String.fromCharCode.apply(null, array) shortcut, which 40139 // throws a "maximum call stack size exceeded" error for large arrays. 40140 40141 var s = ''; 40142 40143 for ( var i = 0, il = array.length; i < il; i ++ ) { 40144 40145 // Implicitly assumes little-endian. 40146 s += String.fromCharCode( array[ i ] ); 40147 40148 } 40149 40150 try { 40151 40152 // merges multi-byte utf-8 characters. 40153 40154 return decodeURIComponent( escape( s ) ); 40155 40156 } catch ( e ) { // see #16358 40157 40158 return s; 40159 40160 } 40161 40162 }, 40163 40164 extractUrlBase: function ( url ) { 40165 40166 var index = url.lastIndexOf( '/' ); 40167 40168 if ( index === - 1 ) return './'; 40169 40170 return url.substr( 0, index + 1 ); 40171 40172 } 40173 40174}; 40175 40176/** 40177 * @author benaadams / https://twitter.com/ben_a_adams 40178 */ 40179 40180function InstancedBufferGeometry() { 40181 40182 BufferGeometry.call( this ); 40183 40184 this.type = 'InstancedBufferGeometry'; 40185 this.maxInstancedCount = undefined; 40186 40187} 40188 40189InstancedBufferGeometry.prototype = Object.assign( Object.create( BufferGeometry.prototype ), { 40190 40191 constructor: InstancedBufferGeometry, 40192 40193 isInstancedBufferGeometry: true, 40194 40195 copy: function ( source ) { 40196 40197 BufferGeometry.prototype.copy.call( this, source ); 40198 40199 this.maxInstancedCount = source.maxInstancedCount; 40200 40201 return this; 40202 40203 }, 40204 40205 clone: function () { 40206 40207 return new this.constructor().copy( this ); 40208 40209 }, 40210 40211 toJSON: function () { 40212 40213 var data = BufferGeometry.prototype.toJSON.call( this ); 40214 40215 data.maxInstancedCount = this.maxInstancedCount; 40216 40217 data.isInstancedBufferGeometry = true; 40218 40219 return data; 40220 40221 } 40222 40223} ); 40224 40225/** 40226 * @author benaadams / https://twitter.com/ben_a_adams 40227 */ 40228 40229function InstancedBufferAttribute( array, itemSize, normalized, meshPerAttribute ) { 40230 40231 if ( typeof ( normalized ) === 'number' ) { 40232
40233 meshPerAttribute = normalized; 40234 40235 normalized = false; 40236 40237 console.error( 'THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.' ); 40238 40239 } 40240 40241 BufferAttribute.call( this, array, itemSize, normalized ); 40242 40243 this.meshPerAttribute = meshPerAttribute || 1; 40244 40245} 40246 40247InstancedBufferAttribute.prototype = Object.assign( Object.create( BufferAttribute.prototype ), { 40248 40249 constructor: InstancedBufferAttribute, 40250 40251 isInstancedBufferAttribute: true, 40252 40253 copy: function ( source ) { 40254 40255 BufferAttribute.prototype.copy.call( this, source ); 40256 40257 this.meshPerAttribute = source.meshPerAttribute; 40258 40259 return this; 40260 40261 }, 40262 40263 toJSON: function () { 40264 40265 var data = BufferAttribute.prototype.toJSON.call( this ); 40266 40267 data.meshPerAttribute = this.meshPerAttribute; 40268 40269 data.isInstancedBufferAttribute = true; 40270 40271 return data; 40272 40273 } 40274 40275} ); 40276 40277/** 40278 * @author mrdoob / http://mrdoob.com/ 40279 */ 40280 40281function BufferGeometryLoader( manager ) { 40282 40283 Loader.call( this, manager ); 40284 40285} 40286 40287BufferGeometryLoader.prototype = Object.assign( Object.create( Loader.prototype ), { 40288 40289 constructor: BufferGeometryLoader, 40290 40291 load: function ( url, onLoad, onProgress, onError ) { 40292 40293 var scope = this; 40294 40295 var loader = new FileLoader( scope.manager ); 40296 loader.setPath( scope.path ); 40297 loader.load( url, function ( text ) { 40298 40299 onLoad( scope.parse( JSON.parse( text ) ) ); 40300 40301 }, onProgress, onError ); 40302 40303 }, 40304 40305 parse: function ( json ) { 40306 40307 var geometry = json.isInstancedBufferGeometry ? new InstancedBufferGeometry() : new BufferGeometry(); 40308 40309 var index = json.data.index; 40310 40311 if ( index !== undefined ) { 40312 40313 var typedArray = new TYPED_ARRAYS[ index.type ]( index.array ); 40314 geometry.setIndex( new BufferAttribute( typedArray, 1 ) ); 40315 40316 } 40317 40318 var attributes = json.data.attributes; 40319 40320 for ( var key in attributes ) { 40321 40322 var attribute = attributes[ key ]; 40323 var typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array ); 40324 var bufferAttributeConstr = attribute.isInstancedBufferAttribute ? InstancedBufferAttribute : BufferAttribute; 40325 var bufferAttribute = new bufferAttributeConstr( typedArray, attribute.itemSize, attribute.normalized ); 40326 if ( attribute.name !== undefined ) bufferAttribute.name = attribute.name; 40327 geometry.setAttribute( key, bufferAttribute ); 40328 40329 } 40330 40331 var morphAttributes = json.data.morphAttributes; 40332 40333 if ( morphAttributes ) { 40334 40335 for ( var key in morphAttributes ) { 40336 40337 var attributeArray = morphAttributes[ key ]; 40338 40339 var array = []; 40340 40341 for ( var i = 0, il = attributeArray.length; i < il; i ++ ) { 40342 40343 var attribute = attributeArray[ i ]; 40344 var typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array ); 40345 40346 var bufferAttribute = new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ); 40347 if ( attribute.name !== undefined ) bufferAttribute.name = attribute.name; 40348 array.push( bufferAttribute ); 40349 40350 } 40351 40352 geometry.morphAttributes[ key ] = array; 40353 40354 } 40355 40356 } 40357 40358 var morphTargetsRelative = json.data.morphTargetsRelative; 40359 40360 if ( morphTargetsRelative ) { 40361 40362 geometry.morphTargetsRelative = true; 40363 40364 } 40365 40366 var groups = json.data.groups || json.data.drawcalls || json.data.offsets; 40367 40368 if ( groups !== undefined ) { 40369 40370 for ( var i = 0, n = groups.length; i !== n; ++ i ) { 40371 40372 var group = groups[ i ]; 40373 40374 geometry.addGroup( group.start, group.count, group.materialIndex ); 40375 40376 } 40377 40378 } 40379 40380 var boundingSphere = json.data.boundingSphere; 40381 40382 if ( boundingSphere !== undefined ) { 40383 40384 var center = new Vector3(); 40385 40386 if ( boundingSphere.center !== undefined ) { 40387 40388 center.fromArray( boundingSphere.center ); 40389 40390 } 40391 40392 geometry.boundingSphere = new Sphere( center, boundingSphere.radius ); 40393 40394 } 40395 40396 if ( json.name ) geometry.name = json.name; 40397 if ( json.userData ) geometry.userData = json.userData; 40398 40399 return geometry; 40400 40401 } 40402 40403} ); 40404 40405var TYPED_ARRAYS = { 40406 Int8Array: Int8Array, 40407 Uint8Array: Uint8Array, 40408 // Workaround for IE11 pre KB2929437. See #11440 40409 Uint8ClampedArray: typeof Uint8ClampedArray !== 'undefined' ? Uint8ClampedArray : Uint8Array, 40410 Int16Array: Int16Array, 40411 Uint16Array: Uint16Array, 40412 Int32Array: Int32Array, 40413 Uint32Array: Uint32Array, 40414 Float32Array: Float32Array, 40415 Float64Array: Float64Array 40416}; 40417 40418/** 40419 * @author mrdoob / http://mrdoob.com/ 40420 */ 40421 40422function ObjectLoader( manager ) { 40423 40424 Loader.call( this, manager ); 40425 40426} 40427 40428ObjectLoader.prototype = Object.assign( Object.create( Loader.prototype ), { 40429 40430 constructor: ObjectLoader, 40431 40432 load: function ( url, onLoad, onProgress, onError ) { 40433 40434 var scope = this; 40435 40436 var path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path; 40437 this.resourcePath = this.resourcePath || path; 40438 40439 var loader = new FileLoader( scope.manager ); 40440 loader.setPath( this.path ); 40441 loader.load( url, function ( text ) { 40442 40443 var json = null; 40444 40445 try { 40446 40447 json = JSON.parse( text ); 40448 40449 } catch ( error ) { 40450 40451 if ( onError !== undefined ) onError( error ); 40452 40453 console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message ); 40454 40455 return; 40456 40457 } 40458 40459 var metadata = json.metadata; 40460 40461 if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) { 40462 40463 console.error( 'THREE.ObjectLoader: Can\'t load ' + url ); 40464 return; 40465 40466 } 40467 40468 scope.parse( json, onLoad ); 40469 40470 }, onProgress, onError ); 40471 40472 }, 40473 40474 parse: function ( json, onLoad ) { 40475 40476 var shapes = this.parseShape( json.shapes ); 40477 var geometries = this.parseGeometries( json.geometries, shapes ); 40478 40479 var images = this.parseImages( json.images, function () { 40480 40481 if ( onLoad !== undefined ) onLoad( object ); 40482 40483 } ); 40484 40485 var textures = this.parseTextures( json.textures, images ); 40486 var materials = this.parseMaterials( json.materials, textures ); 40487 40488 var object = this.parseObject( json.object, geometries, materials ); 40489 40490 if ( json.animations ) { 40491 40492 object.animations = this.parseAnimations( json.animations ); 40493 40494 } 40495 40496 if ( json.images === undefined || json.images.length === 0 ) { 40497 40498 if ( onLoad !== undefined ) onLoad( object ); 40499 40500 } 40501 40502 return object; 40503 40504 },
40505 40506 parseShape: function ( json ) { 40507 40508 var shapes = {}; 40509 40510 if ( json !== undefined ) { 40511 40512 for ( var i = 0, l = json.length; i < l; i ++ ) { 40513 40514 var shape = new Shape().fromJSON( json[ i ] ); 40515 40516 shapes[ shape.uuid ] = shape; 40517 40518 } 40519 40520 } 40521 40522 return shapes; 40523 40524 }, 40525 40526 parseGeometries: function ( json, shapes ) { 40527 40528 var geometries = {}; 40529 40530 if ( json !== undefined ) { 40531 40532 var bufferGeometryLoader = new BufferGeometryLoader(); 40533 40534 for ( var i = 0, l = json.length; i < l; i ++ ) { 40535 40536 var geometry; 40537 var data = json[ i ]; 40538 40539 switch ( data.type ) { 40540 40541 case 'PlaneGeometry': 40542 case 'PlaneBufferGeometry': 40543 40544 geometry = new Geometries[ data.type ]( 40545 data.width, 40546 data.height, 40547 data.widthSegments, 40548 data.heightSegments 40549 ); 40550 40551 break; 40552 40553 case 'BoxGeometry': 40554 case 'BoxBufferGeometry': 40555 case 'CubeGeometry': // backwards compatible 40556 40557 geometry = new Geometries[ data.type ]( 40558 data.width, 40559 data.height, 40560 data.depth, 40561 data.widthSegments, 40562 data.heightSegments, 40563 data.depthSegments 40564 ); 40565 40566 break; 40567 40568 case 'CircleGeometry': 40569 case 'CircleBufferGeometry': 40570 40571 geometry = new Geometries[ data.type ]( 40572 data.radius, 40573 data.segments, 40574 data.thetaStart, 40575 data.thetaLength 40576 ); 40577 40578 break; 40579 40580 case 'CylinderGeometry': 40581 case 'CylinderBufferGeometry': 40582 40583 geometry = new Geometries[ data.type ]( 40584 data.radiusTop, 40585 data.radiusBottom, 40586 data.height, 40587 data.radialSegments, 40588 data.heightSegments, 40589 data.openEnded, 40590 data.thetaStart, 40591 data.thetaLength 40592 ); 40593 40594 break; 40595 40596 case 'ConeGeometry': 40597 case 'ConeBufferGeometry': 40598 40599 geometry = new Geometries[ data.type ]( 40600 data.radius, 40601 data.height, 40602 data.radialSegments, 40603 data.heightSegments, 40604 data.openEnded, 40605 data.thetaStart, 40606 data.thetaLength 40607 ); 40608 40609 break; 40610 40611 case 'SphereGeometry': 40612 case 'SphereBufferGeometry': 40613 40614 geometry = new Geometries[ data.type ]( 40615 data.radius, 40616 data.widthSegments, 40617 data.heightSegments, 40618 data.phiStart, 40619 data.phiLength, 40620 data.thetaStart, 40621 data.thetaLength 40622 ); 40623 40624 break; 40625 40626 case 'DodecahedronGeometry': 40627 case 'DodecahedronBufferGeometry': 40628 case 'IcosahedronGeometry': 40629 case 'IcosahedronBufferGeometry': 40630 case 'OctahedronGeometry': 40631 case 'OctahedronBufferGeometry': 40632 case 'TetrahedronGeometry': 40633 case 'TetrahedronBufferGeometry': 40634 40635 geometry = new Geometries[ data.type ]( 40636 data.radius, 40637 data.detail 40638 ); 40639 40640 break; 40641 40642 case 'RingGeometry': 40643 case 'RingBufferGeometry': 40644 40645 geometry = new Geometries[ data.type ]( 40646 data.innerRadius, 40647 data.outerRadius, 40648 data.thetaSegments, 40649 data.phiSegments, 40650 data.thetaStart, 40651 data.thetaLength 40652 ); 40653 40654 break; 40655 40656 case 'TorusGeometry': 40657 case 'TorusBufferGeometry': 40658 40659 geometry = new Geometries[ data.type ]( 40660 data.radius, 40661 data.tube, 40662 data.radialSegments, 40663 data.tubularSegments, 40664 data.arc 40665 ); 40666 40667 break; 40668 40669 case 'TorusKnotGeometry': 40670 case 'TorusKnotBufferGeometry': 40671 40672 geometry = new Geometries[ data.type ]( 40673 data.radius, 40674 data.tube, 40675 data.tubularSegments, 40676 data.radialSegments, 40677 data.p, 40678 data.q 40679 ); 40680 40681 break; 40682 40683 case 'TubeGeometry': 40684 case 'TubeBufferGeometry': 40685 40686 // This only works for built-in curves (e.g. CatmullRomCurve3). 40687 // User defined curves or instances of CurvePath will not be deserialized. 40688 geometry = new Geometries[ data.type ]( 40689 new Curves[ data.path.type ]().fromJSON( data.path ), 40690 data.tubularSegments, 40691 data.radius, 40692 data.radialSegments, 40693 data.closed 40694 ); 40695 40696 break; 40697 40698 case 'LatheGeometry': 40699 case 'LatheBufferGeometry': 40700 40701 geometry = new Geometries[ data.type ]( 40702 data.points, 40703 data.segments, 40704 data.phiStart, 40705 data.phiLength 40706 ); 40707 40708 break; 40709 40710 case 'PolyhedronGeometry': 40711 case 'PolyhedronBufferGeometry': 40712 40713 geometry = new Geometries[ data.type ]( 40714 data.vertices, 40715 data.indices, 40716 data.radius, 40717 data.details 40718 ); 40719 40720 break; 40721 40722 case 'ShapeGeometry': 40723 case 'ShapeBufferGeometry': 40724 40725 var geometryShapes = []; 40726 40727 for ( var j = 0, jl = data.shapes.length; j < jl; j ++ ) { 40728 40729 var shape = shapes[ data.shapes[ j ] ]; 40730 40731 geometryShapes.push( shape ); 40732 40733 } 40734 40735 geometry = new Geometries[ data.type ]( 40736 geometryShapes, 40737 data.curveSegments 40738 ); 40739 40740 break; 40741 40742 40743 case 'ExtrudeGeometry': 40744 case 'ExtrudeBufferGeometry': 40745 40746 var geometryShapes = []; 40747 40748 for ( var j = 0, jl = data.shapes.length; j < jl; j ++ ) { 40749 40750 var shape = shapes[ data.shapes[ j ] ]; 40751 40752 geometryShapes.push( shape ); 40753 40754 } 40755 40756 var extrudePath = data.options.extrudePath; 40757 40758 if ( extrudePath !== undefined ) { 40759 40760 data.options.extrudePath = new Curves[ extrudePath.type ]().fromJSON( extrudePath ); 40761 40762 } 40763 40764 geometry = new Geometries[ data.type ]( 40765 geometryShapes, 40766 data.options 40767 ); 40768 40769 break; 40770 40771 case 'BufferGeometry': 40772 case 'InstancedBufferGeometry': 40773 40774 geometry = bufferGeometryLoader.parse( data ); 40775 40776 break; 40777 40778 case 'Geometry': 40779 40780 console.error( 'THREE.ObjectLoader: Loading "Geometry" is not supported anymore.' ); 40781 40782 break; 40783 40784 default: 40785 40786 console.warn( 'THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"' ); 40787 40788 continue; 40789 40790 } 40791 40792 geometry.uuid = data.uuid; 40793 40794 if ( data.name !== undefined ) geometry.name = data.name; 40795 if ( geometry.isBufferGeometry === true && data.userData !== undefined ) geometry.userData = data.userData; 40796 40797 geometries[ data.uuid ] = geometry; 40798 40799 } 40800 40801 } 40802 40803 return geometries; 40804 40805 }, 40806 40807 parseMaterials: function ( json, textures ) { 40808 40809 var cache = {}; // MultiMaterial 40810 var materials = {}; 40811 40812 if ( json !== undefined ) { 40813 40814 var loader = new MaterialLoader(); 40815 loader.setTextures( textures ); 40816 40817 for ( var i = 0, l = json.length; i < l; i ++ ) { 40818 40819 var data = json[ i ]; 40820 40821 if ( data.type === 'MultiMaterial' ) { 40822 40823 // Deprecated 40824 40825 var array = []; 40826 40827 for ( var j = 0; j < data.materials.length; j ++ ) { 40828 40829 var material = data.materials[ j ]; 40830 40831 if ( cache[ material.uuid ] === undefined ) { 40832 40833 cache[ material.uuid ] = loader.parse( material ); 40834 40835 } 40836 40837 array.push( cache[ material.uuid ] ); 40838 40839 } 40840 40841 materials[ data.uuid ] = array; 40842 40843 } else { 40844 40845 if ( cache[ data.uuid ] === undefined ) { 40846 40847 cache[ data.uuid ] = loader.parse( data ); 40848 40849 } 40850 40851 materials[ data.uuid ] = cache[ data.uuid ]; 40852 40853 } 40854 40855 } 40856 40857 } 40858 40859 return materials; 40860 40861 }, 40862 40863 parseAnimations: function ( json ) { 40864 40865 var animations = []; 40866 40867 for ( var i = 0; i < json.length; i ++ ) { 40868 40869 var data = json[ i ]; 40870 40871 var clip = AnimationClip.parse( data ); 40872 40873 if ( data.uuid !== undefined ) clip.uuid = data.uuid; 40874 40875 animations.push( clip ); 40876 40877 } 40878 40879 return animations; 40880 40881 }, 40882 40883 parseImages: function ( json, onLoad ) { 40884 40885 var scope = this; 40886 var images = {}; 40887 40888 function loadImage( url ) { 40889 40890 scope.manager.itemStart( url ); 40891 40892 return loader.load( url, function () { 40893 40894 scope.manager.itemEnd( url ); 40895 40896 }, undefined, function () { 40897 40898 scope.manager.itemError( url ); 40899 scope.manager.itemEnd( url ); 40900 40901 } ); 40902 40903 } 40904 40905 if ( json !== undefined && json.length > 0 ) { 40906 40907 var manager = new LoadingManager( onLoad ); 40908 40909 var loader = new ImageLoader( manager ); 40910 loader.setCrossOrigin( this.crossOrigin ); 40911 40912 for ( var i = 0, il = json.length; i < il; i ++ ) { 40913 40914 var image = json[ i ]; 40915 var url = image.url; 40916 40917 if ( Array.isArray( url ) ) { 40918 40919 // load array of images e.g CubeTexture 40920 40921 images[ image.uuid ] = []; 40922 40923 for ( var j = 0, jl = url.length; j < jl; j ++ ) { 40924 40925 var currentUrl = url[ j ]; 40926 40927 var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( currentUrl ) ? currentUrl : scope.resourcePath + currentUrl; 40928 40929 images[ image.uuid ].push( loadImage( path ) ); 40930 40931 } 40932 40933 } else { 40934 40935 // load single image 40936 40937 var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.resourcePath + image.url; 40938 40939 images[ image.uuid ] = loadImage( path ); 40940 40941 } 40942 40943 } 40944 40945 } 40946 40947 return images; 40948 40949 }, 40950 40951 parseTextures: function ( json, images ) { 40952 40953 function parseConstant( value, type ) { 40954 40955 if ( typeof value === 'number' ) return value; 40956 40957 console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value ); 40958 40959 return type[ value ]; 40960 40961 } 40962 40963 var textures = {}; 40964 40965 if ( json !== undefined ) { 40966 40967 for ( var i = 0, l = json.length; i < l; i ++ ) { 40968 40969 var data = json[ i ]; 40970 40971 if ( data.image === undefined ) { 40972 40973 console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid ); 40974 40975 } 40976 40977 if ( images[ data.image ] === undefined ) { 40978 40979 console.warn( 'THREE.ObjectLoader: Undefined image', data.image ); 40980 40981 } 40982 40983 var texture; 40984 40985 if ( Array.isArray( images[ data.image ] ) ) { 40986 40987 texture = new CubeTexture( images[ data.image ] ); 40988 40989 } else { 40990 40991 texture = new Texture( images[ data.image ] ); 40992 40993 } 40994 40995 texture.needsUpdate = true; 40996 40997 texture.uuid = data.uuid; 40998 40999 if ( data.name !== undefined ) texture.name = data.name; 41000 41001 if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING ); 41002 41003 if ( data.offset !== undefined ) texture.offset.fromArray( data.offset ); 41004 if ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat ); 41005 if ( data.center !== undefined ) texture.center.fromArray( data.center ); 41006 if ( data.rotation !== undefined ) texture.rotation = data.rotation; 41007 41008 if ( data.wrap !== undefined ) { 41009 41010 texture.wrapS = parseConstant( data.wrap[ 0 ], TEXTURE_WRAPPING ); 41011 texture.wrapT = parseConstant( data.wrap[ 1 ], TEXTURE_WRAPPING ); 41012 41013 } 41014 41015 if ( data.format !== undefined ) texture.format = data.format; 41016 if ( data.type !== undefined ) texture.type = data.type; 41017 if ( data.encoding !== undefined ) texture.encoding = data.encoding; 41018 41019 if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER );
41020 if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER ); 41021 if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy; 41022 41023 if ( data.flipY !== undefined ) texture.flipY = data.flipY; 41024 41025 if ( data.premultiplyAlpha !== undefined ) texture.premultiplyAlpha = data.premultiplyAlpha; 41026 if ( data.unpackAlignment !== undefined ) texture.unpackAlignment = data.unpackAlignment; 41027 41028 textures[ data.uuid ] = texture; 41029 41030 } 41031 41032 } 41033 41034 return textures; 41035 41036 }, 41037 41038 parseObject: function ( data, geometries, materials ) { 41039 41040 var object; 41041 41042 function getGeometry( name ) { 41043 41044 if ( geometries[ name ] === undefined ) { 41045 41046 console.warn( 'THREE.ObjectLoader: Undefined geometry', name ); 41047 41048 } 41049 41050 return geometries[ name ]; 41051 41052 } 41053 41054 function getMaterial( name ) { 41055 41056 if ( name === undefined ) return undefined; 41057 41058 if ( Array.isArray( name ) ) { 41059 41060 var array = []; 41061 41062 for ( var i = 0, l = name.length; i < l; i ++ ) { 41063 41064 var uuid = name[ i ]; 41065 41066 if ( materials[ uuid ] === undefined ) { 41067 41068 console.warn( 'THREE.ObjectLoader: Undefined material', uuid ); 41069 41070 } 41071 41072 array.push( materials[ uuid ] ); 41073 41074 } 41075 41076 return array; 41077 41078 } 41079 41080 if ( materials[ name ] === undefined ) { 41081 41082 console.warn( 'THREE.ObjectLoader: Undefined material', name ); 41083 41084 } 41085 41086 return materials[ name ]; 41087 41088 } 41089 41090 switch ( data.type ) { 41091 41092 case 'Scene': 41093 41094 object = new Scene(); 41095 41096 if ( data.background !== undefined ) { 41097 41098 if ( Number.isInteger( data.background ) ) { 41099 41100 object.background = new Color( data.background ); 41101 41102 } 41103 41104 } 41105 41106 if ( data.fog !== undefined ) { 41107 41108 if ( data.fog.type === 'Fog' ) { 41109 41110 object.fog = new Fog( data.fog.color, data.fog.near, data.fog.far ); 41111 41112 } else if ( data.fog.type === 'FogExp2' ) { 41113 41114 object.fog = new FogExp2( data.fog.color, data.fog.density ); 41115 41116 } 41117 41118 } 41119 41120 break; 41121 41122 case 'PerspectiveCamera': 41123 41124 object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far ); 41125 41126 if ( data.focus !== undefined ) object.focus = data.focus; 41127 if ( data.zoom !== undefined ) object.zoom = data.zoom; 41128 if ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge; 41129 if ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset; 41130 if ( data.view !== undefined ) object.view = Object.assign( {}, data.view ); 41131 41132 break; 41133 41134 case 'OrthographicCamera': 41135 41136 object = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far ); 41137 41138 if ( data.zoom !== undefined ) object.zoom = data.zoom; 41139 if ( data.view !== undefined ) object.view = Object.assign( {}, data.view ); 41140 41141 break; 41142 41143 case 'AmbientLight': 41144 41145 object = new AmbientLight( data.color, data.intensity ); 41146 41147 break; 41148 41149 case 'DirectionalLight': 41150 41151 object = new DirectionalLight( data.color, data.intensity ); 41152 41153 break; 41154 41155 case 'PointLight': 41156 41157 object = new PointLight( data.color, data.intensity, data.distance, data.decay ); 41158 41159 break; 41160 41161 case 'RectAreaLight': 41162 41163 object = new RectAreaLight( data.color, data.intensity, data.width, data.height ); 41164 41165 break; 41166 41167 case 'SpotLight': 41168 41169 object = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay ); 41170 41171 break; 41172 41173 case 'HemisphereLight': 41174 41175 object = new HemisphereLight( data.color, data.groundColor, data.intensity ); 41176 41177 break; 41178 41179 case 'LightProbe': 41180 41181 object = new LightProbe().fromJSON( data ); 41182 41183 break; 41184 41185 case 'SkinnedMesh': 41186 41187 console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.' ); 41188 41189 case 'Mesh': 41190 41191 var geometry = getGeometry( data.geometry ); 41192 var material = getMaterial( data.material ); 41193 41194 object = new Mesh( geometry, material ); 41195 41196 break; 41197 41198 case 'InstancedMesh': 41199 41200 var geometry = getGeometry( data.geometry ); 41201 var material = getMaterial( data.material ); 41202 var count = data.count; 41203 var instanceMatrix = data.instanceMatrix; 41204 41205 object = new InstancedMesh( geometry, material, count ); 41206 object.instanceMatrix = new BufferAttribute( new Float32Array( instanceMatrix.array ), 16 ); 41207 41208 break; 41209 41210 case 'LOD': 41211 41212 object = new LOD(); 41213 41214 break; 41215 41216 case 'Line': 41217 41218 object = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode ); 41219 41220 break; 41221 41222 case 'LineLoop': 41223 41224 object = new LineLoop( getGeometry( data.geometry ), getMaterial( data.material ) ); 41225 41226 break; 41227 41228 case 'LineSegments': 41229 41230 object = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) ); 41231 41232 break; 41233 41234 case 'PointCloud': 41235 case 'Points': 41236 41237 object = new Points( getGeometry( data.geometry ), getMaterial( data.material ) ); 41238 41239 break; 41240 41241 case 'Sprite': 41242 41243 object = new Sprite( getMaterial( data.material ) ); 41244 41245 break; 41246 41247 case 'Group': 41248 41249 object = new Group(); 41250 41251 break; 41252 41253 default: 41254 41255 object = new Object3D(); 41256 41257 } 41258 41259 object.uuid = data.uuid; 41260 41261 if ( data.name !== undefined ) object.name = data.name; 41262 41263 if ( data.matrix !== undefined ) { 41264 41265 object.matrix.fromArray( data.matrix ); 41266 41267 if ( data.matrixAutoUpdate !== undefined ) object.matrixAutoUpdate = data.matrixAutoUpdate; 41268 if ( object.matrixAutoUpdate ) object.matrix.decompose( object.position, object.quaternion, object.scale ); 41269 41270 } else { 41271 41272 if ( data.position !== undefined ) object.position.fromArray( data.position ); 41273 if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation ); 41274 if ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion ); 41275 if ( data.scale !== undefined ) object.scale.fromArray( data.scale ); 41276 41277 } 41278 41279 if ( data.castShadow !== undefined ) object.castShadow = data.castShadow; 41280 if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow; 41281 41282 if ( data.shadow ) { 41283 41284 if ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias; 41285 if ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius; 41286 if ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize ); 41287 if ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera ); 41288 41289 } 41290 41291 if ( data.visible !== undefined ) object.visible = data.visible; 41292 if ( data.frustumCulled !== undefined ) object.frustumCulled = data.frustumCulled; 41293 if ( data.renderOrder !== undefined ) object.renderOrder = data.renderOrder; 41294 if ( data.userData !== undefined ) object.userData = data.userData; 41295 if ( data.layers !== undefined ) object.layers.mask = data.layers; 41296 41297 if ( data.children !== undefined ) { 41298 41299 var children = data.children; 41300 41301 for ( var i = 0; i < children.length; i ++ ) { 41302 41303 object.add( this.parseObject( children[ i ], geometries, materials ) ); 41304 41305 } 41306 41307 } 41308 41309 if ( data.type === 'LOD' ) { 41310 41311 if ( data.autoUpdate !== undefined ) object.autoUpdate = data.autoUpdate; 41312 41313 var levels = data.levels; 41314 41315 for ( var l = 0; l < levels.length; l ++ ) { 41316 41317 var level = levels[ l ]; 41318 var child = object.getObjectByProperty( 'uuid', level.object ); 41319 41320 if ( child !== undefined ) { 41321 41322 object.addLevel( child, level.distance ); 41323 41324 } 41325 41326 } 41327 41328 } 41329 41330 return object; 41331 41332 } 41333 41334} ); 41335 41336var TEXTURE_MAPPING = { 41337 UVMapping: UVMapping, 41338 CubeReflectionMapping: CubeReflectionMapping, 41339 CubeRefractionMapping: CubeRefractionMapping, 41340 EquirectangularReflectionMapping: EquirectangularReflectionMapping, 41341 EquirectangularRefractionMapping: EquirectangularRefractionMapping, 41342 SphericalReflectionMapping: SphericalReflectionMapping, 41343 CubeUVReflectionMapping: CubeUVReflectionMapping, 41344 CubeUVRefractionMapping: CubeUVRefractionMapping 41345}; 41346 41347var TEXTURE_WRAPPING = { 41348 RepeatWrapping: RepeatWrapping, 41349 ClampToEdgeWrapping: ClampToEdgeWrapping, 41350 MirroredRepeatWrapping: MirroredRepeatWrapping 41351}; 41352 41353var TEXTURE_FILTER = { 41354 NearestFilter: NearestFilter, 41355 NearestMipmapNearestFilter: NearestMipmapNearestFilter, 41356 NearestMipmapLinearFilter: NearestMipmapLinearFilter, 41357 LinearFilter: LinearFilter, 41358 LinearMipmapNearestFilter: LinearMipmapNearestFilter, 41359 LinearMipmapLinearFilter: LinearMipmapLinearFilter 41360}; 41361 41362/** 41363 * @author thespite / http://clicktorelease.com/ 41364 */ 41365 41366 41367function ImageBitmapLoader( manager ) { 41368 41369 if ( typeof createImageBitmap === 'undefined' ) { 41370 41371 console.warn( 'THREE.ImageBitmapLoader: createImageBitmap() not supported.' ); 41372 41373 } 41374 41375 if ( typeof fetch === 'undefined' ) { 41376 41377 console.warn( 'THREE.ImageBitmapLoader: fetch() not supported.' ); 41378 41379 } 41380 41381 Loader.call( this, manager ); 41382 41383 this.options = undefined; 41384 41385} 41386 41387ImageBitmapLoader.prototype = Object.assign( Object.create( Loader.prototype ), { 41388 41389 constructor: ImageBitmapLoader, 41390 41391 setOptions: function setOptions( options ) { 41392 41393 this.options = options; 41394 41395 return this; 41396 41397 }, 41398 41399 load: function ( url, onLoad, onProgress, onError ) { 41400 41401 if ( url === undefined ) url = ''; 41402 41403 if ( this.path !== undefined ) url = this.path + url; 41404 41405 url = this.manager.resolveURL( url ); 41406 41407 var scope = this; 41408 41409 var cached = Cache.get( url ); 41410 41411 if ( cached !== undefined ) { 41412 41413 scope.manager.itemStart( url ); 41414 41415 setTimeout( function () { 41416 41417 if ( onLoad ) onLoad( cached ); 41418 41419 scope.manager.itemEnd( url ); 41420 41421 }, 0 ); 41422 41423 return cached; 41424 41425 } 41426 41427 fetch( url ).then( function ( res ) { 41428 41429 return res.blob(); 41430 41431 } ).then( function ( blob ) { 41432 41433 if ( scope.options === undefined ) { 41434 41435 // Workaround for FireFox. It causes an error if you pass options. 41436 return createImageBitmap( blob ); 41437 41438 } else { 41439 41440 return createImageBitmap( blob, scope.options ); 41441 41442 } 41443 41444 } ).then( function ( imageBitmap ) { 41445 41446 Cache.add( url, imageBitmap ); 41447 41448 if ( onLoad ) onLoad( imageBitmap ); 41449 41450 scope.manager.itemEnd( url ); 41451 41452 } ).catch( function ( e ) { 41453 41454 if ( onError ) onError( e ); 41455 41456 scope.manager.itemError( url ); 41457 scope.manager.itemEnd( url ); 41458 41459 } ); 41460 41461 scope.manager.itemStart( url ); 41462 41463 } 41464 41465} ); 41466 41467/** 41468 * @author zz85 / http://www.lab4games.net/zz85/blog 41469 * minimal class for proxing functions to Path. Replaces old "extractSubpaths()" 41470 **/ 41471 41472function ShapePath() { 41473 41474 this.type = 'ShapePath'; 41475 41476 this.color = new Color(); 41477 41478 this.subPaths = []; 41479 this.currentPath = null; 41480 41481} 41482 41483Object.assign( ShapePath.prototype, { 41484 41485 moveTo: function ( x, y ) { 41486 41487 this.currentPath = new Path(); 41488 this.subPaths.push( this.currentPath ); 41489 this.currentPath.moveTo( x, y ); 41490 41491 return this; 41492 41493 }, 41494 41495 lineTo: function ( x, y ) { 41496 41497 this.currentPath.lineTo( x, y ); 41498 41499 return this; 41500 41501 }, 41502 41503 quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) { 41504 41505 this.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY ); 41506 41507 return this; 41508 41509 }, 41510 41511 bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) { 41512 41513 this.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ); 41514 41515 return this; 41516 41517 }, 41518 41519 splineThru: function ( pts ) { 41520 41521 this.currentPath.splineThru( pts ); 41522 41523 return this; 41524 41525 }, 41526 41527 toShapes: function ( isCCW, noHoles ) { 41528 41529 function toShapesNoHoles( inSubpaths ) { 41530 41531 var shapes = []; 41532 41533 for ( var i = 0, l = inSubpaths.length; i < l; i ++ ) { 41534 41535 var tmpPath = inSubpaths[ i ]; 41536 41537 var tmpShape = new Shape(); 41538 tmpShape.curves = tmpPath.curves; 41539 41540 shapes.push( tmpShape ); 41541 41542 } 41543 41544 return shapes; 41545 41546 } 41547 41548 function isPointInsidePolygon( inPt, inPolygon ) { 41549 41550 var polyLen = inPolygon.length; 41551 41552 // inPt on polygon contour => immediate success or 41553 // toggling of inside/outside at every single! intersection point of an edge 41554 // with the horizontal line through inPt, left of inPt 41555 // not counting lowerY endpoints of edges and whole edges on that line 41556 var inside = false;
vendor: 11,468 bytes, lines 41557-42131
41557 for ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) { 41558 41559 var edgeLowPt = inPolygon[ p ]; 41560 var edgeHighPt = inPolygon[ q ]; 41561 41562 var edgeDx = edgeHighPt.x - edgeLowPt.x; 41563 var edgeDy = edgeHighPt.y - edgeLowPt.y; 41564 41565 if ( Math.abs( edgeDy ) > Number.EPSILON ) { 41566 41567 // not parallel 41568 if ( edgeDy < 0 ) { 41569 41570 edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx; 41571 edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy; 41572 41573 } 41574 41575 if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue; 41576 41577 if ( inPt.y === edgeLowPt.y ) { 41578 41579 if ( inPt.x === edgeLowPt.x ) return true; // inPt is on contour ? 41580 // continue; // no intersection or edgeLowPt => doesn't count !!! 41581 41582 } else { 41583 41584 var perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y ); 41585 if ( perpEdge === 0 ) return true; // inPt is on contour ? 41586 if ( perpEdge < 0 ) continue; 41587 inside = ! inside; // true intersection left of inPt 41588 41589 } 41590 41591 } else { 41592 41593 // parallel or collinear 41594 if ( inPt.y !== edgeLowPt.y ) continue; // parallel 41595 // edge lies on the same horizontal line as inPt 41596 if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) || 41597 ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true; // inPt: Point on contour ! 41598 // continue; 41599 41600 } 41601 41602 } 41603 41604 return inside; 41605 41606 } 41607 41608 var isClockWise = ShapeUtils.isClockWise; 41609 41610 var subPaths = this.subPaths; 41611 if ( subPaths.length === 0 ) return []; 41612 41613 if ( noHoles === true ) return toShapesNoHoles( subPaths ); 41614 41615 41616 var solid, tmpPath, tmpShape, shapes = []; 41617 41618 if ( subPaths.length === 1 ) { 41619 41620 tmpPath = subPaths[ 0 ]; 41621 tmpShape = new Shape(); 41622 tmpShape.curves = tmpPath.curves; 41623 shapes.push( tmpShape ); 41624 return shapes; 41625 41626 } 41627 41628 var holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() ); 41629 holesFirst = isCCW ? ! holesFirst : holesFirst; 41630 41631 // console.log("Holes first", holesFirst); 41632 41633 var betterShapeHoles = []; 41634 var newShapes = []; 41635 var newShapeHoles = []; 41636 var mainIdx = 0; 41637 var tmpPoints; 41638 41639 newShapes[ mainIdx ] = undefined; 41640 newShapeHoles[ mainIdx ] = []; 41641 41642 for ( var i = 0, l = subPaths.length; i < l; i ++ ) { 41643 41644 tmpPath = subPaths[ i ]; 41645 tmpPoints = tmpPath.getPoints(); 41646 solid = isClockWise( tmpPoints ); 41647 solid = isCCW ? ! solid : solid; 41648 41649 if ( solid ) { 41650 41651 if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++; 41652 41653 newShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints }; 41654 newShapes[ mainIdx ].s.curves = tmpPath.curves; 41655 41656 if ( holesFirst ) mainIdx ++; 41657 newShapeHoles[ mainIdx ] = []; 41658 41659 //console.log('cw', i); 41660 41661 } else { 41662 41663 newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } ); 41664 41665 //console.log('ccw', i); 41666 41667 } 41668 41669 } 41670 41671 // only Holes? -> probably all Shapes with wrong orientation 41672 if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths ); 41673 41674 41675 if ( newShapes.length > 1 ) { 41676 41677 var ambiguous = false; 41678 var toChange = []; 41679 41680 for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { 41681 41682 betterShapeHoles[ sIdx ] = []; 41683 41684 } 41685 41686 for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { 41687 41688 var sho = newShapeHoles[ sIdx ]; 41689 41690 for ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) { 41691 41692 var ho = sho[ hIdx ]; 41693 var hole_unassigned = true; 41694 41695 for ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) { 41696 41697 if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) { 41698 41699 if ( sIdx !== s2Idx ) toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } ); 41700 if ( hole_unassigned ) { 41701 41702 hole_unassigned = false; 41703 betterShapeHoles[ s2Idx ].push( ho ); 41704 41705 } else { 41706 41707 ambiguous = true; 41708 41709 } 41710 41711 } 41712 41713 } 41714 41715 if ( hole_unassigned ) { 41716 41717 betterShapeHoles[ sIdx ].push( ho ); 41718 41719 } 41720 41721 } 41722 41723 } 41724 // console.log("ambiguous: ", ambiguous); 41725 41726 if ( toChange.length > 0 ) { 41727 41728 // console.log("to change: ", toChange); 41729 if ( ! ambiguous ) newShapeHoles = betterShapeHoles; 41730 41731 } 41732 41733 } 41734 41735 var tmpHoles; 41736 41737 for ( var i = 0, il = newShapes.length; i < il; i ++ ) { 41738 41739 tmpShape = newShapes[ i ].s; 41740 shapes.push( tmpShape ); 41741 tmpHoles = newShapeHoles[ i ]; 41742 41743 for ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) { 41744 41745 tmpShape.holes.push( tmpHoles[ j ].h ); 41746 41747 } 41748 41749 } 41750 41751 //console.log("shape", shapes); 41752 41753 return shapes; 41754 41755 } 41756 41757} ); 41758 41759/** 41760 * @author zz85 / http://www.lab4games.net/zz85/blog 41761 * @author mrdoob / http://mrdoob.com/ 41762 */ 41763 41764 41765function Font( data ) { 41766 41767 this.type = 'Font'; 41768 41769 this.data = data; 41770 41771} 41772 41773Object.assign( Font.prototype, { 41774 41775 isFont: true, 41776 41777 generateShapes: function ( text, size ) { 41778 41779 if ( size === undefined ) size = 100; 41780 41781 var shapes = []; 41782 var paths = createPaths( text, size, this.data ); 41783 41784 for ( var p = 0, pl = paths.length; p < pl; p ++ ) { 41785 41786 Array.prototype.push.apply( shapes, paths[ p ].toShapes() ); 41787 41788 } 41789 41790 return shapes; 41791 41792 } 41793 41794} ); 41795 41796function createPaths( text, size, data ) { 41797 41798 var chars = Array.from ? Array.from( text ) : String( text ).split( '' ); // workaround for IE11, see #13988 41799 var scale = size / data.resolution; 41800 var line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale; 41801 41802 var paths = []; 41803 41804 var offsetX = 0, offsetY = 0; 41805 41806 for ( var i = 0; i < chars.length; i ++ ) { 41807 41808 var char = chars[ i ]; 41809 41810 if ( char === '\n' ) { 41811 41812 offsetX = 0; 41813 offsetY -= line_height; 41814 41815 } else { 41816 41817 var ret = createPath( char, scale, offsetX, offsetY, data ); 41818 offsetX += ret.offsetX; 41819 paths.push( ret.path ); 41820 41821 } 41822 41823 } 41824 41825 return paths; 41826 41827} 41828 41829function createPath( char, scale, offsetX, offsetY, data ) { 41830 41831 var glyph = data.glyphs[ char ] || data.glyphs[ '?' ]; 41832 41833 if ( ! glyph ) { 41834 41835 console.error( 'THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.' ); 41836 41837 return; 41838 41839 } 41840 41841 var path = new ShapePath(); 41842 41843 var x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2; 41844 41845 if ( glyph.o ) { 41846 41847 var outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) ); 41848 41849 for ( var i = 0, l = outline.length; i < l; ) { 41850 41851 var action = outline[ i ++ ]; 41852 41853 switch ( action ) { 41854 41855 case 'm': // moveTo 41856 41857 x = outline[ i ++ ] * scale + offsetX; 41858 y = outline[ i ++ ] * scale + offsetY; 41859 41860 path.moveTo( x, y ); 41861 41862 break; 41863 41864 case 'l': // lineTo 41865 41866 x = outline[ i ++ ] * scale + offsetX; 41867 y = outline[ i ++ ] * scale + offsetY; 41868 41869 path.lineTo( x, y ); 41870 41871 break; 41872 41873 case 'q': // quadraticCurveTo 41874 41875 cpx = outline[ i ++ ] * scale + offsetX; 41876 cpy = outline[ i ++ ] * scale + offsetY; 41877 cpx1 = outline[ i ++ ] * scale + offsetX; 41878 cpy1 = outline[ i ++ ] * scale + offsetY; 41879 41880 path.quadraticCurveTo( cpx1, cpy1, cpx, cpy ); 41881 41882 break; 41883 41884 case 'b': // bezierCurveTo 41885 41886 cpx = outline[ i ++ ] * scale + offsetX; 41887 cpy = outline[ i ++ ] * scale + offsetY; 41888 cpx1 = outline[ i ++ ] * scale + offsetX; 41889 cpy1 = outline[ i ++ ] * scale + offsetY; 41890 cpx2 = outline[ i ++ ] * scale + offsetX; 41891 cpy2 = outline[ i ++ ] * scale + offsetY; 41892 41893 path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy ); 41894 41895 break; 41896 41897 } 41898 41899 } 41900 41901 } 41902 41903 return { offsetX: glyph.ha * scale, path: path }; 41904 41905} 41906 41907/** 41908 * @author mrdoob / http://mrdoob.com/ 41909 */ 41910 41911function FontLoader( manager ) { 41912 41913 Loader.call( this, manager ); 41914 41915} 41916 41917FontLoader.prototype = Object.assign( Object.create( Loader.prototype ), { 41918 41919 constructor: FontLoader, 41920 41921 load: function ( url, onLoad, onProgress, onError ) { 41922 41923 var scope = this; 41924 41925 var loader = new FileLoader( this.manager ); 41926 loader.setPath( this.path ); 41927 loader.load( url, function ( text ) { 41928 41929 var json; 41930 41931 try { 41932 41933 json = JSON.parse( text ); 41934 41935 } catch ( e ) { 41936 41937 console.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' ); 41938 json = JSON.parse( text.substring( 65, text.length - 2 ) ); 41939 41940 } 41941 41942 var font = scope.parse( json ); 41943 41944 if ( onLoad ) onLoad( font ); 41945 41946 }, onProgress, onError ); 41947 41948 }, 41949 41950 parse: function ( json ) { 41951 41952 return new Font( json ); 41953 41954 } 41955 41956} ); 41957 41958/** 41959 * @author mrdoob / http://mrdoob.com/ 41960 */ 41961 41962var _context; 41963 41964var AudioContext = { 41965 41966 getContext: function () { 41967 41968 if ( _context === undefined ) { 41969 41970 _context = new ( window.AudioContext || window.webkitAudioContext )(); 41971 41972 } 41973 41974 return _context; 41975 41976 }, 41977 41978 setContext: function ( value ) { 41979 41980 _context = value; 41981 41982 } 41983 41984}; 41985 41986/** 41987 * @author Reece Aaron Lecrivain / http://reecenotes.com/ 41988 */ 41989 41990function AudioLoader( manager ) { 41991 41992 Loader.call( this, manager ); 41993 41994} 41995 41996AudioLoader.prototype = Object.assign( Object.create( Loader.prototype ), { 41997 41998 constructor: AudioLoader, 41999 42000 load: function ( url, onLoad, onProgress, onError ) { 42001 42002 var loader = new FileLoader( this.manager ); 42003 loader.setResponseType( 'arraybuffer' ); 42004 loader.setPath( this.path ); 42005 loader.load( url, function ( buffer ) { 42006 42007 // Create a copy of the buffer. The `decodeAudioData` method 42008 // detaches the buffer when complete, preventing reuse. 42009 var bufferCopy = buffer.slice( 0 ); 42010 42011 var context = AudioContext.getContext(); 42012 context.decodeAudioData( bufferCopy, function ( audioBuffer ) { 42013 42014 onLoad( audioBuffer ); 42015 42016 } ); 42017 42018 }, onProgress, onError ); 42019 42020 } 42021 42022} ); 42023 42024/** 42025 * @author WestLangley / http://github.com/WestLangley 42026 */ 42027 42028function HemisphereLightProbe( skyColor, groundColor, intensity ) { 42029 42030 LightProbe.call( this, undefined, intensity ); 42031 42032 var color1 = new Color().set( skyColor ); 42033 var color2 = new Color().set( groundColor ); 42034 42035 var sky = new Vector3( color1.r, color1.g, color1.b ); 42036 var ground = new Vector3( color2.r, color2.g, color2.b ); 42037 42038 // without extra factor of PI in the shader, should = 1 / Math.sqrt( Math.PI ); 42039 var c0 = Math.sqrt( Math.PI ); 42040 var c1 = c0 * Math.sqrt( 0.75 ); 42041 42042 this.sh.coefficients[ 0 ].copy( sky ).add( ground ).multiplyScalar( c0 ); 42043 this.sh.coefficients[ 1 ].copy( sky ).sub( ground ).multiplyScalar( c1 ); 42044 42045} 42046 42047HemisphereLightProbe.prototype = Object.assign( Object.create( LightProbe.prototype ), { 42048 42049 constructor: HemisphereLightProbe, 42050 42051 isHemisphereLightProbe: true, 42052 42053 copy: function ( source ) { // modifying colors not currently supported 42054 42055 LightProbe.prototype.copy.call( this, source ); 42056 42057 return this; 42058 42059 }, 42060 42061 toJSON: function ( meta ) { 42062 42063 var data = LightProbe.prototype.toJSON.call( this, meta ); 42064 42065 // data.sh = this.sh.toArray(); // todo 42066 42067 return data; 42068 42069 } 42070 42071} ); 42072 42073/** 42074 * @author WestLangley / http://github.com/WestLangley 42075 */ 42076 42077function AmbientLightProbe( color, intensity ) { 42078 42079 LightProbe.call( this, undefined, intensity ); 42080 42081 var color1 = new Color().set( color ); 42082 42083 // without extra factor of PI in the shader, would be 2 / Math.sqrt( Math.PI ); 42084 this.sh.coefficients[ 0 ].set( color1.r, color1.g, color1.b ).multiplyScalar( 2 * Math.sqrt( Math.PI ) ); 42085 42086} 42087 42088AmbientLightProbe.prototype = Object.assign( Object.create( LightProbe.prototype ), { 42089 42090 constructor: AmbientLightProbe, 42091 42092 isAmbientLightProbe: true, 42093 42094 copy: function ( source ) { // modifying color not currently supported 42095 42096 LightProbe.prototype.copy.call( this, source ); 42097 42098 return this; 42099 42100 }, 42101 42102 toJSON: function ( meta ) { 42103 42104 var data = LightProbe.prototype.toJSON.call( this, meta ); 42105 42106 // data.sh = this.sh.toArray(); // todo 42107 42108 return data; 42109 42110 } 42111 42112} ); 42113 42114var _eyeRight = new Matrix4(); 42115var _eyeLeft = new Matrix4(); 42116 42117/** 42118 * @author mrdoob / http://mrdoob.com/ 42119 */ 42120 42121function StereoCamera() { 42122 42123 this.type = 'StereoCamera'; 42124 42125 this.aspect = 1; 42126 42127 this.eyeSep = 0.064; 42128 42129 this.cameraL = new PerspectiveCamera(); 42130 this.cameraL.layers.enable( 1 ); 42131 this.cameraL.matrixAutoUpdate = false;
42132 42133 this.cameraR = new PerspectiveCamera(); 42134 this.cameraR.layers.enable( 2 ); 42135 this.cameraR.matrixAutoUpdate = false; 42136 42137 this._cache = { 42138 focus: null, 42139 fov: null, 42140 aspect: null, 42141 near: null, 42142 far: null, 42143 zoom: null, 42144 eyeSep: null 42145 }; 42146 42147} 42148 42149Object.assign( StereoCamera.prototype, { 42150 42151 update: function ( camera ) { 42152 42153 var cache = this._cache; 42154 42155 var needsUpdate = cache.focus !== camera.focus || cache.fov !== camera.fov || 42156 cache.aspect !== camera.aspect * this.aspect || cache.near !== camera.near || 42157 cache.far !== camera.far || cache.zoom !== camera.zoom || cache.eyeSep !== this.eyeSep; 42158 42159 if ( needsUpdate ) { 42160 42161 cache.focus = camera.focus; 42162 cache.fov = camera.fov; 42163 cache.aspect = camera.aspect * this.aspect; 42164 cache.near = camera.near; 42165 cache.far = camera.far; 42166 cache.zoom = camera.zoom; 42167 cache.eyeSep = this.eyeSep; 42168 42169 // Off-axis stereoscopic effect based on 42170 // http://paulbourke.net/stereographics/stereorender/ 42171 42172 var projectionMatrix = camera.projectionMatrix.clone(); 42173 var eyeSepHalf = cache.eyeSep / 2; 42174 var eyeSepOnProjection = eyeSepHalf * cache.near / cache.focus; 42175 var ymax = ( cache.near * Math.tan( MathUtils.DEG2RAD * cache.fov * 0.5 ) ) / cache.zoom; 42176 var xmin, xmax; 42177 42178 // translate xOffset 42179 42180 _eyeLeft.elements[ 12 ] = - eyeSepHalf; 42181 _eyeRight.elements[ 12 ] = eyeSepHalf; 42182 42183 // for left eye 42184 42185 xmin = - ymax * cache.aspect + eyeSepOnProjection; 42186 xmax = ymax * cache.aspect + eyeSepOnProjection; 42187 42188 projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin ); 42189 projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin ); 42190 42191 this.cameraL.projectionMatrix.copy( projectionMatrix ); 42192 42193 // for right eye 42194 42195 xmin = - ymax * cache.aspect - eyeSepOnProjection; 42196 xmax = ymax * cache.aspect - eyeSepOnProjection; 42197 42198 projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin ); 42199 projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin ); 42200 42201 this.cameraR.projectionMatrix.copy( projectionMatrix ); 42202 42203 } 42204 42205 this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeLeft ); 42206 this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeRight ); 42207 42208 } 42209 42210} ); 42211 42212/** 42213 * @author alteredq / http://alteredqualia.com/ 42214 */ 42215 42216function Clock( autoStart ) { 42217 42218 this.autoStart = ( autoStart !== undefined ) ? autoStart : true; 42219 42220 this.startTime = 0; 42221 this.oldTime = 0; 42222 this.elapsedTime = 0; 42223 42224 this.running = false; 42225 42226} 42227 42228Object.assign( Clock.prototype, { 42229 42230 start: function () { 42231 42232 this.startTime = ( typeof performance === 'undefined' ? Date : performance ).now(); // see #10732 42233 42234 this.oldTime = this.startTime; 42235 this.elapsedTime = 0; 42236 this.running = true; 42237 42238 }, 42239 42240 stop: function () { 42241 42242 this.getElapsedTime(); 42243 this.running = false; 42244 this.autoStart = false;
42245 42246 }, 42247 42248 getElapsedTime: function () { 42249 42250 this.getDelta(); 42251 return this.elapsedTime; 42252 42253 }, 42254 42255 getDelta: function () { 42256 42257 var diff = 0; 42258 42259 if ( this.autoStart && ! this.running ) { 42260 42261 this.start(); 42262 return 0; 42263 42264 } 42265 42266 if ( this.running ) { 42267 42268 var newTime = ( typeof performance === 'undefined' ? Date : performance ).now(); 42269 42270 diff = ( newTime - this.oldTime ) / 1000; 42271 this.oldTime = newTime; 42272 42273 this.elapsedTime += diff; 42274 42275 } 42276 42277 return diff; 42278 42279 } 42280 42281} ); 42282 42283/** 42284 * @author mrdoob / http://mrdoob.com/ 42285 */ 42286 42287var _position$2 = new Vector3(); 42288var _quaternion$3 = new Quaternion(); 42289var _scale$1 = new Vector3(); 42290var _orientation = new Vector3(); 42291 42292function AudioListener() { 42293 42294 Object3D.call( this ); 42295 42296 this.type = 'AudioListener'; 42297 42298 this.context = AudioContext.getContext(); 42299 42300 this.gain = this.context.createGain(); 42301 this.gain.connect( this.context.destination ); 42302 42303 this.filter = null; 42304 42305 this.timeDelta = 0; 42306 42307 // private 42308 42309 this._clock = new Clock(); 42310 42311} 42312 42313AudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), { 42314 42315 constructor: AudioListener, 42316 42317 getInput: function () { 42318 42319 return this.gain; 42320 42321 }, 42322 42323 removeFilter: function ( ) { 42324 42325 if ( this.filter !== null ) { 42326 42327 this.gain.disconnect( this.filter ); 42328 this.filter.disconnect( this.context.destination ); 42329 this.gain.connect( this.context.destination ); 42330 this.filter = null; 42331 42332 } 42333 42334 return this; 42335 42336 }, 42337 42338 getFilter: function () { 42339 42340 return this.filter; 42341 42342 }, 42343 42344 setFilter: function ( value ) { 42345 42346 if ( this.filter !== null ) { 42347 42348 this.gain.disconnect( this.filter ); 42349 this.filter.disconnect( this.context.destination ); 42350 42351 } else { 42352 42353 this.gain.disconnect( this.context.destination ); 42354 42355 } 42356 42357 this.filter = value; 42358 this.gain.connect( this.filter ); 42359 this.filter.connect( this.context.destination ); 42360 42361 return this; 42362 42363 }, 42364 42365 getMasterVolume: function () { 42366 42367 return this.gain.gain.value; 42368 42369 }, 42370 42371 setMasterVolume: function ( value ) { 42372 42373 this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 ); 42374 42375 return this; 42376 42377 }, 42378 42379 updateMatrixWorld: function ( force ) { 42380 42381 Object3D.prototype.updateMatrixWorld.call( this, force ); 42382 42383 var listener = this.context.listener; 42384 var up = this.up; 42385 42386 this.timeDelta = this._clock.getDelta(); 42387 42388 this.matrixWorld.decompose( _position$2, _quaternion$3, _scale$1 ); 42389 42390 _orientation.set( 0, 0, - 1 ).applyQuaternion( _quaternion$3 ); 42391 42392 if ( listener.positionX ) { 42393 42394 // code path for Chrome (see #14393) 42395 42396 var endTime = this.context.currentTime + this.timeDelta; 42397 42398 listener.positionX.linearRampToValueAtTime( _position$2.x, endTime ); 42399 listener.positionY.linearRampToValueAtTime( _position$2.y, endTime ); 42400 listener.positionZ.linearRampToValueAtTime( _position$2.z, endTime ); 42401 listener.forwardX.linearRampToValueAtTime( _orientation.x, endTime ); 42402 listener.forwardY.linearRampToValueAtTime( _orientation.y, endTime ); 42403 listener.forwardZ.linearRampToValueAtTime( _orientation.z, endTime ); 42404 listener.upX.linearRampToValueAtTime( up.x, endTime ); 42405 listener.upY.linearRampToValueAtTime( up.y, endTime ); 42406 listener.upZ.linearRampToValueAtTime( up.z, endTime ); 42407 42408 } else { 42409 42410 listener.setPosition( _position$2.x, _position$2.y, _position$2.z ); 42411 listener.setOrientation( _orientation.x, _orientation.y, _orientation.z, up.x, up.y, up.z ); 42412 42413 } 42414 42415 } 42416 42417} ); 42418 42419/** 42420 * @author mrdoob / http://mrdoob.com/ 42421 * @author Reece Aaron Lecrivain / http://reecenotes.com/ 42422 */ 42423 42424function Audio( listener ) { 42425 42426 Object3D.call( this ); 42427 42428 this.type = 'Audio'; 42429 42430 this.listener = listener; 42431 this.context = listener.context; 42432 42433 this.gain = this.context.createGain(); 42434 this.gain.connect( listener.getInput() ); 42435 42436 this.autoplay = false; 42437 42438 this.buffer = null; 42439 this.detune = 0; 42440 this.loop = false; 42441 this.loopStart = 0; 42442 this.loopEnd = 0; 42443 this.offset = 0; 42444 this.duration = undefined; 42445 this.playbackRate = 1; 42446 this.isPlaying = false; 42447 this.hasPlaybackControl = true; 42448 this.sourceType = 'empty'; 42449 42450 this._startedAt = 0; 42451 this._progress = 0; 42452 42453 this.filters = []; 42454 42455} 42456 42457Audio.prototype = Object.assign( Object.create( Object3D.prototype ), { 42458 42459 constructor: Audio, 42460 42461 getOutput: function () { 42462 42463 return this.gain; 42464 42465 }, 42466 42467 setNodeSource: function ( audioNode ) { 42468 42469 this.hasPlaybackControl = false;
42470 this.sourceType = 'audioNode'; 42471 this.source = audioNode; 42472 this.connect(); 42473 42474 return this; 42475 42476 }, 42477 42478 setMediaElementSource: function ( mediaElement ) { 42479 42480 this.hasPlaybackControl = false; 42481 this.sourceType = 'mediaNode'; 42482 this.source = this.context.createMediaElementSource( mediaElement ); 42483 this.connect(); 42484 42485 return this; 42486 42487 }, 42488 42489 setMediaStreamSource: function ( mediaStream ) { 42490 42491 this.hasPlaybackControl = false; 42492 this.sourceType = 'mediaStreamNode'; 42493 this.source = this.context.createMediaStreamSource( mediaStream ); 42494 this.connect(); 42495 42496 return this; 42497 42498 }, 42499 42500 setBuffer: function ( audioBuffer ) { 42501 42502 this.buffer = audioBuffer; 42503 this.sourceType = 'buffer'; 42504 42505 if ( this.autoplay ) this.play(); 42506 42507 return this; 42508 42509 }, 42510 42511 play: function ( delay ) { 42512 42513 if ( delay === undefined ) delay = 0; 42514 42515 if ( this.isPlaying === true ) { 42516 42517 console.warn( 'THREE.Audio: Audio is already playing.' ); 42518 return; 42519 42520 } 42521 42522 if ( this.hasPlaybackControl === false ) { 42523 42524 console.warn( 'THREE.Audio: this Audio has no playback control.' ); 42525 return; 42526 42527 } 42528 42529 this._startedAt = this.context.currentTime + delay; 42530 42531 var source = this.context.createBufferSource(); 42532 source.buffer = this.buffer; 42533 source.loop = this.loop; 42534 source.loopStart = this.loopStart; 42535 source.loopEnd = this.loopEnd; 42536 source.onended = this.onEnded.bind( this ); 42537 source.start( this._startedAt, this._progress + this.offset, this.duration ); 42538 42539 this.isPlaying = true; 42540 42541 this.source = source; 42542 42543 this.setDetune( this.detune ); 42544 this.setPlaybackRate( this.playbackRate ); 42545 42546 return this.connect(); 42547 42548 }, 42549 42550 pause: function () { 42551 42552 if ( this.hasPlaybackControl === false ) { 42553 42554 console.warn( 'THREE.Audio: this Audio has no playback control.' ); 42555 return; 42556 42557 } 42558 42559 if ( this.isPlaying === true ) { 42560 42561 // update current progress 42562 42563 this._progress += Math.max( this.context.currentTime - this._startedAt, 0 ) * this.playbackRate; 42564 42565 if ( this.loop === true ) { 42566 42567 // ensure _progress does not exceed duration with looped audios 42568 42569 this._progress = this._progress % ( this.duration || this.buffer.duration ); 42570 42571 } 42572 42573 this.source.stop(); 42574 this.source.onended = null; 42575 42576 this.isPlaying = false; 42577 42578 } 42579 42580 return this; 42581 42582 }, 42583 42584 stop: function () { 42585 42586 if ( this.hasPlaybackControl === false ) { 42587 42588 console.warn( 'THREE.Audio: this Audio has no playback control.' ); 42589 return; 42590 42591 } 42592 42593 this._progress = 0; 42594 42595 this.source.stop(); 42596 this.source.onended = null; 42597 this.isPlaying = false; 42598 42599 return this; 42600 42601 }, 42602 42603 connect: function () { 42604 42605 if ( this.filters.length > 0 ) { 42606 42607 this.source.connect( this.filters[ 0 ] ); 42608 42609 for ( var i = 1, l = this.filters.length; i < l; i ++ ) { 42610 42611 this.filters[ i - 1 ].connect( this.filters[ i ] ); 42612 42613 } 42614 42615 this.filters[ this.filters.length - 1 ].connect( this.getOutput() ); 42616 42617 } else { 42618 42619 this.source.connect( this.getOutput() ); 42620 42621 } 42622 42623 return this; 42624 42625 }, 42626 42627 disconnect: function () { 42628 42629 if ( this.filters.length > 0 ) { 42630 42631 this.source.disconnect( this.filters[ 0 ] ); 42632 42633 for ( var i = 1, l = this.filters.length; i < l; i ++ ) { 42634 42635 this.filters[ i - 1 ].disconnect( this.filters[ i ] ); 42636 42637 } 42638 42639 this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() ); 42640 42641 } else { 42642 42643 this.source.disconnect( this.getOutput() ); 42644 42645 } 42646 42647 return this; 42648 42649 }, 42650 42651 getFilters: function () { 42652 42653 return this.filters; 42654 42655 }, 42656 42657 setFilters: function ( value ) { 42658 42659 if ( ! value ) value = []; 42660 42661 if ( this.isPlaying === true ) { 42662 42663 this.disconnect(); 42664 this.filters = value; 42665 this.connect(); 42666 42667 } else { 42668 42669 this.filters = value; 42670 42671 } 42672 42673 return this; 42674 42675 }, 42676 42677 setDetune: function ( value ) { 42678 42679 this.detune = value; 42680 42681 if ( this.source.detune === undefined ) return; // only set detune when available 42682 42683 if ( this.isPlaying === true ) { 42684 42685 this.source.detune.setTargetAtTime( this.detune, this.context.currentTime, 0.01 ); 42686 42687 } 42688 42689 return this; 42690 42691 }, 42692 42693 getDetune: function () { 42694 42695 return this.detune; 42696 42697 }, 42698 42699 getFilter: function () { 42700 42701 return this.getFilters()[ 0 ]; 42702 42703 }, 42704 42705 setFilter: function ( filter ) { 42706 42707 return this.setFilters( filter ? [ filter ] : [] ); 42708 42709 }, 42710 42711 setPlaybackRate: function ( value ) { 42712 42713 if ( this.hasPlaybackControl === false ) { 42714 42715 console.warn( 'THREE.Audio: this Audio has no playback control.' ); 42716 return; 42717 42718 } 42719 42720 this.playbackRate = value; 42721 42722 if ( this.isPlaying === true ) { 42723 42724 this.source.playbackRate.setTargetAtTime( this.playbackRate, this.context.currentTime, 0.01 ); 42725 42726 } 42727 42728 return this; 42729 42730 }, 42731 42732 getPlaybackRate: function () { 42733 42734 return this.playbackRate; 42735 42736 }, 42737 42738 onEnded: function () { 42739 42740 this.isPlaying = false;
42741 42742 }, 42743 42744 getLoop: function () { 42745 42746 if ( this.hasPlaybackControl === false ) { 42747 42748 console.warn( 'THREE.Audio: this Audio has no playback control.' ); 42749 return false; 42750 42751 } 42752 42753 return this.loop; 42754 42755 }, 42756 42757 setLoop: function ( value ) { 42758 42759 if ( this.hasPlaybackControl === false ) { 42760 42761 console.warn( 'THREE.Audio: this Audio has no playback control.' ); 42762 return; 42763 42764 } 42765 42766 this.loop = value; 42767 42768 if ( this.isPlaying === true ) { 42769 42770 this.source.loop = this.loop; 42771 42772 } 42773 42774 return this; 42775 42776 }, 42777 42778 setLoopStart: function ( value ) { 42779 42780 this.loopStart = value; 42781 42782 return this; 42783 42784 }, 42785 42786 setLoopEnd: function ( value ) { 42787 42788 this.loopEnd = value; 42789 42790 return this; 42791 42792 }, 42793 42794 getVolume: function () { 42795 42796 return this.gain.gain.value; 42797 42798 }, 42799 42800 setVolume: function ( value ) { 42801 42802 this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 ); 42803 42804 return this; 42805 42806 } 42807 42808} ); 42809 42810/** 42811 * @author mrdoob / http://mrdoob.com/ 42812 */ 42813 42814var _position$3 = new Vector3(); 42815var _quaternion$4 = new Quaternion(); 42816var _scale$2 = new Vector3(); 42817var _orientation$1 = new Vector3(); 42818 42819function PositionalAudio( listener ) { 42820 42821 Audio.call( this, listener ); 42822 42823 this.panner = this.context.createPanner(); 42824 this.panner.panningModel = 'HRTF'; 42825 this.panner.connect( this.gain ); 42826 42827} 42828 42829PositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), { 42830 42831 constructor: PositionalAudio, 42832 42833 getOutput: function () { 42834 42835 return this.panner; 42836 42837 }, 42838 42839 getRefDistance: function () { 42840 42841 return this.panner.refDistance; 42842 42843 }, 42844 42845 setRefDistance: function ( value ) { 42846 42847 this.panner.refDistance = value; 42848 42849 return this; 42850 42851 }, 42852 42853 getRolloffFactor: function () { 42854 42855 return this.panner.rolloffFactor; 42856 42857 }, 42858 42859 setRolloffFactor: function ( value ) { 42860 42861 this.panner.rolloffFactor = value; 42862 42863 return this; 42864 42865 }, 42866 42867 getDistanceModel: function () { 42868 42869 return this.panner.distanceModel; 42870 42871 }, 42872 42873 setDistanceModel: function ( value ) { 42874 42875 this.panner.distanceModel = value; 42876 42877 return this; 42878 42879 }, 42880 42881 getMaxDistance: function () { 42882 42883 return this.panner.maxDistance; 42884 42885 }, 42886 42887 setMaxDistance: function ( value ) { 42888 42889 this.panner.maxDistance = value; 42890 42891 return this; 42892 42893 }, 42894 42895 setDirectionalCone: function ( coneInnerAngle, coneOuterAngle, coneOuterGain ) { 42896 42897 this.panner.coneInnerAngle = coneInnerAngle; 42898 this.panner.coneOuterAngle = coneOuterAngle; 42899 this.panner.coneOuterGain = coneOuterGain; 42900 42901 return this; 42902 42903 }, 42904 42905 updateMatrixWorld: function ( force ) { 42906 42907 Object3D.prototype.updateMatrixWorld.call( this, force ); 42908 42909 if ( this.hasPlaybackControl === true && this.isPlaying === false ) return; 42910 42911 this.matrixWorld.decompose( _position$3, _quaternion$4, _scale$2 ); 42912 42913 _orientation$1.set( 0, 0, 1 ).applyQuaternion( _quaternion$4 ); 42914 42915 var panner = this.panner; 42916 42917 if ( panner.positionX ) { 42918 42919 // code path for Chrome and Firefox (see #14393) 42920 42921 var endTime = this.context.currentTime + this.listener.timeDelta; 42922 42923 panner.positionX.linearRampToValueAtTime( _position$3.x, endTime ); 42924 panner.positionY.linearRampToValueAtTime( _position$3.y, endTime ); 42925 panner.positionZ.linearRampToValueAtTime( _position$3.z, endTime ); 42926 panner.orientationX.linearRampToValueAtTime( _orientation$1.x, endTime ); 42927 panner.orientationY.linearRampToValueAtTime( _orientation$1.y, endTime ); 42928 panner.orientationZ.linearRampToValueAtTime( _orientation$1.z, endTime ); 42929 42930 } else { 42931 42932 panner.setPosition( _position$3.x, _position$3.y, _position$3.z ); 42933 panner.setOrientation( _orientation$1.x, _orientation$1.y, _orientation$1.z ); 42934 42935 } 42936 42937 } 42938 42939} ); 42940 42941/** 42942 * @author mrdoob / http://mrdoob.com/ 42943 */ 42944 42945function AudioAnalyser( audio, fftSize ) { 42946 42947 this.analyser = audio.context.createAnalyser(); 42948 this.analyser.fftSize = fftSize !== undefined ? fftSize : 2048; 42949 42950 this.data = new Uint8Array( this.analyser.frequencyBinCount ); 42951 42952 audio.getOutput().connect( this.analyser ); 42953 42954} 42955 42956Object.assign( AudioAnalyser.prototype, { 42957 42958 getFrequencyData: function () { 42959 42960 this.analyser.getByteFrequencyData( this.data ); 42961 42962 return this.data; 42963 42964 }, 42965 42966 getAverageFrequency: function () { 42967 42968 var value = 0, data = this.getFrequencyData(); 42969 42970 for ( var i = 0; i < data.length; i ++ ) { 42971 42972 value += data[ i ]; 42973 42974 } 42975 42976 return value / data.length; 42977 42978 } 42979 42980} ); 42981 42982/** 42983 * 42984 * Buffered scene graph property that allows weighted accumulation. 42985 * 42986 * 42987 * @author Ben Houston / http://clara.io/ 42988 * @author David Sarno / http://lighthaus.us/ 42989 * @author tschw 42990 */ 42991 42992function PropertyMixer( binding, typeName, valueSize ) { 42993 42994 this.binding = binding; 42995 this.valueSize = valueSize; 42996 42997 var mixFunction, 42998 mixFunctionAdditive, 42999 setIdentity; 43000 43001 // buffer layout: [ incoming | accu0 | accu1 | orig | addAccu | (optional work) ] 43002 // 43003 // interpolators can use .buffer as their .result 43004 // the data then goes to 'incoming' 43005 // 43006 // 'accu0' and 'accu1' are used frame-interleaved for 43007 // the cumulative result and are compared to detect 43008 // changes 43009 // 43010 // 'orig' stores the original state of the property 43011 // 43012 // 'add' is used for additive cumulative results 43013 //
vendor: 22,486 bytes, lines 43014-44023
43014 // 'work' is optional and is only present for quaternion types. It is used 43015 // to store intermediate quaternion multiplication results 43016 43017 switch ( typeName ) { 43018 43019 case 'quaternion': 43020 mixFunction = this._slerp; 43021 mixFunctionAdditive = this._slerpAdditive; 43022 setIdentity = this._setAdditiveIdentityQuaternion; 43023 43024 this.buffer = new Float64Array( valueSize * 6 ); 43025 this._workIndex = 5; 43026 break; 43027 43028 case 'string': 43029 case 'bool': 43030 mixFunction = this._select; 43031 43032 // Use the regular mix function and for additive on these types, 43033 // additive is not relevant for non-numeric types 43034 mixFunctionAdditive = this._select; 43035 43036 setIdentity = this._setAdditiveIdentityOther; 43037 43038 this.buffer = new Array( valueSize * 5 ); 43039 break; 43040 43041 default: 43042 mixFunction = this._lerp; 43043 mixFunctionAdditive = this._lerpAdditive; 43044 setIdentity = this._setAdditiveIdentityNumeric; 43045 43046 this.buffer = new Float64Array( valueSize * 5 ); 43047 43048 } 43049 43050 this._mixBufferRegion = mixFunction; 43051 this._mixBufferRegionAdditive = mixFunctionAdditive; 43052 this._setIdentity = setIdentity; 43053 this._origIndex = 3; 43054 this._addIndex = 4; 43055 43056 this.cumulativeWeight = 0; 43057 this.cumulativeWeightAdditive = 0; 43058 43059 this.useCount = 0; 43060 this.referenceCount = 0; 43061 43062} 43063 43064Object.assign( PropertyMixer.prototype, { 43065 43066 // accumulate data in the 'incoming' region into 'accu<i>' 43067 accumulate: function ( accuIndex, weight ) { 43068 43069 // note: happily accumulating nothing when weight = 0, the caller knows 43070 // the weight and shouldn't have made the call in the first place 43071 43072 var buffer = this.buffer, 43073 stride = this.valueSize, 43074 offset = accuIndex * stride + stride, 43075 43076 currentWeight = this.cumulativeWeight; 43077 43078 if ( currentWeight === 0 ) { 43079 43080 // accuN := incoming * weight 43081 43082 for ( var i = 0; i !== stride; ++ i ) { 43083 43084 buffer[ offset + i ] = buffer[ i ]; 43085 43086 } 43087 43088 currentWeight = weight; 43089 43090 } else { 43091 43092 // accuN := accuN + incoming * weight 43093 43094 currentWeight += weight; 43095 var mix = weight / currentWeight; 43096 this._mixBufferRegion( buffer, offset, 0, mix, stride ); 43097 43098 } 43099 43100 this.cumulativeWeight = currentWeight; 43101 43102 }, 43103 43104 // accumulate data in the 'incoming' region into 'add' 43105 accumulateAdditive: function ( weight ) { 43106 43107 var buffer = this.buffer, 43108 stride = this.valueSize, 43109 offset = stride * this._addIndex; 43110 43111 if ( this.cumulativeWeightAdditive === 0 ) { 43112 43113 // add = identity 43114 43115 this._setIdentity(); 43116 43117 } 43118 43119 // add := add + incoming * weight 43120 43121 this._mixBufferRegionAdditive( buffer, offset, 0, weight, stride ); 43122 this.cumulativeWeightAdditive += weight; 43123 43124 }, 43125 43126 // apply the state of 'accu<i>' to the binding when accus differ 43127 apply: function ( accuIndex ) { 43128 43129 var stride = this.valueSize, 43130 buffer = this.buffer, 43131 offset = accuIndex * stride + stride, 43132 43133 weight = this.cumulativeWeight, 43134 weightAdditive = this.cumulativeWeightAdditive, 43135 43136 binding = this.binding; 43137 43138 this.cumulativeWeight = 0; 43139 this.cumulativeWeightAdditive = 0; 43140 43141 if ( weight < 1 ) { 43142 43143 // accuN := accuN + original * ( 1 - cumulativeWeight ) 43144 43145 var originalValueOffset = stride * this._origIndex; 43146 43147 this._mixBufferRegion( 43148 buffer, offset, originalValueOffset, 1 - weight, stride ); 43149 43150 } 43151 43152 if ( weightAdditive > 0 ) { 43153 43154 // accuN := accuN + additive accuN 43155 43156 this._mixBufferRegionAdditive( buffer, offset, this._addIndex * stride, 1, stride ); 43157 43158 } 43159 43160 for ( var i = stride, e = stride + stride; i !== e; ++ i ) { 43161 43162 if ( buffer[ i ] !== buffer[ i + stride ] ) { 43163 43164 // value has changed -> update scene graph 43165 43166 binding.setValue( buffer, offset ); 43167 break; 43168 43169 } 43170 43171 } 43172 43173 }, 43174 43175 // remember the state of the bound property and copy it to both accus 43176 saveOriginalState: function () { 43177 43178 var binding = this.binding; 43179 43180 var buffer = this.buffer, 43181 stride = this.valueSize, 43182 43183 originalValueOffset = stride * this._origIndex; 43184 43185 binding.getValue( buffer, originalValueOffset ); 43186 43187 // accu[0..1] := orig -- initially detect changes against the original 43188 for ( var i = stride, e = originalValueOffset; i !== e; ++ i ) { 43189 43190 buffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ]; 43191 43192 } 43193 43194 // Add to identity for additive 43195 this._setIdentity(); 43196 43197 this.cumulativeWeight = 0; 43198 this.cumulativeWeightAdditive = 0; 43199 43200 }, 43201 43202 // apply the state previously taken via 'saveOriginalState' to the binding 43203 restoreOriginalState: function () { 43204 43205 var originalValueOffset = this.valueSize * 3; 43206 this.binding.setValue( this.buffer, originalValueOffset ); 43207 43208 }, 43209 43210 _setAdditiveIdentityNumeric: function () { 43211 43212 var startIndex = this._addIndex * this.valueSize; 43213 43214 this.buffer.fill( 0, startIndex, startIndex + this.valueSize ); 43215 43216 }, 43217 43218 _setAdditiveIdentityQuaternion: function () { 43219 43220 this._setAdditiveIdentityNumeric(); 43221 this.buffer[ this._addIndex * 4 + 3 ] = 1; 43222 43223 }, 43224 43225 _setAdditiveIdentityOther: function () { 43226 43227 var startIndex = this._origIndex * this.valueSize; 43228 var targetIndex = this._addIndex * this.valueSize; 43229 43230 this.buffer.copyWithin( targetIndex, startIndex, this.valueSize ); 43231 43232 }, 43233 43234 43235 // mix functions 43236 43237 _select: function ( buffer, dstOffset, srcOffset, t, stride ) { 43238 43239 if ( t >= 0.5 ) { 43240 43241 for ( var i = 0; i !== stride; ++ i ) { 43242 43243 buffer[ dstOffset + i ] = buffer[ srcOffset + i ]; 43244 43245 } 43246 43247 } 43248 43249 }, 43250 43251 _slerp: function ( buffer, dstOffset, srcOffset, t ) { 43252 43253 Quaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t ); 43254 43255 }, 43256 43257 _slerpAdditive: function ( buffer, dstOffset, srcOffset, t, stride ) { 43258 43259 var workOffset = this._workIndex * stride; 43260 43261 // Store result in intermediate buffer offset 43262 Quaternion.multiplyQuaternionsFlat( buffer, workOffset, buffer, dstOffset, buffer, srcOffset ); 43263 43264 // Slerp to the intermediate result 43265 Quaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t ); 43266 43267 }, 43268 43269 _lerp: function ( buffer, dstOffset, srcOffset, t, stride ) { 43270 43271 var s = 1 - t; 43272 43273 for ( var i = 0; i !== stride; ++ i ) { 43274 43275 var j = dstOffset + i; 43276 43277 buffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t; 43278 43279 } 43280 43281 }, 43282 43283 _lerpAdditive: function ( buffer, dstOffset, srcOffset, t, stride ) { 43284 43285 for ( var i = 0; i !== stride; ++ i ) { 43286 43287 var j = dstOffset + i; 43288 43289 buffer[ j ] = buffer[ j ] + buffer[ srcOffset + i ] * t; 43290 43291 } 43292 43293 } 43294 43295} ); 43296 43297/** 43298 * 43299 * A reference to a real property in the scene graph. 43300 * 43301 * 43302 * @author Ben Houston / http://clara.io/ 43303 * @author David Sarno / http://lighthaus.us/ 43304 * @author tschw 43305 */ 43306 43307// Characters [].:/ are reserved for track binding syntax. 43308var _RESERVED_CHARS_RE = '\\[\\]\\.:\\/'; 43309var _reservedRe = new RegExp( '[' + _RESERVED_CHARS_RE + ']', 'g' ); 43310 43311// Attempts to allow node names from any language. ES5's `\w` regexp matches 43312// only latin characters, and the unicode \p{L} is not yet supported. So 43313// instead, we exclude reserved characters and match everything else. 43314var _wordChar = '[^' + _RESERVED_CHARS_RE + ']'; 43315var _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace( '\\.', '' ) + ']'; 43316 43317// Parent directories, delimited by '/' or ':'. Currently unused, but must 43318// be matched to parse the rest of the track name. 43319var _directoryRe = /((?:WC+[\/:])*)/.source.replace( 'WC', _wordChar ); 43320 43321// Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'. 43322var _nodeRe = /(WCOD+)?/.source.replace( 'WCOD', _wordCharOrDot ); 43323 43324// Object on target node, and accessor. May not contain reserved 43325// characters. Accessor may contain any character except closing bracket. 43326var _objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace( 'WC', _wordChar ); 43327 43328// Property and accessor. May not contain reserved characters. Accessor may 43329// contain any non-bracket characters. 43330var _propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace( 'WC', _wordChar ); 43331 43332var _trackRe = new RegExp( '' 43333 + '^' 43334 + _directoryRe 43335 + _nodeRe 43336 + _objectRe 43337 + _propertyRe 43338 + '$' 43339); 43340 43341var _supportedObjectNames = [ 'material', 'materials', 'bones' ]; 43342 43343function Composite( targetGroup, path, optionalParsedPath ) { 43344 43345 var parsedPath = optionalParsedPath || PropertyBinding.parseTrackName( path ); 43346 43347 this._targetGroup = targetGroup; 43348 this._bindings = targetGroup.subscribe_( path, parsedPath ); 43349 43350} 43351 43352Object.assign( Composite.prototype, { 43353 43354 getValue: function ( array, offset ) { 43355 43356 this.bind(); // bind all binding 43357 43358 var firstValidIndex = this._targetGroup.nCachedObjects_, 43359 binding = this._bindings[ firstValidIndex ]; 43360 43361 // and only call .getValue on the first 43362 if ( binding !== undefined ) binding.getValue( array, offset ); 43363 43364 }, 43365 43366 setValue: function ( array, offset ) { 43367 43368 var bindings = this._bindings; 43369 43370 for ( var i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) { 43371 43372 bindings[ i ].setValue( array, offset ); 43373 43374 } 43375 43376 }, 43377 43378 bind: function () { 43379 43380 var bindings = this._bindings; 43381 43382 for ( var i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) { 43383 43384 bindings[ i ].bind(); 43385 43386 } 43387 43388 }, 43389 43390 unbind: function () { 43391 43392 var bindings = this._bindings; 43393 43394 for ( var i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) { 43395 43396 bindings[ i ].unbind(); 43397 43398 } 43399 43400 } 43401 43402} ); 43403 43404 43405function PropertyBinding( rootNode, path, parsedPath ) { 43406 43407 this.path = path; 43408 this.parsedPath = parsedPath || PropertyBinding.parseTrackName( path ); 43409 43410 this.node = PropertyBinding.findNode( rootNode, this.parsedPath.nodeName ) || rootNode; 43411 43412 this.rootNode = rootNode; 43413 43414} 43415 43416Object.assign( PropertyBinding, { 43417 43418 Composite: Composite, 43419 43420 create: function ( root, path, parsedPath ) { 43421 43422 if ( ! ( root && root.isAnimationObjectGroup ) ) { 43423 43424 return new PropertyBinding( root, path, parsedPath ); 43425 43426 } else { 43427 43428 return new PropertyBinding.Composite( root, path, parsedPath ); 43429 43430 } 43431 43432 }, 43433 43434 /** 43435 * Replaces spaces with underscores and removes unsupported characters from 43436 * node names, to ensure compatibility with parseTrackName(). 43437 * 43438 * @param {string} name Node name to be sanitized. 43439 * @return {string} 43440 */ 43441 sanitizeNodeName: function ( name ) { 43442 43443 return name.replace( /\s/g, '_' ).replace( _reservedRe, '' ); 43444 43445 }, 43446 43447 parseTrackName: function ( trackName ) { 43448 43449 var matches = _trackRe.exec( trackName ); 43450 43451 if ( ! matches ) { 43452 43453 throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName ); 43454 43455 } 43456 43457 var results = { 43458 // directoryName: matches[ 1 ], // (tschw) currently unused 43459 nodeName: matches[ 2 ], 43460 objectName: matches[ 3 ], 43461 objectIndex: matches[ 4 ], 43462 propertyName: matches[ 5 ], // required 43463 propertyIndex: matches[ 6 ] 43464 }; 43465 43466 var lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' ); 43467 43468 if ( lastDot !== undefined && lastDot !== - 1 ) { 43469 43470 var objectName = results.nodeName.substring( lastDot + 1 ); 43471 43472 // Object names must be checked against a whitelist. Otherwise, there 43473 // is no way to parse 'foo.bar.baz': 'baz' must be a property, but 43474 // 'bar' could be the objectName, or part of a nodeName (which can 43475 // include '.' characters). 43476 if ( _supportedObjectNames.indexOf( objectName ) !== - 1 ) { 43477 43478 results.nodeName = results.nodeName.substring( 0, lastDot ); 43479 results.objectName = objectName; 43480 43481 } 43482 43483 } 43484 43485 if ( results.propertyName === null || results.propertyName.length === 0 ) { 43486 43487 throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName ); 43488 43489 } 43490 43491 return results; 43492 43493 }, 43494 43495 findNode: function ( root, nodeName ) { 43496 43497 if ( ! nodeName || nodeName === "" || nodeName === "." || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) { 43498 43499 return root; 43500 43501 } 43502 43503 // search into skeleton bones. 43504 if ( root.skeleton ) { 43505 43506 var bone = root.skeleton.getBoneByName( nodeName ); 43507 43508 if ( bone !== undefined ) { 43509 43510 return bone; 43511 43512 } 43513 43514 } 43515 43516 // search into node subtree. 43517 if ( root.children ) { 43518 43519 var searchNodeSubtree = function ( children ) { 43520 43521 for ( var i = 0; i < children.length; i ++ ) { 43522 43523 var childNode = children[ i ]; 43524 43525 if ( childNode.name === nodeName || childNode.uuid === nodeName ) { 43526 43527 return childNode; 43528 43529 } 43530 43531 var result = searchNodeSubtree( childNode.children ); 43532 43533 if ( result ) return result; 43534 43535 } 43536 43537 return null; 43538 43539 }; 43540 43541 var subTreeNode = searchNodeSubtree( root.children ); 43542 43543 if ( subTreeNode ) { 43544 43545 return subTreeNode; 43546 43547 } 43548 43549 } 43550 43551 return null; 43552 43553 } 43554 43555} ); 43556 43557Object.assign( PropertyBinding.prototype, { // prototype, continued 43558 43559 // these are used to "bind" a nonexistent property 43560 _getValue_unavailable: function () {}, 43561 _setValue_unavailable: function () {}, 43562 43563 BindingType: { 43564 Direct: 0, 43565 EntireArray: 1, 43566 ArrayElement: 2, 43567 HasFromToArray: 3 43568 }, 43569 43570 Versioning: { 43571 None: 0, 43572 NeedsUpdate: 1, 43573 MatrixWorldNeedsUpdate: 2 43574 }, 43575 43576 GetterByBindingType: [ 43577 43578 function getValue_direct( buffer, offset ) { 43579 43580 buffer[ offset ] = this.node[ this.propertyName ]; 43581 43582 }, 43583 43584 function getValue_array( buffer, offset ) { 43585 43586 var source = this.resolvedProperty; 43587 43588 for ( var i = 0, n = source.length; i !== n; ++ i ) { 43589 43590 buffer[ offset ++ ] = source[ i ]; 43591 43592 } 43593 43594 }, 43595 43596 function getValue_arrayElement( buffer, offset ) { 43597 43598 buffer[ offset ] = this.resolvedProperty[ this.propertyIndex ]; 43599 43600 }, 43601 43602 function getValue_toArray( buffer, offset ) { 43603 43604 this.resolvedProperty.toArray( buffer, offset ); 43605 43606 } 43607 43608 ], 43609 43610 SetterByBindingTypeAndVersioning: [ 43611 43612 [ 43613 // Direct 43614 43615 function setValue_direct( buffer, offset ) { 43616 43617 this.targetObject[ this.propertyName ] = buffer[ offset ]; 43618 43619 }, 43620 43621 function setValue_direct_setNeedsUpdate( buffer, offset ) { 43622 43623 this.targetObject[ this.propertyName ] = buffer[ offset ]; 43624 this.targetObject.needsUpdate = true; 43625 43626 }, 43627 43628 function setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) { 43629 43630 this.targetObject[ this.propertyName ] = buffer[ offset ]; 43631 this.targetObject.matrixWorldNeedsUpdate = true; 43632 43633 } 43634 43635 ], [ 43636 43637 // EntireArray 43638 43639 function setValue_array( buffer, offset ) { 43640 43641 var dest = this.resolvedProperty; 43642 43643 for ( var i = 0, n = dest.length; i !== n; ++ i ) { 43644 43645 dest[ i ] = buffer[ offset ++ ]; 43646 43647 } 43648 43649 }, 43650 43651 function setValue_array_setNeedsUpdate( buffer, offset ) { 43652 43653 var dest = this.resolvedProperty; 43654 43655 for ( var i = 0, n = dest.length; i !== n; ++ i ) { 43656 43657 dest[ i ] = buffer[ offset ++ ]; 43658 43659 } 43660 43661 this.targetObject.needsUpdate = true; 43662 43663 }, 43664 43665 function setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) { 43666 43667 var dest = this.resolvedProperty; 43668 43669 for ( var i = 0, n = dest.length; i !== n; ++ i ) { 43670 43671 dest[ i ] = buffer[ offset ++ ]; 43672 43673 } 43674 43675 this.targetObject.matrixWorldNeedsUpdate = true; 43676 43677 } 43678 43679 ], [ 43680 43681 // ArrayElement 43682 43683 function setValue_arrayElement( buffer, offset ) { 43684 43685 this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ]; 43686 43687 }, 43688 43689 function setValue_arrayElement_setNeedsUpdate( buffer, offset ) { 43690 43691 this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ]; 43692 this.targetObject.needsUpdate = true; 43693 43694 }, 43695 43696 function setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) { 43697 43698 this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ]; 43699 this.targetObject.matrixWorldNeedsUpdate = true; 43700 43701 } 43702 43703 ], [ 43704 43705 // HasToFromArray 43706 43707 function setValue_fromArray( buffer, offset ) { 43708 43709 this.resolvedProperty.fromArray( buffer, offset ); 43710 43711 }, 43712 43713 function setValue_fromArray_setNeedsUpdate( buffer, offset ) { 43714 43715 this.resolvedProperty.fromArray( buffer, offset ); 43716 this.targetObject.needsUpdate = true; 43717 43718 }, 43719 43720 function setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) { 43721 43722 this.resolvedProperty.fromArray( buffer, offset ); 43723 this.targetObject.matrixWorldNeedsUpdate = true; 43724 43725 } 43726 43727 ] 43728 43729 ], 43730 43731 getValue: function getValue_unbound( targetArray, offset ) { 43732 43733 this.bind(); 43734 this.getValue( targetArray, offset ); 43735 43736 // Note: This class uses a State pattern on a per-method basis: 43737 // 'bind' sets 'this.getValue' / 'setValue' and shadows the 43738 // prototype version of these methods with one that represents 43739 // the bound state. When the property is not found, the methods 43740 // become no-ops. 43741 43742 }, 43743 43744 setValue: function getValue_unbound( sourceArray, offset ) { 43745 43746 this.bind(); 43747 this.setValue( sourceArray, offset ); 43748 43749 }, 43750 43751 // create getter / setter pair for a property in the scene graph 43752 bind: function () { 43753 43754 var targetObject = this.node, 43755 parsedPath = this.parsedPath, 43756 43757 objectName = parsedPath.objectName, 43758 propertyName = parsedPath.propertyName, 43759 propertyIndex = parsedPath.propertyIndex; 43760 43761 if ( ! targetObject ) { 43762 43763 targetObject = PropertyBinding.findNode( this.rootNode, parsedPath.nodeName ) || this.rootNode; 43764 43765 this.node = targetObject; 43766 43767 } 43768 43769 // set fail state so we can just 'return' on error 43770 this.getValue = this._getValue_unavailable; 43771 this.setValue = this._setValue_unavailable; 43772 43773 // ensure there is a value node 43774 if ( ! targetObject ) { 43775 43776 console.error( 'THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.' ); 43777 return; 43778 43779 } 43780 43781 if ( objectName ) { 43782 43783 var objectIndex = parsedPath.objectIndex; 43784 43785 // special cases were we need to reach deeper into the hierarchy to get the face materials.... 43786 switch ( objectName ) { 43787 43788 case 'materials': 43789 43790 if ( ! targetObject.material ) { 43791 43792 console.error( 'THREE.PropertyBinding: Can not bind to material as node does not have a material.', this ); 43793 return; 43794 43795 } 43796 43797 if ( ! targetObject.material.materials ) { 43798 43799 console.error( 'THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.', this ); 43800 return; 43801 43802 } 43803 43804 targetObject = targetObject.material.materials; 43805 43806 break; 43807 43808 case 'bones': 43809 43810 if ( ! targetObject.skeleton ) { 43811 43812 console.error( 'THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.', this ); 43813 return; 43814 43815 } 43816 43817 // potential future optimization: skip this if propertyIndex is already an integer 43818 // and convert the integer string to a true integer. 43819 43820 targetObject = targetObject.skeleton.bones; 43821 43822 // support resolving morphTarget names into indices. 43823 for ( var i = 0; i < targetObject.length; i ++ ) { 43824 43825 if ( targetObject[ i ].name === objectIndex ) { 43826 43827 objectIndex = i; 43828 break; 43829 43830 } 43831 43832 } 43833 43834 break; 43835 43836 default: 43837 43838 if ( targetObject[ objectName ] === undefined ) { 43839 43840 console.error( 'THREE.PropertyBinding: Can not bind to objectName of node undefined.', this ); 43841 return; 43842 43843 } 43844 43845 targetObject = targetObject[ objectName ]; 43846 43847 } 43848 43849 43850 if ( objectIndex !== undefined ) { 43851 43852 if ( targetObject[ objectIndex ] === undefined ) { 43853 43854 console.error( 'THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject ); 43855 return; 43856 43857 } 43858 43859 targetObject = targetObject[ objectIndex ]; 43860 43861 } 43862 43863 } 43864 43865 // resolve property 43866 var nodeProperty = targetObject[ propertyName ]; 43867 43868 if ( nodeProperty === undefined ) { 43869 43870 var nodeName = parsedPath.nodeName; 43871 43872 console.error( 'THREE.PropertyBinding: Trying to update property for track: ' + nodeName + 43873 '.' + propertyName + ' but it wasn\'t found.', targetObject ); 43874 return; 43875 43876 } 43877 43878 // determine versioning scheme 43879 var versioning = this.Versioning.None; 43880 43881 this.targetObject = targetObject; 43882 43883 if ( targetObject.needsUpdate !== undefined ) { // material 43884 43885 versioning = this.Versioning.NeedsUpdate; 43886 43887 } else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform 43888 43889 versioning = this.Versioning.MatrixWorldNeedsUpdate; 43890 43891 } 43892 43893 // determine how the property gets bound 43894 var bindingType = this.BindingType.Direct; 43895 43896 if ( propertyIndex !== undefined ) { 43897 43898 // access a sub element of the property array (only primitives are supported right now) 43899 43900 if ( propertyName === "morphTargetInfluences" ) { 43901 43902 // potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer. 43903 43904 // support resolving morphTarget names into indices. 43905 if ( ! targetObject.geometry ) { 43906 43907 console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.', this ); 43908 return; 43909 43910 } 43911 43912 if ( targetObject.geometry.isBufferGeometry ) { 43913 43914 if ( ! targetObject.geometry.morphAttributes ) { 43915 43916 console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this ); 43917 return; 43918 43919 } 43920 43921 for ( var i = 0; i < this.node.geometry.morphAttributes.position.length; i ++ ) { 43922 43923 if ( targetObject.geometry.morphAttributes.position[ i ].name === propertyIndex ) { 43924 43925 propertyIndex = i; 43926 break; 43927 43928 } 43929 43930 } 43931 43932 43933 } else { 43934 43935 if ( ! targetObject.geometry.morphTargets ) { 43936 43937 console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphTargets.', this ); 43938 return; 43939 43940 } 43941 43942 for ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) { 43943 43944 if ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) { 43945 43946 propertyIndex = i; 43947 break; 43948 43949 } 43950 43951 } 43952 43953 } 43954 43955 } 43956 43957 bindingType = this.BindingType.ArrayElement; 43958 43959 this.resolvedProperty = nodeProperty; 43960 this.propertyIndex = propertyIndex; 43961 43962 } else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) { 43963 43964 // must use copy for Object3D.Euler/Quaternion 43965 43966 bindingType = this.BindingType.HasFromToArray; 43967 43968 this.resolvedProperty = nodeProperty; 43969 43970 } else if ( Array.isArray( nodeProperty ) ) { 43971 43972 bindingType = this.BindingType.EntireArray; 43973 43974 this.resolvedProperty = nodeProperty; 43975 43976 } else { 43977 43978 this.propertyName = propertyName; 43979 43980 } 43981 43982 // select getter / setter 43983 this.getValue = this.GetterByBindingType[ bindingType ]; 43984 this.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ]; 43985 43986 }, 43987 43988 unbind: function () { 43989 43990 this.node = null; 43991 43992 // back to the prototype version of getValue / setValue 43993 // note: avoiding to mutate the shape of 'this' via 'delete' 43994 this.getValue = this._getValue_unbound; 43995 this.setValue = this._setValue_unbound; 43996 43997 } 43998 43999} ); 44000 44001// DECLARE ALIAS AFTER assign prototype 44002Object.assign( PropertyBinding.prototype, { 44003 44004 // initial state of these methods that calls 'bind' 44005 _getValue_unbound: PropertyBinding.prototype.getValue, 44006 _setValue_unbound: PropertyBinding.prototype.setValue, 44007 44008} ); 44009 44010/** 44011 * 44012 * A group of objects that receives a shared animation state. 44013 * 44014 * Usage: 44015 * 44016 * - Add objects you would otherwise pass as 'root' to the 44017 * constructor or the .clipAction method of AnimationMixer. 44018 * 44019 * - Instead pass this object as 'root'. 44020 * 44021 * - You can also add and remove objects later when the mixer 44022 * is running. 44023 *
44024 * Note: 44025 * 44026 * Objects of this class appear as one object to the mixer, 44027 * so cache control of the individual objects must be done 44028 * on the group. 44029 * 44030 * Limitation: 44031 * 44032 * - The animated properties must be compatible among the 44033 * all objects in the group. 44034 * 44035 * - A single property can either be controlled through a 44036 * target group or directly, but not both. 44037 * 44038 * @author tschw 44039 */ 44040 44041function AnimationObjectGroup() { 44042 44043 this.uuid = MathUtils.generateUUID(); 44044 44045 // cached objects followed by the active ones 44046 this._objects = Array.prototype.slice.call( arguments ); 44047 44048 this.nCachedObjects_ = 0; // threshold 44049 // note: read by PropertyBinding.Composite 44050 44051 var indices = {}; 44052 this._indicesByUUID = indices; // for bookkeeping 44053 44054 for ( var i = 0, n = arguments.length; i !== n; ++ i ) { 44055 44056 indices[ arguments[ i ].uuid ] = i; 44057 44058 } 44059 44060 this._paths = []; // inside: string 44061 this._parsedPaths = []; // inside: { we don't care, here } 44062 this._bindings = []; // inside: Array< PropertyBinding > 44063 this._bindingsIndicesByPath = {}; // inside: indices in these arrays 44064 44065 var scope = this; 44066 44067 this.stats = { 44068 44069 objects: { 44070 get total() { 44071 44072 return scope._objects.length; 44073 44074 }, 44075 get inUse() { 44076 44077 return this.total - scope.nCachedObjects_; 44078 44079 } 44080 }, 44081 get bindingsPerObject() { 44082 44083 return scope._bindings.length; 44084 44085 } 44086 44087 }; 44088 44089} 44090 44091Object.assign( AnimationObjectGroup.prototype, { 44092 44093 isAnimationObjectGroup: true, 44094 44095 add: function () { 44096 44097 var objects = this._objects, 44098 nObjects = objects.length, 44099 nCachedObjects = this.nCachedObjects_, 44100 indicesByUUID = this._indicesByUUID, 44101 paths = this._paths, 44102 parsedPaths = this._parsedPaths, 44103 bindings = this._bindings, 44104 nBindings = bindings.length, 44105 knownObject = undefined; 44106 44107 for ( var i = 0, n = arguments.length; i !== n; ++ i ) { 44108 44109 var object = arguments[ i ], 44110 uuid = object.uuid, 44111 index = indicesByUUID[ uuid ]; 44112 44113 if ( index === undefined ) { 44114 44115 // unknown object -> add it to the ACTIVE region 44116 44117 index = nObjects ++; 44118 indicesByUUID[ uuid ] = index; 44119 objects.push( object ); 44120 44121 // accounting is done, now do the same for all bindings 44122 44123 for ( var j = 0, m = nBindings; j !== m; ++ j ) { 44124 44125 bindings[ j ].push( new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ) ); 44126 44127 } 44128 44129 } else if ( index < nCachedObjects ) { 44130 44131 knownObject = objects[ index ]; 44132 44133 // move existing object to the ACTIVE region 44134 44135 var firstActiveIndex = -- nCachedObjects, 44136 lastCachedObject = objects[ firstActiveIndex ]; 44137 44138 indicesByUUID[ lastCachedObject.uuid ] = index; 44139 objects[ index ] = lastCachedObject; 44140 44141 indicesByUUID[ uuid ] = firstActiveIndex; 44142 objects[ firstActiveIndex ] = object; 44143 44144 // accounting is done, now do the same for all bindings 44145 44146 for ( var j = 0, m = nBindings; j !== m; ++ j ) { 44147 44148 var bindingsForPath = bindings[ j ], 44149 lastCached = bindingsForPath[ firstActiveIndex ], 44150 binding = bindingsForPath[ index ]; 44151 44152 bindingsForPath[ index ] = lastCached; 44153 44154 if ( binding === undefined ) { 44155 44156 // since we do not bother to create new bindings 44157 // for objects that are cached, the binding may 44158 // or may not exist 44159 44160 binding = new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ); 44161 44162 } 44163 44164 bindingsForPath[ firstActiveIndex ] = binding; 44165 44166 } 44167 44168 } else if ( objects[ index ] !== knownObject ) { 44169 44170 console.error( 'THREE.AnimationObjectGroup: Different objects with the same UUID ' + 44171 'detected. Clean the caches or recreate your infrastructure when reloading scenes.' ); 44172 44173 } // else the object is already where we want it to be 44174 44175 } // for arguments 44176 44177 this.nCachedObjects_ = nCachedObjects; 44178 44179 }, 44180 44181 remove: function () { 44182 44183 var objects = this._objects, 44184 nCachedObjects = this.nCachedObjects_, 44185 indicesByUUID = this._indicesByUUID, 44186 bindings = this._bindings, 44187 nBindings = bindings.length; 44188 44189 for ( var i = 0, n = arguments.length; i !== n; ++ i ) { 44190 44191 var object = arguments[ i ], 44192 uuid = object.uuid, 44193 index = indicesByUUID[ uuid ]; 44194 44195 if ( index !== undefined && index >= nCachedObjects ) { 44196 44197 // move existing object into the CACHED region 44198 44199 var lastCachedIndex = nCachedObjects ++, 44200 firstActiveObject = objects[ lastCachedIndex ]; 44201 44202 indicesByUUID[ firstActiveObject.uuid ] = index; 44203 objects[ index ] = firstActiveObject; 44204 44205 indicesByUUID[ uuid ] = lastCachedIndex; 44206 objects[ lastCachedIndex ] = object; 44207 44208 // accounting is done, now do the same for all bindings 44209 44210 for ( var j = 0, m = nBindings; j !== m; ++ j ) { 44211
vendor: 6,456 bytes, lines 44212-44485
44212 var bindingsForPath = bindings[ j ], 44213 firstActive = bindingsForPath[ lastCachedIndex ], 44214 binding = bindingsForPath[ index ]; 44215 44216 bindingsForPath[ index ] = firstActive; 44217 bindingsForPath[ lastCachedIndex ] = binding; 44218 44219 } 44220 44221 } 44222 44223 } // for arguments 44224 44225 this.nCachedObjects_ = nCachedObjects; 44226 44227 }, 44228 44229 // remove & forget 44230 uncache: function () { 44231 44232 var objects = this._objects, 44233 nObjects = objects.length, 44234 nCachedObjects = this.nCachedObjects_, 44235 indicesByUUID = this._indicesByUUID, 44236 bindings = this._bindings, 44237 nBindings = bindings.length; 44238 44239 for ( var i = 0, n = arguments.length; i !== n; ++ i ) { 44240 44241 var object = arguments[ i ], 44242 uuid = object.uuid, 44243 index = indicesByUUID[ uuid ]; 44244 44245 if ( index !== undefined ) { 44246 44247 delete indicesByUUID[ uuid ]; 44248 44249 if ( index < nCachedObjects ) { 44250 44251 // object is cached, shrink the CACHED region 44252 44253 var firstActiveIndex = -- nCachedObjects, 44254 lastCachedObject = objects[ firstActiveIndex ], 44255 lastIndex = -- nObjects, 44256 lastObject = objects[ lastIndex ]; 44257 44258 // last cached object takes this object's place 44259 indicesByUUID[ lastCachedObject.uuid ] = index; 44260 objects[ index ] = lastCachedObject; 44261 44262 // last object goes to the activated slot and pop 44263 indicesByUUID[ lastObject.uuid ] = firstActiveIndex; 44264 objects[ firstActiveIndex ] = lastObject; 44265 objects.pop(); 44266 44267 // accounting is done, now do the same for all bindings 44268 44269 for ( var j = 0, m = nBindings; j !== m; ++ j ) { 44270 44271 var bindingsForPath = bindings[ j ], 44272 lastCached = bindingsForPath[ firstActiveIndex ], 44273 last = bindingsForPath[ lastIndex ]; 44274 44275 bindingsForPath[ index ] = lastCached; 44276 bindingsForPath[ firstActiveIndex ] = last; 44277 bindingsForPath.pop(); 44278 44279 } 44280 44281 } else { 44282 44283 // object is active, just swap with the last and pop 44284 44285 var lastIndex = -- nObjects, 44286 lastObject = objects[ lastIndex ]; 44287 44288 indicesByUUID[ lastObject.uuid ] = index; 44289 objects[ index ] = lastObject; 44290 objects.pop(); 44291 44292 // accounting is done, now do the same for all bindings 44293 44294 for ( var j = 0, m = nBindings; j !== m; ++ j ) { 44295 44296 var bindingsForPath = bindings[ j ]; 44297 44298 bindingsForPath[ index ] = bindingsForPath[ lastIndex ]; 44299 bindingsForPath.pop(); 44300 44301 } 44302 44303 } // cached or active 44304 44305 } // if object is known 44306 44307 } // for arguments 44308 44309 this.nCachedObjects_ = nCachedObjects; 44310 44311 }, 44312 44313 // Internal interface used by befriended PropertyBinding.Composite: 44314 44315 subscribe_: function ( path, parsedPath ) { 44316 44317 // returns an array of bindings for the given path that is changed 44318 // according to the contained objects in the group 44319 44320 var indicesByPath = this._bindingsIndicesByPath, 44321 index = indicesByPath[ path ], 44322 bindings = this._bindings; 44323 44324 if ( index !== undefined ) return bindings[ index ]; 44325 44326 var paths = this._paths, 44327 parsedPaths = this._parsedPaths, 44328 objects = this._objects, 44329 nObjects = objects.length, 44330 nCachedObjects = this.nCachedObjects_, 44331 bindingsForPath = new Array( nObjects ); 44332 44333 index = bindings.length; 44334 44335 indicesByPath[ path ] = index; 44336 44337 paths.push( path ); 44338 parsedPaths.push( parsedPath ); 44339 bindings.push( bindingsForPath ); 44340 44341 for ( var i = nCachedObjects, n = objects.length; i !== n; ++ i ) { 44342 44343 var object = objects[ i ]; 44344 bindingsForPath[ i ] = new PropertyBinding( object, path, parsedPath ); 44345 44346 } 44347 44348 return bindingsForPath; 44349 44350 }, 44351 44352 unsubscribe_: function ( path ) { 44353 44354 // tells the group to forget about a property path and no longer 44355 // update the array previously obtained with 'subscribe_' 44356 44357 var indicesByPath = this._bindingsIndicesByPath, 44358 index = indicesByPath[ path ]; 44359 44360 if ( index !== undefined ) { 44361 44362 var paths = this._paths, 44363 parsedPaths = this._parsedPaths, 44364 bindings = this._bindings, 44365 lastBindingsIndex = bindings.length - 1, 44366 lastBindings = bindings[ lastBindingsIndex ], 44367 lastBindingsPath = path[ lastBindingsIndex ]; 44368 44369 indicesByPath[ lastBindingsPath ] = index; 44370 44371 bindings[ index ] = lastBindings; 44372 bindings.pop(); 44373 44374 parsedPaths[ index ] = parsedPaths[ lastBindingsIndex ]; 44375 parsedPaths.pop(); 44376 44377 paths[ index ] = paths[ lastBindingsIndex ]; 44378 paths.pop(); 44379 44380 } 44381 44382 } 44383 44384} ); 44385 44386/** 44387 * 44388 * Action provided by AnimationMixer for scheduling clip playback on specific 44389 * objects. 44390 * 44391 * @author Ben Houston / http://clara.io/ 44392 * @author David Sarno / http://lighthaus.us/ 44393 * @author tschw 44394 * 44395 */ 44396 44397function AnimationAction( mixer, clip, localRoot, blendMode ) { 44398 44399 this._mixer = mixer; 44400 this._clip = clip; 44401 this._localRoot = localRoot || null; 44402 this.blendMode = blendMode || clip.blendMode; 44403 44404 var tracks = clip.tracks, 44405 nTracks = tracks.length, 44406 interpolants = new Array( nTracks ); 44407 44408 var interpolantSettings = { 44409 endingStart: ZeroCurvatureEnding, 44410 endingEnd: ZeroCurvatureEnding 44411 }; 44412 44413 for ( var i = 0; i !== nTracks; ++ i ) { 44414 44415 var interpolant = tracks[ i ].createInterpolant( null ); 44416 interpolants[ i ] = interpolant; 44417 interpolant.settings = interpolantSettings; 44418 44419 } 44420 44421 this._interpolantSettings = interpolantSettings; 44422 44423 this._interpolants = interpolants; // bound by the mixer 44424 44425 // inside: PropertyMixer (managed by the mixer) 44426 this._propertyBindings = new Array( nTracks ); 44427 44428 this._cacheIndex = null; // for the memory manager 44429 this._byClipCacheIndex = null; // for the memory manager 44430 44431 this._timeScaleInterpolant = null; 44432 this._weightInterpolant = null; 44433 44434 this.loop = LoopRepeat; 44435 this._loopCount = - 1; 44436 44437 // global mixer time when the action is to be started 44438 // it's set back to 'null' upon start of the action 44439 this._startTime = null; 44440 44441 // scaled local time of the action 44442 // gets clamped or wrapped to 0..clip.duration according to loop 44443 this.time = 0; 44444 44445 this.timeScale = 1; 44446 this._effectiveTimeScale = 1; 44447 44448 this.weight = 1; 44449 this._effectiveWeight = 1; 44450 44451 this.repetitions = Infinity; // no. of repetitions when looping 44452 44453 this.paused = false; // true -> zero effective time scale 44454 this.enabled = true; // false -> zero effective weight 44455 44456 this.clampWhenFinished = false;// keep feeding the last frame? 44457 44458 this.zeroSlopeAtStart = true;// for smooth interpolation w/o separate 44459 this.zeroSlopeAtEnd = true;// clips for start, loop and end 44460 44461} 44462 44463Object.assign( AnimationAction.prototype, { 44464 44465 // State & Scheduling 44466 44467 play: function () { 44468 44469 this._mixer._activateAction( this ); 44470 44471 return this; 44472 44473 }, 44474 44475 stop: function () { 44476 44477 this._mixer._deactivateAction( this ); 44478 44479 return this.reset(); 44480 44481 }, 44482 44483 reset: function () { 44484 44485 this.paused = false;
vendor: 4,176 bytes, lines 44486-44709
44486 this.enabled = true; 44487 44488 this.time = 0; // restart clip 44489 this._loopCount = - 1;// forget previous loops 44490 this._startTime = null;// forget scheduling 44491 44492 return this.stopFading().stopWarping(); 44493 44494 }, 44495 44496 isRunning: function () { 44497 44498 return this.enabled && ! this.paused && this.timeScale !== 0 && 44499 this._startTime === null && this._mixer._isActiveAction( this ); 44500 44501 }, 44502 44503 // return true when play has been called 44504 isScheduled: function () { 44505 44506 return this._mixer._isActiveAction( this ); 44507 44508 }, 44509 44510 startAt: function ( time ) { 44511 44512 this._startTime = time; 44513 44514 return this; 44515 44516 }, 44517 44518 setLoop: function ( mode, repetitions ) { 44519 44520 this.loop = mode; 44521 this.repetitions = repetitions; 44522 44523 return this; 44524 44525 }, 44526 44527 // Weight 44528 44529 // set the weight stopping any scheduled fading 44530 // although .enabled = false yields an effective weight of zero, this 44531 // method does *not* change .enabled, because it would be confusing 44532 setEffectiveWeight: function ( weight ) { 44533 44534 this.weight = weight; 44535 44536 // note: same logic as when updated at runtime 44537 this._effectiveWeight = this.enabled ? weight : 0; 44538 44539 return this.stopFading(); 44540 44541 }, 44542 44543 // return the weight considering fading and .enabled 44544 getEffectiveWeight: function () { 44545 44546 return this._effectiveWeight; 44547 44548 }, 44549 44550 fadeIn: function ( duration ) { 44551 44552 return this._scheduleFading( duration, 0, 1 ); 44553 44554 }, 44555 44556 fadeOut: function ( duration ) { 44557 44558 return this._scheduleFading( duration, 1, 0 ); 44559 44560 }, 44561 44562 crossFadeFrom: function ( fadeOutAction, duration, warp ) { 44563 44564 fadeOutAction.fadeOut( duration ); 44565 this.fadeIn( duration ); 44566 44567 if ( warp ) { 44568 44569 var fadeInDuration = this._clip.duration, 44570 fadeOutDuration = fadeOutAction._clip.duration, 44571 44572 startEndRatio = fadeOutDuration / fadeInDuration, 44573 endStartRatio = fadeInDuration / fadeOutDuration; 44574 44575 fadeOutAction.warp( 1.0, startEndRatio, duration ); 44576 this.warp( endStartRatio, 1.0, duration ); 44577 44578 } 44579 44580 return this; 44581 44582 }, 44583 44584 crossFadeTo: function ( fadeInAction, duration, warp ) { 44585 44586 return fadeInAction.crossFadeFrom( this, duration, warp ); 44587 44588 }, 44589 44590 stopFading: function () { 44591 44592 var weightInterpolant = this._weightInterpolant; 44593 44594 if ( weightInterpolant !== null ) { 44595 44596 this._weightInterpolant = null; 44597 this._mixer._takeBackControlInterpolant( weightInterpolant ); 44598 44599 } 44600 44601 return this; 44602 44603 }, 44604 44605 // Time Scale Control 44606 44607 // set the time scale stopping any scheduled warping 44608 // although .paused = true yields an effective time scale of zero, this 44609 // method does *not* change .paused, because it would be confusing 44610 setEffectiveTimeScale: function ( timeScale ) { 44611 44612 this.timeScale = timeScale; 44613 this._effectiveTimeScale = this.paused ? 0 : timeScale; 44614 44615 return this.stopWarping(); 44616 44617 }, 44618 44619 // return the time scale considering warping and .paused 44620 getEffectiveTimeScale: function () { 44621 44622 return this._effectiveTimeScale; 44623 44624 }, 44625 44626 setDuration: function ( duration ) { 44627 44628 this.timeScale = this._clip.duration / duration; 44629 44630 return this.stopWarping(); 44631 44632 }, 44633 44634 syncWith: function ( action ) { 44635 44636 this.time = action.time; 44637 this.timeScale = action.timeScale; 44638 44639 return this.stopWarping(); 44640 44641 }, 44642 44643 halt: function ( duration ) { 44644 44645 return this.warp( this._effectiveTimeScale, 0, duration ); 44646 44647 }, 44648 44649 warp: function ( startTimeScale, endTimeScale, duration ) { 44650 44651 var mixer = this._mixer, now = mixer.time, 44652 interpolant = this._timeScaleInterpolant, 44653 44654 timeScale = this.timeScale; 44655 44656 if ( interpolant === null ) { 44657 44658 interpolant = mixer._lendControlInterpolant(); 44659 this._timeScaleInterpolant = interpolant; 44660 44661 } 44662 44663 var times = interpolant.parameterPositions, 44664 values = interpolant.sampleValues; 44665 44666 times[ 0 ] = now; 44667 times[ 1 ] = now + duration; 44668 44669 values[ 0 ] = startTimeScale / timeScale; 44670 values[ 1 ] = endTimeScale / timeScale; 44671 44672 return this; 44673 44674 }, 44675 44676 stopWarping: function () { 44677 44678 var timeScaleInterpolant = this._timeScaleInterpolant; 44679 44680 if ( timeScaleInterpolant !== null ) { 44681 44682 this._timeScaleInterpolant = null; 44683 this._mixer._takeBackControlInterpolant( timeScaleInterpolant ); 44684 44685 } 44686 44687 return this; 44688 44689 }, 44690 44691 // Object Accessors 44692 44693 getMixer: function () { 44694 44695 return this._mixer; 44696 44697 }, 44698 44699 getClip: function () { 44700 44701 return this._clip; 44702 44703 }, 44704 44705 getRoot: function () { 44706 44707 return this._localRoot || this._mixer._root; 44708 44709 },
vendor: 17,748 bytes, lines 44710-45610
44710 44711 // Interna 44712 44713 _update: function ( time, deltaTime, timeDirection, accuIndex ) { 44714 44715 // called by the mixer 44716 44717 if ( ! this.enabled ) { 44718 44719 // call ._updateWeight() to update ._effectiveWeight 44720 44721 this._updateWeight( time ); 44722 return; 44723 44724 } 44725 44726 var startTime = this._startTime; 44727 44728 if ( startTime !== null ) { 44729 44730 // check for scheduled start of action 44731 44732 var timeRunning = ( time - startTime ) * timeDirection; 44733 if ( timeRunning < 0 || timeDirection === 0 ) { 44734 44735 return; // yet to come / don't decide when delta = 0 44736 44737 } 44738 44739 // start 44740 44741 this._startTime = null; // unschedule 44742 deltaTime = timeDirection * timeRunning; 44743 44744 } 44745 44746 // apply time scale and advance time 44747 44748 deltaTime *= this._updateTimeScale( time ); 44749 var clipTime = this._updateTime( deltaTime ); 44750 44751 // note: _updateTime may disable the action resulting in 44752 // an effective weight of 0 44753 44754 var weight = this._updateWeight( time ); 44755 44756 if ( weight > 0 ) { 44757 44758 var interpolants = this._interpolants; 44759 var propertyMixers = this._propertyBindings; 44760 44761 switch ( this.blendMode ) { 44762 44763 case AdditiveAnimationBlendMode: 44764 44765 for ( var j = 0, m = interpolants.length; j !== m; ++ j ) { 44766 44767 interpolants[ j ].evaluate( clipTime ); 44768 propertyMixers[ j ].accumulateAdditive( weight ); 44769 44770 } 44771 44772 break; 44773 44774 case NormalAnimationBlendMode: 44775 default: 44776 44777 for ( var j = 0, m = interpolants.length; j !== m; ++ j ) { 44778 44779 interpolants[ j ].evaluate( clipTime ); 44780 propertyMixers[ j ].accumulate( accuIndex, weight ); 44781 44782 } 44783 44784 } 44785 44786 } 44787 44788 }, 44789 44790 _updateWeight: function ( time ) { 44791 44792 var weight = 0; 44793 44794 if ( this.enabled ) { 44795 44796 weight = this.weight; 44797 var interpolant = this._weightInterpolant; 44798 44799 if ( interpolant !== null ) { 44800 44801 var interpolantValue = interpolant.evaluate( time )[ 0 ]; 44802 44803 weight *= interpolantValue; 44804 44805 if ( time > interpolant.parameterPositions[ 1 ] ) { 44806 44807 this.stopFading(); 44808 44809 if ( interpolantValue === 0 ) { 44810 44811 // faded out, disable 44812 this.enabled = false; 44813 44814 } 44815 44816 } 44817 44818 } 44819 44820 } 44821 44822 this._effectiveWeight = weight; 44823 return weight; 44824 44825 }, 44826 44827 _updateTimeScale: function ( time ) { 44828 44829 var timeScale = 0; 44830 44831 if ( ! this.paused ) { 44832 44833 timeScale = this.timeScale; 44834 44835 var interpolant = this._timeScaleInterpolant; 44836 44837 if ( interpolant !== null ) { 44838 44839 var interpolantValue = interpolant.evaluate( time )[ 0 ]; 44840 44841 timeScale *= interpolantValue; 44842 44843 if ( time > interpolant.parameterPositions[ 1 ] ) { 44844 44845 this.stopWarping(); 44846 44847 if ( timeScale === 0 ) { 44848 44849 // motion has halted, pause 44850 this.paused = true; 44851 44852 } else { 44853 44854 // warp done - apply final time scale 44855 this.timeScale = timeScale; 44856 44857 } 44858 44859 } 44860 44861 } 44862 44863 } 44864 44865 this._effectiveTimeScale = timeScale; 44866 return timeScale; 44867 44868 }, 44869 44870 _updateTime: function ( deltaTime ) { 44871 44872 var time = this.time + deltaTime; 44873 var duration = this._clip.duration; 44874 var loop = this.loop; 44875 var loopCount = this._loopCount; 44876 44877 var pingPong = ( loop === LoopPingPong ); 44878 44879 if ( deltaTime === 0 ) { 44880 44881 if ( loopCount === - 1 ) return time; 44882 44883 return ( pingPong && ( loopCount & 1 ) === 1 ) ? duration - time : time; 44884 44885 } 44886 44887 if ( loop === LoopOnce ) { 44888 44889 if ( loopCount === - 1 ) { 44890 44891 // just started 44892 44893 this._loopCount = 0; 44894 this._setEndings( true, true, false ); 44895 44896 } 44897 44898 handle_stop: { 44899 44900 if ( time >= duration ) { 44901 44902 time = duration; 44903 44904 } else if ( time < 0 ) { 44905 44906 time = 0; 44907 44908 } else { 44909 44910 this.time = time; 44911 44912 break handle_stop; 44913 44914 } 44915 44916 if ( this.clampWhenFinished ) this.paused = true; 44917 else this.enabled = false; 44918 44919 this.time = time; 44920 44921 this._mixer.dispatchEvent( { 44922 type: 'finished', action: this, 44923 direction: deltaTime < 0 ? - 1 : 1 44924 } ); 44925 44926 } 44927 44928 } else { // repetitive Repeat or PingPong 44929 44930 if ( loopCount === - 1 ) { 44931 44932 // just started 44933 44934 if ( deltaTime >= 0 ) { 44935 44936 loopCount = 0; 44937 44938 this._setEndings( true, this.repetitions === 0, pingPong ); 44939 44940 } else { 44941 44942 // when looping in reverse direction, the initial 44943 // transition through zero counts as a repetition, 44944 // so leave loopCount at -1 44945 44946 this._setEndings( this.repetitions === 0, true, pingPong ); 44947 44948 } 44949 44950 } 44951 44952 if ( time >= duration || time < 0 ) { 44953 44954 // wrap around 44955 44956 var loopDelta = Math.floor( time / duration ); // signed 44957 time -= duration * loopDelta; 44958 44959 loopCount += Math.abs( loopDelta ); 44960 44961 var pending = this.repetitions - loopCount; 44962 44963 if ( pending <= 0 ) { 44964 44965 // have to stop (switch state, clamp time, fire event) 44966 44967 if ( this.clampWhenFinished ) this.paused = true; 44968 else this.enabled = false; 44969 44970 time = deltaTime > 0 ? duration : 0; 44971 44972 this.time = time; 44973 44974 this._mixer.dispatchEvent( { 44975 type: 'finished', action: this, 44976 direction: deltaTime > 0 ? 1 : - 1 44977 } ); 44978 44979 } else { 44980 44981 // keep running 44982 44983 if ( pending === 1 ) { 44984 44985 // entering the last round 44986 44987 var atStart = deltaTime < 0; 44988 this._setEndings( atStart, ! atStart, pingPong ); 44989 44990 } else { 44991 44992 this._setEndings( false, false, pingPong ); 44993 44994 } 44995 44996 this._loopCount = loopCount; 44997 44998 this.time = time; 44999 45000 this._mixer.dispatchEvent( { 45001 type: 'loop', action: this, loopDelta: loopDelta 45002 } ); 45003 45004 } 45005 45006 } else { 45007 45008 this.time = time; 45009 45010 } 45011 45012 if ( pingPong && ( loopCount & 1 ) === 1 ) { 45013 45014 // invert time for the "pong round" 45015 45016 return duration - time; 45017 45018 } 45019 45020 } 45021 45022 return time; 45023 45024 }, 45025 45026 _setEndings: function ( atStart, atEnd, pingPong ) { 45027 45028 var settings = this._interpolantSettings; 45029 45030 if ( pingPong ) { 45031 45032 settings.endingStart = ZeroSlopeEnding; 45033 settings.endingEnd = ZeroSlopeEnding; 45034 45035 } else { 45036 45037 // assuming for LoopOnce atStart == atEnd == true 45038 45039 if ( atStart ) { 45040 45041 settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding; 45042 45043 } else { 45044 45045 settings.endingStart = WrapAroundEnding; 45046 45047 } 45048 45049 if ( atEnd ) { 45050 45051 settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding; 45052 45053 } else { 45054 45055 settings.endingEnd = WrapAroundEnding; 45056 45057 } 45058 45059 } 45060 45061 }, 45062 45063 _scheduleFading: function ( duration, weightNow, weightThen ) { 45064 45065 var mixer = this._mixer, now = mixer.time, 45066 interpolant = this._weightInterpolant; 45067 45068 if ( interpolant === null ) { 45069 45070 interpolant = mixer._lendControlInterpolant(); 45071 this._weightInterpolant = interpolant; 45072 45073 } 45074 45075 var times = interpolant.parameterPositions, 45076 values = interpolant.sampleValues; 45077 45078 times[ 0 ] = now; 45079 values[ 0 ] = weightNow; 45080 times[ 1 ] = now + duration; 45081 values[ 1 ] = weightThen; 45082 45083 return this; 45084 45085 } 45086 45087} ); 45088 45089/** 45090 * 45091 * Player for AnimationClips. 45092 * 45093 * 45094 * @author Ben Houston / http://clara.io/ 45095 * @author David Sarno / http://lighthaus.us/ 45096 * @author tschw 45097 */ 45098 45099function AnimationMixer( root ) { 45100 45101 this._root = root; 45102 this._initMemoryManager(); 45103 this._accuIndex = 0; 45104 45105 this.time = 0; 45106 45107 this.timeScale = 1.0; 45108 45109} 45110 45111AnimationMixer.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { 45112 45113 constructor: AnimationMixer, 45114 45115 _bindAction: function ( action, prototypeAction ) { 45116 45117 var root = action._localRoot || this._root, 45118 tracks = action._clip.tracks, 45119 nTracks = tracks.length, 45120 bindings = action._propertyBindings, 45121 interpolants = action._interpolants, 45122 rootUuid = root.uuid, 45123 bindingsByRoot = this._bindingsByRootAndName, 45124 bindingsByName = bindingsByRoot[ rootUuid ]; 45125 45126 if ( bindingsByName === undefined ) { 45127 45128 bindingsByName = {}; 45129 bindingsByRoot[ rootUuid ] = bindingsByName; 45130 45131 } 45132 45133 for ( var i = 0; i !== nTracks; ++ i ) { 45134 45135 var track = tracks[ i ], 45136 trackName = track.name, 45137 binding = bindingsByName[ trackName ]; 45138 45139 if ( binding !== undefined ) { 45140 45141 bindings[ i ] = binding; 45142 45143 } else { 45144 45145 binding = bindings[ i ]; 45146 45147 if ( binding !== undefined ) { 45148 45149 // existing binding, make sure the cache knows 45150 45151 if ( binding._cacheIndex === null ) { 45152 45153 ++ binding.referenceCount; 45154 this._addInactiveBinding( binding, rootUuid, trackName ); 45155 45156 } 45157 45158 continue; 45159 45160 } 45161 45162 var path = prototypeAction && prototypeAction. 45163 _propertyBindings[ i ].binding.parsedPath; 45164 45165 binding = new PropertyMixer( 45166 PropertyBinding.create( root, trackName, path ), 45167 track.ValueTypeName, track.getValueSize() ); 45168 45169 ++ binding.referenceCount; 45170 this._addInactiveBinding( binding, rootUuid, trackName ); 45171 45172 bindings[ i ] = binding; 45173 45174 } 45175 45176 interpolants[ i ].resultBuffer = binding.buffer; 45177 45178 } 45179 45180 }, 45181 45182 _activateAction: function ( action ) { 45183 45184 if ( ! this._isActiveAction( action ) ) { 45185 45186 if ( action._cacheIndex === null ) { 45187 45188 // this action has been forgotten by the cache, but the user 45189 // appears to be still using it -> rebind 45190 45191 var rootUuid = ( action._localRoot || this._root ).uuid, 45192 clipUuid = action._clip.uuid, 45193 actionsForClip = this._actionsByClip[ clipUuid ]; 45194 45195 this._bindAction( action, 45196 actionsForClip && actionsForClip.knownActions[ 0 ] ); 45197 45198 this._addInactiveAction( action, clipUuid, rootUuid ); 45199 45200 } 45201 45202 var bindings = action._propertyBindings; 45203 45204 // increment reference counts / sort out state 45205 for ( var i = 0, n = bindings.length; i !== n; ++ i ) { 45206 45207 var binding = bindings[ i ]; 45208 45209 if ( binding.useCount ++ === 0 ) { 45210 45211 this._lendBinding( binding ); 45212 binding.saveOriginalState(); 45213 45214 } 45215 45216 } 45217 45218 this._lendAction( action ); 45219 45220 } 45221 45222 }, 45223 45224 _deactivateAction: function ( action ) { 45225 45226 if ( this._isActiveAction( action ) ) { 45227 45228 var bindings = action._propertyBindings; 45229 45230 // decrement reference counts / sort out state 45231 for ( var i = 0, n = bindings.length; i !== n; ++ i ) { 45232 45233 var binding = bindings[ i ]; 45234 45235 if ( -- binding.useCount === 0 ) { 45236 45237 binding.restoreOriginalState(); 45238 this._takeBackBinding( binding ); 45239 45240 } 45241 45242 } 45243 45244 this._takeBackAction( action ); 45245 45246 } 45247 45248 }, 45249 45250 // Memory manager 45251 45252 _initMemoryManager: function () { 45253 45254 this._actions = []; // 'nActiveActions' followed by inactive ones 45255 this._nActiveActions = 0; 45256 45257 this._actionsByClip = {}; 45258 // inside: 45259 // { 45260 // knownActions: Array< AnimationAction > - used as prototypes 45261 // actionByRoot: AnimationAction - lookup 45262 // } 45263 45264 45265 this._bindings = []; // 'nActiveBindings' followed by inactive ones 45266 this._nActiveBindings = 0; 45267 45268 this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer > 45269 45270 45271 this._controlInterpolants = []; // same game as above 45272 this._nActiveControlInterpolants = 0; 45273 45274 var scope = this; 45275 45276 this.stats = { 45277 45278 actions: { 45279 get total() { 45280 45281 return scope._actions.length; 45282 45283 }, 45284 get inUse() { 45285 45286 return scope._nActiveActions; 45287 45288 } 45289 }, 45290 bindings: { 45291 get total() { 45292 45293 return scope._bindings.length; 45294 45295 }, 45296 get inUse() { 45297 45298 return scope._nActiveBindings; 45299 45300 } 45301 }, 45302 controlInterpolants: { 45303 get total() { 45304 45305 return scope._controlInterpolants.length; 45306 45307 }, 45308 get inUse() { 45309 45310 return scope._nActiveControlInterpolants; 45311 45312 } 45313 } 45314 45315 }; 45316 45317 }, 45318 45319 // Memory management for AnimationAction objects 45320 45321 _isActiveAction: function ( action ) { 45322 45323 var index = action._cacheIndex; 45324 return index !== null && index < this._nActiveActions; 45325 45326 }, 45327 45328 _addInactiveAction: function ( action, clipUuid, rootUuid ) { 45329 45330 var actions = this._actions, 45331 actionsByClip = this._actionsByClip, 45332 actionsForClip = actionsByClip[ clipUuid ]; 45333 45334 if ( actionsForClip === undefined ) { 45335 45336 actionsForClip = { 45337 45338 knownActions: [ action ], 45339 actionByRoot: {} 45340 45341 }; 45342 45343 action._byClipCacheIndex = 0; 45344 45345 actionsByClip[ clipUuid ] = actionsForClip; 45346 45347 } else { 45348 45349 var knownActions = actionsForClip.knownActions; 45350 45351 action._byClipCacheIndex = knownActions.length; 45352 knownActions.push( action ); 45353 45354 } 45355 45356 action._cacheIndex = actions.length; 45357 actions.push( action ); 45358 45359 actionsForClip.actionByRoot[ rootUuid ] = action; 45360 45361 }, 45362 45363 _removeInactiveAction: function ( action ) { 45364 45365 var actions = this._actions, 45366 lastInactiveAction = actions[ actions.length - 1 ], 45367 cacheIndex = action._cacheIndex; 45368 45369 lastInactiveAction._cacheIndex = cacheIndex; 45370 actions[ cacheIndex ] = lastInactiveAction; 45371 actions.pop(); 45372 45373 action._cacheIndex = null; 45374 45375 45376 var clipUuid = action._clip.uuid, 45377 actionsByClip = this._actionsByClip, 45378 actionsForClip = actionsByClip[ clipUuid ], 45379 knownActionsForClip = actionsForClip.knownActions, 45380 45381 lastKnownAction = 45382 knownActionsForClip[ knownActionsForClip.length - 1 ], 45383 45384 byClipCacheIndex = action._byClipCacheIndex; 45385 45386 lastKnownAction._byClipCacheIndex = byClipCacheIndex; 45387 knownActionsForClip[ byClipCacheIndex ] = lastKnownAction; 45388 knownActionsForClip.pop(); 45389 45390 action._byClipCacheIndex = null; 45391 45392 45393 var actionByRoot = actionsForClip.actionByRoot, 45394 rootUuid = ( action._localRoot || this._root ).uuid; 45395 45396 delete actionByRoot[ rootUuid ]; 45397 45398 if ( knownActionsForClip.length === 0 ) { 45399 45400 delete actionsByClip[ clipUuid ]; 45401 45402 } 45403 45404 this._removeInactiveBindingsForAction( action ); 45405 45406 }, 45407 45408 _removeInactiveBindingsForAction: function ( action ) { 45409 45410 var bindings = action._propertyBindings; 45411 for ( var i = 0, n = bindings.length; i !== n; ++ i ) { 45412 45413 var binding = bindings[ i ]; 45414 45415 if ( -- binding.referenceCount === 0 ) { 45416 45417 this._removeInactiveBinding( binding ); 45418 45419 } 45420 45421 } 45422 45423 }, 45424 45425 _lendAction: function ( action ) { 45426 45427 // [ active actions | inactive actions ] 45428 // [ active actions >| inactive actions ] 45429 // s a 45430 // <-swap-> 45431 // a s 45432 45433 var actions = this._actions, 45434 prevIndex = action._cacheIndex, 45435 45436 lastActiveIndex = this._nActiveActions ++, 45437 45438 firstInactiveAction = actions[ lastActiveIndex ]; 45439 45440 action._cacheIndex = lastActiveIndex; 45441 actions[ lastActiveIndex ] = action; 45442 45443 firstInactiveAction._cacheIndex = prevIndex; 45444 actions[ prevIndex ] = firstInactiveAction; 45445 45446 }, 45447 45448 _takeBackAction: function ( action ) { 45449 45450 // [ active actions | inactive actions ] 45451 // [ active actions |< inactive actions ] 45452 // a s 45453 // <-swap-> 45454 // s a 45455 45456 var actions = this._actions, 45457 prevIndex = action._cacheIndex, 45458 45459 firstInactiveIndex = -- this._nActiveActions, 45460 45461 lastActiveAction = actions[ firstInactiveIndex ]; 45462 45463 action._cacheIndex = firstInactiveIndex; 45464 actions[ firstInactiveIndex ] = action; 45465 45466 lastActiveAction._cacheIndex = prevIndex; 45467 actions[ prevIndex ] = lastActiveAction; 45468 45469 }, 45470 45471 // Memory management for PropertyMixer objects 45472 45473 _addInactiveBinding: function ( binding, rootUuid, trackName ) { 45474 45475 var bindingsByRoot = this._bindingsByRootAndName, 45476 bindingByName = bindingsByRoot[ rootUuid ], 45477 45478 bindings = this._bindings; 45479 45480 if ( bindingByName === undefined ) { 45481 45482 bindingByName = {}; 45483 bindingsByRoot[ rootUuid ] = bindingByName; 45484 45485 } 45486 45487 bindingByName[ trackName ] = binding; 45488 45489 binding._cacheIndex = bindings.length; 45490 bindings.push( binding ); 45491 45492 }, 45493 45494 _removeInactiveBinding: function ( binding ) { 45495 45496 var bindings = this._bindings, 45497 propBinding = binding.binding, 45498 rootUuid = propBinding.rootNode.uuid, 45499 trackName = propBinding.path, 45500 bindingsByRoot = this._bindingsByRootAndName, 45501 bindingByName = bindingsByRoot[ rootUuid ], 45502 45503 lastInactiveBinding = bindings[ bindings.length - 1 ], 45504 cacheIndex = binding._cacheIndex; 45505 45506 lastInactiveBinding._cacheIndex = cacheIndex; 45507 bindings[ cacheIndex ] = lastInactiveBinding; 45508 bindings.pop(); 45509 45510 delete bindingByName[ trackName ]; 45511 45512 if ( Object.keys( bindingByName ).length === 0 ) { 45513 45514 delete bindingsByRoot[ rootUuid ]; 45515 45516 } 45517 45518 }, 45519 45520 _lendBinding: function ( binding ) { 45521 45522 var bindings = this._bindings, 45523 prevIndex = binding._cacheIndex, 45524 45525 lastActiveIndex = this._nActiveBindings ++, 45526 45527 firstInactiveBinding = bindings[ lastActiveIndex ]; 45528 45529 binding._cacheIndex = lastActiveIndex; 45530 bindings[ lastActiveIndex ] = binding; 45531 45532 firstInactiveBinding._cacheIndex = prevIndex; 45533 bindings[ prevIndex ] = firstInactiveBinding; 45534 45535 }, 45536 45537 _takeBackBinding: function ( binding ) { 45538 45539 var bindings = this._bindings, 45540 prevIndex = binding._cacheIndex, 45541 45542 firstInactiveIndex = -- this._nActiveBindings, 45543 45544 lastActiveBinding = bindings[ firstInactiveIndex ]; 45545 45546 binding._cacheIndex = firstInactiveIndex; 45547 bindings[ firstInactiveIndex ] = binding; 45548 45549 lastActiveBinding._cacheIndex = prevIndex; 45550 bindings[ prevIndex ] = lastActiveBinding; 45551 45552 }, 45553 45554 45555 // Memory management of Interpolants for weight and time scale 45556 45557 _lendControlInterpolant: function () { 45558 45559 var interpolants = this._controlInterpolants, 45560 lastActiveIndex = this._nActiveControlInterpolants ++, 45561 interpolant = interpolants[ lastActiveIndex ]; 45562 45563 if ( interpolant === undefined ) { 45564 45565 interpolant = new LinearInterpolant( 45566 new Float32Array( 2 ), new Float32Array( 2 ), 45567 1, this._controlInterpolantsResultBuffer ); 45568 45569 interpolant.__cacheIndex = lastActiveIndex; 45570 interpolants[ lastActiveIndex ] = interpolant; 45571 45572 } 45573 45574 return interpolant; 45575 45576 }, 45577 45578 _takeBackControlInterpolant: function ( interpolant ) { 45579 45580 var interpolants = this._controlInterpolants, 45581 prevIndex = interpolant.__cacheIndex, 45582 45583 firstInactiveIndex = -- this._nActiveControlInterpolants, 45584 45585 lastActiveInterpolant = interpolants[ firstInactiveIndex ]; 45586 45587 interpolant.__cacheIndex = firstInactiveIndex; 45588 interpolants[ firstInactiveIndex ] = interpolant; 45589 45590 lastActiveInterpolant.__cacheIndex = prevIndex; 45591 interpolants[ prevIndex ] = lastActiveInterpolant; 45592 45593 }, 45594 45595 _controlInterpolantsResultBuffer: new Float32Array( 1 ), 45596 45597 // return an action for a clip optionally using a custom root target 45598 // object (this method allocates a lot of dynamic memory in case a 45599 // previously unknown clip/root combination is specified) 45600 clipAction: function ( clip, optionalRoot, blendMode ) { 45601 45602 var root = optionalRoot || this._root, 45603 rootUuid = root.uuid, 45604 45605 clipObject = typeof clip === 'string' ? 45606 AnimationClip.findByName( root, clip ) : clip, 45607 45608 clipUuid = clipObject !== null ? clipObject.uuid : clip, 45609 45610 actionsForClip = this._actionsByClip[ clipUuid ],
45611 prototypeAction = null; 45612 45613 if ( blendMode === undefined ) { 45614 45615 if ( clipObject !== null ) { 45616 45617 blendMode = clipObject.blendMode; 45618 45619 } else { 45620 45621 blendMode = NormalAnimationBlendMode; 45622 45623 } 45624 45625 } 45626 45627 if ( actionsForClip !== undefined ) { 45628 45629 var existingAction = 45630 actionsForClip.actionByRoot[ rootUuid ]; 45631 45632 if ( existingAction !== undefined && existingAction.blendMode === blendMode ) { 45633 45634 return existingAction; 45635 45636 } 45637 45638 // we know the clip, so we don't have to parse all 45639 // the bindings again but can just copy 45640 prototypeAction = actionsForClip.knownActions[ 0 ]; 45641 45642 // also, take the clip from the prototype action 45643 if ( clipObject === null ) 45644 clipObject = prototypeAction._clip; 45645 45646 } 45647 45648 // clip must be known when specified via string 45649 if ( clipObject === null ) return null; 45650 45651 // allocate all resources required to run it 45652 var newAction = new AnimationAction( this, clipObject, optionalRoot, blendMode ); 45653 45654 this._bindAction( newAction, prototypeAction ); 45655 45656 // and make the action known to the memory manager 45657 this._addInactiveAction( newAction, clipUuid, rootUuid ); 45658 45659 return newAction; 45660 45661 }, 45662 45663 // get an existing action 45664 existingAction: function ( clip, optionalRoot ) { 45665 45666 var root = optionalRoot || this._root, 45667 rootUuid = root.uuid, 45668 45669 clipObject = typeof clip === 'string' ? 45670 AnimationClip.findByName( root, clip ) : clip, 45671 45672 clipUuid = clipObject ? clipObject.uuid : clip, 45673 45674 actionsForClip = this._actionsByClip[ clipUuid ]; 45675 45676 if ( actionsForClip !== undefined ) { 45677 45678 return actionsForClip.actionByRoot[ rootUuid ] || null; 45679 45680 } 45681 45682 return null; 45683 45684 }, 45685 45686 // deactivates all previously scheduled actions 45687 stopAllAction: function () { 45688 45689 var actions = this._actions, 45690 nActions = this._nActiveActions, 45691 bindings = this._bindings, 45692 nBindings = this._nActiveBindings; 45693 45694 this._nActiveActions = 0; 45695 this._nActiveBindings = 0; 45696 45697 for ( var i = 0; i !== nActions; ++ i ) { 45698 45699 actions[ i ].reset(); 45700 45701 } 45702 45703 for ( var i = 0; i !== nBindings; ++ i ) { 45704 45705 bindings[ i ].useCount = 0; 45706 45707 } 45708 45709 return this; 45710 45711 }, 45712 45713 // advance the time and update apply the animation 45714 update: function ( deltaTime ) { 45715 45716 deltaTime *= this.timeScale; 45717 45718 var actions = this._actions, 45719 nActions = this._nActiveActions, 45720 45721 time = this.time += deltaTime, 45722 timeDirection = Math.sign( deltaTime ), 45723 45724 accuIndex = this._accuIndex ^= 1; 45725 45726 // run active actions 45727 45728 for ( var i = 0; i !== nActions; ++ i ) { 45729 45730 var action = actions[ i ]; 45731 45732 action._update( time, deltaTime, timeDirection, accuIndex ); 45733 45734 } 45735 45736 // update scene graph 45737 45738 var bindings = this._bindings, 45739 nBindings = this._nActiveBindings; 45740 45741 for ( var i = 0; i !== nBindings; ++ i ) { 45742 45743 bindings[ i ].apply( accuIndex ); 45744 45745 } 45746 45747 return this; 45748 45749 }, 45750 45751 // Allows you to seek to a specific time in an animation. 45752 setTime: function ( timeInSeconds ) { 45753 45754 this.time = 0; // Zero out time attribute for AnimationMixer object; 45755 for ( var i = 0; i < this._actions.length; i ++ ) { 45756 45757 this._actions[ i ].time = 0; // Zero out time attribute for all associated AnimationAction objects. 45758 45759 } 45760 45761 return this.update( timeInSeconds ); // Update used to set exact time. Returns "this" AnimationMixer object. 45762 45763 }, 45764 45765 // return this mixer's root target object 45766 getRoot: function () { 45767 45768 return this._root; 45769 45770 },
vendor: 4,901 bytes, lines 45771-46005
45771 45772 // free all resources specific to a particular clip 45773 uncacheClip: function ( clip ) { 45774 45775 var actions = this._actions, 45776 clipUuid = clip.uuid, 45777 actionsByClip = this._actionsByClip, 45778 actionsForClip = actionsByClip[ clipUuid ]; 45779 45780 if ( actionsForClip !== undefined ) { 45781 45782 // note: just calling _removeInactiveAction would mess up the 45783 // iteration state and also require updating the state we can 45784 // just throw away 45785 45786 var actionsToRemove = actionsForClip.knownActions; 45787 45788 for ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) { 45789 45790 var action = actionsToRemove[ i ]; 45791 45792 this._deactivateAction( action ); 45793 45794 var cacheIndex = action._cacheIndex, 45795 lastInactiveAction = actions[ actions.length - 1 ]; 45796 45797 action._cacheIndex = null; 45798 action._byClipCacheIndex = null; 45799 45800 lastInactiveAction._cacheIndex = cacheIndex; 45801 actions[ cacheIndex ] = lastInactiveAction; 45802 actions.pop(); 45803 45804 this._removeInactiveBindingsForAction( action ); 45805 45806 } 45807 45808 delete actionsByClip[ clipUuid ]; 45809 45810 } 45811 45812 }, 45813 45814 // free all resources specific to a particular root target object 45815 uncacheRoot: function ( root ) { 45816 45817 var rootUuid = root.uuid, 45818 actionsByClip = this._actionsByClip; 45819 45820 for ( var clipUuid in actionsByClip ) { 45821 45822 var actionByRoot = actionsByClip[ clipUuid ].actionByRoot, 45823 action = actionByRoot[ rootUuid ]; 45824 45825 if ( action !== undefined ) { 45826 45827 this._deactivateAction( action ); 45828 this._removeInactiveAction( action ); 45829 45830 } 45831 45832 } 45833 45834 var bindingsByRoot = this._bindingsByRootAndName, 45835 bindingByName = bindingsByRoot[ rootUuid ]; 45836 45837 if ( bindingByName !== undefined ) { 45838 45839 for ( var trackName in bindingByName ) { 45840 45841 var binding = bindingByName[ trackName ]; 45842 binding.restoreOriginalState(); 45843 this._removeInactiveBinding( binding ); 45844 45845 } 45846 45847 } 45848 45849 }, 45850 45851 // remove a targeted clip from the cache 45852 uncacheAction: function ( clip, optionalRoot ) { 45853 45854 var action = this.existingAction( clip, optionalRoot ); 45855 45856 if ( action !== null ) { 45857 45858 this._deactivateAction( action ); 45859 this._removeInactiveAction( action ); 45860 45861 } 45862 45863 } 45864 45865} ); 45866 45867/** 45868 * @author mrdoob / http://mrdoob.com/ 45869 */ 45870 45871function Uniform( value ) { 45872 45873 if ( typeof value === 'string' ) { 45874 45875 console.warn( 'THREE.Uniform: Type parameter is no longer needed.' ); 45876 value = arguments[ 1 ]; 45877 45878 } 45879 45880 this.value = value; 45881 45882} 45883 45884Uniform.prototype.clone = function () { 45885 45886 return new Uniform( this.value.clone === undefined ? this.value : this.value.clone() ); 45887 45888}; 45889 45890/** 45891 * @author benaadams / https://twitter.com/ben_a_adams 45892 */ 45893 45894function InstancedInterleavedBuffer( array, stride, meshPerAttribute ) { 45895 45896 InterleavedBuffer.call( this, array, stride ); 45897 45898 this.meshPerAttribute = meshPerAttribute || 1; 45899 45900} 45901 45902InstancedInterleavedBuffer.prototype = Object.assign( Object.create( InterleavedBuffer.prototype ), { 45903 45904 constructor: InstancedInterleavedBuffer, 45905 45906 isInstancedInterleavedBuffer: true, 45907 45908 copy: function ( source ) { 45909 45910 InterleavedBuffer.prototype.copy.call( this, source ); 45911 45912 this.meshPerAttribute = source.meshPerAttribute; 45913 45914 return this; 45915 45916 } 45917 45918} ); 45919 45920/** 45921 * @author mrdoob / http://mrdoob.com/ 45922 * @author bhouston / http://clara.io/ 45923 * @author stephomi / http://stephaneginier.com/ 45924 */ 45925 45926function Raycaster( origin, direction, near, far ) { 45927 45928 this.ray = new Ray( origin, direction ); 45929 // direction is assumed to be normalized (for accurate distance calculations) 45930 45931 this.near = near || 0; 45932 this.far = far || Infinity; 45933 this.camera = null; 45934 this.layers = new Layers(); 45935 45936 this.params = { 45937 Mesh: {}, 45938 Line: { threshold: 1 }, 45939 LOD: {}, 45940 Points: { threshold: 1 }, 45941 Sprite: {} 45942 }; 45943 45944 Object.defineProperties( this.params, { 45945 PointCloud: { 45946 get: function () { 45947 45948 console.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' ); 45949 return this.Points; 45950 45951 } 45952 } 45953 } ); 45954 45955} 45956 45957function ascSort( a, b ) { 45958 45959 return a.distance - b.distance; 45960 45961} 45962 45963function intersectObject( object, raycaster, intersects, recursive ) { 45964 45965 if ( object.layers.test( raycaster.layers ) ) { 45966 45967 object.raycast( raycaster, intersects ); 45968 45969 } 45970 45971 if ( recursive === true ) { 45972 45973 var children = object.children; 45974 45975 for ( var i = 0, l = children.length; i < l; i ++ ) { 45976 45977 intersectObject( children[ i ], raycaster, intersects, true ); 45978 45979 } 45980 45981 } 45982 45983} 45984 45985Object.assign( Raycaster.prototype, { 45986 45987 set: function ( origin, direction ) { 45988 45989 // direction is assumed to be normalized (for accurate distance calculations) 45990 45991 this.ray.set( origin, direction ); 45992 45993 }, 45994 45995 setFromCamera: function ( coords, camera ) { 45996 45997 if ( ( camera && camera.isPerspectiveCamera ) ) { 45998 45999 this.ray.origin.setFromMatrixPosition( camera.matrixWorld ); 46000 this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize(); 46001 this.camera = camera; 46002 46003 } else if ( ( camera && camera.isOrthographicCamera ) ) { 46004 46005 this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera );
46005 // set origin in plane of camera 46006 this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld ); 46007 this.camera = camera; 46008 46009 } else { 46010 46011 console.error( 'THREE.Raycaster: Unsupported camera type.' ); 46012 46013 } 46014 46015 }, 46016 46017 intersectObject: function ( object, recursive, optionalTarget ) { 46018 46019 var intersects = optionalTarget || []; 46020 46021 intersectObject( object, this, intersects, recursive ); 46022 46023 intersects.sort( ascSort ); 46024 46025 return intersects; 46026 46027 }, 46028 46029 intersectObjects: function ( objects, recursive, optionalTarget ) { 46030 46031 var intersects = optionalTarget || []; 46032 46033 if ( Array.isArray( objects ) === false ) { 46034 46035 console.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' ); 46036 return intersects; 46037 46038 } 46039 46040 for ( var i = 0, l = objects.length; i < l; i ++ ) { 46041 46042 intersectObject( objects[ i ], this, intersects, recursive ); 46043 46044 } 46045 46046 intersects.sort( ascSort ); 46047 46048 return intersects; 46049 46050 } 46051 46052} ); 46053 46054/** 46055 * @author bhouston / http://clara.io 46056 * @author WestLangley / http://github.com/WestLangley 46057 * 46058 * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system 46059 * 46060 * The polar angle (phi) is measured from the positive y-axis. The positive y-axis is up. 46061 * The azimuthal angle (theta) is measured from the positive z-axis. 46062 */ 46063 46064function Spherical( radius, phi, theta ) { 46065 46066 this.radius = ( radius !== undefined ) ? radius : 1.0; 46067 this.phi = ( phi !== undefined ) ? phi : 0; // polar angle 46068 this.theta = ( theta !== undefined ) ? theta : 0; // azimuthal angle 46069 46070 return this; 46071 46072} 46073 46074Object.assign( Spherical.prototype, { 46075 46076 set: function ( radius, phi, theta ) { 46077 46078 this.radius = radius; 46079 this.phi = phi; 46080 this.theta = theta; 46081 46082 return this; 46083 46084 }, 46085 46086 clone: function () { 46087 46088 return new this.constructor().copy( this ); 46089 46090 }, 46091 46092 copy: function ( other ) { 46093 46094 this.radius = other.radius; 46095 this.phi = other.phi; 46096 this.theta = other.theta; 46097 46098 return this; 46099 46100 }, 46101 46102 // restrict phi to be betwee EPS and PI-EPS 46103 makeSafe: function () { 46104 46105 var EPS = 0.000001; 46106 this.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) ); 46107 46108 return this; 46109 46110 }, 46111 46112 setFromVector3: function ( v ) { 46113 46114 return this.setFromCartesianCoords( v.x, v.y, v.z ); 46115 46116 }, 46117 46118 setFromCartesianCoords: function ( x, y, z ) { 46119 46120 this.radius = Math.sqrt( x * x + y * y + z * z ); 46121 46122 if ( this.radius === 0 ) { 46123 46124 this.theta = 0; 46125 this.phi = 0; 46126 46127 } else { 46128 46129 this.theta = Math.atan2( x, z ); 46130 this.phi = Math.acos( MathUtils.clamp( y / this.radius, - 1, 1 ) ); 46131 46132 } 46133 46134 return this; 46135 46136 } 46137 46138} ); 46139 46140/** 46141 * @author Mugen87 / https://github.com/Mugen87 46142 * 46143 * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system 46144 * 46145 */ 46146 46147function Cylindrical( radius, theta, y ) { 46148 46149 this.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane 46150 this.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis 46151 this.y = ( y !== undefined ) ? y : 0; // height above the x-z plane 46152 46153 return this; 46154 46155} 46156 46157Object.assign( Cylindrical.prototype, { 46158 46159 set: function ( radius, theta, y ) { 46160 46161 this.radius = radius; 46162 this.theta = theta; 46163 this.y = y; 46164 46165 return this; 46166 46167 }, 46168 46169 clone: function () { 46170 46171 return new this.constructor().copy( this ); 46172 46173 }, 46174 46175 copy: function ( other ) { 46176 46177 this.radius = other.radius; 46178 this.theta = other.theta; 46179 this.y = other.y; 46180 46181 return this; 46182 46183 }, 46184 46185 setFromVector3: function ( v ) { 46186 46187 return this.setFromCartesianCoords( v.x, v.y, v.z ); 46188 46189 }, 46190 46191 setFromCartesianCoords: function ( x, y, z ) { 46192 46193 this.radius = Math.sqrt( x * x + z * z ); 46194 this.theta = Math.atan2( x, z ); 46195 this.y = y; 46196 46197 return this; 46198 46199 } 46200 46201} ); 46202 46203/** 46204 * @author bhouston / http://clara.io 46205 */ 46206 46207var _vector$7 = new Vector2(); 46208 46209function Box2( min, max ) { 46210 46211 this.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity ); 46212 this.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity ); 46213 46214} 46215 46216Object.assign( Box2.prototype, { 46217 46218 set: function ( min, max ) { 46219 46220 this.min.copy( min ); 46221 this.max.copy( max ); 46222 46223 return this; 46224 46225 }, 46226 46227 setFromPoints: function ( points ) { 46228 46229 this.makeEmpty(); 46230 46231 for ( var i = 0, il = points.length; i < il; i ++ ) { 46232 46233 this.expandByPoint( points[ i ] ); 46234 46235 } 46236 46237 return this; 46238 46239 }, 46240 46241 setFromCenterAndSize: function ( center, size ) { 46242 46243 var halfSize = _vector$7.copy( size ).multiplyScalar( 0.5 ); 46244 this.min.copy( center ).sub( halfSize ); 46245 this.max.copy( center ).add( halfSize ); 46246 46247 return this; 46248 46249 }, 46250 46251 clone: function () { 46252 46253 return new this.constructor().copy( this ); 46254 46255 }, 46256 46257 copy: function ( box ) { 46258 46259 this.min.copy( box.min ); 46260 this.max.copy( box.max ); 46261 46262 return this; 46263 46264 }, 46265 46266 makeEmpty: function () { 46267 46268 this.min.x = this.min.y = + Infinity; 46269 this.max.x = this.max.y = - Infinity; 46270 46271 return this; 46272 46273 }, 46274 46275 isEmpty: function () { 46276 46277 // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes 46278 46279 return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ); 46280 46281 }, 46282 46283 getCenter: function ( target ) { 46284 46285 if ( target === undefined ) { 46286 46287 console.warn( 'THREE.Box2: .getCenter() target is now required' ); 46288 target = new Vector2(); 46289 46290 } 46291 46292 return this.isEmpty() ? target.set( 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); 46293 46294 }, 46295 46296 getSize: function ( target ) { 46297 46298 if ( target === undefined ) { 46299 46300 console.warn( 'THREE.Box2: .getSize() target is now required' ); 46301 target = new Vector2(); 46302 46303 } 46304 46305 return this.isEmpty() ? target.set( 0, 0 ) : target.subVectors( this.max, this.min ); 46306 46307 }, 46308 46309 expandByPoint: function ( point ) { 46310 46311 this.min.min( point ); 46312 this.max.max( point ); 46313 46314 return this; 46315 46316 }, 46317 46318 expandByVector: function ( vector ) { 46319 46320 this.min.sub( vector ); 46321 this.max.add( vector ); 46322 46323 return this; 46324 46325 }, 46326 46327 expandByScalar: function ( scalar ) { 46328 46329 this.min.addScalar( - scalar ); 46330 this.max.addScalar( scalar ); 46331 46332 return this; 46333 46334 }, 46335 46336 containsPoint: function ( point ) { 46337 46338 return point.x < this.min.x || point.x > this.max.x || 46339 point.y < this.min.y || point.y > this.max.y ? false : true; 46340 46341 }, 46342 46343 containsBox: function ( box ) { 46344 46345 return this.min.x <= box.min.x && box.max.x <= this.max.x && 46346 this.min.y <= box.min.y && box.max.y <= this.max.y; 46347 46348 }, 46349 46350 getParameter: function ( point, target ) { 46351 46352 // This can potentially have a divide by zero if the box 46353 // has a size dimension of 0. 46354 46355 if ( target === undefined ) { 46356 46357 console.warn( 'THREE.Box2: .getParameter() target is now required' ); 46358 target = new Vector2(); 46359 46360 } 46361 46362 return target.set( 46363 ( point.x - this.min.x ) / ( this.max.x - this.min.x ), 46364 ( point.y - this.min.y ) / ( this.max.y - this.min.y ) 46365 ); 46366 46367 }, 46368 46369 intersectsBox: function ( box ) { 46370 46371 // using 4 splitting planes to rule out intersections 46372 46373 return box.max.x < this.min.x || box.min.x > this.max.x || 46374 box.max.y < this.min.y || box.min.y > this.max.y ? false : true; 46375 46376 }, 46377 46378 clampPoint: function ( point, target ) { 46379 46380 if ( target === undefined ) { 46381 46382 console.warn( 'THREE.Box2: .clampPoint() target is now required' ); 46383 target = new Vector2(); 46384 46385 } 46386 46387 return target.copy( point ).clamp( this.min, this.max ); 46388 46389 }, 46390 46391 distanceToPoint: function ( point ) { 46392 46393 var clampedPoint = _vector$7.copy( point ).clamp( this.min, this.max ); 46394 return clampedPoint.sub( point ).length(); 46395 46396 }, 46397 46398 intersect: function ( box ) { 46399 46400 this.min.max( box.min ); 46401 this.max.min( box.max ); 46402 46403 return this; 46404 46405 }, 46406 46407 union: function ( box ) { 46408 46409 this.min.min( box.min ); 46410 this.max.max( box.max ); 46411 46412 return this; 46413 46414 }, 46415 46416 translate: function ( offset ) { 46417 46418 this.min.add( offset ); 46419 this.max.add( offset ); 46420 46421 return this; 46422 46423 }, 46424 46425 equals: function ( box ) { 46426 46427 return box.min.equals( this.min ) && box.max.equals( this.max ); 46428 46429 } 46430 46431} ); 46432 46433/** 46434 * @author bhouston / http://clara.io 46435 */ 46436 46437var _startP = new Vector3(); 46438var _startEnd = new Vector3(); 46439 46440function Line3( start, end ) { 46441 46442 this.start = ( start !== undefined ) ? start : new Vector3(); 46443 this.end = ( end !== undefined ) ? end : new Vector3(); 46444 46445} 46446 46447Object.assign( Line3.prototype, { 46448 46449 set: function ( start, end ) { 46450 46451 this.start.copy( start ); 46452 this.end.copy( end ); 46453 46454 return this; 46455 46456 }, 46457 46458 clone: function () { 46459 46460 return new this.constructor().copy( this ); 46461 46462 }, 46463 46464 copy: function ( line ) { 46465 46466 this.start.copy( line.start ); 46467 this.end.copy( line.end ); 46468 46469 return this; 46470 46471 }, 46472 46473 getCenter: function ( target ) { 46474 46475 if ( target === undefined ) { 46476 46477 console.warn( 'THREE.Line3: .getCenter() target is now required' ); 46478 target = new Vector3(); 46479 46480 } 46481 46482 return target.addVectors( this.start, this.end ).multiplyScalar( 0.5 ); 46483 46484 }, 46485 46486 delta: function ( target ) { 46487 46488 if ( target === undefined ) { 46489 46490 console.warn( 'THREE.Line3: .delta() target is now required' ); 46491 target = new Vector3(); 46492 46493 } 46494 46495 return target.subVectors( this.end, this.start ); 46496 46497 }, 46498 46499 distanceSq: function () { 46500 46501 return this.start.distanceToSquared( this.end ); 46502 46503 }, 46504 46505 distance: function () { 46506 46507 return this.start.distanceTo( this.end ); 46508 46509 }, 46510 46511 at: function ( t, target ) { 46512 46513 if ( target === undefined ) { 46514
46515 console.warn( 'THREE.Line3: .at() target is now required' ); 46516 target = new Vector3(); 46517 46518 } 46519 46520 return this.delta( target ).multiplyScalar( t ).add( this.start ); 46521 46522 }, 46523 46524 closestPointToPointParameter: function ( point, clampToLine ) { 46525 46526 _startP.subVectors( point, this.start ); 46527 _startEnd.subVectors( this.end, this.start ); 46528 46529 var startEnd2 = _startEnd.dot( _startEnd ); 46530 var startEnd_startP = _startEnd.dot( _startP ); 46531 46532 var t = startEnd_startP / startEnd2; 46533 46534 if ( clampToLine ) { 46535 46536 t = MathUtils.clamp( t, 0, 1 ); 46537 46538 } 46539 46540 return t; 46541 46542 }, 46543 46544 closestPointToPoint: function ( point, clampToLine, target ) { 46545 46546 var t = this.closestPointToPointParameter( point, clampToLine ); 46547 46548 if ( target === undefined ) { 46549 46550 console.warn( 'THREE.Line3: .closestPointToPoint() target is now required' ); 46551 target = new Vector3(); 46552 46553 } 46554 46555 return this.delta( target ).multiplyScalar( t ).add( this.start ); 46556 46557 }, 46558 46559 applyMatrix4: function ( matrix ) { 46560 46561 this.start.applyMatrix4( matrix ); 46562 this.end.applyMatrix4( matrix ); 46563 46564 return this; 46565 46566 }, 46567 46568 equals: function ( line ) { 46569 46570 return line.start.equals( this.start ) && line.end.equals( this.end ); 46571 46572 } 46573 46574} ); 46575 46576/** 46577 * @author alteredq / http://alteredqualia.com/ 46578 */ 46579 46580function ImmediateRenderObject( material ) { 46581 46582 Object3D.call( this ); 46583 46584 this.material = material; 46585 this.render = function ( /* renderCallback */ ) {}; 46586 46587} 46588 46589ImmediateRenderObject.prototype = Object.create( Object3D.prototype ); 46590ImmediateRenderObject.prototype.constructor = ImmediateRenderObject; 46591 46592ImmediateRenderObject.prototype.isImmediateRenderObject = true; 46593 46594/** 46595 * @author alteredq / http://alteredqualia.com/ 46596 * @author mrdoob / http://mrdoob.com/ 46597 * @author WestLangley / http://github.com/WestLangley 46598 */ 46599 46600var _vector$8 = new Vector3(); 46601 46602function SpotLightHelper( light, color ) { 46603 46604 Object3D.call( this ); 46605 46606 this.light = light; 46607 this.light.updateMatrixWorld(); 46608 46609 this.matrix = light.matrixWorld; 46610 this.matrixAutoUpdate = false; 46611 46612 this.color = color; 46613 46614 var geometry = new BufferGeometry(); 46615 46616 var positions = [ 46617 0, 0, 0, 0, 0, 1, 46618 0, 0, 0, 1, 0, 1, 46619 0, 0, 0, - 1, 0, 1, 46620 0, 0, 0, 0, 1, 1, 46621 0, 0, 0, 0, - 1, 1 46622 ]; 46623 46624 for ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) { 46625 46626 var p1 = ( i / l ) * Math.PI * 2; 46627 var p2 = ( j / l ) * Math.PI * 2; 46628 46629 positions.push( 46630 Math.cos( p1 ), Math.sin( p1 ), 1, 46631 Math.cos( p2 ), Math.sin( p2 ), 1 46632 ); 46633 46634 } 46635 46636 geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); 46637 46638 var material = new LineBasicMaterial( { fog: false, toneMapped: false } ); 46639 46640 this.cone = new LineSegments( geometry, material ); 46641 this.add( this.cone ); 46642 46643 this.update(); 46644 46645} 46646 46647SpotLightHelper.prototype = Object.create( Object3D.prototype ); 46648SpotLightHelper.prototype.constructor = SpotLightHelper; 46649 46650SpotLightHelper.prototype.dispose = function () { 46651 46652 this.cone.geometry.dispose(); 46653 this.cone.material.dispose(); 46654 46655}; 46656 46657SpotLightHelper.prototype.update = function () { 46658 46659 this.light.updateMatrixWorld(); 46660 46661 var coneLength = this.light.distance ? this.light.distance : 1000; 46662 var coneWidth = coneLength * Math.tan( this.light.angle ); 46663 46664 this.cone.scale.set( coneWidth, coneWidth, coneLength ); 46665 46666 _vector$8.setFromMatrixPosition( this.light.target.matrixWorld ); 46667 46668 this.cone.lookAt( _vector$8 ); 46669 46670 if ( this.color !== undefined ) { 46671 46672 this.cone.material.color.set( this.color ); 46673 46674 } else { 46675 46676 this.cone.material.color.copy( this.light.color ); 46677 46678 } 46679 46680}; 46681 46682/** 46683 * @author Sean Griffin / http://twitter.com/sgrif 46684 * @author Michael Guerrero / http://realitymeltdown.com 46685 * @author mrdoob / http://mrdoob.com/ 46686 * @author ikerr / http://verold.com 46687 * @author Mugen87 / https://github.com/Mugen87 46688 */ 46689 46690var _vector$9 = new Vector3(); 46691var _boneMatrix = new Matrix4(); 46692var _matrixWorldInv = new Matrix4(); 46693 46694function getBoneList( object ) { 46695 46696 var boneList = []; 46697 46698 if ( object && object.isBone ) { 46699 46700 boneList.push( object ); 46701 46702 } 46703 46704 for ( var i = 0; i < object.children.length; i ++ ) { 46705 46706 boneList.push.apply( boneList, getBoneList( object.children[ i ] ) ); 46707 46708 } 46709 46710 return boneList; 46711 46712} 46713 46714function SkeletonHelper( object ) { 46715 46716 var bones = getBoneList( object ); 46717 46718 var geometry = new BufferGeometry(); 46719 46720 var vertices = []; 46721 var colors = []; 46722 46723 var color1 = new Color( 0, 0, 1 ); 46724 var color2 = new Color( 0, 1, 0 ); 46725 46726 for ( var i = 0; i < bones.length; i ++ ) { 46727 46728 var bone = bones[ i ]; 46729 46730 if ( bone.parent && bone.parent.isBone ) { 46731 46732 vertices.push( 0, 0, 0 ); 46733 vertices.push( 0, 0, 0 ); 46734 colors.push( color1.r, color1.g, color1.b ); 46735 colors.push( color2.r, color2.g, color2.b ); 46736 46737 } 46738 46739 } 46740 46741 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 46742 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); 46743 46744 var material = new LineBasicMaterial( { vertexColors: true, depthTest: false, depthWrite: false, toneMapped: false, transparent: true } ); 46745 46746 LineSegments.call( this, geometry, material ); 46747 46748 this.type = 'SkeletonHelper'; 46749 46750 this.root = object; 46751 this.bones = bones; 46752 46753 this.matrix = object.matrixWorld; 46754 this.matrixAutoUpdate = false;
46755 46756} 46757 46758SkeletonHelper.prototype = Object.create( LineSegments.prototype ); 46759SkeletonHelper.prototype.constructor = SkeletonHelper; 46760 46761SkeletonHelper.prototype.isSkeletonHelper = true; 46762 46763SkeletonHelper.prototype.updateMatrixWorld = function ( force ) { 46764 46765 var bones = this.bones; 46766 46767 var geometry = this.geometry; 46768 var position = geometry.getAttribute( 'position' ); 46769 46770 _matrixWorldInv.getInverse( this.root.matrixWorld ); 46771 46772 for ( var i = 0, j = 0; i < bones.length; i ++ ) { 46773 46774 var bone = bones[ i ]; 46775 46776 if ( bone.parent && bone.parent.isBone ) { 46777 46778 _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.matrixWorld ); 46779 _vector$9.setFromMatrixPosition( _boneMatrix ); 46780 position.setXYZ( j, _vector$9.x, _vector$9.y, _vector$9.z ); 46781 46782 _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.parent.matrixWorld ); 46783 _vector$9.setFromMatrixPosition( _boneMatrix ); 46784 position.setXYZ( j + 1, _vector$9.x, _vector$9.y, _vector$9.z ); 46785 46786 j += 2; 46787 46788 } 46789 46790 } 46791 46792 geometry.getAttribute( 'position' ).needsUpdate = true; 46793 46794 Object3D.prototype.updateMatrixWorld.call( this, force ); 46795 46796}; 46797 46798/** 46799 * @author alteredq / http://alteredqualia.com/ 46800 * @author mrdoob / http://mrdoob.com/ 46801 */ 46802 46803function PointLightHelper( light, sphereSize, color ) { 46804 46805 this.light = light; 46806 this.light.updateMatrixWorld(); 46807 46808 this.color = color; 46809 46810 var geometry = new SphereBufferGeometry( sphereSize, 4, 2 ); 46811 var material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } ); 46812 46813 Mesh.call( this, geometry, material ); 46814 46815 this.type = 'PointLightHelper'; 46816 46817 this.matrix = this.light.matrixWorld; 46818 this.matrixAutoUpdate = false; 46819 46820 this.update(); 46821 46822 46823 /* 46824 var distanceGeometry = new THREE.IcosahedronBufferGeometry( 1, 2 ); 46825 var distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } ); 46826 46827 this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial ); 46828 this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial ); 46829 46830 var d = light.distance; 46831 46832 if ( d === 0.0 ) { 46833 46834 this.lightDistance.visible = false; 46835 46836 } else { 46837 46838 this.lightDistance.scale.set( d, d, d ); 46839 46840 } 46841 46842 this.add( this.lightDistance ); 46843 */ 46844 46845} 46846 46847PointLightHelper.prototype = Object.create( Mesh.prototype ); 46848PointLightHelper.prototype.constructor = PointLightHelper; 46849 46850PointLightHelper.prototype.dispose = function () { 46851 46852 this.geometry.dispose(); 46853 this.material.dispose(); 46854 46855}; 46856 46857PointLightHelper.prototype.update = function () { 46858 46859 if ( this.color !== undefined ) { 46860 46861 this.material.color.set( this.color ); 46862 46863 } else { 46864 46865 this.material.color.copy( this.light.color ); 46866 46867 } 46868 46869 /* 46870 var d = this.light.distance; 46871 46872 if ( d === 0.0 ) { 46873 46874 this.lightDistance.visible = false; 46875 46876 } else { 46877 46878 this.lightDistance.visible = true; 46879 this.lightDistance.scale.set( d, d, d ); 46880 46881 } 46882 */ 46883 46884}; 46885 46886/** 46887 * @author alteredq / http://alteredqualia.com/ 46888 * @author mrdoob / http://mrdoob.com/ 46889 * @author Mugen87 / https://github.com/Mugen87 46890 */ 46891 46892var _vector$a = new Vector3(); 46893var _color1 = new Color(); 46894var _color2 = new Color(); 46895 46896function HemisphereLightHelper( light, size, color ) { 46897 46898 Object3D.call( this ); 46899 46900 this.light = light; 46901 this.light.updateMatrixWorld(); 46902 46903 this.matrix = light.matrixWorld; 46904 this.matrixAutoUpdate = false; 46905 46906 this.color = color; 46907 46908 var geometry = new OctahedronBufferGeometry( size ); 46909 geometry.rotateY( Math.PI * 0.5 ); 46910 46911 this.material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } ); 46912 if ( this.color === undefined ) this.material.vertexColors = true; 46913 46914 var position = geometry.getAttribute( 'position' ); 46915 var colors = new Float32Array( position.count * 3 ); 46916 46917 geometry.setAttribute( 'color', new BufferAttribute( colors, 3 ) ); 46918 46919 this.add( new Mesh( geometry, this.material ) ); 46920 46921 this.update(); 46922 46923} 46924 46925HemisphereLightHelper.prototype = Object.create( Object3D.prototype ); 46926HemisphereLightHelper.prototype.constructor = HemisphereLightHelper; 46927 46928HemisphereLightHelper.prototype.dispose = function () { 46929 46930 this.children[ 0 ].geometry.dispose(); 46931 this.children[ 0 ].material.dispose(); 46932 46933}; 46934 46935HemisphereLightHelper.prototype.update = function () { 46936 46937 var mesh = this.children[ 0 ]; 46938 46939 if ( this.color !== undefined ) { 46940 46941 this.material.color.set( this.color ); 46942 46943 } else { 46944 46945 var colors = mesh.geometry.getAttribute( 'color' ); 46946 46947 _color1.copy( this.light.color ); 46948 _color2.copy( this.light.groundColor ); 46949 46950 for ( var i = 0, l = colors.count; i < l; i ++ ) { 46951 46952 var color = ( i < ( l / 2 ) ) ? _color1 : _color2; 46953 46954 colors.setXYZ( i, color.r, color.g, color.b ); 46955 46956 } 46957 46958 colors.needsUpdate = true; 46959 46960 } 46961 46962 mesh.lookAt( _vector$a.setFromMatrixPosition( this.light.matrixWorld ).negate() ); 46963 46964}; 46965 46966/** 46967 * @author mrdoob / http://mrdoob.com/ 46968 */ 46969 46970function GridHelper( size, divisions, color1, color2 ) { 46971 46972 size = size || 10; 46973 divisions = divisions || 10; 46974 color1 = new Color( color1 !== undefined ? color1 : 0x444444 ); 46975 color2 = new Color( color2 !== undefined ? color2 : 0x888888 ); 46976 46977 var center = divisions / 2; 46978 var step = size / divisions; 46979 var halfSize = size / 2; 46980 46981 var vertices = [], colors = []; 46982 46983 for ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) { 46984
46985 vertices.push( - halfSize, 0, k, halfSize, 0, k ); 46986 vertices.push( k, 0, - halfSize, k, 0, halfSize ); 46987 46988 var color = i === center ? color1 : color2; 46989 46990 color.toArray( colors, j ); j += 3; 46991 color.toArray( colors, j ); j += 3; 46992 color.toArray( colors, j ); j += 3; 46993 color.toArray( colors, j ); j += 3; 46994 46995 } 46996 46997 var geometry = new BufferGeometry(); 46998 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 46999 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); 47000 47001 var material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } ); 47002 47003 LineSegments.call( this, geometry, material ); 47004 47005 this.type = 'GridHelper'; 47006 47007} 47008 47009GridHelper.prototype = Object.assign( Object.create( LineSegments.prototype ), { 47010 47011 constructor: GridHelper, 47012 47013 copy: function ( source ) { 47014 47015 LineSegments.prototype.copy.call( this, source ); 47016 47017 this.geometry.copy( source.geometry ); 47018 this.material.copy( source.material ); 47019 47020 return this; 47021 47022 }, 47023 47024 clone: function () { 47025 47026 return new this.constructor().copy( this ); 47027 47028 } 47029 47030} ); 47031 47032/** 47033 * @author mrdoob / http://mrdoob.com/ 47034 * @author Mugen87 / http://github.com/Mugen87 47035 * @author Hectate / http://www.github.com/Hectate 47036 */ 47037 47038function PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) { 47039 47040 radius = radius || 10; 47041 radials = radials || 16; 47042 circles = circles || 8; 47043 divisions = divisions || 64; 47044 color1 = new Color( color1 !== undefined ? color1 : 0x444444 ); 47045 color2 = new Color( color2 !== undefined ? color2 : 0x888888 ); 47046 47047 var vertices = []; 47048 var colors = []; 47049 47050 var x, z; 47051 var v, i, j, r, color; 47052 47053 // create the radials 47054 47055 for ( i = 0; i <= radials; i ++ ) { 47056 47057 v = ( i / radials ) * ( Math.PI * 2 ); 47058 47059 x = Math.sin( v ) * radius; 47060 z = Math.cos( v ) * radius; 47061 47062 vertices.push( 0, 0, 0 ); 47063 vertices.push( x, 0, z ); 47064 47065 color = ( i & 1 ) ? color1 : color2; 47066 47067 colors.push( color.r, color.g, color.b ); 47068 colors.push( color.r, color.g, color.b ); 47069 47070 } 47071 47072 // create the circles 47073 47074 for ( i = 0; i <= circles; i ++ ) { 47075 47076 color = ( i & 1 ) ? color1 : color2; 47077 47078 r = radius - ( radius / circles * i ); 47079 47080 for ( j = 0; j < divisions; j ++ ) { 47081 47082 // first vertex 47083 47084 v = ( j / divisions ) * ( Math.PI * 2 ); 47085 47086 x = Math.sin( v ) * r; 47087 z = Math.cos( v ) * r; 47088 47089 vertices.push( x, 0, z ); 47090 colors.push( color.r, color.g, color.b ); 47091 47092 // second vertex 47093 47094 v = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 ); 47095 47096 x = Math.sin( v ) * r; 47097 z = Math.cos( v ) * r; 47098 47099 vertices.push( x, 0, z ); 47100 colors.push( color.r, color.g, color.b ); 47101 47102 } 47103 47104 } 47105 47106 var geometry = new BufferGeometry(); 47107 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 47108 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); 47109 47110 var material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } ); 47111 47112 LineSegments.call( this, geometry, material ); 47113 47114 this.type = 'PolarGridHelper'; 47115 47116} 47117 47118PolarGridHelper.prototype = Object.create( LineSegments.prototype ); 47119PolarGridHelper.prototype.constructor = PolarGridHelper; 47120 47121/** 47122 * @author alteredq / http://alteredqualia.com/ 47123 * @author mrdoob / http://mrdoob.com/ 47124 * @author WestLangley / http://github.com/WestLangley 47125 */ 47126 47127var _v1$5 = new Vector3(); 47128var _v2$3 = new Vector3(); 47129var _v3$1 = new Vector3(); 47130 47131function DirectionalLightHelper( light, size, color ) { 47132 47133 Object3D.call( this ); 47134 47135 this.light = light; 47136 this.light.updateMatrixWorld(); 47137 47138 this.matrix = light.matrixWorld; 47139 this.matrixAutoUpdate = false; 47140 47141 this.color = color; 47142 47143 if ( size === undefined ) size = 1; 47144 47145 var geometry = new BufferGeometry(); 47146 geometry.setAttribute( 'position', new Float32BufferAttribute( [ 47147 - size, size, 0, 47148 size, size, 0, 47149 size, - size, 0, 47150 - size, - size, 0, 47151 - size, size, 0 47152 ], 3 ) ); 47153 47154 var material = new LineBasicMaterial( { fog: false, toneMapped: false } ); 47155 47156 this.lightPlane = new Line( geometry, material ); 47157 this.add( this.lightPlane ); 47158 47159 geometry = new BufferGeometry(); 47160 geometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) ); 47161 47162 this.targetLine = new Line( geometry, material ); 47163 this.add( this.targetLine ); 47164 47165 this.update(); 47166 47167} 47168 47169DirectionalLightHelper.prototype = Object.create( Object3D.prototype ); 47170DirectionalLightHelper.prototype.constructor = DirectionalLightHelper; 47171 47172DirectionalLightHelper.prototype.dispose = function () { 47173 47174 this.lightPlane.geometry.dispose(); 47175 this.lightPlane.material.dispose(); 47176 this.targetLine.geometry.dispose(); 47177 this.targetLine.material.dispose(); 47178 47179}; 47180 47181DirectionalLightHelper.prototype.update = function () { 47182 47183 _v1$5.setFromMatrixPosition( this.light.matrixWorld ); 47184 _v2$3.setFromMatrixPosition( this.light.target.matrixWorld ); 47185 _v3$1.subVectors( _v2$3, _v1$5 ); 47186 47187 this.lightPlane.lookAt( _v2$3 ); 47188 47189 if ( this.color !== undefined ) { 47190 47191 this.lightPlane.material.color.set( this.color ); 47192 this.targetLine.material.color.set( this.color ); 47193 47194 } else { 47195 47196 this.lightPlane.material.color.copy( this.light.color ); 47197 this.targetLine.material.color.copy( this.light.color ); 47198 47199 } 47200 47201 this.targetLine.lookAt( _v2$3 ); 47202 this.targetLine.scale.z = _v3$1.length(); 47203 47204}; 47205 47206/** 47207 * @author alteredq / http://alteredqualia.com/ 47208 * @author Mugen87 / https://github.com/Mugen87 47209 * 47210 * - shows frustum, line of sight and up of the camera 47211 * - suitable for fast updates 47212 * - based on frustum visualization in lightgl.js shadowmap example 47213 * http://evanw.github.com/lightgl.js/tests/shadowmap.html 47214 */ 47215 47216var _vector$b = new Vector3(); 47217var _camera = new Camera(); 47218 47219function CameraHelper( camera ) { 47220 47221 var geometry = new BufferGeometry(); 47222 var material = new LineBasicMaterial( { color: 0xffffff, vertexColors: true, toneMapped: false } ); 47223 47224 var vertices = []; 47225 var colors = []; 47226 47227 var pointMap = {}; 47228 47229 // colors 47230 47231 var colorFrustum = new Color( 0xffaa00 ); 47232 var colorCone = new Color( 0xff0000 ); 47233 var colorUp = new Color( 0x00aaff ); 47234 var colorTarget = new Color( 0xffffff ); 47235 var colorCross = new Color( 0x333333 ); 47236 47237 // near 47238 47239 addLine( 'n1', 'n2', colorFrustum ); 47240 addLine( 'n2', 'n4', colorFrustum ); 47241 addLine( 'n4', 'n3', colorFrustum ); 47242 addLine( 'n3', 'n1', colorFrustum ); 47243 47244 // far 47245 47246 addLine( 'f1', 'f2', colorFrustum ); 47247 addLine( 'f2', 'f4', colorFrustum ); 47248 addLine( 'f4', 'f3', colorFrustum ); 47249 addLine( 'f3', 'f1', colorFrustum ); 47250 47251 // sides 47252 47253 addLine( 'n1', 'f1', colorFrustum ); 47254 addLine( 'n2', 'f2', colorFrustum ); 47255 addLine( 'n3', 'f3', colorFrustum ); 47256 addLine( 'n4', 'f4', colorFrustum ); 47257 47258 // cone 47259 47260 addLine( 'p', 'n1', colorCone ); 47261 addLine( 'p', 'n2', colorCone ); 47262 addLine( 'p', 'n3', colorCone ); 47263 addLine( 'p', 'n4', colorCone ); 47264 47265 // up 47266 47267 addLine( 'u1', 'u2', colorUp ); 47268 addLine( 'u2', 'u3', colorUp ); 47269 addLine( 'u3', 'u1', colorUp ); 47270 47271 // target 47272 47273 addLine( 'c', 't', colorTarget ); 47274 addLine( 'p', 'c', colorCross ); 47275 47276 // cross 47277 47278 addLine( 'cn1', 'cn2', colorCross ); 47279 addLine( 'cn3', 'cn4', colorCross ); 47280 47281 addLine( 'cf1', 'cf2', colorCross ); 47282 addLine( 'cf3', 'cf4', colorCross ); 47283 47284 function addLine( a, b, color ) { 47285 47286 addPoint( a, color ); 47287 addPoint( b, color ); 47288 47289 } 47290 47291 function addPoint( id, color ) { 47292 47293 vertices.push( 0, 0, 0 ); 47294 colors.push( color.r, color.g, color.b ); 47295 47296 if ( pointMap[ id ] === undefined ) { 47297 47298 pointMap[ id ] = []; 47299 47300 } 47301 47302 pointMap[ id ].push( ( vertices.length / 3 ) - 1 ); 47303 47304 } 47305 47306 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 47307 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); 47308 47309 LineSegments.call( this, geometry, material ); 47310 47311 this.type = 'CameraHelper'; 47312 47313 this.camera = camera; 47314 if ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix(); 47315 47316 this.matrix = camera.matrixWorld; 47317 this.matrixAutoUpdate = false;
47318 47319 this.pointMap = pointMap; 47320 47321 this.update(); 47322 47323} 47324 47325CameraHelper.prototype = Object.create( LineSegments.prototype ); 47326CameraHelper.prototype.constructor = CameraHelper; 47327 47328CameraHelper.prototype.update = function () { 47329 47330 var geometry = this.geometry; 47331 var pointMap = this.pointMap; 47332 47333 var w = 1, h = 1; 47334 47335 // we need just camera projection matrix inverse 47336 // world matrix must be identity 47337 47338 _camera.projectionMatrixInverse.copy( this.camera.projectionMatrixInverse ); 47339 47340 // center / target 47341 47342 setPoint( 'c', pointMap, geometry, _camera, 0, 0, - 1 ); 47343 setPoint( 't', pointMap, geometry, _camera, 0, 0, 1 ); 47344 47345 // near 47346 47347 setPoint( 'n1', pointMap, geometry, _camera, - w, - h, - 1 ); 47348 setPoint( 'n2', pointMap, geometry, _camera, w, - h, - 1 ); 47349 setPoint( 'n3', pointMap, geometry, _camera, - w, h, - 1 ); 47350 setPoint( 'n4', pointMap, geometry, _camera, w, h, - 1 ); 47351 47352 // far 47353 47354 setPoint( 'f1', pointMap, geometry, _camera, - w, - h, 1 ); 47355 setPoint( 'f2', pointMap, geometry, _camera, w, - h, 1 ); 47356 setPoint( 'f3', pointMap, geometry, _camera, - w, h, 1 ); 47357 setPoint( 'f4', pointMap, geometry, _camera, w, h, 1 ); 47358 47359 // up 47360 47361 setPoint( 'u1', pointMap, geometry, _camera, w * 0.7, h * 1.1, - 1 ); 47362 setPoint( 'u2', pointMap, geometry, _camera, - w * 0.7, h * 1.1, - 1 ); 47363 setPoint( 'u3', pointMap, geometry, _camera, 0, h * 2, - 1 ); 47364 47365 // cross 47366 47367 setPoint( 'cf1', pointMap, geometry, _camera, - w, 0, 1 ); 47368 setPoint( 'cf2', pointMap, geometry, _camera, w, 0, 1 ); 47369 setPoint( 'cf3', pointMap, geometry, _camera, 0, - h, 1 ); 47370 setPoint( 'cf4', pointMap, geometry, _camera, 0, h, 1 ); 47371 47372 setPoint( 'cn1', pointMap, geometry, _camera, - w, 0, - 1 ); 47373 setPoint( 'cn2', pointMap, geometry, _camera, w, 0, - 1 ); 47374 setPoint( 'cn3', pointMap, geometry, _camera, 0, - h, - 1 ); 47375 setPoint( 'cn4', pointMap, geometry, _camera, 0, h, - 1 ); 47376 47377 geometry.getAttribute( 'position' ).needsUpdate = true; 47378 47379}; 47380 47381function setPoint( point, pointMap, geometry, camera, x, y, z ) { 47382 47383 _vector$b.set( x, y, z ).unproject( camera ); 47384 47385 var points = pointMap[ point ]; 47386 47387 if ( points !== undefined ) { 47388 47389 var position = geometry.getAttribute( 'position' ); 47390 47391 for ( var i = 0, l = points.length; i < l; i ++ ) { 47392 47393 position.setXYZ( points[ i ], _vector$b.x, _vector$b.y, _vector$b.z ); 47394 47395 } 47396 47397 } 47398 47399} 47400 47401/** 47402 * @author mrdoob / http://mrdoob.com/ 47403 * @author Mugen87 / http://github.com/Mugen87 47404 */ 47405 47406var _box$3 = new Box3(); 47407 47408function BoxHelper( object, color ) { 47409 47410 this.object = object; 47411 47412 if ( color === undefined ) color = 0xffff00; 47413 47414 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 ] ); 47415 var positions = new Float32Array( 8 * 3 ); 47416 47417 var geometry = new BufferGeometry(); 47418 geometry.setIndex( new BufferAttribute( indices, 1 ) ); 47419 geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) ); 47420 47421 LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) ); 47422 47423 this.type = 'BoxHelper'; 47424 47425 this.matrixAutoUpdate = false; 47426 47427 this.update(); 47428 47429} 47430 47431BoxHelper.prototype = Object.create( LineSegments.prototype ); 47432BoxHelper.prototype.constructor = BoxHelper; 47433 47434BoxHelper.prototype.update = function ( object ) { 47435 47436 if ( object !== undefined ) { 47437 47438 console.warn( 'THREE.BoxHelper: .update() has no longer arguments.' ); 47439 47440 } 47441 47442 if ( this.object !== undefined ) { 47443 47444 _box$3.setFromObject( this.object ); 47445 47446 } 47447 47448 if ( _box$3.isEmpty() ) return; 47449 47450 var min = _box$3.min; 47451 var max = _box$3.max; 47452 47453 /* 47454 5____4 47455 1/___0/| 47456 | 6__|_7 47457 2/___3/ 47458 47459 0: max.x, max.y, max.z 47460 1: min.x, max.y, max.z 47461 2: min.x, min.y, max.z 47462 3: max.x, min.y, max.z 47463 4: max.x, max.y, min.z 47464 5: min.x, max.y, min.z 47465 6: min.x, min.y, min.z 47466 7: max.x, min.y, min.z 47467 */ 47468 47469 var position = this.geometry.attributes.position; 47470 var array = position.array; 47471 47472 array[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z; 47473 array[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z; 47474 array[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z; 47475 array[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z; 47476 array[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z; 47477 array[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z; 47478 array[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z; 47479 array[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z; 47480 47481 position.needsUpdate = true; 47482 47483 this.geometry.computeBoundingSphere(); 47484 47485 47486}; 47487 47488BoxHelper.prototype.setFromObject = function ( object ) { 47489 47490 this.object = object; 47491 this.update(); 47492 47493 return this; 47494 47495}; 47496 47497BoxHelper.prototype.copy = function ( source ) { 47498 47499 LineSegments.prototype.copy.call( this, source ); 47500 47501 this.object = source.object; 47502 47503 return this; 47504 47505}; 47506 47507BoxHelper.prototype.clone = function () { 47508 47509 return new this.constructor().copy( this ); 47510 47511}; 47512 47513/** 47514 * @author WestLangley / http://github.com/WestLangley 47515 */ 47516 47517function Box3Helper( box, color ) { 47518 47519 this.type = 'Box3Helper'; 47520 47521 this.box = box; 47522 47523 color = color || 0xffff00; 47524 47525 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 ] ); 47526 47527 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 ]; 47528 47529 var geometry = new BufferGeometry(); 47530 47531 geometry.setIndex( new BufferAttribute( indices, 1 ) ); 47532 47533 geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); 47534 47535 LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) ); 47536 47537 this.type = 'Box3Helper'; 47538 47539 this.geometry.computeBoundingSphere(); 47540 47541} 47542 47543Box3Helper.prototype = Object.create( LineSegments.prototype ); 47544Box3Helper.prototype.constructor = Box3Helper; 47545 47546Box3Helper.prototype.updateMatrixWorld = function ( force ) { 47547 47548 var box = this.box; 47549 47550 if ( box.isEmpty() ) return; 47551 47552 box.getCenter( this.position ); 47553 47554 box.getSize( this.scale ); 47555 47556 this.scale.multiplyScalar( 0.5 ); 47557 47558 Object3D.prototype.updateMatrixWorld.call( this, force ); 47559 47560}; 47561 47562/** 47563 * @author WestLangley / http://github.com/WestLangley 47564 */ 47565 47566function PlaneHelper( plane, size, hex ) { 47567 47568 this.plane = plane; 47569 47570 this.size = ( size === undefined ) ? 1 : size; 47571 47572 var color = ( hex !== undefined ) ? hex : 0xffff00; 47573 47574 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 ]; 47575 47576 var geometry = new BufferGeometry(); 47577 geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); 47578 geometry.computeBoundingSphere(); 47579 47580 Line.call( this, geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) ); 47581 47582 this.type = 'PlaneHelper'; 47583 47584 // 47585 47586 var positions2 = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, - 1, 1, 1, - 1, 1 ]; 47587 47588 var geometry2 = new BufferGeometry(); 47589 geometry2.setAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) ); 47590 geometry2.computeBoundingSphere(); 47591 47592 this.add( new Mesh( geometry2, new MeshBasicMaterial( { color: color, opacity: 0.2, transparent: true, depthWrite: false, toneMapped: false } ) ) ); 47593 47594} 47595 47596PlaneHelper.prototype = Object.create( Line.prototype ); 47597PlaneHelper.prototype.constructor = PlaneHelper; 47598 47599PlaneHelper.prototype.updateMatrixWorld = function ( force ) { 47600 47601 var scale = - this.plane.constant; 47602 47603 if ( Math.abs( scale ) < 1e-8 ) scale = 1e-8; // sign does not matter 47604 47605 this.scale.set( 0.5 * this.size, 0.5 * this.size, scale ); 47606 47607 this.children[ 0 ].material.side = ( scale < 0 ) ? BackSide : FrontSide; // renderer flips side when determinant < 0; flipping not wanted here 47608 47609 this.lookAt( this.plane.normal ); 47610 47611 Object3D.prototype.updateMatrixWorld.call( this, force ); 47612 47613}; 47614 47615/** 47616 * @author WestLangley / http://github.com/WestLangley 47617 * @author zz85 / http://github.com/zz85 47618 * @author bhouston / http://clara.io 47619 * 47620 * Creates an arrow for visualizing directions 47621 * 47622 * Parameters: 47623 * dir - Vector3 47624 * origin - Vector3 47625 * length - Number 47626 * color - color in hex value 47627 * headLength - Number 47628 * headWidth - Number 47629 */ 47630 47631var _axis = new Vector3(); 47632var _lineGeometry, _coneGeometry; 47633 47634function ArrowHelper( dir, origin, length, color, headLength, headWidth ) { 47635 47636 // dir is assumed to be normalized 47637 47638 Object3D.call( this ); 47639 47640 this.type = 'ArrowHelper'; 47641 47642 if ( dir === undefined ) dir = new Vector3( 0, 0, 1 ); 47643 if ( origin === undefined ) origin = new Vector3( 0, 0, 0 ); 47644 if ( length === undefined ) length = 1; 47645 if ( color === undefined ) color = 0xffff00; 47646 if ( headLength === undefined ) headLength = 0.2 * length; 47647 if ( headWidth === undefined ) headWidth = 0.2 * headLength; 47648 47649 if ( _lineGeometry === undefined ) { 47650 47651 _lineGeometry = new BufferGeometry(); 47652 _lineGeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) ); 47653 47654 _coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 ); 47655 _coneGeometry.translate( 0, - 0.5, 0 ); 47656 47657 } 47658 47659 this.position.copy( origin ); 47660 47661 this.line = new Line( _lineGeometry, new LineBasicMaterial( { color: color, toneMapped: false } ) ); 47662 this.line.matrixAutoUpdate = false;
47663 this.add( this.line ); 47664 47665 this.cone = new Mesh( _coneGeometry, new MeshBasicMaterial( { color: color, toneMapped: false } ) ); 47666 this.cone.matrixAutoUpdate = false; 47667 this.add( this.cone ); 47668 47669 this.setDirection( dir ); 47670 this.setLength( length, headLength, headWidth ); 47671 47672} 47673 47674ArrowHelper.prototype = Object.create( Object3D.prototype ); 47675ArrowHelper.prototype.constructor = ArrowHelper; 47676 47677ArrowHelper.prototype.setDirection = function ( dir ) { 47678 47679 // dir is assumed to be normalized 47680 47681 if ( dir.y > 0.99999 ) { 47682 47683 this.quaternion.set( 0, 0, 0, 1 ); 47684 47685 } else if ( dir.y < - 0.99999 ) { 47686 47687 this.quaternion.set( 1, 0, 0, 0 ); 47688 47689 } else { 47690 47691 _axis.set( dir.z, 0, - dir.x ).normalize(); 47692 47693 var radians = Math.acos( dir.y ); 47694 47695 this.quaternion.setFromAxisAngle( _axis, radians ); 47696 47697 } 47698 47699}; 47700 47701ArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) { 47702 47703 if ( headLength === undefined ) headLength = 0.2 * length; 47704 if ( headWidth === undefined ) headWidth = 0.2 * headLength; 47705 47706 this.line.scale.set( 1, Math.max( 0.0001, length - headLength ), 1 ); // see #17458 47707 this.line.updateMatrix(); 47708 47709 this.cone.scale.set( headWidth, headLength, headWidth ); 47710 this.cone.position.y = length; 47711 this.cone.updateMatrix(); 47712 47713}; 47714 47715ArrowHelper.prototype.setColor = function ( color ) { 47716 47717 this.line.material.color.set( color ); 47718 this.cone.material.color.set( color ); 47719 47720}; 47721 47722ArrowHelper.prototype.copy = function ( source ) { 47723 47724 Object3D.prototype.copy.call( this, source, false ); 47725 47726 this.line.copy( source.line ); 47727 this.cone.copy( source.cone ); 47728 47729 return this; 47730 47731}; 47732 47733ArrowHelper.prototype.clone = function () { 47734 47735 return new this.constructor().copy( this ); 47736 47737}; 47738 47739/** 47740 * @author sroucheray / http://sroucheray.org/ 47741 * @author mrdoob / http://mrdoob.com/ 47742 */ 47743 47744function AxesHelper( size ) { 47745 47746 size = size || 1; 47747 47748 var vertices = [ 47749 0, 0, 0, size, 0, 0, 47750 0, 0, 0, 0, size, 0, 47751 0, 0, 0, 0, 0, size 47752 ]; 47753 47754 var colors = [ 47755 1, 0, 0, 1, 0.6, 0, 47756 0, 1, 0, 0.6, 1, 0, 47757 0, 0, 1, 0, 0.6, 1 47758 ]; 47759 47760 var geometry = new BufferGeometry(); 47761 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 47762 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); 47763 47764 var material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } ); 47765 47766 LineSegments.call( this, geometry, material ); 47767 47768 this.type = 'AxesHelper'; 47769 47770} 47771 47772AxesHelper.prototype = Object.create( LineSegments.prototype ); 47773AxesHelper.prototype.constructor = AxesHelper; 47774 47775/** 47776 * @author Emmett Lalish / elalish 47777 * 47778 * This class generates a Prefiltered, Mipmapped Radiance Environment Map 47779 * (PMREM) from a cubeMap environment texture. This allows different levels of 47780 * blur to be quickly accessed based on material roughness. It is packed into a 47781 * special CubeUV format that allows us to perform custom interpolation so that 47782 * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap 47783 * chain, it only goes down to the LOD_MIN level (above), and then creates extra 47784 * even more filtered 'mips' at the same LOD_MIN resolution, associated with 47785 * higher roughness levels. In this way we maintain resolution to smoothly 47786 * interpolate diffuse lighting while limiting sampling computation. 47787 */ 47788 47789var LOD_MIN = 4; 47790var LOD_MAX = 8; 47791var SIZE_MAX = Math.pow( 2, LOD_MAX ); 47792 47793// The standard deviations (radians) associated with the extra mips. These are 47794// chosen to approximate a Trowbridge-Reitz distribution function times the 47795// geometric shadowing function. These sigma values squared must match the 47796// variance #defines in cube_uv_reflection_fragment.glsl.js. 47797var EXTRA_LOD_SIGMA = [ 0.125, 0.215, 0.35, 0.446, 0.526, 0.582 ]; 47798 47799var TOTAL_LODS = LOD_MAX - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; 47800 47801// The maximum length of the blur for loop. Smaller sigmas will use fewer 47802// samples and exit early, but not recompile the shader. 47803var MAX_SAMPLES = 20; 47804 47805var ENCODINGS = { 47806 [ LinearEncoding ]: 0, 47807 [ sRGBEncoding ]: 1, 47808 [ RGBEEncoding ]: 2, 47809 [ RGBM7Encoding ]: 3, 47810 [ RGBM16Encoding ]: 4, 47811 [ RGBDEncoding ]: 5, 47812 [ GammaEncoding ]: 6 47813}; 47814 47815var _flatCamera = new OrthographicCamera(); 47816var { _lodPlanes, _sizeLods, _sigmas } = _createPlanes(); 47817var _oldTarget = null; 47818 47819// Golden Ratio 47820var PHI = ( 1 + Math.sqrt( 5 ) ) / 2; 47821var INV_PHI = 1 / PHI; 47822 47823// Vertices of a dodecahedron (except the opposites, which represent the 47824// same axis), used as axis directions evenly spread on a sphere. 47825var _axisDirections = [ 47826 new Vector3( 1, 1, 1 ), 47827 new Vector3( - 1, 1, 1 ), 47828 new Vector3( 1, 1, - 1 ), 47829 new Vector3( - 1, 1, - 1 ), 47830 new Vector3( 0, PHI, INV_PHI ), 47831 new Vector3( 0, PHI, - INV_PHI ), 47832 new Vector3( INV_PHI, 0, PHI ), 47833 new Vector3( - INV_PHI, 0, PHI ), 47834 new Vector3( PHI, INV_PHI, 0 ), 47835 new Vector3( - PHI, INV_PHI, 0 ) ]; 47836 47837function PMREMGenerator( renderer ) { 47838 47839 this._renderer = renderer; 47840 this._pingPongRenderTarget = null; 47841 47842 this._blurMaterial = _getBlurShader( MAX_SAMPLES ); 47843 this._equirectShader = null; 47844 this._cubemapShader = null; 47845 47846 this._compileMaterial( this._blurMaterial ); 47847 47848} 47849 47850PMREMGenerator.prototype = { 47851 47852 constructor: PMREMGenerator, 47853 47854 /** 47855 * Generates a PMREM from a supplied Scene, which can be faster than using an 47856 * image if networking bandwidth is low. Optional sigma specifies a blur radius 47857 * in radians to be applied to the scene before PMREM generation. Optional near 47858 * and far planes ensure the scene is rendered in its entirety (the cubeCamera 47859 * is placed at the origin). 47860 */ 47861 fromScene: function ( scene, sigma = 0, near = 0.1, far = 100 ) { 47862 47863 _oldTarget = this._renderer.getRenderTarget(); 47864 var cubeUVRenderTarget = this._allocateTargets(); 47865 47866 this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget ); 47867 if ( sigma > 0 ) { 47868 47869 this._blur( cubeUVRenderTarget, 0, 0, sigma ); 47870 47871 } 47872 47873 this._applyPMREM( cubeUVRenderTarget ); 47874 this._cleanup( cubeUVRenderTarget ); 47875 47876 return cubeUVRenderTarget; 47877 47878 }, 47879 47880 /** 47881 * Generates a PMREM from an equirectangular texture, which can be either LDR 47882 * (RGBFormat) or HDR (RGBEFormat). The ideal input image size is 1k (1024 x 512), 47883 * as this matches best with the 256 x 256 cubemap output. 47884 */ 47885 fromEquirectangular: function ( equirectangular ) { 47886 47887 equirectangular.magFilter = NearestFilter; 47888 equirectangular.minFilter = NearestFilter; 47889 equirectangular.generateMipmaps = false;
47890 47891 return this.fromCubemap( equirectangular ); 47892 47893 }, 47894 47895 /** 47896 * Generates a PMREM from an cubemap texture, which can be either LDR 47897 * (RGBFormat) or HDR (RGBEFormat). The ideal input cube size is 256 x 256, 47898 * as this matches best with the 256 x 256 cubemap output. 47899 */ 47900 fromCubemap: function ( cubemap ) { 47901 47902 _oldTarget = this._renderer.getRenderTarget(); 47903 var cubeUVRenderTarget = this._allocateTargets( cubemap ); 47904 this._textureToCubeUV( cubemap, cubeUVRenderTarget ); 47905 this._applyPMREM( cubeUVRenderTarget ); 47906 this._cleanup( cubeUVRenderTarget ); 47907 47908 return cubeUVRenderTarget; 47909 47910 }, 47911 47912 /** 47913 * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during 47914 * your texture's network fetch for increased concurrency. 47915 */ 47916 compileCubemapShader: function () { 47917 47918 if ( this._cubemapShader === null ) { 47919 47920 this._cubemapShader = _getCubemapShader(); 47921 this._compileMaterial( this._cubemapShader ); 47922 47923 } 47924 47925 }, 47926 47927 /** 47928 * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during 47929 * your texture's network fetch for increased concurrency. 47930 */ 47931 compileEquirectangularShader: function () { 47932 47933 if ( this._equirectShader === null ) { 47934 47935 this._equirectShader = _getEquirectShader(); 47936 this._compileMaterial( this._equirectShader ); 47937 47938 } 47939 47940 }, 47941 47942 /** 47943 * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, 47944 * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on 47945 * one of them will cause any others to also become unusable. 47946 */ 47947 dispose: function () { 47948 47949 this._blurMaterial.dispose(); 47950 47951 if ( this._cubemapShader !== null ) this._cubemapShader.dispose(); 47952 if ( this._equirectShader !== null ) this._equirectShader.dispose(); 47953 47954 for ( var i = 0; i < _lodPlanes.length; i ++ ) { 47955 47956 _lodPlanes[ i ].dispose(); 47957 47958 } 47959 47960 }, 47961 47962 // private interface 47963 47964 _cleanup: function ( outputTarget ) { 47965 47966 this._pingPongRenderTarget.dispose(); 47967 this._renderer.setRenderTarget( _oldTarget ); 47968 outputTarget.scissorTest = false; 47969 // reset viewport and scissor 47970 outputTarget.setSize( outputTarget.width, outputTarget.height ); 47971 47972 }, 47973 47974 _allocateTargets: function ( equirectangular ) { 47975 47976 var params = { 47977 magFilter: NearestFilter, 47978 minFilter: NearestFilter, 47979 generateMipmaps: false, 47980 type: UnsignedByteType, 47981 format: RGBEFormat, 47982 encoding: _isLDR( equirectangular ) ? equirectangular.encoding : RGBEEncoding, 47983 depthBuffer: false, 47984 stencilBuffer: false 47985 }; 47986 47987 var cubeUVRenderTarget = _createRenderTarget( params ); 47988 cubeUVRenderTarget.depthBuffer = equirectangular ? false : true; 47989 this._pingPongRenderTarget = _createRenderTarget( params ); 47990 return cubeUVRenderTarget; 47991 47992 }, 47993 47994 _compileMaterial: function ( material ) { 47995 47996 var tmpScene = new Scene(); 47997 tmpScene.add( new Mesh( _lodPlanes[ 0 ], material ) ); 47998 this._renderer.compile( tmpScene, _flatCamera ); 47999 48000 }, 48001 48002 _sceneToCubeUV: function ( scene, near, far, cubeUVRenderTarget ) { 48003 48004 var fov = 90; 48005 var aspect = 1; 48006 var cubeCamera = new PerspectiveCamera( fov, aspect, near, far ); 48007 var upSign = [ 1, 1, 1, 1, - 1, 1 ]; 48008 var forwardSign = [ 1, 1, - 1, - 1, - 1, 1 ]; 48009 var renderer = this._renderer; 48010 48011 var outputEncoding = renderer.outputEncoding; 48012 var toneMapping = renderer.toneMapping; 48013 var toneMappingExposure = renderer.toneMappingExposure; 48014 var clearColor = renderer.getClearColor(); 48015 var clearAlpha = renderer.getClearAlpha(); 48016 48017 renderer.toneMapping = LinearToneMapping; 48018 renderer.toneMappingExposure = 1.0; 48019 renderer.outputEncoding = LinearEncoding; 48020 scene.scale.z *= - 1; 48021 48022 var background = scene.background; 48023 if ( background && background.isColor ) { 48024 48025 background.convertSRGBToLinear(); 48026 // Convert linear to RGBE 48027 var maxComponent = Math.max( background.r, background.g, background.b ); 48028 var fExp = Math.min( Math.max( Math.ceil( Math.log2( maxComponent ) ), - 128.0 ), 127.0 ); 48029 background = background.multiplyScalar( Math.pow( 2.0, - fExp ) ); 48030 var alpha = ( fExp + 128.0 ) / 255.0;
vendor: 9,285 bytes, lines 48031-48400
48031 renderer.setClearColor( background, alpha ); 48032 scene.background = null; 48033 48034 } 48035 48036 for ( var i = 0; i < 6; i ++ ) { 48037 48038 var col = i % 3; 48039 if ( col == 0 ) { 48040 48041 cubeCamera.up.set( 0, upSign[ i ], 0 ); 48042 cubeCamera.lookAt( forwardSign[ i ], 0, 0 ); 48043 48044 } else if ( col == 1 ) { 48045 48046 cubeCamera.up.set( 0, 0, upSign[ i ] ); 48047 cubeCamera.lookAt( 0, forwardSign[ i ], 0 ); 48048 48049 } else { 48050 48051 cubeCamera.up.set( 0, upSign[ i ], 0 ); 48052 cubeCamera.lookAt( 0, 0, forwardSign[ i ] ); 48053 48054 } 48055 48056 _setViewport( cubeUVRenderTarget, 48057 col * SIZE_MAX, i > 2 ? SIZE_MAX : 0, SIZE_MAX, SIZE_MAX ); 48058 renderer.setRenderTarget( cubeUVRenderTarget ); 48059 renderer.render( scene, cubeCamera ); 48060 48061 } 48062 48063 renderer.toneMapping = toneMapping; 48064 renderer.toneMappingExposure = toneMappingExposure; 48065 renderer.outputEncoding = outputEncoding; 48066 renderer.setClearColor( clearColor, clearAlpha ); 48067 scene.scale.z *= - 1; 48068 48069 }, 48070 48071 _textureToCubeUV: function ( texture, cubeUVRenderTarget ) { 48072 48073 var scene = new Scene(); 48074 var renderer = this._renderer; 48075 48076 if ( texture.isCubeTexture ) { 48077 48078 if ( this._cubemapShader == null ) { 48079 48080 this._cubemapShader = _getCubemapShader(); 48081 48082 } 48083 48084 } else { 48085 48086 if ( this._equirectShader == null ) { 48087 48088 this._equirectShader = _getEquirectShader(); 48089 48090 } 48091 48092 } 48093 48094 var material = texture.isCubeTexture ? this._cubemapShader : this._equirectShader; 48095 scene.add( new Mesh( _lodPlanes[ 0 ], material ) ); 48096 48097 var uniforms = material.uniforms; 48098 48099 uniforms[ 'envMap' ].value = texture; 48100 48101 if ( ! texture.isCubeTexture ) { 48102 48103 uniforms[ 'texelSize' ].value.set( 1.0 / texture.image.width, 1.0 / texture.image.height ); 48104 48105 } 48106 48107 uniforms[ 'inputEncoding' ].value = ENCODINGS[ texture.encoding ]; 48108 uniforms[ 'outputEncoding' ].value = ENCODINGS[ cubeUVRenderTarget.texture.encoding ]; 48109 48110 _setViewport( cubeUVRenderTarget, 0, 0, 3 * SIZE_MAX, 2 * SIZE_MAX ); 48111 48112 renderer.setRenderTarget( cubeUVRenderTarget ); 48113 renderer.render( scene, _flatCamera ); 48114 48115 }, 48116 48117 _applyPMREM: function ( cubeUVRenderTarget ) { 48118 48119 var renderer = this._renderer; 48120 var autoClear = renderer.autoClear; 48121 renderer.autoClear = false; 48122 48123 for ( var i = 1; i < TOTAL_LODS; i ++ ) { 48124 48125 var sigma = Math.sqrt( _sigmas[ i ] * _sigmas[ i ] - _sigmas[ i - 1 ] * _sigmas[ i - 1 ] ); 48126 48127 var poleAxis = _axisDirections[ ( i - 1 ) % _axisDirections.length ]; 48128 48129 this._blur( cubeUVRenderTarget, i - 1, i, sigma, poleAxis ); 48130 48131 } 48132 48133 renderer.autoClear = autoClear; 48134 48135 }, 48136 48137 /** 48138 * This is a two-pass Gaussian blur for a cubemap. Normally this is done 48139 * vertically and horizontally, but this breaks down on a cube. Here we apply 48140 * the blur latitudinally (around the poles), and then longitudinally (towards 48141 * the poles) to approximate the orthogonally-separable blur. It is least 48142 * accurate at the poles, but still does a decent job. 48143 */ 48144 _blur: function ( cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis ) { 48145 48146 var pingPongRenderTarget = this._pingPongRenderTarget; 48147 48148 this._halfBlur( 48149 cubeUVRenderTarget, 48150 pingPongRenderTarget, 48151 lodIn, 48152 lodOut, 48153 sigma, 48154 'latitudinal', 48155 poleAxis ); 48156 48157 this._halfBlur( 48158 pingPongRenderTarget, 48159 cubeUVRenderTarget, 48160 lodOut, 48161 lodOut, 48162 sigma, 48163 'longitudinal', 48164 poleAxis ); 48165 48166 }, 48167 48168 _halfBlur: function ( targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis ) { 48169 48170 var renderer = this._renderer; 48171 var blurMaterial = this._blurMaterial; 48172 48173 if ( direction !== 'latitudinal' && direction !== 'longitudinal' ) { 48174 48175 console.error( 48176 'blur direction must be either latitudinal or longitudinal!' ); 48177 48178 } 48179 48180 // Number of standard deviations at which to cut off the discrete approximation. 48181 var STANDARD_DEVIATIONS = 3; 48182 48183 var blurScene = new Scene(); 48184 blurScene.add( new Mesh( _lodPlanes[ lodOut ], blurMaterial ) ); 48185 var blurUniforms = blurMaterial.uniforms; 48186 48187 var pixels = _sizeLods[ lodIn ] - 1; 48188 var radiansPerPixel = isFinite( sigmaRadians ) ? Math.PI / ( 2 * pixels ) : 2 * Math.PI / ( 2 * MAX_SAMPLES - 1 ); 48189 var sigmaPixels = sigmaRadians / radiansPerPixel; 48190 var samples = isFinite( sigmaRadians ) ? 1 + Math.floor( STANDARD_DEVIATIONS * sigmaPixels ) : MAX_SAMPLES; 48191 48192 if ( samples > MAX_SAMPLES ) { 48193 48194 console.warn( `sigmaRadians, ${ 48195 sigmaRadians}, is too large and will clip, as it requested ${ 48196 samples} samples when the maximum is set to ${MAX_SAMPLES}` ); 48197 48198 } 48199 48200 var weights = []; 48201 var sum = 0; 48202 48203 for ( var i = 0; i < MAX_SAMPLES; ++ i ) { 48204 48205 var x = i / sigmaPixels; 48206 var weight = Math.exp( - x * x / 2 ); 48207 weights.push( weight ); 48208 48209 if ( i == 0 ) { 48210 48211 sum += weight; 48212 48213 } else if ( i < samples ) { 48214 48215 sum += 2 * weight; 48216 48217 } 48218 48219 } 48220 48221 for ( var i = 0; i < weights.length; i ++ ) { 48222 48223 weights[ i ] = weights[ i ] / sum; 48224 48225 } 48226 48227 blurUniforms[ 'envMap' ].value = targetIn.texture; 48228 blurUniforms[ 'samples' ].value = samples; 48229 blurUniforms[ 'weights' ].value = weights; 48230 blurUniforms[ 'latitudinal' ].value = direction === 'latitudinal'; 48231 48232 if ( poleAxis ) { 48233 48234 blurUniforms[ 'poleAxis' ].value = poleAxis; 48235 48236 } 48237 48238 blurUniforms[ 'dTheta' ].value = radiansPerPixel; 48239 blurUniforms[ 'mipInt' ].value = LOD_MAX - lodIn; 48240 blurUniforms[ 'inputEncoding' ].value = ENCODINGS[ targetIn.texture.encoding ]; 48241 blurUniforms[ 'outputEncoding' ].value = ENCODINGS[ targetIn.texture.encoding ]; 48242 48243 var outputSize = _sizeLods[ lodOut ]; 48244 var x = 3 * Math.max( 0, SIZE_MAX - 2 * outputSize ); 48245 var y = ( lodOut === 0 ? 0 : 2 * SIZE_MAX ) + 2 * outputSize * ( lodOut > LOD_MAX - LOD_MIN ? lodOut - LOD_MAX + LOD_MIN : 0 ); 48246 48247 _setViewport( targetOut, x, y, 3 * outputSize, 2 * outputSize ); 48248 renderer.setRenderTarget( targetOut ); 48249 renderer.render( blurScene, _flatCamera ); 48250 48251 } 48252 48253}; 48254 48255function _isLDR( texture ) { 48256 48257 if ( texture === undefined || texture.type !== UnsignedByteType ) return false; 48258 48259 return texture.encoding === LinearEncoding || texture.encoding === sRGBEncoding || texture.encoding === GammaEncoding; 48260 48261} 48262 48263function _createPlanes() { 48264 48265 var _lodPlanes = []; 48266 var _sizeLods = []; 48267 var _sigmas = []; 48268 48269 var lod = LOD_MAX; 48270 48271 for ( var i = 0; i < TOTAL_LODS; i ++ ) { 48272 48273 var sizeLod = Math.pow( 2, lod ); 48274 _sizeLods.push( sizeLod ); 48275 var sigma = 1.0 / sizeLod; 48276 48277 if ( i > LOD_MAX - LOD_MIN ) { 48278 48279 sigma = EXTRA_LOD_SIGMA[ i - LOD_MAX + LOD_MIN - 1 ]; 48280 48281 } else if ( i == 0 ) { 48282 48283 sigma = 0; 48284 48285 } 48286 48287 _sigmas.push( sigma ); 48288 48289 var texelSize = 1.0 / ( sizeLod - 1 ); 48290 var min = - texelSize / 2; 48291 var max = 1 + texelSize / 2; 48292 var uv1 = [ min, min, max, min, max, max, min, min, max, max, min, max ]; 48293 48294 var cubeFaces = 6; 48295 var vertices = 6; 48296 var positionSize = 3; 48297 var uvSize = 2; 48298 var faceIndexSize = 1; 48299 48300 var position = new Float32Array( positionSize * vertices * cubeFaces ); 48301 var uv = new Float32Array( uvSize * vertices * cubeFaces ); 48302 var faceIndex = new Float32Array( faceIndexSize * vertices * cubeFaces ); 48303 48304 for ( var face = 0; face < cubeFaces; face ++ ) { 48305 48306 var x = ( face % 3 ) * 2 / 3 - 1; 48307 var y = face > 2 ? 0 : - 1; 48308 var coordinates = [ 48309 x, y, 0, 48310 x + 2 / 3, y, 0, 48311 x + 2 / 3, y + 1, 0, 48312 x, y, 0, 48313 x + 2 / 3, y + 1, 0, 48314 x, y + 1, 0 48315 ]; 48316 position.set( coordinates, positionSize * vertices * face ); 48317 uv.set( uv1, uvSize * vertices * face ); 48318 var fill = [ face, face, face, face, face, face ]; 48319 faceIndex.set( fill, faceIndexSize * vertices * face ); 48320 48321 } 48322 48323 var planes = new BufferGeometry(); 48324 planes.setAttribute( 'position', new BufferAttribute( position, positionSize ) ); 48325 planes.setAttribute( 'uv', new BufferAttribute( uv, uvSize ) ); 48326 planes.setAttribute( 'faceIndex', new BufferAttribute( faceIndex, faceIndexSize ) ); 48327 _lodPlanes.push( planes ); 48328 48329 if ( lod > LOD_MIN ) { 48330 48331 lod --; 48332 48333 } 48334 48335 } 48336 48337 return { _lodPlanes, _sizeLods, _sigmas }; 48338 48339} 48340 48341function _createRenderTarget( params ) { 48342 48343 var cubeUVRenderTarget = new WebGLRenderTarget( 3 * SIZE_MAX, 3 * SIZE_MAX, params ); 48344 cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; 48345 cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; 48346 cubeUVRenderTarget.scissorTest = true; 48347 return cubeUVRenderTarget; 48348 48349} 48350 48351function _setViewport( target, x, y, width, height ) { 48352 48353 target.viewport.set( x, y, width, height ); 48354 target.scissor.set( x, y, width, height ); 48355 48356} 48357 48358function _getBlurShader( maxSamples ) { 48359 48360 var weights = new Float32Array( maxSamples ); 48361 var poleAxis = new Vector3( 0, 1, 0 ); 48362 var shaderMaterial = new RawShaderMaterial( { 48363 48364 defines: { 'n': maxSamples }, 48365 48366 uniforms: { 48367 'envMap': { value: null }, 48368 'samples': { value: 1 }, 48369 'weights': { value: weights }, 48370 'latitudinal': { value: false }, 48371 'dTheta': { value: 0 }, 48372 'mipInt': { value: 0 }, 48373 'poleAxis': { value: poleAxis }, 48374 'inputEncoding': { value: ENCODINGS[ LinearEncoding ] }, 48375 'outputEncoding': { value: ENCODINGS[ LinearEncoding ] } 48376 }, 48377 48378 vertexShader: _getCommonVertexShader(), 48379 48380 fragmentShader: ` 48381precision mediump float; 48382precision mediump int; 48383varying vec3 vOutputDirection; 48384uniform sampler2D envMap; 48385uniform int samples; 48386uniform float weights[n]; 48387uniform bool latitudinal; 48388uniform float dTheta; 48389uniform float mipInt; 48390uniform vec3 poleAxis; 48391 48392${_getEncodings()} 48393 48394#define ENVMAP_TYPE_CUBE_UV 48395#include <cube_uv_reflection_fragment> 48396 48397vec3 getSample(float theta, vec3 axis) { 48398 float cosTheta = cos(theta); 48399 // Rodrigues' axis-angle rotation 48400 vec3 sampleDirection = vOutputDirection * cosTheta
48401 + cross(axis, vOutputDirection) * sin(theta) 48402 + axis * dot(axis, vOutputDirection) * (1.0 - cosTheta); 48403 return bilinearCubeUV(envMap, sampleDirection, mipInt); 48404} 48405 48406void main() { 48407 vec3 axis = latitudinal ? poleAxis : cross(poleAxis, vOutputDirection); 48408 if (all(equal(axis, vec3(0.0)))) 48409 axis = vec3(vOutputDirection.z, 0.0, - vOutputDirection.x); 48410 axis = normalize(axis); 48411 gl_FragColor = vec4(0.0); 48412 gl_FragColor.rgb += weights[0] * getSample(0.0, axis); 48413 for (int i = 1; i < n; i++) { 48414 if (i >= samples) 48415 break; 48416 float theta = dTheta * float(i); 48417 gl_FragColor.rgb += weights[i] * getSample(-1.0 * theta, axis); 48418 gl_FragColor.rgb += weights[i] * getSample(theta, axis); 48419 } 48420 gl_FragColor = linearToOutputTexel(gl_FragColor); 48421} 48422 `, 48423 48424 blending: NoBlending, 48425 depthTest: false, 48426 depthWrite: false 48427 48428 } ); 48429 48430 shaderMaterial.type = 'SphericalGaussianBlur'; 48431 48432 return shaderMaterial; 48433 48434} 48435 48436function _getEquirectShader() { 48437 48438 var texelSize = new Vector2( 1, 1 ); 48439 var shaderMaterial = new RawShaderMaterial( { 48440 48441 uniforms: { 48442 'envMap': { value: null }, 48443 'texelSize': { value: texelSize }, 48444 'inputEncoding': { value: ENCODINGS[ LinearEncoding ] }, 48445 'outputEncoding': { value: ENCODINGS[ LinearEncoding ] } 48446 }, 48447 48448 vertexShader: _getCommonVertexShader(), 48449 48450 fragmentShader: ` 48451precision mediump float; 48452precision mediump int; 48453varying vec3 vOutputDirection; 48454uniform sampler2D envMap; 48455uniform vec2 texelSize; 48456 48457${_getEncodings()} 48458 48459#define RECIPROCAL_PI 0.31830988618 48460#define RECIPROCAL_PI2 0.15915494 48461 48462void main() { 48463 gl_FragColor = vec4(0.0); 48464 vec3 outputDirection = normalize(vOutputDirection); 48465 vec2 uv; 48466 uv.y = asin(clamp(outputDirection.y, -1.0, 1.0)) * RECIPROCAL_PI + 0.5; 48467 uv.x = atan(outputDirection.z, outputDirection.x) * RECIPROCAL_PI2 + 0.5; 48468 vec2 f = fract(uv / texelSize - 0.5); 48469 uv -= f * texelSize; 48470 vec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb; 48471 uv.x += texelSize.x; 48472 vec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb; 48473 uv.y += texelSize.y; 48474 vec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb; 48475 uv.x -= texelSize.x; 48476 vec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb; 48477 vec3 tm = mix(tl, tr, f.x); 48478 vec3 bm = mix(bl, br, f.x); 48479 gl_FragColor.rgb = mix(tm, bm, f.y); 48480 gl_FragColor = linearToOutputTexel(gl_FragColor); 48481} 48482 `, 48483 48484 blending: NoBlending, 48485 depthTest: false, 48486 depthWrite: false 48487 48488 } ); 48489 48490 shaderMaterial.type = 'EquirectangularToCubeUV'; 48491 48492 return shaderMaterial; 48493 48494} 48495 48496function _getCubemapShader() { 48497 48498 var shaderMaterial = new RawShaderMaterial( { 48499 48500 uniforms: { 48501 'envMap': { value: null }, 48502 'inputEncoding': { value: ENCODINGS[ LinearEncoding ] }, 48503 'outputEncoding': { value: ENCODINGS[ LinearEncoding ] } 48504 }, 48505 48506 vertexShader: _getCommonVertexShader(), 48507 48508 fragmentShader: ` 48509precision mediump float; 48510precision mediump int; 48511varying vec3 vOutputDirection; 48512uniform samplerCube envMap; 48513 48514${_getEncodings()} 48515 48516void main() { 48517 gl_FragColor = vec4(0.0); 48518 gl_FragColor.rgb = envMapTexelToLinear(textureCube(envMap, vec3( - vOutputDirection.x, vOutputDirection.yz ))).rgb; 48519 gl_FragColor = linearToOutputTexel(gl_FragColor); 48520} 48521 `, 48522 48523 blending: NoBlending, 48524 depthTest: false, 48525 depthWrite: false 48526 48527 } ); 48528 48529 shaderMaterial.type = 'CubemapToCubeUV'; 48530 48531 return shaderMaterial; 48532 48533} 48534 48535function _getCommonVertexShader() { 48536 48537 return ` 48538precision mediump float; 48539precision mediump int; 48540attribute vec3 position; 48541attribute vec2 uv; 48542attribute float faceIndex; 48543varying vec3 vOutputDirection; 48544vec3 getDirection(vec2 uv, float face) { 48545 uv = 2.0 * uv - 1.0; 48546 vec3 direction = vec3(uv, 1.0); 48547 if (face == 0.0) { 48548 direction = direction.zyx; 48549 direction.z *= -1.0; 48550 } else if (face == 1.0) { 48551 direction = direction.xzy; 48552 direction.z *= -1.0; 48553 } else if (face == 3.0) { 48554 direction = direction.zyx; 48555 direction.x *= -1.0; 48556 } else if (face == 4.0) { 48557 direction = direction.xzy; 48558 direction.y *= -1.0; 48559 } else if (face == 5.0) { 48560 direction.xz *= -1.0; 48561 } 48562 return direction; 48563} 48564void main() { 48565 vOutputDirection = getDirection(uv, faceIndex); 48566 gl_Position = vec4( position, 1.0 ); 48567} 48568 `; 48569 48570} 48571 48572function _getEncodings() { 48573 48574 return ` 48575uniform int inputEncoding; 48576uniform int outputEncoding; 48577 48578#include <encodings_pars_fragment> 48579 48580vec4 inputTexelToLinear(vec4 value){ 48581 if(inputEncoding == 0){ 48582 return value; 48583 }else if(inputEncoding == 1){ 48584 return sRGBToLinear(value); 48585 }else if(inputEncoding == 2){ 48586 return RGBEToLinear(value); 48587 }else if(inputEncoding == 3){ 48588 return RGBMToLinear(value, 7.0); 48589 }else if(inputEncoding == 4){ 48590 return RGBMToLinear(value, 16.0); 48591 }else if(inputEncoding == 5){ 48592 return RGBDToLinear(value, 256.0); 48593 }else{ 48594 return GammaToLinear(value, 2.2); 48595 } 48596} 48597 48598vec4 linearToOutputTexel(vec4 value){ 48599 if(outputEncoding == 0){ 48600 return value; 48601 }else if(outputEncoding == 1){ 48602 return LinearTosRGB(value); 48603 }else if(outputEncoding == 2){ 48604 return LinearToRGBE(value); 48605 }else if(outputEncoding == 3){ 48606 return LinearToRGBM(value, 7.0); 48607 }else if(outputEncoding == 4){ 48608 return LinearToRGBM(value, 16.0); 48609 }else if(outputEncoding == 5){ 48610 return LinearToRGBD(value, 256.0); 48611 }else{ 48612 return LinearToGamma(value, 2.2); 48613 } 48614} 48615 48616vec4 envMapTexelToLinear(vec4 color) { 48617 return inputTexelToLinear(color); 48618} 48619 `; 48620 48621} 48622 48623/** 48624 * @author mrdoob / http://mrdoob.com/ 48625 */ 48626 48627function Face4( a, b, c, d, normal, color, materialIndex ) { 48628 48629 console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' ); 48630 return new Face3( a, b, c, normal, color, materialIndex ); 48631 48632} 48633 48634var LineStrip = 0; 48635var LinePieces = 1; 48636var NoColors = 0; 48637var FaceColors = 1; 48638var VertexColors = 2; 48639 48640function MeshFaceMaterial( materials ) { 48641 48642 console.warn( 'THREE.MeshFaceMaterial has been removed. Use an Array instead.' ); 48643 return materials; 48644 48645} 48646 48647function MultiMaterial( materials ) { 48648 48649 if ( materials === undefined ) materials = []; 48650 48651 console.warn( 'THREE.MultiMaterial has been removed. Use an Array instead.' ); 48652 materials.isMultiMaterial = true; 48653 materials.materials = materials; 48654 materials.clone = function () { 48655 48656 return materials.slice(); 48657 48658 }; 48659 48660 return materials; 48661 48662} 48663 48664function PointCloud( geometry, material ) { 48665 48666 console.warn( 'THREE.PointCloud has been renamed to THREE.Points.' ); 48667 return new Points( geometry, material ); 48668 48669} 48670 48671function Particle( material ) { 48672 48673 console.warn( 'THREE.Particle has been renamed to THREE.Sprite.' ); 48674 return new Sprite( material ); 48675 48676} 48677 48678function ParticleSystem( geometry, material ) { 48679 48680 console.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' ); 48681 return new Points( geometry, material ); 48682 48683} 48684 48685function PointCloudMaterial( parameters ) { 48686 48687 console.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' ); 48688 return new PointsMaterial( parameters ); 48689 48690} 48691 48692function ParticleBasicMaterial( parameters ) { 48693 48694 console.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' ); 48695 return new PointsMaterial( parameters ); 48696 48697} 48698 48699function ParticleSystemMaterial( parameters ) { 48700 48701 console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' ); 48702 return new PointsMaterial( parameters ); 48703 48704} 48705 48706function Vertex( x, y, z ) { 48707 48708 console.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' ); 48709 return new Vector3( x, y, z ); 48710 48711} 48712 48713// 48714 48715function DynamicBufferAttribute( array, itemSize ) { 48716 48717 console.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setUsage( THREE.DynamicDrawUsage ) instead.' ); 48718 return new BufferAttribute( array, itemSize ).setUsage( DynamicDrawUsage ); 48719 48720} 48721 48722function Int8Attribute( array, itemSize ) { 48723 48724 console.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' ); 48725 return new Int8BufferAttribute( array, itemSize ); 48726 48727} 48728 48729function Uint8Attribute( array, itemSize ) { 48730 48731 console.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' ); 48732 return new Uint8BufferAttribute( array, itemSize ); 48733 48734} 48735 48736function Uint8ClampedAttribute( array, itemSize ) { 48737 48738 console.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' ); 48739 return new Uint8ClampedBufferAttribute( array, itemSize ); 48740 48741} 48742 48743function Int16Attribute( array, itemSize ) { 48744 48745 console.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' ); 48746 return new Int16BufferAttribute( array, itemSize ); 48747 48748} 48749 48750function Uint16Attribute( array, itemSize ) { 48751 48752 console.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' ); 48753 return new Uint16BufferAttribute( array, itemSize ); 48754 48755} 48756 48757function Int32Attribute( array, itemSize ) { 48758 48759 console.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' ); 48760 return new Int32BufferAttribute( array, itemSize ); 48761 48762} 48763 48764function Uint32Attribute( array, itemSize ) { 48765 48766 console.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' ); 48767 return new Uint32BufferAttribute( array, itemSize ); 48768 48769} 48770 48771function Float32Attribute( array, itemSize ) { 48772 48773 console.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' ); 48774 return new Float32BufferAttribute( array, itemSize ); 48775 48776} 48777 48778function Float64Attribute( array, itemSize ) { 48779 48780 console.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' ); 48781 return new Float64BufferAttribute( array, itemSize ); 48782 48783} 48784 48785// 48786 48787Curve.create = function ( construct, getPoint ) { 48788 48789 console.log( 'THREE.Curve.create() has been deprecated' ); 48790 48791 construct.prototype = Object.create( Curve.prototype ); 48792 construct.prototype.constructor = construct; 48793 construct.prototype.getPoint = getPoint; 48794 48795 return construct; 48796 48797}; 48798 48799// 48800 48801Object.assign( CurvePath.prototype, { 48802 48803 createPointsGeometry: function ( divisions ) { 48804 48805 console.warn( 'THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' ); 48806 48807 // generate geometry from path points (for Line or Points objects) 48808 48809 var pts = this.getPoints( divisions ); 48810 return this.createGeometry( pts ); 48811 48812 }, 48813 48814 createSpacedPointsGeometry: function ( divisions ) { 48815 48816 console.warn( 'THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' ); 48817 48818 // generate geometry from equidistant sampling along the path 48819
48820 var pts = this.getSpacedPoints( divisions ); 48821 return this.createGeometry( pts ); 48822 48823 }, 48824 48825 createGeometry: function ( points ) { 48826 48827 console.warn( 'THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' ); 48828 48829 var geometry = new Geometry(); 48830 48831 for ( var i = 0, l = points.length; i < l; i ++ ) { 48832 48833 var point = points[ i ]; 48834 geometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) ); 48835 48836 } 48837 48838 return geometry; 48839 48840 } 48841 48842} ); 48843 48844// 48845 48846Object.assign( Path.prototype, { 48847 48848 fromPoints: function ( points ) { 48849 48850 console.warn( 'THREE.Path: .fromPoints() has been renamed to .setFromPoints().' ); 48851 return this.setFromPoints( points ); 48852 48853 } 48854 48855} ); 48856 48857// 48858 48859function ClosedSplineCurve3( points ) { 48860 48861 console.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' ); 48862 48863 CatmullRomCurve3.call( this, points ); 48864 this.type = 'catmullrom'; 48865 this.closed = true; 48866 48867} 48868 48869ClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype ); 48870 48871// 48872 48873function SplineCurve3( points ) { 48874 48875 console.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' ); 48876 48877 CatmullRomCurve3.call( this, points ); 48878 this.type = 'catmullrom'; 48879 48880} 48881 48882SplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype ); 48883 48884// 48885 48886function Spline( points ) { 48887 48888 console.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' ); 48889 48890 CatmullRomCurve3.call( this, points ); 48891 this.type = 'catmullrom'; 48892 48893} 48894 48895Spline.prototype = Object.create( CatmullRomCurve3.prototype ); 48896 48897Object.assign( Spline.prototype, { 48898 48899 initFromArray: function ( /* a */ ) { 48900 48901 console.error( 'THREE.Spline: .initFromArray() has been removed.' ); 48902 48903 }, 48904 getControlPointsArray: function ( /* optionalTarget */ ) { 48905 48906 console.error( 'THREE.Spline: .getControlPointsArray() has been removed.' ); 48907 48908 }, 48909 reparametrizeByArcLength: function ( /* samplingCoef */ ) { 48910 48911 console.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' ); 48912 48913 } 48914 48915} ); 48916 48917// 48918 48919function AxisHelper( size ) { 48920 48921 console.warn( 'THREE.AxisHelper has been renamed to THREE.AxesHelper.' ); 48922 return new AxesHelper( size ); 48923 48924} 48925 48926function BoundingBoxHelper( object, color ) { 48927 48928 console.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' ); 48929 return new BoxHelper( object, color ); 48930 48931} 48932 48933function EdgesHelper( object, hex ) { 48934 48935 console.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' ); 48936 return new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) ); 48937 48938} 48939 48940GridHelper.prototype.setColors = function () { 48941 48942 console.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' ); 48943 48944}; 48945 48946SkeletonHelper.prototype.update = function () { 48947 48948 console.error( 'THREE.SkeletonHelper: update() no longer needs to be called.' ); 48949 48950}; 48951 48952function WireframeHelper( object, hex ) { 48953 48954 console.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' ); 48955 return new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) ); 48956 48957} 48958 48959// 48960 48961Object.assign( Loader.prototype, { 48962 48963 extractUrlBase: function ( url ) { 48964 48965 console.warn( 'THREE.Loader: .extractUrlBase() has been deprecated. Use THREE.LoaderUtils.extractUrlBase() instead.' ); 48966 return LoaderUtils.extractUrlBase( url ); 48967 48968 } 48969 48970} ); 48971 48972Loader.Handlers = { 48973 48974 add: function ( /* regex, loader */ ) { 48975 48976 console.error( 'THREE.Loader: Handlers.add() has been removed. Use LoadingManager.addHandler() instead.' ); 48977 48978 }, 48979 48980 get: function ( /* file */ ) { 48981 48982 console.error( 'THREE.Loader: Handlers.get() has been removed. Use LoadingManager.getHandler() instead.' ); 48983 48984 } 48985 48986}; 48987 48988function XHRLoader( manager ) { 48989 48990 console.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' ); 48991 return new FileLoader( manager ); 48992 48993} 48994 48995function BinaryTextureLoader( manager ) { 48996 48997 console.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' ); 48998 return new DataTextureLoader( manager ); 48999 49000} 49001 49002Object.assign( ObjectLoader.prototype, { 49003 49004 setTexturePath: function ( value ) { 49005 49006 console.warn( 'THREE.ObjectLoader: .setTexturePath() has been renamed to .setResourcePath().' ); 49007 return this.setResourcePath( value ); 49008 49009 } 49010 49011} ); 49012 49013// 49014 49015Object.assign( Box2.prototype, { 49016 49017 center: function ( optionalTarget ) { 49018 49019 console.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' ); 49020 return this.getCenter( optionalTarget ); 49021 49022 }, 49023 empty: function () { 49024 49025 console.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' ); 49026 return this.isEmpty(); 49027 49028 }, 49029 isIntersectionBox: function ( box ) { 49030 49031 console.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' ); 49032 return this.intersectsBox( box ); 49033 49034 }, 49035 size: function ( optionalTarget ) { 49036 49037 console.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );
49038 return this.getSize( optionalTarget ); 49039 49040 } 49041} ); 49042 49043Object.assign( Box3.prototype, { 49044 49045 center: function ( optionalTarget ) { 49046 49047 console.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' ); 49048 return this.getCenter( optionalTarget ); 49049 49050 }, 49051 empty: function () { 49052 49053 console.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' ); 49054 return this.isEmpty(); 49055 49056 }, 49057 isIntersectionBox: function ( box ) { 49058 49059 console.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' ); 49060 return this.intersectsBox( box ); 49061 49062 }, 49063 isIntersectionSphere: function ( sphere ) { 49064 49065 console.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' ); 49066 return this.intersectsSphere( sphere ); 49067 49068 }, 49069 size: function ( optionalTarget ) { 49070 49071 console.warn( 'THREE.Box3: .size() has been renamed to .getSize().' ); 49072 return this.getSize( optionalTarget ); 49073 49074 } 49075} ); 49076 49077Object.assign( Sphere.prototype, { 49078 49079 empty: function () { 49080 49081 console.warn( 'THREE.Sphere: .empty() has been renamed to .isEmpty().' ); 49082 return this.isEmpty(); 49083 49084 }, 49085 49086} ); 49087 49088Frustum.prototype.setFromMatrix = function ( m ) { 49089 49090 console.warn( 'THREE.Frustum: .setFromMatrix() has been renamed to .setFromProjectionMatrix().' ); 49091 return this.setFromProjectionMatrix( m ); 49092 49093}; 49094 49095Line3.prototype.center = function ( optionalTarget ) { 49096 49097 console.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' ); 49098 return this.getCenter( optionalTarget ); 49099 49100}; 49101 49102Object.assign( MathUtils, { 49103 49104 random16: function () { 49105 49106 console.warn( 'THREE.Math: .random16() has been deprecated. Use Math.random() instead.' ); 49107 return Math.random(); 49108 49109 }, 49110 49111 nearestPowerOfTwo: function ( value ) { 49112 49113 console.warn( 'THREE.Math: .nearestPowerOfTwo() has been renamed to .floorPowerOfTwo().' ); 49114 return MathUtils.floorPowerOfTwo( value ); 49115 49116 }, 49117 49118 nextPowerOfTwo: function ( value ) { 49119 49120 console.warn( 'THREE.Math: .nextPowerOfTwo() has been renamed to .ceilPowerOfTwo().' ); 49121 return MathUtils.ceilPowerOfTwo( value ); 49122 49123 } 49124 49125} ); 49126 49127Object.assign( Matrix3.prototype, { 49128 49129 flattenToArrayOffset: function ( array, offset ) { 49130 49131 console.warn( "THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." ); 49132 return this.toArray( array, offset ); 49133 49134 }, 49135 multiplyVector3: function ( vector ) { 49136
vendor: 1,651 bytes, lines 49137-49192
49137 console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' ); 49138 return vector.applyMatrix3( this ); 49139 49140 }, 49141 multiplyVector3Array: function ( /* a */ ) { 49142 49143 console.error( 'THREE.Matrix3: .multiplyVector3Array() has been removed.' ); 49144 49145 }, 49146 applyToBufferAttribute: function ( attribute ) { 49147 49148 console.warn( 'THREE.Matrix3: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix3( matrix ) instead.' ); 49149 return attribute.applyMatrix3( this ); 49150 49151 }, 49152 applyToVector3Array: function ( /* array, offset, length */ ) { 49153 49154 console.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' ); 49155 49156 } 49157 49158} ); 49159 49160Object.assign( Matrix4.prototype, { 49161 49162 extractPosition: function ( m ) { 49163 49164 console.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' ); 49165 return this.copyPosition( m ); 49166 49167 }, 49168 flattenToArrayOffset: function ( array, offset ) { 49169 49170 console.warn( "THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." ); 49171 return this.toArray( array, offset ); 49172 49173 }, 49174 getPosition: function () { 49175 49176 console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' ); 49177 return new Vector3().setFromMatrixColumn( this, 3 ); 49178 49179 }, 49180 setRotationFromQuaternion: function ( q ) { 49181 49182 console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' ); 49183 return this.makeRotationFromQuaternion( q ); 49184 49185 }, 49186 multiplyToArray: function () { 49187 49188 console.warn( 'THREE.Matrix4: .multiplyToArray() has been removed.' ); 49189 49190 }, 49191 multiplyVector3: function ( vector ) { 49192
49193 console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); 49194 return vector.applyMatrix4( this ); 49195 49196 }, 49197 multiplyVector4: function ( vector ) { 49198 49199 console.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); 49200 return vector.applyMatrix4( this ); 49201 49202 }, 49203 multiplyVector3Array: function ( /* a */ ) { 49204 49205 console.error( 'THREE.Matrix4: .multiplyVector3Array() has been removed.' ); 49206 49207 }, 49208 rotateAxis: function ( v ) { 49209 49210 console.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' ); 49211 v.transformDirection( this ); 49212 49213 }, 49214 crossVector: function ( vector ) { 49215 49216 console.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); 49217 return vector.applyMatrix4( this ); 49218 49219 }, 49220 translate: function () { 49221 49222 console.error( 'THREE.Matrix4: .translate() has been removed.' ); 49223 49224 }, 49225 rotateX: function () { 49226 49227 console.error( 'THREE.Matrix4: .rotateX() has been removed.' ); 49228 49229 }, 49230 rotateY: function () { 49231 49232 console.error( 'THREE.Matrix4: .rotateY() has been removed.' ); 49233 49234 }, 49235 rotateZ: function () { 49236 49237 console.error( 'THREE.Matrix4: .rotateZ() has been removed.' ); 49238 49239 }, 49240 rotateByAxis: function () { 49241 49242 console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' ); 49243 49244 }, 49245 applyToBufferAttribute: function ( attribute ) { 49246 49247 console.warn( 'THREE.Matrix4: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix4( matrix ) instead.' ); 49248 return attribute.applyMatrix4( this ); 49249 49250 }, 49251 applyToVector3Array: function ( /* array, offset, length */ ) { 49252 49253 console.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' ); 49254 49255 }, 49256 makeFrustum: function ( left, right, bottom, top, near, far ) { 49257 49258 console.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' ); 49259 return this.makePerspective( left, right, top, bottom, near, far ); 49260 49261 } 49262 49263} ); 49264 49265Plane.prototype.isIntersectionLine = function ( line ) { 49266 49267 console.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' ); 49268 return this.intersectsLine( line ); 49269 49270}; 49271 49272Quaternion.prototype.multiplyVector3 = function ( vector ) { 49273
vendor: 28,316 bytes, lines 49274-50459
49274 console.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' ); 49275 return vector.applyQuaternion( this ); 49276 49277}; 49278 49279Object.assign( Ray.prototype, { 49280 49281 isIntersectionBox: function ( box ) { 49282 49283 console.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' ); 49284 return this.intersectsBox( box ); 49285 49286 }, 49287 isIntersectionPlane: function ( plane ) { 49288 49289 console.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' ); 49290 return this.intersectsPlane( plane ); 49291 49292 }, 49293 isIntersectionSphere: function ( sphere ) { 49294 49295 console.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' ); 49296 return this.intersectsSphere( sphere ); 49297 49298 } 49299 49300} ); 49301 49302Object.assign( Triangle.prototype, { 49303 49304 area: function () { 49305 49306 console.warn( 'THREE.Triangle: .area() has been renamed to .getArea().' ); 49307 return this.getArea(); 49308 49309 }, 49310 barycoordFromPoint: function ( point, target ) { 49311 49312 console.warn( 'THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().' ); 49313 return this.getBarycoord( point, target ); 49314 49315 }, 49316 midpoint: function ( target ) { 49317 49318 console.warn( 'THREE.Triangle: .midpoint() has been renamed to .getMidpoint().' ); 49319 return this.getMidpoint( target ); 49320 49321 }, 49322 normal: function ( target ) { 49323 49324 console.warn( 'THREE.Triangle: .normal() has been renamed to .getNormal().' ); 49325 return this.getNormal( target ); 49326 49327 }, 49328 plane: function ( target ) { 49329 49330 console.warn( 'THREE.Triangle: .plane() has been renamed to .getPlane().' ); 49331 return this.getPlane( target ); 49332 49333 } 49334 49335} ); 49336 49337Object.assign( Triangle, { 49338 49339 barycoordFromPoint: function ( point, a, b, c, target ) { 49340 49341 console.warn( 'THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().' ); 49342 return Triangle.getBarycoord( point, a, b, c, target ); 49343 49344 }, 49345 normal: function ( a, b, c, target ) { 49346 49347 console.warn( 'THREE.Triangle: .normal() has been renamed to .getNormal().' ); 49348 return Triangle.getNormal( a, b, c, target ); 49349 49350 } 49351 49352} ); 49353 49354Object.assign( Shape.prototype, { 49355 49356 extractAllPoints: function ( divisions ) { 49357 49358 console.warn( 'THREE.Shape: .extractAllPoints() has been removed. Use .extractPoints() instead.' ); 49359 return this.extractPoints( divisions ); 49360 49361 }, 49362 extrude: function ( options ) { 49363 49364 console.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' ); 49365 return new ExtrudeGeometry( this, options ); 49366 49367 }, 49368 makeGeometry: function ( options ) { 49369 49370 console.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' ); 49371 return new ShapeGeometry( this, options ); 49372 49373 } 49374 49375} ); 49376 49377Object.assign( Vector2.prototype, { 49378 49379 fromAttribute: function ( attribute, index, offset ) { 49380 49381 console.warn( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' ); 49382 return this.fromBufferAttribute( attribute, index, offset ); 49383 49384 }, 49385 distanceToManhattan: function ( v ) { 49386 49387 console.warn( 'THREE.Vector2: .distanceToManhattan() has been renamed to .manhattanDistanceTo().' ); 49388 return this.manhattanDistanceTo( v ); 49389 49390 }, 49391 lengthManhattan: function () { 49392 49393 console.warn( 'THREE.Vector2: .lengthManhattan() has been renamed to .manhattanLength().' ); 49394 return this.manhattanLength(); 49395 49396 } 49397 49398} ); 49399 49400Object.assign( Vector3.prototype, { 49401 49402 setEulerFromRotationMatrix: function () { 49403 49404 console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' ); 49405 49406 }, 49407 setEulerFromQuaternion: function () { 49408 49409 console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' ); 49410 49411 }, 49412 getPositionFromMatrix: function ( m ) { 49413 49414 console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' ); 49415 return this.setFromMatrixPosition( m ); 49416 49417 }, 49418 getScaleFromMatrix: function ( m ) { 49419 49420 console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' ); 49421 return this.setFromMatrixScale( m ); 49422 49423 }, 49424 getColumnFromMatrix: function ( index, matrix ) { 49425 49426 console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' ); 49427 return this.setFromMatrixColumn( matrix, index ); 49428 49429 }, 49430 applyProjection: function ( m ) { 49431 49432 console.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' ); 49433 return this.applyMatrix4( m ); 49434 49435 }, 49436 fromAttribute: function ( attribute, index, offset ) { 49437 49438 console.warn( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' ); 49439 return this.fromBufferAttribute( attribute, index, offset ); 49440 49441 }, 49442 distanceToManhattan: function ( v ) { 49443 49444 console.warn( 'THREE.Vector3: .distanceToManhattan() has been renamed to .manhattanDistanceTo().' ); 49445 return this.manhattanDistanceTo( v ); 49446 49447 }, 49448 lengthManhattan: function () { 49449 49450 console.warn( 'THREE.Vector3: .lengthManhattan() has been renamed to .manhattanLength().' ); 49451 return this.manhattanLength(); 49452 49453 } 49454 49455} ); 49456 49457Object.assign( Vector4.prototype, { 49458 49459 fromAttribute: function ( attribute, index, offset ) { 49460 49461 console.warn( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' ); 49462 return this.fromBufferAttribute( attribute, index, offset ); 49463 49464 }, 49465 lengthManhattan: function () { 49466 49467 console.warn( 'THREE.Vector4: .lengthManhattan() has been renamed to .manhattanLength().' ); 49468 return this.manhattanLength(); 49469 49470 } 49471 49472} ); 49473 49474// 49475 49476Object.assign( Geometry.prototype, { 49477 49478 computeTangents: function () { 49479 49480 console.error( 'THREE.Geometry: .computeTangents() has been removed.' ); 49481 49482 }, 49483 computeLineDistances: function () { 49484 49485 console.error( 'THREE.Geometry: .computeLineDistances() has been removed. Use THREE.Line.computeLineDistances() instead.' ); 49486 49487 }, 49488 applyMatrix: function ( matrix ) { 49489 49490 console.warn( 'THREE.Geometry: .applyMatrix() has been renamed to .applyMatrix4().' ); 49491 return this.applyMatrix4( matrix ); 49492 49493 } 49494 49495} ); 49496 49497Object.assign( Object3D.prototype, { 49498 49499 getChildByName: function ( name ) { 49500 49501 console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' ); 49502 return this.getObjectByName( name ); 49503 49504 }, 49505 renderDepth: function () { 49506 49507 console.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' ); 49508 49509 }, 49510 translate: function ( distance, axis ) { 49511 49512 console.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' ); 49513 return this.translateOnAxis( axis, distance ); 49514 49515 }, 49516 getWorldRotation: function () { 49517 49518 console.error( 'THREE.Object3D: .getWorldRotation() has been removed. Use THREE.Object3D.getWorldQuaternion( target ) instead.' ); 49519 49520 }, 49521 applyMatrix: function ( matrix ) { 49522 49523 console.warn( 'THREE.Object3D: .applyMatrix() has been renamed to .applyMatrix4().' ); 49524 return this.applyMatrix4( matrix ); 49525 49526 } 49527 49528} ); 49529 49530Object.defineProperties( Object3D.prototype, { 49531 49532 eulerOrder: { 49533 get: function () { 49534 49535 console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' ); 49536 return this.rotation.order; 49537 49538 }, 49539 set: function ( value ) { 49540 49541 console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' ); 49542 this.rotation.order = value; 49543 49544 } 49545 }, 49546 useQuaternion: { 49547 get: function () { 49548 49549 console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); 49550 49551 }, 49552 set: function () { 49553 49554 console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); 49555 49556 } 49557 } 49558 49559} ); 49560 49561Object.assign( Mesh.prototype, { 49562 49563 setDrawMode: function () { 49564 49565 console.error( 'THREE.Mesh: .setDrawMode() has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.' ); 49566 49567 }, 49568 49569} ); 49570 49571Object.defineProperties( Mesh.prototype, { 49572 49573 drawMode: { 49574 get: function () { 49575 49576 console.error( 'THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode.' ); 49577 return TrianglesDrawMode; 49578 49579 }, 49580 set: function () { 49581 49582 console.error( 'THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.' ); 49583 49584 } 49585 } 49586 49587} ); 49588 49589Object.defineProperties( LOD.prototype, { 49590 49591 objects: { 49592 get: function () { 49593 49594 console.warn( 'THREE.LOD: .objects has been renamed to .levels.' ); 49595 return this.levels; 49596 49597 } 49598 } 49599 49600} ); 49601 49602Object.defineProperty( Skeleton.prototype, 'useVertexTexture', { 49603 49604 get: function () { 49605 49606 console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' ); 49607 49608 }, 49609 set: function () { 49610 49611 console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' ); 49612 49613 } 49614 49615} ); 49616 49617SkinnedMesh.prototype.initBones = function () { 49618 49619 console.error( 'THREE.SkinnedMesh: initBones() has been removed.' ); 49620 49621}; 49622 49623Object.defineProperty( Curve.prototype, '__arcLengthDivisions', { 49624 49625 get: function () { 49626 49627 console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' ); 49628 return this.arcLengthDivisions; 49629 49630 }, 49631 set: function ( value ) { 49632 49633 console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' ); 49634 this.arcLengthDivisions = value; 49635 49636 } 49637 49638} ); 49639 49640// 49641 49642PerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) { 49643 49644 console.warn( "THREE.PerspectiveCamera.setLens is deprecated. " + 49645 "Use .setFocalLength and .filmGauge for a photographic setup." ); 49646 49647 if ( filmGauge !== undefined ) this.filmGauge = filmGauge; 49648 this.setFocalLength( focalLength ); 49649 49650}; 49651 49652// 49653 49654Object.defineProperties( Light.prototype, { 49655 onlyShadow: { 49656 set: function () { 49657 49658 console.warn( 'THREE.Light: .onlyShadow has been removed.' ); 49659 49660 } 49661 }, 49662 shadowCameraFov: { 49663 set: function ( value ) { 49664 49665 console.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' ); 49666 this.shadow.camera.fov = value; 49667 49668 } 49669 }, 49670 shadowCameraLeft: { 49671 set: function ( value ) { 49672 49673 console.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' ); 49674 this.shadow.camera.left = value; 49675 49676 } 49677 }, 49678 shadowCameraRight: { 49679 set: function ( value ) { 49680 49681 console.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' ); 49682 this.shadow.camera.right = value; 49683 49684 } 49685 }, 49686 shadowCameraTop: { 49687 set: function ( value ) { 49688 49689 console.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' ); 49690 this.shadow.camera.top = value; 49691 49692 } 49693 }, 49694 shadowCameraBottom: { 49695 set: function ( value ) { 49696 49697 console.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' ); 49698 this.shadow.camera.bottom = value; 49699 49700 } 49701 }, 49702 shadowCameraNear: { 49703 set: function ( value ) { 49704 49705 console.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' ); 49706 this.shadow.camera.near = value; 49707 49708 } 49709 }, 49710 shadowCameraFar: { 49711 set: function ( value ) { 49712 49713 console.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' ); 49714 this.shadow.camera.far = value; 49715 49716 } 49717 }, 49718 shadowCameraVisible: { 49719 set: function () { 49720 49721 console.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' ); 49722 49723 } 49724 }, 49725 shadowBias: { 49726 set: function ( value ) { 49727 49728 console.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' ); 49729 this.shadow.bias = value; 49730 49731 } 49732 }, 49733 shadowDarkness: { 49734 set: function () { 49735 49736 console.warn( 'THREE.Light: .shadowDarkness has been removed.' ); 49737 49738 } 49739 }, 49740 shadowMapWidth: { 49741 set: function ( value ) { 49742 49743 console.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' ); 49744 this.shadow.mapSize.width = value; 49745 49746 } 49747 }, 49748 shadowMapHeight: { 49749 set: function ( value ) { 49750 49751 console.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' ); 49752 this.shadow.mapSize.height = value; 49753 49754 } 49755 } 49756} ); 49757 49758// 49759 49760Object.defineProperties( BufferAttribute.prototype, { 49761 49762 length: { 49763 get: function () { 49764 49765 console.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' ); 49766 return this.array.length; 49767 49768 } 49769 }, 49770 dynamic: { 49771 get: function () { 49772 49773 console.warn( 'THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.' ); 49774 return this.usage === DynamicDrawUsage; 49775 49776 }, 49777 set: function ( /* value */ ) { 49778 49779 console.warn( 'THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.' ); 49780 this.setUsage( DynamicDrawUsage ); 49781 49782 } 49783 } 49784 49785} ); 49786 49787Object.assign( BufferAttribute.prototype, { 49788 setDynamic: function ( value ) { 49789 49790 console.warn( 'THREE.BufferAttribute: .setDynamic() has been deprecated. Use .setUsage() instead.' ); 49791 this.setUsage( value === true ? DynamicDrawUsage : StaticDrawUsage ); 49792 return this; 49793 49794 }, 49795 copyIndicesArray: function ( /* indices */ ) { 49796 49797 console.error( 'THREE.BufferAttribute: .copyIndicesArray() has been removed.' ); 49798 49799 }, 49800 setArray: function ( /* array */ ) { 49801 49802 console.error( 'THREE.BufferAttribute: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers' ); 49803 49804 } 49805} ); 49806 49807Object.assign( BufferGeometry.prototype, { 49808 49809 addIndex: function ( index ) { 49810 49811 console.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' ); 49812 this.setIndex( index ); 49813 49814 }, 49815 addAttribute: function ( name, attribute ) { 49816 49817 console.warn( 'THREE.BufferGeometry: .addAttribute() has been renamed to .setAttribute().' ); 49818 49819 if ( ! ( attribute && attribute.isBufferAttribute ) && ! ( attribute && attribute.isInterleavedBufferAttribute ) ) { 49820 49821 console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); 49822 49823 return this.setAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) ); 49824 49825 } 49826 49827 if ( name === 'index' ) { 49828 49829 console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' ); 49830 this.setIndex( attribute ); 49831 49832 return this; 49833 49834 } 49835 49836 return this.setAttribute( name, attribute ); 49837 49838 }, 49839 addDrawCall: function ( start, count, indexOffset ) { 49840 49841 if ( indexOffset !== undefined ) { 49842 49843 console.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' ); 49844 49845 } 49846 49847 console.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' ); 49848 this.addGroup( start, count ); 49849 49850 }, 49851 clearDrawCalls: function () { 49852 49853 console.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' ); 49854 this.clearGroups(); 49855 49856 }, 49857 computeTangents: function () { 49858 49859 console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' ); 49860 49861 }, 49862 computeOffsets: function () { 49863 49864 console.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' ); 49865 49866 }, 49867 removeAttribute: function ( name ) { 49868 49869 console.warn( 'THREE.BufferGeometry: .removeAttribute() has been renamed to .deleteAttribute().' ); 49870 49871 return this.deleteAttribute( name ); 49872 49873 }, 49874 applyMatrix: function ( matrix ) { 49875 49876 console.warn( 'THREE.BufferGeometry: .applyMatrix() has been renamed to .applyMatrix4().' ); 49877 return this.applyMatrix4( matrix ); 49878 49879 } 49880 49881} ); 49882 49883Object.defineProperties( BufferGeometry.prototype, { 49884 49885 drawcalls: { 49886 get: function () { 49887 49888 console.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' ); 49889 return this.groups; 49890 49891 } 49892 }, 49893 offsets: { 49894 get: function () { 49895 49896 console.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' ); 49897 return this.groups; 49898 49899 } 49900 } 49901 49902} ); 49903 49904Object.defineProperties( Raycaster.prototype, { 49905 49906 linePrecision: { 49907 get: function () { 49908 49909 console.warn( 'THREE.Raycaster: .linePrecision has been deprecated. Use .params.Line.threshold instead.' ); 49910 return this.params.Line.threshold; 49911 49912 }, 49913 set: function ( value ) { 49914 49915 console.warn( 'THREE.Raycaster: .linePrecision has been deprecated. Use .params.Line.threshold instead.' ); 49916 this.params.Line.threshold = value; 49917 49918 } 49919 } 49920 49921} ); 49922 49923Object.defineProperties( InterleavedBuffer.prototype, { 49924 49925 dynamic: { 49926 get: function () { 49927 49928 console.warn( 'THREE.InterleavedBuffer: .length has been deprecated. Use .usage instead.' ); 49929 return this.usage === DynamicDrawUsage; 49930 49931 }, 49932 set: function ( value ) { 49933 49934 console.warn( 'THREE.InterleavedBuffer: .length has been deprecated. Use .usage instead.' ); 49935 this.setUsage( value ); 49936 49937 } 49938 } 49939 49940} ); 49941 49942Object.assign( InterleavedBuffer.prototype, { 49943 setDynamic: function ( value ) { 49944 49945 console.warn( 'THREE.InterleavedBuffer: .setDynamic() has been deprecated. Use .setUsage() instead.' ); 49946 this.setUsage( value === true ? DynamicDrawUsage : StaticDrawUsage ); 49947 return this; 49948 49949 }, 49950 setArray: function ( /* array */ ) { 49951 49952 console.error( 'THREE.InterleavedBuffer: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers' ); 49953 49954 } 49955} ); 49956 49957// 49958 49959Object.assign( ExtrudeBufferGeometry.prototype, { 49960 49961 getArrays: function () { 49962 49963 console.error( 'THREE.ExtrudeBufferGeometry: .getArrays() has been removed.' ); 49964 49965 }, 49966 49967 addShapeList: function () { 49968 49969 console.error( 'THREE.ExtrudeBufferGeometry: .addShapeList() has been removed.' ); 49970 49971 }, 49972 49973 addShape: function () { 49974 49975 console.error( 'THREE.ExtrudeBufferGeometry: .addShape() has been removed.' ); 49976 49977 } 49978 49979} ); 49980 49981// 49982 49983Object.defineProperties( Uniform.prototype, { 49984 49985 dynamic: { 49986 set: function () { 49987 49988 console.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' ); 49989 49990 } 49991 }, 49992 onUpdate: { 49993 value: function () { 49994 49995 console.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' ); 49996 return this; 49997 49998 } 49999 } 50000 50001} ); 50002 50003// 50004 50005Object.defineProperties( Material.prototype, { 50006 50007 wrapAround: { 50008 get: function () { 50009 50010 console.warn( 'THREE.Material: .wrapAround has been removed.' ); 50011 50012 }, 50013 set: function () { 50014 50015 console.warn( 'THREE.Material: .wrapAround has been removed.' ); 50016 50017 } 50018 }, 50019 50020 overdraw: { 50021 get: function () { 50022 50023 console.warn( 'THREE.Material: .overdraw has been removed.' ); 50024 50025 }, 50026 set: function () { 50027 50028 console.warn( 'THREE.Material: .overdraw has been removed.' ); 50029 50030 } 50031 }, 50032 50033 wrapRGB: { 50034 get: function () { 50035 50036 console.warn( 'THREE.Material: .wrapRGB has been removed.' ); 50037 return new Color(); 50038 50039 } 50040 }, 50041 50042 shading: { 50043 get: function () { 50044 50045 console.error( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); 50046 50047 }, 50048 set: function ( value ) { 50049 50050 console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); 50051 this.flatShading = ( value === FlatShading ); 50052 50053 } 50054 }, 50055 50056 stencilMask: { 50057 get: function () { 50058 50059 console.warn( 'THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.' ); 50060 return this.stencilFuncMask; 50061 50062 }, 50063 set: function ( value ) { 50064 50065 console.warn( 'THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.' ); 50066 this.stencilFuncMask = value; 50067 50068 } 50069 } 50070 50071} ); 50072 50073Object.defineProperties( MeshPhongMaterial.prototype, { 50074 50075 metal: { 50076 get: function () { 50077 50078 console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' ); 50079 return false; 50080 50081 }, 50082 set: function () { 50083 50084 console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' ); 50085 50086 } 50087 } 50088 50089} ); 50090 50091Object.defineProperties( ShaderMaterial.prototype, { 50092 50093 derivatives: { 50094 get: function () { 50095 50096 console.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' ); 50097 return this.extensions.derivatives; 50098 50099 }, 50100 set: function ( value ) { 50101 50102 console.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' ); 50103 this.extensions.derivatives = value; 50104 50105 } 50106 } 50107 50108} ); 50109 50110// 50111 50112Object.assign( WebGLRenderer.prototype, { 50113 50114 clearTarget: function ( renderTarget, color, depth, stencil ) { 50115 50116 console.warn( 'THREE.WebGLRenderer: .clearTarget() has been deprecated. Use .setRenderTarget() and .clear() instead.' ); 50117 this.setRenderTarget( renderTarget ); 50118 this.clear( color, depth, stencil ); 50119 50120 }, 50121 animate: function ( callback ) { 50122 50123 console.warn( 'THREE.WebGLRenderer: .animate() is now .setAnimationLoop().' ); 50124 this.setAnimationLoop( callback ); 50125 50126 }, 50127 getCurrentRenderTarget: function () { 50128 50129 console.warn( 'THREE.WebGLRenderer: .getCurrentRenderTarget() is now .getRenderTarget().' ); 50130 return this.getRenderTarget(); 50131 50132 }, 50133 getMaxAnisotropy: function () { 50134 50135 console.warn( 'THREE.WebGLRenderer: .getMaxAnisotropy() is now .capabilities.getMaxAnisotropy().' ); 50136 return this.capabilities.getMaxAnisotropy(); 50137 50138 }, 50139 getPrecision: function () { 50140 50141 console.warn( 'THREE.WebGLRenderer: .getPrecision() is now .capabilities.precision.' ); 50142 return this.capabilities.precision; 50143 50144 }, 50145 resetGLState: function () { 50146 50147 console.warn( 'THREE.WebGLRenderer: .resetGLState() is now .state.reset().' ); 50148 return this.state.reset(); 50149 50150 }, 50151 supportsFloatTextures: function () { 50152 50153 console.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).' ); 50154 return this.extensions.get( 'OES_texture_float' ); 50155 50156 }, 50157 supportsHalfFloatTextures: function () { 50158 50159 console.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).' ); 50160 return this.extensions.get( 'OES_texture_half_float' ); 50161 50162 }, 50163 supportsStandardDerivatives: function () { 50164 50165 console.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).' ); 50166 return this.extensions.get( 'OES_standard_derivatives' ); 50167 50168 }, 50169 supportsCompressedTextureS3TC: function () { 50170 50171 console.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).' ); 50172 return this.extensions.get( 'WEBGL_compressed_texture_s3tc' ); 50173 50174 }, 50175 supportsCompressedTexturePVRTC: function () { 50176 50177 console.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).' ); 50178 return this.extensions.get( 'WEBGL_compressed_texture_pvrtc' ); 50179 50180 }, 50181 supportsBlendMinMax: function () { 50182 50183 console.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).' ); 50184 return this.extensions.get( 'EXT_blend_minmax' ); 50185 50186 }, 50187 supportsVertexTextures: function () { 50188 50189 console.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' ); 50190 return this.capabilities.vertexTextures; 50191 50192 }, 50193 supportsInstancedArrays: function () { 50194 50195 console.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \'ANGLE_instanced_arrays\' ).' ); 50196 return this.extensions.get( 'ANGLE_instanced_arrays' ); 50197 50198 }, 50199 enableScissorTest: function ( boolean ) { 50200 50201 console.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' ); 50202 this.setScissorTest( boolean ); 50203 50204 }, 50205 initMaterial: function () { 50206 50207 console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' ); 50208 50209 }, 50210 addPrePlugin: function () { 50211 50212 console.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' ); 50213 50214 }, 50215 addPostPlugin: function () { 50216 50217 console.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' ); 50218 50219 }, 50220 updateShadowMap: function () { 50221 50222 console.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' ); 50223 50224 }, 50225 setFaceCulling: function () { 50226 50227 console.warn( 'THREE.WebGLRenderer: .setFaceCulling() has been removed.' ); 50228 50229 }, 50230 allocTextureUnit: function () { 50231 50232 console.warn( 'THREE.WebGLRenderer: .allocTextureUnit() has been removed.' ); 50233 50234 }, 50235 setTexture: function () { 50236 50237 console.warn( 'THREE.WebGLRenderer: .setTexture() has been removed.' ); 50238 50239 }, 50240 setTexture2D: function () { 50241 50242 console.warn( 'THREE.WebGLRenderer: .setTexture2D() has been removed.' ); 50243 50244 }, 50245 setTextureCube: function () { 50246 50247 console.warn( 'THREE.WebGLRenderer: .setTextureCube() has been removed.' ); 50248 50249 }, 50250 getActiveMipMapLevel: function () { 50251 50252 console.warn( 'THREE.WebGLRenderer: .getActiveMipMapLevel() is now .getActiveMipmapLevel().' ); 50253 return this.getActiveMipmapLevel(); 50254 50255 } 50256 50257} ); 50258 50259Object.defineProperties( WebGLRenderer.prototype, { 50260 50261 shadowMapEnabled: { 50262 get: function () { 50263 50264 return this.shadowMap.enabled; 50265 50266 }, 50267 set: function ( value ) { 50268 50269 console.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' ); 50270 this.shadowMap.enabled = value; 50271 50272 } 50273 }, 50274 shadowMapType: { 50275 get: function () { 50276 50277 return this.shadowMap.type; 50278 50279 }, 50280 set: function ( value ) { 50281 50282 console.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' ); 50283 this.shadowMap.type = value; 50284 50285 } 50286 }, 50287 shadowMapCullFace: { 50288 get: function () { 50289 50290 console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.' ); 50291 return undefined; 50292 50293 }, 50294 set: function ( /* value */ ) { 50295 50296 console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.' ); 50297 50298 } 50299 }, 50300 context: { 50301 get: function () { 50302 50303 console.warn( 'THREE.WebGLRenderer: .context has been removed. Use .getContext() instead.' ); 50304 return this.getContext(); 50305 50306 } 50307 }, 50308 vr: { 50309 get: function () { 50310 50311 console.warn( 'THREE.WebGLRenderer: .vr has been renamed to .xr' ); 50312 return this.xr; 50313 50314 } 50315 }, 50316 gammaInput: { 50317 get: function () { 50318 50319 console.warn( 'THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.' ); 50320 return false; 50321 50322 }, 50323 set: function () { 50324 50325 console.warn( 'THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.' ); 50326 50327 } 50328 }, 50329 gammaOutput: { 50330 get: function () { 50331 50332 console.warn( 'THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.' ); 50333 return false; 50334 50335 }, 50336 set: function ( value ) { 50337 50338 console.warn( 'THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.' ); 50339 this.outputEncoding = ( value === true ) ? sRGBEncoding : LinearEncoding; 50340 50341 } 50342 } 50343 50344} ); 50345 50346Object.defineProperties( WebGLShadowMap.prototype, { 50347 50348 cullFace: { 50349 get: function () { 50350 50351 console.warn( 'THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.' ); 50352 return undefined; 50353 50354 }, 50355 set: function ( /* cullFace */ ) { 50356 50357 console.warn( 'THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.' ); 50358 50359 } 50360 }, 50361 renderReverseSided: { 50362 get: function () { 50363 50364 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.' ); 50365 return undefined; 50366 50367 }, 50368 set: function () { 50369 50370 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.' ); 50371 50372 } 50373 }, 50374 renderSingleSided: { 50375 get: function () { 50376 50377 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.' ); 50378 return undefined; 50379 50380 }, 50381 set: function () { 50382 50383 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.' ); 50384 50385 } 50386 } 50387 50388} ); 50389 50390function WebGLRenderTargetCube( width, height, options ) { 50391 50392 console.warn( 'THREE.WebGLRenderTargetCube( width, height, options ) is now WebGLCubeRenderTarget( size, options ).' ); 50393 return new WebGLCubeRenderTarget( width, options ); 50394 50395} 50396 50397// 50398 50399Object.defineProperties( WebGLRenderTarget.prototype, { 50400 50401 wrapS: { 50402 get: function () { 50403 50404 console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' ); 50405 return this.texture.wrapS; 50406 50407 }, 50408 set: function ( value ) { 50409 50410 console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' ); 50411 this.texture.wrapS = value; 50412 50413 } 50414 }, 50415 wrapT: { 50416 get: function () { 50417 50418 console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' ); 50419 return this.texture.wrapT; 50420 50421 }, 50422 set: function ( value ) { 50423 50424 console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' ); 50425 this.texture.wrapT = value; 50426 50427 } 50428 }, 50429 magFilter: { 50430 get: function () { 50431 50432 console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' ); 50433 return this.texture.magFilter; 50434 50435 }, 50436 set: function ( value ) { 50437 50438 console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' ); 50439 this.texture.magFilter = value; 50440 50441 } 50442 }, 50443 minFilter: { 50444 get: function () { 50445 50446 console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' ); 50447 return this.texture.minFilter; 50448 50449 }, 50450 set: function ( value ) { 50451 50452 console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' ); 50453 this.texture.minFilter = value; 50454 50455 } 50456 }, 50457 anisotropy: { 50458 get: function () { 50459
vendor: 2,617 bytes, lines 50460-50584
50460 console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' ); 50461 return this.texture.anisotropy; 50462 50463 }, 50464 set: function ( value ) { 50465 50466 console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' ); 50467 this.texture.anisotropy = value; 50468 50469 } 50470 }, 50471 offset: { 50472 get: function () { 50473 50474 console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' ); 50475 return this.texture.offset; 50476 50477 }, 50478 set: function ( value ) { 50479 50480 console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' ); 50481 this.texture.offset = value; 50482 50483 } 50484 }, 50485 repeat: { 50486 get: function () { 50487 50488 console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' ); 50489 return this.texture.repeat; 50490 50491 }, 50492 set: function ( value ) { 50493 50494 console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' ); 50495 this.texture.repeat = value; 50496 50497 } 50498 }, 50499 format: { 50500 get: function () { 50501 50502 console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' ); 50503 return this.texture.format; 50504 50505 }, 50506 set: function ( value ) { 50507 50508 console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' ); 50509 this.texture.format = value; 50510 50511 } 50512 }, 50513 type: { 50514 get: function () { 50515 50516 console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' ); 50517 return this.texture.type; 50518 50519 }, 50520 set: function ( value ) { 50521 50522 console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' ); 50523 this.texture.type = value; 50524 50525 } 50526 }, 50527 generateMipmaps: { 50528 get: function () { 50529 50530 console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' ); 50531 return this.texture.generateMipmaps; 50532 50533 }, 50534 set: function ( value ) { 50535 50536 console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' ); 50537 this.texture.generateMipmaps = value; 50538 50539 } 50540 } 50541 50542} ); 50543 50544// 50545 50546Object.defineProperties( Audio.prototype, { 50547 50548 load: { 50549 value: function ( file ) { 50550 50551 console.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' ); 50552 var scope = this; 50553 var audioLoader = new AudioLoader(); 50554 audioLoader.load( file, function ( buffer ) { 50555 50556 scope.setBuffer( buffer ); 50557 50558 } ); 50559 return this; 50560 50561 } 50562 }, 50563 startTime: { 50564 set: function () { 50565 50566 console.warn( 'THREE.Audio: .startTime is now .play( delay ).' ); 50567 50568 } 50569 } 50570 50571} ); 50572 50573AudioAnalyser.prototype.getData = function () { 50574 50575 console.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' ); 50576 return this.getFrequencyData(); 50577 50578}; 50579 50580// 50581 50582CubeCamera.prototype.updateCubeMap = function ( renderer, scene ) { 50583 50584 console.warn( 'THREE.CubeCamera: .updateCubeMap() is now .update(
50584).' ); 50585 return this.update( renderer, scene ); 50586 50587}; 50588 50589// 50590 50591var GeometryUtils = { 50592 50593 merge: function ( geometry1, geometry2, materialIndexOffset ) { 50594 50595 console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' ); 50596 var matrix; 50597 50598 if ( geometry2.isMesh ) { 50599 50600 geometry2.matrixAutoUpdate && geometry2.updateMatrix(); 50601 50602 matrix = geometry2.matrix; 50603 geometry2 = geometry2.geometry; 50604 50605 } 50606 50607 geometry1.merge( geometry2, matrix, materialIndexOffset ); 50608 50609 }, 50610 50611 center: function ( geometry ) { 50612 50613 console.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' ); 50614 return geometry.center(); 50615 50616 } 50617 50618}; 50619 50620ImageUtils.crossOrigin = undefined; 50621 50622ImageUtils.loadTexture = function ( url, mapping, onLoad, onError ) { 50623 50624 console.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' ); 50625 50626 var loader = new TextureLoader(); 50627 loader.setCrossOrigin( this.crossOrigin ); 50628 50629 var texture = loader.load( url, onLoad, undefined, onError ); 50630 50631 if ( mapping ) texture.mapping = mapping; 50632 50633 return texture; 50634 50635}; 50636 50637ImageUtils.loadTextureCube = function ( urls, mapping, onLoad, onError ) { 50638 50639 console.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' ); 50640 50641 var loader = new CubeTextureLoader(); 50642 loader.setCrossOrigin( this.crossOrigin ); 50643 50644 var texture = loader.load( urls, onLoad, undefined, onError ); 50645 50646 if ( mapping ) texture.mapping = mapping; 50647 50648 return texture; 50649 50650}; 50651 50652ImageUtils.loadCompressedTexture = function () { 50653 50654 console.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' ); 50655 50656}; 50657 50658ImageUtils.loadCompressedTextureCube = function () { 50659 50660 console.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' ); 50661 50662}; 50663 50664// 50665 50666function CanvasRenderer() { 50667 50668 console.error( 'THREE.CanvasRenderer has been removed' ); 50669 50670} 50671 50672// 50673 50674function JSONLoader() { 50675 50676 console.error( 'THREE.JSONLoader has been removed.' ); 50677 50678} 50679 50680// 50681 50682var SceneUtils = { 50683 50684 createMultiMaterialObject: function ( /* geometry, materials */ ) { 50685 50686 console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' ); 50687 50688 }, 50689 50690 detach: function ( /* child, parent, scene */ ) { 50691 50692 console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' ); 50693 50694 }, 50695 50696 attach: function ( /* child, scene, parent */ ) { 50697 50698 console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' ); 50699 50700 } 50701 50702}; 50703 50704// 50705 50706function LensFlare() { 50707 50708 console.error( 'THREE.LensFlare has been moved to /examples/jsm/objects/Lensflare.js' ); 50709 50710} 50711 50712if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { 50713 50714 /* eslint-disable no-undef */ 50715 __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'register', { detail: { 50716 revision: REVISION, 50717 } } ) ); 50718 /* eslint-enable no-undef */ 50719 50720} 50721 50722export { ACESFilmicToneMapping, AddEquation, AddOperation, AdditiveAnimationBlendMode, AdditiveBlending, AlphaFormat, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AmbientLightProbe, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrayCamera, ArrowHelper, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, AxisHelper, BackSide, BasicDepthPacking, BasicShadowMap, BinaryTextureLoader, Bone, BooleanKeyframeTrack, BoundingBoxHelper, Box2, Box3, Box3Helper, BoxBufferGeometry, BoxGeometry, BoxHelper, BufferAttribute, BufferGeometry, BufferGeometryLoader, ByteType, Cache, Camera, CameraHelper, CanvasRenderer, CanvasTexture, CatmullRomCurve3, CineonToneMapping, CircleBufferGeometry, CircleGeometry, ClampToEdgeWrapping, Clock, ClosedSplineCurve3, Color, ColorKeyframeTrack, CompressedTexture, CompressedTextureLoader, ConeBufferGeometry, ConeGeometry, CubeCamera, BoxGeometry as CubeGeometry, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureLoader, CubeUVReflectionMapping, CubeUVRefractionMapping, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceBack, CullFaceFront, CullFaceFrontBack, CullFaceNone, Curve, CurvePath, CustomBlending, CylinderBufferGeometry, CylinderGeometry, Cylindrical, DataTexture, DataTexture2DArray, DataTexture3D, DataTextureLoader, DecrementStencilOp, DecrementWrapStencilOp, DefaultLoadingManager, DepthFormat, DepthStencilFormat, DepthTexture, DirectionalLight, DirectionalLightHelper, DirectionalLightShadow, DiscreteInterpolant, DodecahedronBufferGeometry, DodecahedronGeometry, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicBufferAttribute, DynamicCopyUsage, DynamicDrawUsage, DynamicReadUsage, EdgesGeometry, EdgesHelper, EllipseCurve, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, ExtrudeBufferGeometry, ExtrudeGeometry, Face3, Face4, FaceColors, FileLoader, FlatShading, Float32Attribute, Float32BufferAttribute, Float64Attribute, Float64BufferAttribute, FloatType, Fog, FogExp2, Font, FontLoader, FrontFaceDirectionCCW, FrontFaceDirectionCW, FrontSide, Frustum, GammaEncoding, Geometry, GeometryUtils, GreaterDepth, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, GridHelper, Group, HalfFloatType, HemisphereLight, HemisphereLightHelper, HemisphereLightProbe, IcosahedronBufferGeometry, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, ImmediateRenderObject, IncrementStencilOp, IncrementWrapStencilOp, InstancedBufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, InstancedMesh, Int16Attribute, Int16BufferAttribute, Int32Attribute, Int32BufferAttribute, Int8Attribute, Int8BufferAttribute, IntType, InterleavedBuffer, InterleavedBufferAttribute, Interpolant, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InvertStencilOp, JSONLoader, KeepStencilOp, KeyframeTrack, LOD, LatheBufferGeometry, LatheGeometry, Layers, LensFlare, LessDepth, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, Light, LightProbe, LightShadow, Line, Line3, LineBasicMaterial, LineCurve, LineCurve3, LineDashedMaterial, LineLoop, LinePieces, LineSegments, LineStrip, LinearEncoding, LinearFilter, LinearInterpolant, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearToneMapping, Loader, LoaderUtils, LoadingManager, LogLuvEncoding, LoopOnce, LoopPingPong, LoopRepeat, LuminanceAlphaFormat, LuminanceFormat, MOUSE, Material, MaterialLoader, MathUtils as Math, MathUtils, Matrix3, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshDistanceMaterial, MeshFaceMaterial, MeshLambertMaterial, MeshMatcapMaterial, MeshNormalMaterial, MeshPhongMaterial, MeshPhysicalMaterial, MeshStandardMaterial, MeshToonMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, MultiMaterial, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeverDepth, NeverStencilFunc, NoBlending, NoColors, NoToneMapping, NormalAnimationBlendMode, NormalBlending, NotEqualDepth, NotEqualStencilFunc, NumberKeyframeTrack, Object3D, ObjectLoader, ObjectSpaceNormalMap, OctahedronBufferGeometry, OctahedronGeometry, OneFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, Orthogra
50722phicCamera, PCFShadowMap, PCFSoftShadowMap, PMREMGenerator, ParametricBufferGeometry, ParametricGeometry, Particle, ParticleBasicMaterial, ParticleSystem, ParticleSystemMaterial, Path, PerspectiveCamera, Plane, PlaneBufferGeometry, PlaneGeometry, PlaneHelper, PointCloud, PointCloudMaterial, PointLight, PointLightHelper, Points, PointsMaterial, PolarGridHelper, PolyhedronBufferGeometry, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, Quaternion, QuaternionKeyframeTrack, QuaternionLinearInterpolant, REVISION, RGBADepthPacking, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBDEncoding, RGBEEncoding, RGBEFormat, RGBFormat, RGBIntegerFormat, RGBM16Encoding, RGBM7Encoding, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RawShaderMaterial, Ray, Raycaster, RectAreaLight, RedFormat, RedIntegerFormat, ReinhardToneMapping, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RingBufferGeometry, RingGeometry, SRGB8_ALPHA8_ASTC_10x10_Format, SRGB8_ALPHA8_ASTC_10x5_Format, SRGB8_ALPHA8_ASTC_10x6_Format, SRGB8_ALPHA8_ASTC_10x8_Format, SRGB8_ALPHA8_ASTC_12x10_Format, SRGB8_ALPHA8_ASTC_12x12_Format, SRGB8_ALPHA8_ASTC_4x4_Format, SRGB8_ALPHA8_ASTC_5x4_Format, SRGB8_ALPHA8_ASTC_5x5_Format, SRGB8_ALPHA8_ASTC_6x5_Format, SRGB8_ALPHA8_ASTC_6x6_Format, SRGB8_ALPHA8_ASTC_8x5_Format, SRGB8_ALPHA8_ASTC_8x6_Format, SRGB8_ALPHA8_ASTC_8x8_Format, Scene, SceneUtils, ShaderChunk, ShaderLib, ShaderMaterial, ShadowMaterial, Shape, ShapeBufferGeometry, ShapeGeometry, ShapePath, ShapeUtils, ShortType, Skeleton, SkeletonHelper, SkinnedMesh, SmoothShading, Sphere, SphereBufferGeometry, SphereGeometry, Spherical, SphericalHarmonics3, SphericalReflectionMapping, Spline, SplineCurve, SplineCurve3, SpotLight, SpotLightHelper, SpotLightShadow, Sprite, SpriteMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StaticCopyUsage, StaticDrawUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, SubtractEquation, SubtractiveBlending, TOUCH, TangentSpaceNormalMap, TetrahedronBufferGeometry, TetrahedronGeometry, TextBufferGeometry, TextGeometry, Texture, TextureLoader, TorusBufferGeometry, TorusGeometry, TorusKnotBufferGeometry, TorusKnotGeometry, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeBufferGeometry, TubeGeometry, UVMapping, Uint16Attribute, Uint16BufferAttribute, Uint32Attribute, Uint32BufferAttribute, Uint8Attribute, Uint8BufferAttribute, Uint8ClampedAttribute, Uint8ClampedBufferAttribute, Uncharted2ToneMapping, Uniform, UniformsLib, UniformsUtils, UnsignedByteType, UnsignedInt248Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShort565Type, UnsignedShortType, VSMShadowMap, Vector2, Vector3, Vector4, VectorKeyframeTrack, Vertex, VertexColors, VideoTexture, WebGLCubeRenderTarget, WebGLMultisampleRenderTarget, WebGLRenderTarget, WebGLRenderTargetCube, WebGLRenderer, WebGLUtils, WireframeGeometry, WireframeHelper, WrapAroundEnding, XHRLoader, ZeroCurvatureEnding, ZeroFactor, ZeroSlopeEnding, ZeroStencilOp, sRGBEncoding };
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.