00001
00002
00007 var THREE = { REVISION: '73' };
00008
00009
00010
00011 if ( typeof define === 'function' && define.amd ) {
00012
00013 define( 'three', THREE );
00014
00015 } else if ( 'undefined' !== typeof exports && 'undefined' !== typeof module ) {
00016
00017 module.exports = THREE;
00018
00019 }
00020
00021
00022
00023
00024 if ( self.requestAnimationFrame === undefined || self.cancelAnimationFrame === undefined ) {
00025
00026
00027
00028 ( function () {
00029
00030 var lastTime = 0;
00031 var vendors = [ 'ms', 'moz', 'webkit', 'o' ];
00032
00033 for ( var x = 0; x < vendors.length && ! self.requestAnimationFrame; ++ x ) {
00034
00035 self.requestAnimationFrame = self[ vendors[ x ] + 'RequestAnimationFrame' ];
00036 self.cancelAnimationFrame = self[ vendors[ x ] + 'CancelAnimationFrame' ] || self[ vendors[ x ] + 'CancelRequestAnimationFrame' ];
00037
00038 }
00039
00040 if ( self.requestAnimationFrame === undefined && self.setTimeout !== undefined ) {
00041
00042 self.requestAnimationFrame = function ( callback ) {
00043
00044 var currTime = Date.now(), timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );
00045 var id = self.setTimeout( function () {
00046
00047 callback( currTime + timeToCall );
00048
00049 }, timeToCall );
00050 lastTime = currTime + timeToCall;
00051 return id;
00052
00053 };
00054
00055 }
00056
00057 if ( self.cancelAnimationFrame === undefined && self.clearTimeout !== undefined ) {
00058
00059 self.cancelAnimationFrame = function ( id ) {
00060
00061 self.clearTimeout( id );
00062
00063 };
00064
00065 }
00066
00067 } )();
00068
00069 }
00070
00071
00072
00073 if ( self.performance === undefined ) {
00074
00075 self.performance = {};
00076
00077 }
00078
00079 if ( self.performance.now === undefined ) {
00080
00081 ( function () {
00082
00083 var start = Date.now();
00084
00085 self.performance.now = function () {
00086
00087 return Date.now() - start;
00088
00089 }
00090
00091 } )();
00092
00093 }
00094
00095
00096
00097 if ( Number.EPSILON === undefined ) {
00098
00099 Number.EPSILON = Math.pow( 2, -52 );
00100
00101 }
00102
00103
00104
00105 if ( Math.sign === undefined ) {
00106
00107
00108
00109 Math.sign = function ( x ) {
00110
00111 return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;
00112
00113 };
00114
00115 }
00116
00117 if ( Function.prototype.name === undefined && Object.defineProperty !== undefined ) {
00118
00119
00120
00121
00122 Object.defineProperty( Function.prototype, 'name', {
00123
00124 get: function () {
00125
00126 return this.toString().match( /^\s*function\s*(\S*)\s*\(/ )[ 1 ];
00127
00128 }
00129
00130 } );
00131
00132 }
00133
00134
00135
00136 THREE.MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };
00137
00138
00139
00140 THREE.CullFaceNone = 0;
00141 THREE.CullFaceBack = 1;
00142 THREE.CullFaceFront = 2;
00143 THREE.CullFaceFrontBack = 3;
00144
00145 THREE.FrontFaceDirectionCW = 0;
00146 THREE.FrontFaceDirectionCCW = 1;
00147
00148
00149
00150 THREE.BasicShadowMap = 0;
00151 THREE.PCFShadowMap = 1;
00152 THREE.PCFSoftShadowMap = 2;
00153
00154
00155
00156
00157
00158 THREE.FrontSide = 0;
00159 THREE.BackSide = 1;
00160 THREE.DoubleSide = 2;
00161
00162
00163
00164 THREE.FlatShading = 1;
00165 THREE.SmoothShading = 2;
00166
00167
00168
00169 THREE.NoColors = 0;
00170 THREE.FaceColors = 1;
00171 THREE.VertexColors = 2;
00172
00173
00174
00175 THREE.NoBlending = 0;
00176 THREE.NormalBlending = 1;
00177 THREE.AdditiveBlending = 2;
00178 THREE.SubtractiveBlending = 3;
00179 THREE.MultiplyBlending = 4;
00180 THREE.CustomBlending = 5;
00181
00182
00183
00184
00185
00186 THREE.AddEquation = 100;
00187 THREE.SubtractEquation = 101;
00188 THREE.ReverseSubtractEquation = 102;
00189 THREE.MinEquation = 103;
00190 THREE.MaxEquation = 104;
00191
00192
00193
00194 THREE.ZeroFactor = 200;
00195 THREE.OneFactor = 201;
00196 THREE.SrcColorFactor = 202;
00197 THREE.OneMinusSrcColorFactor = 203;
00198 THREE.SrcAlphaFactor = 204;
00199 THREE.OneMinusSrcAlphaFactor = 205;
00200 THREE.DstAlphaFactor = 206;
00201 THREE.OneMinusDstAlphaFactor = 207;
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 THREE.DstColorFactor = 208;
00212 THREE.OneMinusDstColorFactor = 209;
00213 THREE.SrcAlphaSaturateFactor = 210;
00214
00215
00216
00217 THREE.NeverDepth = 0;
00218 THREE.AlwaysDepth = 1;
00219 THREE.LessDepth = 2;
00220 THREE.LessEqualDepth = 3;
00221 THREE.EqualDepth = 4;
00222 THREE.GreaterEqualDepth = 5;
00223 THREE.GreaterDepth = 6;
00224 THREE.NotEqualDepth = 7;
00225
00226
00227
00228
00229 THREE.MultiplyOperation = 0;
00230 THREE.MixOperation = 1;
00231 THREE.AddOperation = 2;
00232
00233
00234
00235 THREE.UVMapping = 300;
00236
00237 THREE.CubeReflectionMapping = 301;
00238 THREE.CubeRefractionMapping = 302;
00239
00240 THREE.EquirectangularReflectionMapping = 303;
00241 THREE.EquirectangularRefractionMapping = 304;
00242
00243 THREE.SphericalReflectionMapping = 305;
00244
00245
00246
00247 THREE.RepeatWrapping = 1000;
00248 THREE.ClampToEdgeWrapping = 1001;
00249 THREE.MirroredRepeatWrapping = 1002;
00250
00251
00252
00253 THREE.NearestFilter = 1003;
00254 THREE.NearestMipMapNearestFilter = 1004;
00255 THREE.NearestMipMapLinearFilter = 1005;
00256 THREE.LinearFilter = 1006;
00257 THREE.LinearMipMapNearestFilter = 1007;
00258 THREE.LinearMipMapLinearFilter = 1008;
00259
00260
00261
00262 THREE.UnsignedByteType = 1009;
00263 THREE.ByteType = 1010;
00264 THREE.ShortType = 1011;
00265 THREE.UnsignedShortType = 1012;
00266 THREE.IntType = 1013;
00267 THREE.UnsignedIntType = 1014;
00268 THREE.FloatType = 1015;
00269 THREE.HalfFloatType = 1025;
00270
00271
00272
00273
00274 THREE.UnsignedShort4444Type = 1016;
00275 THREE.UnsignedShort5551Type = 1017;
00276 THREE.UnsignedShort565Type = 1018;
00277
00278
00279
00280 THREE.AlphaFormat = 1019;
00281 THREE.RGBFormat = 1020;
00282 THREE.RGBAFormat = 1021;
00283 THREE.LuminanceFormat = 1022;
00284 THREE.LuminanceAlphaFormat = 1023;
00285
00286 THREE.RGBEFormat = THREE.RGBAFormat;
00287
00288
00289
00290 THREE.RGB_S3TC_DXT1_Format = 2001;
00291 THREE.RGBA_S3TC_DXT1_Format = 2002;
00292 THREE.RGBA_S3TC_DXT3_Format = 2003;
00293 THREE.RGBA_S3TC_DXT5_Format = 2004;
00294
00295
00296
00297
00298 THREE.RGB_PVRTC_4BPPV1_Format = 2100;
00299 THREE.RGB_PVRTC_2BPPV1_Format = 2101;
00300 THREE.RGBA_PVRTC_4BPPV1_Format = 2102;
00301 THREE.RGBA_PVRTC_2BPPV1_Format = 2103;
00302
00303
00304
00305 THREE.LoopOnce = 2200;
00306 THREE.LoopRepeat = 2201;
00307 THREE.LoopPingPong = 2202;
00308
00309
00310
00311 THREE.Projector = function () {
00312
00313 console.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );
00314
00315 this.projectVector = function ( vector, camera ) {
00316
00317 console.warn( 'THREE.Projector: .projectVector() is now vector.project().' );
00318 vector.project( camera );
00319
00320 };
00321
00322 this.unprojectVector = function ( vector, camera ) {
00323
00324 console.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );
00325 vector.unproject( camera );
00326
00327 };
00328
00329 this.pickingRay = function ( vector, camera ) {
00330
00331 console.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );
00332
00333 };
00334
00335 };
00336
00337 THREE.CanvasRenderer = function () {
00338
00339 console.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );
00340
00341 this.domElement = document.createElement( 'canvas' );
00342 this.clear = function () {};
00343 this.render = function () {};
00344 this.setClearColor = function () {};
00345 this.setSize = function () {};
00346
00347 };
00348
00349
00350
00355 THREE.Color = function ( color ) {
00356
00357 if ( arguments.length === 3 ) {
00358
00359 return this.fromArray( arguments );
00360
00361 }
00362
00363 return this.set( color );
00364
00365 };
00366
00367 THREE.Color.prototype = {
00368
00369 constructor: THREE.Color,
00370
00371 r: 1, g: 1, b: 1,
00372
00373 set: function ( value ) {
00374
00375 if ( value instanceof THREE.Color ) {
00376
00377 this.copy( value );
00378
00379 } else if ( typeof value === 'number' ) {
00380
00381 this.setHex( value );
00382
00383 } else if ( typeof value === 'string' ) {
00384
00385 this.setStyle( value );
00386
00387 }
00388
00389 return this;
00390
00391 },
00392
00393 setHex: function ( hex ) {
00394
00395 hex = Math.floor( hex );
00396
00397 this.r = ( hex >> 16 & 255 ) / 255;
00398 this.g = ( hex >> 8 & 255 ) / 255;
00399 this.b = ( hex & 255 ) / 255;
00400
00401 return this;
00402
00403 },
00404
00405 setRGB: function ( r, g, b ) {
00406
00407 this.r = r;
00408 this.g = g;
00409 this.b = b;
00410
00411 return this;
00412
00413 },
00414
00415 setHSL: function () {
00416
00417 function hue2rgb( p, q, t ) {
00418
00419 if ( t < 0 ) t += 1;
00420 if ( t > 1 ) t -= 1;
00421 if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;
00422 if ( t < 1 / 2 ) return q;
00423 if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );
00424 return p;
00425
00426 }
00427
00428 return function ( h, s, l ) {
00429
00430
00431 h = THREE.Math.euclideanModulo( h, 1 );
00432 s = THREE.Math.clamp( s, 0, 1 );
00433 l = THREE.Math.clamp( l, 0, 1 );
00434
00435 if ( s === 0 ) {
00436
00437 this.r = this.g = this.b = l;
00438
00439 } else {
00440
00441 var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );
00442 var q = ( 2 * l ) - p;
00443
00444 this.r = hue2rgb( q, p, h + 1 / 3 );
00445 this.g = hue2rgb( q, p, h );
00446 this.b = hue2rgb( q, p, h - 1 / 3 );
00447
00448 }
00449
00450 return this;
00451
00452 };
00453
00454 }(),
00455
00456 setStyle: function ( style ) {
00457
00458 function handleAlpha( string ) {
00459
00460 if ( string === undefined ) return;
00461
00462 if ( parseFloat( string ) < 1 ) {
00463
00464 console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );
00465
00466 }
00467
00468 }
00469
00470
00471 var m;
00472
00473 if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) {
00474
00475
00476
00477 var color;
00478 var name = m[ 1 ];
00479 var components = m[ 2 ];
00480
00481 switch ( name ) {
00482
00483 case 'rgb':
00484 case 'rgba':
00485
00486 if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
00487
00488
00489 this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;
00490 this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;
00491 this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;
00492
00493 handleAlpha( color[ 5 ] );
00494
00495 return this;
00496
00497 }
00498
00499 if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
00500
00501
00502 this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;
00503 this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;
00504 this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;
00505
00506 handleAlpha( color[ 5 ] );
00507
00508 return this;
00509
00510 }
00511
00512 break;
00513
00514 case 'hsl':
00515 case 'hsla':
00516
00517 if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
00518
00519
00520 var h = parseFloat( color[ 1 ] ) / 360;
00521 var s = parseInt( color[ 2 ], 10 ) / 100;
00522 var l = parseInt( color[ 3 ], 10 ) / 100;
00523
00524 handleAlpha( color[ 5 ] );
00525
00526 return this.setHSL( h, s, l );
00527
00528 }
00529
00530 break;
00531
00532 }
00533
00534 } else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) {
00535
00536
00537
00538 var hex = m[ 1 ];
00539 var size = hex.length;
00540
00541 if ( size === 3 ) {
00542
00543
00544 this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;
00545 this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;
00546 this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;
00547
00548 return this;
00549
00550 } else if ( size === 6 ) {
00551
00552
00553 this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;
00554 this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;
00555 this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;
00556
00557 return this;
00558
00559 }
00560
00561 }
00562
00563 if ( style && style.length > 0 ) {
00564
00565
00566 var hex = THREE.ColorKeywords[ style ];
00567
00568 if ( hex !== undefined ) {
00569
00570
00571 this.setHex( hex );
00572
00573 } else {
00574
00575
00576 console.warn( 'THREE.Color: Unknown color ' + style );
00577
00578 }
00579
00580 }
00581
00582 return this;
00583
00584 },
00585
00586 clone: function () {
00587
00588 return new this.constructor( this.r, this.g, this.b );
00589
00590 },
00591
00592 copy: function ( color ) {
00593
00594 this.r = color.r;
00595 this.g = color.g;
00596 this.b = color.b;
00597
00598 return this;
00599
00600 },
00601
00602 copyGammaToLinear: function ( color, gammaFactor ) {
00603
00604 if ( gammaFactor === undefined ) gammaFactor = 2.0;
00605
00606 this.r = Math.pow( color.r, gammaFactor );
00607 this.g = Math.pow( color.g, gammaFactor );
00608 this.b = Math.pow( color.b, gammaFactor );
00609
00610 return this;
00611
00612 },
00613
00614 copyLinearToGamma: function ( color, gammaFactor ) {
00615
00616 if ( gammaFactor === undefined ) gammaFactor = 2.0;
00617
00618 var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;
00619
00620 this.r = Math.pow( color.r, safeInverse );
00621 this.g = Math.pow( color.g, safeInverse );
00622 this.b = Math.pow( color.b, safeInverse );
00623
00624 return this;
00625
00626 },
00627
00628 convertGammaToLinear: function () {
00629
00630 var r = this.r, g = this.g, b = this.b;
00631
00632 this.r = r * r;
00633 this.g = g * g;
00634 this.b = b * b;
00635
00636 return this;
00637
00638 },
00639
00640 convertLinearToGamma: function () {
00641
00642 this.r = Math.sqrt( this.r );
00643 this.g = Math.sqrt( this.g );
00644 this.b = Math.sqrt( this.b );
00645
00646 return this;
00647
00648 },
00649
00650 getHex: function () {
00651
00652 return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;
00653
00654 },
00655
00656 getHexString: function () {
00657
00658 return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );
00659
00660 },
00661
00662 getHSL: function ( optionalTarget ) {
00663
00664
00665
00666 var hsl = optionalTarget || { h: 0, s: 0, l: 0 };
00667
00668 var r = this.r, g = this.g, b = this.b;
00669
00670 var max = Math.max( r, g, b );
00671 var min = Math.min( r, g, b );
00672
00673 var hue, saturation;
00674 var lightness = ( min + max ) / 2.0;
00675
00676 if ( min === max ) {
00677
00678 hue = 0;
00679 saturation = 0;
00680
00681 } else {
00682
00683 var delta = max - min;
00684
00685 saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );
00686
00687 switch ( max ) {
00688
00689 case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;
00690 case g: hue = ( b - r ) / delta + 2; break;
00691 case b: hue = ( r - g ) / delta + 4; break;
00692
00693 }
00694
00695 hue /= 6;
00696
00697 }
00698
00699 hsl.h = hue;
00700 hsl.s = saturation;
00701 hsl.l = lightness;
00702
00703 return hsl;
00704
00705 },
00706
00707 getStyle: function () {
00708
00709 return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';
00710
00711 },
00712
00713 offsetHSL: function ( h, s, l ) {
00714
00715 var hsl = this.getHSL();
00716
00717 hsl.h += h; hsl.s += s; hsl.l += l;
00718
00719 this.setHSL( hsl.h, hsl.s, hsl.l );
00720
00721 return this;
00722
00723 },
00724
00725 add: function ( color ) {
00726
00727 this.r += color.r;
00728 this.g += color.g;
00729 this.b += color.b;
00730
00731 return this;
00732
00733 },
00734
00735 addColors: function ( color1, color2 ) {
00736
00737 this.r = color1.r + color2.r;
00738 this.g = color1.g + color2.g;
00739 this.b = color1.b + color2.b;
00740
00741 return this;
00742
00743 },
00744
00745 addScalar: function ( s ) {
00746
00747 this.r += s;
00748 this.g += s;
00749 this.b += s;
00750
00751 return this;
00752
00753 },
00754
00755 multiply: function ( color ) {
00756
00757 this.r *= color.r;
00758 this.g *= color.g;
00759 this.b *= color.b;
00760
00761 return this;
00762
00763 },
00764
00765 multiplyScalar: function ( s ) {
00766
00767 this.r *= s;
00768 this.g *= s;
00769 this.b *= s;
00770
00771 return this;
00772
00773 },
00774
00775 lerp: function ( color, alpha ) {
00776
00777 this.r += ( color.r - this.r ) * alpha;
00778 this.g += ( color.g - this.g ) * alpha;
00779 this.b += ( color.b - this.b ) * alpha;
00780
00781 return this;
00782
00783 },
00784
00785 equals: function ( c ) {
00786
00787 return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );
00788
00789 },
00790
00791 fromArray: function ( array, offset ) {
00792
00793 if ( offset === undefined ) offset = 0;
00794
00795 this.r = array[ offset ];
00796 this.g = array[ offset + 1 ];
00797 this.b = array[ offset + 2 ];
00798
00799 return this;
00800
00801 },
00802
00803 toArray: function ( array, offset ) {
00804
00805 if ( array === undefined ) array = [];
00806 if ( offset === undefined ) offset = 0;
00807
00808 array[ offset ] = this.r;
00809 array[ offset + 1 ] = this.g;
00810 array[ offset + 2 ] = this.b;
00811
00812 return array;
00813
00814 }
00815
00816 };
00817
00818 THREE.ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,
00819 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,
00820 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,
00821 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,
00822 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,
00823 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,
00824 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,
00825 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,
00826 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,
00827 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,
00828 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,
00829 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,
00830 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,
00831 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,
00832 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,
00833 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,
00834 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,
00835 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,
00836 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,
00837 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,
00838 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,
00839 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,
00840 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,
00841 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };
00842
00843
00844
00852 THREE.Quaternion = function ( x, y, z, w ) {
00853
00854 this._x = x || 0;
00855 this._y = y || 0;
00856 this._z = z || 0;
00857 this._w = ( w !== undefined ) ? w : 1;
00858
00859 };
00860
00861 THREE.Quaternion.prototype = {
00862
00863 constructor: THREE.Quaternion,
00864
00865 get x () {
00866
00867 return this._x;
00868
00869 },
00870
00871 set x ( value ) {
00872
00873 this._x = value;
00874 this.onChangeCallback();
00875
00876 },
00877
00878 get y () {
00879
00880 return this._y;
00881
00882 },
00883
00884 set y ( value ) {
00885
00886 this._y = value;
00887 this.onChangeCallback();
00888
00889 },
00890
00891 get z () {
00892
00893 return this._z;
00894
00895 },
00896
00897 set z ( value ) {
00898
00899 this._z = value;
00900 this.onChangeCallback();
00901
00902 },
00903
00904 get w () {
00905
00906 return this._w;
00907
00908 },
00909
00910 set w ( value ) {
00911
00912 this._w = value;
00913 this.onChangeCallback();
00914
00915 },
00916
00917 set: function ( x, y, z, w ) {
00918
00919 this._x = x;
00920 this._y = y;
00921 this._z = z;
00922 this._w = w;
00923
00924 this.onChangeCallback();
00925
00926 return this;
00927
00928 },
00929
00930 clone: function () {
00931
00932 return new this.constructor( this._x, this._y, this._z, this._w );
00933
00934 },
00935
00936 copy: function ( quaternion ) {
00937
00938 this._x = quaternion.x;
00939 this._y = quaternion.y;
00940 this._z = quaternion.z;
00941 this._w = quaternion.w;
00942
00943 this.onChangeCallback();
00944
00945 return this;
00946
00947 },
00948
00949 setFromEuler: function ( euler, update ) {
00950
00951 if ( euler instanceof THREE.Euler === false ) {
00952
00953 throw new Error( 'THREE.Quaternion: .setFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );
00954
00955 }
00956
00957
00958
00959
00960
00961 var c1 = Math.cos( euler._x / 2 );
00962 var c2 = Math.cos( euler._y / 2 );
00963 var c3 = Math.cos( euler._z / 2 );
00964 var s1 = Math.sin( euler._x / 2 );
00965 var s2 = Math.sin( euler._y / 2 );
00966 var s3 = Math.sin( euler._z / 2 );
00967
00968 var order = euler.order;
00969
00970 if ( order === 'XYZ' ) {
00971
00972 this._x = s1 * c2 * c3 + c1 * s2 * s3;
00973 this._y = c1 * s2 * c3 - s1 * c2 * s3;
00974 this._z = c1 * c2 * s3 + s1 * s2 * c3;
00975 this._w = c1 * c2 * c3 - s1 * s2 * s3;
00976
00977 } else if ( order === 'YXZ' ) {
00978
00979 this._x = s1 * c2 * c3 + c1 * s2 * s3;
00980 this._y = c1 * s2 * c3 - s1 * c2 * s3;
00981 this._z = c1 * c2 * s3 - s1 * s2 * c3;
00982 this._w = c1 * c2 * c3 + s1 * s2 * s3;
00983
00984 } else if ( order === 'ZXY' ) {
00985
00986 this._x = s1 * c2 * c3 - c1 * s2 * s3;
00987 this._y = c1 * s2 * c3 + s1 * c2 * s3;
00988 this._z = c1 * c2 * s3 + s1 * s2 * c3;
00989 this._w = c1 * c2 * c3 - s1 * s2 * s3;
00990
00991 } else if ( order === 'ZYX' ) {
00992
00993 this._x = s1 * c2 * c3 - c1 * s2 * s3;
00994 this._y = c1 * s2 * c3 + s1 * c2 * s3;
00995 this._z = c1 * c2 * s3 - s1 * s2 * c3;
00996 this._w = c1 * c2 * c3 + s1 * s2 * s3;
00997
00998 } else if ( order === 'YZX' ) {
00999
01000 this._x = s1 * c2 * c3 + c1 * s2 * s3;
01001 this._y = c1 * s2 * c3 + s1 * c2 * s3;
01002 this._z = c1 * c2 * s3 - s1 * s2 * c3;
01003 this._w = c1 * c2 * c3 - s1 * s2 * s3;
01004
01005 } else if ( order === 'XZY' ) {
01006
01007 this._x = s1 * c2 * c3 - c1 * s2 * s3;
01008 this._y = c1 * s2 * c3 - s1 * c2 * s3;
01009 this._z = c1 * c2 * s3 + s1 * s2 * c3;
01010 this._w = c1 * c2 * c3 + s1 * s2 * s3;
01011
01012 }
01013
01014 if ( update !== false ) this.onChangeCallback();
01015
01016 return this;
01017
01018 },
01019
01020 setFromAxisAngle: function ( axis, angle ) {
01021
01022
01023
01024
01025
01026 var halfAngle = angle / 2, s = Math.sin( halfAngle );
01027
01028 this._x = axis.x * s;
01029 this._y = axis.y * s;
01030 this._z = axis.z * s;
01031 this._w = Math.cos( halfAngle );
01032
01033 this.onChangeCallback();
01034
01035 return this;
01036
01037 },
01038
01039 setFromRotationMatrix: function ( m ) {
01040
01041
01042
01043
01044
01045 var te = m.elements,
01046
01047 m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],
01048 m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],
01049 m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],
01050
01051 trace = m11 + m22 + m33,
01052 s;
01053
01054 if ( trace > 0 ) {
01055
01056 s = 0.5 / Math.sqrt( trace + 1.0 );
01057
01058 this._w = 0.25 / s;
01059 this._x = ( m32 - m23 ) * s;
01060 this._y = ( m13 - m31 ) * s;
01061 this._z = ( m21 - m12 ) * s;
01062
01063 } else if ( m11 > m22 && m11 > m33 ) {
01064
01065 s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );
01066
01067 this._w = ( m32 - m23 ) / s;
01068 this._x = 0.25 * s;
01069 this._y = ( m12 + m21 ) / s;
01070 this._z = ( m13 + m31 ) / s;
01071
01072 } else if ( m22 > m33 ) {
01073
01074 s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );
01075
01076 this._w = ( m13 - m31 ) / s;
01077 this._x = ( m12 + m21 ) / s;
01078 this._y = 0.25 * s;
01079 this._z = ( m23 + m32 ) / s;
01080
01081 } else {
01082
01083 s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );
01084
01085 this._w = ( m21 - m12 ) / s;
01086 this._x = ( m13 + m31 ) / s;
01087 this._y = ( m23 + m32 ) / s;
01088 this._z = 0.25 * s;
01089
01090 }
01091
01092 this.onChangeCallback();
01093
01094 return this;
01095
01096 },
01097
01098 setFromUnitVectors: function () {
01099
01100
01101
01102
01103
01104 var v1, r;
01105
01106 var EPS = 0.000001;
01107
01108 return function ( vFrom, vTo ) {
01109
01110 if ( v1 === undefined ) v1 = new THREE.Vector3();
01111
01112 r = vFrom.dot( vTo ) + 1;
01113
01114 if ( r < EPS ) {
01115
01116 r = 0;
01117
01118 if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {
01119
01120 v1.set( - vFrom.y, vFrom.x, 0 );
01121
01122 } else {
01123
01124 v1.set( 0, - vFrom.z, vFrom.y );
01125
01126 }
01127
01128 } else {
01129
01130 v1.crossVectors( vFrom, vTo );
01131
01132 }
01133
01134 this._x = v1.x;
01135 this._y = v1.y;
01136 this._z = v1.z;
01137 this._w = r;
01138
01139 this.normalize();
01140
01141 return this;
01142
01143 }
01144
01145 }(),
01146
01147 inverse: function () {
01148
01149 this.conjugate().normalize();
01150
01151 return this;
01152
01153 },
01154
01155 conjugate: function () {
01156
01157 this._x *= - 1;
01158 this._y *= - 1;
01159 this._z *= - 1;
01160
01161 this.onChangeCallback();
01162
01163 return this;
01164
01165 },
01166
01167 dot: function ( v ) {
01168
01169 return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
01170
01171 },
01172
01173 lengthSq: function () {
01174
01175 return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
01176
01177 },
01178
01179 length: function () {
01180
01181 return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );
01182
01183 },
01184
01185 normalize: function () {
01186
01187 var l = this.length();
01188
01189 if ( l === 0 ) {
01190
01191 this._x = 0;
01192 this._y = 0;
01193 this._z = 0;
01194 this._w = 1;
01195
01196 } else {
01197
01198 l = 1 / l;
01199
01200 this._x = this._x * l;
01201 this._y = this._y * l;
01202 this._z = this._z * l;
01203 this._w = this._w * l;
01204
01205 }
01206
01207 this.onChangeCallback();
01208
01209 return this;
01210
01211 },
01212
01213 multiply: function ( q, p ) {
01214
01215 if ( p !== undefined ) {
01216
01217 console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );
01218 return this.multiplyQuaternions( q, p );
01219
01220 }
01221
01222 return this.multiplyQuaternions( this, q );
01223
01224 },
01225
01226 multiplyQuaternions: function ( a, b ) {
01227
01228
01229
01230 var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;
01231 var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;
01232
01233 this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
01234 this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
01235 this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
01236 this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
01237
01238 this.onChangeCallback();
01239
01240 return this;
01241
01242 },
01243
01244 multiplyVector3: function ( vector ) {
01245
01246 console.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );
01247 return vector.applyQuaternion( this );
01248
01249 },
01250
01251 slerp: function ( qb, t ) {
01252
01253 if ( t === 0 ) return this;
01254 if ( t === 1 ) return this.copy( qb );
01255
01256 var x = this._x, y = this._y, z = this._z, w = this._w;
01257
01258
01259
01260 var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;
01261
01262 if ( cosHalfTheta < 0 ) {
01263
01264 this._w = - qb._w;
01265 this._x = - qb._x;
01266 this._y = - qb._y;
01267 this._z = - qb._z;
01268
01269 cosHalfTheta = - cosHalfTheta;
01270
01271 } else {
01272
01273 this.copy( qb );
01274
01275 }
01276
01277 if ( cosHalfTheta >= 1.0 ) {
01278
01279 this._w = w;
01280 this._x = x;
01281 this._y = y;
01282 this._z = z;
01283
01284 return this;
01285
01286 }
01287
01288 var halfTheta = Math.acos( cosHalfTheta );
01289 var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );
01290
01291 if ( Math.abs( sinHalfTheta ) < 0.001 ) {
01292
01293 this._w = 0.5 * ( w + this._w );
01294 this._x = 0.5 * ( x + this._x );
01295 this._y = 0.5 * ( y + this._y );
01296 this._z = 0.5 * ( z + this._z );
01297
01298 return this;
01299
01300 }
01301
01302 var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
01303 ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
01304
01305 this._w = ( w * ratioA + this._w * ratioB );
01306 this._x = ( x * ratioA + this._x * ratioB );
01307 this._y = ( y * ratioA + this._y * ratioB );
01308 this._z = ( z * ratioA + this._z * ratioB );
01309
01310 this.onChangeCallback();
01311
01312 return this;
01313
01314 },
01315
01316 equals: function ( quaternion ) {
01317
01318 return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );
01319
01320 },
01321
01322 fromArray: function ( array, offset ) {
01323
01324 if ( offset === undefined ) offset = 0;
01325
01326 this._x = array[ offset ];
01327 this._y = array[ offset + 1 ];
01328 this._z = array[ offset + 2 ];
01329 this._w = array[ offset + 3 ];
01330
01331 this.onChangeCallback();
01332
01333 return this;
01334
01335 },
01336
01337 toArray: function ( array, offset ) {
01338
01339 if ( array === undefined ) array = [];
01340 if ( offset === undefined ) offset = 0;
01341
01342 array[ offset ] = this._x;
01343 array[ offset + 1 ] = this._y;
01344 array[ offset + 2 ] = this._z;
01345 array[ offset + 3 ] = this._w;
01346
01347 return array;
01348
01349 },
01350
01351 onChange: function ( callback ) {
01352
01353 this.onChangeCallback = callback;
01354
01355 return this;
01356
01357 },
01358
01359 onChangeCallback: function () {}
01360
01361 };
01362
01363 THREE.Quaternion.slerp = function ( qa, qb, qm, t ) {
01364
01365 return qm.copy( qa ).slerp( qb, t );
01366
01367 };
01368
01369
01370
01378 THREE.Vector2 = function ( x, y ) {
01379
01380 this.x = x || 0;
01381 this.y = y || 0;
01382
01383 };
01384
01385 THREE.Vector2.prototype = {
01386
01387 constructor: THREE.Vector2,
01388
01389 get width() { return this.x },
01390 set width( value ) { this.x = value },
01391
01392 get height() { return this.y },
01393 set height( value ) { this.y = value },
01394
01395
01396
01397 set: function ( x, y ) {
01398
01399 this.x = x;
01400 this.y = y;
01401
01402 return this;
01403
01404 },
01405
01406 setX: function ( x ) {
01407
01408 this.x = x;
01409
01410 return this;
01411
01412 },
01413
01414 setY: function ( y ) {
01415
01416 this.y = y;
01417
01418 return this;
01419
01420 },
01421
01422 setComponent: function ( index, value ) {
01423
01424 switch ( index ) {
01425
01426 case 0: this.x = value; break;
01427 case 1: this.y = value; break;
01428 default: throw new Error( 'index is out of range: ' + index );
01429
01430 }
01431
01432 },
01433
01434 getComponent: function ( index ) {
01435
01436 switch ( index ) {
01437
01438 case 0: return this.x;
01439 case 1: return this.y;
01440 default: throw new Error( 'index is out of range: ' + index );
01441
01442 }
01443
01444 },
01445
01446 clone: function () {
01447
01448 return new this.constructor( this.x, this.y );
01449
01450 },
01451
01452 copy: function ( v ) {
01453
01454 this.x = v.x;
01455 this.y = v.y;
01456
01457 return this;
01458
01459 },
01460
01461 add: function ( v, w ) {
01462
01463 if ( w !== undefined ) {
01464
01465 console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
01466 return this.addVectors( v, w );
01467
01468 }
01469
01470 this.x += v.x;
01471 this.y += v.y;
01472
01473 return this;
01474
01475 },
01476
01477 addScalar: function ( s ) {
01478
01479 this.x += s;
01480 this.y += s;
01481
01482 return this;
01483
01484 },
01485
01486 addVectors: function ( a, b ) {
01487
01488 this.x = a.x + b.x;
01489 this.y = a.y + b.y;
01490
01491 return this;
01492
01493 },
01494
01495 addScaledVector: function ( v, s ) {
01496
01497 this.x += v.x * s;
01498 this.y += v.y * s;
01499
01500 return this;
01501
01502 },
01503
01504 sub: function ( v, w ) {
01505
01506 if ( w !== undefined ) {
01507
01508 console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
01509 return this.subVectors( v, w );
01510
01511 }
01512
01513 this.x -= v.x;
01514 this.y -= v.y;
01515
01516 return this;
01517
01518 },
01519
01520 subScalar: function ( s ) {
01521
01522 this.x -= s;
01523 this.y -= s;
01524
01525 return this;
01526
01527 },
01528
01529 subVectors: function ( a, b ) {
01530
01531 this.x = a.x - b.x;
01532 this.y = a.y - b.y;
01533
01534 return this;
01535
01536 },
01537
01538 multiply: function ( v ) {
01539
01540 this.x *= v.x;
01541 this.y *= v.y;
01542
01543 return this;
01544
01545 },
01546
01547 multiplyScalar: function ( scalar ) {
01548
01549 if ( isFinite( scalar ) ) {
01550 this.x *= scalar;
01551 this.y *= scalar;
01552 } else {
01553 this.x = 0;
01554 this.y = 0;
01555 }
01556
01557 return this;
01558
01559 },
01560
01561 divide: function ( v ) {
01562
01563 this.x /= v.x;
01564 this.y /= v.y;
01565
01566 return this;
01567
01568 },
01569
01570 divideScalar: function ( scalar ) {
01571
01572 return this.multiplyScalar( 1 / scalar );
01573
01574 },
01575
01576 min: function ( v ) {
01577
01578 this.x = Math.min( this.x, v.x );
01579 this.y = Math.min( this.y, v.y );
01580
01581 return this;
01582
01583 },
01584
01585 max: function ( v ) {
01586
01587 this.x = Math.max( this.x, v.x );
01588 this.y = Math.max( this.y, v.y );
01589
01590 return this;
01591
01592 },
01593
01594 clamp: function ( min, max ) {
01595
01596
01597
01598 this.x = Math.max( min.x, Math.min( max.x, this.x ) );
01599 this.y = Math.max( min.y, Math.min( max.y, this.y ) );
01600
01601 return this;
01602
01603 },
01604
01605 clampScalar: function () {
01606
01607 var min, max;
01608
01609 return function clampScalar( minVal, maxVal ) {
01610
01611 if ( min === undefined ) {
01612
01613 min = new THREE.Vector2();
01614 max = new THREE.Vector2();
01615
01616 }
01617
01618 min.set( minVal, minVal );
01619 max.set( maxVal, maxVal );
01620
01621 return this.clamp( min, max );
01622
01623 };
01624
01625 }(),
01626
01627 clampLength: function ( min, max ) {
01628
01629 var length = this.length();
01630
01631 this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );
01632
01633 return this;
01634
01635 },
01636
01637 floor: function () {
01638
01639 this.x = Math.floor( this.x );
01640 this.y = Math.floor( this.y );
01641
01642 return this;
01643
01644 },
01645
01646 ceil: function () {
01647
01648 this.x = Math.ceil( this.x );
01649 this.y = Math.ceil( this.y );
01650
01651 return this;
01652
01653 },
01654
01655 round: function () {
01656
01657 this.x = Math.round( this.x );
01658 this.y = Math.round( this.y );
01659
01660 return this;
01661
01662 },
01663
01664 roundToZero: function () {
01665
01666 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
01667 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
01668
01669 return this;
01670
01671 },
01672
01673 negate: function () {
01674
01675 this.x = - this.x;
01676 this.y = - this.y;
01677
01678 return this;
01679
01680 },
01681
01682 dot: function ( v ) {
01683
01684 return this.x * v.x + this.y * v.y;
01685
01686 },
01687
01688 lengthSq: function () {
01689
01690 return this.x * this.x + this.y * this.y;
01691
01692 },
01693
01694 length: function () {
01695
01696 return Math.sqrt( this.x * this.x + this.y * this.y );
01697
01698 },
01699
01700 lengthManhattan: function() {
01701
01702 return Math.abs( this.x ) + Math.abs( this.y );
01703
01704 },
01705
01706 normalize: function () {
01707
01708 return this.divideScalar( this.length() );
01709
01710 },
01711
01712 distanceTo: function ( v ) {
01713
01714 return Math.sqrt( this.distanceToSquared( v ) );
01715
01716 },
01717
01718 distanceToSquared: function ( v ) {
01719
01720 var dx = this.x - v.x, dy = this.y - v.y;
01721 return dx * dx + dy * dy;
01722
01723 },
01724
01725 setLength: function ( length ) {
01726
01727 return this.multiplyScalar( length / this.length() );
01728
01729 },
01730
01731 lerp: function ( v, alpha ) {
01732
01733 this.x += ( v.x - this.x ) * alpha;
01734 this.y += ( v.y - this.y ) * alpha;
01735
01736 return this;
01737
01738 },
01739
01740 lerpVectors: function ( v1, v2, alpha ) {
01741
01742 this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );
01743
01744 return this;
01745
01746 },
01747
01748 equals: function ( v ) {
01749
01750 return ( ( v.x === this.x ) && ( v.y === this.y ) );
01751
01752 },
01753
01754 fromArray: function ( array, offset ) {
01755
01756 if ( offset === undefined ) offset = 0;
01757
01758 this.x = array[ offset ];
01759 this.y = array[ offset + 1 ];
01760
01761 return this;
01762
01763 },
01764
01765 toArray: function ( array, offset ) {
01766
01767 if ( array === undefined ) array = [];
01768 if ( offset === undefined ) offset = 0;
01769
01770 array[ offset ] = this.x;
01771 array[ offset + 1 ] = this.y;
01772
01773 return array;
01774
01775 },
01776
01777 fromAttribute: function ( attribute, index, offset ) {
01778
01779 if ( offset === undefined ) offset = 0;
01780
01781 index = index * attribute.itemSize + offset;
01782
01783 this.x = attribute.array[ index ];
01784 this.y = attribute.array[ index + 1 ];
01785
01786 return this;
01787
01788 },
01789
01790 rotateAround: function ( center, angle ) {
01791
01792 var c = Math.cos( angle ), s = Math.sin( angle );
01793
01794 var x = this.x - center.x;
01795 var y = this.y - center.y;
01796
01797 this.x = x * c - y * s + center.x;
01798 this.y = x * s + y * c + center.y;
01799
01800 return this;
01801
01802 }
01803
01804 };
01805
01806
01807
01817 THREE.Vector3 = function ( x, y, z ) {
01818
01819 this.x = x || 0;
01820 this.y = y || 0;
01821 this.z = z || 0;
01822
01823 };
01824
01825 THREE.Vector3.prototype = {
01826
01827 constructor: THREE.Vector3,
01828
01829 set: function ( x, y, z ) {
01830
01831 this.x = x;
01832 this.y = y;
01833 this.z = z;
01834
01835 return this;
01836
01837 },
01838
01839 setX: function ( x ) {
01840
01841 this.x = x;
01842
01843 return this;
01844
01845 },
01846
01847 setY: function ( y ) {
01848
01849 this.y = y;
01850
01851 return this;
01852
01853 },
01854
01855 setZ: function ( z ) {
01856
01857 this.z = z;
01858
01859 return this;
01860
01861 },
01862
01863 setComponent: function ( index, value ) {
01864
01865 switch ( index ) {
01866
01867 case 0: this.x = value; break;
01868 case 1: this.y = value; break;
01869 case 2: this.z = value; break;
01870 default: throw new Error( 'index is out of range: ' + index );
01871
01872 }
01873
01874 },
01875
01876 getComponent: function ( index ) {
01877
01878 switch ( index ) {
01879
01880 case 0: return this.x;
01881 case 1: return this.y;
01882 case 2: return this.z;
01883 default: throw new Error( 'index is out of range: ' + index );
01884
01885 }
01886
01887 },
01888
01889 clone: function () {
01890
01891 return new this.constructor( this.x, this.y, this.z );
01892
01893 },
01894
01895 copy: function ( v ) {
01896
01897 this.x = v.x;
01898 this.y = v.y;
01899 this.z = v.z;
01900
01901 return this;
01902
01903 },
01904
01905 add: function ( v, w ) {
01906
01907 if ( w !== undefined ) {
01908
01909 console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
01910 return this.addVectors( v, w );
01911
01912 }
01913
01914 this.x += v.x;
01915 this.y += v.y;
01916 this.z += v.z;
01917
01918 return this;
01919
01920 },
01921
01922 addScalar: function ( s ) {
01923
01924 this.x += s;
01925 this.y += s;
01926 this.z += s;
01927
01928 return this;
01929
01930 },
01931
01932 addVectors: function ( a, b ) {
01933
01934 this.x = a.x + b.x;
01935 this.y = a.y + b.y;
01936 this.z = a.z + b.z;
01937
01938 return this;
01939
01940 },
01941
01942 addScaledVector: function ( v, s ) {
01943
01944 this.x += v.x * s;
01945 this.y += v.y * s;
01946 this.z += v.z * s;
01947
01948 return this;
01949
01950 },
01951
01952 sub: function ( v, w ) {
01953
01954 if ( w !== undefined ) {
01955
01956 console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
01957 return this.subVectors( v, w );
01958
01959 }
01960
01961 this.x -= v.x;
01962 this.y -= v.y;
01963 this.z -= v.z;
01964
01965 return this;
01966
01967 },
01968
01969 subScalar: function ( s ) {
01970
01971 this.x -= s;
01972 this.y -= s;
01973 this.z -= s;
01974
01975 return this;
01976
01977 },
01978
01979 subVectors: function ( a, b ) {
01980
01981 this.x = a.x - b.x;
01982 this.y = a.y - b.y;
01983 this.z = a.z - b.z;
01984
01985 return this;
01986
01987 },
01988
01989 multiply: function ( v, w ) {
01990
01991 if ( w !== undefined ) {
01992
01993 console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );
01994 return this.multiplyVectors( v, w );
01995
01996 }
01997
01998 this.x *= v.x;
01999 this.y *= v.y;
02000 this.z *= v.z;
02001
02002 return this;
02003
02004 },
02005
02006 multiplyScalar: function ( scalar ) {
02007
02008 if ( isFinite( scalar ) ) {
02009 this.x *= scalar;
02010 this.y *= scalar;
02011 this.z *= scalar;
02012 } else {
02013 this.x = 0;
02014 this.y = 0;
02015 this.z = 0;
02016 }
02017
02018 return this;
02019
02020 },
02021
02022 multiplyVectors: function ( a, b ) {
02023
02024 this.x = a.x * b.x;
02025 this.y = a.y * b.y;
02026 this.z = a.z * b.z;
02027
02028 return this;
02029
02030 },
02031
02032 applyEuler: function () {
02033
02034 var quaternion;
02035
02036 return function applyEuler( euler ) {
02037
02038 if ( euler instanceof THREE.Euler === false ) {
02039
02040 console.error( 'THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.' );
02041
02042 }
02043
02044 if ( quaternion === undefined ) quaternion = new THREE.Quaternion();
02045
02046 this.applyQuaternion( quaternion.setFromEuler( euler ) );
02047
02048 return this;
02049
02050 };
02051
02052 }(),
02053
02054 applyAxisAngle: function () {
02055
02056 var quaternion;
02057
02058 return function applyAxisAngle( axis, angle ) {
02059
02060 if ( quaternion === undefined ) quaternion = new THREE.Quaternion();
02061
02062 this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );
02063
02064 return this;
02065
02066 };
02067
02068 }(),
02069
02070 applyMatrix3: function ( m ) {
02071
02072 var x = this.x;
02073 var y = this.y;
02074 var z = this.z;
02075
02076 var e = m.elements;
02077
02078 this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;
02079 this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;
02080 this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;
02081
02082 return this;
02083
02084 },
02085
02086 applyMatrix4: function ( m ) {
02087
02088
02089
02090 var x = this.x, y = this.y, z = this.z;
02091
02092 var e = m.elements;
02093
02094 this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];
02095 this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];
02096 this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];
02097
02098 return this;
02099
02100 },
02101
02102 applyProjection: function ( m ) {
02103
02104
02105
02106 var x = this.x, y = this.y, z = this.z;
02107
02108 var e = m.elements;
02109 var d = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] );
02110
02111 this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * d;
02112 this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * d;
02113 this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * d;
02114
02115 return this;
02116
02117 },
02118
02119 applyQuaternion: function ( q ) {
02120
02121 var x = this.x;
02122 var y = this.y;
02123 var z = this.z;
02124
02125 var qx = q.x;
02126 var qy = q.y;
02127 var qz = q.z;
02128 var qw = q.w;
02129
02130
02131
02132 var ix = qw * x + qy * z - qz * y;
02133 var iy = qw * y + qz * x - qx * z;
02134 var iz = qw * z + qx * y - qy * x;
02135 var iw = - qx * x - qy * y - qz * z;
02136
02137
02138
02139 this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
02140 this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
02141 this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;
02142
02143 return this;
02144
02145 },
02146
02147 project: function () {
02148
02149 var matrix;
02150
02151 return function project( camera ) {
02152
02153 if ( matrix === undefined ) matrix = new THREE.Matrix4();
02154
02155 matrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );
02156 return this.applyProjection( matrix );
02157
02158 };
02159
02160 }(),
02161
02162 unproject: function () {
02163
02164 var matrix;
02165
02166 return function unproject( camera ) {
02167
02168 if ( matrix === undefined ) matrix = new THREE.Matrix4();
02169
02170 matrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );
02171 return this.applyProjection( matrix );
02172
02173 };
02174
02175 }(),
02176
02177 transformDirection: function ( m ) {
02178
02179
02180
02181
02182 var x = this.x, y = this.y, z = this.z;
02183
02184 var e = m.elements;
02185
02186 this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;
02187 this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;
02188 this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;
02189
02190 this.normalize();
02191
02192 return this;
02193
02194 },
02195
02196 divide: function ( v ) {
02197
02198 this.x /= v.x;
02199 this.y /= v.y;
02200 this.z /= v.z;
02201
02202 return this;
02203
02204 },
02205
02206 divideScalar: function ( scalar ) {
02207
02208 return this.multiplyScalar( 1 / scalar );
02209
02210 },
02211
02212 min: function ( v ) {
02213
02214 this.x = Math.min( this.x, v.x );
02215 this.y = Math.min( this.y, v.y );
02216 this.z = Math.min( this.z, v.z );
02217
02218 return this;
02219
02220 },
02221
02222 max: function ( v ) {
02223
02224 this.x = Math.max( this.x, v.x );
02225 this.y = Math.max( this.y, v.y );
02226 this.z = Math.max( this.z, v.z );
02227
02228 return this;
02229
02230 },
02231
02232 clamp: function ( min, max ) {
02233
02234
02235
02236 this.x = Math.max( min.x, Math.min( max.x, this.x ) );
02237 this.y = Math.max( min.y, Math.min( max.y, this.y ) );
02238 this.z = Math.max( min.z, Math.min( max.z, this.z ) );
02239
02240 return this;
02241
02242 },
02243
02244 clampScalar: function () {
02245
02246 var min, max;
02247
02248 return function clampScalar( minVal, maxVal ) {
02249
02250 if ( min === undefined ) {
02251
02252 min = new THREE.Vector3();
02253 max = new THREE.Vector3();
02254
02255 }
02256
02257 min.set( minVal, minVal, minVal );
02258 max.set( maxVal, maxVal, maxVal );
02259
02260 return this.clamp( min, max );
02261
02262 };
02263
02264 }(),
02265
02266 clampLength: function ( min, max ) {
02267
02268 var length = this.length();
02269
02270 this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );
02271
02272 return this;
02273
02274 },
02275
02276 floor: function () {
02277
02278 this.x = Math.floor( this.x );
02279 this.y = Math.floor( this.y );
02280 this.z = Math.floor( this.z );
02281
02282 return this;
02283
02284 },
02285
02286 ceil: function () {
02287
02288 this.x = Math.ceil( this.x );
02289 this.y = Math.ceil( this.y );
02290 this.z = Math.ceil( this.z );
02291
02292 return this;
02293
02294 },
02295
02296 round: function () {
02297
02298 this.x = Math.round( this.x );
02299 this.y = Math.round( this.y );
02300 this.z = Math.round( this.z );
02301
02302 return this;
02303
02304 },
02305
02306 roundToZero: function () {
02307
02308 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
02309 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
02310 this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
02311
02312 return this;
02313
02314 },
02315
02316 negate: function () {
02317
02318 this.x = - this.x;
02319 this.y = - this.y;
02320 this.z = - this.z;
02321
02322 return this;
02323
02324 },
02325
02326 dot: function ( v ) {
02327
02328 return this.x * v.x + this.y * v.y + this.z * v.z;
02329
02330 },
02331
02332 lengthSq: function () {
02333
02334 return this.x * this.x + this.y * this.y + this.z * this.z;
02335
02336 },
02337
02338 length: function () {
02339
02340 return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
02341
02342 },
02343
02344 lengthManhattan: function () {
02345
02346 return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );
02347
02348 },
02349
02350 normalize: function () {
02351
02352 return this.divideScalar( this.length() );
02353
02354 },
02355
02356 setLength: function ( length ) {
02357
02358 return this.multiplyScalar( length / this.length() );
02359
02360 },
02361
02362 lerp: function ( v, alpha ) {
02363
02364 this.x += ( v.x - this.x ) * alpha;
02365 this.y += ( v.y - this.y ) * alpha;
02366 this.z += ( v.z - this.z ) * alpha;
02367
02368 return this;
02369
02370 },
02371
02372 lerpVectors: function ( v1, v2, alpha ) {
02373
02374 this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );
02375
02376 return this;
02377
02378 },
02379
02380 cross: function ( v, w ) {
02381
02382 if ( w !== undefined ) {
02383
02384 console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );
02385 return this.crossVectors( v, w );
02386
02387 }
02388
02389 var x = this.x, y = this.y, z = this.z;
02390
02391 this.x = y * v.z - z * v.y;
02392 this.y = z * v.x - x * v.z;
02393 this.z = x * v.y - y * v.x;
02394
02395 return this;
02396
02397 },
02398
02399 crossVectors: function ( a, b ) {
02400
02401 var ax = a.x, ay = a.y, az = a.z;
02402 var bx = b.x, by = b.y, bz = b.z;
02403
02404 this.x = ay * bz - az * by;
02405 this.y = az * bx - ax * bz;
02406 this.z = ax * by - ay * bx;
02407
02408 return this;
02409
02410 },
02411
02412 projectOnVector: function () {
02413
02414 var v1, dot;
02415
02416 return function projectOnVector( vector ) {
02417
02418 if ( v1 === undefined ) v1 = new THREE.Vector3();
02419
02420 v1.copy( vector ).normalize();
02421
02422 dot = this.dot( v1 );
02423
02424 return this.copy( v1 ).multiplyScalar( dot );
02425
02426 };
02427
02428 }(),
02429
02430 projectOnPlane: function () {
02431
02432 var v1;
02433
02434 return function projectOnPlane( planeNormal ) {
02435
02436 if ( v1 === undefined ) v1 = new THREE.Vector3();
02437
02438 v1.copy( this ).projectOnVector( planeNormal );
02439
02440 return this.sub( v1 );
02441
02442 }
02443
02444 }(),
02445
02446 reflect: function () {
02447
02448
02449
02450
02451 var v1;
02452
02453 return function reflect( normal ) {
02454
02455 if ( v1 === undefined ) v1 = new THREE.Vector3();
02456
02457 return this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );
02458
02459 }
02460
02461 }(),
02462
02463 angleTo: function ( v ) {
02464
02465 var theta = this.dot( v ) / ( this.length() * v.length() );
02466
02467
02468
02469 return Math.acos( THREE.Math.clamp( theta, - 1, 1 ) );
02470
02471 },
02472
02473 distanceTo: function ( v ) {
02474
02475 return Math.sqrt( this.distanceToSquared( v ) );
02476
02477 },
02478
02479 distanceToSquared: function ( v ) {
02480
02481 var dx = this.x - v.x;
02482 var dy = this.y - v.y;
02483 var dz = this.z - v.z;
02484
02485 return dx * dx + dy * dy + dz * dz;
02486
02487 },
02488
02489 setEulerFromRotationMatrix: function ( m, order ) {
02490
02491 console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );
02492
02493 },
02494
02495 setEulerFromQuaternion: function ( q, order ) {
02496
02497 console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );
02498
02499 },
02500
02501 getPositionFromMatrix: function ( m ) {
02502
02503 console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );
02504
02505 return this.setFromMatrixPosition( m );
02506
02507 },
02508
02509 getScaleFromMatrix: function ( m ) {
02510
02511 console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );
02512
02513 return this.setFromMatrixScale( m );
02514
02515 },
02516
02517 getColumnFromMatrix: function ( index, matrix ) {
02518
02519 console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );
02520
02521 return this.setFromMatrixColumn( index, matrix );
02522
02523 },
02524
02525 setFromMatrixPosition: function ( m ) {
02526
02527 this.x = m.elements[ 12 ];
02528 this.y = m.elements[ 13 ];
02529 this.z = m.elements[ 14 ];
02530
02531 return this;
02532
02533 },
02534
02535 setFromMatrixScale: function ( m ) {
02536
02537 var sx = this.set( m.elements[ 0 ], m.elements[ 1 ], m.elements[ 2 ] ).length();
02538 var sy = this.set( m.elements[ 4 ], m.elements[ 5 ], m.elements[ 6 ] ).length();
02539 var sz = this.set( m.elements[ 8 ], m.elements[ 9 ], m.elements[ 10 ] ).length();
02540
02541 this.x = sx;
02542 this.y = sy;
02543 this.z = sz;
02544
02545 return this;
02546
02547 },
02548
02549 setFromMatrixColumn: function ( index, matrix ) {
02550
02551 var offset = index * 4;
02552
02553 var me = matrix.elements;
02554
02555 this.x = me[ offset ];
02556 this.y = me[ offset + 1 ];
02557 this.z = me[ offset + 2 ];
02558
02559 return this;
02560
02561 },
02562
02563 equals: function ( v ) {
02564
02565 return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );
02566
02567 },
02568
02569 fromArray: function ( array, offset ) {
02570
02571 if ( offset === undefined ) offset = 0;
02572
02573 this.x = array[ offset ];
02574 this.y = array[ offset + 1 ];
02575 this.z = array[ offset + 2 ];
02576
02577 return this;
02578
02579 },
02580
02581 toArray: function ( array, offset ) {
02582
02583 if ( array === undefined ) array = [];
02584 if ( offset === undefined ) offset = 0;
02585
02586 array[ offset ] = this.x;
02587 array[ offset + 1 ] = this.y;
02588 array[ offset + 2 ] = this.z;
02589
02590 return array;
02591
02592 },
02593
02594 fromAttribute: function ( attribute, index, offset ) {
02595
02596 if ( offset === undefined ) offset = 0;
02597
02598 index = index * attribute.itemSize + offset;
02599
02600 this.x = attribute.array[ index ];
02601 this.y = attribute.array[ index + 1 ];
02602 this.z = attribute.array[ index + 2 ];
02603
02604 return this;
02605
02606 }
02607
02608 };
02609
02610
02611
02620 THREE.Vector4 = function ( x, y, z, w ) {
02621
02622 this.x = x || 0;
02623 this.y = y || 0;
02624 this.z = z || 0;
02625 this.w = ( w !== undefined ) ? w : 1;
02626
02627 };
02628
02629 THREE.Vector4.prototype = {
02630
02631 constructor: THREE.Vector4,
02632
02633 set: function ( x, y, z, w ) {
02634
02635 this.x = x;
02636 this.y = y;
02637 this.z = z;
02638 this.w = w;
02639
02640 return this;
02641
02642 },
02643
02644 setX: function ( x ) {
02645
02646 this.x = x;
02647
02648 return this;
02649
02650 },
02651
02652 setY: function ( y ) {
02653
02654 this.y = y;
02655
02656 return this;
02657
02658 },
02659
02660 setZ: function ( z ) {
02661
02662 this.z = z;
02663
02664 return this;
02665
02666 },
02667
02668 setW: function ( w ) {
02669
02670 this.w = w;
02671
02672 return this;
02673
02674 },
02675
02676 setComponent: function ( index, value ) {
02677
02678 switch ( index ) {
02679
02680 case 0: this.x = value; break;
02681 case 1: this.y = value; break;
02682 case 2: this.z = value; break;
02683 case 3: this.w = value; break;
02684 default: throw new Error( 'index is out of range: ' + index );
02685
02686 }
02687
02688 },
02689
02690 getComponent: function ( index ) {
02691
02692 switch ( index ) {
02693
02694 case 0: return this.x;
02695 case 1: return this.y;
02696 case 2: return this.z;
02697 case 3: return this.w;
02698 default: throw new Error( 'index is out of range: ' + index );
02699
02700 }
02701
02702 },
02703
02704 clone: function () {
02705
02706 return new this.constructor( this.x, this.y, this.z, this.w );
02707
02708 },
02709
02710 copy: function ( v ) {
02711
02712 this.x = v.x;
02713 this.y = v.y;
02714 this.z = v.z;
02715 this.w = ( v.w !== undefined ) ? v.w : 1;
02716
02717 return this;
02718
02719 },
02720
02721 add: function ( v, w ) {
02722
02723 if ( w !== undefined ) {
02724
02725 console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
02726 return this.addVectors( v, w );
02727
02728 }
02729
02730 this.x += v.x;
02731 this.y += v.y;
02732 this.z += v.z;
02733 this.w += v.w;
02734
02735 return this;
02736
02737 },
02738
02739 addScalar: function ( s ) {
02740
02741 this.x += s;
02742 this.y += s;
02743 this.z += s;
02744 this.w += s;
02745
02746 return this;
02747
02748 },
02749
02750 addVectors: function ( a, b ) {
02751
02752 this.x = a.x + b.x;
02753 this.y = a.y + b.y;
02754 this.z = a.z + b.z;
02755 this.w = a.w + b.w;
02756
02757 return this;
02758
02759 },
02760
02761 addScaledVector: function ( v, s ) {
02762
02763 this.x += v.x * s;
02764 this.y += v.y * s;
02765 this.z += v.z * s;
02766 this.w += v.w * s;
02767
02768 return this;
02769
02770 },
02771
02772 sub: function ( v, w ) {
02773
02774 if ( w !== undefined ) {
02775
02776 console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
02777 return this.subVectors( v, w );
02778
02779 }
02780
02781 this.x -= v.x;
02782 this.y -= v.y;
02783 this.z -= v.z;
02784 this.w -= v.w;
02785
02786 return this;
02787
02788 },
02789
02790 subScalar: function ( s ) {
02791
02792 this.x -= s;
02793 this.y -= s;
02794 this.z -= s;
02795 this.w -= s;
02796
02797 return this;
02798
02799 },
02800
02801 subVectors: function ( a, b ) {
02802
02803 this.x = a.x - b.x;
02804 this.y = a.y - b.y;
02805 this.z = a.z - b.z;
02806 this.w = a.w - b.w;
02807
02808 return this;
02809
02810 },
02811
02812 multiplyScalar: function ( scalar ) {
02813
02814 if ( isFinite( scalar ) ) {
02815 this.x *= scalar;
02816 this.y *= scalar;
02817 this.z *= scalar;
02818 this.w *= scalar;
02819 } else {
02820 this.x = 0;
02821 this.y = 0;
02822 this.z = 0;
02823 this.w = 0;
02824 }
02825
02826 return this;
02827
02828 },
02829
02830 applyMatrix4: function ( m ) {
02831
02832 var x = this.x;
02833 var y = this.y;
02834 var z = this.z;
02835 var w = this.w;
02836
02837 var e = m.elements;
02838
02839 this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;
02840 this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;
02841 this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;
02842 this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;
02843
02844 return this;
02845
02846 },
02847
02848 divideScalar: function ( scalar ) {
02849
02850 return this.multiplyScalar( 1 / scalar );
02851
02852 },
02853
02854 setAxisAngleFromQuaternion: function ( q ) {
02855
02856
02857
02858
02859
02860 this.w = 2 * Math.acos( q.w );
02861
02862 var s = Math.sqrt( 1 - q.w * q.w );
02863
02864 if ( s < 0.0001 ) {
02865
02866 this.x = 1;
02867 this.y = 0;
02868 this.z = 0;
02869
02870 } else {
02871
02872 this.x = q.x / s;
02873 this.y = q.y / s;
02874 this.z = q.z / s;
02875
02876 }
02877
02878 return this;
02879
02880 },
02881
02882 setAxisAngleFromRotationMatrix: function ( m ) {
02883
02884
02885
02886
02887
02888 var angle, x, y, z,
02889 epsilon = 0.01,
02890 epsilon2 = 0.1,
02891
02892 te = m.elements,
02893
02894 m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],
02895 m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],
02896 m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];
02897
02898 if ( ( Math.abs( m12 - m21 ) < epsilon )
02899 && ( Math.abs( m13 - m31 ) < epsilon )
02900 && ( Math.abs( m23 - m32 ) < epsilon ) ) {
02901
02902
02903
02904
02905
02906 if ( ( Math.abs( m12 + m21 ) < epsilon2 )
02907 && ( Math.abs( m13 + m31 ) < epsilon2 )
02908 && ( Math.abs( m23 + m32 ) < epsilon2 )
02909 && ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {
02910
02911
02912
02913 this.set( 1, 0, 0, 0 );
02914
02915 return this;
02916
02917 }
02918
02919
02920
02921 angle = Math.PI;
02922
02923 var xx = ( m11 + 1 ) / 2;
02924 var yy = ( m22 + 1 ) / 2;
02925 var zz = ( m33 + 1 ) / 2;
02926 var xy = ( m12 + m21 ) / 4;
02927 var xz = ( m13 + m31 ) / 4;
02928 var yz = ( m23 + m32 ) / 4;
02929
02930 if ( ( xx > yy ) && ( xx > zz ) ) {
02931
02932
02933
02934 if ( xx < epsilon ) {
02935
02936 x = 0;
02937 y = 0.707106781;
02938 z = 0.707106781;
02939
02940 } else {
02941
02942 x = Math.sqrt( xx );
02943 y = xy / x;
02944 z = xz / x;
02945
02946 }
02947
02948 } else if ( yy > zz ) {
02949
02950
02951
02952 if ( yy < epsilon ) {
02953
02954 x = 0.707106781;
02955 y = 0;
02956 z = 0.707106781;
02957
02958 } else {
02959
02960 y = Math.sqrt( yy );
02961 x = xy / y;
02962 z = yz / y;
02963
02964 }
02965
02966 } else {
02967
02968
02969
02970 if ( zz < epsilon ) {
02971
02972 x = 0.707106781;
02973 y = 0.707106781;
02974 z = 0;
02975
02976 } else {
02977
02978 z = Math.sqrt( zz );
02979 x = xz / z;
02980 y = yz / z;
02981
02982 }
02983
02984 }
02985
02986 this.set( x, y, z, angle );
02987
02988 return this;
02989
02990 }
02991
02992
02993
02994 var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 )
02995 + ( m13 - m31 ) * ( m13 - m31 )
02996 + ( m21 - m12 ) * ( m21 - m12 ) );
02997
02998 if ( Math.abs( s ) < 0.001 ) s = 1;
02999
03000
03001
03002
03003 this.x = ( m32 - m23 ) / s;
03004 this.y = ( m13 - m31 ) / s;
03005 this.z = ( m21 - m12 ) / s;
03006 this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );
03007
03008 return this;
03009
03010 },
03011
03012 min: function ( v ) {
03013
03014 this.x = Math.min( this.x, v.x );
03015 this.y = Math.min( this.y, v.y );
03016 this.z = Math.min( this.z, v.z );
03017 this.w = Math.min( this.w, v.w );
03018
03019 return this;
03020
03021 },
03022
03023 max: function ( v ) {
03024
03025 this.x = Math.max( this.x, v.x );
03026 this.y = Math.max( this.y, v.y );
03027 this.z = Math.max( this.z, v.z );
03028 this.w = Math.max( this.w, v.w );
03029
03030 return this;
03031
03032 },
03033
03034 clamp: function ( min, max ) {
03035
03036
03037
03038 this.x = Math.max( min.x, Math.min( max.x, this.x ) );
03039 this.y = Math.max( min.y, Math.min( max.y, this.y ) );
03040 this.z = Math.max( min.z, Math.min( max.z, this.z ) );
03041 this.w = Math.max( min.w, Math.min( max.w, this.w ) );
03042
03043 return this;
03044
03045 },
03046
03047 clampScalar: function () {
03048
03049 var min, max;
03050
03051 return function clampScalar( minVal, maxVal ) {
03052
03053 if ( min === undefined ) {
03054
03055 min = new THREE.Vector4();
03056 max = new THREE.Vector4();
03057
03058 }
03059
03060 min.set( minVal, minVal, minVal, minVal );
03061 max.set( maxVal, maxVal, maxVal, maxVal );
03062
03063 return this.clamp( min, max );
03064
03065 };
03066
03067 }(),
03068
03069 floor: function () {
03070
03071 this.x = Math.floor( this.x );
03072 this.y = Math.floor( this.y );
03073 this.z = Math.floor( this.z );
03074 this.w = Math.floor( this.w );
03075
03076 return this;
03077
03078 },
03079
03080 ceil: function () {
03081
03082 this.x = Math.ceil( this.x );
03083 this.y = Math.ceil( this.y );
03084 this.z = Math.ceil( this.z );
03085 this.w = Math.ceil( this.w );
03086
03087 return this;
03088
03089 },
03090
03091 round: function () {
03092
03093 this.x = Math.round( this.x );
03094 this.y = Math.round( this.y );
03095 this.z = Math.round( this.z );
03096 this.w = Math.round( this.w );
03097
03098 return this;
03099
03100 },
03101
03102 roundToZero: function () {
03103
03104 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
03105 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
03106 this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
03107 this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );
03108
03109 return this;
03110
03111 },
03112
03113 negate: function () {
03114
03115 this.x = - this.x;
03116 this.y = - this.y;
03117 this.z = - this.z;
03118 this.w = - this.w;
03119
03120 return this;
03121
03122 },
03123
03124 dot: function ( v ) {
03125
03126 return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
03127
03128 },
03129
03130 lengthSq: function () {
03131
03132 return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
03133
03134 },
03135
03136 length: function () {
03137
03138 return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
03139
03140 },
03141
03142 lengthManhattan: function () {
03143
03144 return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );
03145
03146 },
03147
03148 normalize: function () {
03149
03150 return this.divideScalar( this.length() );
03151
03152 },
03153
03154 setLength: function ( length ) {
03155
03156 return this.multiplyScalar( length / this.length() );
03157
03158 },
03159
03160 lerp: function ( v, alpha ) {
03161
03162 this.x += ( v.x - this.x ) * alpha;
03163 this.y += ( v.y - this.y ) * alpha;
03164 this.z += ( v.z - this.z ) * alpha;
03165 this.w += ( v.w - this.w ) * alpha;
03166
03167 return this;
03168
03169 },
03170
03171 lerpVectors: function ( v1, v2, alpha ) {
03172
03173 this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );
03174
03175 return this;
03176
03177 },
03178
03179 equals: function ( v ) {
03180
03181 return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );
03182
03183 },
03184
03185 fromArray: function ( array, offset ) {
03186
03187 if ( offset === undefined ) offset = 0;
03188
03189 this.x = array[ offset ];
03190 this.y = array[ offset + 1 ];
03191 this.z = array[ offset + 2 ];
03192 this.w = array[ offset + 3 ];
03193
03194 return this;
03195
03196 },
03197
03198 toArray: function ( array, offset ) {
03199
03200 if ( array === undefined ) array = [];
03201 if ( offset === undefined ) offset = 0;
03202
03203 array[ offset ] = this.x;
03204 array[ offset + 1 ] = this.y;
03205 array[ offset + 2 ] = this.z;
03206 array[ offset + 3 ] = this.w;
03207
03208 return array;
03209
03210 },
03211
03212 fromAttribute: function ( attribute, index, offset ) {
03213
03214 if ( offset === undefined ) offset = 0;
03215
03216 index = index * attribute.itemSize + offset;
03217
03218 this.x = attribute.array[ index ];
03219 this.y = attribute.array[ index + 1 ];
03220 this.z = attribute.array[ index + 2 ];
03221 this.w = attribute.array[ index + 3 ];
03222
03223 return this;
03224
03225 }
03226
03227 };
03228
03229
03230
03237 THREE.Euler = function ( x, y, z, order ) {
03238
03239 this._x = x || 0;
03240 this._y = y || 0;
03241 this._z = z || 0;
03242 this._order = order || THREE.Euler.DefaultOrder;
03243
03244 };
03245
03246 THREE.Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];
03247
03248 THREE.Euler.DefaultOrder = 'XYZ';
03249
03250 THREE.Euler.prototype = {
03251
03252 constructor: THREE.Euler,
03253
03254 get x () {
03255
03256 return this._x;
03257
03258 },
03259
03260 set x ( value ) {
03261
03262 this._x = value;
03263 this.onChangeCallback();
03264
03265 },
03266
03267 get y () {
03268
03269 return this._y;
03270
03271 },
03272
03273 set y ( value ) {
03274
03275 this._y = value;
03276 this.onChangeCallback();
03277
03278 },
03279
03280 get z () {
03281
03282 return this._z;
03283
03284 },
03285
03286 set z ( value ) {
03287
03288 this._z = value;
03289 this.onChangeCallback();
03290
03291 },
03292
03293 get order () {
03294
03295 return this._order;
03296
03297 },
03298
03299 set order ( value ) {
03300
03301 this._order = value;
03302 this.onChangeCallback();
03303
03304 },
03305
03306 set: function ( x, y, z, order ) {
03307
03308 this._x = x;
03309 this._y = y;
03310 this._z = z;
03311 this._order = order || this._order;
03312
03313 this.onChangeCallback();
03314
03315 return this;
03316
03317 },
03318
03319 clone: function () {
03320
03321 return new this.constructor( this._x, this._y, this._z, this._order);
03322
03323 },
03324
03325 copy: function ( euler ) {
03326
03327 this._x = euler._x;
03328 this._y = euler._y;
03329 this._z = euler._z;
03330 this._order = euler._order;
03331
03332 this.onChangeCallback();
03333
03334 return this;
03335
03336 },
03337
03338 setFromRotationMatrix: function ( m, order, update ) {
03339
03340 var clamp = THREE.Math.clamp;
03341
03342
03343
03344 var te = m.elements;
03345 var m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];
03346 var m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];
03347 var m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];
03348
03349 order = order || this._order;
03350
03351 if ( order === 'XYZ' ) {
03352
03353 this._y = Math.asin( clamp( m13, - 1, 1 ) );
03354
03355 if ( Math.abs( m13 ) < 0.99999 ) {
03356
03357 this._x = Math.atan2( - m23, m33 );
03358 this._z = Math.atan2( - m12, m11 );
03359
03360 } else {
03361
03362 this._x = Math.atan2( m32, m22 );
03363 this._z = 0;
03364
03365 }
03366
03367 } else if ( order === 'YXZ' ) {
03368
03369 this._x = Math.asin( - clamp( m23, - 1, 1 ) );
03370
03371 if ( Math.abs( m23 ) < 0.99999 ) {
03372
03373 this._y = Math.atan2( m13, m33 );
03374 this._z = Math.atan2( m21, m22 );
03375
03376 } else {
03377
03378 this._y = Math.atan2( - m31, m11 );
03379 this._z = 0;
03380
03381 }
03382
03383 } else if ( order === 'ZXY' ) {
03384
03385 this._x = Math.asin( clamp( m32, - 1, 1 ) );
03386
03387 if ( Math.abs( m32 ) < 0.99999 ) {
03388
03389 this._y = Math.atan2( - m31, m33 );
03390 this._z = Math.atan2( - m12, m22 );
03391
03392 } else {
03393
03394 this._y = 0;
03395 this._z = Math.atan2( m21, m11 );
03396
03397 }
03398
03399 } else if ( order === 'ZYX' ) {
03400
03401 this._y = Math.asin( - clamp( m31, - 1, 1 ) );
03402
03403 if ( Math.abs( m31 ) < 0.99999 ) {
03404
03405 this._x = Math.atan2( m32, m33 );
03406 this._z = Math.atan2( m21, m11 );
03407
03408 } else {
03409
03410 this._x = 0;
03411 this._z = Math.atan2( - m12, m22 );
03412
03413 }
03414
03415 } else if ( order === 'YZX' ) {
03416
03417 this._z = Math.asin( clamp( m21, - 1, 1 ) );
03418
03419 if ( Math.abs( m21 ) < 0.99999 ) {
03420
03421 this._x = Math.atan2( - m23, m22 );
03422 this._y = Math.atan2( - m31, m11 );
03423
03424 } else {
03425
03426 this._x = 0;
03427 this._y = Math.atan2( m13, m33 );
03428
03429 }
03430
03431 } else if ( order === 'XZY' ) {
03432
03433 this._z = Math.asin( - clamp( m12, - 1, 1 ) );
03434
03435 if ( Math.abs( m12 ) < 0.99999 ) {
03436
03437 this._x = Math.atan2( m32, m22 );
03438 this._y = Math.atan2( m13, m11 );
03439
03440 } else {
03441
03442 this._x = Math.atan2( - m23, m33 );
03443 this._y = 0;
03444
03445 }
03446
03447 } else {
03448
03449 console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order )
03450
03451 }
03452
03453 this._order = order;
03454
03455 if ( update !== false ) this.onChangeCallback();
03456
03457 return this;
03458
03459 },
03460
03461 setFromQuaternion: function () {
03462
03463 var matrix;
03464
03465 return function ( q, order, update ) {
03466
03467 if ( matrix === undefined ) matrix = new THREE.Matrix4();
03468 matrix.makeRotationFromQuaternion( q );
03469 this.setFromRotationMatrix( matrix, order, update );
03470
03471 return this;
03472
03473 };
03474
03475 }(),
03476
03477 setFromVector3: function ( v, order ) {
03478
03479 return this.set( v.x, v.y, v.z, order || this._order );
03480
03481 },
03482
03483 reorder: function () {
03484
03485
03486
03487 var q = new THREE.Quaternion();
03488
03489 return function ( newOrder ) {
03490
03491 q.setFromEuler( this );
03492 this.setFromQuaternion( q, newOrder );
03493
03494 };
03495
03496 }(),
03497
03498 equals: function ( euler ) {
03499
03500 return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );
03501
03502 },
03503
03504 fromArray: function ( array ) {
03505
03506 this._x = array[ 0 ];
03507 this._y = array[ 1 ];
03508 this._z = array[ 2 ];
03509 if ( array[ 3 ] !== undefined ) this._order = array[ 3 ];
03510
03511 this.onChangeCallback();
03512
03513 return this;
03514
03515 },
03516
03517 toArray: function ( array, offset ) {
03518
03519 if ( array === undefined ) array = [];
03520 if ( offset === undefined ) offset = 0;
03521
03522 array[ offset ] = this._x;
03523 array[ offset + 1 ] = this._y;
03524 array[ offset + 2 ] = this._z;
03525 array[ offset + 3 ] = this._order;
03526
03527 return array;
03528
03529 },
03530
03531 toVector3: function ( optionalResult ) {
03532
03533 if ( optionalResult ) {
03534
03535 return optionalResult.set( this._x, this._y, this._z );
03536
03537 } else {
03538
03539 return new THREE.Vector3( this._x, this._y, this._z );
03540
03541 }
03542
03543 },
03544
03545 onChange: function ( callback ) {
03546
03547 this.onChangeCallback = callback;
03548
03549 return this;
03550
03551 },
03552
03553 onChangeCallback: function () {}
03554
03555 };
03556
03557
03558
03563 THREE.Line3 = function ( start, end ) {
03564
03565 this.start = ( start !== undefined ) ? start : new THREE.Vector3();
03566 this.end = ( end !== undefined ) ? end : new THREE.Vector3();
03567
03568 };
03569
03570 THREE.Line3.prototype = {
03571
03572 constructor: THREE.Line3,
03573
03574 set: function ( start, end ) {
03575
03576 this.start.copy( start );
03577 this.end.copy( end );
03578
03579 return this;
03580
03581 },
03582
03583 clone: function () {
03584
03585 return new this.constructor().copy( this );
03586
03587 },
03588
03589 copy: function ( line ) {
03590
03591 this.start.copy( line.start );
03592 this.end.copy( line.end );
03593
03594 return this;
03595
03596 },
03597
03598 center: function ( optionalTarget ) {
03599
03600 var result = optionalTarget || new THREE.Vector3();
03601 return result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );
03602
03603 },
03604
03605 delta: function ( optionalTarget ) {
03606
03607 var result = optionalTarget || new THREE.Vector3();
03608 return result.subVectors( this.end, this.start );
03609
03610 },
03611
03612 distanceSq: function () {
03613
03614 return this.start.distanceToSquared( this.end );
03615
03616 },
03617
03618 distance: function () {
03619
03620 return this.start.distanceTo( this.end );
03621
03622 },
03623
03624 at: function ( t, optionalTarget ) {
03625
03626 var result = optionalTarget || new THREE.Vector3();
03627
03628 return this.delta( result ).multiplyScalar( t ).add( this.start );
03629
03630 },
03631
03632 closestPointToPointParameter: function () {
03633
03634 var startP = new THREE.Vector3();
03635 var startEnd = new THREE.Vector3();
03636
03637 return function ( point, clampToLine ) {
03638
03639 startP.subVectors( point, this.start );
03640 startEnd.subVectors( this.end, this.start );
03641
03642 var startEnd2 = startEnd.dot( startEnd );
03643 var startEnd_startP = startEnd.dot( startP );
03644
03645 var t = startEnd_startP / startEnd2;
03646
03647 if ( clampToLine ) {
03648
03649 t = THREE.Math.clamp( t, 0, 1 );
03650
03651 }
03652
03653 return t;
03654
03655 };
03656
03657 }(),
03658
03659 closestPointToPoint: function ( point, clampToLine, optionalTarget ) {
03660
03661 var t = this.closestPointToPointParameter( point, clampToLine );
03662
03663 var result = optionalTarget || new THREE.Vector3();
03664
03665 return this.delta( result ).multiplyScalar( t ).add( this.start );
03666
03667 },
03668
03669 applyMatrix4: function ( matrix ) {
03670
03671 this.start.applyMatrix4( matrix );
03672 this.end.applyMatrix4( matrix );
03673
03674 return this;
03675
03676 },
03677
03678 equals: function ( line ) {
03679
03680 return line.start.equals( this.start ) && line.end.equals( this.end );
03681
03682 }
03683
03684 };
03685
03686
03687
03692 THREE.Box2 = function ( min, max ) {
03693
03694 this.min = ( min !== undefined ) ? min : new THREE.Vector2( Infinity, Infinity );
03695 this.max = ( max !== undefined ) ? max : new THREE.Vector2( - Infinity, - Infinity );
03696
03697 };
03698
03699 THREE.Box2.prototype = {
03700
03701 constructor: THREE.Box2,
03702
03703 set: function ( min, max ) {
03704
03705 this.min.copy( min );
03706 this.max.copy( max );
03707
03708 return this;
03709
03710 },
03711
03712 setFromPoints: function ( points ) {
03713
03714 this.makeEmpty();
03715
03716 for ( var i = 0, il = points.length; i < il; i ++ ) {
03717
03718 this.expandByPoint( points[ i ] )
03719
03720 }
03721
03722 return this;
03723
03724 },
03725
03726 setFromCenterAndSize: function () {
03727
03728 var v1 = new THREE.Vector2();
03729
03730 return function ( center, size ) {
03731
03732 var halfSize = v1.copy( size ).multiplyScalar( 0.5 );
03733 this.min.copy( center ).sub( halfSize );
03734 this.max.copy( center ).add( halfSize );
03735
03736 return this;
03737
03738 };
03739
03740 }(),
03741
03742 clone: function () {
03743
03744 return new this.constructor().copy( this );
03745
03746 },
03747
03748 copy: function ( box ) {
03749
03750 this.min.copy( box.min );
03751 this.max.copy( box.max );
03752
03753 return this;
03754
03755 },
03756
03757 makeEmpty: function () {
03758
03759 this.min.x = this.min.y = Infinity;
03760 this.max.x = this.max.y = - Infinity;
03761
03762 return this;
03763
03764 },
03765
03766 empty: function () {
03767
03768
03769
03770 return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );
03771
03772 },
03773
03774 center: function ( optionalTarget ) {
03775
03776 var result = optionalTarget || new THREE.Vector2();
03777 return result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
03778
03779 },
03780
03781 size: function ( optionalTarget ) {
03782
03783 var result = optionalTarget || new THREE.Vector2();
03784 return result.subVectors( this.max, this.min );
03785
03786 },
03787
03788 expandByPoint: function ( point ) {
03789
03790 this.min.min( point );
03791 this.max.max( point );
03792
03793 return this;
03794
03795 },
03796
03797 expandByVector: function ( vector ) {
03798
03799 this.min.sub( vector );
03800 this.max.add( vector );
03801
03802 return this;
03803
03804 },
03805
03806 expandByScalar: function ( scalar ) {
03807
03808 this.min.addScalar( - scalar );
03809 this.max.addScalar( scalar );
03810
03811 return this;
03812
03813 },
03814
03815 containsPoint: function ( point ) {
03816
03817 if ( point.x < this.min.x || point.x > this.max.x ||
03818 point.y < this.min.y || point.y > this.max.y ) {
03819
03820 return false;
03821
03822 }
03823
03824 return true;
03825
03826 },
03827
03828 containsBox: function ( box ) {
03829
03830 if ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) &&
03831 ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) ) {
03832
03833 return true;
03834
03835 }
03836
03837 return false;
03838
03839 },
03840
03841 getParameter: function ( point, optionalTarget ) {
03842
03843
03844
03845
03846 var result = optionalTarget || new THREE.Vector2();
03847
03848 return result.set(
03849 ( point.x - this.min.x ) / ( this.max.x - this.min.x ),
03850 ( point.y - this.min.y ) / ( this.max.y - this.min.y )
03851 );
03852
03853 },
03854
03855 isIntersectionBox: function ( box ) {
03856
03857
03858
03859 if ( box.max.x < this.min.x || box.min.x > this.max.x ||
03860 box.max.y < this.min.y || box.min.y > this.max.y ) {
03861
03862 return false;
03863
03864 }
03865
03866 return true;
03867
03868 },
03869
03870 clampPoint: function ( point, optionalTarget ) {
03871
03872 var result = optionalTarget || new THREE.Vector2();
03873 return result.copy( point ).clamp( this.min, this.max );
03874
03875 },
03876
03877 distanceToPoint: function () {
03878
03879 var v1 = new THREE.Vector2();
03880
03881 return function ( point ) {
03882
03883 var clampedPoint = v1.copy( point ).clamp( this.min, this.max );
03884 return clampedPoint.sub( point ).length();
03885
03886 };
03887
03888 }(),
03889
03890 intersect: function ( box ) {
03891
03892 this.min.max( box.min );
03893 this.max.min( box.max );
03894
03895 return this;
03896
03897 },
03898
03899 union: function ( box ) {
03900
03901 this.min.min( box.min );
03902 this.max.max( box.max );
03903
03904 return this;
03905
03906 },
03907
03908 translate: function ( offset ) {
03909
03910 this.min.add( offset );
03911 this.max.add( offset );
03912
03913 return this;
03914
03915 },
03916
03917 equals: function ( box ) {
03918
03919 return box.min.equals( this.min ) && box.max.equals( this.max );
03920
03921 }
03922
03923 };
03924
03925
03926
03932 THREE.Box3 = function ( min, max ) {
03933
03934 this.min = ( min !== undefined ) ? min : new THREE.Vector3( Infinity, Infinity, Infinity );
03935 this.max = ( max !== undefined ) ? max : new THREE.Vector3( - Infinity, - Infinity, - Infinity );
03936
03937 };
03938
03939 THREE.Box3.prototype = {
03940
03941 constructor: THREE.Box3,
03942
03943 set: function ( min, max ) {
03944
03945 this.min.copy( min );
03946 this.max.copy( max );
03947
03948 return this;
03949
03950 },
03951
03952 setFromPoints: function ( points ) {
03953
03954 this.makeEmpty();
03955
03956 for ( var i = 0, il = points.length; i < il; i ++ ) {
03957
03958 this.expandByPoint( points[ i ] );
03959
03960 }
03961
03962 return this;
03963
03964 },
03965
03966 setFromCenterAndSize: function () {
03967
03968 var v1 = new THREE.Vector3();
03969
03970 return function ( center, size ) {
03971
03972 var halfSize = v1.copy( size ).multiplyScalar( 0.5 );
03973
03974 this.min.copy( center ).sub( halfSize );
03975 this.max.copy( center ).add( halfSize );
03976
03977 return this;
03978
03979 };
03980
03981 }(),
03982
03983 setFromObject: function () {
03984
03985
03986
03987
03988 var v1 = new THREE.Vector3();
03989
03990 return function ( object ) {
03991
03992 var scope = this;
03993
03994 object.updateMatrixWorld( true );
03995
03996 this.makeEmpty();
03997
03998 object.traverse( function ( node ) {
03999
04000 var geometry = node.geometry;
04001
04002 if ( geometry !== undefined ) {
04003
04004 if ( geometry instanceof THREE.Geometry ) {
04005
04006 var vertices = geometry.vertices;
04007
04008 for ( var i = 0, il = vertices.length; i < il; i ++ ) {
04009
04010 v1.copy( vertices[ i ] );
04011
04012 v1.applyMatrix4( node.matrixWorld );
04013
04014 scope.expandByPoint( v1 );
04015
04016 }
04017
04018 } else if ( geometry instanceof THREE.BufferGeometry && geometry.attributes[ 'position' ] !== undefined ) {
04019
04020 var positions = geometry.attributes[ 'position' ].array;
04021
04022 for ( var i = 0, il = positions.length; i < il; i += 3 ) {
04023
04024 v1.set( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
04025
04026 v1.applyMatrix4( node.matrixWorld );
04027
04028 scope.expandByPoint( v1 );
04029
04030 }
04031
04032 }
04033
04034 }
04035
04036 } );
04037
04038 return this;
04039
04040 };
04041
04042 }(),
04043
04044 clone: function () {
04045
04046 return new this.constructor().copy( this );
04047
04048 },
04049
04050 copy: function ( box ) {
04051
04052 this.min.copy( box.min );
04053 this.max.copy( box.max );
04054
04055 return this;
04056
04057 },
04058
04059 makeEmpty: function () {
04060
04061 this.min.x = this.min.y = this.min.z = Infinity;
04062 this.max.x = this.max.y = this.max.z = - Infinity;
04063
04064 return this;
04065
04066 },
04067
04068 empty: function () {
04069
04070
04071
04072 return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );
04073
04074 },
04075
04076 center: function ( optionalTarget ) {
04077
04078 var result = optionalTarget || new THREE.Vector3();
04079 return result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
04080
04081 },
04082
04083 size: function ( optionalTarget ) {
04084
04085 var result = optionalTarget || new THREE.Vector3();
04086 return result.subVectors( this.max, this.min );
04087
04088 },
04089
04090 expandByPoint: function ( point ) {
04091
04092 this.min.min( point );
04093 this.max.max( point );
04094
04095 return this;
04096
04097 },
04098
04099 expandByVector: function ( vector ) {
04100
04101 this.min.sub( vector );
04102 this.max.add( vector );
04103
04104 return this;
04105
04106 },
04107
04108 expandByScalar: function ( scalar ) {
04109
04110 this.min.addScalar( - scalar );
04111 this.max.addScalar( scalar );
04112
04113 return this;
04114
04115 },
04116
04117 containsPoint: function ( point ) {
04118
04119 if ( point.x < this.min.x || point.x > this.max.x ||
04120 point.y < this.min.y || point.y > this.max.y ||
04121 point.z < this.min.z || point.z > this.max.z ) {
04122
04123 return false;
04124
04125 }
04126
04127 return true;
04128
04129 },
04130
04131 containsBox: function ( box ) {
04132
04133 if ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) &&
04134 ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) &&
04135 ( this.min.z <= box.min.z ) && ( box.max.z <= this.max.z ) ) {
04136
04137 return true;
04138
04139 }
04140
04141 return false;
04142
04143 },
04144
04145 getParameter: function ( point, optionalTarget ) {
04146
04147
04148
04149
04150 var result = optionalTarget || new THREE.Vector3();
04151
04152 return result.set(
04153 ( point.x - this.min.x ) / ( this.max.x - this.min.x ),
04154 ( point.y - this.min.y ) / ( this.max.y - this.min.y ),
04155 ( point.z - this.min.z ) / ( this.max.z - this.min.z )
04156 );
04157
04158 },
04159
04160 isIntersectionBox: function ( box ) {
04161
04162
04163
04164 if ( box.max.x < this.min.x || box.min.x > this.max.x ||
04165 box.max.y < this.min.y || box.min.y > this.max.y ||
04166 box.max.z < this.min.z || box.min.z > this.max.z ) {
04167
04168 return false;
04169
04170 }
04171
04172 return true;
04173
04174 },
04175
04176 clampPoint: function ( point, optionalTarget ) {
04177
04178 var result = optionalTarget || new THREE.Vector3();
04179 return result.copy( point ).clamp( this.min, this.max );
04180
04181 },
04182
04183 distanceToPoint: function () {
04184
04185 var v1 = new THREE.Vector3();
04186
04187 return function ( point ) {
04188
04189 var clampedPoint = v1.copy( point ).clamp( this.min, this.max );
04190 return clampedPoint.sub( point ).length();
04191
04192 };
04193
04194 }(),
04195
04196 getBoundingSphere: function () {
04197
04198 var v1 = new THREE.Vector3();
04199
04200 return function ( optionalTarget ) {
04201
04202 var result = optionalTarget || new THREE.Sphere();
04203
04204 result.center = this.center();
04205 result.radius = this.size( v1 ).length() * 0.5;
04206
04207 return result;
04208
04209 };
04210
04211 }(),
04212
04213 intersect: function ( box ) {
04214
04215 this.min.max( box.min );
04216 this.max.min( box.max );
04217
04218 return this;
04219
04220 },
04221
04222 union: function ( box ) {
04223
04224 this.min.min( box.min );
04225 this.max.max( box.max );
04226
04227 return this;
04228
04229 },
04230
04231 applyMatrix4: function () {
04232
04233 var points = [
04234 new THREE.Vector3(),
04235 new THREE.Vector3(),
04236 new THREE.Vector3(),
04237 new THREE.Vector3(),
04238 new THREE.Vector3(),
04239 new THREE.Vector3(),
04240 new THREE.Vector3(),
04241 new THREE.Vector3()
04242 ];
04243
04244 return function ( matrix ) {
04245
04246
04247 points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix );
04248 points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix );
04249 points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix );
04250 points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix );
04251 points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix );
04252 points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix );
04253 points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix );
04254 points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );
04255
04256 this.makeEmpty();
04257 this.setFromPoints( points );
04258
04259 return this;
04260
04261 };
04262
04263 }(),
04264
04265 translate: function ( offset ) {
04266
04267 this.min.add( offset );
04268 this.max.add( offset );
04269
04270 return this;
04271
04272 },
04273
04274 equals: function ( box ) {
04275
04276 return box.min.equals( this.min ) && box.max.equals( this.max );
04277
04278 }
04279
04280 };
04281
04282
04283
04290 THREE.Matrix3 = function () {
04291
04292 this.elements = new Float32Array( [
04293
04294 1, 0, 0,
04295 0, 1, 0,
04296 0, 0, 1
04297
04298 ] );
04299
04300 if ( arguments.length > 0 ) {
04301
04302 console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );
04303
04304 }
04305
04306 };
04307
04308 THREE.Matrix3.prototype = {
04309
04310 constructor: THREE.Matrix3,
04311
04312 set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
04313
04314 var te = this.elements;
04315
04316 te[ 0 ] = n11; te[ 3 ] = n12; te[ 6 ] = n13;
04317 te[ 1 ] = n21; te[ 4 ] = n22; te[ 7 ] = n23;
04318 te[ 2 ] = n31; te[ 5 ] = n32; te[ 8 ] = n33;
04319
04320 return this;
04321
04322 },
04323
04324 identity: function () {
04325
04326 this.set(
04327
04328 1, 0, 0,
04329 0, 1, 0,
04330 0, 0, 1
04331
04332 );
04333
04334 return this;
04335
04336 },
04337
04338 clone: function () {
04339
04340 return new this.constructor().fromArray( this.elements );
04341
04342 },
04343
04344 copy: function ( m ) {
04345
04346 var me = m.elements;
04347
04348 this.set(
04349
04350 me[ 0 ], me[ 3 ], me[ 6 ],
04351 me[ 1 ], me[ 4 ], me[ 7 ],
04352 me[ 2 ], me[ 5 ], me[ 8 ]
04353
04354 );
04355
04356 return this;
04357
04358 },
04359
04360 multiplyVector3: function ( vector ) {
04361
04362 console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );
04363 return vector.applyMatrix3( this );
04364
04365 },
04366
04367 multiplyVector3Array: function ( a ) {
04368
04369 console.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );
04370 return this.applyToVector3Array( a );
04371
04372 },
04373
04374 applyToVector3Array: function () {
04375
04376 var v1;
04377
04378 return function ( array, offset, length ) {
04379
04380 if ( v1 === undefined ) v1 = new THREE.Vector3();
04381 if ( offset === undefined ) offset = 0;
04382 if ( length === undefined ) length = array.length;
04383
04384 for ( var i = 0, j = offset; i < length; i += 3, j += 3 ) {
04385
04386 v1.fromArray( array, j );
04387 v1.applyMatrix3( this );
04388 v1.toArray( array, j );
04389
04390 }
04391
04392 return array;
04393
04394 };
04395
04396 }(),
04397
04398 applyToBuffer: function () {
04399
04400 var v1;
04401
04402 return function applyToBuffer( buffer, offset, length ) {
04403
04404 if ( v1 === undefined ) v1 = new THREE.Vector3();
04405 if ( offset === undefined ) offset = 0;
04406 if ( length === undefined ) length = buffer.length / buffer.itemSize;
04407
04408 for ( var i = 0, j = offset; i < length; i ++, j ++ ) {
04409
04410 v1.x = buffer.getX( j );
04411 v1.y = buffer.getY( j );
04412 v1.z = buffer.getZ( j );
04413
04414 v1.applyMatrix3( this );
04415
04416 buffer.setXYZ( v1.x, v1.y, v1.z );
04417
04418 }
04419
04420 return buffer;
04421
04422 };
04423
04424 }(),
04425
04426 multiplyScalar: function ( s ) {
04427
04428 var te = this.elements;
04429
04430 te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;
04431 te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;
04432 te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;
04433
04434 return this;
04435
04436 },
04437
04438 determinant: function () {
04439
04440 var te = this.elements;
04441
04442 var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],
04443 d = te[ 3 ], e = te[ 4 ], f = te[ 5 ],
04444 g = te[ 6 ], h = te[ 7 ], i = te[ 8 ];
04445
04446 return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;
04447
04448 },
04449
04450 getInverse: function ( matrix, throwOnInvertible ) {
04451
04452
04453
04454
04455 var me = matrix.elements;
04456 var te = this.elements;
04457
04458 te[ 0 ] = me[ 10 ] * me[ 5 ] - me[ 6 ] * me[ 9 ];
04459 te[ 1 ] = - me[ 10 ] * me[ 1 ] + me[ 2 ] * me[ 9 ];
04460 te[ 2 ] = me[ 6 ] * me[ 1 ] - me[ 2 ] * me[ 5 ];
04461 te[ 3 ] = - me[ 10 ] * me[ 4 ] + me[ 6 ] * me[ 8 ];
04462 te[ 4 ] = me[ 10 ] * me[ 0 ] - me[ 2 ] * me[ 8 ];
04463 te[ 5 ] = - me[ 6 ] * me[ 0 ] + me[ 2 ] * me[ 4 ];
04464 te[ 6 ] = me[ 9 ] * me[ 4 ] - me[ 5 ] * me[ 8 ];
04465 te[ 7 ] = - me[ 9 ] * me[ 0 ] + me[ 1 ] * me[ 8 ];
04466 te[ 8 ] = me[ 5 ] * me[ 0 ] - me[ 1 ] * me[ 4 ];
04467
04468 var det = me[ 0 ] * te[ 0 ] + me[ 1 ] * te[ 3 ] + me[ 2 ] * te[ 6 ];
04469
04470
04471
04472 if ( det === 0 ) {
04473
04474 var msg = "Matrix3.getInverse(): can't invert matrix, determinant is 0";
04475
04476 if ( throwOnInvertible || false ) {
04477
04478 throw new Error( msg );
04479
04480 } else {
04481
04482 console.warn( msg );
04483
04484 }
04485
04486 this.identity();
04487
04488 return this;
04489
04490 }
04491
04492 this.multiplyScalar( 1.0 / det );
04493
04494 return this;
04495
04496 },
04497
04498 transpose: function () {
04499
04500 var tmp, m = this.elements;
04501
04502 tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;
04503 tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;
04504 tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;
04505
04506 return this;
04507
04508 },
04509
04510 flattenToArrayOffset: function ( array, offset ) {
04511
04512 var te = this.elements;
04513
04514 array[ offset ] = te[ 0 ];
04515 array[ offset + 1 ] = te[ 1 ];
04516 array[ offset + 2 ] = te[ 2 ];
04517
04518 array[ offset + 3 ] = te[ 3 ];
04519 array[ offset + 4 ] = te[ 4 ];
04520 array[ offset + 5 ] = te[ 5 ];
04521
04522 array[ offset + 6 ] = te[ 6 ];
04523 array[ offset + 7 ] = te[ 7 ];
04524 array[ offset + 8 ] = te[ 8 ];
04525
04526 return array;
04527
04528 },
04529
04530 getNormalMatrix: function ( m ) {
04531
04532
04533
04534 this.getInverse( m ).transpose();
04535
04536 return this;
04537
04538 },
04539
04540 transposeIntoArray: function ( r ) {
04541
04542 var m = this.elements;
04543
04544 r[ 0 ] = m[ 0 ];
04545 r[ 1 ] = m[ 3 ];
04546 r[ 2 ] = m[ 6 ];
04547 r[ 3 ] = m[ 1 ];
04548 r[ 4 ] = m[ 4 ];
04549 r[ 5 ] = m[ 7 ];
04550 r[ 6 ] = m[ 2 ];
04551 r[ 7 ] = m[ 5 ];
04552 r[ 8 ] = m[ 8 ];
04553
04554 return this;
04555
04556 },
04557
04558 fromArray: function ( array ) {
04559
04560 this.elements.set( array );
04561
04562 return this;
04563
04564 },
04565
04566 toArray: function () {
04567
04568 var te = this.elements;
04569
04570 return [
04571 te[ 0 ], te[ 1 ], te[ 2 ],
04572 te[ 3 ], te[ 4 ], te[ 5 ],
04573 te[ 6 ], te[ 7 ], te[ 8 ]
04574 ];
04575
04576 }
04577
04578 };
04579
04580
04581
04595 THREE.Matrix4 = function () {
04596
04597 this.elements = new Float32Array( [
04598
04599 1, 0, 0, 0,
04600 0, 1, 0, 0,
04601 0, 0, 1, 0,
04602 0, 0, 0, 1
04603
04604 ] );
04605
04606 if ( arguments.length > 0 ) {
04607
04608 console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );
04609
04610 }
04611
04612 };
04613
04614 THREE.Matrix4.prototype = {
04615
04616 constructor: THREE.Matrix4,
04617
04618 set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
04619
04620 var te = this.elements;
04621
04622 te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;
04623 te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;
04624 te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;
04625 te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;
04626
04627 return this;
04628
04629 },
04630
04631 identity: function () {
04632
04633 this.set(
04634
04635 1, 0, 0, 0,
04636 0, 1, 0, 0,
04637 0, 0, 1, 0,
04638 0, 0, 0, 1
04639
04640 );
04641
04642 return this;
04643
04644 },
04645
04646 clone: function () {
04647
04648 return new THREE.Matrix4().fromArray( this.elements );
04649
04650 },
04651
04652 copy: function ( m ) {
04653
04654 this.elements.set( m.elements );
04655
04656 return this;
04657
04658 },
04659
04660 extractPosition: function ( m ) {
04661
04662 console.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );
04663 return this.copyPosition( m );
04664
04665 },
04666
04667 copyPosition: function ( m ) {
04668
04669 var te = this.elements;
04670 var me = m.elements;
04671
04672 te[ 12 ] = me[ 12 ];
04673 te[ 13 ] = me[ 13 ];
04674 te[ 14 ] = me[ 14 ];
04675
04676 return this;
04677
04678 },
04679
04680 extractBasis: function ( xAxis, yAxis, zAxis ) {
04681
04682 var te = this.elements;
04683
04684 xAxis.set( te[ 0 ], te[ 1 ], te[ 2 ] );
04685 yAxis.set( te[ 4 ], te[ 5 ], te[ 6 ] );
04686 zAxis.set( te[ 8 ], te[ 9 ], te[ 10 ] );
04687
04688 return this;
04689
04690 },
04691
04692 makeBasis: function ( xAxis, yAxis, zAxis ) {
04693
04694 this.set(
04695 xAxis.x, yAxis.x, zAxis.x, 0,
04696 xAxis.y, yAxis.y, zAxis.y, 0,
04697 xAxis.z, yAxis.z, zAxis.z, 0,
04698 0, 0, 0, 1
04699 );
04700
04701 return this;
04702
04703 },
04704
04705 extractRotation: function () {
04706
04707 var v1;
04708
04709 return function ( m ) {
04710
04711 if ( v1 === undefined ) v1 = new THREE.Vector3();
04712
04713 var te = this.elements;
04714 var me = m.elements;
04715
04716 var scaleX = 1 / v1.set( me[ 0 ], me[ 1 ], me[ 2 ] ).length();
04717 var scaleY = 1 / v1.set( me[ 4 ], me[ 5 ], me[ 6 ] ).length();
04718 var scaleZ = 1 / v1.set( me[ 8 ], me[ 9 ], me[ 10 ] ).length();
04719
04720 te[ 0 ] = me[ 0 ] * scaleX;
04721 te[ 1 ] = me[ 1 ] * scaleX;
04722 te[ 2 ] = me[ 2 ] * scaleX;
04723
04724 te[ 4 ] = me[ 4 ] * scaleY;
04725 te[ 5 ] = me[ 5 ] * scaleY;
04726 te[ 6 ] = me[ 6 ] * scaleY;
04727
04728 te[ 8 ] = me[ 8 ] * scaleZ;
04729 te[ 9 ] = me[ 9 ] * scaleZ;
04730 te[ 10 ] = me[ 10 ] * scaleZ;
04731
04732 return this;
04733
04734 };
04735
04736 }(),
04737
04738 makeRotationFromEuler: function ( euler ) {
04739
04740 if ( euler instanceof THREE.Euler === false ) {
04741
04742 console.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );
04743
04744 }
04745
04746 var te = this.elements;
04747
04748 var x = euler.x, y = euler.y, z = euler.z;
04749 var a = Math.cos( x ), b = Math.sin( x );
04750 var c = Math.cos( y ), d = Math.sin( y );
04751 var e = Math.cos( z ), f = Math.sin( z );
04752
04753 if ( euler.order === 'XYZ' ) {
04754
04755 var ae = a * e, af = a * f, be = b * e, bf = b * f;
04756
04757 te[ 0 ] = c * e;
04758 te[ 4 ] = - c * f;
04759 te[ 8 ] = d;
04760
04761 te[ 1 ] = af + be * d;
04762 te[ 5 ] = ae - bf * d;
04763 te[ 9 ] = - b * c;
04764
04765 te[ 2 ] = bf - ae * d;
04766 te[ 6 ] = be + af * d;
04767 te[ 10 ] = a * c;
04768
04769 } else if ( euler.order === 'YXZ' ) {
04770
04771 var ce = c * e, cf = c * f, de = d * e, df = d * f;
04772
04773 te[ 0 ] = ce + df * b;
04774 te[ 4 ] = de * b - cf;
04775 te[ 8 ] = a * d;
04776
04777 te[ 1 ] = a * f;
04778 te[ 5 ] = a * e;
04779 te[ 9 ] = - b;
04780
04781 te[ 2 ] = cf * b - de;
04782 te[ 6 ] = df + ce * b;
04783 te[ 10 ] = a * c;
04784
04785 } else if ( euler.order === 'ZXY' ) {
04786
04787 var ce = c * e, cf = c * f, de = d * e, df = d * f;
04788
04789 te[ 0 ] = ce - df * b;
04790 te[ 4 ] = - a * f;
04791 te[ 8 ] = de + cf * b;
04792
04793 te[ 1 ] = cf + de * b;
04794 te[ 5 ] = a * e;
04795 te[ 9 ] = df - ce * b;
04796
04797 te[ 2 ] = - a * d;
04798 te[ 6 ] = b;
04799 te[ 10 ] = a * c;
04800
04801 } else if ( euler.order === 'ZYX' ) {
04802
04803 var ae = a * e, af = a * f, be = b * e, bf = b * f;
04804
04805 te[ 0 ] = c * e;
04806 te[ 4 ] = be * d - af;
04807 te[ 8 ] = ae * d + bf;
04808
04809 te[ 1 ] = c * f;
04810 te[ 5 ] = bf * d + ae;
04811 te[ 9 ] = af * d - be;
04812
04813 te[ 2 ] = - d;
04814 te[ 6 ] = b * c;
04815 te[ 10 ] = a * c;
04816
04817 } else if ( euler.order === 'YZX' ) {
04818
04819 var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
04820
04821 te[ 0 ] = c * e;
04822 te[ 4 ] = bd - ac * f;
04823 te[ 8 ] = bc * f + ad;
04824
04825 te[ 1 ] = f;
04826 te[ 5 ] = a * e;
04827 te[ 9 ] = - b * e;
04828
04829 te[ 2 ] = - d * e;
04830 te[ 6 ] = ad * f + bc;
04831 te[ 10 ] = ac - bd * f;
04832
04833 } else if ( euler.order === 'XZY' ) {
04834
04835 var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
04836
04837 te[ 0 ] = c * e;
04838 te[ 4 ] = - f;
04839 te[ 8 ] = d * e;
04840
04841 te[ 1 ] = ac * f + bd;
04842 te[ 5 ] = a * e;
04843 te[ 9 ] = ad * f - bc;
04844
04845 te[ 2 ] = bc * f - ad;
04846 te[ 6 ] = b * e;
04847 te[ 10 ] = bd * f + ac;
04848
04849 }
04850
04851
04852 te[ 3 ] = 0;
04853 te[ 7 ] = 0;
04854 te[ 11 ] = 0;
04855
04856
04857 te[ 12 ] = 0;
04858 te[ 13 ] = 0;
04859 te[ 14 ] = 0;
04860 te[ 15 ] = 1;
04861
04862 return this;
04863
04864 },
04865
04866 setRotationFromQuaternion: function ( q ) {
04867
04868 console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );
04869
04870 return this.makeRotationFromQuaternion( q );
04871
04872 },
04873
04874 makeRotationFromQuaternion: function ( q ) {
04875
04876 var te = this.elements;
04877
04878 var x = q.x, y = q.y, z = q.z, w = q.w;
04879 var x2 = x + x, y2 = y + y, z2 = z + z;
04880 var xx = x * x2, xy = x * y2, xz = x * z2;
04881 var yy = y * y2, yz = y * z2, zz = z * z2;
04882 var wx = w * x2, wy = w * y2, wz = w * z2;
04883
04884 te[ 0 ] = 1 - ( yy + zz );
04885 te[ 4 ] = xy - wz;
04886 te[ 8 ] = xz + wy;
04887
04888 te[ 1 ] = xy + wz;
04889 te[ 5 ] = 1 - ( xx + zz );
04890 te[ 9 ] = yz - wx;
04891
04892 te[ 2 ] = xz - wy;
04893 te[ 6 ] = yz + wx;
04894 te[ 10 ] = 1 - ( xx + yy );
04895
04896
04897 te[ 3 ] = 0;
04898 te[ 7 ] = 0;
04899 te[ 11 ] = 0;
04900
04901
04902 te[ 12 ] = 0;
04903 te[ 13 ] = 0;
04904 te[ 14 ] = 0;
04905 te[ 15 ] = 1;
04906
04907 return this;
04908
04909 },
04910
04911 lookAt: function () {
04912
04913 var x, y, z;
04914
04915 return function ( eye, target, up ) {
04916
04917 if ( x === undefined ) x = new THREE.Vector3();
04918 if ( y === undefined ) y = new THREE.Vector3();
04919 if ( z === undefined ) z = new THREE.Vector3();
04920
04921 var te = this.elements;
04922
04923 z.subVectors( eye, target ).normalize();
04924
04925 if ( z.lengthSq() === 0 ) {
04926
04927 z.z = 1;
04928
04929 }
04930
04931 x.crossVectors( up, z ).normalize();
04932
04933 if ( x.lengthSq() === 0 ) {
04934
04935 z.x += 0.0001;
04936 x.crossVectors( up, z ).normalize();
04937
04938 }
04939
04940 y.crossVectors( z, x );
04941
04942
04943 te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;
04944 te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;
04945 te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;
04946
04947 return this;
04948
04949 };
04950
04951 }(),
04952
04953 multiply: function ( m, n ) {
04954
04955 if ( n !== undefined ) {
04956
04957 console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );
04958 return this.multiplyMatrices( m, n );
04959
04960 }
04961
04962 return this.multiplyMatrices( this, m );
04963
04964 },
04965
04966 multiplyMatrices: function ( a, b ) {
04967
04968 var ae = a.elements;
04969 var be = b.elements;
04970 var te = this.elements;
04971
04972 var a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];
04973 var a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];
04974 var a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];
04975 var a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];
04976
04977 var b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];
04978 var b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];
04979 var b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];
04980 var b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];
04981
04982 te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
04983 te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
04984 te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
04985 te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
04986
04987 te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
04988 te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
04989 te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
04990 te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
04991
04992 te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
04993 te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
04994 te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
04995 te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
04996
04997 te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
04998 te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
04999 te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
05000 te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
05001
05002 return this;
05003
05004 },
05005
05006 multiplyToArray: function ( a, b, r ) {
05007
05008 var te = this.elements;
05009
05010 this.multiplyMatrices( a, b );
05011
05012 r[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];
05013 r[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];
05014 r[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];
05015 r[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];
05016
05017 return this;
05018
05019 },
05020
05021 multiplyScalar: function ( s ) {
05022
05023 var te = this.elements;
05024
05025 te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;
05026 te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;
05027 te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;
05028 te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;
05029
05030 return this;
05031
05032 },
05033
05034 multiplyVector3: function ( vector ) {
05035
05036 console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' );
05037 return vector.applyProjection( this );
05038
05039 },
05040
05041 multiplyVector4: function ( vector ) {
05042
05043 console.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
05044 return vector.applyMatrix4( this );
05045
05046 },
05047
05048 multiplyVector3Array: function ( a ) {
05049
05050 console.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );
05051 return this.applyToVector3Array( a );
05052
05053 },
05054
05055 applyToVector3Array: function () {
05056
05057 var v1;
05058
05059 return function ( array, offset, length ) {
05060
05061 if ( v1 === undefined ) v1 = new THREE.Vector3();
05062 if ( offset === undefined ) offset = 0;
05063 if ( length === undefined ) length = array.length;
05064
05065 for ( var i = 0, j = offset; i < length; i += 3, j += 3 ) {
05066
05067 v1.fromArray( array, j );
05068 v1.applyMatrix4( this );
05069 v1.toArray( array, j );
05070
05071 }
05072
05073 return array;
05074
05075 };
05076
05077 }(),
05078
05079 applyToBuffer: function () {
05080
05081 var v1;
05082
05083 return function applyToBuffer( buffer, offset, length ) {
05084
05085 if ( v1 === undefined ) v1 = new THREE.Vector3();
05086 if ( offset === undefined ) offset = 0;
05087 if ( length === undefined ) length = buffer.length / buffer.itemSize;
05088
05089 for ( var i = 0, j = offset; i < length; i ++, j ++ ) {
05090
05091 v1.x = buffer.getX( j );
05092 v1.y = buffer.getY( j );
05093 v1.z = buffer.getZ( j );
05094
05095 v1.applyMatrix4( this );
05096
05097 buffer.setXYZ( v1.x, v1.y, v1.z );
05098
05099 }
05100
05101 return buffer;
05102
05103 };
05104
05105 }(),
05106
05107 rotateAxis: function ( v ) {
05108
05109 console.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );
05110
05111 v.transformDirection( this );
05112
05113 },
05114
05115 crossVector: function ( vector ) {
05116
05117 console.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
05118 return vector.applyMatrix4( this );
05119
05120 },
05121
05122 determinant: function () {
05123
05124 var te = this.elements;
05125
05126 var n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];
05127 var n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];
05128 var n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];
05129 var n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];
05130
05131
05132
05133
05134 return (
05135 n41 * (
05136 + n14 * n23 * n32
05137 - n13 * n24 * n32
05138 - n14 * n22 * n33
05139 + n12 * n24 * n33
05140 + n13 * n22 * n34
05141 - n12 * n23 * n34
05142 ) +
05143 n42 * (
05144 + n11 * n23 * n34
05145 - n11 * n24 * n33
05146 + n14 * n21 * n33
05147 - n13 * n21 * n34
05148 + n13 * n24 * n31
05149 - n14 * n23 * n31
05150 ) +
05151 n43 * (
05152 + n11 * n24 * n32
05153 - n11 * n22 * n34
05154 - n14 * n21 * n32
05155 + n12 * n21 * n34
05156 + n14 * n22 * n31
05157 - n12 * n24 * n31
05158 ) +
05159 n44 * (
05160 - n13 * n22 * n31
05161 - n11 * n23 * n32
05162 + n11 * n22 * n33
05163 + n13 * n21 * n32
05164 - n12 * n21 * n33
05165 + n12 * n23 * n31
05166 )
05167
05168 );
05169
05170 },
05171
05172 transpose: function () {
05173
05174 var te = this.elements;
05175 var tmp;
05176
05177 tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;
05178 tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;
05179 tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;
05180
05181 tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;
05182 tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;
05183 tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;
05184
05185 return this;
05186
05187 },
05188
05189 flattenToArrayOffset: function ( array, offset ) {
05190
05191 var te = this.elements;
05192
05193 array[ offset ] = te[ 0 ];
05194 array[ offset + 1 ] = te[ 1 ];
05195 array[ offset + 2 ] = te[ 2 ];
05196 array[ offset + 3 ] = te[ 3 ];
05197
05198 array[ offset + 4 ] = te[ 4 ];
05199 array[ offset + 5 ] = te[ 5 ];
05200 array[ offset + 6 ] = te[ 6 ];
05201 array[ offset + 7 ] = te[ 7 ];
05202
05203 array[ offset + 8 ] = te[ 8 ];
05204 array[ offset + 9 ] = te[ 9 ];
05205 array[ offset + 10 ] = te[ 10 ];
05206 array[ offset + 11 ] = te[ 11 ];
05207
05208 array[ offset + 12 ] = te[ 12 ];
05209 array[ offset + 13 ] = te[ 13 ];
05210 array[ offset + 14 ] = te[ 14 ];
05211 array[ offset + 15 ] = te[ 15 ];
05212
05213 return array;
05214
05215 },
05216
05217 getPosition: function () {
05218
05219 var v1;
05220
05221 return function () {
05222
05223 if ( v1 === undefined ) v1 = new THREE.Vector3();
05224 console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );
05225
05226 var te = this.elements;
05227 return v1.set( te[ 12 ], te[ 13 ], te[ 14 ] );
05228
05229 };
05230
05231 }(),
05232
05233 setPosition: function ( v ) {
05234
05235 var te = this.elements;
05236
05237 te[ 12 ] = v.x;
05238 te[ 13 ] = v.y;
05239 te[ 14 ] = v.z;
05240
05241 return this;
05242
05243 },
05244
05245 getInverse: function ( m, throwOnInvertible ) {
05246
05247
05248 var te = this.elements;
05249 var me = m.elements;
05250
05251 var n11 = me[ 0 ], n12 = me[ 4 ], n13 = me[ 8 ], n14 = me[ 12 ];
05252 var n21 = me[ 1 ], n22 = me[ 5 ], n23 = me[ 9 ], n24 = me[ 13 ];
05253 var n31 = me[ 2 ], n32 = me[ 6 ], n33 = me[ 10 ], n34 = me[ 14 ];
05254 var n41 = me[ 3 ], n42 = me[ 7 ], n43 = me[ 11 ], n44 = me[ 15 ];
05255
05256 te[ 0 ] = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44;
05257 te[ 4 ] = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44;
05258 te[ 8 ] = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44;
05259 te[ 12 ] = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
05260 te[ 1 ] = n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44;
05261 te[ 5 ] = n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44;
05262 te[ 9 ] = n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44;
05263 te[ 13 ] = n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34;
05264 te[ 2 ] = n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44;
05265 te[ 6 ] = n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44;
05266 te[ 10 ] = n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44;
05267 te[ 14 ] = n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34;
05268 te[ 3 ] = n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43;
05269 te[ 7 ] = n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43;
05270 te[ 11 ] = n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43;
05271 te[ 15 ] = n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33;
05272
05273 var det = n11 * te[ 0 ] + n21 * te[ 4 ] + n31 * te[ 8 ] + n41 * te[ 12 ];
05274
05275 if ( det === 0 ) {
05276
05277 var msg = "THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0";
05278
05279 if ( throwOnInvertible || false ) {
05280
05281 throw new Error( msg );
05282
05283 } else {
05284
05285 console.warn( msg );
05286
05287 }
05288
05289 this.identity();
05290
05291 return this;
05292
05293 }
05294
05295 this.multiplyScalar( 1 / det );
05296
05297 return this;
05298
05299 },
05300
05301 translate: function ( v ) {
05302
05303 console.error( 'THREE.Matrix4: .translate() has been removed.' );
05304
05305 },
05306
05307 rotateX: function ( angle ) {
05308
05309 console.error( 'THREE.Matrix4: .rotateX() has been removed.' );
05310
05311 },
05312
05313 rotateY: function ( angle ) {
05314
05315 console.error( 'THREE.Matrix4: .rotateY() has been removed.' );
05316
05317 },
05318
05319 rotateZ: function ( angle ) {
05320
05321 console.error( 'THREE.Matrix4: .rotateZ() has been removed.' );
05322
05323 },
05324
05325 rotateByAxis: function ( axis, angle ) {
05326
05327 console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );
05328
05329 },
05330
05331 scale: function ( v ) {
05332
05333 var te = this.elements;
05334 var x = v.x, y = v.y, z = v.z;
05335
05336 te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;
05337 te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;
05338 te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;
05339 te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;
05340
05341 return this;
05342
05343 },
05344
05345 getMaxScaleOnAxis: function () {
05346
05347 var te = this.elements;
05348
05349 var scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];
05350 var scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];
05351 var scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];
05352
05353 return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );
05354
05355 },
05356
05357 makeTranslation: function ( x, y, z ) {
05358
05359 this.set(
05360
05361 1, 0, 0, x,
05362 0, 1, 0, y,
05363 0, 0, 1, z,
05364 0, 0, 0, 1
05365
05366 );
05367
05368 return this;
05369
05370 },
05371
05372 makeRotationX: function ( theta ) {
05373
05374 var c = Math.cos( theta ), s = Math.sin( theta );
05375
05376 this.set(
05377
05378 1, 0, 0, 0,
05379 0, c, - s, 0,
05380 0, s, c, 0,
05381 0, 0, 0, 1
05382
05383 );
05384
05385 return this;
05386
05387 },
05388
05389 makeRotationY: function ( theta ) {
05390
05391 var c = Math.cos( theta ), s = Math.sin( theta );
05392
05393 this.set(
05394
05395 c, 0, s, 0,
05396 0, 1, 0, 0,
05397 - s, 0, c, 0,
05398 0, 0, 0, 1
05399
05400 );
05401
05402 return this;
05403
05404 },
05405
05406 makeRotationZ: function ( theta ) {
05407
05408 var c = Math.cos( theta ), s = Math.sin( theta );
05409
05410 this.set(
05411
05412 c, - s, 0, 0,
05413 s, c, 0, 0,
05414 0, 0, 1, 0,
05415 0, 0, 0, 1
05416
05417 );
05418
05419 return this;
05420
05421 },
05422
05423 makeRotationAxis: function ( axis, angle ) {
05424
05425
05426
05427 var c = Math.cos( angle );
05428 var s = Math.sin( angle );
05429 var t = 1 - c;
05430 var x = axis.x, y = axis.y, z = axis.z;
05431 var tx = t * x, ty = t * y;
05432
05433 this.set(
05434
05435 tx * x + c, tx * y - s * z, tx * z + s * y, 0,
05436 tx * y + s * z, ty * y + c, ty * z - s * x, 0,
05437 tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
05438 0, 0, 0, 1
05439
05440 );
05441
05442 return this;
05443
05444 },
05445
05446 makeScale: function ( x, y, z ) {
05447
05448 this.set(
05449
05450 x, 0, 0, 0,
05451 0, y, 0, 0,
05452 0, 0, z, 0,
05453 0, 0, 0, 1
05454
05455 );
05456
05457 return this;
05458
05459 },
05460
05461 compose: function ( position, quaternion, scale ) {
05462
05463 this.makeRotationFromQuaternion( quaternion );
05464 this.scale( scale );
05465 this.setPosition( position );
05466
05467 return this;
05468
05469 },
05470
05471 decompose: function () {
05472
05473 var vector, matrix;
05474
05475 return function ( position, quaternion, scale ) {
05476
05477 if ( vector === undefined ) vector = new THREE.Vector3();
05478 if ( matrix === undefined ) matrix = new THREE.Matrix4();
05479
05480 var te = this.elements;
05481
05482 var sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();
05483 var sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();
05484 var sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();
05485
05486
05487 var det = this.determinant();
05488 if ( det < 0 ) {
05489
05490 sx = - sx;
05491
05492 }
05493
05494 position.x = te[ 12 ];
05495 position.y = te[ 13 ];
05496 position.z = te[ 14 ];
05497
05498
05499
05500 matrix.elements.set( this.elements );
05501
05502 var invSX = 1 / sx;
05503 var invSY = 1 / sy;
05504 var invSZ = 1 / sz;
05505
05506 matrix.elements[ 0 ] *= invSX;
05507 matrix.elements[ 1 ] *= invSX;
05508 matrix.elements[ 2 ] *= invSX;
05509
05510 matrix.elements[ 4 ] *= invSY;
05511 matrix.elements[ 5 ] *= invSY;
05512 matrix.elements[ 6 ] *= invSY;
05513
05514 matrix.elements[ 8 ] *= invSZ;
05515 matrix.elements[ 9 ] *= invSZ;
05516 matrix.elements[ 10 ] *= invSZ;
05517
05518 quaternion.setFromRotationMatrix( matrix );
05519
05520 scale.x = sx;
05521 scale.y = sy;
05522 scale.z = sz;
05523
05524 return this;
05525
05526 };
05527
05528 }(),
05529
05530 makeFrustum: function ( left, right, bottom, top, near, far ) {
05531
05532 var te = this.elements;
05533 var x = 2 * near / ( right - left );
05534 var y = 2 * near / ( top - bottom );
05535
05536 var a = ( right + left ) / ( right - left );
05537 var b = ( top + bottom ) / ( top - bottom );
05538 var c = - ( far + near ) / ( far - near );
05539 var d = - 2 * far * near / ( far - near );
05540
05541 te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0;
05542 te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0;
05543 te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d;
05544 te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0;
05545
05546 return this;
05547
05548 },
05549
05550 makePerspective: function ( fov, aspect, near, far ) {
05551
05552 var ymax = near * Math.tan( THREE.Math.degToRad( fov * 0.5 ) );
05553 var ymin = - ymax;
05554 var xmin = ymin * aspect;
05555 var xmax = ymax * aspect;
05556
05557 return this.makeFrustum( xmin, xmax, ymin, ymax, near, far );
05558
05559 },
05560
05561 makeOrthographic: function ( left, right, top, bottom, near, far ) {
05562
05563 var te = this.elements;
05564 var w = right - left;
05565 var h = top - bottom;
05566 var p = far - near;
05567
05568 var x = ( right + left ) / w;
05569 var y = ( top + bottom ) / h;
05570 var z = ( far + near ) / p;
05571
05572 te[ 0 ] = 2 / w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x;
05573 te[ 1 ] = 0; te[ 5 ] = 2 / h; te[ 9 ] = 0; te[ 13 ] = - y;
05574 te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 / p; te[ 14 ] = - z;
05575 te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1;
05576
05577 return this;
05578
05579 },
05580
05581 equals: function ( matrix ) {
05582
05583 var te = this.elements;
05584 var me = matrix.elements;
05585
05586 for ( var i = 0; i < 16; i ++ ) {
05587
05588 if ( te[ i ] !== me[ i ] ) return false;
05589
05590 }
05591
05592 return true;
05593
05594 },
05595
05596 fromArray: function ( array ) {
05597
05598 this.elements.set( array );
05599
05600 return this;
05601
05602 },
05603
05604 toArray: function () {
05605
05606 var te = this.elements;
05607
05608 return [
05609 te[ 0 ], te[ 1 ], te[ 2 ], te[ 3 ],
05610 te[ 4 ], te[ 5 ], te[ 6 ], te[ 7 ],
05611 te[ 8 ], te[ 9 ], te[ 10 ], te[ 11 ],
05612 te[ 12 ], te[ 13 ], te[ 14 ], te[ 15 ]
05613 ];
05614
05615 }
05616
05617 };
05618
05619
05620
05625 THREE.Ray = function ( origin, direction ) {
05626
05627 this.origin = ( origin !== undefined ) ? origin : new THREE.Vector3();
05628 this.direction = ( direction !== undefined ) ? direction : new THREE.Vector3();
05629
05630 };
05631
05632 THREE.Ray.prototype = {
05633
05634 constructor: THREE.Ray,
05635
05636 set: function ( origin, direction ) {
05637
05638 this.origin.copy( origin );
05639 this.direction.copy( direction );
05640
05641 return this;
05642
05643 },
05644
05645 clone: function () {
05646
05647 return new this.constructor().copy( this );
05648
05649 },
05650
05651 copy: function ( ray ) {
05652
05653 this.origin.copy( ray.origin );
05654 this.direction.copy( ray.direction );
05655
05656 return this;
05657
05658 },
05659
05660 at: function ( t, optionalTarget ) {
05661
05662 var result = optionalTarget || new THREE.Vector3();
05663
05664 return result.copy( this.direction ).multiplyScalar( t ).add( this.origin );
05665
05666 },
05667
05668 recast: function () {
05669
05670 var v1 = new THREE.Vector3();
05671
05672 return function ( t ) {
05673
05674 this.origin.copy( this.at( t, v1 ) );
05675
05676 return this;
05677
05678 };
05679
05680 }(),
05681
05682 closestPointToPoint: function ( point, optionalTarget ) {
05683
05684 var result = optionalTarget || new THREE.Vector3();
05685 result.subVectors( point, this.origin );
05686 var directionDistance = result.dot( this.direction );
05687
05688 if ( directionDistance < 0 ) {
05689
05690 return result.copy( this.origin );
05691
05692 }
05693
05694 return result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
05695
05696 },
05697
05698 distanceToPoint: function ( point ) {
05699
05700 return Math.sqrt( this.distanceSqToPoint( point ) );
05701
05702 },
05703
05704 distanceSqToPoint: function () {
05705
05706 var v1 = new THREE.Vector3();
05707
05708 return function ( point ) {
05709
05710 var directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );
05711
05712
05713
05714 if ( directionDistance < 0 ) {
05715
05716 return this.origin.distanceToSquared( point );
05717
05718 }
05719
05720 v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
05721
05722 return v1.distanceToSquared( point );
05723
05724 };
05725
05726 }(),
05727
05728 distanceSqToSegment: function () {
05729
05730 var segCenter = new THREE.Vector3();
05731 var segDir = new THREE.Vector3();
05732 var diff = new THREE.Vector3();
05733
05734 return function ( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {
05735
05736
05737
05738
05739
05740
05741
05742
05743 segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );
05744 segDir.copy( v1 ).sub( v0 ).normalize();
05745 diff.copy( this.origin ).sub( segCenter );
05746
05747 var segExtent = v0.distanceTo( v1 ) * 0.5;
05748 var a01 = - this.direction.dot( segDir );
05749 var b0 = diff.dot( this.direction );
05750 var b1 = - diff.dot( segDir );
05751 var c = diff.lengthSq();
05752 var det = Math.abs( 1 - a01 * a01 );
05753 var s0, s1, sqrDist, extDet;
05754
05755 if ( det > 0 ) {
05756
05757
05758
05759 s0 = a01 * b1 - b0;
05760 s1 = a01 * b0 - b1;
05761 extDet = segExtent * det;
05762
05763 if ( s0 >= 0 ) {
05764
05765 if ( s1 >= - extDet ) {
05766
05767 if ( s1 <= extDet ) {
05768
05769
05770
05771
05772 var invDet = 1 / det;
05773 s0 *= invDet;
05774 s1 *= invDet;
05775 sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;
05776
05777 } else {
05778
05779
05780
05781 s1 = segExtent;
05782 s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
05783 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
05784
05785 }
05786
05787 } else {
05788
05789
05790
05791 s1 = - segExtent;
05792 s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
05793 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
05794
05795 }
05796
05797 } else {
05798
05799 if ( s1 <= - extDet ) {
05800
05801
05802
05803 s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );
05804 s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
05805 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
05806
05807 } else if ( s1 <= extDet ) {
05808
05809
05810
05811 s0 = 0;
05812 s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );
05813 sqrDist = s1 * ( s1 + 2 * b1 ) + c;
05814
05815 } else {
05816
05817
05818
05819 s0 = Math.max( 0, - ( a01 * segExtent + b0 ) );
05820 s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
05821 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
05822
05823 }
05824
05825 }
05826
05827 } else {
05828
05829
05830
05831 s1 = ( a01 > 0 ) ? - segExtent : segExtent;
05832 s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
05833 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
05834
05835 }
05836
05837 if ( optionalPointOnRay ) {
05838
05839 optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );
05840
05841 }
05842
05843 if ( optionalPointOnSegment ) {
05844
05845 optionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );
05846
05847 }
05848
05849 return sqrDist;
05850
05851 };
05852
05853 }(),
05854
05855
05856 isIntersectionSphere: function ( sphere ) {
05857
05858 return this.distanceToPoint( sphere.center ) <= sphere.radius;
05859
05860 },
05861
05862 intersectSphere: function () {
05863
05864
05865
05866 var v1 = new THREE.Vector3();
05867
05868 return function ( sphere, optionalTarget ) {
05869
05870 v1.subVectors( sphere.center, this.origin );
05871
05872 var tca = v1.dot( this.direction );
05873
05874 var d2 = v1.dot( v1 ) - tca * tca;
05875
05876 var radius2 = sphere.radius * sphere.radius;
05877
05878 if ( d2 > radius2 ) return null;
05879
05880 var thc = Math.sqrt( radius2 - d2 );
05881
05882
05883 var t0 = tca - thc;
05884
05885
05886 var t1 = tca + thc;
05887
05888
05889 if ( t0 < 0 && t1 < 0 ) return null;
05890
05891
05892
05893
05894 if ( t0 < 0 ) return this.at( t1, optionalTarget );
05895
05896
05897 return this.at( t0, optionalTarget );
05898
05899 }
05900
05901 }(),
05902
05903 isIntersectionPlane: function ( plane ) {
05904
05905
05906
05907 var distToPoint = plane.distanceToPoint( this.origin );
05908
05909 if ( distToPoint === 0 ) {
05910
05911 return true;
05912
05913 }
05914
05915 var denominator = plane.normal.dot( this.direction );
05916
05917 if ( denominator * distToPoint < 0 ) {
05918
05919 return true;
05920
05921 }
05922
05923
05924
05925 return false;
05926
05927 },
05928
05929 distanceToPlane: function ( plane ) {
05930
05931 var denominator = plane.normal.dot( this.direction );
05932 if ( denominator === 0 ) {
05933
05934
05935 if ( plane.distanceToPoint( this.origin ) === 0 ) {
05936
05937 return 0;
05938
05939 }
05940
05941
05942
05943 return null;
05944
05945 }
05946
05947 var t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;
05948
05949
05950
05951 return t >= 0 ? t : null;
05952
05953 },
05954
05955 intersectPlane: function ( plane, optionalTarget ) {
05956
05957 var t = this.distanceToPlane( plane );
05958
05959 if ( t === null ) {
05960
05961 return null;
05962
05963 }
05964
05965 return this.at( t, optionalTarget );
05966
05967 },
05968
05969 isIntersectionBox: function () {
05970
05971 var v = new THREE.Vector3();
05972
05973 return function ( box ) {
05974
05975 return this.intersectBox( box, v ) !== null;
05976
05977 };
05978
05979 }(),
05980
05981 intersectBox: function ( box, optionalTarget ) {
05982
05983
05984
05985 var tmin, tmax, tymin, tymax, tzmin, tzmax;
05986
05987 var invdirx = 1 / this.direction.x,
05988 invdiry = 1 / this.direction.y,
05989 invdirz = 1 / this.direction.z;
05990
05991 var origin = this.origin;
05992
05993 if ( invdirx >= 0 ) {
05994
05995 tmin = ( box.min.x - origin.x ) * invdirx;
05996 tmax = ( box.max.x - origin.x ) * invdirx;
05997
05998 } else {
05999
06000 tmin = ( box.max.x - origin.x ) * invdirx;
06001 tmax = ( box.min.x - origin.x ) * invdirx;
06002
06003 }
06004
06005 if ( invdiry >= 0 ) {
06006
06007 tymin = ( box.min.y - origin.y ) * invdiry;
06008 tymax = ( box.max.y - origin.y ) * invdiry;
06009
06010 } else {
06011
06012 tymin = ( box.max.y - origin.y ) * invdiry;
06013 tymax = ( box.min.y - origin.y ) * invdiry;
06014
06015 }
06016
06017 if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;
06018
06019
06020
06021
06022 if ( tymin > tmin || tmin !== tmin ) tmin = tymin;
06023
06024 if ( tymax < tmax || tmax !== tmax ) tmax = tymax;
06025
06026 if ( invdirz >= 0 ) {
06027
06028 tzmin = ( box.min.z - origin.z ) * invdirz;
06029 tzmax = ( box.max.z - origin.z ) * invdirz;
06030
06031 } else {
06032
06033 tzmin = ( box.max.z - origin.z ) * invdirz;
06034 tzmax = ( box.min.z - origin.z ) * invdirz;
06035
06036 }
06037
06038 if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;
06039
06040 if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;
06041
06042 if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;
06043
06044
06045
06046 if ( tmax < 0 ) return null;
06047
06048 return this.at( tmin >= 0 ? tmin : tmax, optionalTarget );
06049
06050 },
06051
06052 intersectTriangle: function () {
06053
06054
06055 var diff = new THREE.Vector3();
06056 var edge1 = new THREE.Vector3();
06057 var edge2 = new THREE.Vector3();
06058 var normal = new THREE.Vector3();
06059
06060 return function ( a, b, c, backfaceCulling, optionalTarget ) {
06061
06062
06063
06064 edge1.subVectors( b, a );
06065 edge2.subVectors( c, a );
06066 normal.crossVectors( edge1, edge2 );
06067
06068
06069
06070
06071
06072
06073 var DdN = this.direction.dot( normal );
06074 var sign;
06075
06076 if ( DdN > 0 ) {
06077
06078 if ( backfaceCulling ) return null;
06079 sign = 1;
06080
06081 } else if ( DdN < 0 ) {
06082
06083 sign = - 1;
06084 DdN = - DdN;
06085
06086 } else {
06087
06088 return null;
06089
06090 }
06091
06092 diff.subVectors( this.origin, a );
06093 var DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );
06094
06095
06096 if ( DdQxE2 < 0 ) {
06097
06098 return null;
06099
06100 }
06101
06102 var DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );
06103
06104
06105 if ( DdE1xQ < 0 ) {
06106
06107 return null;
06108
06109 }
06110
06111
06112 if ( DdQxE2 + DdE1xQ > DdN ) {
06113
06114 return null;
06115
06116 }
06117
06118
06119 var QdN = - sign * diff.dot( normal );
06120
06121
06122 if ( QdN < 0 ) {
06123
06124 return null;
06125
06126 }
06127
06128
06129 return this.at( QdN / DdN, optionalTarget );
06130
06131 };
06132
06133 }(),
06134
06135 applyMatrix4: function ( matrix4 ) {
06136
06137 this.direction.add( this.origin ).applyMatrix4( matrix4 );
06138 this.origin.applyMatrix4( matrix4 );
06139 this.direction.sub( this.origin );
06140 this.direction.normalize();
06141
06142 return this;
06143
06144 },
06145
06146 equals: function ( ray ) {
06147
06148 return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );
06149
06150 }
06151
06152 };
06153
06154
06155
06161 THREE.Sphere = function ( center, radius ) {
06162
06163 this.center = ( center !== undefined ) ? center : new THREE.Vector3();
06164 this.radius = ( radius !== undefined ) ? radius : 0;
06165
06166 };
06167
06168 THREE.Sphere.prototype = {
06169
06170 constructor: THREE.Sphere,
06171
06172 set: function ( center, radius ) {
06173
06174 this.center.copy( center );
06175 this.radius = radius;
06176
06177 return this;
06178
06179 },
06180
06181 setFromPoints: function () {
06182
06183 var box = new THREE.Box3();
06184
06185 return function ( points, optionalCenter ) {
06186
06187 var center = this.center;
06188
06189 if ( optionalCenter !== undefined ) {
06190
06191 center.copy( optionalCenter );
06192
06193 } else {
06194
06195 box.setFromPoints( points ).center( center );
06196
06197 }
06198
06199 var maxRadiusSq = 0;
06200
06201 for ( var i = 0, il = points.length; i < il; i ++ ) {
06202
06203 maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );
06204
06205 }
06206
06207 this.radius = Math.sqrt( maxRadiusSq );
06208
06209 return this;
06210
06211 };
06212
06213 }(),
06214
06215 clone: function () {
06216
06217 return new this.constructor().copy( this );
06218
06219 },
06220
06221 copy: function ( sphere ) {
06222
06223 this.center.copy( sphere.center );
06224 this.radius = sphere.radius;
06225
06226 return this;
06227
06228 },
06229
06230 empty: function () {
06231
06232 return ( this.radius <= 0 );
06233
06234 },
06235
06236 containsPoint: function ( point ) {
06237
06238 return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );
06239
06240 },
06241
06242 distanceToPoint: function ( point ) {
06243
06244 return ( point.distanceTo( this.center ) - this.radius );
06245
06246 },
06247
06248 intersectsSphere: function ( sphere ) {
06249
06250 var radiusSum = this.radius + sphere.radius;
06251
06252 return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );
06253
06254 },
06255
06256 clampPoint: function ( point, optionalTarget ) {
06257
06258 var deltaLengthSq = this.center.distanceToSquared( point );
06259
06260 var result = optionalTarget || new THREE.Vector3();
06261 result.copy( point );
06262
06263 if ( deltaLengthSq > ( this.radius * this.radius ) ) {
06264
06265 result.sub( this.center ).normalize();
06266 result.multiplyScalar( this.radius ).add( this.center );
06267
06268 }
06269
06270 return result;
06271
06272 },
06273
06274 getBoundingBox: function ( optionalTarget ) {
06275
06276 var box = optionalTarget || new THREE.Box3();
06277
06278 box.set( this.center, this.center );
06279 box.expandByScalar( this.radius );
06280
06281 return box;
06282
06283 },
06284
06285 applyMatrix4: function ( matrix ) {
06286
06287 this.center.applyMatrix4( matrix );
06288 this.radius = this.radius * matrix.getMaxScaleOnAxis();
06289
06290 return this;
06291
06292 },
06293
06294 translate: function ( offset ) {
06295
06296 this.center.add( offset );
06297
06298 return this;
06299
06300 },
06301
06302 equals: function ( sphere ) {
06303
06304 return sphere.center.equals( this.center ) && ( sphere.radius === this.radius );
06305
06306 }
06307
06308 };
06309
06310
06311
06318 THREE.Frustum = function ( p0, p1, p2, p3, p4, p5 ) {
06319
06320 this.planes = [
06321
06322 ( p0 !== undefined ) ? p0 : new THREE.Plane(),
06323 ( p1 !== undefined ) ? p1 : new THREE.Plane(),
06324 ( p2 !== undefined ) ? p2 : new THREE.Plane(),
06325 ( p3 !== undefined ) ? p3 : new THREE.Plane(),
06326 ( p4 !== undefined ) ? p4 : new THREE.Plane(),
06327 ( p5 !== undefined ) ? p5 : new THREE.Plane()
06328
06329 ];
06330
06331 };
06332
06333 THREE.Frustum.prototype = {
06334
06335 constructor: THREE.Frustum,
06336
06337 set: function ( p0, p1, p2, p3, p4, p5 ) {
06338
06339 var planes = this.planes;
06340
06341 planes[ 0 ].copy( p0 );
06342 planes[ 1 ].copy( p1 );
06343 planes[ 2 ].copy( p2 );
06344 planes[ 3 ].copy( p3 );
06345 planes[ 4 ].copy( p4 );
06346 planes[ 5 ].copy( p5 );
06347
06348 return this;
06349
06350 },
06351
06352 clone: function () {
06353
06354 return new this.constructor().copy( this );
06355
06356 },
06357
06358 copy: function ( frustum ) {
06359
06360 var planes = this.planes;
06361
06362 for ( var i = 0; i < 6; i ++ ) {
06363
06364 planes[ i ].copy( frustum.planes[ i ] );
06365
06366 }
06367
06368 return this;
06369
06370 },
06371
06372 setFromMatrix: function ( m ) {
06373
06374 var planes = this.planes;
06375 var me = m.elements;
06376 var me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];
06377 var me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];
06378 var me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];
06379 var me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];
06380
06381 planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();
06382 planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();
06383 planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();
06384 planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();
06385 planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();
06386 planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();
06387
06388 return this;
06389
06390 },
06391
06392 intersectsObject: function () {
06393
06394 var sphere = new THREE.Sphere();
06395
06396 return function ( object ) {
06397
06398 var geometry = object.geometry;
06399
06400 if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
06401
06402 sphere.copy( geometry.boundingSphere );
06403 sphere.applyMatrix4( object.matrixWorld );
06404
06405 return this.intersectsSphere( sphere );
06406
06407 };
06408
06409 }(),
06410
06411 intersectsSphere: function ( sphere ) {
06412
06413 var planes = this.planes;
06414 var center = sphere.center;
06415 var negRadius = - sphere.radius;
06416
06417 for ( var i = 0; i < 6; i ++ ) {
06418
06419 var distance = planes[ i ].distanceToPoint( center );
06420
06421 if ( distance < negRadius ) {
06422
06423 return false;
06424
06425 }
06426
06427 }
06428
06429 return true;
06430
06431 },
06432
06433 intersectsBox: function () {
06434
06435 var p1 = new THREE.Vector3(),
06436 p2 = new THREE.Vector3();
06437
06438 return function ( box ) {
06439
06440 var planes = this.planes;
06441
06442 for ( var i = 0; i < 6 ; i ++ ) {
06443
06444 var plane = planes[ i ];
06445
06446 p1.x = plane.normal.x > 0 ? box.min.x : box.max.x;
06447 p2.x = plane.normal.x > 0 ? box.max.x : box.min.x;
06448 p1.y = plane.normal.y > 0 ? box.min.y : box.max.y;
06449 p2.y = plane.normal.y > 0 ? box.max.y : box.min.y;
06450 p1.z = plane.normal.z > 0 ? box.min.z : box.max.z;
06451 p2.z = plane.normal.z > 0 ? box.max.z : box.min.z;
06452
06453 var d1 = plane.distanceToPoint( p1 );
06454 var d2 = plane.distanceToPoint( p2 );
06455
06456
06457
06458 if ( d1 < 0 && d2 < 0 ) {
06459
06460 return false;
06461
06462 }
06463
06464 }
06465
06466 return true;
06467
06468 };
06469
06470 }(),
06471
06472
06473 containsPoint: function ( point ) {
06474
06475 var planes = this.planes;
06476
06477 for ( var i = 0; i < 6; i ++ ) {
06478
06479 if ( planes[ i ].distanceToPoint( point ) < 0 ) {
06480
06481 return false;
06482
06483 }
06484
06485 }
06486
06487 return true;
06488
06489 }
06490
06491 };
06492
06493
06494
06499 THREE.Plane = function ( normal, constant ) {
06500
06501 this.normal = ( normal !== undefined ) ? normal : new THREE.Vector3( 1, 0, 0 );
06502 this.constant = ( constant !== undefined ) ? constant : 0;
06503
06504 };
06505
06506 THREE.Plane.prototype = {
06507
06508 constructor: THREE.Plane,
06509
06510 set: function ( normal, constant ) {
06511
06512 this.normal.copy( normal );
06513 this.constant = constant;
06514
06515 return this;
06516
06517 },
06518
06519 setComponents: function ( x, y, z, w ) {
06520
06521 this.normal.set( x, y, z );
06522 this.constant = w;
06523
06524 return this;
06525
06526 },
06527
06528 setFromNormalAndCoplanarPoint: function ( normal, point ) {
06529
06530 this.normal.copy( normal );
06531 this.constant = - point.dot( this.normal );
06532
06533 return this;
06534
06535 },
06536
06537 setFromCoplanarPoints: function () {
06538
06539 var v1 = new THREE.Vector3();
06540 var v2 = new THREE.Vector3();
06541
06542 return function ( a, b, c ) {
06543
06544 var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();
06545
06546
06547
06548 this.setFromNormalAndCoplanarPoint( normal, a );
06549
06550 return this;
06551
06552 };
06553
06554 }(),
06555
06556 clone: function () {
06557
06558 return new this.constructor().copy( this );
06559
06560 },
06561
06562 copy: function ( plane ) {
06563
06564 this.normal.copy( plane.normal );
06565 this.constant = plane.constant;
06566
06567 return this;
06568
06569 },
06570
06571 normalize: function () {
06572
06573
06574
06575 var inverseNormalLength = 1.0 / this.normal.length();
06576 this.normal.multiplyScalar( inverseNormalLength );
06577 this.constant *= inverseNormalLength;
06578
06579 return this;
06580
06581 },
06582
06583 negate: function () {
06584
06585 this.constant *= - 1;
06586 this.normal.negate();
06587
06588 return this;
06589
06590 },
06591
06592 distanceToPoint: function ( point ) {
06593
06594 return this.normal.dot( point ) + this.constant;
06595
06596 },
06597
06598 distanceToSphere: function ( sphere ) {
06599
06600 return this.distanceToPoint( sphere.center ) - sphere.radius;
06601
06602 },
06603
06604 projectPoint: function ( point, optionalTarget ) {
06605
06606 return this.orthoPoint( point, optionalTarget ).sub( point ).negate();
06607
06608 },
06609
06610 orthoPoint: function ( point, optionalTarget ) {
06611
06612 var perpendicularMagnitude = this.distanceToPoint( point );
06613
06614 var result = optionalTarget || new THREE.Vector3();
06615 return result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );
06616
06617 },
06618
06619 isIntersectionLine: function ( line ) {
06620
06621
06622
06623 var startSign = this.distanceToPoint( line.start );
06624 var endSign = this.distanceToPoint( line.end );
06625
06626 return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );
06627
06628 },
06629
06630 intersectLine: function () {
06631
06632 var v1 = new THREE.Vector3();
06633
06634 return function ( line, optionalTarget ) {
06635
06636 var result = optionalTarget || new THREE.Vector3();
06637
06638 var direction = line.delta( v1 );
06639
06640 var denominator = this.normal.dot( direction );
06641
06642 if ( denominator === 0 ) {
06643
06644
06645 if ( this.distanceToPoint( line.start ) === 0 ) {
06646
06647 return result.copy( line.start );
06648
06649 }
06650
06651
06652 return undefined;
06653
06654 }
06655
06656 var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;
06657
06658 if ( t < 0 || t > 1 ) {
06659
06660 return undefined;
06661
06662 }
06663
06664 return result.copy( direction ).multiplyScalar( t ).add( line.start );
06665
06666 };
06667
06668 }(),
06669
06670
06671 coplanarPoint: function ( optionalTarget ) {
06672
06673 var result = optionalTarget || new THREE.Vector3();
06674 return result.copy( this.normal ).multiplyScalar( - this.constant );
06675
06676 },
06677
06678 applyMatrix4: function () {
06679
06680 var v1 = new THREE.Vector3();
06681 var v2 = new THREE.Vector3();
06682 var m1 = new THREE.Matrix3();
06683
06684 return function ( matrix, optionalNormalMatrix ) {
06685
06686
06687
06688 var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );
06689 var newNormal = v1.copy( this.normal ).applyMatrix3( normalMatrix );
06690
06691 var newCoplanarPoint = this.coplanarPoint( v2 );
06692 newCoplanarPoint.applyMatrix4( matrix );
06693
06694 this.setFromNormalAndCoplanarPoint( newNormal, newCoplanarPoint );
06695
06696 return this;
06697
06698 };
06699
06700 }(),
06701
06702 translate: function ( offset ) {
06703
06704 this.constant = this.constant - offset.dot( this.normal );
06705
06706 return this;
06707
06708 },
06709
06710 equals: function ( plane ) {
06711
06712 return plane.normal.equals( this.normal ) && ( plane.constant === this.constant );
06713
06714 }
06715
06716 };
06717
06718
06719
06725 THREE.Math = {
06726
06727 generateUUID: function () {
06728
06729
06730
06731 var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );
06732 var uuid = new Array( 36 );
06733 var rnd = 0, r;
06734
06735 return function () {
06736
06737 for ( var i = 0; i < 36; i ++ ) {
06738
06739 if ( i === 8 || i === 13 || i === 18 || i === 23 ) {
06740
06741 uuid[ i ] = '-';
06742
06743 } else if ( i === 14 ) {
06744
06745 uuid[ i ] = '4';
06746
06747 } else {
06748
06749 if ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;
06750 r = rnd & 0xf;
06751 rnd = rnd >> 4;
06752 uuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];
06753
06754 }
06755
06756 }
06757
06758 return uuid.join( '' );
06759
06760 };
06761
06762 }(),
06763
06764 clamp: function ( value, min, max ) {
06765
06766 return Math.max( min, Math.min( max, value ) );
06767
06768 },
06769
06770
06771
06772
06773 euclideanModulo: function ( n, m ) {
06774
06775 return ( ( n % m ) + m ) % m;
06776
06777 },
06778
06779
06780
06781 mapLinear: function ( x, a1, a2, b1, b2 ) {
06782
06783 return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
06784
06785 },
06786
06787
06788
06789 smoothstep: function ( x, min, max ) {
06790
06791 if ( x <= min ) return 0;
06792 if ( x >= max ) return 1;
06793
06794 x = ( x - min ) / ( max - min );
06795
06796 return x * x * ( 3 - 2 * x );
06797
06798 },
06799
06800 smootherstep: function ( x, min, max ) {
06801
06802 if ( x <= min ) return 0;
06803 if ( x >= max ) return 1;
06804
06805 x = ( x - min ) / ( max - min );
06806
06807 return x * x * x * ( x * ( x * 6 - 15 ) + 10 );
06808
06809 },
06810
06811
06812
06813
06814 random16: function () {
06815
06816 return ( 65280 * Math.random() + 255 * Math.random() ) / 65535;
06817
06818 },
06819
06820
06821
06822 randInt: function ( low, high ) {
06823
06824 return low + Math.floor( Math.random() * ( high - low + 1 ) );
06825
06826 },
06827
06828
06829
06830 randFloat: function ( low, high ) {
06831
06832 return low + Math.random() * ( high - low );
06833
06834 },
06835
06836
06837
06838 randFloatSpread: function ( range ) {
06839
06840 return range * ( 0.5 - Math.random() );
06841
06842 },
06843
06844 degToRad: function () {
06845
06846 var degreeToRadiansFactor = Math.PI / 180;
06847
06848 return function ( degrees ) {
06849
06850 return degrees * degreeToRadiansFactor;
06851
06852 };
06853
06854 }(),
06855
06856 radToDeg: function () {
06857
06858 var radianToDegreesFactor = 180 / Math.PI;
06859
06860 return function ( radians ) {
06861
06862 return radians * radianToDegreesFactor;
06863
06864 };
06865
06866 }(),
06867
06868 isPowerOfTwo: function ( value ) {
06869
06870 return ( value & ( value - 1 ) ) === 0 && value !== 0;
06871
06872 },
06873
06874 nearestPowerOfTwo: function ( value ) {
06875
06876 return Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );
06877
06878 },
06879
06880 nextPowerOfTwo: function ( value ) {
06881
06882 value --;
06883 value |= value >> 1;
06884 value |= value >> 2;
06885 value |= value >> 4;
06886 value |= value >> 8;
06887 value |= value >> 16;
06888 value ++;
06889
06890 return value;
06891
06892 }
06893
06894 };
06895
06896
06897
06906 THREE.Spline = function ( points ) {
06907
06908 this.points = points;
06909
06910 var c = [], v3 = { x: 0, y: 0, z: 0 },
06911 point, intPoint, weight, w2, w3,
06912 pa, pb, pc, pd;
06913
06914 this.initFromArray = function ( a ) {
06915
06916 this.points = [];
06917
06918 for ( var i = 0; i < a.length; i ++ ) {
06919
06920 this.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] };
06921
06922 }
06923
06924 };
06925
06926 this.getPoint = function ( k ) {
06927
06928 point = ( this.points.length - 1 ) * k;
06929 intPoint = Math.floor( point );
06930 weight = point - intPoint;
06931
06932 c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;
06933 c[ 1 ] = intPoint;
06934 c[ 2 ] = intPoint > this.points.length - 2 ? this.points.length - 1 : intPoint + 1;
06935 c[ 3 ] = intPoint > this.points.length - 3 ? this.points.length - 1 : intPoint + 2;
06936
06937 pa = this.points[ c[ 0 ] ];
06938 pb = this.points[ c[ 1 ] ];
06939 pc = this.points[ c[ 2 ] ];
06940 pd = this.points[ c[ 3 ] ];
06941
06942 w2 = weight * weight;
06943 w3 = weight * w2;
06944
06945 v3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 );
06946 v3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 );
06947 v3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 );
06948
06949 return v3;
06950
06951 };
06952
06953 this.getControlPointsArray = function () {
06954
06955 var i, p, l = this.points.length,
06956 coords = [];
06957
06958 for ( i = 0; i < l; i ++ ) {
06959
06960 p = this.points[ i ];
06961 coords[ i ] = [ p.x, p.y, p.z ];
06962
06963 }
06964
06965 return coords;
06966
06967 };
06968
06969
06970
06971 this.getLength = function ( nSubDivisions ) {
06972
06973 var i, index, nSamples, position,
06974 point = 0, intPoint = 0, oldIntPoint = 0,
06975 oldPosition = new THREE.Vector3(),
06976 tmpVec = new THREE.Vector3(),
06977 chunkLengths = [],
06978 totalLength = 0;
06979
06980
06981
06982 chunkLengths[ 0 ] = 0;
06983
06984 if ( ! nSubDivisions ) nSubDivisions = 100;
06985
06986 nSamples = this.points.length * nSubDivisions;
06987
06988 oldPosition.copy( this.points[ 0 ] );
06989
06990 for ( i = 1; i < nSamples; i ++ ) {
06991
06992 index = i / nSamples;
06993
06994 position = this.getPoint( index );
06995 tmpVec.copy( position );
06996
06997 totalLength += tmpVec.distanceTo( oldPosition );
06998
06999 oldPosition.copy( position );
07000
07001 point = ( this.points.length - 1 ) * index;
07002 intPoint = Math.floor( point );
07003
07004 if ( intPoint !== oldIntPoint ) {
07005
07006 chunkLengths[ intPoint ] = totalLength;
07007 oldIntPoint = intPoint;
07008
07009 }
07010
07011 }
07012
07013
07014
07015 chunkLengths[ chunkLengths.length ] = totalLength;
07016
07017 return { chunks: chunkLengths, total: totalLength };
07018
07019 };
07020
07021 this.reparametrizeByArcLength = function ( samplingCoef ) {
07022
07023 var i, j,
07024 index, indexCurrent, indexNext,
07025 realDistance,
07026 sampling, position,
07027 newpoints = [],
07028 tmpVec = new THREE.Vector3(),
07029 sl = this.getLength();
07030
07031 newpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() );
07032
07033 for ( i = 1; i < this.points.length; i ++ ) {
07034
07035
07036
07037
07038 realDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ];
07039
07040 sampling = Math.ceil( samplingCoef * realDistance / sl.total );
07041
07042 indexCurrent = ( i - 1 ) / ( this.points.length - 1 );
07043 indexNext = i / ( this.points.length - 1 );
07044
07045 for ( j = 1; j < sampling - 1; j ++ ) {
07046
07047 index = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent );
07048
07049 position = this.getPoint( index );
07050 newpoints.push( tmpVec.copy( position ).clone() );
07051
07052 }
07053
07054 newpoints.push( tmpVec.copy( this.points[ i ] ).clone() );
07055
07056 }
07057
07058 this.points = newpoints;
07059
07060 };
07061
07062
07063
07064 function interpolate( p0, p1, p2, p3, t, t2, t3 ) {
07065
07066 var v0 = ( p2 - p0 ) * 0.5,
07067 v1 = ( p3 - p1 ) * 0.5;
07068
07069 return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;
07070
07071 }
07072
07073 };
07074
07075
07076
07082 THREE.Triangle = function ( a, b, c ) {
07083
07084 this.a = ( a !== undefined ) ? a : new THREE.Vector3();
07085 this.b = ( b !== undefined ) ? b : new THREE.Vector3();
07086 this.c = ( c !== undefined ) ? c : new THREE.Vector3();
07087
07088 };
07089
07090 THREE.Triangle.normal = function () {
07091
07092 var v0 = new THREE.Vector3();
07093
07094 return function ( a, b, c, optionalTarget ) {
07095
07096 var result = optionalTarget || new THREE.Vector3();
07097
07098 result.subVectors( c, b );
07099 v0.subVectors( a, b );
07100 result.cross( v0 );
07101
07102 var resultLengthSq = result.lengthSq();
07103 if ( resultLengthSq > 0 ) {
07104
07105 return result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );
07106
07107 }
07108
07109 return result.set( 0, 0, 0 );
07110
07111 };
07112
07113 }();
07114
07115
07116
07117 THREE.Triangle.barycoordFromPoint = function () {
07118
07119 var v0 = new THREE.Vector3();
07120 var v1 = new THREE.Vector3();
07121 var v2 = new THREE.Vector3();
07122
07123 return function ( point, a, b, c, optionalTarget ) {
07124
07125 v0.subVectors( c, a );
07126 v1.subVectors( b, a );
07127 v2.subVectors( point, a );
07128
07129 var dot00 = v0.dot( v0 );
07130 var dot01 = v0.dot( v1 );
07131 var dot02 = v0.dot( v2 );
07132 var dot11 = v1.dot( v1 );
07133 var dot12 = v1.dot( v2 );
07134
07135 var denom = ( dot00 * dot11 - dot01 * dot01 );
07136
07137 var result = optionalTarget || new THREE.Vector3();
07138
07139
07140 if ( denom === 0 ) {
07141
07142
07143
07144 return result.set( - 2, - 1, - 1 );
07145
07146 }
07147
07148 var invDenom = 1 / denom;
07149 var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
07150 var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
07151
07152
07153 return result.set( 1 - u - v, v, u );
07154
07155 };
07156
07157 }();
07158
07159 THREE.Triangle.containsPoint = function () {
07160
07161 var v1 = new THREE.Vector3();
07162
07163 return function ( point, a, b, c ) {
07164
07165 var result = THREE.Triangle.barycoordFromPoint( point, a, b, c, v1 );
07166
07167 return ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );
07168
07169 };
07170
07171 }();
07172
07173 THREE.Triangle.prototype = {
07174
07175 constructor: THREE.Triangle,
07176
07177 set: function ( a, b, c ) {
07178
07179 this.a.copy( a );
07180 this.b.copy( b );
07181 this.c.copy( c );
07182
07183 return this;
07184
07185 },
07186
07187 setFromPointsAndIndices: function ( points, i0, i1, i2 ) {
07188
07189 this.a.copy( points[ i0 ] );
07190 this.b.copy( points[ i1 ] );
07191 this.c.copy( points[ i2 ] );
07192
07193 return this;
07194
07195 },
07196
07197 clone: function () {
07198
07199 return new this.constructor().copy( this );
07200
07201 },
07202
07203 copy: function ( triangle ) {
07204
07205 this.a.copy( triangle.a );
07206 this.b.copy( triangle.b );
07207 this.c.copy( triangle.c );
07208
07209 return this;
07210
07211 },
07212
07213 area: function () {
07214
07215 var v0 = new THREE.Vector3();
07216 var v1 = new THREE.Vector3();
07217
07218 return function () {
07219
07220 v0.subVectors( this.c, this.b );
07221 v1.subVectors( this.a, this.b );
07222
07223 return v0.cross( v1 ).length() * 0.5;
07224
07225 };
07226
07227 }(),
07228
07229 midpoint: function ( optionalTarget ) {
07230
07231 var result = optionalTarget || new THREE.Vector3();
07232 return result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );
07233
07234 },
07235
07236 normal: function ( optionalTarget ) {
07237
07238 return THREE.Triangle.normal( this.a, this.b, this.c, optionalTarget );
07239
07240 },
07241
07242 plane: function ( optionalTarget ) {
07243
07244 var result = optionalTarget || new THREE.Plane();
07245
07246 return result.setFromCoplanarPoints( this.a, this.b, this.c );
07247
07248 },
07249
07250 barycoordFromPoint: function ( point, optionalTarget ) {
07251
07252 return THREE.Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );
07253
07254 },
07255
07256 containsPoint: function ( point ) {
07257
07258 return THREE.Triangle.containsPoint( point, this.a, this.b, this.c );
07259
07260 },
07261
07262 equals: function ( triangle ) {
07263
07264 return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );
07265
07266 }
07267
07268 };
07269
07270
07271
07276 THREE.Channels = function () {
07277
07278 this.mask = 1;
07279
07280 };
07281
07282 THREE.Channels.prototype = {
07283
07284 constructor: THREE.Channels,
07285
07286 set: function ( channel ) {
07287
07288 this.mask = 1 << channel;
07289
07290 },
07291
07292 enable: function ( channel ) {
07293
07294 this.mask |= 1 << channel;
07295
07296 },
07297
07298 toggle: function ( channel ) {
07299
07300 this.mask ^= 1 << channel;
07301
07302 },
07303
07304 disable: function ( channel ) {
07305
07306 this.mask &= ~ ( 1 << channel );
07307
07308 }
07309
07310 };
07311
07312
07313
07318 THREE.Clock = function ( autoStart ) {
07319
07320 this.autoStart = ( autoStart !== undefined ) ? autoStart : true;
07321
07322 this.startTime = 0;
07323 this.oldTime = 0;
07324 this.elapsedTime = 0;
07325
07326 this.running = false;
07327
07328 };
07329
07330 THREE.Clock.prototype = {
07331
07332 constructor: THREE.Clock,
07333
07334 start: function () {
07335
07336 this.startTime = self.performance.now();
07337
07338 this.oldTime = this.startTime;
07339 this.running = true;
07340
07341 },
07342
07343 stop: function () {
07344
07345 this.getElapsedTime();
07346 this.running = false;
07347
07348 },
07349
07350 getElapsedTime: function () {
07351
07352 this.getDelta();
07353 return this.elapsedTime;
07354
07355 },
07356
07357 getDelta: function () {
07358
07359 var diff = 0;
07360
07361 if ( this.autoStart && ! this.running ) {
07362
07363 this.start();
07364
07365 }
07366
07367 if ( this.running ) {
07368
07369 var newTime = self.performance.now();
07370
07371 diff = 0.001 * ( newTime - this.oldTime );
07372 this.oldTime = newTime;
07373
07374 this.elapsedTime += diff;
07375
07376 }
07377
07378 return diff;
07379
07380 }
07381
07382 };
07383
07384
07385
07390 THREE.EventDispatcher = function () {};
07391
07392 THREE.EventDispatcher.prototype = {
07393
07394 constructor: THREE.EventDispatcher,
07395
07396 apply: function ( object ) {
07397
07398 object.addEventListener = THREE.EventDispatcher.prototype.addEventListener;
07399 object.hasEventListener = THREE.EventDispatcher.prototype.hasEventListener;
07400 object.removeEventListener = THREE.EventDispatcher.prototype.removeEventListener;
07401 object.dispatchEvent = THREE.EventDispatcher.prototype.dispatchEvent;
07402
07403 },
07404
07405 addEventListener: function ( type, listener ) {
07406
07407 if ( this._listeners === undefined ) this._listeners = {};
07408
07409 var listeners = this._listeners;
07410
07411 if ( listeners[ type ] === undefined ) {
07412
07413 listeners[ type ] = [];
07414
07415 }
07416
07417 if ( listeners[ type ].indexOf( listener ) === - 1 ) {
07418
07419 listeners[ type ].push( listener );
07420
07421 }
07422
07423 },
07424
07425 hasEventListener: function ( type, listener ) {
07426
07427 if ( this._listeners === undefined ) return false;
07428
07429 var listeners = this._listeners;
07430
07431 if ( listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1 ) {
07432
07433 return true;
07434
07435 }
07436
07437 return false;
07438
07439 },
07440
07441 removeEventListener: function ( type, listener ) {
07442
07443 if ( this._listeners === undefined ) return;
07444
07445 var listeners = this._listeners;
07446 var listenerArray = listeners[ type ];
07447
07448 if ( listenerArray !== undefined ) {
07449
07450 var index = listenerArray.indexOf( listener );
07451
07452 if ( index !== - 1 ) {
07453
07454 listenerArray.splice( index, 1 );
07455
07456 }
07457
07458 }
07459
07460 },
07461
07462 dispatchEvent: function ( event ) {
07463
07464 if ( this._listeners === undefined ) return;
07465
07466 var listeners = this._listeners;
07467 var listenerArray = listeners[ event.type ];
07468
07469 if ( listenerArray !== undefined ) {
07470
07471 event.target = this;
07472
07473 var array = [];
07474 var length = listenerArray.length;
07475
07476 for ( var i = 0; i < length; i ++ ) {
07477
07478 array[ i ] = listenerArray[ i ];
07479
07480 }
07481
07482 for ( var i = 0; i < length; i ++ ) {
07483
07484 array[ i ].call( this, event );
07485
07486 }
07487
07488 }
07489
07490 }
07491
07492 };
07493
07494
07495
07502 ( function ( THREE ) {
07503
07504 THREE.Raycaster = function ( origin, direction, near, far ) {
07505
07506 this.ray = new THREE.Ray( origin, direction );
07507
07508
07509 this.near = near || 0;
07510 this.far = far || Infinity;
07511
07512 this.params = {
07513 Mesh: {},
07514 Line: {},
07515 LOD: {},
07516 Points: { threshold: 1 },
07517 Sprite: {}
07518 };
07519
07520 Object.defineProperties( this.params, {
07521 PointCloud: {
07522 get: function () {
07523 console.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );
07524 return this.Points;
07525 }
07526 }
07527 } );
07528
07529 };
07530
07531 function descSort( a, b ) {
07532
07533 return a.distance - b.distance;
07534
07535 }
07536
07537 function intersectObject( object, raycaster, intersects, recursive ) {
07538
07539 if ( object.visible === false ) return;
07540
07541 object.raycast( raycaster, intersects );
07542
07543 if ( recursive === true ) {
07544
07545 var children = object.children;
07546
07547 for ( var i = 0, l = children.length; i < l; i ++ ) {
07548
07549 intersectObject( children[ i ], raycaster, intersects, true );
07550
07551 }
07552
07553 }
07554
07555 }
07556
07557
07558
07559 THREE.Raycaster.prototype = {
07560
07561 constructor: THREE.Raycaster,
07562
07563 linePrecision: 1,
07564
07565 set: function ( origin, direction ) {
07566
07567
07568
07569 this.ray.set( origin, direction );
07570
07571 },
07572
07573 setFromCamera: function ( coords, camera ) {
07574
07575 if ( camera instanceof THREE.PerspectiveCamera ) {
07576
07577 this.ray.origin.setFromMatrixPosition( camera.matrixWorld );
07578 this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();
07579
07580 } else if ( camera instanceof THREE.OrthographicCamera ) {
07581
07582 this.ray.origin.set( coords.x, coords.y, - 1 ).unproject( camera );
07583 this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );
07584
07585 } else {
07586
07587 console.error( 'THREE.Raycaster: Unsupported camera type.' );
07588
07589 }
07590
07591 },
07592
07593 intersectObject: function ( object, recursive ) {
07594
07595 var intersects = [];
07596
07597 intersectObject( object, this, intersects, recursive );
07598
07599 intersects.sort( descSort );
07600
07601 return intersects;
07602
07603 },
07604
07605 intersectObjects: function ( objects, recursive ) {
07606
07607 var intersects = [];
07608
07609 if ( Array.isArray( objects ) === false ) {
07610
07611 console.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );
07612 return intersects;
07613
07614 }
07615
07616 for ( var i = 0, l = objects.length; i < l; i ++ ) {
07617
07618 intersectObject( objects[ i ], this, intersects, recursive );
07619
07620 }
07621
07622 intersects.sort( descSort );
07623
07624 return intersects;
07625
07626 }
07627
07628 };
07629
07630 }( THREE ) );
07631
07632
07633
07642 THREE.Object3D = function () {
07643
07644 Object.defineProperty( this, 'id', { value: THREE.Object3DIdCount ++ } );
07645
07646 this.uuid = THREE.Math.generateUUID();
07647
07648 this.name = '';
07649 this.type = 'Object3D';
07650
07651 this.parent = null;
07652 this.channels = new THREE.Channels();
07653 this.children = [];
07654
07655 this.up = THREE.Object3D.DefaultUp.clone();
07656
07657 var position = new THREE.Vector3();
07658 var rotation = new THREE.Euler();
07659 var quaternion = new THREE.Quaternion();
07660 var scale = new THREE.Vector3( 1, 1, 1 );
07661
07662 function onRotationChange() {
07663
07664 quaternion.setFromEuler( rotation, false );
07665
07666 }
07667
07668 function onQuaternionChange() {
07669
07670 rotation.setFromQuaternion( quaternion, undefined, false );
07671
07672 }
07673
07674 rotation.onChange( onRotationChange );
07675 quaternion.onChange( onQuaternionChange );
07676
07677 Object.defineProperties( this, {
07678 position: {
07679 enumerable: true,
07680 value: position
07681 },
07682 rotation: {
07683 enumerable: true,
07684 value: rotation
07685 },
07686 quaternion: {
07687 enumerable: true,
07688 value: quaternion
07689 },
07690 scale: {
07691 enumerable: true,
07692 value: scale
07693 },
07694 modelViewMatrix: {
07695 value: new THREE.Matrix4()
07696 },
07697 normalMatrix: {
07698 value: new THREE.Matrix3()
07699 }
07700 } );
07701
07702 this.rotationAutoUpdate = true;
07703
07704 this.matrix = new THREE.Matrix4();
07705 this.matrixWorld = new THREE.Matrix4();
07706
07707 this.matrixAutoUpdate = THREE.Object3D.DefaultMatrixAutoUpdate;
07708 this.matrixWorldNeedsUpdate = false;
07709
07710 this.visible = true;
07711
07712 this.castShadow = false;
07713 this.receiveShadow = false;
07714
07715 this.frustumCulled = true;
07716 this.renderOrder = 0;
07717
07718 this.userData = {};
07719
07720 };
07721
07722 THREE.Object3D.DefaultUp = new THREE.Vector3( 0, 1, 0 );
07723 THREE.Object3D.DefaultMatrixAutoUpdate = true;
07724
07725 THREE.Object3D.prototype = {
07726
07727 constructor: THREE.Object3D,
07728
07729 get eulerOrder () {
07730
07731 console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );
07732
07733 return this.rotation.order;
07734
07735 },
07736
07737 set eulerOrder ( value ) {
07738
07739 console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );
07740
07741 this.rotation.order = value;
07742
07743 },
07744
07745 get useQuaternion () {
07746
07747 console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
07748
07749 },
07750
07751 set useQuaternion ( value ) {
07752
07753 console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
07754
07755 },
07756
07757 set renderDepth ( value ) {
07758
07759 console.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );
07760
07761 },
07762
07763
07764
07765 applyMatrix: function ( matrix ) {
07766
07767 this.matrix.multiplyMatrices( matrix, this.matrix );
07768
07769 this.matrix.decompose( this.position, this.quaternion, this.scale );
07770
07771 },
07772
07773 setRotationFromAxisAngle: function ( axis, angle ) {
07774
07775
07776
07777 this.quaternion.setFromAxisAngle( axis, angle );
07778
07779 },
07780
07781 setRotationFromEuler: function ( euler ) {
07782
07783 this.quaternion.setFromEuler( euler, true );
07784
07785 },
07786
07787 setRotationFromMatrix: function ( m ) {
07788
07789
07790
07791 this.quaternion.setFromRotationMatrix( m );
07792
07793 },
07794
07795 setRotationFromQuaternion: function ( q ) {
07796
07797
07798
07799 this.quaternion.copy( q );
07800
07801 },
07802
07803 rotateOnAxis: function () {
07804
07805
07806
07807
07808 var q1 = new THREE.Quaternion();
07809
07810 return function ( axis, angle ) {
07811
07812 q1.setFromAxisAngle( axis, angle );
07813
07814 this.quaternion.multiply( q1 );
07815
07816 return this;
07817
07818 };
07819
07820 }(),
07821
07822 rotateX: function () {
07823
07824 var v1 = new THREE.Vector3( 1, 0, 0 );
07825
07826 return function ( angle ) {
07827
07828 return this.rotateOnAxis( v1, angle );
07829
07830 };
07831
07832 }(),
07833
07834 rotateY: function () {
07835
07836 var v1 = new THREE.Vector3( 0, 1, 0 );
07837
07838 return function ( angle ) {
07839
07840 return this.rotateOnAxis( v1, angle );
07841
07842 };
07843
07844 }(),
07845
07846 rotateZ: function () {
07847
07848 var v1 = new THREE.Vector3( 0, 0, 1 );
07849
07850 return function ( angle ) {
07851
07852 return this.rotateOnAxis( v1, angle );
07853
07854 };
07855
07856 }(),
07857
07858 translateOnAxis: function () {
07859
07860
07861
07862
07863 var v1 = new THREE.Vector3();
07864
07865 return function ( axis, distance ) {
07866
07867 v1.copy( axis ).applyQuaternion( this.quaternion );
07868
07869 this.position.add( v1.multiplyScalar( distance ) );
07870
07871 return this;
07872
07873 };
07874
07875 }(),
07876
07877 translate: function ( distance, axis ) {
07878
07879 console.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );
07880 return this.translateOnAxis( axis, distance );
07881
07882 },
07883
07884 translateX: function () {
07885
07886 var v1 = new THREE.Vector3( 1, 0, 0 );
07887
07888 return function ( distance ) {
07889
07890 return this.translateOnAxis( v1, distance );
07891
07892 };
07893
07894 }(),
07895
07896 translateY: function () {
07897
07898 var v1 = new THREE.Vector3( 0, 1, 0 );
07899
07900 return function ( distance ) {
07901
07902 return this.translateOnAxis( v1, distance );
07903
07904 };
07905
07906 }(),
07907
07908 translateZ: function () {
07909
07910 var v1 = new THREE.Vector3( 0, 0, 1 );
07911
07912 return function ( distance ) {
07913
07914 return this.translateOnAxis( v1, distance );
07915
07916 };
07917
07918 }(),
07919
07920 localToWorld: function ( vector ) {
07921
07922 return vector.applyMatrix4( this.matrixWorld );
07923
07924 },
07925
07926 worldToLocal: function () {
07927
07928 var m1 = new THREE.Matrix4();
07929
07930 return function ( vector ) {
07931
07932 return vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );
07933
07934 };
07935
07936 }(),
07937
07938 lookAt: function () {
07939
07940
07941
07942 var m1 = new THREE.Matrix4();
07943
07944 return function ( vector ) {
07945
07946 m1.lookAt( vector, this.position, this.up );
07947
07948 this.quaternion.setFromRotationMatrix( m1 );
07949
07950 };
07951
07952 }(),
07953
07954 add: function ( object ) {
07955
07956 if ( arguments.length > 1 ) {
07957
07958 for ( var i = 0; i < arguments.length; i ++ ) {
07959
07960 this.add( arguments[ i ] );
07961
07962 }
07963
07964 return this;
07965
07966 }
07967
07968 if ( object === this ) {
07969
07970 console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object );
07971 return this;
07972
07973 }
07974
07975 if ( object instanceof THREE.Object3D ) {
07976
07977 if ( object.parent !== null ) {
07978
07979 object.parent.remove( object );
07980
07981 }
07982
07983 object.parent = this;
07984 object.dispatchEvent( { type: 'added' } );
07985
07986 this.children.push( object );
07987
07988 } else {
07989
07990 console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object );
07991
07992 }
07993
07994 return this;
07995
07996 },
07997
07998 remove: function ( object ) {
07999
08000 if ( arguments.length > 1 ) {
08001
08002 for ( var i = 0; i < arguments.length; i ++ ) {
08003
08004 this.remove( arguments[ i ] );
08005
08006 }
08007
08008 }
08009
08010 var index = this.children.indexOf( object );
08011
08012 if ( index !== - 1 ) {
08013
08014 object.parent = null;
08015
08016 object.dispatchEvent( { type: 'removed' } );
08017
08018 this.children.splice( index, 1 );
08019
08020 }
08021
08022 },
08023
08024 getChildByName: function ( name ) {
08025
08026 console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );
08027 return this.getObjectByName( name );
08028
08029 },
08030
08031 getObjectById: function ( id ) {
08032
08033 return this.getObjectByProperty( 'id', id );
08034
08035 },
08036
08037 getObjectByName: function ( name ) {
08038
08039 return this.getObjectByProperty( 'name', name );
08040
08041 },
08042
08043 getObjectByProperty: function ( name, value ) {
08044
08045 if ( this[ name ] === value ) return this;
08046
08047 for ( var i = 0, l = this.children.length; i < l; i ++ ) {
08048
08049 var child = this.children[ i ];
08050 var object = child.getObjectByProperty( name, value );
08051
08052 if ( object !== undefined ) {
08053
08054 return object;
08055
08056 }
08057
08058 }
08059
08060 return undefined;
08061
08062 },
08063
08064 getWorldPosition: function ( optionalTarget ) {
08065
08066 var result = optionalTarget || new THREE.Vector3();
08067
08068 this.updateMatrixWorld( true );
08069
08070 return result.setFromMatrixPosition( this.matrixWorld );
08071
08072 },
08073
08074 getWorldQuaternion: function () {
08075
08076 var position = new THREE.Vector3();
08077 var scale = new THREE.Vector3();
08078
08079 return function ( optionalTarget ) {
08080
08081 var result = optionalTarget || new THREE.Quaternion();
08082
08083 this.updateMatrixWorld( true );
08084
08085 this.matrixWorld.decompose( position, result, scale );
08086
08087 return result;
08088
08089 };
08090
08091 }(),
08092
08093 getWorldRotation: function () {
08094
08095 var quaternion = new THREE.Quaternion();
08096
08097 return function ( optionalTarget ) {
08098
08099 var result = optionalTarget || new THREE.Euler();
08100
08101 this.getWorldQuaternion( quaternion );
08102
08103 return result.setFromQuaternion( quaternion, this.rotation.order, false );
08104
08105 };
08106
08107 }(),
08108
08109 getWorldScale: function () {
08110
08111 var position = new THREE.Vector3();
08112 var quaternion = new THREE.Quaternion();
08113
08114 return function ( optionalTarget ) {
08115
08116 var result = optionalTarget || new THREE.Vector3();
08117
08118 this.updateMatrixWorld( true );
08119
08120 this.matrixWorld.decompose( position, quaternion, result );
08121
08122 return result;
08123
08124 };
08125
08126 }(),
08127
08128 getWorldDirection: function () {
08129
08130 var quaternion = new THREE.Quaternion();
08131
08132 return function ( optionalTarget ) {
08133
08134 var result = optionalTarget || new THREE.Vector3();
08135
08136 this.getWorldQuaternion( quaternion );
08137
08138 return result.set( 0, 0, 1 ).applyQuaternion( quaternion );
08139
08140 };
08141
08142 }(),
08143
08144 raycast: function () {},
08145
08146 traverse: function ( callback ) {
08147
08148 callback( this );
08149
08150 var children = this.children;
08151
08152 for ( var i = 0, l = children.length; i < l; i ++ ) {
08153
08154 children[ i ].traverse( callback );
08155
08156 }
08157
08158 },
08159
08160 traverseVisible: function ( callback ) {
08161
08162 if ( this.visible === false ) return;
08163
08164 callback( this );
08165
08166 var children = this.children;
08167
08168 for ( var i = 0, l = children.length; i < l; i ++ ) {
08169
08170 children[ i ].traverseVisible( callback );
08171
08172 }
08173
08174 },
08175
08176 traverseAncestors: function ( callback ) {
08177
08178 var parent = this.parent;
08179
08180 if ( parent !== null ) {
08181
08182 callback( parent );
08183
08184 parent.traverseAncestors( callback );
08185
08186 }
08187
08188 },
08189
08190 updateMatrix: function () {
08191
08192 this.matrix.compose( this.position, this.quaternion, this.scale );
08193
08194 this.matrixWorldNeedsUpdate = true;
08195
08196 },
08197
08198 updateMatrixWorld: function ( force ) {
08199
08200 if ( this.matrixAutoUpdate === true ) this.updateMatrix();
08201
08202 if ( this.matrixWorldNeedsUpdate === true || force === true ) {
08203
08204 if ( this.parent === null ) {
08205
08206 this.matrixWorld.copy( this.matrix );
08207
08208 } else {
08209
08210 this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
08211
08212 }
08213
08214 this.matrixWorldNeedsUpdate = false;
08215
08216 force = true;
08217
08218 }
08219
08220
08221
08222 for ( var i = 0, l = this.children.length; i < l; i ++ ) {
08223
08224 this.children[ i ].updateMatrixWorld( force );
08225
08226 }
08227
08228 },
08229
08230 toJSON: function ( meta ) {
08231
08232 var isRootObject = ( meta === undefined );
08233
08234 var output = {};
08235
08236
08237
08238
08239 if ( isRootObject ) {
08240
08241
08242 meta = {
08243 geometries: {},
08244 materials: {},
08245 textures: {},
08246 images: {}
08247 };
08248
08249 output.metadata = {
08250 version: 4.4,
08251 type: 'Object',
08252 generator: 'Object3D.toJSON'
08253 };
08254
08255 }
08256
08257
08258
08259 var object = {};
08260
08261 object.uuid = this.uuid;
08262 object.type = this.type;
08263
08264 if ( this.name !== '' ) object.name = this.name;
08265 if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;
08266 if ( this.castShadow === true ) object.castShadow = true;
08267 if ( this.receiveShadow === true ) object.receiveShadow = true;
08268 if ( this.visible === false ) object.visible = false;
08269
08270 object.matrix = this.matrix.toArray();
08271
08272
08273
08274 if ( this.geometry !== undefined ) {
08275
08276 if ( meta.geometries[ this.geometry.uuid ] === undefined ) {
08277
08278 meta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );
08279
08280 }
08281
08282 object.geometry = this.geometry.uuid;
08283
08284 }
08285
08286 if ( this.material !== undefined ) {
08287
08288 if ( meta.materials[ this.material.uuid ] === undefined ) {
08289
08290 meta.materials[ this.material.uuid ] = this.material.toJSON( meta );
08291
08292 }
08293
08294 object.material = this.material.uuid;
08295
08296 }
08297
08298
08299
08300 if ( this.children.length > 0 ) {
08301
08302 object.children = [];
08303
08304 for ( var i = 0; i < this.children.length; i ++ ) {
08305
08306 object.children.push( this.children[ i ].toJSON( meta ).object );
08307
08308 }
08309
08310 }
08311
08312 if ( isRootObject ) {
08313
08314 var geometries = extractFromCache( meta.geometries );
08315 var materials = extractFromCache( meta.materials );
08316 var textures = extractFromCache( meta.textures );
08317 var images = extractFromCache( meta.images );
08318
08319 if ( geometries.length > 0 ) output.geometries = geometries;
08320 if ( materials.length > 0 ) output.materials = materials;
08321 if ( textures.length > 0 ) output.textures = textures;
08322 if ( images.length > 0 ) output.images = images;
08323
08324 }
08325
08326 output.object = object;
08327
08328 return output;
08329
08330
08331
08332
08333 function extractFromCache ( cache ) {
08334
08335 var values = [];
08336 for ( var key in cache ) {
08337
08338 var data = cache[ key ];
08339 delete data.metadata;
08340 values.push( data );
08341
08342 }
08343 return values;
08344
08345 }
08346
08347 },
08348
08349 clone: function ( recursive ) {
08350
08351 return new this.constructor().copy( this, recursive );
08352
08353 },
08354
08355 copy: function ( source, recursive ) {
08356
08357 if ( recursive === undefined ) recursive = true;
08358
08359 this.name = source.name;
08360
08361 this.up.copy( source.up );
08362
08363 this.position.copy( source.position );
08364 this.quaternion.copy( source.quaternion );
08365 this.scale.copy( source.scale );
08366
08367 this.rotationAutoUpdate = source.rotationAutoUpdate;
08368
08369 this.matrix.copy( source.matrix );
08370 this.matrixWorld.copy( source.matrixWorld );
08371
08372 this.matrixAutoUpdate = source.matrixAutoUpdate;
08373 this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
08374
08375 this.visible = source.visible;
08376
08377 this.castShadow = source.castShadow;
08378 this.receiveShadow = source.receiveShadow;
08379
08380 this.frustumCulled = source.frustumCulled;
08381 this.renderOrder = source.renderOrder;
08382
08383 this.userData = JSON.parse( JSON.stringify( source.userData ) );
08384
08385 if ( recursive === true ) {
08386
08387 for ( var i = 0; i < source.children.length; i ++ ) {
08388
08389 var child = source.children[ i ];
08390 this.add( child.clone() );
08391
08392 }
08393
08394 }
08395
08396 return this;
08397
08398 }
08399
08400 };
08401
08402 THREE.EventDispatcher.prototype.apply( THREE.Object3D.prototype );
08403
08404 THREE.Object3DIdCount = 0;
08405
08406
08407
08413 THREE.Face3 = function ( a, b, c, normal, color, materialIndex ) {
08414
08415 this.a = a;
08416 this.b = b;
08417 this.c = c;
08418
08419 this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
08420 this.vertexNormals = Array.isArray( normal ) ? normal : [];
08421
08422 this.color = color instanceof THREE.Color ? color : new THREE.Color();
08423 this.vertexColors = Array.isArray( color ) ? color : [];
08424
08425 this.materialIndex = materialIndex !== undefined ? materialIndex : 0;
08426
08427 };
08428
08429 THREE.Face3.prototype = {
08430
08431 constructor: THREE.Face3,
08432
08433 clone: function () {
08434
08435 return new this.constructor().copy( this );
08436
08437 },
08438
08439 copy: function ( source ) {
08440
08441 this.a = source.a;
08442 this.b = source.b;
08443 this.c = source.c;
08444
08445 this.normal.copy( source.normal );
08446 this.color.copy( source.color );
08447
08448 this.materialIndex = source.materialIndex;
08449
08450 for ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {
08451
08452 this.vertexNormals[ i ] = source.vertexNormals[ i ].clone();
08453
08454 }
08455
08456 for ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {
08457
08458 this.vertexColors[ i ] = source.vertexColors[ i ].clone();
08459
08460 }
08461
08462 return this;
08463
08464 }
08465
08466 };
08467
08468
08469
08474 THREE.Face4 = function ( a, b, c, d, normal, color, materialIndex ) {
08475
08476 console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );
08477 return new THREE.Face3( a, b, c, normal, color, materialIndex );
08478
08479 };
08480
08481
08482
08487 THREE.BufferAttribute = function ( array, itemSize ) {
08488
08489 this.uuid = THREE.Math.generateUUID();
08490
08491 this.array = array;
08492 this.itemSize = itemSize;
08493
08494 this.dynamic = false;
08495 this.updateRange = { offset: 0, count: - 1 };
08496
08497 this.version = 0;
08498
08499 };
08500
08501 THREE.BufferAttribute.prototype = {
08502
08503 constructor: THREE.BufferAttribute,
08504
08505 get length() {
08506
08507 console.warn( 'THREE.BufferAttribute: .length has been deprecated. Please use .count.' );
08508 return this.array.length;
08509
08510 },
08511
08512 get count() {
08513
08514 return this.array.length / this.itemSize;
08515
08516 },
08517
08518 set needsUpdate( value ) {
08519
08520 if ( value === true ) this.version ++;
08521
08522 },
08523
08524 setDynamic: function ( value ) {
08525
08526 this.dynamic = value;
08527
08528 return this;
08529
08530 },
08531
08532 copy: function ( source ) {
08533
08534 this.array = new source.array.constructor( source.array );
08535 this.itemSize = source.itemSize;
08536
08537 this.dynamic = source.dynamic;
08538
08539 return this;
08540
08541 },
08542
08543 copyAt: function ( index1, attribute, index2 ) {
08544
08545 index1 *= this.itemSize;
08546 index2 *= attribute.itemSize;
08547
08548 for ( var i = 0, l = this.itemSize; i < l; i ++ ) {
08549
08550 this.array[ index1 + i ] = attribute.array[ index2 + i ];
08551
08552 }
08553
08554 return this;
08555
08556 },
08557
08558 copyArray: function ( array ) {
08559
08560 this.array.set( array );
08561
08562 return this;
08563
08564 },
08565
08566 copyColorsArray: function ( colors ) {
08567
08568 var array = this.array, offset = 0;
08569
08570 for ( var i = 0, l = colors.length; i < l; i ++ ) {
08571
08572 var color = colors[ i ];
08573
08574 if ( color === undefined ) {
08575
08576 console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );
08577 color = new THREE.Color();
08578
08579 }
08580
08581 array[ offset ++ ] = color.r;
08582 array[ offset ++ ] = color.g;
08583 array[ offset ++ ] = color.b;
08584
08585 }
08586
08587 return this;
08588
08589 },
08590
08591 copyIndicesArray: function ( indices ) {
08592
08593 var array = this.array, offset = 0;
08594
08595 for ( var i = 0, l = indices.length; i < l; i ++ ) {
08596
08597 var index = indices[ i ];
08598
08599 array[ offset ++ ] = index.a;
08600 array[ offset ++ ] = index.b;
08601 array[ offset ++ ] = index.c;
08602
08603 }
08604
08605 return this;
08606
08607 },
08608
08609 copyVector2sArray: function ( vectors ) {
08610
08611 var array = this.array, offset = 0;
08612
08613 for ( var i = 0, l = vectors.length; i < l; i ++ ) {
08614
08615 var vector = vectors[ i ];
08616
08617 if ( vector === undefined ) {
08618
08619 console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );
08620 vector = new THREE.Vector2();
08621
08622 }
08623
08624 array[ offset ++ ] = vector.x;
08625 array[ offset ++ ] = vector.y;
08626
08627 }
08628
08629 return this;
08630
08631 },
08632
08633 copyVector3sArray: function ( vectors ) {
08634
08635 var array = this.array, offset = 0;
08636
08637 for ( var i = 0, l = vectors.length; i < l; i ++ ) {
08638
08639 var vector = vectors[ i ];
08640
08641 if ( vector === undefined ) {
08642
08643 console.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );
08644 vector = new THREE.Vector3();
08645
08646 }
08647
08648 array[ offset ++ ] = vector.x;
08649 array[ offset ++ ] = vector.y;
08650 array[ offset ++ ] = vector.z;
08651
08652 }
08653
08654 return this;
08655
08656 },
08657
08658 copyVector4sArray: function ( vectors ) {
08659
08660 var array = this.array, offset = 0;
08661
08662 for ( var i = 0, l = vectors.length; i < l; i ++ ) {
08663
08664 var vector = vectors[ i ];
08665
08666 if ( vector === undefined ) {
08667
08668 console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );
08669 vector = new THREE.Vector4();
08670
08671 }
08672
08673 array[ offset ++ ] = vector.x;
08674 array[ offset ++ ] = vector.y;
08675 array[ offset ++ ] = vector.z;
08676 array[ offset ++ ] = vector.w;
08677
08678 }
08679
08680 return this;
08681
08682 },
08683
08684 set: function ( value, offset ) {
08685
08686 if ( offset === undefined ) offset = 0;
08687
08688 this.array.set( value, offset );
08689
08690 return this;
08691
08692 },
08693
08694 getX: function ( index ) {
08695
08696 return this.array[ index * this.itemSize ];
08697
08698 },
08699
08700 setX: function ( index, x ) {
08701
08702 this.array[ index * this.itemSize ] = x;
08703
08704 return this;
08705
08706 },
08707
08708 getY: function ( index ) {
08709
08710 return this.array[ index * this.itemSize + 1 ];
08711
08712 },
08713
08714 setY: function ( index, y ) {
08715
08716 this.array[ index * this.itemSize + 1 ] = y;
08717
08718 return this;
08719
08720 },
08721
08722 getZ: function ( index ) {
08723
08724 return this.array[ index * this.itemSize + 2 ];
08725
08726 },
08727
08728 setZ: function ( index, z ) {
08729
08730 this.array[ index * this.itemSize + 2 ] = z;
08731
08732 return this;
08733
08734 },
08735
08736 getW: function ( index ) {
08737
08738 return this.array[ index * this.itemSize + 3 ];
08739
08740 },
08741
08742 setW: function ( index, w ) {
08743
08744 this.array[ index * this.itemSize + 3 ] = w;
08745
08746 return this;
08747
08748 },
08749
08750 setXY: function ( index, x, y ) {
08751
08752 index *= this.itemSize;
08753
08754 this.array[ index + 0 ] = x;
08755 this.array[ index + 1 ] = y;
08756
08757 return this;
08758
08759 },
08760
08761 setXYZ: function ( index, x, y, z ) {
08762
08763 index *= this.itemSize;
08764
08765 this.array[ index + 0 ] = x;
08766 this.array[ index + 1 ] = y;
08767 this.array[ index + 2 ] = z;
08768
08769 return this;
08770
08771 },
08772
08773 setXYZW: function ( index, x, y, z, w ) {
08774
08775 index *= this.itemSize;
08776
08777 this.array[ index + 0 ] = x;
08778 this.array[ index + 1 ] = y;
08779 this.array[ index + 2 ] = z;
08780 this.array[ index + 3 ] = w;
08781
08782 return this;
08783
08784 },
08785
08786 clone: function () {
08787
08788 return new this.constructor().copy( this );
08789
08790 }
08791
08792 };
08793
08794
08795
08796 THREE.Int8Attribute = function ( array, itemSize ) {
08797
08798 return new THREE.BufferAttribute( new Int8Array( array ), itemSize );
08799
08800 };
08801
08802 THREE.Uint8Attribute = function ( array, itemSize ) {
08803
08804 return new THREE.BufferAttribute( new Uint8Array( array ), itemSize );
08805
08806 };
08807
08808 THREE.Uint8ClampedAttribute = function ( array, itemSize ) {
08809
08810 return new THREE.BufferAttribute( new Uint8ClampedArray( array ), itemSize );
08811
08812 };
08813
08814 THREE.Int16Attribute = function ( array, itemSize ) {
08815
08816 return new THREE.BufferAttribute( new Int16Array( array ), itemSize );
08817
08818 };
08819
08820 THREE.Uint16Attribute = function ( array, itemSize ) {
08821
08822 return new THREE.BufferAttribute( new Uint16Array( array ), itemSize );
08823
08824 };
08825
08826 THREE.Int32Attribute = function ( array, itemSize ) {
08827
08828 return new THREE.BufferAttribute( new Int32Array( array ), itemSize );
08829
08830 };
08831
08832 THREE.Uint32Attribute = function ( array, itemSize ) {
08833
08834 return new THREE.BufferAttribute( new Uint32Array( array ), itemSize );
08835
08836 };
08837
08838 THREE.Float32Attribute = function ( array, itemSize ) {
08839
08840 return new THREE.BufferAttribute( new Float32Array( array ), itemSize );
08841
08842 };
08843
08844 THREE.Float64Attribute = function ( array, itemSize ) {
08845
08846 return new THREE.BufferAttribute( new Float64Array( array ), itemSize );
08847
08848 };
08849
08850
08851
08852
08853 THREE.DynamicBufferAttribute = function ( array, itemSize ) {
08854
08855 console.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );
08856 return new THREE.BufferAttribute( array, itemSize ).setDynamic( true );
08857
08858 };
08859
08860
08861
08866 THREE.InstancedBufferAttribute = function ( array, itemSize, meshPerAttribute ) {
08867
08868 THREE.BufferAttribute.call( this, array, itemSize );
08869
08870 this.meshPerAttribute = meshPerAttribute || 1;
08871
08872 };
08873
08874 THREE.InstancedBufferAttribute.prototype = Object.create( THREE.BufferAttribute.prototype );
08875 THREE.InstancedBufferAttribute.prototype.constructor = THREE.InstancedBufferAttribute;
08876
08877 THREE.InstancedBufferAttribute.prototype.copy = function ( source ) {
08878
08879 THREE.BufferAttribute.prototype.copy.call( this, source );
08880
08881 this.meshPerAttribute = source.meshPerAttribute;
08882
08883 return this;
08884
08885 };
08886
08887
08888
08893 THREE.InterleavedBuffer = function ( array, stride ) {
08894
08895 this.uuid = THREE.Math.generateUUID();
08896
08897 this.array = array;
08898 this.stride = stride;
08899
08900 this.dynamic = false;
08901 this.updateRange = { offset: 0, count: - 1 };
08902
08903 this.version = 0;
08904
08905 };
08906
08907 THREE.InterleavedBuffer.prototype = {
08908
08909 constructor: THREE.InterleavedBuffer,
08910
08911 get length () {
08912
08913 return this.array.length;
08914
08915 },
08916
08917 get count () {
08918
08919 return this.array.length / this.stride;
08920
08921 },
08922
08923 set needsUpdate( value ) {
08924
08925 if ( value === true ) this.version ++;
08926
08927 },
08928
08929 setDynamic: function ( value ) {
08930
08931 this.dynamic = value;
08932
08933 return this;
08934
08935 },
08936
08937 copy: function ( source ) {
08938
08939 this.array = new source.array.constructor( source.array );
08940 this.stride = source.stride;
08941 this.dynamic = source.dynamic;
08942
08943 },
08944
08945 copyAt: function ( index1, attribute, index2 ) {
08946
08947 index1 *= this.stride;
08948 index2 *= attribute.stride;
08949
08950 for ( var i = 0, l = this.stride; i < l; i ++ ) {
08951
08952 this.array[ index1 + i ] = attribute.array[ index2 + i ];
08953
08954 }
08955
08956 return this;
08957
08958 },
08959
08960 set: function ( value, offset ) {
08961
08962 if ( offset === undefined ) offset = 0;
08963
08964 this.array.set( value, offset );
08965
08966 return this;
08967
08968 },
08969
08970 clone: function () {
08971
08972 return new this.constructor().copy( this );
08973
08974 }
08975
08976 };
08977
08978
08979
08984 THREE.InstancedInterleavedBuffer = function ( array, stride, meshPerAttribute ) {
08985
08986 THREE.InterleavedBuffer.call( this, array, stride );
08987
08988 this.meshPerAttribute = meshPerAttribute || 1;
08989
08990 };
08991
08992 THREE.InstancedInterleavedBuffer.prototype = Object.create( THREE.InterleavedBuffer.prototype );
08993 THREE.InstancedInterleavedBuffer.prototype.constructor = THREE.InstancedInterleavedBuffer;
08994
08995 THREE.InstancedInterleavedBuffer.prototype.copy = function ( source ) {
08996
08997 THREE.InterleavedBuffer.prototype.copy.call( this, source );
08998
08999 this.meshPerAttribute = source.meshPerAttribute;
09000
09001 return this;
09002
09003 };
09004
09005
09006
09011 THREE.InterleavedBufferAttribute = function ( interleavedBuffer, itemSize, offset ) {
09012
09013 this.uuid = THREE.Math.generateUUID();
09014
09015 this.data = interleavedBuffer;
09016 this.itemSize = itemSize;
09017 this.offset = offset;
09018
09019 };
09020
09021
09022 THREE.InterleavedBufferAttribute.prototype = {
09023
09024 constructor: THREE.InterleavedBufferAttribute,
09025
09026 get length() {
09027
09028 console.warn( 'THREE.BufferAttribute: .length has been deprecated. Please use .count.' );
09029 return this.array.length;
09030
09031 },
09032
09033 get count() {
09034
09035 return this.data.array.length / this.data.stride;
09036
09037 },
09038
09039 setX: function ( index, x ) {
09040
09041 this.data.array[ index * this.data.stride + this.offset ] = x;
09042
09043 return this;
09044
09045 },
09046
09047 setY: function ( index, y ) {
09048
09049 this.data.array[ index * this.data.stride + this.offset + 1 ] = y;
09050
09051 return this;
09052
09053 },
09054
09055 setZ: function ( index, z ) {
09056
09057 this.data.array[ index * this.data.stride + this.offset + 2 ] = z;
09058
09059 return this;
09060
09061 },
09062
09063 setW: function ( index, w ) {
09064
09065 this.data.array[ index * this.data.stride + this.offset + 3 ] = w;
09066
09067 return this;
09068
09069 },
09070
09071 getX: function ( index ) {
09072
09073 return this.data.array[ index * this.data.stride + this.offset ];
09074
09075 },
09076
09077 getY: function ( index ) {
09078
09079 return this.data.array[ index * this.data.stride + this.offset + 1 ];
09080
09081 },
09082
09083 getZ: function ( index ) {
09084
09085 return this.data.array[ index * this.data.stride + this.offset + 2 ];
09086
09087 },
09088
09089 getW: function ( index ) {
09090
09091 return this.data.array[ index * this.data.stride + this.offset + 3 ];
09092
09093 },
09094
09095 setXY: function ( index, x, y ) {
09096
09097 index = index * this.data.stride + this.offset;
09098
09099 this.data.array[ index + 0 ] = x;
09100 this.data.array[ index + 1 ] = y;
09101
09102 return this;
09103
09104 },
09105
09106 setXYZ: function ( index, x, y, z ) {
09107
09108 index = index * this.data.stride + this.offset;
09109
09110 this.data.array[ index + 0 ] = x;
09111 this.data.array[ index + 1 ] = y;
09112 this.data.array[ index + 2 ] = z;
09113
09114 return this;
09115
09116 },
09117
09118 setXYZW: function ( index, x, y, z, w ) {
09119
09120 index = index * this.data.stride + this.offset;
09121
09122 this.data.array[ index + 0 ] = x;
09123 this.data.array[ index + 1 ] = y;
09124 this.data.array[ index + 2 ] = z;
09125 this.data.array[ index + 3 ] = w;
09126
09127 return this;
09128
09129 }
09130
09131 };
09132
09133
09134
09144 THREE.Geometry = function () {
09145
09146 Object.defineProperty( this, 'id', { value: THREE.GeometryIdCount ++ } );
09147
09148 this.uuid = THREE.Math.generateUUID();
09149
09150 this.name = '';
09151 this.type = 'Geometry';
09152
09153 this.vertices = [];
09154 this.colors = [];
09155 this.faces = [];
09156 this.faceVertexUvs = [ [] ];
09157
09158 this.morphTargets = [];
09159 this.morphNormals = [];
09160
09161 this.skinWeights = [];
09162 this.skinIndices = [];
09163
09164 this.lineDistances = [];
09165
09166 this.boundingBox = null;
09167 this.boundingSphere = null;
09168
09169
09170
09171 this.verticesNeedUpdate = false;
09172 this.elementsNeedUpdate = false;
09173 this.uvsNeedUpdate = false;
09174 this.normalsNeedUpdate = false;
09175 this.colorsNeedUpdate = false;
09176 this.lineDistancesNeedUpdate = false;
09177 this.groupsNeedUpdate = false;
09178
09179 };
09180
09181 THREE.Geometry.prototype = {
09182
09183 constructor: THREE.Geometry,
09184
09185 applyMatrix: function ( matrix ) {
09186
09187 var normalMatrix = new THREE.Matrix3().getNormalMatrix( matrix );
09188
09189 for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
09190
09191 var vertex = this.vertices[ i ];
09192 vertex.applyMatrix4( matrix );
09193
09194 }
09195
09196 for ( var i = 0, il = this.faces.length; i < il; i ++ ) {
09197
09198 var face = this.faces[ i ];
09199 face.normal.applyMatrix3( normalMatrix ).normalize();
09200
09201 for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
09202
09203 face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();
09204
09205 }
09206
09207 }
09208
09209 if ( this.boundingBox !== null ) {
09210
09211 this.computeBoundingBox();
09212
09213 }
09214
09215 if ( this.boundingSphere !== null ) {
09216
09217 this.computeBoundingSphere();
09218
09219 }
09220
09221 this.verticesNeedUpdate = true;
09222 this.normalsNeedUpdate = true;
09223
09224 },
09225
09226 rotateX: function () {
09227
09228
09229
09230 var m1;
09231
09232 return function rotateX( angle ) {
09233
09234 if ( m1 === undefined ) m1 = new THREE.Matrix4();
09235
09236 m1.makeRotationX( angle );
09237
09238 this.applyMatrix( m1 );
09239
09240 return this;
09241
09242 };
09243
09244 }(),
09245
09246 rotateY: function () {
09247
09248
09249
09250 var m1;
09251
09252 return function rotateY( angle ) {
09253
09254 if ( m1 === undefined ) m1 = new THREE.Matrix4();
09255
09256 m1.makeRotationY( angle );
09257
09258 this.applyMatrix( m1 );
09259
09260 return this;
09261
09262 };
09263
09264 }(),
09265
09266 rotateZ: function () {
09267
09268
09269
09270 var m1;
09271
09272 return function rotateZ( angle ) {
09273
09274 if ( m1 === undefined ) m1 = new THREE.Matrix4();
09275
09276 m1.makeRotationZ( angle );
09277
09278 this.applyMatrix( m1 );
09279
09280 return this;
09281
09282 };
09283
09284 }(),
09285
09286 translate: function () {
09287
09288
09289
09290 var m1;
09291
09292 return function translate( x, y, z ) {
09293
09294 if ( m1 === undefined ) m1 = new THREE.Matrix4();
09295
09296 m1.makeTranslation( x, y, z );
09297
09298 this.applyMatrix( m1 );
09299
09300 return this;
09301
09302 };
09303
09304 }(),
09305
09306 scale: function () {
09307
09308
09309
09310 var m1;
09311
09312 return function scale( x, y, z ) {
09313
09314 if ( m1 === undefined ) m1 = new THREE.Matrix4();
09315
09316 m1.makeScale( x, y, z );
09317
09318 this.applyMatrix( m1 );
09319
09320 return this;
09321
09322 };
09323
09324 }(),
09325
09326 lookAt: function () {
09327
09328 var obj;
09329
09330 return function lookAt( vector ) {
09331
09332 if ( obj === undefined ) obj = new THREE.Object3D();
09333
09334 obj.lookAt( vector );
09335
09336 obj.updateMatrix();
09337
09338 this.applyMatrix( obj.matrix );
09339
09340 };
09341
09342 }(),
09343
09344 fromBufferGeometry: function ( geometry ) {
09345
09346 var scope = this;
09347
09348 var indices = geometry.index !== null ? geometry.index.array : undefined;
09349 var attributes = geometry.attributes;
09350
09351 var vertices = attributes.position.array;
09352 var normals = attributes.normal !== undefined ? attributes.normal.array : undefined;
09353 var colors = attributes.color !== undefined ? attributes.color.array : undefined;
09354 var uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;
09355 var uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;
09356
09357 if ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];
09358
09359 var tempNormals = [];
09360 var tempUVs = [];
09361 var tempUVs2 = [];
09362
09363 for ( var i = 0, j = 0, k = 0; i < vertices.length; i += 3, j += 2, k += 4 ) {
09364
09365 scope.vertices.push( new THREE.Vector3( vertices[ i ], vertices[ i + 1 ], vertices[ i + 2 ] ) );
09366
09367 if ( normals !== undefined ) {
09368
09369 tempNormals.push( new THREE.Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );
09370
09371 }
09372
09373 if ( colors !== undefined ) {
09374
09375 scope.colors.push( new THREE.Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );
09376
09377 }
09378
09379 if ( uvs !== undefined ) {
09380
09381 tempUVs.push( new THREE.Vector2( uvs[ j ], uvs[ j + 1 ] ) );
09382
09383 }
09384
09385 if ( uvs2 !== undefined ) {
09386
09387 tempUVs2.push( new THREE.Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );
09388
09389 }
09390
09391 }
09392
09393 function addFace( a, b, c ) {
09394
09395 var vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];
09396 var vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];
09397
09398 var face = new THREE.Face3( a, b, c, vertexNormals, vertexColors );
09399
09400 scope.faces.push( face );
09401
09402 if ( uvs !== undefined ) {
09403
09404 scope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );
09405
09406 }
09407
09408 if ( uvs2 !== undefined ) {
09409
09410 scope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );
09411
09412 }
09413
09414 };
09415
09416 if ( indices !== undefined ) {
09417
09418 var groups = geometry.groups;
09419
09420 if ( groups.length > 0 ) {
09421
09422 for ( var i = 0; i < groups.length; i ++ ) {
09423
09424 var group = groups[ i ];
09425
09426 var start = group.start;
09427 var count = group.count;
09428
09429 for ( var j = start, jl = start + count; j < jl; j += 3 ) {
09430
09431 addFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ] );
09432
09433 }
09434
09435 }
09436
09437 } else {
09438
09439 for ( var i = 0; i < indices.length; i += 3 ) {
09440
09441 addFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );
09442
09443 }
09444
09445 }
09446
09447 } else {
09448
09449 for ( var i = 0; i < vertices.length / 3; i += 3 ) {
09450
09451 addFace( i, i + 1, i + 2 );
09452
09453 }
09454
09455 }
09456
09457 this.computeFaceNormals();
09458
09459 if ( geometry.boundingBox !== null ) {
09460
09461 this.boundingBox = geometry.boundingBox.clone();
09462
09463 }
09464
09465 if ( geometry.boundingSphere !== null ) {
09466
09467 this.boundingSphere = geometry.boundingSphere.clone();
09468
09469 }
09470
09471 return this;
09472
09473 },
09474
09475 center: function () {
09476
09477 this.computeBoundingBox();
09478
09479 var offset = this.boundingBox.center().negate();
09480
09481 this.translate( offset.x, offset.y, offset.z );
09482
09483 return offset;
09484
09485 },
09486
09487 normalize: function () {
09488
09489 this.computeBoundingSphere();
09490
09491 var center = this.boundingSphere.center;
09492 var radius = this.boundingSphere.radius;
09493
09494 var s = radius === 0 ? 1 : 1.0 / radius;
09495
09496 var matrix = new THREE.Matrix4();
09497 matrix.set(
09498 s, 0, 0, - s * center.x,
09499 0, s, 0, - s * center.y,
09500 0, 0, s, - s * center.z,
09501 0, 0, 0, 1
09502 );
09503
09504 this.applyMatrix( matrix );
09505
09506 return this;
09507
09508 },
09509
09510 computeFaceNormals: function () {
09511
09512 var cb = new THREE.Vector3(), ab = new THREE.Vector3();
09513
09514 for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {
09515
09516 var face = this.faces[ f ];
09517
09518 var vA = this.vertices[ face.a ];
09519 var vB = this.vertices[ face.b ];
09520 var vC = this.vertices[ face.c ];
09521
09522 cb.subVectors( vC, vB );
09523 ab.subVectors( vA, vB );
09524 cb.cross( ab );
09525
09526 cb.normalize();
09527
09528 face.normal.copy( cb );
09529
09530 }
09531
09532 },
09533
09534 computeVertexNormals: function ( areaWeighted ) {
09535
09536 var v, vl, f, fl, face, vertices;
09537
09538 vertices = new Array( this.vertices.length );
09539
09540 for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
09541
09542 vertices[ v ] = new THREE.Vector3();
09543
09544 }
09545
09546 if ( areaWeighted ) {
09547
09548
09549
09550
09551 var vA, vB, vC;
09552 var cb = new THREE.Vector3(), ab = new THREE.Vector3();
09553
09554 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
09555
09556 face = this.faces[ f ];
09557
09558 vA = this.vertices[ face.a ];
09559 vB = this.vertices[ face.b ];
09560 vC = this.vertices[ face.c ];
09561
09562 cb.subVectors( vC, vB );
09563 ab.subVectors( vA, vB );
09564 cb.cross( ab );
09565
09566 vertices[ face.a ].add( cb );
09567 vertices[ face.b ].add( cb );
09568 vertices[ face.c ].add( cb );
09569
09570 }
09571
09572 } else {
09573
09574 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
09575
09576 face = this.faces[ f ];
09577
09578 vertices[ face.a ].add( face.normal );
09579 vertices[ face.b ].add( face.normal );
09580 vertices[ face.c ].add( face.normal );
09581
09582 }
09583
09584 }
09585
09586 for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
09587
09588 vertices[ v ].normalize();
09589
09590 }
09591
09592 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
09593
09594 face = this.faces[ f ];
09595
09596 var vertexNormals = face.vertexNormals;
09597
09598 if ( vertexNormals.length === 3 ) {
09599
09600 vertexNormals[ 0 ].copy( vertices[ face.a ] );
09601 vertexNormals[ 1 ].copy( vertices[ face.b ] );
09602 vertexNormals[ 2 ].copy( vertices[ face.c ] );
09603
09604 } else {
09605
09606 vertexNormals[ 0 ] = vertices[ face.a ].clone();
09607 vertexNormals[ 1 ] = vertices[ face.b ].clone();
09608 vertexNormals[ 2 ] = vertices[ face.c ].clone();
09609
09610 }
09611
09612 }
09613
09614 },
09615
09616 computeMorphNormals: function () {
09617
09618 var i, il, f, fl, face;
09619
09620
09621
09622
09623
09624 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
09625
09626 face = this.faces[ f ];
09627
09628 if ( ! face.__originalFaceNormal ) {
09629
09630 face.__originalFaceNormal = face.normal.clone();
09631
09632 } else {
09633
09634 face.__originalFaceNormal.copy( face.normal );
09635
09636 }
09637
09638 if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];
09639
09640 for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {
09641
09642 if ( ! face.__originalVertexNormals[ i ] ) {
09643
09644 face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();
09645
09646 } else {
09647
09648 face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );
09649
09650 }
09651
09652 }
09653
09654 }
09655
09656
09657
09658 var tmpGeo = new THREE.Geometry();
09659 tmpGeo.faces = this.faces;
09660
09661 for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {
09662
09663
09664
09665 if ( ! this.morphNormals[ i ] ) {
09666
09667 this.morphNormals[ i ] = {};
09668 this.morphNormals[ i ].faceNormals = [];
09669 this.morphNormals[ i ].vertexNormals = [];
09670
09671 var dstNormalsFace = this.morphNormals[ i ].faceNormals;
09672 var dstNormalsVertex = this.morphNormals[ i ].vertexNormals;
09673
09674 var faceNormal, vertexNormals;
09675
09676 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
09677
09678 faceNormal = new THREE.Vector3();
09679 vertexNormals = { a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3() };
09680
09681 dstNormalsFace.push( faceNormal );
09682 dstNormalsVertex.push( vertexNormals );
09683
09684 }
09685
09686 }
09687
09688 var morphNormals = this.morphNormals[ i ];
09689
09690
09691
09692 tmpGeo.vertices = this.morphTargets[ i ].vertices;
09693
09694
09695
09696 tmpGeo.computeFaceNormals();
09697 tmpGeo.computeVertexNormals();
09698
09699
09700
09701 var faceNormal, vertexNormals;
09702
09703 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
09704
09705 face = this.faces[ f ];
09706
09707 faceNormal = morphNormals.faceNormals[ f ];
09708 vertexNormals = morphNormals.vertexNormals[ f ];
09709
09710 faceNormal.copy( face.normal );
09711
09712 vertexNormals.a.copy( face.vertexNormals[ 0 ] );
09713 vertexNormals.b.copy( face.vertexNormals[ 1 ] );
09714 vertexNormals.c.copy( face.vertexNormals[ 2 ] );
09715
09716 }
09717
09718 }
09719
09720
09721
09722 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
09723
09724 face = this.faces[ f ];
09725
09726 face.normal = face.__originalFaceNormal;
09727 face.vertexNormals = face.__originalVertexNormals;
09728
09729 }
09730
09731 },
09732
09733 computeTangents: function () {
09734
09735 console.warn( 'THREE.Geometry: .computeTangents() has been removed.' );
09736
09737 },
09738
09739 computeLineDistances: function () {
09740
09741 var d = 0;
09742 var vertices = this.vertices;
09743
09744 for ( var i = 0, il = vertices.length; i < il; i ++ ) {
09745
09746 if ( i > 0 ) {
09747
09748 d += vertices[ i ].distanceTo( vertices[ i - 1 ] );
09749
09750 }
09751
09752 this.lineDistances[ i ] = d;
09753
09754 }
09755
09756 },
09757
09758 computeBoundingBox: function () {
09759
09760 if ( this.boundingBox === null ) {
09761
09762 this.boundingBox = new THREE.Box3();
09763
09764 }
09765
09766 this.boundingBox.setFromPoints( this.vertices );
09767
09768 },
09769
09770 computeBoundingSphere: function () {
09771
09772 if ( this.boundingSphere === null ) {
09773
09774 this.boundingSphere = new THREE.Sphere();
09775
09776 }
09777
09778 this.boundingSphere.setFromPoints( this.vertices );
09779
09780 },
09781
09782 merge: function ( geometry, matrix, materialIndexOffset ) {
09783
09784 if ( geometry instanceof THREE.Geometry === false ) {
09785
09786 console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );
09787 return;
09788
09789 }
09790
09791 var normalMatrix,
09792 vertexOffset = this.vertices.length,
09793 vertices1 = this.vertices,
09794 vertices2 = geometry.vertices,
09795 faces1 = this.faces,
09796 faces2 = geometry.faces,
09797 uvs1 = this.faceVertexUvs[ 0 ],
09798 uvs2 = geometry.faceVertexUvs[ 0 ];
09799
09800 if ( materialIndexOffset === undefined ) materialIndexOffset = 0;
09801
09802 if ( matrix !== undefined ) {
09803
09804 normalMatrix = new THREE.Matrix3().getNormalMatrix( matrix );
09805
09806 }
09807
09808
09809
09810 for ( var i = 0, il = vertices2.length; i < il; i ++ ) {
09811
09812 var vertex = vertices2[ i ];
09813
09814 var vertexCopy = vertex.clone();
09815
09816 if ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );
09817
09818 vertices1.push( vertexCopy );
09819
09820 }
09821
09822
09823
09824 for ( i = 0, il = faces2.length; i < il; i ++ ) {
09825
09826 var face = faces2[ i ], faceCopy, normal, color,
09827 faceVertexNormals = face.vertexNormals,
09828 faceVertexColors = face.vertexColors;
09829
09830 faceCopy = new THREE.Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );
09831 faceCopy.normal.copy( face.normal );
09832
09833 if ( normalMatrix !== undefined ) {
09834
09835 faceCopy.normal.applyMatrix3( normalMatrix ).normalize();
09836
09837 }
09838
09839 for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {
09840
09841 normal = faceVertexNormals[ j ].clone();
09842
09843 if ( normalMatrix !== undefined ) {
09844
09845 normal.applyMatrix3( normalMatrix ).normalize();
09846
09847 }
09848
09849 faceCopy.vertexNormals.push( normal );
09850
09851 }
09852
09853 faceCopy.color.copy( face.color );
09854
09855 for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {
09856
09857 color = faceVertexColors[ j ];
09858 faceCopy.vertexColors.push( color.clone() );
09859
09860 }
09861
09862 faceCopy.materialIndex = face.materialIndex + materialIndexOffset;
09863
09864 faces1.push( faceCopy );
09865
09866 }
09867
09868
09869
09870 for ( i = 0, il = uvs2.length; i < il; i ++ ) {
09871
09872 var uv = uvs2[ i ], uvCopy = [];
09873
09874 if ( uv === undefined ) {
09875
09876 continue;
09877
09878 }
09879
09880 for ( var j = 0, jl = uv.length; j < jl; j ++ ) {
09881
09882 uvCopy.push( uv[ j ].clone() );
09883
09884 }
09885
09886 uvs1.push( uvCopy );
09887
09888 }
09889
09890 },
09891
09892 mergeMesh: function ( mesh ) {
09893
09894 if ( mesh instanceof THREE.Mesh === false ) {
09895
09896 console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );
09897 return;
09898
09899 }
09900
09901 mesh.matrixAutoUpdate && mesh.updateMatrix();
09902
09903 this.merge( mesh.geometry, mesh.matrix );
09904
09905 },
09906
09907
09908
09909
09910
09911
09912
09913 mergeVertices: function () {
09914
09915 var verticesMap = {};
09916 var unique = [], changes = [];
09917
09918 var v, key;
09919 var precisionPoints = 4;
09920 var precision = Math.pow( 10, precisionPoints );
09921 var i, il, face;
09922 var indices, j, jl;
09923
09924 for ( i = 0, il = this.vertices.length; i < il; i ++ ) {
09925
09926 v = this.vertices[ i ];
09927 key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );
09928
09929 if ( verticesMap[ key ] === undefined ) {
09930
09931 verticesMap[ key ] = i;
09932 unique.push( this.vertices[ i ] );
09933 changes[ i ] = unique.length - 1;
09934
09935 } else {
09936
09937
09938 changes[ i ] = changes[ verticesMap[ key ] ];
09939
09940 }
09941
09942 }
09943
09944
09945
09946
09947 var faceIndicesToRemove = [];
09948
09949 for ( i = 0, il = this.faces.length; i < il; i ++ ) {
09950
09951 face = this.faces[ i ];
09952
09953 face.a = changes[ face.a ];
09954 face.b = changes[ face.b ];
09955 face.c = changes[ face.c ];
09956
09957 indices = [ face.a, face.b, face.c ];
09958
09959 var dupIndex = - 1;
09960
09961
09962
09963 for ( var n = 0; n < 3; n ++ ) {
09964
09965 if ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {
09966
09967 dupIndex = n;
09968 faceIndicesToRemove.push( i );
09969 break;
09970
09971 }
09972
09973 }
09974
09975 }
09976
09977 for ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {
09978
09979 var idx = faceIndicesToRemove[ i ];
09980
09981 this.faces.splice( idx, 1 );
09982
09983 for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
09984
09985 this.faceVertexUvs[ j ].splice( idx, 1 );
09986
09987 }
09988
09989 }
09990
09991
09992
09993 var diff = this.vertices.length - unique.length;
09994 this.vertices = unique;
09995 return diff;
09996
09997 },
09998
09999 sortFacesByMaterialIndex: function () {
10000
10001 var faces = this.faces;
10002 var length = faces.length;
10003
10004
10005
10006 for ( var i = 0; i < length; i ++ ) {
10007
10008 faces[ i ]._id = i;
10009
10010 }
10011
10012
10013
10014 function materialIndexSort( a, b ) {
10015
10016 return a.materialIndex - b.materialIndex;
10017
10018 }
10019
10020 faces.sort( materialIndexSort );
10021
10022
10023
10024 var uvs1 = this.faceVertexUvs[ 0 ];
10025 var uvs2 = this.faceVertexUvs[ 1 ];
10026
10027 var newUvs1, newUvs2;
10028
10029 if ( uvs1 && uvs1.length === length ) newUvs1 = [];
10030 if ( uvs2 && uvs2.length === length ) newUvs2 = [];
10031
10032 for ( var i = 0; i < length; i ++ ) {
10033
10034 var id = faces[ i ]._id;
10035
10036 if ( newUvs1 ) newUvs1.push( uvs1[ id ] );
10037 if ( newUvs2 ) newUvs2.push( uvs2[ id ] );
10038
10039 }
10040
10041 if ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;
10042 if ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;
10043
10044 },
10045
10046 toJSON: function () {
10047
10048 var data = {
10049 metadata: {
10050 version: 4.4,
10051 type: 'Geometry',
10052 generator: 'Geometry.toJSON'
10053 }
10054 };
10055
10056
10057
10058 data.uuid = this.uuid;
10059 data.type = this.type;
10060 if ( this.name !== '' ) data.name = this.name;
10061
10062 if ( this.parameters !== undefined ) {
10063
10064 var parameters = this.parameters;
10065
10066 for ( var key in parameters ) {
10067
10068 if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];
10069
10070 }
10071
10072 return data;
10073
10074 }
10075
10076 var vertices = [];
10077
10078 for ( var i = 0; i < this.vertices.length; i ++ ) {
10079
10080 var vertex = this.vertices[ i ];
10081 vertices.push( vertex.x, vertex.y, vertex.z );
10082
10083 }
10084
10085 var faces = [];
10086 var normals = [];
10087 var normalsHash = {};
10088 var colors = [];
10089 var colorsHash = {};
10090 var uvs = [];
10091 var uvsHash = {};
10092
10093 for ( var i = 0; i < this.faces.length; i ++ ) {
10094
10095 var face = this.faces[ i ];
10096
10097 var hasMaterial = false;
10098 var hasFaceUv = false;
10099 var hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;
10100 var hasFaceNormal = face.normal.length() > 0;
10101 var hasFaceVertexNormal = face.vertexNormals.length > 0;
10102 var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;
10103 var hasFaceVertexColor = face.vertexColors.length > 0;
10104
10105 var faceType = 0;
10106
10107 faceType = setBit( faceType, 0, 0 );
10108 faceType = setBit( faceType, 1, hasMaterial );
10109 faceType = setBit( faceType, 2, hasFaceUv );
10110 faceType = setBit( faceType, 3, hasFaceVertexUv );
10111 faceType = setBit( faceType, 4, hasFaceNormal );
10112 faceType = setBit( faceType, 5, hasFaceVertexNormal );
10113 faceType = setBit( faceType, 6, hasFaceColor );
10114 faceType = setBit( faceType, 7, hasFaceVertexColor );
10115
10116 faces.push( faceType );
10117 faces.push( face.a, face.b, face.c );
10118
10119 if ( hasFaceVertexUv ) {
10120
10121 var faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];
10122
10123 faces.push(
10124 getUvIndex( faceVertexUvs[ 0 ] ),
10125 getUvIndex( faceVertexUvs[ 1 ] ),
10126 getUvIndex( faceVertexUvs[ 2 ] )
10127 );
10128
10129 }
10130
10131 if ( hasFaceNormal ) {
10132
10133 faces.push( getNormalIndex( face.normal ) );
10134
10135 }
10136
10137 if ( hasFaceVertexNormal ) {
10138
10139 var vertexNormals = face.vertexNormals;
10140
10141 faces.push(
10142 getNormalIndex( vertexNormals[ 0 ] ),
10143 getNormalIndex( vertexNormals[ 1 ] ),
10144 getNormalIndex( vertexNormals[ 2 ] )
10145 );
10146
10147 }
10148
10149 if ( hasFaceColor ) {
10150
10151 faces.push( getColorIndex( face.color ) );
10152
10153 }
10154
10155 if ( hasFaceVertexColor ) {
10156
10157 var vertexColors = face.vertexColors;
10158
10159 faces.push(
10160 getColorIndex( vertexColors[ 0 ] ),
10161 getColorIndex( vertexColors[ 1 ] ),
10162 getColorIndex( vertexColors[ 2 ] )
10163 );
10164
10165 }
10166
10167 }
10168
10169 function setBit( value, position, enabled ) {
10170
10171 return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );
10172
10173 }
10174
10175 function getNormalIndex( normal ) {
10176
10177 var hash = normal.x.toString() + normal.y.toString() + normal.z.toString();
10178
10179 if ( normalsHash[ hash ] !== undefined ) {
10180
10181 return normalsHash[ hash ];
10182
10183 }
10184
10185 normalsHash[ hash ] = normals.length / 3;
10186 normals.push( normal.x, normal.y, normal.z );
10187
10188 return normalsHash[ hash ];
10189
10190 }
10191
10192 function getColorIndex( color ) {
10193
10194 var hash = color.r.toString() + color.g.toString() + color.b.toString();
10195
10196 if ( colorsHash[ hash ] !== undefined ) {
10197
10198 return colorsHash[ hash ];
10199
10200 }
10201
10202 colorsHash[ hash ] = colors.length;
10203 colors.push( color.getHex() );
10204
10205 return colorsHash[ hash ];
10206
10207 }
10208
10209 function getUvIndex( uv ) {
10210
10211 var hash = uv.x.toString() + uv.y.toString();
10212
10213 if ( uvsHash[ hash ] !== undefined ) {
10214
10215 return uvsHash[ hash ];
10216
10217 }
10218
10219 uvsHash[ hash ] = uvs.length / 2;
10220 uvs.push( uv.x, uv.y );
10221
10222 return uvsHash[ hash ];
10223
10224 }
10225
10226 data.data = {};
10227
10228 data.data.vertices = vertices;
10229 data.data.normals = normals;
10230 if ( colors.length > 0 ) data.data.colors = colors;
10231 if ( uvs.length > 0 ) data.data.uvs = [ uvs ];
10232 data.data.faces = faces;
10233
10234 return data;
10235
10236 },
10237
10238 clone: function () {
10239
10240 return new this.constructor().copy( this );
10241
10242 },
10243
10244 copy: function ( source ) {
10245
10246 this.vertices = [];
10247 this.faces = [];
10248 this.faceVertexUvs = [ [] ];
10249
10250 var vertices = source.vertices;
10251
10252 for ( var i = 0, il = vertices.length; i < il; i ++ ) {
10253
10254 this.vertices.push( vertices[ i ].clone() );
10255
10256 }
10257
10258 var faces = source.faces;
10259
10260 for ( var i = 0, il = faces.length; i < il; i ++ ) {
10261
10262 this.faces.push( faces[ i ].clone() );
10263
10264 }
10265
10266 for ( var i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {
10267
10268 var faceVertexUvs = source.faceVertexUvs[ i ];
10269
10270 if ( this.faceVertexUvs[ i ] === undefined ) {
10271
10272 this.faceVertexUvs[ i ] = [];
10273
10274 }
10275
10276 for ( var j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {
10277
10278 var uvs = faceVertexUvs[ j ], uvsCopy = [];
10279
10280 for ( var k = 0, kl = uvs.length; k < kl; k ++ ) {
10281
10282 var uv = uvs[ k ];
10283
10284 uvsCopy.push( uv.clone() );
10285
10286 }
10287
10288 this.faceVertexUvs[ i ].push( uvsCopy );
10289
10290 }
10291
10292 }
10293
10294 return this;
10295
10296 },
10297
10298 dispose: function () {
10299
10300 this.dispatchEvent( { type: 'dispose' } );
10301
10302 }
10303
10304 };
10305
10306 THREE.EventDispatcher.prototype.apply( THREE.Geometry.prototype );
10307
10308 THREE.GeometryIdCount = 0;
10309
10310
10311
10316 THREE.DirectGeometry = function () {
10317
10318 Object.defineProperty( this, 'id', { value: THREE.GeometryIdCount ++ } );
10319
10320 this.uuid = THREE.Math.generateUUID();
10321
10322 this.name = '';
10323 this.type = 'DirectGeometry';
10324
10325 this.indices = [];
10326 this.vertices = [];
10327 this.normals = [];
10328 this.colors = [];
10329 this.uvs = [];
10330 this.uvs2 = [];
10331
10332 this.groups = [];
10333
10334 this.morphTargets = {};
10335
10336 this.skinWeights = [];
10337 this.skinIndices = [];
10338
10339
10340
10341 this.boundingBox = null;
10342 this.boundingSphere = null;
10343
10344
10345
10346 this.verticesNeedUpdate = false;
10347 this.normalsNeedUpdate = false;
10348 this.colorsNeedUpdate = false;
10349 this.uvsNeedUpdate = false;
10350 this.groupsNeedUpdate = false;
10351
10352 };
10353
10354 THREE.DirectGeometry.prototype = {
10355
10356 constructor: THREE.DirectGeometry,
10357
10358 computeBoundingBox: THREE.Geometry.prototype.computeBoundingBox,
10359 computeBoundingSphere: THREE.Geometry.prototype.computeBoundingSphere,
10360
10361 computeFaceNormals: function () {
10362
10363 console.warn( 'THREE.DirectGeometry: computeFaceNormals() is not a method of this type of geometry.' );
10364
10365 },
10366
10367 computeVertexNormals: function () {
10368
10369 console.warn( 'THREE.DirectGeometry: computeVertexNormals() is not a method of this type of geometry.' );
10370
10371 },
10372
10373 computeGroups: function ( geometry ) {
10374
10375 var group;
10376 var groups = [];
10377 var materialIndex;
10378
10379 var faces = geometry.faces;
10380
10381 for ( var i = 0; i < faces.length; i ++ ) {
10382
10383 var face = faces[ i ];
10384
10385
10386
10387 if ( face.materialIndex !== materialIndex ) {
10388
10389 materialIndex = face.materialIndex;
10390
10391 if ( group !== undefined ) {
10392
10393 group.count = ( i * 3 ) - group.start;
10394 groups.push( group );
10395
10396 }
10397
10398 group = {
10399 start: i * 3,
10400 materialIndex: materialIndex
10401 };
10402
10403 }
10404
10405 }
10406
10407 if ( group !== undefined ) {
10408
10409 group.count = ( i * 3 ) - group.start;
10410 groups.push( group );
10411
10412 }
10413
10414 this.groups = groups;
10415
10416 },
10417
10418 fromGeometry: function ( geometry ) {
10419
10420 var faces = geometry.faces;
10421 var vertices = geometry.vertices;
10422 var faceVertexUvs = geometry.faceVertexUvs;
10423
10424 var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;
10425 var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;
10426
10427
10428
10429 var morphTargets = geometry.morphTargets;
10430 var morphTargetsLength = morphTargets.length;
10431
10432 if ( morphTargetsLength > 0 ) {
10433
10434 var morphTargetsPosition = [];
10435
10436 for ( var i = 0; i < morphTargetsLength; i ++ ) {
10437
10438 morphTargetsPosition[ i ] = [];
10439
10440 }
10441
10442 this.morphTargets.position = morphTargetsPosition;
10443
10444 }
10445
10446 var morphNormals = geometry.morphNormals;
10447 var morphNormalsLength = morphNormals.length;
10448
10449 if ( morphNormalsLength > 0 ) {
10450
10451 var morphTargetsNormal = [];
10452
10453 for ( var i = 0; i < morphNormalsLength; i ++ ) {
10454
10455 morphTargetsNormal[ i ] = [];
10456
10457 }
10458
10459 this.morphTargets.normal = morphTargetsNormal;
10460
10461 }
10462
10463
10464
10465 var skinIndices = geometry.skinIndices;
10466 var skinWeights = geometry.skinWeights;
10467
10468 var hasSkinIndices = skinIndices.length === vertices.length;
10469 var hasSkinWeights = skinWeights.length === vertices.length;
10470
10471
10472
10473 for ( var i = 0; i < faces.length; i ++ ) {
10474
10475 var face = faces[ i ];
10476
10477 this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );
10478
10479 var vertexNormals = face.vertexNormals;
10480
10481 if ( vertexNormals.length === 3 ) {
10482
10483 this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );
10484
10485 } else {
10486
10487 var normal = face.normal;
10488
10489 this.normals.push( normal, normal, normal );
10490
10491 }
10492
10493 var vertexColors = face.vertexColors;
10494
10495 if ( vertexColors.length === 3 ) {
10496
10497 this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );
10498
10499 } else {
10500
10501 var color = face.color;
10502
10503 this.colors.push( color, color, color );
10504
10505 }
10506
10507 if ( hasFaceVertexUv === true ) {
10508
10509 var vertexUvs = faceVertexUvs[ 0 ][ i ];
10510
10511 if ( vertexUvs !== undefined ) {
10512
10513 this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
10514
10515 } else {
10516
10517 console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );
10518
10519 this.uvs.push( new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2() );
10520
10521 }
10522
10523 }
10524
10525 if ( hasFaceVertexUv2 === true ) {
10526
10527 var vertexUvs = faceVertexUvs[ 1 ][ i ];
10528
10529 if ( vertexUvs !== undefined ) {
10530
10531 this.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
10532
10533 } else {
10534
10535 console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );
10536
10537 this.uvs2.push( new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2() );
10538
10539 }
10540
10541 }
10542
10543
10544
10545 for ( var j = 0; j < morphTargetsLength; j ++ ) {
10546
10547 var morphTarget = morphTargets[ j ].vertices;
10548
10549 morphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );
10550
10551 }
10552
10553 for ( var j = 0; j < morphNormalsLength; j ++ ) {
10554
10555 var morphNormal = morphNormals[ j ].vertexNormals[ i ];
10556
10557 morphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );
10558
10559 }
10560
10561
10562
10563 if ( hasSkinIndices ) {
10564
10565 this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );
10566
10567 }
10568
10569 if ( hasSkinWeights ) {
10570
10571 this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );
10572
10573 }
10574
10575 }
10576
10577 this.computeGroups( geometry );
10578
10579 this.verticesNeedUpdate = geometry.verticesNeedUpdate;
10580 this.normalsNeedUpdate = geometry.normalsNeedUpdate;
10581 this.colorsNeedUpdate = geometry.colorsNeedUpdate;
10582 this.uvsNeedUpdate = geometry.uvsNeedUpdate;
10583 this.groupsNeedUpdate = geometry.groupsNeedUpdate;
10584
10585 return this;
10586
10587 },
10588
10589 dispose: function () {
10590
10591 this.dispatchEvent( { type: 'dispose' } );
10592
10593 }
10594
10595 };
10596
10597 THREE.EventDispatcher.prototype.apply( THREE.DirectGeometry.prototype );
10598
10599
10600
10606 THREE.BufferGeometry = function () {
10607
10608 Object.defineProperty( this, 'id', { value: THREE.GeometryIdCount ++ } );
10609
10610 this.uuid = THREE.Math.generateUUID();
10611
10612 this.name = '';
10613 this.type = 'BufferGeometry';
10614
10615 this.index = null;
10616 this.attributes = {};
10617
10618 this.morphAttributes = {};
10619
10620 this.groups = [];
10621
10622 this.boundingBox = null;
10623 this.boundingSphere = null;
10624
10625 this.drawRange = { start: 0, count: Infinity };
10626
10627 };
10628
10629 THREE.BufferGeometry.prototype = {
10630
10631 constructor: THREE.BufferGeometry,
10632
10633 addIndex: function ( index ) {
10634
10635 console.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );
10636 this.setIndex( index );
10637
10638 },
10639
10640 getIndex: function () {
10641
10642 return this.index;
10643
10644 },
10645
10646 setIndex: function ( index ) {
10647
10648 this.index = index;
10649
10650 },
10651
10652 addAttribute: function ( name, attribute ) {
10653
10654 if ( attribute instanceof THREE.BufferAttribute === false && attribute instanceof THREE.InterleavedBufferAttribute === false ) {
10655
10656 console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );
10657
10658 this.addAttribute( name, new THREE.BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );
10659
10660 return;
10661
10662 }
10663
10664 if ( name === 'index' ) {
10665
10666 console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );
10667 this.setIndex( attribute );
10668
10669 return;
10670
10671 }
10672
10673 this.attributes[ name ] = attribute;
10674
10675 },
10676
10677 getAttribute: function ( name ) {
10678
10679 return this.attributes[ name ];
10680
10681 },
10682
10683 removeAttribute: function ( name ) {
10684
10685 delete this.attributes[ name ];
10686
10687 },
10688
10689 get drawcalls() {
10690
10691 console.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );
10692 return this.groups;
10693
10694 },
10695
10696 get offsets() {
10697
10698 console.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );
10699 return this.groups;
10700
10701 },
10702
10703 addDrawCall: function ( start, count, indexOffset ) {
10704
10705 if ( indexOffset !== undefined ) {
10706
10707 console.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );
10708
10709 }
10710
10711 console.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );
10712 this.addGroup( start, count );
10713
10714 },
10715
10716 clearDrawCalls: function () {
10717
10718 console.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );
10719 this.clearGroups();
10720
10721 },
10722
10723 addGroup: function ( start, count, materialIndex ) {
10724
10725 this.groups.push( {
10726
10727 start: start,
10728 count: count,
10729 materialIndex: materialIndex !== undefined ? materialIndex : 0
10730
10731 } );
10732
10733 },
10734
10735 clearGroups: function () {
10736
10737 this.groups = [];
10738
10739 },
10740
10741 setDrawRange: function ( start, count ) {
10742
10743 this.drawRange.start = start;
10744 this.drawRange.count = count;
10745
10746 },
10747
10748 applyMatrix: function ( matrix ) {
10749
10750 var position = this.attributes.position;
10751
10752 if ( position !== undefined ) {
10753
10754 matrix.applyToVector3Array( position.array );
10755 position.needsUpdate = true;
10756
10757 }
10758
10759 var normal = this.attributes.normal;
10760
10761 if ( normal !== undefined ) {
10762
10763 var normalMatrix = new THREE.Matrix3().getNormalMatrix( matrix );
10764
10765 normalMatrix.applyToVector3Array( normal.array );
10766 normal.needsUpdate = true;
10767
10768 }
10769
10770 if ( this.boundingBox !== null ) {
10771
10772 this.computeBoundingBox();
10773
10774 }
10775
10776 if ( this.boundingSphere !== null ) {
10777
10778 this.computeBoundingSphere();
10779
10780 }
10781
10782 },
10783
10784 rotateX: function () {
10785
10786
10787
10788 var m1;
10789
10790 return function rotateX( angle ) {
10791
10792 if ( m1 === undefined ) m1 = new THREE.Matrix4();
10793
10794 m1.makeRotationX( angle );
10795
10796 this.applyMatrix( m1 );
10797
10798 return this;
10799
10800 };
10801
10802 }(),
10803
10804 rotateY: function () {
10805
10806
10807
10808 var m1;
10809
10810 return function rotateY( angle ) {
10811
10812 if ( m1 === undefined ) m1 = new THREE.Matrix4();
10813
10814 m1.makeRotationY( angle );
10815
10816 this.applyMatrix( m1 );
10817
10818 return this;
10819
10820 };
10821
10822 }(),
10823
10824 rotateZ: function () {
10825
10826
10827
10828 var m1;
10829
10830 return function rotateZ( angle ) {
10831
10832 if ( m1 === undefined ) m1 = new THREE.Matrix4();
10833
10834 m1.makeRotationZ( angle );
10835
10836 this.applyMatrix( m1 );
10837
10838 return this;
10839
10840 };
10841
10842 }(),
10843
10844 translate: function () {
10845
10846
10847
10848 var m1;
10849
10850 return function translate( x, y, z ) {
10851
10852 if ( m1 === undefined ) m1 = new THREE.Matrix4();
10853
10854 m1.makeTranslation( x, y, z );
10855
10856 this.applyMatrix( m1 );
10857
10858 return this;
10859
10860 };
10861
10862 }(),
10863
10864 scale: function () {
10865
10866
10867
10868 var m1;
10869
10870 return function scale( x, y, z ) {
10871
10872 if ( m1 === undefined ) m1 = new THREE.Matrix4();
10873
10874 m1.makeScale( x, y, z );
10875
10876 this.applyMatrix( m1 );
10877
10878 return this;
10879
10880 };
10881
10882 }(),
10883
10884 lookAt: function () {
10885
10886 var obj;
10887
10888 return function lookAt( vector ) {
10889
10890 if ( obj === undefined ) obj = new THREE.Object3D();
10891
10892 obj.lookAt( vector );
10893
10894 obj.updateMatrix();
10895
10896 this.applyMatrix( obj.matrix );
10897
10898 };
10899
10900 }(),
10901
10902 center: function () {
10903
10904 this.computeBoundingBox();
10905
10906 var offset = this.boundingBox.center().negate();
10907
10908 this.translate( offset.x, offset.y, offset.z );
10909
10910 return offset;
10911
10912 },
10913
10914 setFromObject: function ( object ) {
10915
10916
10917
10918 var geometry = object.geometry;
10919
10920 if ( object instanceof THREE.Points || object instanceof THREE.Line ) {
10921
10922 var positions = new THREE.Float32Attribute( geometry.vertices.length * 3, 3 );
10923 var colors = new THREE.Float32Attribute( geometry.colors.length * 3, 3 );
10924
10925 this.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );
10926 this.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );
10927
10928 if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {
10929
10930 var lineDistances = new THREE.Float32Attribute( geometry.lineDistances.length, 1 );
10931
10932 this.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );
10933
10934 }
10935
10936 if ( geometry.boundingSphere !== null ) {
10937
10938 this.boundingSphere = geometry.boundingSphere.clone();
10939
10940 }
10941
10942 if ( geometry.boundingBox !== null ) {
10943
10944 this.boundingBox = geometry.boundingBox.clone();
10945
10946 }
10947
10948 } else if ( object instanceof THREE.Mesh ) {
10949
10950 if ( geometry instanceof THREE.Geometry ) {
10951
10952 this.fromGeometry( geometry );
10953
10954 }
10955
10956 }
10957
10958 return this;
10959
10960 },
10961
10962 updateFromObject: function ( object ) {
10963
10964 var geometry = object.geometry;
10965
10966 if ( object instanceof THREE.Mesh ) {
10967
10968 var direct = geometry.__directGeometry;
10969
10970 if ( direct === undefined ) {
10971
10972 return this.fromGeometry( geometry );
10973
10974 }
10975
10976 direct.verticesNeedUpdate = geometry.verticesNeedUpdate;
10977 direct.normalsNeedUpdate = geometry.normalsNeedUpdate;
10978 direct.colorsNeedUpdate = geometry.colorsNeedUpdate;
10979 direct.uvsNeedUpdate = geometry.uvsNeedUpdate;
10980 direct.groupsNeedUpdate = geometry.groupsNeedUpdate;
10981
10982 geometry.verticesNeedUpdate = false;
10983 geometry.normalsNeedUpdate = false;
10984 geometry.colorsNeedUpdate = false;
10985 geometry.uvsNeedUpdate = false;
10986 geometry.groupsNeedUpdate = false;
10987
10988 geometry = direct;
10989
10990 }
10991
10992 if ( geometry.verticesNeedUpdate === true ) {
10993
10994 var attribute = this.attributes.position;
10995
10996 if ( attribute !== undefined ) {
10997
10998 attribute.copyVector3sArray( geometry.vertices );
10999 attribute.needsUpdate = true;
11000
11001 }
11002
11003 geometry.verticesNeedUpdate = false;
11004
11005 }
11006
11007 if ( geometry.normalsNeedUpdate === true ) {
11008
11009 var attribute = this.attributes.normal;
11010
11011 if ( attribute !== undefined ) {
11012
11013 attribute.copyVector3sArray( geometry.normals );
11014 attribute.needsUpdate = true;
11015
11016 }
11017
11018 geometry.normalsNeedUpdate = false;
11019
11020 }
11021
11022 if ( geometry.colorsNeedUpdate === true ) {
11023
11024 var attribute = this.attributes.color;
11025
11026 if ( attribute !== undefined ) {
11027
11028 attribute.copyColorsArray( geometry.colors );
11029 attribute.needsUpdate = true;
11030
11031 }
11032
11033 geometry.colorsNeedUpdate = false;
11034
11035 }
11036
11037 if ( geometry.uvsNeedUpdate ) {
11038
11039 var attribute = this.attributes.uv;
11040
11041 if ( attribute !== undefined ) {
11042
11043 attribute.copyVector2sArray( geometry.uvs );
11044 attribute.needsUpdate = true;
11045
11046 }
11047
11048 geometry.uvsNeedUpdate = false;
11049
11050 }
11051
11052 if ( geometry.lineDistancesNeedUpdate ) {
11053
11054 var attribute = this.attributes.lineDistance;
11055
11056 if ( attribute !== undefined ) {
11057
11058 attribute.copyArray( geometry.lineDistances );
11059 attribute.needsUpdate = true;
11060
11061 }
11062
11063 geometry.lineDistancesNeedUpdate = false;
11064
11065 }
11066
11067 if ( geometry.groupsNeedUpdate ) {
11068
11069 geometry.computeGroups( object.geometry );
11070 this.groups = geometry.groups;
11071
11072 geometry.groupsNeedUpdate = false;
11073
11074 }
11075
11076 return this;
11077
11078 },
11079
11080 fromGeometry: function ( geometry ) {
11081
11082 geometry.__directGeometry = new THREE.DirectGeometry().fromGeometry( geometry );
11083
11084 return this.fromDirectGeometry( geometry.__directGeometry );
11085
11086 },
11087
11088 fromDirectGeometry: function ( geometry ) {
11089
11090 var positions = new Float32Array( geometry.vertices.length * 3 );
11091 this.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );
11092
11093 if ( geometry.normals.length > 0 ) {
11094
11095 var normals = new Float32Array( geometry.normals.length * 3 );
11096 this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );
11097
11098 }
11099
11100 if ( geometry.colors.length > 0 ) {
11101
11102 var colors = new Float32Array( geometry.colors.length * 3 );
11103 this.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );
11104
11105 }
11106
11107 if ( geometry.uvs.length > 0 ) {
11108
11109 var uvs = new Float32Array( geometry.uvs.length * 2 );
11110 this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );
11111
11112 }
11113
11114 if ( geometry.uvs2.length > 0 ) {
11115
11116 var uvs2 = new Float32Array( geometry.uvs2.length * 2 );
11117 this.addAttribute( 'uv2', new THREE.BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );
11118
11119 }
11120
11121 if ( geometry.indices.length > 0 ) {
11122
11123 var TypeArray = geometry.vertices.length > 65535 ? Uint32Array : Uint16Array;
11124 var indices = new TypeArray( geometry.indices.length * 3 );
11125 this.setIndex( new THREE.BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );
11126
11127 }
11128
11129
11130
11131 this.groups = geometry.groups;
11132
11133
11134
11135 for ( var name in geometry.morphTargets ) {
11136
11137 var array = [];
11138 var morphTargets = geometry.morphTargets[ name ];
11139
11140 for ( var i = 0, l = morphTargets.length; i < l; i ++ ) {
11141
11142 var morphTarget = morphTargets[ i ];
11143
11144 var attribute = new THREE.Float32Attribute( morphTarget.length * 3, 3 );
11145
11146 array.push( attribute.copyVector3sArray( morphTarget ) );
11147
11148 }
11149
11150 this.morphAttributes[ name ] = array;
11151
11152 }
11153
11154
11155
11156 if ( geometry.skinIndices.length > 0 ) {
11157
11158 var skinIndices = new THREE.Float32Attribute( geometry.skinIndices.length * 4, 4 );
11159 this.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );
11160
11161 }
11162
11163 if ( geometry.skinWeights.length > 0 ) {
11164
11165 var skinWeights = new THREE.Float32Attribute( geometry.skinWeights.length * 4, 4 );
11166 this.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );
11167
11168 }
11169
11170
11171
11172 if ( geometry.boundingSphere !== null ) {
11173
11174 this.boundingSphere = geometry.boundingSphere.clone();
11175
11176 }
11177
11178 if ( geometry.boundingBox !== null ) {
11179
11180 this.boundingBox = geometry.boundingBox.clone();
11181
11182 }
11183
11184 return this;
11185
11186 },
11187
11188 computeBoundingBox: function () {
11189
11190 var vector = new THREE.Vector3();
11191
11192 return function () {
11193
11194 if ( this.boundingBox === null ) {
11195
11196 this.boundingBox = new THREE.Box3();
11197
11198 }
11199
11200 var positions = this.attributes.position.array;
11201
11202 if ( positions ) {
11203
11204 var bb = this.boundingBox;
11205 bb.makeEmpty();
11206
11207 for ( var i = 0, il = positions.length; i < il; i += 3 ) {
11208
11209 vector.fromArray( positions, i );
11210 bb.expandByPoint( vector );
11211
11212 }
11213
11214 }
11215
11216 if ( positions === undefined || positions.length === 0 ) {
11217
11218 this.boundingBox.min.set( 0, 0, 0 );
11219 this.boundingBox.max.set( 0, 0, 0 );
11220
11221 }
11222
11223 if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {
11224
11225 console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this );
11226
11227 }
11228
11229 };
11230
11231 }(),
11232
11233 computeBoundingSphere: function () {
11234
11235 var box = new THREE.Box3();
11236 var vector = new THREE.Vector3();
11237
11238 return function () {
11239
11240 if ( this.boundingSphere === null ) {
11241
11242 this.boundingSphere = new THREE.Sphere();
11243
11244 }
11245
11246 var positions = this.attributes.position.array;
11247
11248 if ( positions ) {
11249
11250 box.makeEmpty();
11251
11252 var center = this.boundingSphere.center;
11253
11254 for ( var i = 0, il = positions.length; i < il; i += 3 ) {
11255
11256 vector.fromArray( positions, i );
11257 box.expandByPoint( vector );
11258
11259 }
11260
11261 box.center( center );
11262
11263
11264
11265
11266 var maxRadiusSq = 0;
11267
11268 for ( var i = 0, il = positions.length; i < il; i += 3 ) {
11269
11270 vector.fromArray( positions, i );
11271 maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
11272
11273 }
11274
11275 this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
11276
11277 if ( isNaN( this.boundingSphere.radius ) ) {
11278
11279 console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this );
11280
11281 }
11282
11283 }
11284
11285 };
11286
11287 }(),
11288
11289 computeFaceNormals: function () {
11290
11291
11292
11293 },
11294
11295 computeVertexNormals: function () {
11296
11297 var index = this.index;
11298 var attributes = this.attributes;
11299 var groups = this.groups;
11300
11301 if ( attributes.position ) {
11302
11303 var positions = attributes.position.array;
11304
11305 if ( attributes.normal === undefined ) {
11306
11307 this.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( positions.length ), 3 ) );
11308
11309 } else {
11310
11311
11312
11313 var normals = attributes.normal.array;
11314
11315 for ( var i = 0, il = normals.length; i < il; i ++ ) {
11316
11317 normals[ i ] = 0;
11318
11319 }
11320
11321 }
11322
11323 var normals = attributes.normal.array;
11324
11325 var vA, vB, vC,
11326
11327 pA = new THREE.Vector3(),
11328 pB = new THREE.Vector3(),
11329 pC = new THREE.Vector3(),
11330
11331 cb = new THREE.Vector3(),
11332 ab = new THREE.Vector3();
11333
11334
11335
11336 if ( index ) {
11337
11338 var indices = index.array;
11339
11340 if ( groups.length === 0 ) {
11341
11342 this.addGroup( 0, indices.length );
11343
11344 }
11345
11346 for ( var j = 0, jl = groups.length; j < jl; ++ j ) {
11347
11348 var group = groups[ j ];
11349
11350 var start = group.start;
11351 var count = group.count;
11352
11353 for ( var i = start, il = start + count; i < il; i += 3 ) {
11354
11355 vA = indices[ i + 0 ] * 3;
11356 vB = indices[ i + 1 ] * 3;
11357 vC = indices[ i + 2 ] * 3;
11358
11359 pA.fromArray( positions, vA );
11360 pB.fromArray( positions, vB );
11361 pC.fromArray( positions, vC );
11362
11363 cb.subVectors( pC, pB );
11364 ab.subVectors( pA, pB );
11365 cb.cross( ab );
11366
11367 normals[ vA ] += cb.x;
11368 normals[ vA + 1 ] += cb.y;
11369 normals[ vA + 2 ] += cb.z;
11370
11371 normals[ vB ] += cb.x;
11372 normals[ vB + 1 ] += cb.y;
11373 normals[ vB + 2 ] += cb.z;
11374
11375 normals[ vC ] += cb.x;
11376 normals[ vC + 1 ] += cb.y;
11377 normals[ vC + 2 ] += cb.z;
11378
11379 }
11380
11381 }
11382
11383 } else {
11384
11385
11386
11387 for ( var i = 0, il = positions.length; i < il; i += 9 ) {
11388
11389 pA.fromArray( positions, i );
11390 pB.fromArray( positions, i + 3 );
11391 pC.fromArray( positions, i + 6 );
11392
11393 cb.subVectors( pC, pB );
11394 ab.subVectors( pA, pB );
11395 cb.cross( ab );
11396
11397 normals[ i ] = cb.x;
11398 normals[ i + 1 ] = cb.y;
11399 normals[ i + 2 ] = cb.z;
11400
11401 normals[ i + 3 ] = cb.x;
11402 normals[ i + 4 ] = cb.y;
11403 normals[ i + 5 ] = cb.z;
11404
11405 normals[ i + 6 ] = cb.x;
11406 normals[ i + 7 ] = cb.y;
11407 normals[ i + 8 ] = cb.z;
11408
11409 }
11410
11411 }
11412
11413 this.normalizeNormals();
11414
11415 attributes.normal.needsUpdate = true;
11416
11417 }
11418
11419 },
11420
11421 computeTangents: function () {
11422
11423 console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );
11424
11425 },
11426
11427 computeOffsets: function ( size ) {
11428
11429 console.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.')
11430
11431 },
11432
11433 merge: function ( geometry, offset ) {
11434
11435 if ( geometry instanceof THREE.BufferGeometry === false ) {
11436
11437 console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );
11438 return;
11439
11440 }
11441
11442 if ( offset === undefined ) offset = 0;
11443
11444 var attributes = this.attributes;
11445
11446 for ( var key in attributes ) {
11447
11448 if ( geometry.attributes[ key ] === undefined ) continue;
11449
11450 var attribute1 = attributes[ key ];
11451 var attributeArray1 = attribute1.array;
11452
11453 var attribute2 = geometry.attributes[ key ];
11454 var attributeArray2 = attribute2.array;
11455
11456 var attributeSize = attribute2.itemSize;
11457
11458 for ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {
11459
11460 attributeArray1[ j ] = attributeArray2[ i ];
11461
11462 }
11463
11464 }
11465
11466 return this;
11467
11468 },
11469
11470 normalizeNormals: function () {
11471
11472 var normals = this.attributes.normal.array;
11473
11474 var x, y, z, n;
11475
11476 for ( var i = 0, il = normals.length; i < il; i += 3 ) {
11477
11478 x = normals[ i ];
11479 y = normals[ i + 1 ];
11480 z = normals[ i + 2 ];
11481
11482 n = 1.0 / Math.sqrt( x * x + y * y + z * z );
11483
11484 normals[ i ] *= n;
11485 normals[ i + 1 ] *= n;
11486 normals[ i + 2 ] *= n;
11487
11488 }
11489
11490 },
11491
11492 toJSON: function () {
11493
11494 var data = {
11495 metadata: {
11496 version: 4.4,
11497 type: 'BufferGeometry',
11498 generator: 'BufferGeometry.toJSON'
11499 }
11500 };
11501
11502
11503
11504 data.uuid = this.uuid;
11505 data.type = this.type;
11506 if ( this.name !== '' ) data.name = this.name;
11507
11508 if ( this.parameters !== undefined ) {
11509
11510 var parameters = this.parameters;
11511
11512 for ( var key in parameters ) {
11513
11514 if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];
11515
11516 }
11517
11518 return data;
11519
11520 }
11521
11522 data.data = { attributes: {} };
11523
11524 var index = this.index;
11525
11526 if ( index !== null ) {
11527
11528 var array = Array.prototype.slice.call( index.array );
11529
11530 data.data.index = {
11531 type: index.array.constructor.name,
11532 array: array
11533 };
11534
11535 }
11536
11537 var attributes = this.attributes;
11538
11539 for ( var key in attributes ) {
11540
11541 var attribute = attributes[ key ];
11542
11543 var array = Array.prototype.slice.call( attribute.array );
11544
11545 data.data.attributes[ key ] = {
11546 itemSize: attribute.itemSize,
11547 type: attribute.array.constructor.name,
11548 array: array
11549 };
11550
11551 }
11552
11553 var groups = this.groups;
11554
11555 if ( groups.length > 0 ) {
11556
11557 data.data.groups = JSON.parse( JSON.stringify( groups ) );
11558
11559 }
11560
11561 var boundingSphere = this.boundingSphere;
11562
11563 if ( boundingSphere !== null ) {
11564
11565 data.data.boundingSphere = {
11566 center: boundingSphere.center.toArray(),
11567 radius: boundingSphere.radius
11568 };
11569
11570 }
11571
11572 return data;
11573
11574 },
11575
11576 clone: function () {
11577
11578 return new this.constructor().copy( this );
11579
11580 },
11581
11582 copy: function ( source ) {
11583
11584 var index = source.index;
11585
11586 if ( index !== null ) {
11587
11588 this.setIndex( index.clone() );
11589
11590 }
11591
11592 var attributes = source.attributes;
11593
11594 for ( var name in attributes ) {
11595
11596 var attribute = attributes[ name ];
11597 this.addAttribute( name, attribute.clone() );
11598
11599 }
11600
11601 var groups = source.groups;
11602
11603 for ( var i = 0, l = groups.length; i < l; i ++ ) {
11604
11605 var group = groups[ i ];
11606 this.addGroup( group.start, group.count );
11607
11608 }
11609
11610 return this;
11611
11612 },
11613
11614 dispose: function () {
11615
11616 this.dispatchEvent( { type: 'dispose' } );
11617
11618 }
11619
11620 };
11621
11622 THREE.EventDispatcher.prototype.apply( THREE.BufferGeometry.prototype );
11623
11624 THREE.BufferGeometry.MaxIndex = 65535;
11625
11626
11627
11632 THREE.InstancedBufferGeometry = function () {
11633
11634 THREE.BufferGeometry.call( this );
11635
11636 this.type = 'InstancedBufferGeometry';
11637 this.maxInstancedCount = undefined;
11638
11639 };
11640
11641 THREE.InstancedBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
11642 THREE.InstancedBufferGeometry.prototype.constructor = THREE.InstancedBufferGeometry;
11643
11644 THREE.InstancedBufferGeometry.prototype.addGroup = function ( start, count, instances ) {
11645
11646 this.groups.push( {
11647
11648 start: start,
11649 count: count,
11650 instances: instances
11651
11652 } );
11653
11654 };
11655
11656 THREE.InstancedBufferGeometry.prototype.copy = function ( source ) {
11657
11658 var index = source.index;
11659
11660 if ( index !== null ) {
11661
11662 this.setIndex( index.clone() );
11663
11664 }
11665
11666 var attributes = source.attributes;
11667
11668 for ( var name in attributes ) {
11669
11670 var attribute = attributes[ name ];
11671 this.addAttribute( name, attribute.clone() );
11672
11673 }
11674
11675 var groups = source.groups;
11676
11677 for ( var i = 0, l = groups.length; i < l; i ++ ) {
11678
11679 var group = groups[ i ];
11680 this.addGroup( group.start, group.count, group.instances );
11681
11682 }
11683
11684 return this;
11685
11686 };
11687
11688 THREE.EventDispatcher.prototype.apply( THREE.InstancedBufferGeometry.prototype );
11689
11690
11691
11700 THREE.AnimationAction = function ( clip, startTime, timeScale, weight, loop ) {
11701
11702 if ( clip === undefined ) throw new Error( 'clip is null' );
11703 this.clip = clip;
11704 this.localRoot = null;
11705 this.startTime = startTime || 0;
11706 this.timeScale = timeScale || 1;
11707 this.weight = weight || 1;
11708 this.loop = loop || THREE.LoopRepeat;
11709 this.loopCount = 0;
11710 this.enabled = true;
11711
11712 this.actionTime = - this.startTime;
11713 this.clipTime = 0;
11714
11715 this.propertyBindings = [];
11716 };
11717
11718
11719
11720
11721
11722
11723
11724 THREE.AnimationAction.prototype = {
11725
11726 constructor: THREE.AnimationAction,
11727
11728 setLocalRoot: function( localRoot ) {
11729
11730 this.localRoot = localRoot;
11731
11732 return this;
11733
11734 },
11735
11736 updateTime: function( clipDeltaTime ) {
11737
11738 var previousClipTime = this.clipTime;
11739 var previousLoopCount = this.loopCount;
11740 var previousActionTime = this.actionTime;
11741
11742 var duration = this.clip.duration;
11743
11744 this.actionTime = this.actionTime + clipDeltaTime;
11745
11746 if ( this.loop === THREE.LoopOnce ) {
11747
11748 this.loopCount = 0;
11749 this.clipTime = Math.min( Math.max( this.actionTime, 0 ), duration );
11750
11751
11752 if ( this.clipTime !== previousClipTime ) {
11753
11754 if ( this.clipTime === duration ) {
11755
11756 this.mixer.dispatchEvent( { type: 'finished', action: this, direction: 1 } );
11757
11758 } else if ( this.clipTime === 0 ) {
11759
11760 this.mixer.dispatchEvent( { type: 'finished', action: this, direction: -1 } );
11761
11762 }
11763
11764 }
11765
11766
11767 return this.clipTime;
11768
11769 }
11770
11771 this.loopCount = Math.floor( this.actionTime / duration );
11772
11773 var newClipTime = this.actionTime - this.loopCount * duration;
11774 newClipTime = newClipTime % duration;
11775
11776
11777 if ( this.loop == THREE.LoopPingPong ) {
11778
11779 if ( Math.abs( this.loopCount % 2 ) === 1 ) {
11780
11781 newClipTime = duration - newClipTime;
11782
11783 }
11784
11785 }
11786
11787 this.clipTime = newClipTime;
11788
11789 if ( this.loopCount !== previousLoopCount ) {
11790
11791 this.mixer.dispatchEvent( { type: 'loop', action: this, loopDelta: ( this.loopCount - this.loopCount ) } );
11792
11793 }
11794
11795 return this.clipTime;
11796
11797 },
11798
11799 syncWith: function( action ) {
11800
11801 this.actionTime = action.actionTime;
11802 this.timeScale = action.timeScale;
11803
11804 return this;
11805 },
11806
11807 warpToDuration: function( duration ) {
11808
11809 this.timeScale = this.clip.duration / duration;
11810
11811 return this;
11812 },
11813
11814 init: function( time ) {
11815
11816 this.clipTime = time - this.startTime;
11817
11818 return this;
11819
11820 },
11821
11822 update: function( clipDeltaTime ) {
11823
11824 this.updateTime( clipDeltaTime );
11825
11826 var clipResults = this.clip.getAt( this.clipTime );
11827
11828 return clipResults;
11829
11830 },
11831
11832 getTimeScaleAt: function( time ) {
11833
11834 if ( this.timeScale.getAt ) {
11835
11836 return this.timeScale.getAt( time );
11837
11838 }
11839
11840 return this.timeScale;
11841
11842 },
11843
11844 getWeightAt: function( time ) {
11845
11846 if ( this.weight.getAt ) {
11847
11848 return this.weight.getAt( time );
11849
11850 }
11851
11852 return this.weight;
11853
11854 }
11855
11856 };
11857
11858
11859
11868 THREE.AnimationClip = function ( name, duration, tracks ) {
11869
11870 this.name = name;
11871 this.tracks = tracks;
11872 this.duration = ( duration !== undefined ) ? duration : -1;
11873
11874
11875 if ( this.duration < 0 ) {
11876 for ( var i = 0; i < this.tracks.length; i ++ ) {
11877 var track = this.tracks[i];
11878 this.duration = Math.max( track.keys[ track.keys.length - 1 ].time );
11879 }
11880 }
11881
11882
11883
11884 this.trim();
11885 this.optimize();
11886
11887 this.results = [];
11888
11889 };
11890
11891 THREE.AnimationClip.prototype = {
11892
11893 constructor: THREE.AnimationClip,
11894
11895 getAt: function( clipTime ) {
11896
11897 clipTime = Math.max( 0, Math.min( clipTime, this.duration ) );
11898
11899 for ( var i = 0; i < this.tracks.length; i ++ ) {
11900
11901 var track = this.tracks[ i ];
11902
11903 this.results[ i ] = track.getAt( clipTime );
11904
11905 }
11906
11907 return this.results;
11908 },
11909
11910 trim: function() {
11911
11912 for ( var i = 0; i < this.tracks.length; i ++ ) {
11913
11914 this.tracks[ i ].trim( 0, this.duration );
11915
11916 }
11917
11918 return this;
11919
11920 },
11921
11922 optimize: function() {
11923
11924 for ( var i = 0; i < this.tracks.length; i ++ ) {
11925
11926 this.tracks[ i ].optimize();
11927
11928 }
11929
11930 return this;
11931
11932 }
11933
11934 };
11935
11936
11937 THREE.AnimationClip.CreateFromMorphTargetSequence = function( name, morphTargetSequence, fps ) {
11938
11939
11940 var numMorphTargets = morphTargetSequence.length;
11941 var tracks = [];
11942
11943 for ( var i = 0; i < numMorphTargets; i ++ ) {
11944
11945 var keys = [];
11946
11947 keys.push( { time: ( i + numMorphTargets - 1 ) % numMorphTargets, value: 0 } );
11948 keys.push( { time: i, value: 1 } );
11949 keys.push( { time: ( i + 1 ) % numMorphTargets, value: 0 } );
11950
11951 keys.sort( THREE.KeyframeTrack.keyComparer );
11952
11953
11954 if ( keys[0].time === 0 ) {
11955 keys.push( {
11956 time: numMorphTargets,
11957 value: keys[0].value
11958 });
11959 }
11960
11961 tracks.push( new THREE.NumberKeyframeTrack( '.morphTargetInfluences[' + morphTargetSequence[i].name + ']', keys ).scale( 1.0 / fps ) );
11962 }
11963
11964 return new THREE.AnimationClip( name, -1, tracks );
11965
11966 };
11967
11968 THREE.AnimationClip.findByName = function( clipArray, name ) {
11969
11970 for ( var i = 0; i < clipArray.length; i ++ ) {
11971
11972 if ( clipArray[i].name === name ) {
11973
11974 return clipArray[i];
11975
11976 }
11977 }
11978
11979 return null;
11980
11981 };
11982
11983 THREE.AnimationClip.CreateClipsFromMorphTargetSequences = function( morphTargets, fps ) {
11984
11985 var animationToMorphTargets = {};
11986
11987
11988 var pattern = /^([\w-]*?)([\d]+)$/;
11989
11990
11991 for ( var i = 0, il = morphTargets.length; i < il; i ++ ) {
11992
11993 var morphTarget = morphTargets[ i ];
11994 var parts = morphTarget.name.match( pattern );
11995
11996 if ( parts && parts.length > 1 ) {
11997
11998 var name = parts[ 1 ];
11999
12000 var animationMorphTargets = animationToMorphTargets[ name ];
12001 if ( ! animationMorphTargets ) {
12002 animationToMorphTargets[ name ] = animationMorphTargets = [];
12003 }
12004
12005 animationMorphTargets.push( morphTarget );
12006
12007 }
12008
12009 }
12010
12011 var clips = [];
12012
12013 for ( var name in animationToMorphTargets ) {
12014
12015 clips.push( THREE.AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps ) );
12016 }
12017
12018 return clips;
12019
12020 };
12021
12022
12023 THREE.AnimationClip.parse = function( json ) {
12024
12025 var tracks = [];
12026
12027 for ( var i = 0; i < json.tracks.length; i ++ ) {
12028
12029 tracks.push( THREE.KeyframeTrack.parse( json.tracks[i] ).scale( 1.0 / json.fps ) );
12030
12031 }
12032
12033 return new THREE.AnimationClip( json.name, json.duration, tracks );
12034
12035 };
12036
12037
12038
12039 THREE.AnimationClip.parseAnimation = function( animation, bones, nodeName ) {
12040
12041 if ( ! animation ) {
12042 console.error( " no animation in JSONLoader data" );
12043 return null;
12044 }
12045
12046 var convertTrack = function( trackName, animationKeys, propertyName, trackType, animationKeyToValueFunc ) {
12047
12048 var keys = [];
12049
12050 for ( var k = 0; k < animationKeys.length; k ++ ) {
12051
12052 var animationKey = animationKeys[k];
12053
12054 if ( animationKey[propertyName] !== undefined ) {
12055
12056 keys.push( { time: animationKey.time, value: animationKeyToValueFunc( animationKey ) } );
12057 }
12058
12059 }
12060
12061
12062 if ( keys.length > 0 ) {
12063
12064 return new trackType( trackName, keys );
12065
12066 }
12067
12068 return null;
12069
12070 };
12071
12072 var tracks = [];
12073
12074 var clipName = animation.name || 'default';
12075 var duration = animation.length || -1;
12076 var fps = animation.fps || 30;
12077
12078 var hierarchyTracks = animation.hierarchy || [];
12079
12080 for ( var h = 0; h < hierarchyTracks.length; h ++ ) {
12081
12082 var animationKeys = hierarchyTracks[ h ].keys;
12083
12084
12085 if ( ! animationKeys || animationKeys.length == 0 ) {
12086 continue;
12087 }
12088
12089
12090 if ( animationKeys[0].morphTargets ) {
12091
12092
12093 var morphTargetNames = {};
12094 for ( var k = 0; k < animationKeys.length; k ++ ) {
12095
12096 if ( animationKeys[k].morphTargets ) {
12097 for ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {
12098
12099 morphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;
12100 }
12101 }
12102
12103 }
12104
12105
12106 for ( var morphTargetName in morphTargetNames ) {
12107
12108 var keys = [];
12109
12110 for ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {
12111
12112 var animationKey = animationKeys[k];
12113
12114 keys.push( {
12115 time: animationKey.time,
12116 value: (( animationKey.morphTarget === morphTargetName ) ? 1 : 0 )
12117 });
12118
12119 }
12120
12121 tracks.push( new THREE.NumberKeyframeTrack( nodeName + '.morphTargetInfluence[' + morphTargetName + ']', keys ) );
12122
12123 }
12124
12125 duration = morphTargetNames.length * ( fps || 1.0 );
12126
12127 } else {
12128
12129 var boneName = nodeName + '.bones[' + bones[ h ].name + ']';
12130
12131
12132 var positionTrack = convertTrack( boneName + '.position', animationKeys, 'pos', THREE.VectorKeyframeTrack, function( animationKey ) {
12133 return new THREE.Vector3().fromArray( animationKey.pos )
12134 } );
12135
12136 if ( positionTrack ) tracks.push( positionTrack );
12137
12138
12139 var quaternionTrack = convertTrack( boneName + '.quaternion', animationKeys, 'rot', THREE.QuaternionKeyframeTrack, function( animationKey ) {
12140 if ( animationKey.rot.slerp ) {
12141 return animationKey.rot.clone();
12142 } else {
12143 return new THREE.Quaternion().fromArray( animationKey.rot );
12144 }
12145 } );
12146
12147 if ( quaternionTrack ) tracks.push( quaternionTrack );
12148
12149
12150 var scaleTrack = convertTrack( boneName + '.scale', animationKeys, 'scl', THREE.VectorKeyframeTrack, function( animationKey ) {
12151 return new THREE.Vector3().fromArray( animationKey.scl )
12152 } );
12153
12154 if ( scaleTrack ) tracks.push( scaleTrack );
12155
12156 }
12157 }
12158
12159 if ( tracks.length === 0 ) {
12160
12161 return null;
12162
12163 }
12164
12165 var clip = new THREE.AnimationClip( clipName, duration, tracks );
12166
12167 return clip;
12168
12169 };
12170
12171
12172
12182 THREE.AnimationMixer = function( root ) {
12183
12184 this.root = root;
12185 this.time = 0;
12186 this.timeScale = 1.0;
12187 this.actions = [];
12188 this.propertyBindingMap = {};
12189
12190 };
12191
12192 THREE.AnimationMixer.prototype = {
12193
12194 constructor: THREE.AnimationMixer,
12195
12196 addAction: function( action ) {
12197
12198
12199
12200 this.actions.push( action );
12201 action.init( this.time );
12202 action.mixer = this;
12203
12204 var tracks = action.clip.tracks;
12205
12206 var root = action.localRoot || this.root;
12207
12208 for ( var i = 0; i < tracks.length; i ++ ) {
12209
12210 var track = tracks[ i ];
12211
12212 var propertyBindingKey = root.uuid + '-' + track.name;
12213 var propertyBinding = this.propertyBindingMap[ propertyBindingKey ];
12214
12215 if ( propertyBinding === undefined ) {
12216
12217 propertyBinding = new THREE.PropertyBinding( root, track.name );
12218 this.propertyBindingMap[ propertyBindingKey ] = propertyBinding;
12219
12220 }
12221
12222
12223 action.propertyBindings.push( propertyBinding );
12224
12225
12226 propertyBinding.referenceCount += 1;
12227
12228 }
12229
12230 },
12231
12232 removeAllActions: function() {
12233
12234 for ( var i = 0; i < this.actions.length; i ++ ) {
12235
12236 this.actions[i].mixer = null;
12237
12238 }
12239
12240
12241 for ( var properyBindingKey in this.propertyBindingMap ) {
12242
12243 this.propertyBindingMap[ properyBindingKey ].unbind();
12244
12245 }
12246
12247 this.actions = [];
12248 this.propertyBindingMap = {};
12249
12250 return this;
12251
12252 },
12253
12254 removeAction: function( action ) {
12255
12256 var index = this.actions.indexOf( action );
12257
12258 if ( index !== - 1 ) {
12259
12260 this.actions.splice( index, 1 );
12261 action.mixer = null;
12262
12263 }
12264
12265
12266
12267 var root = action.localRoot || this.root;
12268 var tracks = action.clip.tracks;
12269
12270 for ( var i = 0; i < tracks.length; i ++ ) {
12271
12272 var track = tracks[ i ];
12273
12274 var propertyBindingKey = root.uuid + '-' + track.name;
12275 var propertyBinding = this.propertyBindingMap[ propertyBindingKey ];
12276
12277 propertyBinding.referenceCount -= 1;
12278
12279 if ( propertyBinding.referenceCount <= 0 ) {
12280
12281 propertyBinding.unbind();
12282
12283 delete this.propertyBindingMap[ propertyBindingKey ];
12284
12285 }
12286 }
12287
12288 return this;
12289
12290 },
12291
12292
12293 findActionByName: function( name ) {
12294
12295 for ( var i = 0; i < this.actions.length; i ++ ) {
12296
12297 if ( this.actions[i].name === name ) return this.actions[i];
12298
12299 }
12300
12301 return null;
12302
12303 },
12304
12305 play: function( action, optionalFadeInDuration ) {
12306
12307 action.startTime = this.time;
12308 this.addAction( action );
12309
12310 return this;
12311
12312 },
12313
12314 fadeOut: function( action, duration ) {
12315
12316 var keys = [];
12317
12318 keys.push( { time: this.time, value: 1 } );
12319 keys.push( { time: this.time + duration, value: 0 } );
12320
12321 action.weight = new THREE.NumberKeyframeTrack( "weight", keys );
12322
12323 return this;
12324
12325 },
12326
12327 fadeIn: function( action, duration ) {
12328
12329 var keys = [];
12330
12331 keys.push( { time: this.time, value: 0 } );
12332 keys.push( { time: this.time + duration, value: 1 } );
12333
12334 action.weight = new THREE.NumberKeyframeTrack( "weight", keys );
12335
12336 return this;
12337
12338 },
12339
12340 warp: function( action, startTimeScale, endTimeScale, duration ) {
12341
12342 var keys = [];
12343
12344 keys.push( { time: this.time, value: startTimeScale } );
12345 keys.push( { time: this.time + duration, value: endTimeScale } );
12346
12347 action.timeScale = new THREE.NumberKeyframeTrack( "timeScale", keys );
12348
12349 return this;
12350
12351 },
12352
12353 crossFade: function( fadeOutAction, fadeInAction, duration, warp ) {
12354
12355 this.fadeOut( fadeOutAction, duration );
12356 this.fadeIn( fadeInAction, duration );
12357
12358 if ( warp ) {
12359
12360 var startEndRatio = fadeOutAction.clip.duration / fadeInAction.clip.duration;
12361 var endStartRatio = 1.0 / startEndRatio;
12362
12363 this.warp( fadeOutAction, 1.0, startEndRatio, duration );
12364 this.warp( fadeInAction, endStartRatio, 1.0, duration );
12365
12366 }
12367
12368 return this;
12369
12370 },
12371
12372 update: function( deltaTime ) {
12373
12374 var mixerDeltaTime = deltaTime * this.timeScale;
12375 this.time += mixerDeltaTime;
12376
12377 for ( var i = 0; i < this.actions.length; i ++ ) {
12378
12379 var action = this.actions[i];
12380
12381 var weight = action.getWeightAt( this.time );
12382
12383 var actionTimeScale = action.getTimeScaleAt( this.time );
12384 var actionDeltaTime = mixerDeltaTime * actionTimeScale;
12385
12386 var actionResults = action.update( actionDeltaTime );
12387
12388 if ( action.weight <= 0 || ! action.enabled ) continue;
12389
12390 for ( var j = 0; j < actionResults.length; j ++ ) {
12391
12392 var name = action.clip.tracks[j].name;
12393
12394 action.propertyBindings[ j ].accumulate( actionResults[j], weight );
12395
12396 }
12397
12398 }
12399
12400
12401 for ( var propertyBindingKey in this.propertyBindingMap ) {
12402
12403 this.propertyBindingMap[ propertyBindingKey ].apply();
12404
12405 }
12406
12407 return this;
12408
12409 }
12410
12411 };
12412
12413 THREE.EventDispatcher.prototype.apply( THREE.AnimationMixer.prototype );
12414
12415
12416
12422 THREE.AnimationUtils = {
12423
12424 getEqualsFunc: function( exemplarValue ) {
12425
12426 if ( exemplarValue.equals ) {
12427 return function equals_object( a, b ) {
12428 return a.equals( b );
12429 }
12430 }
12431
12432 return function equals_primitive( a, b ) {
12433 return ( a === b );
12434 };
12435
12436 },
12437
12438 clone: function( exemplarValue ) {
12439
12440 var typeName = typeof exemplarValue;
12441 if ( typeName === "object" ) {
12442 if ( exemplarValue.clone ) {
12443 return exemplarValue.clone();
12444 }
12445 console.error( "can not figure out how to copy exemplarValue", exemplarValue );
12446 }
12447
12448 return exemplarValue;
12449
12450 },
12451
12452 lerp: function( a, b, alpha, interTrack ) {
12453
12454 var lerpFunc = THREE.AnimationUtils.getLerpFunc( a, interTrack );
12455
12456 return lerpFunc( a, b, alpha );
12457
12458 },
12459
12460 lerp_object: function( a, b, alpha ) {
12461 return a.lerp( b, alpha );
12462 },
12463
12464 slerp_object: function( a, b, alpha ) {
12465 return a.slerp( b, alpha );
12466 },
12467
12468 lerp_number: function( a, b, alpha ) {
12469 return a * ( 1 - alpha ) + b * alpha;
12470 },
12471
12472 lerp_boolean: function( a, b, alpha ) {
12473 return ( alpha < 0.5 ) ? a : b;
12474 },
12475
12476 lerp_boolean_immediate: function( a, b, alpha ) {
12477 return a;
12478 },
12479
12480 lerp_string: function( a, b, alpha ) {
12481 return ( alpha < 0.5 ) ? a : b;
12482 },
12483
12484 lerp_string_immediate: function( a, b, alpha ) {
12485 return a;
12486 },
12487
12488
12489 getLerpFunc: function( exemplarValue, interTrack ) {
12490
12491 if ( exemplarValue === undefined || exemplarValue === null ) throw new Error( "examplarValue is null" );
12492
12493 var typeName = typeof exemplarValue;
12494
12495 switch( typeName ) {
12496
12497 case "object":
12498 if ( exemplarValue.lerp ) {
12499 return THREE.AnimationUtils.lerp_object;
12500 }
12501
12502 if ( exemplarValue.slerp ) {
12503 return THREE.AnimationUtils.slerp_object;
12504 }
12505 break;
12506
12507 case "number":
12508 return THREE.AnimationUtils.lerp_number;
12509
12510 case "boolean":
12511 if ( interTrack ) {
12512 return THREE.AnimationUtils.lerp_boolean;
12513 } else {
12514 return THREE.AnimationUtils.lerp_boolean_immediate;
12515 }
12516
12517 case "string":
12518 if ( interTrack ) {
12519 return THREE.AnimationUtils.lerp_string;
12520 } else {
12521 return THREE.AnimationUtils.lerp_string_immediate;
12522 }
12523
12524 }
12525
12526 }
12527
12528 };
12529
12530
12531
12540 THREE.KeyframeTrack = function ( name, keys ) {
12541
12542 if ( name === undefined ) throw new Error( "track name is undefined" );
12543 if ( keys === undefined || keys.length === 0 ) throw new Error( "no keys in track named " + name );
12544
12545 this.name = name;
12546 this.keys = keys;
12547
12548
12549 this.lastIndex = 0;
12550
12551 this.validate();
12552 this.optimize();
12553
12554 };
12555
12556 THREE.KeyframeTrack.prototype = {
12557
12558 constructor: THREE.KeyframeTrack,
12559
12560 getAt: function( time ) {
12561
12562
12563
12564 while( ( this.lastIndex < this.keys.length ) && ( time >= this.keys[this.lastIndex].time ) ) {
12565 this.lastIndex ++;
12566 };
12567
12568
12569 while( ( this.lastIndex > 0 ) && ( time < this.keys[this.lastIndex - 1].time ) ) {
12570 this.lastIndex --;
12571 }
12572
12573 if ( this.lastIndex >= this.keys.length ) {
12574
12575 this.setResult( this.keys[ this.keys.length - 1 ].value );
12576
12577 return this.result;
12578
12579 }
12580
12581 if ( this.lastIndex === 0 ) {
12582
12583 this.setResult( this.keys[ 0 ].value );
12584
12585 return this.result;
12586
12587 }
12588
12589 var prevKey = this.keys[ this.lastIndex - 1 ];
12590 this.setResult( prevKey.value );
12591
12592
12593 if ( prevKey.constantToNext ) {
12594
12595 return this.result;
12596
12597 }
12598
12599
12600 var currentKey = this.keys[ this.lastIndex ];
12601 var alpha = ( time - prevKey.time ) / ( currentKey.time - prevKey.time );
12602 this.result = this.lerpValues( this.result, currentKey.value, alpha );
12603
12604 return this.result;
12605
12606 },
12607
12608
12609 shift: function( timeOffset ) {
12610
12611 if ( timeOffset !== 0.0 ) {
12612
12613 for ( var i = 0; i < this.keys.length; i ++ ) {
12614 this.keys[i].time += timeOffset;
12615 }
12616
12617 }
12618
12619 return this;
12620
12621 },
12622
12623
12624 scale: function( timeScale ) {
12625
12626 if ( timeScale !== 1.0 ) {
12627
12628 for ( var i = 0; i < this.keys.length; i ++ ) {
12629 this.keys[i].time *= timeScale;
12630 }
12631
12632 }
12633
12634 return this;
12635
12636 },
12637
12638
12639
12640 trim: function( startTime, endTime ) {
12641
12642 var firstKeysToRemove = 0;
12643 for ( var i = 1; i < this.keys.length; i ++ ) {
12644 if ( this.keys[i] <= startTime ) {
12645 firstKeysToRemove ++;
12646 }
12647 }
12648
12649 var lastKeysToRemove = 0;
12650 for ( var i = this.keys.length - 2; i > 0; i ++ ) {
12651 if ( this.keys[i] >= endTime ) {
12652 lastKeysToRemove ++;
12653 } else {
12654 break;
12655 }
12656 }
12657
12658
12659 if ( ( firstKeysToRemove + lastKeysToRemove ) > 0 ) {
12660 this.keys = this.keys.splice( firstKeysToRemove, this.keys.length - lastKeysToRemove - firstKeysToRemove );;
12661 }
12662
12663 return this;
12664
12665 },
12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676
12677
12678
12679 validate: function() {
12680
12681 var prevKey = null;
12682
12683 if ( this.keys.length === 0 ) {
12684 console.error( " track is empty, no keys", this );
12685 return;
12686 }
12687
12688 for ( var i = 0; i < this.keys.length; i ++ ) {
12689
12690 var currKey = this.keys[i];
12691
12692 if ( ! currKey ) {
12693 console.error( " key is null in track", this, i );
12694 return;
12695 }
12696
12697 if ( ( typeof currKey.time ) !== 'number' || isNaN( currKey.time ) ) {
12698 console.error( " key.time is not a valid number", this, i, currKey );
12699 return;
12700 }
12701
12702 if ( currKey.value === undefined || currKey.value === null) {
12703 console.error( " key.value is null in track", this, i, currKey );
12704 return;
12705 }
12706
12707 if ( prevKey && prevKey.time > currKey.time ) {
12708 console.error( " key.time is less than previous key time, out of order keys", this, i, currKey, prevKey );
12709 return;
12710 }
12711
12712 prevKey = currKey;
12713
12714 }
12715
12716 return this;
12717
12718 },
12719
12720
12721 optimize: function() {
12722
12723 var newKeys = [];
12724 var prevKey = this.keys[0];
12725 newKeys.push( prevKey );
12726
12727 var equalsFunc = THREE.AnimationUtils.getEqualsFunc( prevKey.value );
12728
12729 for ( var i = 1; i < this.keys.length - 1; i ++ ) {
12730 var currKey = this.keys[i];
12731 var nextKey = this.keys[i+1];
12732
12733
12734
12735 if ( ( prevKey.time === currKey.time ) ) {
12736
12737 continue;
12738
12739 }
12740
12741
12742 if ( this.compareValues( prevKey.value, currKey.value ) && this.compareValues( currKey.value, nextKey.value ) ) {
12743
12744 continue;
12745
12746 }
12747
12748
12749 prevKey.constantToNext = this.compareValues( prevKey.value, currKey.value );
12750
12751 newKeys.push( currKey );
12752 prevKey = currKey;
12753 }
12754 newKeys.push( this.keys[ this.keys.length - 1 ] );
12755
12756 this.keys = newKeys;
12757
12758 return this;
12759
12760 }
12761
12762 };
12763
12764 THREE.KeyframeTrack.keyComparer = function keyComparator(key0, key1) {
12765 return key0.time - key1.time;
12766 };
12767
12768 THREE.KeyframeTrack.parse = function( json ) {
12769
12770 if ( json.type === undefined ) throw new Error( "track type undefined, can not parse" );
12771
12772 var trackType = THREE.KeyframeTrack.GetTrackTypeForTypeName( json.type );
12773
12774 return trackType.parse( json );
12775
12776 };
12777
12778 THREE.KeyframeTrack.GetTrackTypeForTypeName = function( typeName ) {
12779 switch( typeName.toLowerCase() ) {
12780 case "vector":
12781 case "vector2":
12782 case "vector3":
12783 case "vector4":
12784 return THREE.VectorKeyframeTrack;
12785
12786 case "quaternion":
12787 return THREE.QuaternionKeyframeTrack;
12788
12789 case "integer":
12790 case "scalar":
12791 case "double":
12792 case "float":
12793 case "number":
12794 return THREE.NumberKeyframeTrack;
12795
12796 case "bool":
12797 case "boolean":
12798 return THREE.BooleanKeyframeTrack;
12799
12800 case "string":
12801 return THREE.StringKeyframeTrack;
12802 };
12803
12804 throw new Error( "Unsupported typeName: " + typeName );
12805 };
12806
12807
12808
12817 THREE.PropertyBinding = function ( rootNode, trackName ) {
12818
12819 this.rootNode = rootNode;
12820 this.trackName = trackName;
12821 this.referenceCount = 0;
12822 this.originalValue = null;
12823
12824 var parseResults = THREE.PropertyBinding.parseTrackName( trackName );
12825
12826 this.directoryName = parseResults.directoryName;
12827 this.nodeName = parseResults.nodeName;
12828 this.objectName = parseResults.objectName;
12829 this.objectIndex = parseResults.objectIndex;
12830 this.propertyName = parseResults.propertyName;
12831 this.propertyIndex = parseResults.propertyIndex;
12832
12833 this.node = THREE.PropertyBinding.findNode( rootNode, this.nodeName ) || rootNode;
12834
12835 this.cumulativeValue = null;
12836 this.cumulativeWeight = 0;
12837 };
12838
12839 THREE.PropertyBinding.prototype = {
12840
12841 constructor: THREE.PropertyBinding,
12842
12843 reset: function() {
12844
12845 this.cumulativeValue = null;
12846 this.cumulativeWeight = 0;
12847
12848 },
12849
12850 accumulate: function( value, weight ) {
12851
12852 if ( ! this.isBound ) this.bind();
12853
12854 if ( this.cumulativeWeight === 0 ) {
12855
12856 if ( weight > 0 ) {
12857
12858 if ( this.cumulativeValue === null ) {
12859 this.cumulativeValue = THREE.AnimationUtils.clone( value );
12860 }
12861 this.cumulativeWeight = weight;
12862
12863 }
12864
12865 } else {
12866
12867 var lerpAlpha = weight / ( this.cumulativeWeight + weight );
12868 this.cumulativeValue = this.lerpValue( this.cumulativeValue, value, lerpAlpha );
12869 this.cumulativeWeight += weight;
12870
12871 }
12872
12873 },
12874
12875 unbind: function() {
12876
12877 if ( ! this.isBound ) return;
12878
12879 this.setValue( this.originalValue );
12880
12881 this.setValue = null;
12882 this.getValue = null;
12883 this.lerpValue = null;
12884 this.equalsValue = null;
12885 this.triggerDirty = null;
12886 this.isBound = false;
12887
12888 },
12889
12890
12891 bind: function() {
12892
12893 if ( this.isBound ) return;
12894
12895 var targetObject = this.node;
12896
12897
12898 if ( ! targetObject ) {
12899 console.error( " trying to update node for track: " + this.trackName + " but it wasn't found." );
12900 return;
12901 }
12902
12903 if ( this.objectName ) {
12904
12905 if ( this.objectName === "materials" ) {
12906 if ( ! targetObject.material ) {
12907 console.error( ' can not bind to material as node does not have a material', this );
12908 return;
12909 }
12910 if ( ! targetObject.material.materials ) {
12911 console.error( ' can not bind to material.materials as node.material does not have a materials array', this );
12912 return;
12913 }
12914 targetObject = targetObject.material.materials;
12915 } else if ( this.objectName === "bones" ) {
12916 if ( ! targetObject.skeleton ) {
12917 console.error( ' can not bind to bones as node does not have a skeleton', this );
12918 return;
12919 }
12920
12921
12922 targetObject = targetObject.skeleton.bones;
12923
12924
12925 for ( var i = 0; i < targetObject.length; i ++ ) {
12926 if ( targetObject[i].name === this.objectIndex ) {
12927 this.objectIndex = i;
12928 break;
12929 }
12930 }
12931 } else {
12932
12933 if ( targetObject[ this.objectName ] === undefined ) {
12934 console.error( ' can not bind to objectName of node, undefined', this );
12935 return;
12936 }
12937 targetObject = targetObject[ this.objectName ];
12938 }
12939
12940 if ( this.objectIndex !== undefined ) {
12941 if ( targetObject[ this.objectIndex ] === undefined ) {
12942 console.error( " trying to bind to objectIndex of objectName, but is undefined:", this, targetObject );
12943 return;
12944 }
12945
12946 targetObject = targetObject[ this.objectIndex ];
12947 }
12948
12949 }
12950
12951
12952 var nodeProperty = targetObject[ this.propertyName ];
12953 if ( ! nodeProperty ) {
12954 console.error( " trying to update property for track: " + this.nodeName + '.' + this.propertyName + " but it wasn't found.", targetObject );
12955 return;
12956 }
12957
12958
12959 if ( this.propertyIndex !== undefined ) {
12960
12961 if ( this.propertyName === "morphTargetInfluences" ) {
12962
12963
12964
12965 if ( ! targetObject.geometry ) {
12966 console.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );
12967 }
12968 if ( ! targetObject.geometry.morphTargets ) {
12969 console.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );
12970 }
12971
12972 for ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {
12973 if ( targetObject.geometry.morphTargets[i].name === this.propertyIndex ) {
12974 this.propertyIndex = i;
12975 break;
12976 }
12977 }
12978 }
12979
12980 this.setValue = function setValue_propertyIndexed( value ) {
12981 if ( ! this.equalsValue( nodeProperty[ this.propertyIndex ], value ) ) {
12982 nodeProperty[ this.propertyIndex ] = value;
12983 return true;
12984 }
12985 return false;
12986 };
12987
12988 this.getValue = function getValue_propertyIndexed() {
12989 return nodeProperty[ this.propertyIndex ];
12990 };
12991
12992 }
12993
12994 else if ( nodeProperty.copy ) {
12995
12996 this.setValue = function setValue_propertyObject( value ) {
12997 if ( ! this.equalsValue( nodeProperty, value ) ) {
12998 nodeProperty.copy( value );
12999 return true;
13000 }
13001 return false;
13002 }
13003
13004 this.getValue = function getValue_propertyObject() {
13005 return nodeProperty;
13006 };
13007
13008 }
13009
13010 else {
13011
13012 this.setValue = function setValue_property( value ) {
13013 if ( ! this.equalsValue( targetObject[ this.propertyName ], value ) ) {
13014 targetObject[ this.propertyName ] = value;
13015 return true;
13016 }
13017 return false;
13018 }
13019
13020 this.getValue = function getValue_property() {
13021 return targetObject[ this.propertyName ];
13022 };
13023
13024 }
13025
13026
13027 if ( targetObject.needsUpdate !== undefined ) {
13028
13029 this.triggerDirty = function triggerDirty_needsUpdate() {
13030 this.node.needsUpdate = true;
13031 }
13032
13033 } else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) {
13034
13035 this.triggerDirty = function triggerDirty_matrixWorldNeedsUpdate() {
13036 targetObject.matrixWorldNeedsUpdate = true;
13037 }
13038
13039 }
13040
13041 this.originalValue = this.getValue();
13042
13043 this.equalsValue = THREE.AnimationUtils.getEqualsFunc( this.originalValue );
13044 this.lerpValue = THREE.AnimationUtils.getLerpFunc( this.originalValue, true );
13045
13046 this.isBound = true;
13047
13048 },
13049
13050 apply: function() {
13051
13052
13053 if ( ! this.isBound ) this.bind();
13054
13055
13056 if ( this.cumulativeWeight > 0 ) {
13057
13058
13059 if ( this.cumulativeWeight < 1 ) {
13060
13061 var remainingWeight = 1 - this.cumulativeWeight;
13062 var lerpAlpha = remainingWeight / ( this.cumulativeWeight + remainingWeight );
13063 this.cumulativeValue = this.lerpValue( this.cumulativeValue, this.originalValue, lerpAlpha );
13064
13065 }
13066
13067 var valueChanged = this.setValue( this.cumulativeValue );
13068
13069 if ( valueChanged && this.triggerDirty ) {
13070 this.triggerDirty();
13071 }
13072
13073
13074 this.cumulativeValue = null;
13075 this.cumulativeWeight = 0;
13076
13077 }
13078 }
13079
13080 };
13081
13082
13083 THREE.PropertyBinding.parseTrackName = function( trackName ) {
13084
13085
13086
13087
13088
13089
13090
13091
13092
13093
13094
13095
13096 var re = /^(([\w]+\/)*)([\w-\d]+)?(\.([\w]+)(\[([\w\d\[\]\_. ]+)\])?)?(\.([\w.]+)(\[([\w\d\[\]\_. ]+)\])?)$/;
13097 var matches = re.exec(trackName);
13098
13099 if ( ! matches ) {
13100 throw new Error( "cannot parse trackName at all: " + trackName );
13101 }
13102
13103 if (matches.index === re.lastIndex) {
13104 re.lastIndex++;
13105 }
13106
13107 var results = {
13108 directoryName: matches[1],
13109 nodeName: matches[3],
13110 objectName: matches[5],
13111 objectIndex: matches[7],
13112 propertyName: matches[9],
13113 propertyIndex: matches[11]
13114 };
13115
13116 if ( results.propertyName === null || results.propertyName.length === 0 ) {
13117 throw new Error( "can not parse propertyName from trackName: " + trackName );
13118 }
13119
13120 return results;
13121
13122 };
13123
13124 THREE.PropertyBinding.findNode = function( root, nodeName ) {
13125
13126 function searchSkeleton( skeleton ) {
13127
13128 for ( var i = 0; i < skeleton.bones.length; i ++ ) {
13129
13130 var bone = skeleton.bones[i];
13131
13132 if ( bone.name === nodeName ) {
13133
13134 return bone;
13135
13136 }
13137 }
13138
13139 return null;
13140
13141 }
13142
13143 function searchNodeSubtree( children ) {
13144
13145 for ( var i = 0; i < children.length; i ++ ) {
13146
13147 var childNode = children[i];
13148
13149 if ( childNode.name === nodeName || childNode.uuid === nodeName ) {
13150
13151 return childNode;
13152
13153 }
13154
13155 var result = searchNodeSubtree( childNode.children );
13156
13157 if ( result ) return result;
13158
13159 }
13160
13161 return null;
13162
13163 }
13164
13165
13166
13167 if ( ! nodeName || nodeName === "" || nodeName === "root" || nodeName === "." || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {
13168
13169 return root;
13170
13171 }
13172
13173
13174 if ( root.skeleton ) {
13175
13176 var bone = searchSkeleton( root.skeleton );
13177
13178 if ( bone ) {
13179
13180 return bone;
13181
13182 }
13183 }
13184
13185
13186 if ( root.children ) {
13187
13188 var subTreeNode = searchNodeSubtree( root.children );
13189
13190 if ( subTreeNode ) {
13191
13192 return subTreeNode;
13193
13194 }
13195
13196 }
13197
13198 return null;
13199 }
13200
13201
13202
13211 THREE.VectorKeyframeTrack = function ( name, keys ) {
13212
13213 THREE.KeyframeTrack.call( this, name, keys );
13214
13215
13216 this.result = this.keys[0].value.clone();
13217
13218 };
13219
13220 THREE.VectorKeyframeTrack.prototype = Object.create( THREE.KeyframeTrack.prototype );
13221
13222 THREE.VectorKeyframeTrack.prototype.constructor = THREE.VectorKeyframeTrack;
13223
13224 THREE.VectorKeyframeTrack.prototype.setResult = function( value ) {
13225
13226 this.result.copy( value );
13227
13228 };
13229
13230
13231
13232 THREE.VectorKeyframeTrack.prototype.lerpValues = function( value0, value1, alpha ) {
13233
13234 return value0.lerp( value1, alpha );
13235
13236 };
13237
13238 THREE.VectorKeyframeTrack.prototype.compareValues = function( value0, value1 ) {
13239
13240 return value0.equals( value1 );
13241
13242 };
13243
13244 THREE.VectorKeyframeTrack.prototype.clone = function() {
13245
13246 var clonedKeys = [];
13247
13248 for ( var i = 0; i < this.keys.length; i ++ ) {
13249
13250 var key = this.keys[i];
13251 clonedKeys.push( {
13252 time: key.time,
13253 value: key.value.clone()
13254 } );
13255 }
13256
13257 return new THREE.VectorKeyframeTrack( this.name, clonedKeys );
13258
13259 };
13260
13261 THREE.VectorKeyframeTrack.parse = function( json ) {
13262
13263 var elementCount = json.keys[0].value.length;
13264 var valueType = THREE[ 'Vector' + elementCount ];
13265
13266 var keys = [];
13267
13268 for ( var i = 0; i < json.keys.length; i ++ ) {
13269 var jsonKey = json.keys[i];
13270 keys.push( {
13271 value: new valueType().fromArray( jsonKey.value ),
13272 time: jsonKey.time
13273 } );
13274 }
13275
13276 return new THREE.VectorKeyframeTrack( json.name, keys );
13277
13278 };
13279
13280
13281
13290 THREE.QuaternionKeyframeTrack = function ( name, keys ) {
13291
13292 THREE.KeyframeTrack.call( this, name, keys );
13293
13294
13295 this.result = this.keys[0].value.clone();
13296
13297 };
13298
13299 THREE.QuaternionKeyframeTrack.prototype = Object.create( THREE.KeyframeTrack.prototype );
13300
13301 THREE.QuaternionKeyframeTrack.prototype.constructor = THREE.QuaternionKeyframeTrack;
13302
13303 THREE.QuaternionKeyframeTrack.prototype.setResult = function( value ) {
13304
13305 this.result.copy( value );
13306
13307 };
13308
13309
13310
13311 THREE.QuaternionKeyframeTrack.prototype.lerpValues = function( value0, value1, alpha ) {
13312
13313 return value0.slerp( value1, alpha );
13314
13315 };
13316
13317 THREE.QuaternionKeyframeTrack.prototype.compareValues = function( value0, value1 ) {
13318
13319 return value0.equals( value1 );
13320
13321 };
13322
13323 THREE.QuaternionKeyframeTrack.prototype.multiply = function( quat ) {
13324
13325 for ( var i = 0; i < this.keys.length; i ++ ) {
13326
13327 this.keys[i].value.multiply( quat );
13328
13329 }
13330
13331 return this;
13332
13333 };
13334
13335 THREE.QuaternionKeyframeTrack.prototype.clone = function() {
13336
13337 var clonedKeys = [];
13338
13339 for ( var i = 0; i < this.keys.length; i ++ ) {
13340
13341 var key = this.keys[i];
13342 clonedKeys.push( {
13343 time: key.time,
13344 value: key.value.clone()
13345 } );
13346 }
13347
13348 return new THREE.QuaternionKeyframeTrack( this.name, clonedKeys );
13349
13350 };
13351
13352 THREE.QuaternionKeyframeTrack.parse = function( json ) {
13353
13354 var keys = [];
13355
13356 for ( var i = 0; i < json.keys.length; i ++ ) {
13357 var jsonKey = json.keys[i];
13358 keys.push( {
13359 value: new THREE.Quaternion().fromArray( jsonKey.value ),
13360 time: jsonKey.time
13361 } );
13362 }
13363
13364 return new THREE.QuaternionKeyframeTrack( json.name, keys );
13365
13366 };
13367
13368
13369
13378 THREE.StringKeyframeTrack = function ( name, keys ) {
13379
13380 THREE.KeyframeTrack.call( this, name, keys );
13381
13382
13383 this.result = this.keys[0].value;
13384
13385 };
13386
13387 THREE.StringKeyframeTrack.prototype = Object.create( THREE.KeyframeTrack.prototype );
13388
13389 THREE.StringKeyframeTrack.prototype.constructor = THREE.StringKeyframeTrack;
13390
13391 THREE.StringKeyframeTrack.prototype.setResult = function( value ) {
13392
13393 this.result = value;
13394
13395 };
13396
13397
13398
13399 THREE.StringKeyframeTrack.prototype.lerpValues = function( value0, value1, alpha ) {
13400
13401 return ( alpha < 1.0 ) ? value0 : value1;
13402
13403 };
13404
13405 THREE.StringKeyframeTrack.prototype.compareValues = function( value0, value1 ) {
13406
13407 return ( value0 === value1 );
13408
13409 };
13410
13411 THREE.StringKeyframeTrack.prototype.clone = function() {
13412
13413 var clonedKeys = [];
13414
13415 for ( var i = 0; i < this.keys.length; i ++ ) {
13416
13417 var key = this.keys[i];
13418 clonedKeys.push( {
13419 time: key.time,
13420 value: key.value
13421 } );
13422 }
13423
13424 return new THREE.StringKeyframeTrack( this.name, clonedKeys );
13425
13426 };
13427
13428 THREE.StringKeyframeTrack.parse = function( json ) {
13429
13430 return new THREE.StringKeyframeTrack( json.name, json.keys );
13431
13432 };
13433
13434
13435
13444 THREE.BooleanKeyframeTrack = function ( name, keys ) {
13445
13446 THREE.KeyframeTrack.call( this, name, keys );
13447
13448
13449 this.result = this.keys[0].value;
13450
13451 };
13452
13453 THREE.BooleanKeyframeTrack.prototype = Object.create( THREE.KeyframeTrack.prototype );
13454
13455 THREE.BooleanKeyframeTrack.prototype.constructor = THREE.BooleanKeyframeTrack;
13456
13457 THREE.BooleanKeyframeTrack.prototype.setResult = function( value ) {
13458
13459 this.result = value;
13460
13461 };
13462
13463
13464
13465 THREE.BooleanKeyframeTrack.prototype.lerpValues = function( value0, value1, alpha ) {
13466
13467 return ( alpha < 1.0 ) ? value0 : value1;
13468
13469 };
13470
13471 THREE.BooleanKeyframeTrack.prototype.compareValues = function( value0, value1 ) {
13472
13473 return ( value0 === value1 );
13474
13475 };
13476
13477 THREE.BooleanKeyframeTrack.prototype.clone = function() {
13478
13479 var clonedKeys = [];
13480
13481 for ( var i = 0; i < this.keys.length; i ++ ) {
13482
13483 var key = this.keys[i];
13484 clonedKeys.push( {
13485 time: key.time,
13486 value: key.value
13487 } );
13488 }
13489
13490 return new THREE.BooleanKeyframeTrack( this.name, clonedKeys );
13491
13492 };
13493
13494 THREE.BooleanKeyframeTrack.parse = function( json ) {
13495
13496 return new THREE.BooleanKeyframeTrack( json.name, json.keys );
13497
13498 };
13499
13500
13501
13510 THREE.NumberKeyframeTrack = function ( name, keys ) {
13511
13512 THREE.KeyframeTrack.call( this, name, keys );
13513
13514
13515 this.result = this.keys[0].value;
13516
13517 };
13518
13519 THREE.NumberKeyframeTrack.prototype = Object.create( THREE.KeyframeTrack.prototype );
13520
13521 THREE.NumberKeyframeTrack.prototype.constructor = THREE.NumberKeyframeTrack;
13522
13523 THREE.NumberKeyframeTrack.prototype.setResult = function( value ) {
13524
13525 this.result = value;
13526
13527 };
13528
13529
13530
13531 THREE.NumberKeyframeTrack.prototype.lerpValues = function( value0, value1, alpha ) {
13532
13533 return value0 * ( 1 - alpha ) + value1 * alpha;
13534
13535 };
13536
13537 THREE.NumberKeyframeTrack.prototype.compareValues = function( value0, value1 ) {
13538
13539 return ( value0 === value1 );
13540
13541 };
13542
13543 THREE.NumberKeyframeTrack.prototype.clone = function() {
13544
13545 var clonedKeys = [];
13546
13547 for ( var i = 0; i < this.keys.length; i ++ ) {
13548
13549 var key = this.keys[i];
13550 clonedKeys.push( {
13551 time: key.time,
13552 value: key.value
13553 } );
13554 }
13555
13556 return new THREE.NumberKeyframeTrack( this.name, clonedKeys );
13557
13558 };
13559
13560 THREE.NumberKeyframeTrack.parse = function( json ) {
13561
13562 return new THREE.NumberKeyframeTrack( json.name, json.keys );
13563
13564 };
13565
13566
13567
13574 THREE.Camera = function () {
13575
13576 THREE.Object3D.call( this );
13577
13578 this.type = 'Camera';
13579
13580 this.matrixWorldInverse = new THREE.Matrix4();
13581 this.projectionMatrix = new THREE.Matrix4();
13582
13583 };
13584
13585 THREE.Camera.prototype = Object.create( THREE.Object3D.prototype );
13586 THREE.Camera.prototype.constructor = THREE.Camera;
13587
13588 THREE.Camera.prototype.getWorldDirection = function () {
13589
13590 var quaternion = new THREE.Quaternion();
13591
13592 return function ( optionalTarget ) {
13593
13594 var result = optionalTarget || new THREE.Vector3();
13595
13596 this.getWorldQuaternion( quaternion );
13597
13598 return result.set( 0, 0, - 1 ).applyQuaternion( quaternion );
13599
13600 };
13601
13602 }();
13603
13604 THREE.Camera.prototype.lookAt = function () {
13605
13606
13607
13608 var m1 = new THREE.Matrix4();
13609
13610 return function ( vector ) {
13611
13612 m1.lookAt( this.position, vector, this.up );
13613
13614 this.quaternion.setFromRotationMatrix( m1 );
13615
13616 };
13617
13618 }();
13619
13620 THREE.Camera.prototype.clone = function () {
13621
13622 return new this.constructor().copy( this );
13623
13624 };
13625
13626 THREE.Camera.prototype.copy = function ( source ) {
13627
13628 THREE.Object3D.prototype.copy.call( this, source );
13629
13630 this.matrixWorldInverse.copy( source.matrixWorldInverse );
13631 this.projectionMatrix.copy( source.projectionMatrix );
13632
13633 return this;
13634
13635 };
13636
13637
13638
13646 THREE.CubeCamera = function ( near, far, cubeResolution ) {
13647
13648 THREE.Object3D.call( this );
13649
13650 this.type = 'CubeCamera';
13651
13652 var fov = 90, aspect = 1;
13653
13654 var cameraPX = new THREE.PerspectiveCamera( fov, aspect, near, far );
13655 cameraPX.up.set( 0, - 1, 0 );
13656 cameraPX.lookAt( new THREE.Vector3( 1, 0, 0 ) );
13657 this.add( cameraPX );
13658
13659 var cameraNX = new THREE.PerspectiveCamera( fov, aspect, near, far );
13660 cameraNX.up.set( 0, - 1, 0 );
13661 cameraNX.lookAt( new THREE.Vector3( - 1, 0, 0 ) );
13662 this.add( cameraNX );
13663
13664 var cameraPY = new THREE.PerspectiveCamera( fov, aspect, near, far );
13665 cameraPY.up.set( 0, 0, 1 );
13666 cameraPY.lookAt( new THREE.Vector3( 0, 1, 0 ) );
13667 this.add( cameraPY );
13668
13669 var cameraNY = new THREE.PerspectiveCamera( fov, aspect, near, far );
13670 cameraNY.up.set( 0, 0, - 1 );
13671 cameraNY.lookAt( new THREE.Vector3( 0, - 1, 0 ) );
13672 this.add( cameraNY );
13673
13674 var cameraPZ = new THREE.PerspectiveCamera( fov, aspect, near, far );
13675 cameraPZ.up.set( 0, - 1, 0 );
13676 cameraPZ.lookAt( new THREE.Vector3( 0, 0, 1 ) );
13677 this.add( cameraPZ );
13678
13679 var cameraNZ = new THREE.PerspectiveCamera( fov, aspect, near, far );
13680 cameraNZ.up.set( 0, - 1, 0 );
13681 cameraNZ.lookAt( new THREE.Vector3( 0, 0, - 1 ) );
13682 this.add( cameraNZ );
13683
13684 this.renderTarget = new THREE.WebGLRenderTargetCube( cubeResolution, cubeResolution, { format: THREE.RGBFormat, magFilter: THREE.LinearFilter, minFilter: THREE.LinearFilter } );
13685
13686 this.updateCubeMap = function ( renderer, scene ) {
13687
13688 if ( this.parent === null ) this.updateMatrixWorld();
13689
13690 var renderTarget = this.renderTarget;
13691 var generateMipmaps = renderTarget.texture.generateMipmaps;
13692
13693 renderTarget.texture.generateMipmaps = false;
13694
13695 renderTarget.activeCubeFace = 0;
13696 renderer.render( scene, cameraPX, renderTarget );
13697
13698 renderTarget.activeCubeFace = 1;
13699 renderer.render( scene, cameraNX, renderTarget );
13700
13701 renderTarget.activeCubeFace = 2;
13702 renderer.render( scene, cameraPY, renderTarget );
13703
13704 renderTarget.activeCubeFace = 3;
13705 renderer.render( scene, cameraNY, renderTarget );
13706
13707 renderTarget.activeCubeFace = 4;
13708 renderer.render( scene, cameraPZ, renderTarget );
13709
13710 renderTarget.texture.generateMipmaps = generateMipmaps;
13711
13712 renderTarget.activeCubeFace = 5;
13713 renderer.render( scene, cameraNZ, renderTarget );
13714
13715 renderer.setRenderTarget( null );
13716
13717 };
13718
13719 };
13720
13721 THREE.CubeCamera.prototype = Object.create( THREE.Object3D.prototype );
13722 THREE.CubeCamera.prototype.constructor = THREE.CubeCamera;
13723
13724
13725
13730 THREE.OrthographicCamera = function ( left, right, top, bottom, near, far ) {
13731
13732 THREE.Camera.call( this );
13733
13734 this.type = 'OrthographicCamera';
13735
13736 this.zoom = 1;
13737
13738 this.left = left;
13739 this.right = right;
13740 this.top = top;
13741 this.bottom = bottom;
13742
13743 this.near = ( near !== undefined ) ? near : 0.1;
13744 this.far = ( far !== undefined ) ? far : 2000;
13745
13746 this.updateProjectionMatrix();
13747
13748 };
13749
13750 THREE.OrthographicCamera.prototype = Object.create( THREE.Camera.prototype );
13751 THREE.OrthographicCamera.prototype.constructor = THREE.OrthographicCamera;
13752
13753 THREE.OrthographicCamera.prototype.updateProjectionMatrix = function () {
13754
13755 var dx = ( this.right - this.left ) / ( 2 * this.zoom );
13756 var dy = ( this.top - this.bottom ) / ( 2 * this.zoom );
13757 var cx = ( this.right + this.left ) / 2;
13758 var cy = ( this.top + this.bottom ) / 2;
13759
13760 this.projectionMatrix.makeOrthographic( cx - dx, cx + dx, cy + dy, cy - dy, this.near, this.far );
13761
13762 };
13763
13764 THREE.OrthographicCamera.prototype.copy = function ( source ) {
13765
13766 THREE.Camera.prototype.copy.call( this, source );
13767
13768 this.left = source.left;
13769 this.right = source.right;
13770 this.top = source.top;
13771 this.bottom = source.bottom;
13772 this.near = source.near;
13773 this.far = source.far;
13774
13775 this.zoom = source.zoom;
13776
13777 return this;
13778
13779 };
13780
13781 THREE.OrthographicCamera.prototype.toJSON = function ( meta ) {
13782
13783 var data = THREE.Object3D.prototype.toJSON.call( this, meta );
13784
13785 data.object.zoom = this.zoom;
13786 data.object.left = this.left;
13787 data.object.right = this.right;
13788 data.object.top = this.top;
13789 data.object.bottom = this.bottom;
13790 data.object.near = this.near;
13791 data.object.far = this.far;
13792
13793 return data;
13794
13795 };
13796
13797
13798
13805 THREE.PerspectiveCamera = function ( fov, aspect, near, far ) {
13806
13807 THREE.Camera.call( this );
13808
13809 this.type = 'PerspectiveCamera';
13810
13811 this.zoom = 1;
13812
13813 this.fov = fov !== undefined ? fov : 50;
13814 this.aspect = aspect !== undefined ? aspect : 1;
13815 this.near = near !== undefined ? near : 0.1;
13816 this.far = far !== undefined ? far : 2000;
13817
13818 this.updateProjectionMatrix();
13819
13820 };
13821
13822 THREE.PerspectiveCamera.prototype = Object.create( THREE.Camera.prototype );
13823 THREE.PerspectiveCamera.prototype.constructor = THREE.PerspectiveCamera;
13824
13825
13832 THREE.PerspectiveCamera.prototype.setLens = function ( focalLength, frameHeight ) {
13833
13834 if ( frameHeight === undefined ) frameHeight = 24;
13835
13836 this.fov = 2 * THREE.Math.radToDeg( Math.atan( frameHeight / ( focalLength * 2 ) ) );
13837 this.updateProjectionMatrix();
13838
13839 };
13840
13841
13878 THREE.PerspectiveCamera.prototype.setViewOffset = function ( fullWidth, fullHeight, x, y, width, height ) {
13879
13880 this.fullWidth = fullWidth;
13881 this.fullHeight = fullHeight;
13882 this.x = x;
13883 this.y = y;
13884 this.width = width;
13885 this.height = height;
13886
13887 this.updateProjectionMatrix();
13888
13889 };
13890
13891
13892 THREE.PerspectiveCamera.prototype.updateProjectionMatrix = function () {
13893
13894 var fov = THREE.Math.radToDeg( 2 * Math.atan( Math.tan( THREE.Math.degToRad( this.fov ) * 0.5 ) / this.zoom ) );
13895
13896 if ( this.fullWidth ) {
13897
13898 var aspect = this.fullWidth / this.fullHeight;
13899 var top = Math.tan( THREE.Math.degToRad( fov * 0.5 ) ) * this.near;
13900 var bottom = - top;
13901 var left = aspect * bottom;
13902 var right = aspect * top;
13903 var width = Math.abs( right - left );
13904 var height = Math.abs( top - bottom );
13905
13906 this.projectionMatrix.makeFrustum(
13907 left + this.x * width / this.fullWidth,
13908 left + ( this.x + this.width ) * width / this.fullWidth,
13909 top - ( this.y + this.height ) * height / this.fullHeight,
13910 top - this.y * height / this.fullHeight,
13911 this.near,
13912 this.far
13913 );
13914
13915 } else {
13916
13917 this.projectionMatrix.makePerspective( fov, this.aspect, this.near, this.far );
13918
13919 }
13920
13921 };
13922
13923 THREE.PerspectiveCamera.prototype.copy = function ( source ) {
13924
13925 THREE.Camera.prototype.copy.call( this, source );
13926
13927 this.fov = source.fov;
13928 this.aspect = source.aspect;
13929 this.near = source.near;
13930 this.far = source.far;
13931
13932 this.zoom = source.zoom;
13933
13934 return this;
13935
13936 };
13937
13938 THREE.PerspectiveCamera.prototype.toJSON = function ( meta ) {
13939
13940 var data = THREE.Object3D.prototype.toJSON.call( this, meta );
13941
13942 data.object.zoom = this.zoom;
13943 data.object.fov = this.fov;
13944 data.object.aspect = this.aspect;
13945 data.object.near = this.near;
13946 data.object.far = this.far;
13947
13948 return data;
13949
13950 };
13951
13952
13953
13959 THREE.Light = function ( color ) {
13960
13961 THREE.Object3D.call( this );
13962
13963 this.type = 'Light';
13964
13965 this.color = new THREE.Color( color );
13966
13967 this.receiveShadow = undefined;
13968
13969 };
13970
13971 THREE.Light.prototype = Object.create( THREE.Object3D.prototype );
13972 THREE.Light.prototype.constructor = THREE.Light;
13973
13974 Object.defineProperties( THREE.Light.prototype, {
13975 onlyShadow: {
13976 set: function ( value ) {
13977 console.warn( 'THREE.Light: .onlyShadow has been removed.' );
13978 }
13979 },
13980 shadowCameraFov: {
13981 set: function ( value ) {
13982 this.shadow.camera.fov = value;
13983 }
13984 },
13985 shadowCameraLeft: {
13986 set: function ( value ) {
13987 this.shadow.camera.left = value;
13988 }
13989 },
13990 shadowCameraRight: {
13991 set: function ( value ) {
13992 this.shadow.camera.right = value;
13993 }
13994 },
13995 shadowCameraTop: {
13996 set: function ( value ) {
13997 this.shadow.camera.top = value;
13998 }
13999 },
14000 shadowCameraBottom: {
14001 set: function ( value ) {
14002 this.shadow.camera.bottom = value;
14003 }
14004 },
14005 shadowCameraNear: {
14006 set: function ( value ) {
14007 this.shadow.camera.near = value;
14008 }
14009 },
14010 shadowCameraFar: {
14011 set: function ( value ) {
14012 this.shadow.camera.far = value;
14013 }
14014 },
14015 shadowCameraVisible: {
14016 set: function ( value ) {
14017 console.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow ) instead.' );
14018 }
14019 },
14020 shadowBias: {
14021 set: function ( value ) {
14022 this.shadow.bias = value;
14023 }
14024 },
14025 shadowDarkness: {
14026 set: function ( value ) {
14027 this.shadow.darkness = value;
14028 }
14029 },
14030 shadowMapWidth: {
14031 set: function ( value ) {
14032 this.shadow.mapSize.width = value;
14033 }
14034 },
14035 shadowMapHeight: {
14036 set: function ( value ) {
14037 this.shadow.mapSize.height = value;
14038 }
14039 }
14040 } );
14041
14042 THREE.Light.prototype.copy = function ( source ) {
14043
14044 THREE.Object3D.prototype.copy.call( this, source );
14045
14046 this.color.copy( source.color );
14047
14048 return this;
14049
14050 };
14051
14052 THREE.Light.prototype.toJSON = function ( meta ) {
14053
14054 var data = THREE.Object3D.prototype.toJSON.call( this, meta );
14055
14056 data.object.color = this.color.getHex();
14057 if ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();
14058
14059 if ( this.intensity !== undefined ) data.object.intensity = this.intensity;
14060 if ( this.distance !== undefined ) data.object.distance = this.distance;
14061 if ( this.angle !== undefined ) data.object.angle = this.angle;
14062 if ( this.decay !== undefined ) data.object.decay = this.decay;
14063 if ( this.exponent !== undefined ) data.object.exponent = this.exponent;
14064
14065 return data;
14066
14067 };
14068
14069
14070
14075 THREE.LightShadow = function ( camera ) {
14076
14077 this.camera = camera;
14078
14079 this.bias = 0;
14080 this.darkness = 1;
14081
14082 this.mapSize = new THREE.Vector2( 512, 512 );
14083
14084 this.map = null;
14085 this.matrix = null;
14086
14087 };
14088
14089 THREE.LightShadow.prototype = {
14090
14091 constructor: THREE.LightShadow,
14092
14093 copy: function ( source ) {
14094
14095 this.camera = source.camera.clone();
14096
14097 this.bias = source.bias;
14098 this.darkness = source.darkness;
14099
14100 this.mapSize.copy( source.mapSize );
14101
14102 },
14103
14104 clone: function () {
14105
14106 return new this.constructor().copy( this );
14107
14108 }
14109
14110 };
14111
14112
14113
14118 THREE.AmbientLight = function ( color ) {
14119
14120 THREE.Light.call( this, color );
14121
14122 this.type = 'AmbientLight';
14123
14124 this.castShadow = undefined;
14125
14126 };
14127
14128 THREE.AmbientLight.prototype = Object.create( THREE.Light.prototype );
14129 THREE.AmbientLight.prototype.constructor = THREE.AmbientLight;
14130
14131
14132
14138 THREE.DirectionalLight = function ( color, intensity ) {
14139
14140 THREE.Light.call( this, color );
14141
14142 this.type = 'DirectionalLight';
14143
14144 this.position.set( 0, 1, 0 );
14145 this.updateMatrix();
14146
14147 this.target = new THREE.Object3D();
14148
14149 this.intensity = ( intensity !== undefined ) ? intensity : 1;
14150
14151 this.shadow = new THREE.LightShadow( new THREE.OrthographicCamera( - 500, 500, 500, - 500, 50, 5000 ) );
14152
14153 };
14154
14155 THREE.DirectionalLight.prototype = Object.create( THREE.Light.prototype );
14156 THREE.DirectionalLight.prototype.constructor = THREE.DirectionalLight;
14157
14158 THREE.DirectionalLight.prototype.copy = function ( source ) {
14159
14160 THREE.Light.prototype.copy.call( this, source );
14161
14162 this.intensity = source.intensity;
14163 this.target = source.target.clone();
14164
14165 this.shadow = source.shadow.clone();
14166
14167 return this;
14168
14169 };
14170
14171
14172
14177 THREE.HemisphereLight = function ( skyColor, groundColor, intensity ) {
14178
14179 THREE.Light.call( this, skyColor );
14180
14181 this.type = 'HemisphereLight';
14182
14183 this.castShadow = undefined;
14184
14185 this.position.set( 0, 1, 0 );
14186 this.updateMatrix();
14187
14188 this.groundColor = new THREE.Color( groundColor );
14189 this.intensity = ( intensity !== undefined ) ? intensity : 1;
14190
14191 };
14192
14193 THREE.HemisphereLight.prototype = Object.create( THREE.Light.prototype );
14194 THREE.HemisphereLight.prototype.constructor = THREE.HemisphereLight;
14195
14196 THREE.HemisphereLight.prototype.copy = function ( source ) {
14197
14198 THREE.Light.prototype.copy.call( this, source );
14199
14200 this.groundColor.copy( source.groundColor );
14201 this.intensity = source.intensity;
14202
14203 return this;
14204
14205 };
14206
14207
14208
14214 THREE.PointLight = function ( color, intensity, distance, decay ) {
14215
14216 THREE.Light.call( this, color );
14217
14218 this.type = 'PointLight';
14219
14220 this.intensity = ( intensity !== undefined ) ? intensity : 1;
14221 this.distance = ( distance !== undefined ) ? distance : 0;
14222 this.decay = ( decay !== undefined ) ? decay : 1;
14223
14224 this.shadow = new THREE.LightShadow( new THREE.PerspectiveCamera( 90, 1, 1, 500 ) );
14225
14226 };
14227
14228 THREE.PointLight.prototype = Object.create( THREE.Light.prototype );
14229 THREE.PointLight.prototype.constructor = THREE.PointLight;
14230
14231 THREE.PointLight.prototype.copy = function ( source ) {
14232
14233 THREE.Light.prototype.copy.call( this, source );
14234
14235 this.intensity = source.intensity;
14236 this.distance = source.distance;
14237 this.decay = source.decay;
14238
14239 this.shadow = source.shadow.clone();
14240
14241 return this;
14242
14243 };
14244
14245
14246
14251 THREE.SpotLight = function ( color, intensity, distance, angle, exponent, decay ) {
14252
14253 THREE.Light.call( this, color );
14254
14255 this.type = 'SpotLight';
14256
14257 this.position.set( 0, 1, 0 );
14258 this.updateMatrix();
14259
14260 this.target = new THREE.Object3D();
14261
14262 this.intensity = ( intensity !== undefined ) ? intensity : 1;
14263 this.distance = ( distance !== undefined ) ? distance : 0;
14264 this.angle = ( angle !== undefined ) ? angle : Math.PI / 3;
14265 this.exponent = ( exponent !== undefined ) ? exponent : 10;
14266 this.decay = ( decay !== undefined ) ? decay : 1;
14267
14268 this.shadow = new THREE.LightShadow( new THREE.PerspectiveCamera( 50, 1, 50, 5000 ) );
14269
14270 };
14271
14272 THREE.SpotLight.prototype = Object.create( THREE.Light.prototype );
14273 THREE.SpotLight.prototype.constructor = THREE.SpotLight;
14274
14275 THREE.SpotLight.prototype.copy = function ( source ) {
14276
14277 THREE.Light.prototype.copy.call( this, source );
14278
14279 this.intensity = source.intensity;
14280 this.distance = source.distance;
14281 this.angle = source.angle;
14282 this.exponent = source.exponent;
14283 this.decay = source.decay;
14284
14285 this.target = source.target.clone();
14286
14287 this.shadow = source.shadow.clone();
14288
14289 return this;
14290
14291 };
14292
14293
14294
14299 THREE.Cache = {
14300
14301 enabled: false,
14302
14303 files: {},
14304
14305 add: function ( key, file ) {
14306
14307 if ( this.enabled === false ) return;
14308
14309
14310
14311 this.files[ key ] = file;
14312
14313 },
14314
14315 get: function ( key ) {
14316
14317 if ( this.enabled === false ) return;
14318
14319
14320
14321 return this.files[ key ];
14322
14323 },
14324
14325 remove: function ( key ) {
14326
14327 delete this.files[ key ];
14328
14329 },
14330
14331 clear: function () {
14332
14333 this.files = {};
14334
14335 }
14336
14337 };
14338
14339
14340
14345 THREE.Loader = function () {
14346
14347 this.onLoadStart = function () {};
14348 this.onLoadProgress = function () {};
14349 this.onLoadComplete = function () {};
14350
14351 };
14352
14353 THREE.Loader.prototype = {
14354
14355 constructor: THREE.Loader,
14356
14357 crossOrigin: undefined,
14358
14359 extractUrlBase: function ( url ) {
14360
14361 var parts = url.split( '/' );
14362
14363 if ( parts.length === 1 ) return './';
14364
14365 parts.pop();
14366
14367 return parts.join( '/' ) + '/';
14368
14369 },
14370
14371 initMaterials: function ( materials, texturePath, crossOrigin ) {
14372
14373 var array = [];
14374
14375 for ( var i = 0; i < materials.length; ++ i ) {
14376
14377 array[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );
14378
14379 }
14380
14381 return array;
14382
14383 },
14384
14385 createMaterial: ( function () {
14386
14387 var color, textureLoader, materialLoader;
14388
14389 return function ( m, texturePath, crossOrigin ) {
14390
14391 if ( color === undefined ) color = new THREE.Color();
14392 if ( textureLoader === undefined ) textureLoader = new THREE.TextureLoader();
14393 if ( materialLoader === undefined ) materialLoader = new THREE.MaterialLoader();
14394
14395
14396
14397 var textures = {};
14398
14399 function loadTexture( path, repeat, offset, wrap, anisotropy ) {
14400
14401 var fullPath = texturePath + path;
14402 var loader = THREE.Loader.Handlers.get( fullPath );
14403
14404 var texture;
14405
14406 if ( loader !== null ) {
14407
14408 texture = loader.load( fullPath );
14409
14410 } else {
14411
14412 textureLoader.setCrossOrigin( crossOrigin );
14413 texture = textureLoader.load( fullPath );
14414
14415 }
14416
14417 if ( repeat !== undefined ) {
14418
14419 texture.repeat.fromArray( repeat );
14420
14421 if ( repeat[ 0 ] !== 1 ) texture.wrapS = THREE.RepeatWrapping;
14422 if ( repeat[ 1 ] !== 1 ) texture.wrapT = THREE.RepeatWrapping;
14423
14424 }
14425
14426 if ( offset !== undefined ) {
14427
14428 texture.offset.fromArray( offset );
14429
14430 }
14431
14432 if ( wrap !== undefined ) {
14433
14434 if ( wrap[ 0 ] === 'repeat' ) texture.wrapS = THREE.RepeatWrapping;
14435 if ( wrap[ 0 ] === 'mirror' ) texture.wrapS = THREE.MirroredRepeatWrapping;
14436
14437 if ( wrap[ 1 ] === 'repeat' ) texture.wrapT = THREE.RepeatWrapping;
14438 if ( wrap[ 1 ] === 'mirror' ) texture.wrapT = THREE.MirroredRepeatWrapping;
14439
14440 }
14441
14442 if ( anisotropy !== undefined ) {
14443
14444 texture.anisotropy = anisotropy;
14445
14446 }
14447
14448 var uuid = THREE.Math.generateUUID();
14449
14450 textures[ uuid ] = texture;
14451
14452 return uuid;
14453
14454 }
14455
14456
14457
14458 var json = {
14459 uuid: THREE.Math.generateUUID(),
14460 type: 'MeshLambertMaterial'
14461 };
14462
14463 for ( var name in m ) {
14464
14465 var value = m[ name ];
14466
14467 switch ( name ) {
14468 case 'DbgColor':
14469 json.color = value;
14470 break;
14471 case 'DbgIndex':
14472 case 'opticalDensity':
14473 case 'illumination':
14474
14475 break;
14476 case 'DbgName':
14477 json.name = value;
14478 break;
14479 case 'blending':
14480 json.blending = THREE[ value ];
14481 break;
14482 case 'colorDiffuse':
14483 json.color = color.fromArray( value ).getHex();
14484 break;
14485 case 'colorSpecular':
14486 json.specular = color.fromArray( value ).getHex();
14487 break;
14488 case 'colorEmissive':
14489 json.emissive = color.fromArray( value ).getHex();
14490 break;
14491 case 'specularCoef':
14492 json.shininess = value;
14493 break;
14494 case 'shading':
14495 if ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';
14496 if ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';
14497 break;
14498 case 'mapDiffuse':
14499 json.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );
14500 break;
14501 case 'mapDiffuseRepeat':
14502 case 'mapDiffuseOffset':
14503 case 'mapDiffuseWrap':
14504 case 'mapDiffuseAnisotropy':
14505 break;
14506 case 'mapLight':
14507 json.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );
14508 break;
14509 case 'mapLightRepeat':
14510 case 'mapLightOffset':
14511 case 'mapLightWrap':
14512 case 'mapLightAnisotropy':
14513 break;
14514 case 'mapAO':
14515 json.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );
14516 break;
14517 case 'mapAORepeat':
14518 case 'mapAOOffset':
14519 case 'mapAOWrap':
14520 case 'mapAOAnisotropy':
14521 break;
14522 case 'mapBump':
14523 json.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );
14524 break;
14525 case 'mapBumpScale':
14526 json.bumpScale = value;
14527 break;
14528 case 'mapBumpRepeat':
14529 case 'mapBumpOffset':
14530 case 'mapBumpWrap':
14531 case 'mapBumpAnisotropy':
14532 break;
14533 case 'mapNormal':
14534 json.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );
14535 break;
14536 case 'mapNormalFactor':
14537 json.normalScale = [ value, value ];
14538 break;
14539 case 'mapNormalRepeat':
14540 case 'mapNormalOffset':
14541 case 'mapNormalWrap':
14542 case 'mapNormalAnisotropy':
14543 break;
14544 case 'mapSpecular':
14545 json.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );
14546 break;
14547 case 'mapSpecularRepeat':
14548 case 'mapSpecularOffset':
14549 case 'mapSpecularWrap':
14550 case 'mapSpecularAnisotropy':
14551 break;
14552 case 'mapAlpha':
14553 json.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );
14554 break;
14555 case 'mapAlphaRepeat':
14556 case 'mapAlphaOffset':
14557 case 'mapAlphaWrap':
14558 case 'mapAlphaAnisotropy':
14559 break;
14560 case 'flipSided':
14561 json.side = THREE.BackSide;
14562 break;
14563 case 'doubleSided':
14564 json.side = THREE.DoubleSide;
14565 break;
14566 case 'transparency':
14567 console.warn( 'THREE.Loader: transparency has been renamed to opacity' );
14568 json.opacity = value;
14569 break;
14570 case 'opacity':
14571 case 'transparent':
14572 case 'depthTest':
14573 case 'depthWrite':
14574 case 'transparent':
14575 case 'visible':
14576 case 'wireframe':
14577 json[ name ] = value;
14578 break;
14579 case 'vertexColors':
14580 if ( value === true ) json.vertexColors = THREE.VertexColors;
14581 if ( value === 'face' ) json.vertexColors = THREE.FaceColors;
14582 break;
14583 default:
14584 console.error( 'Loader.createMaterial: Unsupported', name, value );
14585 break;
14586 }
14587
14588 }
14589
14590 if ( json.type !== 'MeshPhongMaterial' ) delete json.specular;
14591 if ( json.opacity < 1 ) json.transparent = true;
14592
14593 materialLoader.setTextures( textures );
14594
14595 return materialLoader.parse( json );
14596
14597 };
14598
14599 } )()
14600
14601 };
14602
14603 THREE.Loader.Handlers = {
14604
14605 handlers: [],
14606
14607 add: function ( regex, loader ) {
14608
14609 this.handlers.push( regex, loader );
14610
14611 },
14612
14613 get: function ( file ) {
14614
14615 var handlers = this.handlers;
14616
14617 for ( var i = 0, l = handlers.length; i < l; i += 2 ) {
14618
14619 var regex = handlers[ i ];
14620 var loader = handlers[ i + 1 ];
14621
14622 if ( regex.test( file ) ) {
14623
14624 return loader;
14625
14626 }
14627
14628 }
14629
14630 return null;
14631
14632 }
14633
14634 };
14635
14636
14637
14642 THREE.XHRLoader = function ( manager ) {
14643
14644 this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
14645
14646 };
14647
14648 THREE.XHRLoader.prototype = {
14649
14650 constructor: THREE.XHRLoader,
14651
14652 load: function ( url, onLoad, onProgress, onError ) {
14653
14654 var scope = this;
14655
14656 var cached = THREE.Cache.get( url );
14657
14658 if ( cached !== undefined ) {
14659
14660 if ( onLoad ) {
14661
14662 setTimeout( function () {
14663
14664 onLoad( cached );
14665
14666 }, 0 );
14667
14668 }
14669
14670 return cached;
14671
14672 }
14673
14674 var request = new XMLHttpRequest();
14675 request.open( 'GET', url, true );
14676
14677 request.addEventListener( 'load', function ( event ) {
14678
14679 var response = event.target.response;
14680
14681 THREE.Cache.add( url, response );
14682
14683 if ( onLoad ) onLoad( response );
14684
14685 scope.manager.itemEnd( url );
14686
14687 }, false );
14688
14689 if ( onProgress !== undefined ) {
14690
14691 request.addEventListener( 'progress', function ( event ) {
14692
14693 onProgress( event );
14694
14695 }, false );
14696
14697 }
14698
14699 request.addEventListener( 'error', function ( event ) {
14700
14701 if ( onError ) onError( event );
14702
14703 scope.manager.itemError( url );
14704
14705 }, false );
14706
14707 if ( this.crossOrigin !== undefined ) request.crossOrigin = this.crossOrigin;
14708 if ( this.responseType !== undefined ) request.responseType = this.responseType;
14709 if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;
14710
14711 request.send( null );
14712
14713 scope.manager.itemStart( url );
14714
14715 return request;
14716
14717 },
14718
14719 setResponseType: function ( value ) {
14720
14721 this.responseType = value;
14722
14723 },
14724
14725 setCrossOrigin: function ( value ) {
14726
14727 this.crossOrigin = value;
14728
14729 },
14730
14731 setWithCredentials: function ( value ) {
14732
14733 this.withCredentials = value;
14734
14735 }
14736
14737 };
14738
14739
14740
14745 THREE.ImageLoader = function ( manager ) {
14746
14747 this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
14748
14749 };
14750
14751 THREE.ImageLoader.prototype = {
14752
14753 constructor: THREE.ImageLoader,
14754
14755 load: function ( url, onLoad, onProgress, onError ) {
14756
14757 var scope = this;
14758
14759 var cached = THREE.Cache.get( url );
14760
14761 if ( cached !== undefined ) {
14762
14763 scope.manager.itemStart( url );
14764
14765 if ( onLoad ) {
14766
14767 setTimeout( function () {
14768
14769 onLoad( cached );
14770
14771 scope.manager.itemEnd( url );
14772
14773 }, 0 );
14774
14775 } else {
14776
14777 scope.manager.itemEnd( url );
14778
14779 }
14780
14781 return cached;
14782
14783 }
14784
14785 var image = document.createElement( 'img' );
14786
14787 image.addEventListener( 'load', function ( event ) {
14788
14789 THREE.Cache.add( url, this );
14790
14791 if ( onLoad ) onLoad( this );
14792
14793 scope.manager.itemEnd( url );
14794
14795 }, false );
14796
14797 if ( onProgress !== undefined ) {
14798
14799 image.addEventListener( 'progress', function ( event ) {
14800
14801 onProgress( event );
14802
14803 }, false );
14804
14805 }
14806
14807 image.addEventListener( 'error', function ( event ) {
14808
14809 if ( onError ) onError( event );
14810
14811 scope.manager.itemError( url );
14812
14813 }, false );
14814
14815 if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;
14816
14817 scope.manager.itemStart( url );
14818
14819 image.src = url;
14820
14821 return image;
14822
14823 },
14824
14825 setCrossOrigin: function ( value ) {
14826
14827 this.crossOrigin = value;
14828
14829 }
14830
14831 };
14832
14833
14834
14840 THREE.JSONLoader = function ( manager ) {
14841
14842 if ( typeof manager === 'boolean' ) {
14843
14844 console.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );
14845 manager = undefined;
14846
14847 }
14848
14849 this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
14850
14851 this.withCredentials = false;
14852
14853 };
14854
14855 THREE.JSONLoader.prototype = {
14856
14857 constructor: THREE.JSONLoader,
14858
14859
14860
14861 get statusDomElement () {
14862
14863 if ( this._statusDomElement === undefined ) {
14864
14865 this._statusDomElement = document.createElement( 'div' );
14866
14867 }
14868
14869 console.warn( 'THREE.JSONLoader: .statusDomElement has been removed.' );
14870 return this._statusDomElement;
14871
14872 },
14873
14874 load: function( url, onLoad, onProgress, onError ) {
14875
14876 var scope = this;
14877
14878 var texturePath = this.texturePath && ( typeof this.texturePath === "string" ) ? this.texturePath : THREE.Loader.prototype.extractUrlBase( url );
14879
14880 var loader = new THREE.XHRLoader( this.manager );
14881 loader.setCrossOrigin( this.crossOrigin );
14882 loader.setWithCredentials( this.withCredentials );
14883 loader.load( url, function ( text ) {
14884
14885 var json = JSON.parse( text );
14886 var metadata = json.metadata;
14887
14888 if ( metadata !== undefined ) {
14889
14890 if ( metadata.type === 'object' ) {
14891
14892 console.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );
14893 return;
14894
14895 }
14896
14897 if ( metadata.type === 'scene' ) {
14898
14899 console.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );
14900 return;
14901
14902 }
14903
14904 }
14905
14906 var object = scope.parse( json, texturePath );
14907 onLoad( object.geometry, object.materials );
14908
14909 } );
14910
14911 },
14912
14913 setCrossOrigin: function ( value ) {
14914
14915 this.crossOrigin = value;
14916
14917 },
14918
14919 setTexturePath: function ( value ) {
14920
14921 this.texturePath = value;
14922
14923 },
14924
14925 parse: function ( json, texturePath ) {
14926
14927 var geometry = new THREE.Geometry(),
14928 scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;
14929
14930 parseModel( scale );
14931
14932 parseSkin();
14933 parseMorphing( scale );
14934 parseAnimations();
14935
14936 geometry.computeFaceNormals();
14937 geometry.computeBoundingSphere();
14938
14939 function parseModel( scale ) {
14940
14941 function isBitSet( value, position ) {
14942
14943 return value & ( 1 << position );
14944
14945 }
14946
14947 var i, j, fi,
14948
14949 offset, zLength,
14950
14951 colorIndex, normalIndex, uvIndex, materialIndex,
14952
14953 type,
14954 isQuad,
14955 hasMaterial,
14956 hasFaceVertexUv,
14957 hasFaceNormal, hasFaceVertexNormal,
14958 hasFaceColor, hasFaceVertexColor,
14959
14960 vertex, face, faceA, faceB, hex, normal,
14961
14962 uvLayer, uv, u, v,
14963
14964 faces = json.faces,
14965 vertices = json.vertices,
14966 normals = json.normals,
14967 colors = json.colors,
14968
14969 nUvLayers = 0;
14970
14971 if ( json.uvs !== undefined ) {
14972
14973
14974
14975 for ( i = 0; i < json.uvs.length; i ++ ) {
14976
14977 if ( json.uvs[ i ].length ) nUvLayers ++;
14978
14979 }
14980
14981 for ( i = 0; i < nUvLayers; i ++ ) {
14982
14983 geometry.faceVertexUvs[ i ] = [];
14984
14985 }
14986
14987 }
14988
14989 offset = 0;
14990 zLength = vertices.length;
14991
14992 while ( offset < zLength ) {
14993
14994 vertex = new THREE.Vector3();
14995
14996 vertex.x = vertices[ offset ++ ] * scale;
14997 vertex.y = vertices[ offset ++ ] * scale;
14998 vertex.z = vertices[ offset ++ ] * scale;
14999
15000 geometry.vertices.push( vertex );
15001
15002 }
15003
15004 offset = 0;
15005 zLength = faces.length;
15006
15007 while ( offset < zLength ) {
15008
15009 type = faces[ offset ++ ];
15010
15011
15012 isQuad = isBitSet( type, 0 );
15013 hasMaterial = isBitSet( type, 1 );
15014 hasFaceVertexUv = isBitSet( type, 3 );
15015 hasFaceNormal = isBitSet( type, 4 );
15016 hasFaceVertexNormal = isBitSet( type, 5 );
15017 hasFaceColor = isBitSet( type, 6 );
15018 hasFaceVertexColor = isBitSet( type, 7 );
15019
15020
15021
15022 if ( isQuad ) {
15023
15024 faceA = new THREE.Face3();
15025 faceA.a = faces[ offset ];
15026 faceA.b = faces[ offset + 1 ];
15027 faceA.c = faces[ offset + 3 ];
15028
15029 faceB = new THREE.Face3();
15030 faceB.a = faces[ offset + 1 ];
15031 faceB.b = faces[ offset + 2 ];
15032 faceB.c = faces[ offset + 3 ];
15033
15034 offset += 4;
15035
15036 if ( hasMaterial ) {
15037
15038 materialIndex = faces[ offset ++ ];
15039 faceA.materialIndex = materialIndex;
15040 faceB.materialIndex = materialIndex;
15041
15042 }
15043
15044
15045
15046 fi = geometry.faces.length;
15047
15048 if ( hasFaceVertexUv ) {
15049
15050 for ( i = 0; i < nUvLayers; i ++ ) {
15051
15052 uvLayer = json.uvs[ i ];
15053
15054 geometry.faceVertexUvs[ i ][ fi ] = [];
15055 geometry.faceVertexUvs[ i ][ fi + 1 ] = [];
15056
15057 for ( j = 0; j < 4; j ++ ) {
15058
15059 uvIndex = faces[ offset ++ ];
15060
15061 u = uvLayer[ uvIndex * 2 ];
15062 v = uvLayer[ uvIndex * 2 + 1 ];
15063
15064 uv = new THREE.Vector2( u, v );
15065
15066 if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );
15067 if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );
15068
15069 }
15070
15071 }
15072
15073 }
15074
15075 if ( hasFaceNormal ) {
15076
15077 normalIndex = faces[ offset ++ ] * 3;
15078
15079 faceA.normal.set(
15080 normals[ normalIndex ++ ],
15081 normals[ normalIndex ++ ],
15082 normals[ normalIndex ]
15083 );
15084
15085 faceB.normal.copy( faceA.normal );
15086
15087 }
15088
15089 if ( hasFaceVertexNormal ) {
15090
15091 for ( i = 0; i < 4; i ++ ) {
15092
15093 normalIndex = faces[ offset ++ ] * 3;
15094
15095 normal = new THREE.Vector3(
15096 normals[ normalIndex ++ ],
15097 normals[ normalIndex ++ ],
15098 normals[ normalIndex ]
15099 );
15100
15101
15102 if ( i !== 2 ) faceA.vertexNormals.push( normal );
15103 if ( i !== 0 ) faceB.vertexNormals.push( normal );
15104
15105 }
15106
15107 }
15108
15109
15110 if ( hasFaceColor ) {
15111
15112 colorIndex = faces[ offset ++ ];
15113 hex = colors[ colorIndex ];
15114
15115 faceA.color.setHex( hex );
15116 faceB.color.setHex( hex );
15117
15118 }
15119
15120
15121 if ( hasFaceVertexColor ) {
15122
15123 for ( i = 0; i < 4; i ++ ) {
15124
15125 colorIndex = faces[ offset ++ ];
15126 hex = colors[ colorIndex ];
15127
15128 if ( i !== 2 ) faceA.vertexColors.push( new THREE.Color( hex ) );
15129 if ( i !== 0 ) faceB.vertexColors.push( new THREE.Color( hex ) );
15130
15131 }
15132
15133 }
15134
15135 geometry.faces.push( faceA );
15136 geometry.faces.push( faceB );
15137
15138 } else {
15139
15140 face = new THREE.Face3();
15141 face.a = faces[ offset ++ ];
15142 face.b = faces[ offset ++ ];
15143 face.c = faces[ offset ++ ];
15144
15145 if ( hasMaterial ) {
15146
15147 materialIndex = faces[ offset ++ ];
15148 face.materialIndex = materialIndex;
15149
15150 }
15151
15152
15153
15154 fi = geometry.faces.length;
15155
15156 if ( hasFaceVertexUv ) {
15157
15158 for ( i = 0; i < nUvLayers; i ++ ) {
15159
15160 uvLayer = json.uvs[ i ];
15161
15162 geometry.faceVertexUvs[ i ][ fi ] = [];
15163
15164 for ( j = 0; j < 3; j ++ ) {
15165
15166 uvIndex = faces[ offset ++ ];
15167
15168 u = uvLayer[ uvIndex * 2 ];
15169 v = uvLayer[ uvIndex * 2 + 1 ];
15170
15171 uv = new THREE.Vector2( u, v );
15172
15173 geometry.faceVertexUvs[ i ][ fi ].push( uv );
15174
15175 }
15176
15177 }
15178
15179 }
15180
15181 if ( hasFaceNormal ) {
15182
15183 normalIndex = faces[ offset ++ ] * 3;
15184
15185 face.normal.set(
15186 normals[ normalIndex ++ ],
15187 normals[ normalIndex ++ ],
15188 normals[ normalIndex ]
15189 );
15190
15191 }
15192
15193 if ( hasFaceVertexNormal ) {
15194
15195 for ( i = 0; i < 3; i ++ ) {
15196
15197 normalIndex = faces[ offset ++ ] * 3;
15198
15199 normal = new THREE.Vector3(
15200 normals[ normalIndex ++ ],
15201 normals[ normalIndex ++ ],
15202 normals[ normalIndex ]
15203 );
15204
15205 face.vertexNormals.push( normal );
15206
15207 }
15208
15209 }
15210
15211
15212 if ( hasFaceColor ) {
15213
15214 colorIndex = faces[ offset ++ ];
15215 face.color.setHex( colors[ colorIndex ] );
15216
15217 }
15218
15219
15220 if ( hasFaceVertexColor ) {
15221
15222 for ( i = 0; i < 3; i ++ ) {
15223
15224 colorIndex = faces[ offset ++ ];
15225 face.vertexColors.push( new THREE.Color( colors[ colorIndex ] ) );
15226
15227 }
15228
15229 }
15230
15231 geometry.faces.push( face );
15232
15233 }
15234
15235 }
15236
15237 };
15238
15239 function parseSkin() {
15240
15241 var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;
15242
15243 if ( json.skinWeights ) {
15244
15245 for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {
15246
15247 var x = json.skinWeights[ i ];
15248 var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;
15249 var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;
15250 var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;
15251
15252 geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );
15253
15254 }
15255
15256 }
15257
15258 if ( json.skinIndices ) {
15259
15260 for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {
15261
15262 var a = json.skinIndices[ i ];
15263 var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;
15264 var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;
15265 var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;
15266
15267 geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );
15268
15269 }
15270
15271 }
15272
15273 geometry.bones = json.bones;
15274
15275 if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {
15276
15277 console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +
15278 geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );
15279
15280 }
15281
15282 };
15283
15284 function parseMorphing( scale ) {
15285
15286 if ( json.morphTargets !== undefined ) {
15287
15288 for ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {
15289
15290 geometry.morphTargets[ i ] = {};
15291 geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
15292 geometry.morphTargets[ i ].vertices = [];
15293
15294 var dstVertices = geometry.morphTargets[ i ].vertices;
15295 var srcVertices = json.morphTargets[ i ].vertices;
15296
15297 for ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
15298
15299 var vertex = new THREE.Vector3();
15300 vertex.x = srcVertices[ v ] * scale;
15301 vertex.y = srcVertices[ v + 1 ] * scale;
15302 vertex.z = srcVertices[ v + 2 ] * scale;
15303
15304 dstVertices.push( vertex );
15305
15306 }
15307
15308 }
15309
15310 }
15311
15312 if ( json.morphColors !== undefined && json.morphColors.length > 0 ) {
15313
15314 console.warn( 'THREE.JSONLoader: "morphColors" no longer supported. Using them as face colors.' );
15315
15316 var faces = geometry.faces;
15317 var morphColors = json.morphColors[ 0 ].colors;
15318
15319 for ( var i = 0, l = faces.length; i < l; i ++ ) {
15320
15321 faces[ i ].color.fromArray( morphColors, i * 3 );
15322
15323 }
15324
15325 }
15326
15327 }
15328
15329 function parseAnimations() {
15330
15331 var outputAnimations = [];
15332
15333
15334 var animations = [];
15335 if ( json.animation !== undefined ) {
15336 animations.push( json.animation );
15337 }
15338 if ( json.animations !== undefined ) {
15339 if ( json.animations.length ) {
15340 animations = animations.concat( json.animations );
15341 } else {
15342 animations.push( json.animations );
15343 }
15344 }
15345
15346 for ( var i = 0; i < animations.length; i ++ ) {
15347
15348 var clip = THREE.AnimationClip.parseAnimation( animations[i], geometry.bones );
15349 if ( clip ) outputAnimations.push( clip );
15350
15351 }
15352
15353
15354 if ( geometry.morphTargets ) {
15355
15356
15357 var morphAnimationClips = THREE.AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );
15358 outputAnimations = outputAnimations.concat( morphAnimationClips );
15359
15360 }
15361
15362 if ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;
15363
15364 };
15365
15366 if ( json.materials === undefined || json.materials.length === 0 ) {
15367
15368 return { geometry: geometry };
15369
15370 } else {
15371
15372 var materials = THREE.Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );
15373
15374 return { geometry: geometry, materials: materials };
15375
15376 }
15377
15378 }
15379
15380 };
15381
15382
15383
15388 THREE.LoadingManager = function ( onLoad, onProgress, onError ) {
15389
15390 var scope = this;
15391
15392 var isLoading = false, itemsLoaded = 0, itemsTotal = 0;
15393
15394 this.onStart = undefined;
15395 this.onLoad = onLoad;
15396 this.onProgress = onProgress;
15397 this.onError = onError;
15398
15399 this.itemStart = function ( url ) {
15400
15401 itemsTotal ++;
15402
15403 if ( isLoading === false ) {
15404
15405 if ( scope.onStart !== undefined ) {
15406
15407 scope.onStart( url, itemsLoaded, itemsTotal );
15408
15409 }
15410
15411 }
15412
15413 isLoading = true;
15414
15415 };
15416
15417 this.itemEnd = function ( url ) {
15418
15419 itemsLoaded ++;
15420
15421 if ( scope.onProgress !== undefined ) {
15422
15423 scope.onProgress( url, itemsLoaded, itemsTotal );
15424
15425 }
15426
15427 if ( itemsLoaded === itemsTotal ) {
15428
15429 isLoading = false;
15430
15431 if ( scope.onLoad !== undefined ) {
15432
15433 scope.onLoad();
15434
15435 }
15436
15437 }
15438
15439 };
15440
15441 this.itemError = function ( url ) {
15442
15443 if ( scope.onError !== undefined ) {
15444
15445 scope.onError( url );
15446
15447 }
15448
15449 };
15450
15451 };
15452
15453 THREE.DefaultLoadingManager = new THREE.LoadingManager();
15454
15455
15456
15461 THREE.BufferGeometryLoader = function ( manager ) {
15462
15463 this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
15464
15465 };
15466
15467 THREE.BufferGeometryLoader.prototype = {
15468
15469 constructor: THREE.BufferGeometryLoader,
15470
15471 load: function ( url, onLoad, onProgress, onError ) {
15472
15473 var scope = this;
15474
15475 var loader = new THREE.XHRLoader( scope.manager );
15476 loader.setCrossOrigin( this.crossOrigin );
15477 loader.load( url, function ( text ) {
15478
15479 onLoad( scope.parse( JSON.parse( text ) ) );
15480
15481 }, onProgress, onError );
15482
15483 },
15484
15485 setCrossOrigin: function ( value ) {
15486
15487 this.crossOrigin = value;
15488
15489 },
15490
15491 parse: function ( json ) {
15492
15493 var geometry = new THREE.BufferGeometry();
15494
15495 var index = json.data.index;
15496
15497 if ( index !== undefined ) {
15498
15499 var typedArray = new self[ index.type ]( index.array );
15500 geometry.setIndex( new THREE.BufferAttribute( typedArray, 1 ) );
15501
15502 }
15503
15504 var attributes = json.data.attributes;
15505
15506 for ( var key in attributes ) {
15507
15508 var attribute = attributes[ key ];
15509 var typedArray = new self[ attribute.type ]( attribute.array );
15510
15511 geometry.addAttribute( key, new THREE.BufferAttribute( typedArray, attribute.itemSize ) );
15512
15513 }
15514
15515 var groups = json.data.groups || json.data.drawcalls || json.data.offsets;
15516
15517 if ( groups !== undefined ) {
15518
15519 for ( var i = 0, n = groups.length; i !== n; ++ i ) {
15520
15521 var group = groups[ i ];
15522
15523 geometry.addGroup( group.start, group.count );
15524
15525 }
15526
15527 }
15528
15529 var boundingSphere = json.data.boundingSphere;
15530
15531 if ( boundingSphere !== undefined ) {
15532
15533 var center = new THREE.Vector3();
15534
15535 if ( boundingSphere.center !== undefined ) {
15536
15537 center.fromArray( boundingSphere.center );
15538
15539 }
15540
15541 geometry.boundingSphere = new THREE.Sphere( center, boundingSphere.radius );
15542
15543 }
15544
15545 return geometry;
15546
15547 }
15548
15549 };
15550
15551
15552
15557 THREE.MaterialLoader = function ( manager ) {
15558
15559 this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
15560 this.textures = {};
15561
15562 };
15563
15564 THREE.MaterialLoader.prototype = {
15565
15566 constructor: THREE.MaterialLoader,
15567
15568 load: function ( url, onLoad, onProgress, onError ) {
15569
15570 var scope = this;
15571
15572 var loader = new THREE.XHRLoader( scope.manager );
15573 loader.setCrossOrigin( this.crossOrigin );
15574 loader.load( url, function ( text ) {
15575
15576 onLoad( scope.parse( JSON.parse( text ) ) );
15577
15578 }, onProgress, onError );
15579
15580 },
15581
15582 setCrossOrigin: function ( value ) {
15583
15584 this.crossOrigin = value;
15585
15586 },
15587
15588 setTextures: function ( value ) {
15589
15590 this.textures = value;
15591
15592 },
15593
15594 getTexture: function ( name ) {
15595
15596 var textures = this.textures;
15597
15598 if ( textures[ name ] === undefined ) {
15599
15600 console.warn( 'THREE.MaterialLoader: Undefined texture', name );
15601
15602 }
15603
15604 return textures[ name ];
15605
15606 },
15607
15608 parse: function ( json ) {
15609
15610 var material = new THREE[ json.type ];
15611 material.uuid = json.uuid;
15612
15613 if ( json.name !== undefined ) material.name = json.name;
15614 if ( json.color !== undefined ) material.color.setHex( json.color );
15615 if ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );
15616 if ( json.specular !== undefined ) material.specular.setHex( json.specular );
15617 if ( json.shininess !== undefined ) material.shininess = json.shininess;
15618 if ( json.uniforms !== undefined ) material.uniforms = json.uniforms;
15619 if ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;
15620 if ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;
15621 if ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;
15622 if ( json.shading !== undefined ) material.shading = json.shading;
15623 if ( json.blending !== undefined ) material.blending = json.blending;
15624 if ( json.side !== undefined ) material.side = json.side;
15625 if ( json.opacity !== undefined ) material.opacity = json.opacity;
15626 if ( json.transparent !== undefined ) material.transparent = json.transparent;
15627 if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;
15628 if ( json.depthTest !== undefined ) material.depthTest = json.depthTest;
15629 if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;
15630 if ( json.wireframe !== undefined ) material.wireframe = json.wireframe;
15631 if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;
15632
15633
15634 if ( json.size !== undefined ) material.size = json.size;
15635 if ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;
15636
15637
15638
15639 if ( json.map !== undefined ) material.map = this.getTexture( json.map );
15640
15641 if ( json.alphaMap !== undefined ) {
15642
15643 material.alphaMap = this.getTexture( json.alphaMap );
15644 material.transparent = true;
15645
15646 }
15647
15648 if ( json.bumpMap !== undefined ) material.bumpMap = this.getTexture( json.bumpMap );
15649 if ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;
15650
15651 if ( json.normalMap !== undefined ) material.normalMap = this.getTexture( json.normalMap );
15652 if ( json.normalScale ) material.normalScale = new THREE.Vector2( json.normalScale, json.normalScale );
15653
15654 if ( json.displacementMap !== undefined ) material.displacementMap = this.getTexture( json.displacementMap );
15655 if ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;
15656 if ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;
15657
15658 if ( json.specularMap !== undefined ) material.specularMap = this.getTexture( json.specularMap );
15659
15660 if ( json.envMap !== undefined ) {
15661
15662 material.envMap = this.getTexture( json.envMap );
15663 material.combine = THREE.MultiplyOperation;
15664
15665 }
15666
15667 if ( json.reflectivity ) material.reflectivity = json.reflectivity;
15668
15669 if ( json.lightMap !== undefined ) material.lightMap = this.getTexture( json.lightMap );
15670 if ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;
15671
15672 if ( json.aoMap !== undefined ) material.aoMap = this.getTexture( json.aoMap );
15673 if ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;
15674
15675
15676
15677 if ( json.materials !== undefined ) {
15678
15679 for ( var i = 0, l = json.materials.length; i < l; i ++ ) {
15680
15681 material.materials.push( this.parse( json.materials[ i ] ) );
15682
15683 }
15684
15685 }
15686
15687 return material;
15688
15689 }
15690
15691 };
15692
15693
15694
15699 THREE.ObjectLoader = function ( manager ) {
15700
15701 this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
15702 this.texturePath = '';
15703
15704 };
15705
15706 THREE.ObjectLoader.prototype = {
15707
15708 constructor: THREE.ObjectLoader,
15709
15710 load: function ( url, onLoad, onProgress, onError ) {
15711
15712 if ( this.texturePath === '' ) {
15713
15714 this.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );
15715
15716 }
15717
15718 var scope = this;
15719
15720 var loader = new THREE.XHRLoader( scope.manager );
15721 loader.setCrossOrigin( this.crossOrigin );
15722 loader.load( url, function ( text ) {
15723
15724 scope.parse( JSON.parse( text ), onLoad );
15725
15726 }, onProgress, onError );
15727
15728 },
15729
15730 setTexturePath: function ( value ) {
15731
15732 this.texturePath = value;
15733
15734 },
15735
15736 setCrossOrigin: function ( value ) {
15737
15738 this.crossOrigin = value;
15739
15740 },
15741
15742 parse: function ( json, onLoad ) {
15743
15744 var geometries = this.parseGeometries( json.geometries );
15745
15746 var images = this.parseImages( json.images, function () {
15747
15748 if ( onLoad !== undefined ) onLoad( object );
15749
15750 } );
15751
15752 var textures = this.parseTextures( json.textures, images );
15753 var materials = this.parseMaterials( json.materials, textures );
15754
15755 var object = this.parseObject( json.object, geometries, materials );
15756
15757 if ( json.animations ) {
15758
15759 object.animations = this.parseAnimations( json.animations );
15760
15761 }
15762
15763 if ( json.images === undefined || json.images.length === 0 ) {
15764
15765 if ( onLoad !== undefined ) onLoad( object );
15766
15767 }
15768
15769 return object;
15770
15771 },
15772
15773 parseGeometries: function ( json ) {
15774
15775 var geometries = {};
15776
15777 if ( json !== undefined ) {
15778
15779 var geometryLoader = new THREE.JSONLoader();
15780 var bufferGeometryLoader = new THREE.BufferGeometryLoader();
15781
15782 for ( var i = 0, l = json.length; i < l; i ++ ) {
15783
15784 var geometry;
15785 var data = json[ i ];
15786
15787 switch ( data.type ) {
15788
15789 case 'PlaneGeometry':
15790 case 'PlaneBufferGeometry':
15791
15792 geometry = new THREE[ data.type ](
15793 data.width,
15794 data.height,
15795 data.widthSegments,
15796 data.heightSegments
15797 );
15798
15799 break;
15800
15801 case 'BoxGeometry':
15802 case 'CubeGeometry':
15803
15804 geometry = new THREE.BoxGeometry(
15805 data.width,
15806 data.height,
15807 data.depth,
15808 data.widthSegments,
15809 data.heightSegments,
15810 data.depthSegments
15811 );
15812
15813 break;
15814
15815 case 'CircleBufferGeometry':
15816
15817 geometry = new THREE.CircleBufferGeometry(
15818 data.radius,
15819 data.segments,
15820 data.thetaStart,
15821 data.thetaLength
15822 );
15823
15824 break;
15825
15826 case 'CircleGeometry':
15827
15828 geometry = new THREE.CircleGeometry(
15829 data.radius,
15830 data.segments,
15831 data.thetaStart,
15832 data.thetaLength
15833 );
15834
15835 break;
15836
15837 case 'CylinderGeometry':
15838
15839 geometry = new THREE.CylinderGeometry(
15840 data.radiusTop,
15841 data.radiusBottom,
15842 data.height,
15843 data.radialSegments,
15844 data.heightSegments,
15845 data.openEnded,
15846 data.thetaStart,
15847 data.thetaLength
15848 );
15849
15850 break;
15851
15852 case 'SphereGeometry':
15853
15854 geometry = new THREE.SphereGeometry(
15855 data.radius,
15856 data.widthSegments,
15857 data.heightSegments,
15858 data.phiStart,
15859 data.phiLength,
15860 data.thetaStart,
15861 data.thetaLength
15862 );
15863
15864 break;
15865
15866 case 'SphereBufferGeometry':
15867
15868 geometry = new THREE.SphereBufferGeometry(
15869 data.radius,
15870 data.widthSegments,
15871 data.heightSegments,
15872 data.phiStart,
15873 data.phiLength,
15874 data.thetaStart,
15875 data.thetaLength
15876 );
15877
15878 break;
15879
15880 case 'DodecahedronGeometry':
15881
15882 geometry = new THREE.DodecahedronGeometry(
15883 data.radius,
15884 data.detail
15885 );
15886
15887 break;
15888
15889 case 'IcosahedronGeometry':
15890
15891 geometry = new THREE.IcosahedronGeometry(
15892 data.radius,
15893 data.detail
15894 );
15895
15896 break;
15897
15898 case 'OctahedronGeometry':
15899
15900 geometry = new THREE.OctahedronGeometry(
15901 data.radius,
15902 data.detail
15903 );
15904
15905 break;
15906
15907 case 'TetrahedronGeometry':
15908
15909 geometry = new THREE.TetrahedronGeometry(
15910 data.radius,
15911 data.detail
15912 );
15913
15914 break;
15915
15916 case 'RingGeometry':
15917
15918 geometry = new THREE.RingGeometry(
15919 data.innerRadius,
15920 data.outerRadius,
15921 data.thetaSegments,
15922 data.phiSegments,
15923 data.thetaStart,
15924 data.thetaLength
15925 );
15926
15927 break;
15928
15929 case 'TorusGeometry':
15930
15931 geometry = new THREE.TorusGeometry(
15932 data.radius,
15933 data.tube,
15934 data.radialSegments,
15935 data.tubularSegments,
15936 data.arc
15937 );
15938
15939 break;
15940
15941 case 'TorusKnotGeometry':
15942
15943 geometry = new THREE.TorusKnotGeometry(
15944 data.radius,
15945 data.tube,
15946 data.radialSegments,
15947 data.tubularSegments,
15948 data.p,
15949 data.q,
15950 data.heightScale
15951 );
15952
15953 break;
15954
15955 case 'BufferGeometry':
15956
15957 geometry = bufferGeometryLoader.parse( data );
15958
15959 break;
15960
15961 case 'Geometry':
15962
15963 geometry = geometryLoader.parse( data.data, this.texturePath ).geometry;
15964
15965 break;
15966
15967 default:
15968
15969 console.warn( 'THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"' );
15970
15971 continue;
15972
15973 }
15974
15975 geometry.uuid = data.uuid;
15976
15977 if ( data.name !== undefined ) geometry.name = data.name;
15978
15979 geometries[ data.uuid ] = geometry;
15980
15981 }
15982
15983 }
15984
15985 return geometries;
15986
15987 },
15988
15989 parseMaterials: function ( json, textures ) {
15990
15991 var materials = {};
15992
15993 if ( json !== undefined ) {
15994
15995 var loader = new THREE.MaterialLoader();
15996 loader.setTextures( textures );
15997
15998 for ( var i = 0, l = json.length; i < l; i ++ ) {
15999
16000 var material = loader.parse( json[ i ] );
16001 materials[ material.uuid ] = material;
16002
16003 }
16004
16005 }
16006
16007 return materials;
16008
16009 },
16010
16011 parseAnimations: function ( json ) {
16012
16013 var animations = [];
16014
16015 for ( var i = 0; i < json.length; i ++ ) {
16016
16017 var clip = THREE.AnimationClip.parse( json[i] );
16018
16019 animations.push( clip );
16020
16021 }
16022
16023 return animations;
16024
16025 },
16026
16027 parseImages: function ( json, onLoad ) {
16028
16029 var scope = this;
16030 var images = {};
16031
16032 function loadImage( url ) {
16033
16034 scope.manager.itemStart( url );
16035
16036 return loader.load( url, function () {
16037
16038 scope.manager.itemEnd( url );
16039
16040 } );
16041
16042 }
16043
16044 if ( json !== undefined && json.length > 0 ) {
16045
16046 var manager = new THREE.LoadingManager( onLoad );
16047
16048 var loader = new THREE.ImageLoader( manager );
16049 loader.setCrossOrigin( this.crossOrigin );
16050
16051 for ( var i = 0, l = json.length; i < l; i ++ ) {
16052
16053 var image = json[ i ];
16054 var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;
16055
16056 images[ image.uuid ] = loadImage( path );
16057
16058 }
16059
16060 }
16061
16062 return images;
16063
16064 },
16065
16066 parseTextures: function ( json, images ) {
16067
16068 function parseConstant( value ) {
16069
16070 if ( typeof( value ) === 'number' ) return value;
16071
16072 console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );
16073
16074 return THREE[ value ];
16075
16076 }
16077
16078 var textures = {};
16079
16080 if ( json !== undefined ) {
16081
16082 for ( var i = 0, l = json.length; i < l; i ++ ) {
16083
16084 var data = json[ i ];
16085
16086 if ( data.image === undefined ) {
16087
16088 console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid );
16089
16090 }
16091
16092 if ( images[ data.image ] === undefined ) {
16093
16094 console.warn( 'THREE.ObjectLoader: Undefined image', data.image );
16095
16096 }
16097
16098 var texture = new THREE.Texture( images[ data.image ] );
16099 texture.needsUpdate = true;
16100
16101 texture.uuid = data.uuid;
16102
16103 if ( data.name !== undefined ) texture.name = data.name;
16104 if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping );
16105 if ( data.offset !== undefined ) texture.offset = new THREE.Vector2( data.offset[ 0 ], data.offset[ 1 ] );
16106 if ( data.repeat !== undefined ) texture.repeat = new THREE.Vector2( data.repeat[ 0 ], data.repeat[ 1 ] );
16107 if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter );
16108 if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter );
16109 if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;
16110 if ( Array.isArray( data.wrap ) ) {
16111
16112 texture.wrapS = parseConstant( data.wrap[ 0 ] );
16113 texture.wrapT = parseConstant( data.wrap[ 1 ] );
16114
16115 }
16116
16117 textures[ data.uuid ] = texture;
16118
16119 }
16120
16121 }
16122
16123 return textures;
16124
16125 },
16126
16127 parseObject: function () {
16128
16129 var matrix = new THREE.Matrix4();
16130
16131 return function ( data, geometries, materials ) {
16132
16133 var object;
16134
16135 function getGeometry( name ) {
16136
16137 if ( geometries[ name ] === undefined ) {
16138
16139 console.warn( 'THREE.ObjectLoader: Undefined geometry', name );
16140
16141 }
16142
16143 return geometries[ name ];
16144
16145 }
16146
16147 function getMaterial( name ) {
16148
16149 if ( name === undefined ) return undefined;
16150
16151 if ( materials[ name ] === undefined ) {
16152
16153 console.warn( 'THREE.ObjectLoader: Undefined material', name );
16154
16155 }
16156
16157 return materials[ name ];
16158
16159 }
16160
16161 switch ( data.type ) {
16162
16163 case 'Scene':
16164
16165 object = new THREE.Scene();
16166
16167 break;
16168
16169 case 'PerspectiveCamera':
16170
16171 object = new THREE.PerspectiveCamera( data.fov, data.aspect, data.near, data.far );
16172
16173 break;
16174
16175 case 'OrthographicCamera':
16176
16177 object = new THREE.OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );
16178
16179 break;
16180
16181 case 'AmbientLight':
16182
16183 object = new THREE.AmbientLight( data.color );
16184
16185 break;
16186
16187 case 'DirectionalLight':
16188
16189 object = new THREE.DirectionalLight( data.color, data.intensity );
16190
16191 break;
16192
16193 case 'PointLight':
16194
16195 object = new THREE.PointLight( data.color, data.intensity, data.distance, data.decay );
16196
16197 break;
16198
16199 case 'SpotLight':
16200
16201 object = new THREE.SpotLight( data.color, data.intensity, data.distance, data.angle, data.exponent, data.decay );
16202
16203 break;
16204
16205 case 'HemisphereLight':
16206
16207 object = new THREE.HemisphereLight( data.color, data.groundColor, data.intensity );
16208
16209 break;
16210
16211 case 'Mesh':
16212
16213 object = new THREE.Mesh( getGeometry( data.geometry ), getMaterial( data.material ) );
16214
16215 break;
16216
16217 case 'LOD':
16218
16219 object = new THREE.LOD();
16220
16221 break;
16222
16223 case 'Line':
16224
16225 object = new THREE.Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );
16226
16227 break;
16228
16229 case 'PointCloud':
16230 case 'Points':
16231
16232 object = new THREE.Points( getGeometry( data.geometry ), getMaterial( data.material ) );
16233
16234 break;
16235
16236 case 'Sprite':
16237
16238 object = new THREE.Sprite( getMaterial( data.material ) );
16239
16240 break;
16241
16242 case 'Group':
16243
16244 object = new THREE.Group();
16245
16246 break;
16247
16248 default:
16249
16250 object = new THREE.Object3D();
16251
16252 }
16253
16254 object.uuid = data.uuid;
16255
16256 if ( data.name !== undefined ) object.name = data.name;
16257 if ( data.matrix !== undefined ) {
16258
16259 matrix.fromArray( data.matrix );
16260 matrix.decompose( object.position, object.quaternion, object.scale );
16261
16262 } else {
16263
16264 if ( data.position !== undefined ) object.position.fromArray( data.position );
16265 if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );
16266 if ( data.scale !== undefined ) object.scale.fromArray( data.scale );
16267
16268 }
16269
16270 if ( data.castShadow !== undefined ) object.castShadow = data.castShadow;
16271 if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;
16272
16273 if ( data.visible !== undefined ) object.visible = data.visible;
16274 if ( data.userData !== undefined ) object.userData = data.userData;
16275
16276 if ( data.children !== undefined ) {
16277
16278 for ( var child in data.children ) {
16279
16280 object.add( this.parseObject( data.children[ child ], geometries, materials ) );
16281
16282 }
16283
16284 }
16285
16286 if ( data.type === 'LOD' ) {
16287
16288 var levels = data.levels;
16289
16290 for ( var l = 0; l < levels.length; l ++ ) {
16291
16292 var level = levels[ l ];
16293 var child = object.getObjectByProperty( 'uuid', level.object );
16294
16295 if ( child !== undefined ) {
16296
16297 object.addLevel( child, level.distance );
16298
16299 }
16300
16301 }
16302
16303 }
16304
16305 return object;
16306
16307 }
16308
16309 }()
16310
16311 };
16312
16313
16314
16319 THREE.TextureLoader = function ( manager ) {
16320
16321 this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
16322
16323 };
16324
16325 THREE.TextureLoader.prototype = {
16326
16327 constructor: THREE.TextureLoader,
16328
16329 load: function ( url, onLoad, onProgress, onError ) {
16330
16331 var texture = new THREE.Texture();
16332
16333 var loader = new THREE.ImageLoader( this.manager );
16334 loader.setCrossOrigin( this.crossOrigin );
16335 loader.load( url, function ( image ) {
16336
16337 texture.image = image;
16338 texture.needsUpdate = true;
16339
16340 if ( onLoad !== undefined ) {
16341
16342 onLoad( texture );
16343
16344 }
16345
16346 }, onProgress, onError );
16347
16348 return texture;
16349
16350 },
16351
16352 setCrossOrigin: function ( value ) {
16353
16354 this.crossOrigin = value;
16355
16356 }
16357
16358 };
16359
16360
16361
16366 THREE.CubeTextureLoader = function ( manager ) {
16367
16368 this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
16369
16370 };
16371
16372 THREE.CubeTextureLoader.prototype = {
16373
16374 constructor: THREE.CubeTextureLoader,
16375
16376 load: function ( urls, onLoad, onProgress, onError ) {
16377
16378 var texture = new THREE.CubeTexture( [] );
16379
16380 var loader = new THREE.ImageLoader();
16381 loader.setCrossOrigin( this.crossOrigin );
16382
16383 var loaded = 0;
16384
16385 function loadTexture( i ) {
16386
16387 loader.load( urls[ i ], function ( image ) {
16388
16389 texture.images[ i ] = image;
16390
16391 loaded ++;
16392
16393 if ( loaded === 6 ) {
16394
16395 texture.needsUpdate = true;
16396
16397 if ( onLoad ) onLoad( texture );
16398
16399 }
16400
16401 }, undefined, onError );
16402
16403 }
16404
16405 for ( var i = 0; i < urls.length; ++ i ) {
16406
16407 loadTexture( i );
16408
16409 }
16410
16411 return texture;
16412
16413 },
16414
16415 setCrossOrigin: function ( value ) {
16416
16417 this.crossOrigin = value;
16418
16419 }
16420
16421 };
16422
16423
16424
16431 THREE.DataTextureLoader = THREE.BinaryTextureLoader = function ( manager ) {
16432
16433 this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
16434
16435
16436 this._parser = null;
16437
16438 };
16439
16440 THREE.BinaryTextureLoader.prototype = {
16441
16442 constructor: THREE.BinaryTextureLoader,
16443
16444 load: function ( url, onLoad, onProgress, onError ) {
16445
16446 var scope = this;
16447
16448 var texture = new THREE.DataTexture();
16449
16450 var loader = new THREE.XHRLoader( this.manager );
16451 loader.setCrossOrigin( this.crossOrigin );
16452 loader.setResponseType( 'arraybuffer' );
16453
16454 loader.load( url, function ( buffer ) {
16455
16456 var texData = scope._parser( buffer );
16457
16458 if ( ! texData ) return;
16459
16460 if ( undefined !== texData.image ) {
16461
16462 texture.image = texData.image;
16463
16464 } else if ( undefined !== texData.data ) {
16465
16466 texture.image.width = texData.width;
16467 texture.image.height = texData.height;
16468 texture.image.data = texData.data;
16469
16470 }
16471
16472 texture.wrapS = undefined !== texData.wrapS ? texData.wrapS : THREE.ClampToEdgeWrapping;
16473 texture.wrapT = undefined !== texData.wrapT ? texData.wrapT : THREE.ClampToEdgeWrapping;
16474
16475 texture.magFilter = undefined !== texData.magFilter ? texData.magFilter : THREE.LinearFilter;
16476 texture.minFilter = undefined !== texData.minFilter ? texData.minFilter : THREE.LinearMipMapLinearFilter;
16477
16478 texture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;
16479
16480 if ( undefined !== texData.format ) {
16481
16482 texture.format = texData.format;
16483
16484 }
16485 if ( undefined !== texData.type ) {
16486
16487 texture.type = texData.type;
16488
16489 }
16490
16491 if ( undefined !== texData.mipmaps ) {
16492
16493 texture.mipmaps = texData.mipmaps;
16494
16495 }
16496
16497 if ( 1 === texData.mipmapCount ) {
16498
16499 texture.minFilter = THREE.LinearFilter;
16500
16501 }
16502
16503 texture.needsUpdate = true;
16504
16505 if ( onLoad ) onLoad( texture, texData );
16506
16507 }, onProgress, onError );
16508
16509
16510 return texture;
16511
16512 },
16513
16514 setCrossOrigin: function ( value ) {
16515
16516 this.crossOrigin = value;
16517
16518 }
16519
16520 };
16521
16522
16523
16530 THREE.CompressedTextureLoader = function ( manager ) {
16531
16532 this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
16533
16534
16535 this._parser = null;
16536
16537 };
16538
16539
16540 THREE.CompressedTextureLoader.prototype = {
16541
16542 constructor: THREE.CompressedTextureLoader,
16543
16544 load: function ( url, onLoad, onProgress, onError ) {
16545
16546 var scope = this;
16547
16548 var images = [];
16549
16550 var texture = new THREE.CompressedTexture();
16551 texture.image = images;
16552
16553 var loader = new THREE.XHRLoader( this.manager );
16554 loader.setCrossOrigin( this.crossOrigin );
16555 loader.setResponseType( 'arraybuffer' );
16556
16557 if ( Array.isArray( url ) ) {
16558
16559 var loaded = 0;
16560
16561 var loadTexture = function ( i ) {
16562
16563 loader.load( url[ i ], function ( buffer ) {
16564
16565 var texDatas = scope._parser( buffer, true );
16566
16567 images[ i ] = {
16568 width: texDatas.width,
16569 height: texDatas.height,
16570 format: texDatas.format,
16571 mipmaps: texDatas.mipmaps
16572 };
16573
16574 loaded += 1;
16575
16576 if ( loaded === 6 ) {
16577
16578 if ( texDatas.mipmapCount === 1 )
16579 texture.minFilter = THREE.LinearFilter;
16580
16581 texture.format = texDatas.format;
16582 texture.needsUpdate = true;
16583
16584 if ( onLoad ) onLoad( texture );
16585
16586 }
16587
16588 }, onProgress, onError );
16589
16590 };
16591
16592 for ( var i = 0, il = url.length; i < il; ++ i ) {
16593
16594 loadTexture( i );
16595
16596 }
16597
16598 } else {
16599
16600
16601
16602 loader.load( url, function ( buffer ) {
16603
16604 var texDatas = scope._parser( buffer, true );
16605
16606 if ( texDatas.isCubemap ) {
16607
16608 var faces = texDatas.mipmaps.length / texDatas.mipmapCount;
16609
16610 for ( var f = 0; f < faces; f ++ ) {
16611
16612 images[ f ] = { mipmaps : [] };
16613
16614 for ( var i = 0; i < texDatas.mipmapCount; i ++ ) {
16615
16616 images[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );
16617 images[ f ].format = texDatas.format;
16618 images[ f ].width = texDatas.width;
16619 images[ f ].height = texDatas.height;
16620
16621 }
16622
16623 }
16624
16625 } else {
16626
16627 texture.image.width = texDatas.width;
16628 texture.image.height = texDatas.height;
16629 texture.mipmaps = texDatas.mipmaps;
16630
16631 }
16632
16633 if ( texDatas.mipmapCount === 1 ) {
16634
16635 texture.minFilter = THREE.LinearFilter;
16636
16637 }
16638
16639 texture.format = texDatas.format;
16640 texture.needsUpdate = true;
16641
16642 if ( onLoad ) onLoad( texture );
16643
16644 }, onProgress, onError );
16645
16646 }
16647
16648 return texture;
16649
16650 },
16651
16652 setCrossOrigin: function ( value ) {
16653
16654 this.crossOrigin = value;
16655
16656 }
16657
16658 };
16659
16660
16661
16667 THREE.Material = function () {
16668
16669 Object.defineProperty( this, 'id', { value: THREE.MaterialIdCount ++ } );
16670
16671 this.uuid = THREE.Math.generateUUID();
16672
16673 this.name = '';
16674 this.type = 'Material';
16675
16676 this.side = THREE.FrontSide;
16677
16678 this.opacity = 1;
16679 this.transparent = false;
16680
16681 this.blending = THREE.NormalBlending;
16682
16683 this.blendSrc = THREE.SrcAlphaFactor;
16684 this.blendDst = THREE.OneMinusSrcAlphaFactor;
16685 this.blendEquation = THREE.AddEquation;
16686 this.blendSrcAlpha = null;
16687 this.blendDstAlpha = null;
16688 this.blendEquationAlpha = null;
16689
16690 this.depthFunc = THREE.LessEqualDepth;
16691 this.depthTest = true;
16692 this.depthWrite = true;
16693
16694 this.colorWrite = true;
16695
16696 this.precision = null;
16697
16698 this.polygonOffset = false;
16699 this.polygonOffsetFactor = 0;
16700 this.polygonOffsetUnits = 0;
16701
16702 this.alphaTest = 0;
16703
16704 this.overdraw = 0;
16705
16706 this.visible = true;
16707
16708 this._needsUpdate = true;
16709
16710 };
16711
16712 THREE.Material.prototype = {
16713
16714 constructor: THREE.Material,
16715
16716 get needsUpdate () {
16717
16718 return this._needsUpdate;
16719
16720 },
16721
16722 set needsUpdate ( value ) {
16723
16724 if ( value === true ) this.update();
16725
16726 this._needsUpdate = value;
16727
16728 },
16729
16730 setValues: function ( values ) {
16731
16732 if ( values === undefined ) return;
16733
16734 for ( var key in values ) {
16735
16736 var newValue = values[ key ];
16737
16738 if ( newValue === undefined ) {
16739
16740 console.warn( "THREE.Material: '" + key + "' parameter is undefined." );
16741 continue;
16742
16743 }
16744
16745 var currentValue = this[ key ];
16746
16747 if ( currentValue === undefined ) {
16748
16749 console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." );
16750 continue;
16751
16752 }
16753
16754 if ( currentValue instanceof THREE.Color ) {
16755
16756 currentValue.set( newValue );
16757
16758 } else if ( currentValue instanceof THREE.Vector3 && newValue instanceof THREE.Vector3 ) {
16759
16760 currentValue.copy( newValue );
16761
16762 } else if ( key === 'overdraw' ) {
16763
16764
16765 this[ key ] = Number( newValue );
16766
16767 } else {
16768
16769 this[ key ] = newValue;
16770
16771 }
16772
16773 }
16774
16775 },
16776
16777 toJSON: function ( meta ) {
16778
16779 var data = {
16780 metadata: {
16781 version: 4.4,
16782 type: 'Material',
16783 generator: 'Material.toJSON'
16784 }
16785 };
16786
16787
16788 data.uuid = this.uuid;
16789 data.type = this.type;
16790 if ( this.name !== '' ) data.name = this.name;
16791
16792 if ( this.color instanceof THREE.Color ) data.color = this.color.getHex();
16793 if ( this.emissive instanceof THREE.Color ) data.emissive = this.emissive.getHex();
16794 if ( this.specular instanceof THREE.Color ) data.specular = this.specular.getHex();
16795 if ( this.shininess !== undefined ) data.shininess = this.shininess;
16796
16797 if ( this.map instanceof THREE.Texture ) data.map = this.map.toJSON( meta ).uuid;
16798 if ( this.alphaMap instanceof THREE.Texture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;
16799 if ( this.lightMap instanceof THREE.Texture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;
16800 if ( this.bumpMap instanceof THREE.Texture ) {
16801
16802 data.bumpMap = this.bumpMap.toJSON( meta ).uuid;
16803 data.bumpScale = this.bumpScale;
16804
16805 }
16806 if ( this.normalMap instanceof THREE.Texture ) {
16807
16808 data.normalMap = this.normalMap.toJSON( meta ).uuid;
16809 data.normalScale = this.normalScale;
16810
16811 }
16812 if ( this.displacementMap instanceof THREE.Texture ) {
16813
16814 data.displacementMap = this.displacementMap.toJSON( meta ).uuid;
16815 data.displacementScale = this.displacementScale;
16816 data.displacementBias = this.displacementBias;
16817
16818 }
16819 if ( this.specularMap instanceof THREE.Texture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;
16820 if ( this.envMap instanceof THREE.Texture ) {
16821
16822 data.envMap = this.envMap.toJSON( meta ).uuid;
16823 data.reflectivity = this.reflectivity;
16824
16825 }
16826
16827 if ( this.size !== undefined ) data.size = this.size;
16828 if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;
16829
16830 if ( this.vertexColors !== undefined && this.vertexColors !== THREE.NoColors ) data.vertexColors = this.vertexColors;
16831 if ( this.shading !== undefined && this.shading !== THREE.SmoothShading ) data.shading = this.shading;
16832 if ( this.blending !== undefined && this.blending !== THREE.NormalBlending ) data.blending = this.blending;
16833 if ( this.side !== undefined && this.side !== THREE.FrontSide ) data.side = this.side;
16834
16835 if ( this.opacity < 1 ) data.opacity = this.opacity;
16836 if ( this.transparent === true ) data.transparent = this.transparent;
16837 if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;
16838 if ( this.wireframe === true ) data.wireframe = this.wireframe;
16839 if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;
16840
16841 return data;
16842
16843 },
16844
16845 clone: function () {
16846
16847 return new this.constructor().copy( this );
16848
16849 },
16850
16851 copy: function ( source ) {
16852
16853 this.name = source.name;
16854
16855 this.side = source.side;
16856
16857 this.opacity = source.opacity;
16858 this.transparent = source.transparent;
16859
16860 this.blending = source.blending;
16861
16862 this.blendSrc = source.blendSrc;
16863 this.blendDst = source.blendDst;
16864 this.blendEquation = source.blendEquation;
16865 this.blendSrcAlpha = source.blendSrcAlpha;
16866 this.blendDstAlpha = source.blendDstAlpha;
16867 this.blendEquationAlpha = source.blendEquationAlpha;
16868
16869 this.depthFunc = source.depthFunc;
16870 this.depthTest = source.depthTest;
16871 this.depthWrite = source.depthWrite;
16872
16873 this.precision = source.precision;
16874
16875 this.polygonOffset = source.polygonOffset;
16876 this.polygonOffsetFactor = source.polygonOffsetFactor;
16877 this.polygonOffsetUnits = source.polygonOffsetUnits;
16878
16879 this.alphaTest = source.alphaTest;
16880
16881 this.overdraw = source.overdraw;
16882
16883 this.visible = source.visible;
16884
16885 return this;
16886
16887 },
16888
16889 update: function () {
16890
16891 this.dispatchEvent( { type: 'update' } );
16892
16893 },
16894
16895 dispose: function () {
16896
16897 this.dispatchEvent( { type: 'dispose' } );
16898
16899 },
16900
16901
16902
16903 get wrapAround () {
16904
16905 console.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );
16906
16907 },
16908
16909 set wrapAround ( boolean ) {
16910
16911 console.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );
16912
16913 },
16914
16915 get wrapRGB () {
16916
16917 console.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );
16918 return new THREE.Color();
16919
16920 }
16921
16922 };
16923
16924 THREE.EventDispatcher.prototype.apply( THREE.Material.prototype );
16925
16926 THREE.MaterialIdCount = 0;
16927
16928
16929
16952 THREE.LineBasicMaterial = function ( parameters ) {
16953
16954 THREE.Material.call( this );
16955
16956 this.type = 'LineBasicMaterial';
16957
16958 this.color = new THREE.Color( 0xffffff );
16959
16960 this.linewidth = 1;
16961 this.linecap = 'round';
16962 this.linejoin = 'round';
16963
16964 this.vertexColors = THREE.NoColors;
16965
16966 this.fog = true;
16967
16968 this.setValues( parameters );
16969
16970 };
16971
16972 THREE.LineBasicMaterial.prototype = Object.create( THREE.Material.prototype );
16973 THREE.LineBasicMaterial.prototype.constructor = THREE.LineBasicMaterial;
16974
16975 THREE.LineBasicMaterial.prototype.copy = function ( source ) {
16976
16977 THREE.Material.prototype.copy.call( this, source );
16978
16979 this.color.copy( source.color );
16980
16981 this.linewidth = source.linewidth;
16982 this.linecap = source.linecap;
16983 this.linejoin = source.linejoin;
16984
16985 this.vertexColors = source.vertexColors;
16986
16987 this.fog = source.fog;
16988
16989 return this;
16990
16991 };
16992
16993
16994
17018 THREE.LineDashedMaterial = function ( parameters ) {
17019
17020 THREE.Material.call( this );
17021
17022 this.type = 'LineDashedMaterial';
17023
17024 this.color = new THREE.Color( 0xffffff );
17025
17026 this.linewidth = 1;
17027
17028 this.scale = 1;
17029 this.dashSize = 3;
17030 this.gapSize = 1;
17031
17032 this.vertexColors = false;
17033
17034 this.fog = true;
17035
17036 this.setValues( parameters );
17037
17038 };
17039
17040 THREE.LineDashedMaterial.prototype = Object.create( THREE.Material.prototype );
17041 THREE.LineDashedMaterial.prototype.constructor = THREE.LineDashedMaterial;
17042
17043 THREE.LineDashedMaterial.prototype.copy = function ( source ) {
17044
17045 THREE.Material.prototype.copy.call( this, source );
17046
17047 this.color.copy( source.color );
17048
17049 this.linewidth = source.linewidth;
17050
17051 this.scale = source.scale;
17052 this.dashSize = source.dashSize;
17053 this.gapSize = source.gapSize;
17054
17055 this.vertexColors = source.vertexColors;
17056
17057 this.fog = source.fog;
17058
17059 return this;
17060
17061 };
17062
17063
17064
17103 THREE.MeshBasicMaterial = function ( parameters ) {
17104
17105 THREE.Material.call( this );
17106
17107 this.type = 'MeshBasicMaterial';
17108
17109 this.color = new THREE.Color( 0xffffff );
17110
17111 this.map = null;
17112
17113 this.aoMap = null;
17114 this.aoMapIntensity = 1.0;
17115
17116 this.specularMap = null;
17117
17118 this.alphaMap = null;
17119
17120 this.envMap = null;
17121 this.combine = THREE.MultiplyOperation;
17122 this.reflectivity = 1;
17123 this.refractionRatio = 0.98;
17124
17125 this.fog = true;
17126
17127 this.shading = THREE.SmoothShading;
17128
17129 this.wireframe = false;
17130 this.wireframeLinewidth = 1;
17131 this.wireframeLinecap = 'round';
17132 this.wireframeLinejoin = 'round';
17133
17134 this.vertexColors = THREE.NoColors;
17135
17136 this.skinning = false;
17137 this.morphTargets = false;
17138
17139 this.setValues( parameters );
17140
17141 };
17142
17143 THREE.MeshBasicMaterial.prototype = Object.create( THREE.Material.prototype );
17144 THREE.MeshBasicMaterial.prototype.constructor = THREE.MeshBasicMaterial;
17145
17146 THREE.MeshBasicMaterial.prototype.copy = function ( source ) {
17147
17148 THREE.Material.prototype.copy.call( this, source );
17149
17150 this.color.copy( source.color );
17151
17152 this.map = source.map;
17153
17154 this.aoMap = source.aoMap;
17155 this.aoMapIntensity = source.aoMapIntensity;
17156
17157 this.specularMap = source.specularMap;
17158
17159 this.alphaMap = source.alphaMap;
17160
17161 this.envMap = source.envMap;
17162 this.combine = source.combine;
17163 this.reflectivity = source.reflectivity;
17164 this.refractionRatio = source.refractionRatio;
17165
17166 this.fog = source.fog;
17167
17168 this.shading = source.shading;
17169
17170 this.wireframe = source.wireframe;
17171 this.wireframeLinewidth = source.wireframeLinewidth;
17172 this.wireframeLinecap = source.wireframeLinecap;
17173 this.wireframeLinejoin = source.wireframeLinejoin;
17174
17175 this.vertexColors = source.vertexColors;
17176
17177 this.skinning = source.skinning;
17178 this.morphTargets = source.morphTargets;
17179
17180 return this;
17181
17182 };
17183
17184
17185
17223 THREE.MeshLambertMaterial = function ( parameters ) {
17224
17225 THREE.Material.call( this );
17226
17227 this.type = 'MeshLambertMaterial';
17228
17229 this.color = new THREE.Color( 0xffffff );
17230 this.emissive = new THREE.Color( 0x000000 );
17231
17232 this.map = null;
17233
17234 this.specularMap = null;
17235
17236 this.alphaMap = null;
17237
17238 this.envMap = null;
17239 this.combine = THREE.MultiplyOperation;
17240 this.reflectivity = 1;
17241 this.refractionRatio = 0.98;
17242
17243 this.fog = true;
17244
17245 this.wireframe = false;
17246 this.wireframeLinewidth = 1;
17247 this.wireframeLinecap = 'round';
17248 this.wireframeLinejoin = 'round';
17249
17250 this.vertexColors = THREE.NoColors;
17251
17252 this.skinning = false;
17253 this.morphTargets = false;
17254 this.morphNormals = false;
17255
17256 this.setValues( parameters );
17257
17258 };
17259
17260 THREE.MeshLambertMaterial.prototype = Object.create( THREE.Material.prototype );
17261 THREE.MeshLambertMaterial.prototype.constructor = THREE.MeshLambertMaterial;
17262
17263 THREE.MeshLambertMaterial.prototype.copy = function ( source ) {
17264
17265 THREE.Material.prototype.copy.call( this, source );
17266
17267 this.color.copy( source.color );
17268 this.emissive.copy( source.emissive );
17269
17270 this.map = source.map;
17271
17272 this.specularMap = source.specularMap;
17273
17274 this.alphaMap = source.alphaMap;
17275
17276 this.envMap = source.envMap;
17277 this.combine = source.combine;
17278 this.reflectivity = source.reflectivity;
17279 this.refractionRatio = source.refractionRatio;
17280
17281 this.fog = source.fog;
17282
17283 this.wireframe = source.wireframe;
17284 this.wireframeLinewidth = source.wireframeLinewidth;
17285 this.wireframeLinecap = source.wireframeLinecap;
17286 this.wireframeLinejoin = source.wireframeLinejoin;
17287
17288 this.vertexColors = source.vertexColors;
17289
17290 this.skinning = source.skinning;
17291 this.morphTargets = source.morphTargets;
17292 this.morphNormals = source.morphNormals;
17293
17294 return this;
17295
17296 };
17297
17298
17299
17358 THREE.MeshPhongMaterial = function ( parameters ) {
17359
17360 THREE.Material.call( this );
17361
17362 this.type = 'MeshPhongMaterial';
17363
17364 this.color = new THREE.Color( 0xffffff );
17365 this.emissive = new THREE.Color( 0x000000 );
17366 this.specular = new THREE.Color( 0x111111 );
17367 this.shininess = 30;
17368
17369 this.metal = false;
17370
17371 this.map = null;
17372
17373 this.lightMap = null;
17374 this.lightMapIntensity = 1.0;
17375
17376 this.aoMap = null;
17377 this.aoMapIntensity = 1.0;
17378
17379 this.emissiveMap = null;
17380
17381 this.bumpMap = null;
17382 this.bumpScale = 1;
17383
17384 this.normalMap = null;
17385 this.normalScale = new THREE.Vector2( 1, 1 );
17386
17387 this.displacementMap = null;
17388 this.displacementScale = 1;
17389 this.displacementBias = 0;
17390
17391 this.specularMap = null;
17392
17393 this.alphaMap = null;
17394
17395 this.envMap = null;
17396 this.combine = THREE.MultiplyOperation;
17397 this.reflectivity = 1;
17398 this.refractionRatio = 0.98;
17399
17400 this.fog = true;
17401
17402 this.shading = THREE.SmoothShading;
17403
17404 this.wireframe = false;
17405 this.wireframeLinewidth = 1;
17406 this.wireframeLinecap = 'round';
17407 this.wireframeLinejoin = 'round';
17408
17409 this.vertexColors = THREE.NoColors;
17410
17411 this.skinning = false;
17412 this.morphTargets = false;
17413 this.morphNormals = false;
17414
17415 this.setValues( parameters );
17416
17417 };
17418
17419 THREE.MeshPhongMaterial.prototype = Object.create( THREE.Material.prototype );
17420 THREE.MeshPhongMaterial.prototype.constructor = THREE.MeshPhongMaterial;
17421
17422 THREE.MeshPhongMaterial.prototype.copy = function ( source ) {
17423
17424 THREE.Material.prototype.copy.call( this, source );
17425
17426 this.color.copy( source.color );
17427 this.emissive.copy( source.emissive );
17428 this.specular.copy( source.specular );
17429 this.shininess = source.shininess;
17430
17431 this.metal = source.metal;
17432
17433 this.map = source.map;
17434
17435 this.lightMap = source.lightMap;
17436 this.lightMapIntensity = source.lightMapIntensity;
17437
17438 this.aoMap = source.aoMap;
17439 this.aoMapIntensity = source.aoMapIntensity;
17440
17441 this.emissiveMap = source.emissiveMap;
17442
17443 this.bumpMap = source.bumpMap;
17444 this.bumpScale = source.bumpScale;
17445
17446 this.normalMap = source.normalMap;
17447 this.normalScale.copy( source.normalScale );
17448
17449 this.displacementMap = source.displacementMap;
17450 this.displacementScale = source.displacementScale;
17451 this.displacementBias = source.displacementBias;
17452
17453 this.specularMap = source.specularMap;
17454
17455 this.alphaMap = source.alphaMap;
17456
17457 this.envMap = source.envMap;
17458 this.combine = source.combine;
17459 this.reflectivity = source.reflectivity;
17460 this.refractionRatio = source.refractionRatio;
17461
17462 this.fog = source.fog;
17463
17464 this.shading = source.shading;
17465
17466 this.wireframe = source.wireframe;
17467 this.wireframeLinewidth = source.wireframeLinewidth;
17468 this.wireframeLinecap = source.wireframeLinecap;
17469 this.wireframeLinejoin = source.wireframeLinejoin;
17470
17471 this.vertexColors = source.vertexColors;
17472
17473 this.skinning = source.skinning;
17474 this.morphTargets = source.morphTargets;
17475 this.morphNormals = source.morphNormals;
17476
17477 return this;
17478
17479 };
17480
17481
17482
17499 THREE.MeshDepthMaterial = function ( parameters ) {
17500
17501 THREE.Material.call( this );
17502
17503 this.type = 'MeshDepthMaterial';
17504
17505 this.morphTargets = false;
17506 this.wireframe = false;
17507 this.wireframeLinewidth = 1;
17508
17509 this.setValues( parameters );
17510
17511 };
17512
17513 THREE.MeshDepthMaterial.prototype = Object.create( THREE.Material.prototype );
17514 THREE.MeshDepthMaterial.prototype.constructor = THREE.MeshDepthMaterial;
17515
17516 THREE.MeshDepthMaterial.prototype.copy = function ( source ) {
17517
17518 THREE.Material.prototype.copy.call( this, source );
17519
17520 this.wireframe = source.wireframe;
17521 this.wireframeLinewidth = source.wireframeLinewidth;
17522
17523 return this;
17524
17525 };
17526
17527
17528
17545 THREE.MeshNormalMaterial = function ( parameters ) {
17546
17547 THREE.Material.call( this, parameters );
17548
17549 this.type = 'MeshNormalMaterial';
17550
17551 this.wireframe = false;
17552 this.wireframeLinewidth = 1;
17553
17554 this.morphTargets = false;
17555
17556 this.setValues( parameters );
17557
17558 };
17559
17560 THREE.MeshNormalMaterial.prototype = Object.create( THREE.Material.prototype );
17561 THREE.MeshNormalMaterial.prototype.constructor = THREE.MeshNormalMaterial;
17562
17563 THREE.MeshNormalMaterial.prototype.copy = function ( source ) {
17564
17565 THREE.Material.prototype.copy.call( this, source );
17566
17567 this.wireframe = source.wireframe;
17568 this.wireframeLinewidth = source.wireframeLinewidth;
17569
17570 return this;
17571
17572 };
17573
17574
17575
17580 THREE.MultiMaterial = function ( materials ) {
17581
17582 this.uuid = THREE.Math.generateUUID();
17583
17584 this.type = 'MultiMaterial';
17585
17586 this.materials = materials instanceof Array ? materials : [];
17587
17588 this.visible = true;
17589
17590 };
17591
17592 THREE.MultiMaterial.prototype = {
17593
17594 constructor: THREE.MultiMaterial,
17595
17596 toJSON: function () {
17597
17598 var output = {
17599 metadata: {
17600 version: 4.2,
17601 type: 'material',
17602 generator: 'MaterialExporter'
17603 },
17604 uuid: this.uuid,
17605 type: this.type,
17606 materials: []
17607 };
17608
17609 for ( var i = 0, l = this.materials.length; i < l; i ++ ) {
17610
17611 output.materials.push( this.materials[ i ].toJSON() );
17612
17613 }
17614
17615 output.visible = this.visible;
17616
17617 return output;
17618
17619 },
17620
17621 clone: function () {
17622
17623 var material = new this.constructor();
17624
17625 for ( var i = 0; i < this.materials.length; i ++ ) {
17626
17627 material.materials.push( this.materials[ i ].clone() );
17628
17629 }
17630
17631 material.visible = this.visible;
17632
17633 return material;
17634
17635 }
17636
17637 };
17638
17639
17640
17641 THREE.MeshFaceMaterial = THREE.MultiMaterial;
17642
17643
17644
17667 THREE.PointsMaterial = function ( parameters ) {
17668
17669 THREE.Material.call( this );
17670
17671 this.type = 'PointsMaterial';
17672
17673 this.color = new THREE.Color( 0xffffff );
17674
17675 this.map = null;
17676
17677 this.size = 1;
17678 this.sizeAttenuation = true;
17679
17680 this.vertexColors = THREE.NoColors;
17681
17682 this.fog = true;
17683
17684 this.setValues( parameters );
17685
17686 };
17687
17688 THREE.PointsMaterial.prototype = Object.create( THREE.Material.prototype );
17689 THREE.PointsMaterial.prototype.constructor = THREE.PointsMaterial;
17690
17691 THREE.PointsMaterial.prototype.copy = function ( source ) {
17692
17693 THREE.Material.prototype.copy.call( this, source );
17694
17695 this.color.copy( source.color );
17696
17697 this.map = source.map;
17698
17699 this.size = source.size;
17700 this.sizeAttenuation = source.sizeAttenuation;
17701
17702 this.vertexColors = source.vertexColors;
17703
17704 this.fog = source.fog;
17705
17706 return this;
17707
17708 };
17709
17710
17711
17712 THREE.PointCloudMaterial = function ( parameters ) {
17713
17714 console.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );
17715 return new THREE.PointsMaterial( parameters );
17716
17717 };
17718
17719 THREE.ParticleBasicMaterial = function ( parameters ) {
17720
17721 console.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );
17722 return new THREE.PointsMaterial( parameters );
17723
17724 };
17725
17726 THREE.ParticleSystemMaterial = function ( parameters ) {
17727
17728 console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );
17729 return new THREE.PointsMaterial( parameters );
17730
17731 };
17732
17733
17734
17765 THREE.ShaderMaterial = function ( parameters ) {
17766
17767 THREE.Material.call( this );
17768
17769 this.type = 'ShaderMaterial';
17770
17771 this.defines = {};
17772 this.uniforms = {};
17773
17774 this.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}';
17775 this.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}';
17776
17777 this.shading = THREE.SmoothShading;
17778
17779 this.linewidth = 1;
17780
17781 this.wireframe = false;
17782 this.wireframeLinewidth = 1;
17783
17784 this.fog = false;
17785
17786 this.lights = false;
17787
17788 this.vertexColors = THREE.NoColors;
17789
17790 this.skinning = false;
17791
17792 this.morphTargets = false;
17793 this.morphNormals = false;
17794
17795 this.derivatives = false;
17796
17797
17798
17799 this.defaultAttributeValues = {
17800 'color': [ 1, 1, 1 ],
17801 'uv': [ 0, 0 ],
17802 'uv2': [ 0, 0 ]
17803 };
17804
17805 this.index0AttributeName = undefined;
17806
17807 if ( parameters !== undefined ) {
17808
17809 if ( parameters.attributes !== undefined ) {
17810
17811 console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );
17812
17813 }
17814
17815 this.setValues( parameters );
17816
17817 }
17818
17819 };
17820
17821 THREE.ShaderMaterial.prototype = Object.create( THREE.Material.prototype );
17822 THREE.ShaderMaterial.prototype.constructor = THREE.ShaderMaterial;
17823
17824 THREE.ShaderMaterial.prototype.copy = function ( source ) {
17825
17826 THREE.Material.prototype.copy.call( this, source );
17827
17828 this.fragmentShader = source.fragmentShader;
17829 this.vertexShader = source.vertexShader;
17830
17831 this.uniforms = THREE.UniformsUtils.clone( source.uniforms );
17832
17833 this.attributes = source.attributes;
17834 this.defines = source.defines;
17835
17836 this.shading = source.shading;
17837
17838 this.wireframe = source.wireframe;
17839 this.wireframeLinewidth = source.wireframeLinewidth;
17840
17841 this.fog = source.fog;
17842
17843 this.lights = source.lights;
17844
17845 this.vertexColors = source.vertexColors;
17846
17847 this.skinning = source.skinning;
17848
17849 this.morphTargets = source.morphTargets;
17850 this.morphNormals = source.morphNormals;
17851
17852 this.derivatives = source.derivatives;
17853
17854 return this;
17855
17856 };
17857
17858 THREE.ShaderMaterial.prototype.toJSON = function ( meta ) {
17859
17860 var data = THREE.Material.prototype.toJSON.call( this, meta );
17861
17862 data.uniforms = this.uniforms;
17863 data.attributes = this.attributes;
17864 data.vertexShader = this.vertexShader;
17865 data.fragmentShader = this.fragmentShader;
17866
17867 return data;
17868
17869 };
17870
17871
17872
17877 THREE.RawShaderMaterial = function ( parameters ) {
17878
17879 THREE.ShaderMaterial.call( this, parameters );
17880
17881 this.type = 'RawShaderMaterial';
17882
17883 };
17884
17885 THREE.RawShaderMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype );
17886 THREE.RawShaderMaterial.prototype.constructor = THREE.RawShaderMaterial;
17887
17888
17908 THREE.SpriteMaterial = function ( parameters ) {
17909
17910 THREE.Material.call( this );
17911
17912 this.type = 'SpriteMaterial';
17913
17914 this.color = new THREE.Color( 0xffffff );
17915 this.map = null;
17916
17917 this.rotation = 0;
17918
17919 this.fog = false;
17920
17921
17922
17923 this.setValues( parameters );
17924
17925 };
17926
17927 THREE.SpriteMaterial.prototype = Object.create( THREE.Material.prototype );
17928 THREE.SpriteMaterial.prototype.constructor = THREE.SpriteMaterial;
17929
17930 THREE.SpriteMaterial.prototype.copy = function ( source ) {
17931
17932 THREE.Material.prototype.copy.call( this, source );
17933
17934 this.color.copy( source.color );
17935 this.map = source.map;
17936
17937 this.rotation = source.rotation;
17938
17939 this.fog = source.fog;
17940
17941 return this;
17942
17943 };
17944
17945
17946
17953 THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
17954
17955 Object.defineProperty( this, 'id', { value: THREE.TextureIdCount ++ } );
17956
17957 this.uuid = THREE.Math.generateUUID();
17958
17959 this.name = '';
17960 this.sourceFile = '';
17961
17962 this.image = image !== undefined ? image : THREE.Texture.DEFAULT_IMAGE;
17963 this.mipmaps = [];
17964
17965 this.mapping = mapping !== undefined ? mapping : THREE.Texture.DEFAULT_MAPPING;
17966
17967 this.wrapS = wrapS !== undefined ? wrapS : THREE.ClampToEdgeWrapping;
17968 this.wrapT = wrapT !== undefined ? wrapT : THREE.ClampToEdgeWrapping;
17969
17970 this.magFilter = magFilter !== undefined ? magFilter : THREE.LinearFilter;
17971 this.minFilter = minFilter !== undefined ? minFilter : THREE.LinearMipMapLinearFilter;
17972
17973 this.anisotropy = anisotropy !== undefined ? anisotropy : 1;
17974
17975 this.format = format !== undefined ? format : THREE.RGBAFormat;
17976 this.type = type !== undefined ? type : THREE.UnsignedByteType;
17977
17978 this.offset = new THREE.Vector2( 0, 0 );
17979 this.repeat = new THREE.Vector2( 1, 1 );
17980
17981 this.generateMipmaps = true;
17982 this.premultiplyAlpha = false;
17983 this.flipY = true;
17984 this.unpackAlignment = 4;
17985
17986 this.version = 0;
17987 this.onUpdate = null;
17988
17989 };
17990
17991 THREE.Texture.DEFAULT_IMAGE = undefined;
17992 THREE.Texture.DEFAULT_MAPPING = THREE.UVMapping;
17993
17994 THREE.Texture.prototype = {
17995
17996 constructor: THREE.Texture,
17997
17998 set needsUpdate ( value ) {
17999
18000 if ( value === true ) this.version ++;
18001
18002 },
18003
18004 clone: function () {
18005
18006 return new this.constructor().copy( this );
18007
18008 },
18009
18010 copy: function ( source ) {
18011
18012 this.image = source.image;
18013 this.mipmaps = source.mipmaps.slice( 0 );
18014
18015 this.mapping = source.mapping;
18016
18017 this.wrapS = source.wrapS;
18018 this.wrapT = source.wrapT;
18019
18020 this.magFilter = source.magFilter;
18021 this.minFilter = source.minFilter;
18022
18023 this.anisotropy = source.anisotropy;
18024
18025 this.format = source.format;
18026 this.type = source.type;
18027
18028 this.offset.copy( source.offset );
18029 this.repeat.copy( source.repeat );
18030
18031 this.generateMipmaps = source.generateMipmaps;
18032 this.premultiplyAlpha = source.premultiplyAlpha;
18033 this.flipY = source.flipY;
18034 this.unpackAlignment = source.unpackAlignment;
18035
18036 return this;
18037
18038 },
18039
18040 toJSON: function ( meta ) {
18041
18042 if ( meta.textures[ this.uuid ] !== undefined ) {
18043
18044 return meta.textures[ this.uuid ];
18045
18046 }
18047
18048 function getDataURL( image ) {
18049
18050 var canvas;
18051
18052 if ( image.toDataURL !== undefined ) {
18053
18054 canvas = image;
18055
18056 } else {
18057
18058 canvas = document.createElement( 'canvas' );
18059 canvas.width = image.width;
18060 canvas.height = image.height;
18061
18062 canvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );
18063
18064 }
18065
18066 if ( canvas.width > 2048 || canvas.height > 2048 ) {
18067
18068 return canvas.toDataURL( 'image/jpeg', 0.6 );
18069
18070 } else {
18071
18072 return canvas.toDataURL( 'image/png' );
18073
18074 }
18075
18076 }
18077
18078 var output = {
18079 metadata: {
18080 version: 4.4,
18081 type: 'Texture',
18082 generator: 'Texture.toJSON'
18083 },
18084
18085 uuid: this.uuid,
18086 name: this.name,
18087
18088 mapping: this.mapping,
18089
18090 repeat: [ this.repeat.x, this.repeat.y ],
18091 offset: [ this.offset.x, this.offset.y ],
18092 wrap: [ this.wrapS, this.wrapT ],
18093
18094 minFilter: this.minFilter,
18095 magFilter: this.magFilter,
18096 anisotropy: this.anisotropy
18097 };
18098
18099 if ( this.image !== undefined ) {
18100
18101
18102
18103 var image = this.image;
18104
18105 if ( image.uuid === undefined ) {
18106
18107 image.uuid = THREE.Math.generateUUID();
18108
18109 }
18110
18111 if ( meta.images[ image.uuid ] === undefined ) {
18112
18113 meta.images[ image.uuid ] = {
18114 uuid: image.uuid,
18115 url: getDataURL( image )
18116 };
18117
18118 }
18119
18120 output.image = image.uuid;
18121
18122 }
18123
18124 meta.textures[ this.uuid ] = output;
18125
18126 return output;
18127
18128 },
18129
18130 dispose: function () {
18131
18132 this.dispatchEvent( { type: 'dispose' } );
18133
18134 },
18135
18136 transformUv: function ( uv ) {
18137
18138 if ( this.mapping !== THREE.UVMapping ) return;
18139
18140 uv.multiply( this.repeat );
18141 uv.add( this.offset );
18142
18143 if ( uv.x < 0 || uv.x > 1 ) {
18144
18145 switch ( this.wrapS ) {
18146
18147 case THREE.RepeatWrapping:
18148
18149 uv.x = uv.x - Math.floor( uv.x );
18150 break;
18151
18152 case THREE.ClampToEdgeWrapping:
18153
18154 uv.x = uv.x < 0 ? 0 : 1;
18155 break;
18156
18157 case THREE.MirroredRepeatWrapping:
18158
18159 if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {
18160
18161 uv.x = Math.ceil( uv.x ) - uv.x;
18162
18163 } else {
18164
18165 uv.x = uv.x - Math.floor( uv.x );
18166
18167 }
18168 break;
18169
18170 }
18171
18172 }
18173
18174 if ( uv.y < 0 || uv.y > 1 ) {
18175
18176 switch ( this.wrapT ) {
18177
18178 case THREE.RepeatWrapping:
18179
18180 uv.y = uv.y - Math.floor( uv.y );
18181 break;
18182
18183 case THREE.ClampToEdgeWrapping:
18184
18185 uv.y = uv.y < 0 ? 0 : 1;
18186 break;
18187
18188 case THREE.MirroredRepeatWrapping:
18189
18190 if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {
18191
18192 uv.y = Math.ceil( uv.y ) - uv.y;
18193
18194 } else {
18195
18196 uv.y = uv.y - Math.floor( uv.y );
18197
18198 }
18199 break;
18200
18201 }
18202
18203 }
18204
18205 if ( this.flipY ) {
18206
18207 uv.y = 1 - uv.y;
18208
18209 }
18210
18211 }
18212
18213 };
18214
18215 THREE.EventDispatcher.prototype.apply( THREE.Texture.prototype );
18216
18217 THREE.TextureIdCount = 0;
18218
18219
18220
18225 THREE.CanvasTexture = function ( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
18226
18227 THREE.Texture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
18228
18229 this.needsUpdate = true;
18230
18231 };
18232
18233 THREE.CanvasTexture.prototype = Object.create( THREE.Texture.prototype );
18234 THREE.CanvasTexture.prototype.constructor = THREE.CanvasTexture;
18235
18236
18237
18242 THREE.CubeTexture = function ( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
18243
18244 mapping = mapping !== undefined ? mapping : THREE.CubeReflectionMapping;
18245
18246 THREE.Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
18247
18248 this.images = images;
18249 this.flipY = false;
18250
18251 };
18252
18253 THREE.CubeTexture.prototype = Object.create( THREE.Texture.prototype );
18254 THREE.CubeTexture.prototype.constructor = THREE.CubeTexture;
18255
18256 THREE.CubeTexture.prototype.copy = function ( source ) {
18257
18258 THREE.Texture.prototype.copy.call( this, source );
18259
18260 this.images = source.images;
18261
18262 return this;
18263
18264 };
18265
18266
18271 THREE.CompressedTexture = function ( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy ) {
18272
18273 THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
18274
18275 this.image = { width: width, height: height };
18276 this.mipmaps = mipmaps;
18277
18278
18279
18280
18281 this.flipY = false;
18282
18283
18284
18285
18286 this.generateMipmaps = false;
18287
18288 };
18289
18290 THREE.CompressedTexture.prototype = Object.create( THREE.Texture.prototype );
18291 THREE.CompressedTexture.prototype.constructor = THREE.CompressedTexture;
18292
18293
18294
18299 THREE.DataTexture = function ( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy ) {
18300
18301 THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
18302
18303 this.image = { data: data, width: width, height: height };
18304
18305 this.magFilter = magFilter !== undefined ? magFilter : THREE.NearestFilter;
18306 this.minFilter = minFilter !== undefined ? minFilter : THREE.NearestFilter;
18307
18308 this.flipY = false;
18309 this.generateMipmaps = false;
18310
18311 };
18312
18313 THREE.DataTexture.prototype = Object.create( THREE.Texture.prototype );
18314 THREE.DataTexture.prototype.constructor = THREE.DataTexture;
18315
18316
18317
18322 THREE.VideoTexture = function ( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
18323
18324 THREE.Texture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
18325
18326 this.generateMipmaps = false;
18327
18328 var scope = this;
18329
18330 function update() {
18331
18332 requestAnimationFrame( update );
18333
18334 if ( video.readyState === video.HAVE_ENOUGH_DATA ) {
18335
18336 scope.needsUpdate = true;
18337
18338 }
18339
18340 }
18341
18342 update();
18343
18344 };
18345
18346 THREE.VideoTexture.prototype = Object.create( THREE.Texture.prototype );
18347 THREE.VideoTexture.prototype.constructor = THREE.VideoTexture;
18348
18349
18350
18355 THREE.Group = function () {
18356
18357 THREE.Object3D.call( this );
18358
18359 this.type = 'Group';
18360
18361 };
18362
18363 THREE.Group.prototype = Object.create( THREE.Object3D.prototype );
18364 THREE.Group.prototype.constructor = THREE.Group;
18365
18366
18371 THREE.Points = function ( geometry, material ) {
18372
18373 THREE.Object3D.call( this );
18374
18375 this.type = 'Points';
18376
18377 this.geometry = geometry !== undefined ? geometry : new THREE.Geometry();
18378 this.material = material !== undefined ? material : new THREE.PointsMaterial( { color: Math.random() * 0xffffff } );
18379
18380 };
18381
18382 THREE.Points.prototype = Object.create( THREE.Object3D.prototype );
18383 THREE.Points.prototype.constructor = THREE.Points;
18384
18385 THREE.Points.prototype.raycast = ( function () {
18386
18387 var inverseMatrix = new THREE.Matrix4();
18388 var ray = new THREE.Ray();
18389
18390 return function raycast( raycaster, intersects ) {
18391
18392 var object = this;
18393 var geometry = object.geometry;
18394 var threshold = raycaster.params.Points.threshold;
18395
18396 inverseMatrix.getInverse( this.matrixWorld );
18397 ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
18398
18399 if ( geometry.boundingBox !== null ) {
18400
18401 if ( ray.isIntersectionBox( geometry.boundingBox ) === false ) {
18402
18403 return;
18404
18405 }
18406
18407 }
18408
18409 var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
18410 var localThresholdSq = localThreshold * localThreshold;
18411 var position = new THREE.Vector3();
18412
18413 function testPoint( point, index ) {
18414
18415 var rayPointDistanceSq = ray.distanceSqToPoint( point );
18416
18417 if ( rayPointDistanceSq < localThresholdSq ) {
18418
18419 var intersectPoint = ray.closestPointToPoint( point );
18420 intersectPoint.applyMatrix4( object.matrixWorld );
18421
18422 var distance = raycaster.ray.origin.distanceTo( intersectPoint );
18423
18424 if ( distance < raycaster.near || distance > raycaster.far ) return;
18425
18426 intersects.push( {
18427
18428 distance: distance,
18429 distanceToRay: Math.sqrt( rayPointDistanceSq ),
18430 point: intersectPoint.clone(),
18431 index: index,
18432 face: null,
18433 object: object
18434
18435 } );
18436
18437 }
18438
18439 }
18440
18441 if ( geometry instanceof THREE.BufferGeometry ) {
18442
18443 var index = geometry.index;
18444 var attributes = geometry.attributes;
18445 var positions = attributes.position.array;
18446
18447 if ( index !== null ) {
18448
18449 var indices = index.array;
18450
18451 for ( var i = 0, il = indices.length; i < il; i ++ ) {
18452
18453 var a = indices[ i ];
18454
18455 position.fromArray( positions, a * 3 );
18456
18457 testPoint( position, a );
18458
18459 }
18460
18461 } else {
18462
18463 for ( var i = 0, l = positions.length / 3; i < l; i ++ ) {
18464
18465 position.fromArray( positions, i * 3 );
18466
18467 testPoint( position, i );
18468
18469 }
18470
18471 }
18472
18473 } else {
18474
18475 var vertices = geometry.vertices;
18476
18477 for ( var i = 0, l = vertices.length; i < l; i ++ ) {
18478
18479 testPoint( vertices[ i ], i );
18480
18481 }
18482
18483 }
18484
18485 };
18486
18487 }() );
18488
18489 THREE.Points.prototype.clone = function () {
18490
18491 return new this.constructor( this.geometry, this.material ).copy( this );
18492
18493 };
18494
18495
18496
18497 THREE.PointCloud = function ( geometry, material ) {
18498
18499 console.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );
18500 return new THREE.Points( geometry, material );
18501
18502 };
18503
18504 THREE.ParticleSystem = function ( geometry, material ) {
18505
18506 console.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );
18507 return new THREE.Points( geometry, material );
18508
18509 };
18510
18511
18512
18517 THREE.Line = function ( geometry, material, mode ) {
18518
18519 if ( mode === 1 ) {
18520
18521 console.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );
18522 return new THREE.LineSegments( geometry, material );
18523
18524 }
18525
18526 THREE.Object3D.call( this );
18527
18528 this.type = 'Line';
18529
18530 this.geometry = geometry !== undefined ? geometry : new THREE.Geometry();
18531 this.material = material !== undefined ? material : new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } );
18532
18533 };
18534
18535 THREE.Line.prototype = Object.create( THREE.Object3D.prototype );
18536 THREE.Line.prototype.constructor = THREE.Line;
18537
18538 THREE.Line.prototype.raycast = ( function () {
18539
18540 var inverseMatrix = new THREE.Matrix4();
18541 var ray = new THREE.Ray();
18542 var sphere = new THREE.Sphere();
18543
18544 return function raycast( raycaster, intersects ) {
18545
18546 var precision = raycaster.linePrecision;
18547 var precisionSq = precision * precision;
18548
18549 var geometry = this.geometry;
18550
18551 if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
18552
18553
18554
18555 sphere.copy( geometry.boundingSphere );
18556 sphere.applyMatrix4( this.matrixWorld );
18557
18558 if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) {
18559
18560 return;
18561
18562 }
18563
18564 inverseMatrix.getInverse( this.matrixWorld );
18565 ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
18566
18567 var vStart = new THREE.Vector3();
18568 var vEnd = new THREE.Vector3();
18569 var interSegment = new THREE.Vector3();
18570 var interRay = new THREE.Vector3();
18571 var step = this instanceof THREE.LineSegments ? 2 : 1;
18572
18573 if ( geometry instanceof THREE.BufferGeometry ) {
18574
18575 var index = geometry.index;
18576 var attributes = geometry.attributes;
18577
18578 if ( index !== null ) {
18579
18580 var indices = index.array;
18581 var positions = attributes.position.array;
18582
18583 for ( var i = 0, l = indices.length - 1; i < l; i += step ) {
18584
18585 var a = indices[ i ];
18586 var b = indices[ i + 1 ];
18587
18588 vStart.fromArray( positions, a * 3 );
18589 vEnd.fromArray( positions, b * 3 );
18590
18591 var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
18592
18593 if ( distSq > precisionSq ) continue;
18594
18595 interRay.applyMatrix4( this.matrixWorld );
18596
18597 var distance = raycaster.ray.origin.distanceTo( interRay );
18598
18599 if ( distance < raycaster.near || distance > raycaster.far ) continue;
18600
18601 intersects.push( {
18602
18603 distance: distance,
18604
18605
18606 point: interSegment.clone().applyMatrix4( this.matrixWorld ),
18607 index: i,
18608 face: null,
18609 faceIndex: null,
18610 object: this
18611
18612 } );
18613
18614 }
18615
18616 } else {
18617
18618 var positions = attributes.position.array;
18619
18620 for ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {
18621
18622 vStart.fromArray( positions, 3 * i );
18623 vEnd.fromArray( positions, 3 * i + 3 );
18624
18625 var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
18626
18627 if ( distSq > precisionSq ) continue;
18628
18629 interRay.applyMatrix4( this.matrixWorld );
18630
18631 var distance = raycaster.ray.origin.distanceTo( interRay );
18632
18633 if ( distance < raycaster.near || distance > raycaster.far ) continue;
18634
18635 intersects.push( {
18636
18637 distance: distance,
18638
18639
18640 point: interSegment.clone().applyMatrix4( this.matrixWorld ),
18641 index: i,
18642 face: null,
18643 faceIndex: null,
18644 object: this
18645
18646 } );
18647
18648 }
18649
18650 }
18651
18652 } else if ( geometry instanceof THREE.Geometry ) {
18653
18654 var vertices = geometry.vertices;
18655 var nbVertices = vertices.length;
18656
18657 for ( var i = 0; i < nbVertices - 1; i += step ) {
18658
18659 var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
18660
18661 if ( distSq > precisionSq ) continue;
18662
18663 interRay.applyMatrix4( this.matrixWorld );
18664
18665 var distance = raycaster.ray.origin.distanceTo( interRay );
18666
18667 if ( distance < raycaster.near || distance > raycaster.far ) continue;
18668
18669 intersects.push( {
18670
18671 distance: distance,
18672
18673
18674 point: interSegment.clone().applyMatrix4( this.matrixWorld ),
18675 index: i,
18676 face: null,
18677 faceIndex: null,
18678 object: this
18679
18680 } );
18681
18682 }
18683
18684 }
18685
18686 };
18687
18688 }() );
18689
18690 THREE.Line.prototype.clone = function () {
18691
18692 return new this.constructor( this.geometry, this.material ).copy( this );
18693
18694 };
18695
18696
18697
18698 THREE.LineStrip = 0;
18699 THREE.LinePieces = 1;
18700
18701
18702
18707 THREE.LineSegments = function ( geometry, material ) {
18708
18709 THREE.Line.call( this, geometry, material );
18710
18711 this.type = 'LineSegments';
18712
18713 };
18714
18715 THREE.LineSegments.prototype = Object.create( THREE.Line.prototype );
18716 THREE.LineSegments.prototype.constructor = THREE.LineSegments;
18717
18718
18719
18727 THREE.Mesh = function ( geometry, material ) {
18728
18729 THREE.Object3D.call( this );
18730
18731 this.type = 'Mesh';
18732
18733 this.geometry = geometry !== undefined ? geometry : new THREE.Geometry();
18734 this.material = material !== undefined ? material : new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } );
18735
18736 this.updateMorphTargets();
18737
18738 };
18739
18740 THREE.Mesh.prototype = Object.create( THREE.Object3D.prototype );
18741 THREE.Mesh.prototype.constructor = THREE.Mesh;
18742
18743 THREE.Mesh.prototype.updateMorphTargets = function () {
18744
18745 if ( this.geometry.morphTargets !== undefined && this.geometry.morphTargets.length > 0 ) {
18746
18747 this.morphTargetBase = - 1;
18748 this.morphTargetInfluences = [];
18749 this.morphTargetDictionary = {};
18750
18751 for ( var m = 0, ml = this.geometry.morphTargets.length; m < ml; m ++ ) {
18752
18753 this.morphTargetInfluences.push( 0 );
18754 this.morphTargetDictionary[ this.geometry.morphTargets[ m ].name ] = m;
18755
18756 }
18757
18758 }
18759
18760 };
18761
18762 THREE.Mesh.prototype.getMorphTargetIndexByName = function ( name ) {
18763
18764 if ( this.morphTargetDictionary[ name ] !== undefined ) {
18765
18766 return this.morphTargetDictionary[ name ];
18767
18768 }
18769
18770 console.warn( 'THREE.Mesh.getMorphTargetIndexByName: morph target ' + name + ' does not exist. Returning 0.' );
18771
18772 return 0;
18773
18774 };
18775
18776
18777 THREE.Mesh.prototype.raycast = ( function () {
18778
18779 var inverseMatrix = new THREE.Matrix4();
18780 var ray = new THREE.Ray();
18781 var sphere = new THREE.Sphere();
18782
18783 var vA = new THREE.Vector3();
18784 var vB = new THREE.Vector3();
18785 var vC = new THREE.Vector3();
18786
18787 var tempA = new THREE.Vector3();
18788 var tempB = new THREE.Vector3();
18789 var tempC = new THREE.Vector3();
18790
18791 var uvA = new THREE.Vector2();
18792 var uvB = new THREE.Vector2();
18793 var uvC = new THREE.Vector2();
18794
18795 var barycoord = new THREE.Vector3();
18796
18797 var intersectionPoint = new THREE.Vector3();
18798 var intersectionPointWorld = new THREE.Vector3();
18799
18800 function uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {
18801
18802 THREE.Triangle.barycoordFromPoint( point, p1, p2, p3, barycoord );
18803
18804 uv1.multiplyScalar( barycoord.x );
18805 uv2.multiplyScalar( barycoord.y );
18806 uv3.multiplyScalar( barycoord.z );
18807
18808 uv1.add( uv2 ).add( uv3 );
18809
18810 return uv1.clone();
18811
18812 }
18813
18814 function checkIntersection( object, raycaster, ray, pA, pB, pC, point ){
18815
18816 var intersect;
18817 var material = object.material;
18818
18819 if ( material.side === THREE.BackSide ) {
18820
18821 intersect = ray.intersectTriangle( pC, pB, pA, true, point );
18822
18823 } else {
18824
18825 intersect = ray.intersectTriangle( pA, pB, pC, material.side !== THREE.DoubleSide, point );
18826
18827 }
18828
18829 if ( intersect === null ) return null;
18830
18831 intersectionPointWorld.copy( point );
18832 intersectionPointWorld.applyMatrix4( object.matrixWorld );
18833
18834 var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );
18835
18836 if ( distance < raycaster.near || distance > raycaster.far ) return null;
18837
18838 return {
18839 distance: distance,
18840 point: intersectionPointWorld.clone(),
18841 object: object
18842 };
18843
18844 }
18845
18846 function checkBufferGeometryIntersection( object, raycaster, ray, positions, uvs, a, b, c ) {
18847
18848 vA.fromArray( positions, a * 3 );
18849 vB.fromArray( positions, b * 3 );
18850 vC.fromArray( positions, c * 3 );
18851
18852 var intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );
18853
18854 if ( intersection ) {
18855
18856 if ( uvs ) {
18857
18858 uvA.fromArray( uvs, a * 2 );
18859 uvB.fromArray( uvs, b * 2 );
18860 uvC.fromArray( uvs, c * 2 );
18861
18862 intersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );
18863
18864 }
18865
18866 intersection.face = new THREE.Face3( a, b, c, THREE.Triangle.normal( vA, vB, vC ) );
18867 intersection.faceIndex = a;
18868
18869 }
18870
18871 return intersection;
18872
18873 }
18874
18875 return function raycast( raycaster, intersects ) {
18876
18877 var geometry = this.geometry;
18878 var material = this.material;
18879
18880 if ( material === undefined ) return;
18881
18882
18883
18884 if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
18885
18886 var matrixWorld = this.matrixWorld;
18887
18888 sphere.copy( geometry.boundingSphere );
18889 sphere.applyMatrix4( matrixWorld );
18890
18891 if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) return;
18892
18893
18894
18895 inverseMatrix.getInverse( matrixWorld );
18896 ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
18897
18898 if ( geometry.boundingBox !== null ) {
18899
18900 if ( ray.isIntersectionBox( geometry.boundingBox ) === false ) return;
18901
18902 }
18903
18904 var uvs, intersection;
18905
18906 if ( geometry instanceof THREE.BufferGeometry ) {
18907
18908 var a, b, c;
18909 var index = geometry.index;
18910 var attributes = geometry.attributes;
18911 var positions = attributes.position.array;
18912
18913 if ( attributes.uv !== undefined ){
18914
18915 uvs = attributes.uv.array;
18916
18917 }
18918
18919 if ( index !== null ) {
18920
18921 var indices = index.array;
18922
18923 for ( var i = 0, l = indices.length; i < l; i += 3 ) {
18924
18925 a = indices[ i ];
18926 b = indices[ i + 1 ];
18927 c = indices[ i + 2 ];
18928
18929 intersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c );
18930
18931 if ( intersection ) {
18932
18933 intersection.faceIndex = Math.floor( i / 3 );
18934 intersects.push( intersection );
18935
18936 }
18937
18938 }
18939
18940 } else {
18941
18942
18943 for ( var i = 0, l = positions.length; i < l; i += 9 ) {
18944
18945 a = i / 3;
18946 b = a + 1;
18947 c = a + 2;
18948
18949 intersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c );
18950
18951 if ( intersection ) {
18952
18953 intersection.index = a;
18954 intersects.push( intersection );
18955
18956 }
18957
18958 }
18959
18960 }
18961
18962 } else if ( geometry instanceof THREE.Geometry ) {
18963
18964 var fvA, fvB, fvC;
18965 var isFaceMaterial = material instanceof THREE.MeshFaceMaterial;
18966 var materials = isFaceMaterial === true ? material.materials : null;
18967
18968 var vertices = geometry.vertices;
18969 var faces = geometry.faces;
18970 var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
18971 if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;
18972
18973 for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
18974
18975 var face = faces[ f ];
18976 var faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;
18977
18978 if ( faceMaterial === undefined ) continue;
18979
18980 fvA = vertices[ face.a ];
18981 fvB = vertices[ face.b ];
18982 fvC = vertices[ face.c ];
18983
18984 if ( faceMaterial.morphTargets === true ) {
18985
18986 var morphTargets = geometry.morphTargets;
18987 var morphInfluences = this.morphTargetInfluences;
18988
18989 vA.set( 0, 0, 0 );
18990 vB.set( 0, 0, 0 );
18991 vC.set( 0, 0, 0 );
18992
18993 for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {
18994
18995 var influence = morphInfluences[ t ];
18996
18997 if ( influence === 0 ) continue;
18998
18999 var targets = morphTargets[ t ].vertices;
19000
19001 vA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );
19002 vB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );
19003 vC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );
19004
19005 }
19006
19007 vA.add( fvA );
19008 vB.add( fvB );
19009 vC.add( fvC );
19010
19011 fvA = vA;
19012 fvB = vB;
19013 fvC = vC;
19014
19015 }
19016
19017 intersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );
19018
19019 if ( intersection ) {
19020
19021 if ( uvs ) {
19022
19023 var uvs_f = uvs[ f ];
19024 uvA.copy( uvs_f[ 0 ] );
19025 uvB.copy( uvs_f[ 1 ] );
19026 uvC.copy( uvs_f[ 2 ] );
19027
19028 intersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );
19029
19030 }
19031
19032 intersection.face = face;
19033 intersection.faceIndex = f;
19034 intersects.push( intersection );
19035
19036 }
19037
19038 }
19039
19040 }
19041
19042 };
19043
19044 }() );
19045
19046 THREE.Mesh.prototype.clone = function () {
19047
19048 return new this.constructor( this.geometry, this.material ).copy( this );
19049
19050 };
19051
19052
19053
19060 THREE.Bone = function ( skin ) {
19061
19062 THREE.Object3D.call( this );
19063
19064 this.type = 'Bone';
19065
19066 this.skin = skin;
19067
19068 };
19069
19070 THREE.Bone.prototype = Object.create( THREE.Object3D.prototype );
19071 THREE.Bone.prototype.constructor = THREE.Bone;
19072
19073 THREE.Bone.prototype.copy = function ( source ) {
19074
19075 THREE.Object3D.prototype.copy.call( this, source );
19076
19077 this.skin = source.skin;
19078
19079 return this;
19080
19081 };
19082
19083
19084
19092 THREE.Skeleton = function ( bones, boneInverses, useVertexTexture ) {
19093
19094 this.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;
19095
19096 this.identityMatrix = new THREE.Matrix4();
19097
19098
19099
19100 bones = bones || [];
19101
19102 this.bones = bones.slice( 0 );
19103
19104
19105
19106 if ( this.useVertexTexture ) {
19107
19108
19109
19110
19111
19112
19113
19114
19115
19116 var size = Math.sqrt( this.bones.length * 4 );
19117 size = THREE.Math.nextPowerOfTwo( Math.ceil( size ) );
19118 size = Math.max( size, 4 );
19119
19120 this.boneTextureWidth = size;
19121 this.boneTextureHeight = size;
19122
19123 this.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 );
19124 this.boneTexture = new THREE.DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, THREE.RGBAFormat, THREE.FloatType );
19125
19126 } else {
19127
19128 this.boneMatrices = new Float32Array( 16 * this.bones.length );
19129
19130 }
19131
19132
19133
19134 if ( boneInverses === undefined ) {
19135
19136 this.calculateInverses();
19137
19138 } else {
19139
19140 if ( this.bones.length === boneInverses.length ) {
19141
19142 this.boneInverses = boneInverses.slice( 0 );
19143
19144 } else {
19145
19146 console.warn( 'THREE.Skeleton bonInverses is the wrong length.' );
19147
19148 this.boneInverses = [];
19149
19150 for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
19151
19152 this.boneInverses.push( new THREE.Matrix4() );
19153
19154 }
19155
19156 }
19157
19158 }
19159
19160 };
19161
19162 THREE.Skeleton.prototype.calculateInverses = function () {
19163
19164 this.boneInverses = [];
19165
19166 for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
19167
19168 var inverse = new THREE.Matrix4();
19169
19170 if ( this.bones[ b ] ) {
19171
19172 inverse.getInverse( this.bones[ b ].matrixWorld );
19173
19174 }
19175
19176 this.boneInverses.push( inverse );
19177
19178 }
19179
19180 };
19181
19182 THREE.Skeleton.prototype.pose = function () {
19183
19184 var bone;
19185
19186
19187
19188 for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
19189
19190 bone = this.bones[ b ];
19191
19192 if ( bone ) {
19193
19194 bone.matrixWorld.getInverse( this.boneInverses[ b ] );
19195
19196 }
19197
19198 }
19199
19200
19201
19202 for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
19203
19204 bone = this.bones[ b ];
19205
19206 if ( bone ) {
19207
19208 if ( bone.parent ) {
19209
19210 bone.matrix.getInverse( bone.parent.matrixWorld );
19211 bone.matrix.multiply( bone.matrixWorld );
19212
19213 } else {
19214
19215 bone.matrix.copy( bone.matrixWorld );
19216
19217 }
19218
19219 bone.matrix.decompose( bone.position, bone.quaternion, bone.scale );
19220
19221 }
19222
19223 }
19224
19225 };
19226
19227 THREE.Skeleton.prototype.update = ( function () {
19228
19229 var offsetMatrix = new THREE.Matrix4();
19230
19231 return function update() {
19232
19233
19234
19235 for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
19236
19237
19238
19239 var matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;
19240
19241 offsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );
19242 offsetMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
19243
19244 }
19245
19246 if ( this.useVertexTexture ) {
19247
19248 this.boneTexture.needsUpdate = true;
19249
19250 }
19251
19252 };
19253
19254 } )();
19255
19256 THREE.Skeleton.prototype.clone = function () {
19257
19258 return new THREE.Skeleton( this.bones, this.boneInverses, this.useVertexTexture );
19259
19260 };
19261
19262
19263
19270 THREE.SkinnedMesh = function ( geometry, material, useVertexTexture ) {
19271
19272 THREE.Mesh.call( this, geometry, material );
19273
19274 this.type = 'SkinnedMesh';
19275
19276 this.bindMode = "attached";
19277 this.bindMatrix = new THREE.Matrix4();
19278 this.bindMatrixInverse = new THREE.Matrix4();
19279
19280
19281
19282
19283
19284
19285 var bones = [];
19286
19287 if ( this.geometry && this.geometry.bones !== undefined ) {
19288
19289 var bone, gbone;
19290
19291 for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {
19292
19293 gbone = this.geometry.bones[ b ];
19294
19295 bone = new THREE.Bone( this );
19296 bones.push( bone );
19297
19298 bone.name = gbone.name;
19299 bone.position.fromArray( gbone.pos );
19300 bone.quaternion.fromArray( gbone.rotq );
19301 if ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );
19302
19303 }
19304
19305 for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {
19306
19307 gbone = this.geometry.bones[ b ];
19308
19309 if ( gbone.parent !== - 1 && gbone.parent !== null) {
19310
19311 bones[ gbone.parent ].add( bones[ b ] );
19312
19313 } else {
19314
19315 this.add( bones[ b ] );
19316
19317 }
19318
19319 }
19320
19321 }
19322
19323 this.normalizeSkinWeights();
19324
19325 this.updateMatrixWorld( true );
19326 this.bind( new THREE.Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );
19327
19328 };
19329
19330
19331 THREE.SkinnedMesh.prototype = Object.create( THREE.Mesh.prototype );
19332 THREE.SkinnedMesh.prototype.constructor = THREE.SkinnedMesh;
19333
19334 THREE.SkinnedMesh.prototype.bind = function( skeleton, bindMatrix ) {
19335
19336 this.skeleton = skeleton;
19337
19338 if ( bindMatrix === undefined ) {
19339
19340 this.updateMatrixWorld( true );
19341
19342 this.skeleton.calculateInverses();
19343
19344 bindMatrix = this.matrixWorld;
19345
19346 }
19347
19348 this.bindMatrix.copy( bindMatrix );
19349 this.bindMatrixInverse.getInverse( bindMatrix );
19350
19351 };
19352
19353 THREE.SkinnedMesh.prototype.pose = function () {
19354
19355 this.skeleton.pose();
19356
19357 };
19358
19359 THREE.SkinnedMesh.prototype.normalizeSkinWeights = function () {
19360
19361 if ( this.geometry instanceof THREE.Geometry ) {
19362
19363 for ( var i = 0; i < this.geometry.skinIndices.length; i ++ ) {
19364
19365 var sw = this.geometry.skinWeights[ i ];
19366
19367 var scale = 1.0 / sw.lengthManhattan();
19368
19369 if ( scale !== Infinity ) {
19370
19371 sw.multiplyScalar( scale );
19372
19373 } else {
19374
19375 sw.set( 1 );
19376
19377 }
19378
19379 }
19380
19381 } else {
19382
19383
19384
19385 }
19386
19387 };
19388
19389 THREE.SkinnedMesh.prototype.updateMatrixWorld = function( force ) {
19390
19391 THREE.Mesh.prototype.updateMatrixWorld.call( this, true );
19392
19393 if ( this.bindMode === "attached" ) {
19394
19395 this.bindMatrixInverse.getInverse( this.matrixWorld );
19396
19397 } else if ( this.bindMode === "detached" ) {
19398
19399 this.bindMatrixInverse.getInverse( this.bindMatrix );
19400
19401 } else {
19402
19403 console.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );
19404
19405 }
19406
19407 };
19408
19409 THREE.SkinnedMesh.prototype.clone = function() {
19410
19411 return new this.constructor( this.geometry, this.material, this.useVertexTexture ).copy( this );
19412
19413 };
19414
19415
19416
19423 THREE.LOD = function () {
19424
19425 THREE.Object3D.call( this );
19426
19427 this.type = 'LOD';
19428
19429 Object.defineProperties( this, {
19430 levels: {
19431 enumerable: true,
19432 value: []
19433 },
19434 objects: {
19435 get: function () {
19436
19437 console.warn( 'THREE.LOD: .objects has been renamed to .levels.' );
19438 return this.levels;
19439
19440 }
19441 }
19442 } );
19443
19444 };
19445
19446
19447 THREE.LOD.prototype = Object.create( THREE.Object3D.prototype );
19448 THREE.LOD.prototype.constructor = THREE.LOD;
19449
19450 THREE.LOD.prototype.addLevel = function ( object, distance ) {
19451
19452 if ( distance === undefined ) distance = 0;
19453
19454 distance = Math.abs( distance );
19455
19456 var levels = this.levels;
19457
19458 for ( var l = 0; l < levels.length; l ++ ) {
19459
19460 if ( distance < levels[ l ].distance ) {
19461
19462 break;
19463
19464 }
19465
19466 }
19467
19468 levels.splice( l, 0, { distance: distance, object: object } );
19469
19470 this.add( object );
19471
19472 };
19473
19474 THREE.LOD.prototype.getObjectForDistance = function ( distance ) {
19475
19476 var levels = this.levels;
19477
19478 for ( var i = 1, l = levels.length; i < l; i ++ ) {
19479
19480 if ( distance < levels[ i ].distance ) {
19481
19482 break;
19483
19484 }
19485
19486 }
19487
19488 return levels[ i - 1 ].object;
19489
19490 };
19491
19492 THREE.LOD.prototype.raycast = ( function () {
19493
19494 var matrixPosition = new THREE.Vector3();
19495
19496 return function raycast( raycaster, intersects ) {
19497
19498 matrixPosition.setFromMatrixPosition( this.matrixWorld );
19499
19500 var distance = raycaster.ray.origin.distanceTo( matrixPosition );
19501
19502 this.getObjectForDistance( distance ).raycast( raycaster, intersects );
19503
19504 };
19505
19506 }() );
19507
19508 THREE.LOD.prototype.update = function () {
19509
19510 var v1 = new THREE.Vector3();
19511 var v2 = new THREE.Vector3();
19512
19513 return function update( camera ) {
19514
19515 var levels = this.levels;
19516
19517 if ( levels.length > 1 ) {
19518
19519 v1.setFromMatrixPosition( camera.matrixWorld );
19520 v2.setFromMatrixPosition( this.matrixWorld );
19521
19522 var distance = v1.distanceTo( v2 );
19523
19524 levels[ 0 ].object.visible = true;
19525
19526 for ( var i = 1, l = levels.length; i < l; i ++ ) {
19527
19528 if ( distance >= levels[ i ].distance ) {
19529
19530 levels[ i - 1 ].object.visible = false;
19531 levels[ i ].object.visible = true;
19532
19533 } else {
19534
19535 break;
19536
19537 }
19538
19539 }
19540
19541 for ( ; i < l; i ++ ) {
19542
19543 levels[ i ].object.visible = false;
19544
19545 }
19546
19547 }
19548
19549 };
19550
19551 }();
19552
19553 THREE.LOD.prototype.copy = function ( source ) {
19554
19555 THREE.Object3D.prototype.copy.call( this, source, false );
19556
19557 var levels = source.levels;
19558
19559 for ( var i = 0, l = levels.length; i < l; i ++ ) {
19560
19561 var level = levels[ i ];
19562
19563 this.addLevel( level.object.clone(), level.distance );
19564
19565 }
19566
19567 return this;
19568
19569 };
19570
19571 THREE.LOD.prototype.toJSON = function ( meta ) {
19572
19573 var data = THREE.Object3D.prototype.toJSON.call( this, meta );
19574
19575 data.object.levels = [];
19576
19577 var levels = this.levels;
19578
19579 for ( var i = 0, l = levels.length; i < l; i ++ ) {
19580
19581 var level = levels[ i ];
19582
19583 data.object.levels.push( {
19584 object: level.object.uuid,
19585 distance: level.distance
19586 } );
19587
19588 }
19589
19590 return data;
19591
19592 };
19593
19594
19595
19601 THREE.Sprite = ( function () {
19602
19603 var indices = new Uint16Array( [ 0, 1, 2, 0, 2, 3 ] );
19604 var vertices = new Float32Array( [ - 0.5, - 0.5, 0, 0.5, - 0.5, 0, 0.5, 0.5, 0, - 0.5, 0.5, 0 ] );
19605 var uvs = new Float32Array( [ 0, 0, 1, 0, 1, 1, 0, 1 ] );
19606
19607 var geometry = new THREE.BufferGeometry();
19608 geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );
19609 geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
19610 geometry.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
19611
19612 return function Sprite( material ) {
19613
19614 THREE.Object3D.call( this );
19615
19616 this.type = 'Sprite';
19617
19618 this.geometry = geometry;
19619 this.material = ( material !== undefined ) ? material : new THREE.SpriteMaterial();
19620
19621 };
19622
19623 } )();
19624
19625 THREE.Sprite.prototype = Object.create( THREE.Object3D.prototype );
19626 THREE.Sprite.prototype.constructor = THREE.Sprite;
19627
19628 THREE.Sprite.prototype.raycast = ( function () {
19629
19630 var matrixPosition = new THREE.Vector3();
19631
19632 return function raycast( raycaster, intersects ) {
19633
19634 matrixPosition.setFromMatrixPosition( this.matrixWorld );
19635
19636 var distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );
19637 var guessSizeSq = this.scale.x * this.scale.y;
19638
19639 if ( distanceSq > guessSizeSq ) {
19640
19641 return;
19642
19643 }
19644
19645 intersects.push( {
19646
19647 distance: Math.sqrt( distanceSq ),
19648 point: this.position,
19649 face: null,
19650 object: this
19651
19652 } );
19653
19654 };
19655
19656 }() );
19657
19658 THREE.Sprite.prototype.clone = function () {
19659
19660 return new this.constructor( this.material ).copy( this );
19661
19662 };
19663
19664
19665
19666 THREE.Particle = THREE.Sprite;
19667
19668
19669
19675 THREE.LensFlare = function ( texture, size, distance, blending, color ) {
19676
19677 THREE.Object3D.call( this );
19678
19679 this.lensFlares = [];
19680
19681 this.positionScreen = new THREE.Vector3();
19682 this.customUpdateCallback = undefined;
19683
19684 if ( texture !== undefined ) {
19685
19686 this.add( texture, size, distance, blending, color );
19687
19688 }
19689
19690 };
19691
19692 THREE.LensFlare.prototype = Object.create( THREE.Object3D.prototype );
19693 THREE.LensFlare.prototype.constructor = THREE.LensFlare;
19694
19695
19696
19697
19698
19699
19700 THREE.LensFlare.prototype.add = function ( texture, size, distance, blending, color, opacity ) {
19701
19702 if ( size === undefined ) size = - 1;
19703 if ( distance === undefined ) distance = 0;
19704 if ( opacity === undefined ) opacity = 1;
19705 if ( color === undefined ) color = new THREE.Color( 0xffffff );
19706 if ( blending === undefined ) blending = THREE.NormalBlending;
19707
19708 distance = Math.min( distance, Math.max( 0, distance ) );
19709
19710 this.lensFlares.push( {
19711 texture: texture,
19712 size: size,
19713 distance: distance,
19714 x: 0, y: 0, z: 0,
19715 scale: 1,
19716 rotation: 0,
19717 opacity: opacity,
19718 color: color,
19719 blending: blending
19720 } );
19721
19722 };
19723
19724
19725
19726
19727
19728
19729 THREE.LensFlare.prototype.updateLensFlares = function () {
19730
19731 var f, fl = this.lensFlares.length;
19732 var flare;
19733 var vecX = - this.positionScreen.x * 2;
19734 var vecY = - this.positionScreen.y * 2;
19735
19736 for ( f = 0; f < fl; f ++ ) {
19737
19738 flare = this.lensFlares[ f ];
19739
19740 flare.x = this.positionScreen.x + vecX * flare.distance;
19741 flare.y = this.positionScreen.y + vecY * flare.distance;
19742
19743 flare.wantedRotation = flare.x * Math.PI * 0.25;
19744 flare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;
19745
19746 }
19747
19748 };
19749
19750 THREE.LensFlare.prototype.copy = function ( source ) {
19751
19752 THREE.Object3D.prototype.copy.call( this, source );
19753
19754 this.positionScreen.copy( source.positionScreen );
19755 this.customUpdateCallback = source.customUpdateCallback;
19756
19757 for ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {
19758
19759 this.lensFlares.push( source.lensFlares[ i ] );
19760
19761 }
19762
19763 return this;
19764
19765 };
19766
19767
19768
19773 THREE.Scene = function () {
19774
19775 THREE.Object3D.call( this );
19776
19777 this.type = 'Scene';
19778
19779 this.fog = null;
19780 this.overrideMaterial = null;
19781
19782 this.autoUpdate = true;
19783
19784 };
19785
19786 THREE.Scene.prototype = Object.create( THREE.Object3D.prototype );
19787 THREE.Scene.prototype.constructor = THREE.Scene;
19788
19789 THREE.Scene.prototype.copy = function ( source ) {
19790
19791 THREE.Object3D.prototype.copy.call( this, source );
19792
19793 if ( source.fog !== null ) this.fog = source.fog.clone();
19794 if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
19795
19796 this.autoUpdate = source.autoUpdate;
19797 this.matrixAutoUpdate = source.matrixAutoUpdate;
19798
19799 return this;
19800
19801 };
19802
19803
19804
19810 THREE.Fog = function ( color, near, far ) {
19811
19812 this.name = '';
19813
19814 this.color = new THREE.Color( color );
19815
19816 this.near = ( near !== undefined ) ? near : 1;
19817 this.far = ( far !== undefined ) ? far : 1000;
19818
19819 };
19820
19821 THREE.Fog.prototype.clone = function () {
19822
19823 return new THREE.Fog( this.color.getHex(), this.near, this.far );
19824
19825 };
19826
19827
19828
19834 THREE.FogExp2 = function ( color, density ) {
19835
19836 this.name = '';
19837
19838 this.color = new THREE.Color( color );
19839 this.density = ( density !== undefined ) ? density : 0.00025;
19840
19841 };
19842
19843 THREE.FogExp2.prototype.clone = function () {
19844
19845 return new THREE.FogExp2( this.color.getHex(), this.density );
19846
19847 };
19848
19849
19850
19851 THREE.ShaderChunk = {};
19852
19853
19854
19855 THREE.ShaderChunk[ 'alphamap_fragment'] = "#ifdef USE_ALPHAMAP\n\n diffuseColor.a *= texture2D( alphaMap, vUv ).g;\n\n#endif\n";
19856
19857
19858
19859 THREE.ShaderChunk[ 'alphamap_pars_fragment'] = "#ifdef USE_ALPHAMAP\n\n uniform sampler2D alphaMap;\n\n#endif\n";
19860
19861
19862
19863 THREE.ShaderChunk[ 'alphatest_fragment'] = "#ifdef ALPHATEST\n\n if ( diffuseColor.a < ALPHATEST ) discard;\n\n#endif\n";
19864
19865
19866
19867 THREE.ShaderChunk[ 'aomap_fragment'] = "#ifdef USE_AOMAP\n\n totalAmbientLight *= ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\n#endif\n";
19868
19869
19870
19871 THREE.ShaderChunk[ 'aomap_pars_fragment'] = "#ifdef USE_AOMAP\n\n uniform sampler2D aoMap;\n uniform float aoMapIntensity;\n\n#endif";
19872
19873
19874
19875 THREE.ShaderChunk[ 'begin_vertex'] = "\nvec3 transformed = vec3( position );\n";
19876
19877
19878
19879 THREE.ShaderChunk[ 'beginnormal_vertex'] = "\nvec3 objectNormal = vec3( normal );\n";
19880
19881
19882
19883 THREE.ShaderChunk[ 'bumpmap_pars_fragment'] = "#ifdef USE_BUMPMAP\n\n uniform sampler2D bumpMap;\n uniform float bumpScale;\n\n\n\n vec2 dHdxy_fwd() {\n\n vec2 dSTdx = dFdx( vUv );\n vec2 dSTdy = dFdy( vUv );\n\n float Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\n return vec2( dBx, dBy );\n\n }\n\n vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\n vec3 vSigmaX = dFdx( surf_pos );\n vec3 vSigmaY = dFdy( surf_pos );\n vec3 vN = surf_norm;\n vec3 R1 = cross( vSigmaY, vN );\n vec3 R2 = cross( vN, vSigmaX );\n\n float fDet = dot( vSigmaX, R1 );\n\n vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n return normalize( abs( fDet ) * surf_norm - vGrad );\n\n }\n\n#endif\n";
19884
19885
19886
19887 THREE.ShaderChunk[ 'color_fragment'] = "#ifdef USE_COLOR\n\n diffuseColor.rgb *= vColor;\n\n#endif";
19888
19889
19890
19891 THREE.ShaderChunk[ 'color_pars_fragment'] = "#ifdef USE_COLOR\n\n varying vec3 vColor;\n\n#endif\n";
19892
19893
19894
19895 THREE.ShaderChunk[ 'color_pars_vertex'] = "#ifdef USE_COLOR\n\n varying vec3 vColor;\n\n#endif";
19896
19897
19898
19899 THREE.ShaderChunk[ 'color_vertex'] = "#ifdef USE_COLOR\n\n vColor.xyz = color.xyz;\n\n#endif";
19900
19901
19902
19903 THREE.ShaderChunk[ 'common'] = "#define PI 3.14159\n#define PI2 6.28318\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\n\nvec3 transformDirection( in vec3 normal, in mat4 matrix ) {\n\n return normalize( ( matrix * vec4( normal, 0.0 ) ).xyz );\n\n}\n\nvec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) {\n\n return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz );\n\n}\n\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\n float distance = dot( planeNormal, point - pointOnPlane );\n\n return - distance * planeNormal + point;\n\n}\n\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\n return sign( dot( point - pointOnPlane, planeNormal ) );\n\n}\n\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\n return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n\n}\n\nfloat calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) {\n\n if ( decayExponent > 0.0 ) {\n\n return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\n }\n\n return 1.0;\n\n}\n\nvec3 F_Schlick( in vec3 specularColor, in float dotLH ) {\n\n\n float fresnel = exp2( ( -5.55437 * dotLH - 6.98316 ) * dotLH );\n\n return ( 1.0 - specularColor ) * fresnel + specularColor;\n\n}\n\nfloat G_BlinnPhong_Implicit( /* in float dotNL, in float dotNV */ ) {\n\n\n return 0.25;\n\n}\n\nfloat D_BlinnPhong( in float shininess, in float dotNH ) {\n\n\n return ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n\n}\n\nvec3 BRDF_BlinnPhong( in vec3 specularColor, in float shininess, in vec3 normal, in vec3 lightDir, in vec3 viewDir ) {\n\n vec3 halfDir = normalize( lightDir + viewDir );\n\n float dotNH = saturate( dot( normal, halfDir ) );\n float dotLH = saturate( dot( lightDir, halfDir ) );\n\n vec3 F = F_Schlick( specularColor, dotLH );\n\n float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ );\n\n float D = D_BlinnPhong( shininess, dotNH );\n\n return F * G * D;\n\n}\n\nvec3 inputToLinear( in vec3 a ) {\n\n #ifdef GAMMA_INPUT\n\n return pow( a, vec3( float( GAMMA_FACTOR ) ) );\n\n #else\n\n return a;\n\n #endif\n\n}\n\nvec3 linearToOutput( in vec3 a ) {\n\n #ifdef GAMMA_OUTPUT\n\n return pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) );\n\n #else\n\n return a;\n\n #endif\n\n}\n";
19904
19905
19906
19907 THREE.ShaderChunk[ 'defaultnormal_vertex'] = "#ifdef FLIP_SIDED\n\n objectNormal = -objectNormal;\n\n#endif\n\nvec3 transformedNormal = normalMatrix * objectNormal;\n";
19908
19909
19910
19911 THREE.ShaderChunk[ 'displacementmap_vertex'] = "#ifdef USE_DISPLACEMENTMAP\n\n transformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n\n#endif\n";
19912
19913
19914
19915 THREE.ShaderChunk[ 'displacementmap_pars_vertex'] = "#ifdef USE_DISPLACEMENTMAP\n\n uniform sampler2D displacementMap;\n uniform float displacementScale;\n uniform float displacementBias;\n\n#endif\n";
19916
19917
19918
19919 THREE.ShaderChunk[ 'emissivemap_fragment'] = "#ifdef USE_EMISSIVEMAP\n\n vec4 emissiveColor = texture2D( emissiveMap, vUv );\n\n emissiveColor.rgb = inputToLinear( emissiveColor.rgb );\n\n totalEmissiveLight *= emissiveColor.rgb;\n\n#endif\n";
19920
19921
19922
19923 THREE.ShaderChunk[ 'emissivemap_pars_fragment'] = "#ifdef USE_EMISSIVEMAP\n\n uniform sampler2D emissiveMap;\n\n#endif\n";
19924
19925
19926
19927 THREE.ShaderChunk[ 'envmap_fragment'] = "#ifdef USE_ENVMAP\n\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\n vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\n #ifdef ENVMAP_MODE_REFLECTION\n\n vec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\n #else\n\n vec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\n #endif\n\n #else\n\n vec3 reflectVec = vReflect;\n\n #endif\n\n #ifdef DOUBLE_SIDED\n float flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n #else\n float flipNormal = 1.0;\n #endif\n\n #ifdef ENVMAP_TYPE_CUBE\n vec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\n #elif defined( ENVMAP_TYPE_EQUIREC )\n vec2 sampleUV;\n sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n vec4 envColor = texture2D( envMap, sampleUV );\n\n #elif defined( ENVMAP_TYPE_SPHERE )\n vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\n vec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n #endif\n\n envColor.xyz = inputToLinear( envColor.xyz );\n\n #ifdef ENVMAP_BLENDING_MULTIPLY\n\n outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\n #elif defined( ENVMAP_BLENDING_MIX )\n\n outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\n #elif defined( ENVMAP_BLENDING_ADD )\n\n outgoingLight += envColor.xyz * specularStrength * reflectivity;\n\n #endif\n\n#endif\n";
19928
19929
19930
19931 THREE.ShaderChunk[ 'envmap_pars_fragment'] = "#ifdef USE_ENVMAP\n\n uniform float reflectivity;\n #ifdef ENVMAP_TYPE_CUBE\n uniform samplerCube envMap;\n #else\n uniform sampler2D envMap;\n #endif\n uniform float flipEnvMap;\n\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n uniform float refractionRatio;\n\n #else\n\n varying vec3 vReflect;\n\n #endif\n\n#endif\n";
19932
19933
19934
19935 THREE.ShaderChunk[ 'envmap_pars_vertex'] = "#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )\n\n varying vec3 vReflect;\n\n uniform float refractionRatio;\n\n#endif\n";
19936
19937
19938
19939 THREE.ShaderChunk[ 'envmap_vertex'] = "#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )\n\n vec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\n vec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\n #ifdef ENVMAP_MODE_REFLECTION\n\n vReflect = reflect( cameraToVertex, worldNormal );\n\n #else\n\n vReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\n #endif\n\n#endif\n";
19940
19941
19942
19943 THREE.ShaderChunk[ 'fog_fragment'] = "#ifdef USE_FOG\n\n #ifdef USE_LOGDEPTHBUF_EXT\n\n float depth = gl_FragDepthEXT / gl_FragCoord.w;\n\n #else\n\n float depth = gl_FragCoord.z / gl_FragCoord.w;\n\n #endif\n\n #ifdef FOG_EXP2\n\n float fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * depth * depth * LOG2 ) );\n\n #else\n\n float fogFactor = smoothstep( fogNear, fogFar, depth );\n\n #endif\n \n outgoingLight = mix( outgoingLight, fogColor, fogFactor );\n\n#endif";
19944
19945
19946
19947 THREE.ShaderChunk[ 'fog_pars_fragment'] = "#ifdef USE_FOG\n\n uniform vec3 fogColor;\n\n #ifdef FOG_EXP2\n\n uniform float fogDensity;\n\n #else\n\n uniform float fogNear;\n uniform float fogFar;\n #endif\n\n#endif";
19948
19949
19950
19951 THREE.ShaderChunk[ 'hemilight_fragment'] = "#if MAX_HEMI_LIGHTS > 0\n\n for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lightDir = hemisphereLightDirection[ i ];\n\n float dotProduct = dot( normal, lightDir );\n\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n vec3 lightColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n totalAmbientLight += lightColor;\n\n }\n\n#endif\n\n";
19952
19953
19954
19955 THREE.ShaderChunk[ 'lightmap_fragment'] = "#ifdef USE_LIGHTMAP\n\n totalAmbientLight += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\n#endif\n";
19956
19957
19958
19959 THREE.ShaderChunk[ 'lightmap_pars_fragment'] = "#ifdef USE_LIGHTMAP\n\n uniform sampler2D lightMap;\n uniform float lightMapIntensity;\n\n#endif";
19960
19961
19962
19963 THREE.ShaderChunk[ 'lights_lambert_pars_vertex'] = "#if MAX_DIR_LIGHTS > 0\n\n uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n uniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n uniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n";
19964
19965
19966
19967 THREE.ShaderChunk[ 'lights_lambert_vertex'] = "vLightFront = vec3( 0.0 );\n\n#ifdef DOUBLE_SIDED\n\n vLightBack = vec3( 0.0 );\n\n#endif\n\nvec3 normal = normalize( transformedNormal );\n\n#if MAX_POINT_LIGHTS > 0\n\n for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec3 lightColor = pointLightColor[ i ];\n\n vec3 lVector = pointLightPosition[ i ] - mvPosition.xyz;\n vec3 lightDir = normalize( lVector );\n\n\n float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n\n float dotProduct = dot( normal, lightDir );\n\n vLightFront += lightColor * attenuation * saturate( dotProduct );\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += lightColor * attenuation * saturate( - dotProduct );\n\n #endif\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec3 lightColor = spotLightColor[ i ];\n\n vec3 lightPosition = spotLightPosition[ i ];\n vec3 lVector = lightPosition - mvPosition.xyz;\n vec3 lightDir = normalize( lVector );\n\n float spotEffect = dot( spotLightDirection[ i ], lightDir );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = saturate( pow( saturate( spotEffect ), spotLightExponent[ i ] ) );\n\n\n float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n attenuation *= spotEffect;\n\n\n float dotProduct = dot( normal, lightDir );\n\n vLightFront += lightColor * attenuation * saturate( dotProduct );\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += lightColor * attenuation * saturate( - dotProduct );\n\n #endif\n\n }\n\n }\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 lightColor = directionalLightColor[ i ];\n\n vec3 lightDir = directionalLightDirection[ i ];\n\n\n float dotProduct = dot( normal, lightDir );\n\n vLightFront += lightColor * saturate( dotProduct );\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += lightColor * saturate( - dotProduct );\n\n #endif\n\n }\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lightDir = hemisphereLightDirection[ i ];\n\n\n float dotProduct = dot( normal, lightDir );\n\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n vLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n #ifdef DOUBLE_SIDED\n\n float hemiDiffuseWeightBack = - 0.5 * dotProduct + 0.5;\n\n vLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );\n\n #endif\n\n }\n\n#endif\n";
19968
19969
19970
19971 THREE.ShaderChunk[ 'lights_phong_fragment'] = "vec3 viewDir = normalize( vViewPosition );\n\nvec3 totalDiffuseLight = vec3( 0.0 );\nvec3 totalSpecularLight = vec3( 0.0 );\n\n#if MAX_POINT_LIGHTS > 0\n\n for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec3 lightColor = pointLightColor[ i ];\n\n vec3 lightPosition = pointLightPosition[ i ];\n vec3 lVector = lightPosition + vViewPosition.xyz;\n vec3 lightDir = normalize( lVector );\n\n\n float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n\n float cosineTerm = saturate( dot( normal, lightDir ) );\n\n totalDiffuseLight += lightColor * attenuation * cosineTerm;\n\n\n vec3 brdf = BRDF_BlinnPhong( specular, shininess, normal, lightDir, viewDir );\n\n totalSpecularLight += brdf * specularStrength * lightColor * attenuation * cosineTerm;\n\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec3 lightColor = spotLightColor[ i ];\n\n vec3 lightPosition = spotLightPosition[ i ];\n vec3 lVector = lightPosition + vViewPosition.xyz;\n vec3 lightDir = normalize( lVector );\n\n float spotEffect = dot( spotLightDirection[ i ], lightDir );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = saturate( pow( saturate( spotEffect ), spotLightExponent[ i ] ) );\n\n\n float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n attenuation *= spotEffect;\n\n\n float cosineTerm = saturate( dot( normal, lightDir ) );\n\n totalDiffuseLight += lightColor * attenuation * cosineTerm;\n\n\n vec3 brdf = BRDF_BlinnPhong( specular, shininess, normal, lightDir, viewDir );\n\n totalSpecularLight += brdf * specularStrength * lightColor * attenuation * cosineTerm;\n\n }\n\n }\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 lightColor = directionalLightColor[ i ];\n\n vec3 lightDir = directionalLightDirection[ i ];\n\n\n float cosineTerm = saturate( dot( normal, lightDir ) );\n\n totalDiffuseLight += lightColor * cosineTerm;\n\n\n vec3 brdf = BRDF_BlinnPhong( specular, shininess, normal, lightDir, viewDir );\n\n totalSpecularLight += brdf * specularStrength * lightColor * cosineTerm;\n\n }\n\n#endif\n";
19972
19973
19974
19975 THREE.ShaderChunk[ 'lights_phong_pars_fragment'] = "uniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\n uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n uniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n uniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_ENVMAP )\n\n varying vec3 vWorldPosition;\n\n#endif\n\nvarying vec3 vViewPosition;\n\n#ifndef FLAT_SHADED\n\n varying vec3 vNormal;\n\n#endif\n";
19976
19977
19978
19979 THREE.ShaderChunk[ 'lights_phong_pars_vertex'] = "#if MAX_SPOT_LIGHTS > 0 || defined( USE_ENVMAP )\n\n varying vec3 vWorldPosition;\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n\n#endif\n";
19980
19981
19982
19983 THREE.ShaderChunk[ 'lights_phong_vertex'] = "#if MAX_SPOT_LIGHTS > 0 || defined( USE_ENVMAP )\n\n vWorldPosition = worldPosition.xyz;\n\n#endif\n";
19984
19985
19986
19987 THREE.ShaderChunk[ 'linear_to_gamma_fragment'] = "\n outgoingLight = linearToOutput( outgoingLight );\n";
19988
19989
19990
19991 THREE.ShaderChunk[ 'logdepthbuf_fragment'] = "#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\n\n gl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\n\n#endif";
19992
19993
19994
19995 THREE.ShaderChunk[ 'logdepthbuf_pars_fragment'] = "#ifdef USE_LOGDEPTHBUF\n\n uniform float logDepthBufFC;\n\n #ifdef USE_LOGDEPTHBUF_EXT\n\n varying float vFragDepth;\n\n #endif\n\n#endif\n";
19996
19997
19998
19999 THREE.ShaderChunk[ 'logdepthbuf_pars_vertex'] = "#ifdef USE_LOGDEPTHBUF\n\n #ifdef USE_LOGDEPTHBUF_EXT\n\n varying float vFragDepth;\n\n #endif\n\n uniform float logDepthBufFC;\n\n#endif";
20000
20001
20002
20003 THREE.ShaderChunk[ 'logdepthbuf_vertex'] = "#ifdef USE_LOGDEPTHBUF\n\n gl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\n\n #ifdef USE_LOGDEPTHBUF_EXT\n\n vFragDepth = 1.0 + gl_Position.w;\n\n#else\n\n gl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\n\n #endif\n\n#endif";
20004
20005
20006
20007 THREE.ShaderChunk[ 'map_fragment'] = "#ifdef USE_MAP\n\n vec4 texelColor = texture2D( map, vUv );\n\n texelColor.xyz = inputToLinear( texelColor.xyz );\n\n diffuseColor *= texelColor;\n\n#endif\n";
20008
20009
20010
20011 THREE.ShaderChunk[ 'map_pars_fragment'] = "#ifdef USE_MAP\n\n uniform sampler2D map;\n\n#endif";
20012
20013
20014
20015 THREE.ShaderChunk[ 'map_particle_fragment'] = "#ifdef USE_MAP\n\n diffuseColor *= texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\n\n#endif\n";
20016
20017
20018
20019 THREE.ShaderChunk[ 'map_particle_pars_fragment'] = "#ifdef USE_MAP\n\n uniform vec4 offsetRepeat;\n uniform sampler2D map;\n\n#endif\n";
20020
20021
20022
20023 THREE.ShaderChunk[ 'morphnormal_vertex'] = "#ifdef USE_MORPHNORMALS\n\n objectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n objectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n objectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n objectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n\n#endif\n";
20024
20025
20026
20027 THREE.ShaderChunk[ 'morphtarget_pars_vertex'] = "#ifdef USE_MORPHTARGETS\n\n #ifndef USE_MORPHNORMALS\n\n uniform float morphTargetInfluences[ 8 ];\n\n #else\n\n uniform float morphTargetInfluences[ 4 ];\n\n #endif\n\n#endif";
20028
20029
20030
20031 THREE.ShaderChunk[ 'morphtarget_vertex'] = "#ifdef USE_MORPHTARGETS\n\n transformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n transformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n transformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n transformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\n #ifndef USE_MORPHNORMALS\n\n transformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n transformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n transformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n transformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\n #endif\n\n#endif\n";
20032
20033
20034
20035 THREE.ShaderChunk[ 'normal_phong_fragment'] = "#ifndef FLAT_SHADED\n\n vec3 normal = normalize( vNormal );\n\n #ifdef DOUBLE_SIDED\n\n normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n #endif\n\n#else\n\n vec3 fdx = dFdx( vViewPosition );\n vec3 fdy = dFdy( vViewPosition );\n vec3 normal = normalize( cross( fdx, fdy ) );\n\n#endif\n\n#ifdef USE_NORMALMAP\n\n normal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\n";
20036
20037
20038
20039 THREE.ShaderChunk[ 'normalmap_pars_fragment'] = "#ifdef USE_NORMALMAP\n\n uniform sampler2D normalMap;\n uniform vec2 normalScale;\n\n\n vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\n vec3 q0 = dFdx( eye_pos.xyz );\n vec3 q1 = dFdy( eye_pos.xyz );\n vec2 st0 = dFdx( vUv.st );\n vec2 st1 = dFdy( vUv.st );\n\n vec3 S = normalize( q0 * st1.t - q1 * st0.t );\n vec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n vec3 N = normalize( surf_norm );\n\n vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n mapN.xy = normalScale * mapN.xy;\n mat3 tsn = mat3( S, T, N );\n return normalize( tsn * mapN );\n\n }\n\n#endif\n";
20040
20041
20042
20043 THREE.ShaderChunk[ 'project_vertex'] = "#ifdef USE_SKINNING\n\n vec4 mvPosition = modelViewMatrix * skinned;\n\n#else\n\n vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\n\n#endif\n\ngl_Position = projectionMatrix * mvPosition;\n";
20044
20045
20046
20047 THREE.ShaderChunk[ 'shadowmap_fragment'] = "#ifdef USE_SHADOWMAP\n\n for ( int i = 0; i < MAX_SHADOWS; i ++ ) {\n\n float texelSizeY = 1.0 / shadowMapSize[ i ].y;\n\n float shadow = 0.0;\n\n#if defined( POINT_LIGHT_SHADOWS )\n\n bool isPointLight = shadowDarkness[ i ] < 0.0;\n\n if ( isPointLight ) {\n\n float realShadowDarkness = abs( shadowDarkness[ i ] );\n\n vec3 lightToPosition = vShadowCoord[ i ].xyz;\n\n #if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\n vec3 bd3D = normalize( lightToPosition );\n float dp = length( lightToPosition );\n\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D, texelSizeY ) ), shadowBias[ i ], shadow );\n\n\n #if defined( SHADOWMAP_TYPE_PCF )\n const float Dr = 1.25;\n #elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n const float Dr = 2.25;\n #endif\n\n float os = Dr * 2.0 * texelSizeY;\n\n const vec3 Gsd = vec3( - 1, 0, 1 );\n\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zzz * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zxz * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xxz * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xzz * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zzx * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zxx * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xxx * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xzx * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zzy * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zxy * os, texelSizeY ) ), shadowBias[ i ], shadow );\n\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xxy * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xzy * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zyz * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xyz * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zyx * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xyx * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.yzz * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.yxz * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.yxx * os, texelSizeY ) ), shadowBias[ i ], shadow );\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.yzx * os, texelSizeY ) ), shadowBias[ i ], shadow );\n\n shadow *= realShadowDarkness * ( 1.0 / 21.0 );\n\n #else \n vec3 bd3D = normalize( lightToPosition );\n float dp = length( lightToPosition );\n\n adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D, texelSizeY ) ), shadowBias[ i ], shadow );\n\n shadow *= realShadowDarkness;\n\n #endif\n\n } else {\n\n#endif \n float texelSizeX = 1.0 / shadowMapSize[ i ].x;\n\n vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\n\n\n bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n bool inFrustum = all( inFrustumVec );\n\n bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\n bool frustumTest = all( frustumTestVec );\n\n if ( frustumTest ) {\n\n #if defined( SHADOWMAP_TYPE_PCF )\n\n\n /*\n for ( float y = -1.25; y <= 1.25; y += 1.25 )\n for ( float x = -1.25; x <= 1.25; x += 1.25 ) {\n vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );\n float fDepth = unpackDepth( rgbaDepth );\n if ( fDepth < shadowCoord.z )\n shadow += 1.0;\n }\n shadow /= 9.0;\n */\n\n shadowCoord.z += shadowBias[ i ];\n\n const float ShadowDelta = 1.0 / 9.0;\n\n float xPixelOffset = texelSizeX;\n float yPixelOffset = texelSizeY;\n\n float dx0 = - 1.25 * xPixelOffset;\n float dy0 = - 1.25 * yPixelOffset;\n float dx1 = 1.25 * xPixelOffset;\n float dy1 = 1.25 * yPixelOffset;\n\n float fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;\n\n shadow *= shadowDarkness[ i ];\n\n #elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\n\n shadowCoord.z += shadowBias[ i ];\n\n float xPixelOffset = texelSizeX;\n float yPixelOffset = texelSizeY;\n\n float dx0 = - 1.0 * xPixelOffset;\n float dy0 = - 1.0 * yPixelOffset;\n float dx1 = 1.0 * xPixelOffset;\n float dy1 = 1.0 * yPixelOffset;\n\n mat3 shadowKernel;\n mat3 depthKernel;\n\n depthKernel[ 0 ][ 0 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n depthKernel[ 0 ][ 1 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n depthKernel[ 0 ][ 2 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n depthKernel[ 1 ][ 0 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n depthKernel[ 1 ][ 1 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n depthKernel[ 1 ][ 2 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n depthKernel[ 2 ][ 0 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n depthKernel[ 2 ][ 1 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n depthKernel[ 2 ][ 2 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n\n vec3 shadowZ = vec3( shadowCoord.z );\n shadowKernel[ 0 ] = vec3( lessThan( depthKernel[ 0 ], shadowZ ) );\n shadowKernel[ 0 ] *= vec3( 0.25 );\n\n shadowKernel[ 1 ] = vec3( lessThan( depthKernel[ 1 ], shadowZ ) );\n shadowKernel[ 1 ] *= vec3( 0.25 );\n\n shadowKernel[ 2 ] = vec3( lessThan( depthKernel[ 2 ], shadowZ ) );\n shadowKernel[ 2 ] *= vec3( 0.25 );\n\n vec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[ i ].xy );\n\n shadowKernel[ 0 ] = mix( shadowKernel[ 1 ], shadowKernel[ 0 ], fractionalCoord.x );\n shadowKernel[ 1 ] = mix( shadowKernel[ 2 ], shadowKernel[ 1 ], fractionalCoord.x );\n\n vec4 shadowValues;\n shadowValues.x = mix( shadowKernel[ 0 ][ 1 ], shadowKernel[ 0 ][ 0 ], fractionalCoord.y );\n shadowValues.y = mix( shadowKernel[ 0 ][ 2 ], shadowKernel[ 0 ][ 1 ], fractionalCoord.y );\n shadowValues.z = mix( shadowKernel[ 1 ][ 1 ], shadowKernel[ 1 ][ 0 ], fractionalCoord.y );\n shadowValues.w = mix( shadowKernel[ 1 ][ 2 ], shadowKernel[ 1 ][ 1 ], fractionalCoord.y );\n\n shadow = dot( shadowValues, vec4( 1.0 ) ) * shadowDarkness[ i ];\n\n #else \n shadowCoord.z += shadowBias[ i ];\n\n vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\n float fDepth = unpackDepth( rgbaDepth );\n\n if ( fDepth < shadowCoord.z )\n shadow = shadowDarkness[ i ];\n\n #endif\n\n }\n\n#ifdef SHADOWMAP_DEBUG\n\n if ( inFrustum ) {\n\n if ( i == 0 ) {\n\n outgoingLight *= vec3( 1.0, 0.5, 0.0 );\n\n } else if ( i == 1 ) {\n\n outgoingLight *= vec3( 0.0, 1.0, 0.8 );\n\n } else {\n\n outgoingLight *= vec3( 0.0, 0.5, 1.0 );\n\n }\n\n }\n\n#endif\n\n#if defined( POINT_LIGHT_SHADOWS )\n\n }\n\n#endif\n\n shadowMask = shadowMask * vec3( 1.0 - shadow );\n\n }\n\n#endif\n";
20048
20049
20050
20051 THREE.ShaderChunk[ 'shadowmap_pars_fragment'] = "#ifdef USE_SHADOWMAP\n\n uniform sampler2D shadowMap[ MAX_SHADOWS ];\n uniform vec2 shadowMapSize[ MAX_SHADOWS ];\n\n uniform float shadowDarkness[ MAX_SHADOWS ];\n uniform float shadowBias[ MAX_SHADOWS ];\n\n varying vec4 vShadowCoord[ MAX_SHADOWS ];\n\n float unpackDepth( const in vec4 rgba_depth ) {\n\n const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );\n float depth = dot( rgba_depth, bit_shift );\n return depth;\n\n }\n\n #if defined(POINT_LIGHT_SHADOWS)\n\n\n void adjustShadowValue1K( const float testDepth, const vec4 textureData, const float bias, inout float shadowValue ) {\n\n const vec4 bitSh = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );\n if ( testDepth >= dot( textureData, bitSh ) * 1000.0 + bias )\n shadowValue += 1.0;\n\n }\n\n\n vec2 cubeToUV( vec3 v, float texelSizeY ) {\n\n\n vec3 absV = abs( v );\n\n\n float scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n absV *= scaleToCube;\n\n\n v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\n\n\n vec2 planar = v.xy;\n\n float almostATexel = 1.5 * texelSizeY;\n float almostOne = 1.0 - almostATexel;\n\n if ( absV.z >= almostOne ) {\n\n if ( v.z > 0.0 )\n planar.x = 4.0 - v.x;\n\n } else if ( absV.x >= almostOne ) {\n\n float signX = sign( v.x );\n planar.x = v.z * signX + 2.0 * signX;\n\n } else if ( absV.y >= almostOne ) {\n\n float signY = sign( v.y );\n planar.x = v.x + 2.0 * signY + 2.0;\n planar.y = v.z * signY - 2.0;\n\n }\n\n\n return vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\n }\n\n #endif\n\n#endif\n";
20052
20053
20054
20055 THREE.ShaderChunk[ 'shadowmap_pars_vertex'] = "#ifdef USE_SHADOWMAP\n\n uniform float shadowDarkness[ MAX_SHADOWS ];\n uniform mat4 shadowMatrix[ MAX_SHADOWS ];\n varying vec4 vShadowCoord[ MAX_SHADOWS ];\n\n#endif";
20056
20057
20058
20059 THREE.ShaderChunk[ 'shadowmap_vertex'] = "#ifdef USE_SHADOWMAP\n\n for ( int i = 0; i < MAX_SHADOWS; i ++ ) {\n\n vShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;\n\n }\n\n#endif";
20060
20061
20062
20063 THREE.ShaderChunk[ 'skinbase_vertex'] = "#ifdef USE_SKINNING\n\n mat4 boneMatX = getBoneMatrix( skinIndex.x );\n mat4 boneMatY = getBoneMatrix( skinIndex.y );\n mat4 boneMatZ = getBoneMatrix( skinIndex.z );\n mat4 boneMatW = getBoneMatrix( skinIndex.w );\n\n#endif";
20064
20065
20066
20067 THREE.ShaderChunk[ 'skinning_pars_vertex'] = "#ifdef USE_SKINNING\n\n uniform mat4 bindMatrix;\n uniform mat4 bindMatrixInverse;\n\n #ifdef BONE_TEXTURE\n\n uniform sampler2D boneTexture;\n uniform int boneTextureWidth;\n uniform int boneTextureHeight;\n\n mat4 getBoneMatrix( const in float i ) {\n\n float j = i * 4.0;\n float x = mod( j, float( boneTextureWidth ) );\n float y = floor( j / float( boneTextureWidth ) );\n\n float dx = 1.0 / float( boneTextureWidth );\n float dy = 1.0 / float( boneTextureHeight );\n\n y = dy * ( y + 0.5 );\n\n vec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n vec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n vec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n vec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\n mat4 bone = mat4( v1, v2, v3, v4 );\n\n return bone;\n\n }\n\n #else\n\n uniform mat4 boneGlobalMatrices[ MAX_BONES ];\n\n mat4 getBoneMatrix( const in float i ) {\n\n mat4 bone = boneGlobalMatrices[ int(i) ];\n return bone;\n\n }\n\n #endif\n\n#endif\n";
20068
20069
20070
20071 THREE.ShaderChunk[ 'skinning_vertex'] = "#ifdef USE_SKINNING\n\n vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\n vec4 skinned = vec4( 0.0 );\n skinned += boneMatX * skinVertex * skinWeight.x;\n skinned += boneMatY * skinVertex * skinWeight.y;\n skinned += boneMatZ * skinVertex * skinWeight.z;\n skinned += boneMatW * skinVertex * skinWeight.w;\n skinned = bindMatrixInverse * skinned;\n\n#endif\n";
20072
20073
20074
20075 THREE.ShaderChunk[ 'skinnormal_vertex'] = "#ifdef USE_SKINNING\n\n mat4 skinMatrix = mat4( 0.0 );\n skinMatrix += skinWeight.x * boneMatX;\n skinMatrix += skinWeight.y * boneMatY;\n skinMatrix += skinWeight.z * boneMatZ;\n skinMatrix += skinWeight.w * boneMatW;\n skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\n objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\n#endif\n";
20076
20077
20078
20079 THREE.ShaderChunk[ 'specularmap_fragment'] = "float specularStrength;\n\n#ifdef USE_SPECULARMAP\n\n vec4 texelSpecular = texture2D( specularMap, vUv );\n specularStrength = texelSpecular.r;\n\n#else\n\n specularStrength = 1.0;\n\n#endif";
20080
20081
20082
20083 THREE.ShaderChunk[ 'specularmap_pars_fragment'] = "#ifdef USE_SPECULARMAP\n\n uniform sampler2D specularMap;\n\n#endif";
20084
20085
20086
20087 THREE.ShaderChunk[ 'uv2_pars_fragment'] = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\n varying vec2 vUv2;\n\n#endif";
20088
20089
20090
20091 THREE.ShaderChunk[ 'uv2_pars_vertex'] = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\n attribute vec2 uv2;\n varying vec2 vUv2;\n\n#endif";
20092
20093
20094
20095 THREE.ShaderChunk[ 'uv2_vertex'] = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\n vUv2 = uv2;\n\n#endif";
20096
20097
20098
20099 THREE.ShaderChunk[ 'uv_pars_fragment'] = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP )\n\n varying vec2 vUv;\n\n#endif";
20100
20101
20102
20103 THREE.ShaderChunk[ 'uv_pars_vertex'] = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP )\n\n varying vec2 vUv;\n uniform vec4 offsetRepeat;\n\n#endif\n";
20104
20105
20106
20107 THREE.ShaderChunk[ 'uv_vertex'] = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP )\n\n vUv = uv * offsetRepeat.zw + offsetRepeat.xy;\n\n#endif";
20108
20109
20110
20111 THREE.ShaderChunk[ 'worldpos_vertex'] = "#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\n\n #ifdef USE_SKINNING\n\n vec4 worldPosition = modelMatrix * skinned;\n\n #else\n\n vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n\n #endif\n\n#endif\n";
20112
20113
20114
20119 THREE.UniformsUtils = {
20120
20121 merge: function ( uniforms ) {
20122
20123 var merged = {};
20124
20125 for ( var u = 0; u < uniforms.length; u ++ ) {
20126
20127 var tmp = this.clone( uniforms[ u ] );
20128
20129 for ( var p in tmp ) {
20130
20131 merged[ p ] = tmp[ p ];
20132
20133 }
20134
20135 }
20136
20137 return merged;
20138
20139 },
20140
20141 clone: function ( uniforms_src ) {
20142
20143 var uniforms_dst = {};
20144
20145 for ( var u in uniforms_src ) {
20146
20147 uniforms_dst[ u ] = {};
20148
20149 for ( var p in uniforms_src[ u ] ) {
20150
20151 var parameter_src = uniforms_src[ u ][ p ];
20152
20153 if ( parameter_src instanceof THREE.Color ||
20154 parameter_src instanceof THREE.Vector2 ||
20155 parameter_src instanceof THREE.Vector3 ||
20156 parameter_src instanceof THREE.Vector4 ||
20157 parameter_src instanceof THREE.Matrix3 ||
20158 parameter_src instanceof THREE.Matrix4 ||
20159 parameter_src instanceof THREE.Texture ) {
20160
20161 uniforms_dst[ u ][ p ] = parameter_src.clone();
20162
20163 } else if ( Array.isArray( parameter_src ) ) {
20164
20165 uniforms_dst[ u ][ p ] = parameter_src.slice();
20166
20167 } else {
20168
20169 uniforms_dst[ u ][ p ] = parameter_src;
20170
20171 }
20172
20173 }
20174
20175 }
20176
20177 return uniforms_dst;
20178
20179 }
20180
20181 };
20182
20183
20184
20189 THREE.UniformsLib = {
20190
20191 common: {
20192
20193 "diffuse" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
20194 "opacity" : { type: "f", value: 1.0 },
20195
20196 "map" : { type: "t", value: null },
20197 "offsetRepeat" : { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) },
20198
20199 "specularMap" : { type: "t", value: null },
20200 "alphaMap" : { type: "t", value: null },
20201
20202 "envMap" : { type: "t", value: null },
20203 "flipEnvMap" : { type: "f", value: - 1 },
20204 "reflectivity" : { type: "f", value: 1.0 },
20205 "refractionRatio" : { type: "f", value: 0.98 }
20206
20207 },
20208
20209 aomap: {
20210
20211 "aoMap" : { type: "t", value: null },
20212 "aoMapIntensity" : { type: "f", value: 1 },
20213
20214 },
20215
20216 lightmap: {
20217
20218 "lightMap" : { type: "t", value: null },
20219 "lightMapIntensity" : { type: "f", value: 1 },
20220
20221 },
20222
20223 emissivemap: {
20224
20225 "emissiveMap" : { type: "t", value: null },
20226
20227 },
20228
20229 bumpmap: {
20230
20231 "bumpMap" : { type: "t", value: null },
20232 "bumpScale" : { type: "f", value: 1 }
20233
20234 },
20235
20236 normalmap: {
20237
20238 "normalMap" : { type: "t", value: null },
20239 "normalScale" : { type: "v2", value: new THREE.Vector2( 1, 1 ) }
20240
20241 },
20242
20243 displacementmap: {
20244
20245 "displacementMap" : { type: "t", value: null },
20246 "displacementScale" : { type: "f", value: 1 },
20247 "displacementBias" : { type: "f", value: 0 }
20248
20249 },
20250
20251 fog : {
20252
20253 "fogDensity" : { type: "f", value: 0.00025 },
20254 "fogNear" : { type: "f", value: 1 },
20255 "fogFar" : { type: "f", value: 2000 },
20256 "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) }
20257
20258 },
20259
20260 lights: {
20261
20262 "ambientLightColor" : { type: "fv", value: [] },
20263
20264 "directionalLightDirection" : { type: "fv", value: [] },
20265 "directionalLightColor" : { type: "fv", value: [] },
20266
20267 "hemisphereLightDirection" : { type: "fv", value: [] },
20268 "hemisphereLightSkyColor" : { type: "fv", value: [] },
20269 "hemisphereLightGroundColor" : { type: "fv", value: [] },
20270
20271 "pointLightColor" : { type: "fv", value: [] },
20272 "pointLightPosition" : { type: "fv", value: [] },
20273 "pointLightDistance" : { type: "fv1", value: [] },
20274 "pointLightDecay" : { type: "fv1", value: [] },
20275
20276 "spotLightColor" : { type: "fv", value: [] },
20277 "spotLightPosition" : { type: "fv", value: [] },
20278 "spotLightDirection" : { type: "fv", value: [] },
20279 "spotLightDistance" : { type: "fv1", value: [] },
20280 "spotLightAngleCos" : { type: "fv1", value: [] },
20281 "spotLightExponent" : { type: "fv1", value: [] },
20282 "spotLightDecay" : { type: "fv1", value: [] }
20283
20284 },
20285
20286 points: {
20287
20288 "psColor" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
20289 "opacity" : { type: "f", value: 1.0 },
20290 "size" : { type: "f", value: 1.0 },
20291 "scale" : { type: "f", value: 1.0 },
20292 "map" : { type: "t", value: null },
20293 "offsetRepeat" : { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) },
20294
20295 "fogDensity" : { type: "f", value: 0.00025 },
20296 "fogNear" : { type: "f", value: 1 },
20297 "fogFar" : { type: "f", value: 2000 },
20298 "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) }
20299
20300 },
20301
20302 shadowmap: {
20303
20304 "shadowMap": { type: "tv", value: [] },
20305 "shadowMapSize": { type: "v2v", value: [] },
20306
20307 "shadowBias" : { type: "fv1", value: [] },
20308 "shadowDarkness": { type: "fv1", value: [] },
20309
20310 "shadowMatrix" : { type: "m4v", value: [] }
20311
20312 }
20313
20314 };
20315
20316
20317
20327 THREE.ShaderLib = {
20328
20329 'basic': {
20330
20331 uniforms: THREE.UniformsUtils.merge( [
20332
20333 THREE.UniformsLib[ "common" ],
20334 THREE.UniformsLib[ "aomap" ],
20335 THREE.UniformsLib[ "fog" ],
20336 THREE.UniformsLib[ "shadowmap" ]
20337
20338 ] ),
20339
20340 vertexShader: [
20341
20342 THREE.ShaderChunk[ "common" ],
20343 THREE.ShaderChunk[ "uv_pars_vertex" ],
20344 THREE.ShaderChunk[ "uv2_pars_vertex" ],
20345 THREE.ShaderChunk[ "envmap_pars_vertex" ],
20346 THREE.ShaderChunk[ "color_pars_vertex" ],
20347 THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
20348 THREE.ShaderChunk[ "skinning_pars_vertex" ],
20349 THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
20350 THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
20351
20352 "void main() {",
20353
20354 THREE.ShaderChunk[ "uv_vertex" ],
20355 THREE.ShaderChunk[ "uv2_vertex" ],
20356 THREE.ShaderChunk[ "color_vertex" ],
20357 THREE.ShaderChunk[ "skinbase_vertex" ],
20358
20359 " #ifdef USE_ENVMAP",
20360
20361 THREE.ShaderChunk[ "beginnormal_vertex" ],
20362 THREE.ShaderChunk[ "morphnormal_vertex" ],
20363 THREE.ShaderChunk[ "skinnormal_vertex" ],
20364 THREE.ShaderChunk[ "defaultnormal_vertex" ],
20365
20366 " #endif",
20367
20368 THREE.ShaderChunk[ "begin_vertex" ],
20369 THREE.ShaderChunk[ "morphtarget_vertex" ],
20370 THREE.ShaderChunk[ "skinning_vertex" ],
20371 THREE.ShaderChunk[ "project_vertex" ],
20372 THREE.ShaderChunk[ "logdepthbuf_vertex" ],
20373
20374 THREE.ShaderChunk[ "worldpos_vertex" ],
20375 THREE.ShaderChunk[ "envmap_vertex" ],
20376 THREE.ShaderChunk[ "shadowmap_vertex" ],
20377
20378 "}"
20379
20380 ].join( "\n" ),
20381
20382 fragmentShader: [
20383
20384 "uniform vec3 diffuse;",
20385 "uniform float opacity;",
20386
20387 THREE.ShaderChunk[ "common" ],
20388 THREE.ShaderChunk[ "color_pars_fragment" ],
20389 THREE.ShaderChunk[ "uv_pars_fragment" ],
20390 THREE.ShaderChunk[ "uv2_pars_fragment" ],
20391 THREE.ShaderChunk[ "map_pars_fragment" ],
20392 THREE.ShaderChunk[ "alphamap_pars_fragment" ],
20393 THREE.ShaderChunk[ "aomap_pars_fragment" ],
20394 THREE.ShaderChunk[ "envmap_pars_fragment" ],
20395 THREE.ShaderChunk[ "fog_pars_fragment" ],
20396 THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
20397 THREE.ShaderChunk[ "specularmap_pars_fragment" ],
20398 THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
20399
20400 "void main() {",
20401
20402 " vec3 outgoingLight = vec3( 0.0 );",
20403 " vec4 diffuseColor = vec4( diffuse, opacity );",
20404 " vec3 totalAmbientLight = vec3( 1.0 );",
20405 " vec3 shadowMask = vec3( 1.0 );",
20406
20407 THREE.ShaderChunk[ "logdepthbuf_fragment" ],
20408 THREE.ShaderChunk[ "map_fragment" ],
20409 THREE.ShaderChunk[ "color_fragment" ],
20410 THREE.ShaderChunk[ "alphamap_fragment" ],
20411 THREE.ShaderChunk[ "alphatest_fragment" ],
20412 THREE.ShaderChunk[ "specularmap_fragment" ],
20413 THREE.ShaderChunk[ "aomap_fragment" ],
20414 THREE.ShaderChunk[ "shadowmap_fragment" ],
20415
20416 " outgoingLight = diffuseColor.rgb * totalAmbientLight * shadowMask;",
20417
20418 THREE.ShaderChunk[ "envmap_fragment" ],
20419
20420 THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
20421
20422 THREE.ShaderChunk[ "fog_fragment" ],
20423
20424 " gl_FragColor = vec4( outgoingLight, diffuseColor.a );",
20425
20426 "}"
20427
20428 ].join( "\n" )
20429
20430 },
20431
20432 'lambert': {
20433
20434 uniforms: THREE.UniformsUtils.merge( [
20435
20436 THREE.UniformsLib[ "common" ],
20437 THREE.UniformsLib[ "fog" ],
20438 THREE.UniformsLib[ "lights" ],
20439 THREE.UniformsLib[ "shadowmap" ],
20440
20441 {
20442 "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) }
20443 }
20444
20445 ] ),
20446
20447 vertexShader: [
20448
20449 "#define LAMBERT",
20450
20451 "varying vec3 vLightFront;",
20452
20453 "#ifdef DOUBLE_SIDED",
20454
20455 " varying vec3 vLightBack;",
20456
20457 "#endif",
20458
20459 THREE.ShaderChunk[ "common" ],
20460 THREE.ShaderChunk[ "uv_pars_vertex" ],
20461 THREE.ShaderChunk[ "uv2_pars_vertex" ],
20462 THREE.ShaderChunk[ "envmap_pars_vertex" ],
20463 THREE.ShaderChunk[ "lights_lambert_pars_vertex" ],
20464 THREE.ShaderChunk[ "color_pars_vertex" ],
20465 THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
20466 THREE.ShaderChunk[ "skinning_pars_vertex" ],
20467 THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
20468 THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
20469
20470 "void main() {",
20471
20472 THREE.ShaderChunk[ "uv_vertex" ],
20473 THREE.ShaderChunk[ "uv2_vertex" ],
20474 THREE.ShaderChunk[ "color_vertex" ],
20475
20476 THREE.ShaderChunk[ "beginnormal_vertex" ],
20477 THREE.ShaderChunk[ "morphnormal_vertex" ],
20478 THREE.ShaderChunk[ "skinbase_vertex" ],
20479 THREE.ShaderChunk[ "skinnormal_vertex" ],
20480 THREE.ShaderChunk[ "defaultnormal_vertex" ],
20481
20482 THREE.ShaderChunk[ "begin_vertex" ],
20483 THREE.ShaderChunk[ "morphtarget_vertex" ],
20484 THREE.ShaderChunk[ "skinning_vertex" ],
20485 THREE.ShaderChunk[ "project_vertex" ],
20486 THREE.ShaderChunk[ "logdepthbuf_vertex" ],
20487
20488 THREE.ShaderChunk[ "worldpos_vertex" ],
20489 THREE.ShaderChunk[ "envmap_vertex" ],
20490 THREE.ShaderChunk[ "lights_lambert_vertex" ],
20491 THREE.ShaderChunk[ "shadowmap_vertex" ],
20492
20493 "}"
20494
20495 ].join( "\n" ),
20496
20497 fragmentShader: [
20498
20499 "uniform vec3 diffuse;",
20500 "uniform vec3 emissive;",
20501 "uniform float opacity;",
20502
20503 "uniform vec3 ambientLightColor;",
20504
20505 "varying vec3 vLightFront;",
20506
20507 "#ifdef DOUBLE_SIDED",
20508
20509 " varying vec3 vLightBack;",
20510
20511 "#endif",
20512
20513 THREE.ShaderChunk[ "common" ],
20514 THREE.ShaderChunk[ "color_pars_fragment" ],
20515 THREE.ShaderChunk[ "uv_pars_fragment" ],
20516 THREE.ShaderChunk[ "uv2_pars_fragment" ],
20517 THREE.ShaderChunk[ "map_pars_fragment" ],
20518 THREE.ShaderChunk[ "alphamap_pars_fragment" ],
20519 THREE.ShaderChunk[ "envmap_pars_fragment" ],
20520 THREE.ShaderChunk[ "fog_pars_fragment" ],
20521 THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
20522 THREE.ShaderChunk[ "specularmap_pars_fragment" ],
20523 THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
20524
20525 "void main() {",
20526
20527 " vec3 outgoingLight = vec3( 0.0 );",
20528 " vec4 diffuseColor = vec4( diffuse, opacity );",
20529 " vec3 totalAmbientLight = ambientLightColor;",
20530 " vec3 shadowMask = vec3( 1.0 );",
20531
20532 THREE.ShaderChunk[ "logdepthbuf_fragment" ],
20533 THREE.ShaderChunk[ "map_fragment" ],
20534 THREE.ShaderChunk[ "color_fragment" ],
20535 THREE.ShaderChunk[ "alphamap_fragment" ],
20536 THREE.ShaderChunk[ "alphatest_fragment" ],
20537 THREE.ShaderChunk[ "specularmap_fragment" ],
20538 THREE.ShaderChunk[ "shadowmap_fragment" ],
20539
20540 " #ifdef DOUBLE_SIDED",
20541
20542 " if ( gl_FrontFacing )",
20543 " outgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask + totalAmbientLight ) + emissive;",
20544 " else",
20545 " outgoingLight += diffuseColor.rgb * ( vLightBack * shadowMask + totalAmbientLight ) + emissive;",
20546
20547 " #else",
20548
20549 " outgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask + totalAmbientLight ) + emissive;",
20550
20551 " #endif",
20552
20553 THREE.ShaderChunk[ "envmap_fragment" ],
20554
20555 THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
20556
20557 THREE.ShaderChunk[ "fog_fragment" ],
20558
20559 " gl_FragColor = vec4( outgoingLight, diffuseColor.a );",
20560
20561 "}"
20562
20563 ].join( "\n" )
20564
20565 },
20566
20567 'phong': {
20568
20569 uniforms: THREE.UniformsUtils.merge( [
20570
20571 THREE.UniformsLib[ "common" ],
20572 THREE.UniformsLib[ "aomap" ],
20573 THREE.UniformsLib[ "lightmap" ],
20574 THREE.UniformsLib[ "emissivemap" ],
20575 THREE.UniformsLib[ "bumpmap" ],
20576 THREE.UniformsLib[ "normalmap" ],
20577 THREE.UniformsLib[ "displacementmap" ],
20578 THREE.UniformsLib[ "fog" ],
20579 THREE.UniformsLib[ "lights" ],
20580 THREE.UniformsLib[ "shadowmap" ],
20581
20582 {
20583 "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
20584 "specular" : { type: "c", value: new THREE.Color( 0x111111 ) },
20585 "shininess": { type: "f", value: 30 }
20586 }
20587
20588 ] ),
20589
20590 vertexShader: [
20591
20592 "#define PHONG",
20593
20594 "varying vec3 vViewPosition;",
20595
20596 "#ifndef FLAT_SHADED",
20597
20598 " varying vec3 vNormal;",
20599
20600 "#endif",
20601
20602 THREE.ShaderChunk[ "common" ],
20603 THREE.ShaderChunk[ "uv_pars_vertex" ],
20604 THREE.ShaderChunk[ "uv2_pars_vertex" ],
20605 THREE.ShaderChunk[ "displacementmap_pars_vertex" ],
20606 THREE.ShaderChunk[ "envmap_pars_vertex" ],
20607 THREE.ShaderChunk[ "lights_phong_pars_vertex" ],
20608 THREE.ShaderChunk[ "color_pars_vertex" ],
20609 THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
20610 THREE.ShaderChunk[ "skinning_pars_vertex" ],
20611 THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
20612 THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
20613
20614 "void main() {",
20615
20616 THREE.ShaderChunk[ "uv_vertex" ],
20617 THREE.ShaderChunk[ "uv2_vertex" ],
20618 THREE.ShaderChunk[ "color_vertex" ],
20619
20620 THREE.ShaderChunk[ "beginnormal_vertex" ],
20621 THREE.ShaderChunk[ "morphnormal_vertex" ],
20622 THREE.ShaderChunk[ "skinbase_vertex" ],
20623 THREE.ShaderChunk[ "skinnormal_vertex" ],
20624 THREE.ShaderChunk[ "defaultnormal_vertex" ],
20625
20626 "#ifndef FLAT_SHADED",
20627
20628 " vNormal = normalize( transformedNormal );",
20629
20630 "#endif",
20631
20632 THREE.ShaderChunk[ "begin_vertex" ],
20633 THREE.ShaderChunk[ "displacementmap_vertex" ],
20634 THREE.ShaderChunk[ "morphtarget_vertex" ],
20635 THREE.ShaderChunk[ "skinning_vertex" ],
20636 THREE.ShaderChunk[ "project_vertex" ],
20637 THREE.ShaderChunk[ "logdepthbuf_vertex" ],
20638
20639 " vViewPosition = - mvPosition.xyz;",
20640
20641 THREE.ShaderChunk[ "worldpos_vertex" ],
20642 THREE.ShaderChunk[ "envmap_vertex" ],
20643 THREE.ShaderChunk[ "lights_phong_vertex" ],
20644 THREE.ShaderChunk[ "shadowmap_vertex" ],
20645
20646 "}"
20647
20648 ].join( "\n" ),
20649
20650 fragmentShader: [
20651
20652 "#define PHONG",
20653
20654 "uniform vec3 diffuse;",
20655 "uniform vec3 emissive;",
20656 "uniform vec3 specular;",
20657 "uniform float shininess;",
20658 "uniform float opacity;",
20659
20660 THREE.ShaderChunk[ "common" ],
20661 THREE.ShaderChunk[ "color_pars_fragment" ],
20662 THREE.ShaderChunk[ "uv_pars_fragment" ],
20663 THREE.ShaderChunk[ "uv2_pars_fragment" ],
20664 THREE.ShaderChunk[ "map_pars_fragment" ],
20665 THREE.ShaderChunk[ "alphamap_pars_fragment" ],
20666 THREE.ShaderChunk[ "aomap_pars_fragment" ],
20667 THREE.ShaderChunk[ "lightmap_pars_fragment" ],
20668 THREE.ShaderChunk[ "emissivemap_pars_fragment" ],
20669 THREE.ShaderChunk[ "envmap_pars_fragment" ],
20670 THREE.ShaderChunk[ "fog_pars_fragment" ],
20671 THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
20672 THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
20673 THREE.ShaderChunk[ "bumpmap_pars_fragment" ],
20674 THREE.ShaderChunk[ "normalmap_pars_fragment" ],
20675 THREE.ShaderChunk[ "specularmap_pars_fragment" ],
20676 THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
20677
20678 "void main() {",
20679
20680 " vec3 outgoingLight = vec3( 0.0 );",
20681 " vec4 diffuseColor = vec4( diffuse, opacity );",
20682 " vec3 totalAmbientLight = ambientLightColor;",
20683 " vec3 totalEmissiveLight = emissive;",
20684 " vec3 shadowMask = vec3( 1.0 );",
20685
20686 THREE.ShaderChunk[ "logdepthbuf_fragment" ],
20687 THREE.ShaderChunk[ "map_fragment" ],
20688 THREE.ShaderChunk[ "color_fragment" ],
20689 THREE.ShaderChunk[ "alphamap_fragment" ],
20690 THREE.ShaderChunk[ "alphatest_fragment" ],
20691 THREE.ShaderChunk[ "specularmap_fragment" ],
20692 THREE.ShaderChunk[ "normal_phong_fragment" ],
20693 THREE.ShaderChunk[ "lightmap_fragment" ],
20694 THREE.ShaderChunk[ "hemilight_fragment" ],
20695 THREE.ShaderChunk[ "aomap_fragment" ],
20696 THREE.ShaderChunk[ "emissivemap_fragment" ],
20697
20698 THREE.ShaderChunk[ "lights_phong_fragment" ],
20699 THREE.ShaderChunk[ "shadowmap_fragment" ],
20700
20701 "totalDiffuseLight *= shadowMask;",
20702 "totalSpecularLight *= shadowMask;",
20703
20704 "#ifdef METAL",
20705
20706 " outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + totalAmbientLight ) * specular + totalSpecularLight + totalEmissiveLight;",
20707
20708 "#else",
20709
20710 " outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + totalAmbientLight ) + totalSpecularLight + totalEmissiveLight;",
20711
20712 "#endif",
20713
20714 THREE.ShaderChunk[ "envmap_fragment" ],
20715
20716 THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
20717
20718 THREE.ShaderChunk[ "fog_fragment" ],
20719
20720 " gl_FragColor = vec4( outgoingLight, diffuseColor.a );",
20721
20722 "}"
20723
20724 ].join( "\n" )
20725
20726 },
20727
20728 'points': {
20729
20730 uniforms: THREE.UniformsUtils.merge( [
20731
20732 THREE.UniformsLib[ "points" ],
20733 THREE.UniformsLib[ "shadowmap" ]
20734
20735 ] ),
20736
20737 vertexShader: [
20738
20739 "uniform float size;",
20740 "uniform float scale;",
20741
20742 THREE.ShaderChunk[ "common" ],
20743 THREE.ShaderChunk[ "color_pars_vertex" ],
20744 THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
20745 THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
20746
20747 "void main() {",
20748
20749 THREE.ShaderChunk[ "color_vertex" ],
20750
20751 " vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
20752
20753 " #ifdef USE_SIZEATTENUATION",
20754 " gl_PointSize = size * ( scale / length( mvPosition.xyz ) );",
20755 " #else",
20756 " gl_PointSize = size;",
20757 " #endif",
20758
20759 " gl_Position = projectionMatrix * mvPosition;",
20760
20761 THREE.ShaderChunk[ "logdepthbuf_vertex" ],
20762 THREE.ShaderChunk[ "worldpos_vertex" ],
20763 THREE.ShaderChunk[ "shadowmap_vertex" ],
20764
20765 "}"
20766
20767 ].join( "\n" ),
20768
20769 fragmentShader: [
20770
20771 "uniform vec3 psColor;",
20772 "uniform float opacity;",
20773
20774 THREE.ShaderChunk[ "common" ],
20775 THREE.ShaderChunk[ "color_pars_fragment" ],
20776 THREE.ShaderChunk[ "map_particle_pars_fragment" ],
20777 THREE.ShaderChunk[ "fog_pars_fragment" ],
20778 THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
20779 THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
20780
20781 "void main() {",
20782
20783 " vec3 outgoingLight = vec3( 0.0 );",
20784 " vec4 diffuseColor = vec4( psColor, opacity );",
20785 " vec3 shadowMask = vec3( 1.0 );",
20786
20787 THREE.ShaderChunk[ "logdepthbuf_fragment" ],
20788 THREE.ShaderChunk[ "map_particle_fragment" ],
20789 THREE.ShaderChunk[ "color_fragment" ],
20790 THREE.ShaderChunk[ "alphatest_fragment" ],
20791 THREE.ShaderChunk[ "shadowmap_fragment" ],
20792
20793 " outgoingLight = diffuseColor.rgb * shadowMask;",
20794
20795 THREE.ShaderChunk[ "fog_fragment" ],
20796
20797 " gl_FragColor = vec4( outgoingLight, diffuseColor.a );",
20798
20799 "}"
20800
20801 ].join( "\n" )
20802
20803 },
20804
20805 'dashed': {
20806
20807 uniforms: THREE.UniformsUtils.merge( [
20808
20809 THREE.UniformsLib[ "common" ],
20810 THREE.UniformsLib[ "fog" ],
20811
20812 {
20813 "scale" : { type: "f", value: 1 },
20814 "dashSize" : { type: "f", value: 1 },
20815 "totalSize": { type: "f", value: 2 }
20816 }
20817
20818 ] ),
20819
20820 vertexShader: [
20821
20822 "uniform float scale;",
20823 "attribute float lineDistance;",
20824
20825 "varying float vLineDistance;",
20826
20827 THREE.ShaderChunk[ "common" ],
20828 THREE.ShaderChunk[ "color_pars_vertex" ],
20829 THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
20830
20831 "void main() {",
20832
20833 THREE.ShaderChunk[ "color_vertex" ],
20834
20835 " vLineDistance = scale * lineDistance;",
20836
20837 " vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
20838 " gl_Position = projectionMatrix * mvPosition;",
20839
20840 THREE.ShaderChunk[ "logdepthbuf_vertex" ],
20841
20842 "}"
20843
20844 ].join( "\n" ),
20845
20846 fragmentShader: [
20847
20848 "uniform vec3 diffuse;",
20849 "uniform float opacity;",
20850
20851 "uniform float dashSize;",
20852 "uniform float totalSize;",
20853
20854 "varying float vLineDistance;",
20855
20856 THREE.ShaderChunk[ "common" ],
20857 THREE.ShaderChunk[ "color_pars_fragment" ],
20858 THREE.ShaderChunk[ "fog_pars_fragment" ],
20859 THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
20860
20861 "void main() {",
20862
20863 " if ( mod( vLineDistance, totalSize ) > dashSize ) {",
20864
20865 " discard;",
20866
20867 " }",
20868
20869 " vec3 outgoingLight = vec3( 0.0 );",
20870 " vec4 diffuseColor = vec4( diffuse, opacity );",
20871
20872 THREE.ShaderChunk[ "logdepthbuf_fragment" ],
20873 THREE.ShaderChunk[ "color_fragment" ],
20874
20875 " outgoingLight = diffuseColor.rgb;",
20876
20877 THREE.ShaderChunk[ "fog_fragment" ],
20878
20879 " gl_FragColor = vec4( outgoingLight, diffuseColor.a );",
20880
20881 "}"
20882
20883 ].join( "\n" )
20884
20885 },
20886
20887 'depth': {
20888
20889 uniforms: {
20890
20891 "mNear": { type: "f", value: 1.0 },
20892 "mFar" : { type: "f", value: 2000.0 },
20893 "opacity" : { type: "f", value: 1.0 }
20894
20895 },
20896
20897 vertexShader: [
20898
20899 THREE.ShaderChunk[ "common" ],
20900 THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
20901 THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
20902
20903 "void main() {",
20904
20905 THREE.ShaderChunk[ "begin_vertex" ],
20906 THREE.ShaderChunk[ "morphtarget_vertex" ],
20907 THREE.ShaderChunk[ "project_vertex" ],
20908 THREE.ShaderChunk[ "logdepthbuf_vertex" ],
20909
20910 "}"
20911
20912 ].join( "\n" ),
20913
20914 fragmentShader: [
20915
20916 "uniform float mNear;",
20917 "uniform float mFar;",
20918 "uniform float opacity;",
20919
20920 THREE.ShaderChunk[ "common" ],
20921 THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
20922
20923 "void main() {",
20924
20925 THREE.ShaderChunk[ "logdepthbuf_fragment" ],
20926
20927 " #ifdef USE_LOGDEPTHBUF_EXT",
20928
20929 " float depth = gl_FragDepthEXT / gl_FragCoord.w;",
20930
20931 " #else",
20932
20933 " float depth = gl_FragCoord.z / gl_FragCoord.w;",
20934
20935 " #endif",
20936
20937 " float color = 1.0 - smoothstep( mNear, mFar, depth );",
20938 " gl_FragColor = vec4( vec3( color ), opacity );",
20939
20940 "}"
20941
20942 ].join( "\n" )
20943
20944 },
20945
20946 'normal': {
20947
20948 uniforms: {
20949
20950 "opacity" : { type: "f", value: 1.0 }
20951
20952 },
20953
20954 vertexShader: [
20955
20956 "varying vec3 vNormal;",
20957
20958 THREE.ShaderChunk[ "common" ],
20959 THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
20960 THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
20961
20962 "void main() {",
20963
20964 " vNormal = normalize( normalMatrix * normal );",
20965
20966 THREE.ShaderChunk[ "begin_vertex" ],
20967 THREE.ShaderChunk[ "morphtarget_vertex" ],
20968 THREE.ShaderChunk[ "project_vertex" ],
20969 THREE.ShaderChunk[ "logdepthbuf_vertex" ],
20970
20971 "}"
20972
20973 ].join( "\n" ),
20974
20975 fragmentShader: [
20976
20977 "uniform float opacity;",
20978 "varying vec3 vNormal;",
20979
20980 THREE.ShaderChunk[ "common" ],
20981 THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
20982
20983 "void main() {",
20984
20985 " gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",
20986
20987 THREE.ShaderChunk[ "logdepthbuf_fragment" ],
20988
20989 "}"
20990
20991 ].join( "\n" )
20992
20993 },
20994
20995
20996
20997
20998
20999 'cube': {
21000
21001 uniforms: { "tCube": { type: "t", value: null },
21002 "tFlip": { type: "f", value: - 1 } },
21003
21004 vertexShader: [
21005
21006 "varying vec3 vWorldPosition;",
21007
21008 THREE.ShaderChunk[ "common" ],
21009 THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
21010
21011 "void main() {",
21012
21013 " vWorldPosition = transformDirection( position, modelMatrix );",
21014
21015 " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
21016
21017 THREE.ShaderChunk[ "logdepthbuf_vertex" ],
21018
21019 "}"
21020
21021 ].join( "\n" ),
21022
21023 fragmentShader: [
21024
21025 "uniform samplerCube tCube;",
21026 "uniform float tFlip;",
21027
21028 "varying vec3 vWorldPosition;",
21029
21030 THREE.ShaderChunk[ "common" ],
21031 THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
21032
21033 "void main() {",
21034
21035 " gl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );",
21036
21037 THREE.ShaderChunk[ "logdepthbuf_fragment" ],
21038
21039 "}"
21040
21041 ].join( "\n" )
21042
21043 },
21044
21045
21046
21047
21048
21049 'equirect': {
21050
21051 uniforms: { "tEquirect": { type: "t", value: null },
21052 "tFlip": { type: "f", value: - 1 } },
21053
21054 vertexShader: [
21055
21056 "varying vec3 vWorldPosition;",
21057
21058 THREE.ShaderChunk[ "common" ],
21059 THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
21060
21061 "void main() {",
21062
21063 " vWorldPosition = transformDirection( position, modelMatrix );",
21064
21065 " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
21066
21067 THREE.ShaderChunk[ "logdepthbuf_vertex" ],
21068
21069 "}"
21070
21071 ].join( "\n" ),
21072
21073 fragmentShader: [
21074
21075 "uniform sampler2D tEquirect;",
21076 "uniform float tFlip;",
21077
21078 "varying vec3 vWorldPosition;",
21079
21080 THREE.ShaderChunk[ "common" ],
21081 THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
21082
21083 "void main() {",
21084
21085
21086 "vec3 direction = normalize( vWorldPosition );",
21087 "vec2 sampleUV;",
21088 "sampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );",
21089 "sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;",
21090 "gl_FragColor = texture2D( tEquirect, sampleUV );",
21091
21092 THREE.ShaderChunk[ "logdepthbuf_fragment" ],
21093
21094 "}"
21095
21096 ].join( "\n" )
21097
21098 },
21099
21100
21101
21102
21103
21104
21105
21106
21107
21108
21109
21110
21111
21112 'depthRGBA': {
21113
21114 uniforms: {},
21115
21116 vertexShader: [
21117
21118 THREE.ShaderChunk[ "common" ],
21119 THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
21120 THREE.ShaderChunk[ "skinning_pars_vertex" ],
21121 THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
21122
21123 "void main() {",
21124
21125 THREE.ShaderChunk[ "skinbase_vertex" ],
21126
21127 THREE.ShaderChunk[ "begin_vertex" ],
21128 THREE.ShaderChunk[ "morphtarget_vertex" ],
21129 THREE.ShaderChunk[ "skinning_vertex" ],
21130 THREE.ShaderChunk[ "project_vertex" ],
21131 THREE.ShaderChunk[ "logdepthbuf_vertex" ],
21132
21133 "}"
21134
21135 ].join( "\n" ),
21136
21137 fragmentShader: [
21138
21139 THREE.ShaderChunk[ "common" ],
21140 THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
21141
21142 "vec4 pack_depth( const in float depth ) {",
21143
21144 " const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );",
21145 " const vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );",
21146 " vec4 res = mod( depth * bit_shift * vec4( 255 ), vec4( 256 ) ) / vec4( 255 );",
21147 " res -= res.xxyz * bit_mask;",
21148 " return res;",
21149
21150 "}",
21151
21152 "void main() {",
21153
21154 THREE.ShaderChunk[ "logdepthbuf_fragment" ],
21155
21156 " #ifdef USE_LOGDEPTHBUF_EXT",
21157
21158 " gl_FragData[ 0 ] = pack_depth( gl_FragDepthEXT );",
21159
21160 " #else",
21161
21162 " gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );",
21163
21164 " #endif",
21165
21166
21167
21168
21169
21170
21171 "}"
21172
21173 ].join( "\n" )
21174
21175 },
21176
21177
21178 'distanceRGBA': {
21179
21180 uniforms: {
21181
21182 "lightPos": { type: "v3", value: new THREE.Vector3( 0, 0, 0 ) }
21183
21184 },
21185
21186 vertexShader: [
21187
21188 "varying vec4 vWorldPosition;",
21189
21190 THREE.ShaderChunk[ "common" ],
21191 THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
21192 THREE.ShaderChunk[ "skinning_pars_vertex" ],
21193
21194 "void main() {",
21195
21196 THREE.ShaderChunk[ "skinbase_vertex" ],
21197 THREE.ShaderChunk[ "begin_vertex" ],
21198 THREE.ShaderChunk[ "morphtarget_vertex" ],
21199 THREE.ShaderChunk[ "skinning_vertex" ],
21200 THREE.ShaderChunk[ "project_vertex" ],
21201 THREE.ShaderChunk[ "worldpos_vertex" ],
21202
21203 "vWorldPosition = worldPosition;",
21204
21205 "}"
21206
21207 ].join( "\n" ),
21208
21209 fragmentShader: [
21210
21211 "uniform vec3 lightPos;",
21212 "varying vec4 vWorldPosition;",
21213
21214 THREE.ShaderChunk[ "common" ],
21215
21216 "vec4 pack1K ( float depth ) {",
21217
21218 " depth /= 1000.0;",
21219 " const vec4 bitSh = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );",
21220 " const vec4 bitMsk = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );",
21221 " vec4 res = fract( depth * bitSh );",
21222 " res -= res.xxyz * bitMsk;",
21223 " return res; ",
21224
21225 "}",
21226
21227 "float unpack1K ( vec4 color ) {",
21228
21229 " const vec4 bitSh = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );",
21230 " return dot( color, bitSh ) * 1000.0;",
21231
21232 "}",
21233
21234 "void main () {",
21235
21236 " gl_FragColor = pack1K( length( vWorldPosition.xyz - lightPos.xyz ) );",
21237
21238 "}"
21239
21240 ].join( "\n" )
21241
21242 }
21243
21244 };
21245
21246
21247
21255 THREE.WebGLRenderer = function ( parameters ) {
21256
21257 console.log( 'THREE.WebGLRenderer', THREE.REVISION );
21258
21259 parameters = parameters || {};
21260
21261 var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' ),
21262 _context = parameters.context !== undefined ? parameters.context : null,
21263
21264 _width = _canvas.width,
21265 _height = _canvas.height,
21266
21267 pixelRatio = 1,
21268
21269 _alpha = parameters.alpha !== undefined ? parameters.alpha : false,
21270 _depth = parameters.depth !== undefined ? parameters.depth : true,
21271 _stencil = parameters.stencil !== undefined ? parameters.stencil : true,
21272 _antialias = parameters.antialias !== undefined ? parameters.antialias : false,
21273 _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
21274 _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
21275
21276 _clearColor = new THREE.Color( 0x000000 ),
21277 _clearAlpha = 0;
21278
21279 var lights = [];
21280
21281 var opaqueObjects = [];
21282 var opaqueObjectsLastIndex = - 1;
21283 var transparentObjects = [];
21284 var transparentObjectsLastIndex = - 1;
21285
21286 var morphInfluences = new Float32Array( 8 );
21287
21288
21289 var sprites = [];
21290 var lensFlares = [];
21291
21292
21293
21294 this.domElement = _canvas;
21295 this.context = null;
21296
21297
21298
21299 this.autoClear = true;
21300 this.autoClearColor = true;
21301 this.autoClearDepth = true;
21302 this.autoClearStencil = true;
21303
21304
21305
21306 this.sortObjects = true;
21307
21308
21309
21310 this.gammaFactor = 2.0;
21311 this.gammaInput = false;
21312 this.gammaOutput = false;
21313
21314
21315
21316 this.maxMorphTargets = 8;
21317 this.maxMorphNormals = 4;
21318
21319
21320
21321 this.autoScaleCubemaps = true;
21322
21323
21324
21325 var _this = this,
21326
21327
21328
21329 _currentProgram = null,
21330 _currentFramebuffer = null,
21331 _currentMaterialId = - 1,
21332 _currentGeometryProgram = '',
21333 _currentCamera = null,
21334
21335 _usedTextureUnits = 0,
21336
21337 _viewportX = 0,
21338 _viewportY = 0,
21339 _viewportWidth = _canvas.width,
21340 _viewportHeight = _canvas.height,
21341 _currentWidth = 0,
21342 _currentHeight = 0,
21343
21344
21345
21346 _frustum = new THREE.Frustum(),
21347
21348
21349
21350 _projScreenMatrix = new THREE.Matrix4(),
21351
21352 _vector3 = new THREE.Vector3(),
21353
21354
21355
21356 _direction = new THREE.Vector3(),
21357
21358 _lightsNeedUpdate = true,
21359
21360 _lights = {
21361
21362 ambient: [ 0, 0, 0 ],
21363 directional: { length: 0, colors: [], positions: [] },
21364 point: { length: 0, colors: [], positions: [], distances: [], decays: [] },
21365 spot: { length: 0, colors: [], positions: [], distances: [], directions: [], anglesCos: [], exponents: [], decays: [] },
21366 hemi: { length: 0, skyColors: [], groundColors: [], positions: [] }
21367
21368 },
21369
21370
21371
21372 _infoMemory = {
21373
21374 geometries: 0,
21375 textures: 0
21376
21377 },
21378
21379 _infoRender = {
21380
21381 calls: 0,
21382 vertices: 0,
21383 faces: 0,
21384 points: 0
21385
21386 };
21387
21388 this.info = {
21389
21390 render: _infoRender,
21391 memory: _infoMemory,
21392 programs: null
21393
21394 };
21395
21396
21397
21398
21399 var _gl;
21400
21401 try {
21402
21403 var attributes = {
21404 alpha: _alpha,
21405 depth: _depth,
21406 stencil: _stencil,
21407 antialias: _antialias,
21408 premultipliedAlpha: _premultipliedAlpha,
21409 preserveDrawingBuffer: _preserveDrawingBuffer
21410 };
21411
21412 _gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );
21413
21414 if ( _gl === null ) {
21415
21416 if ( _canvas.getContext( 'webgl' ) !== null ) {
21417
21418 throw 'Error creating WebGL context with your selected attributes.';
21419
21420 } else {
21421
21422 throw 'Error creating WebGL context.';
21423
21424 }
21425
21426 }
21427
21428 _canvas.addEventListener( 'webglcontextlost', onContextLost, false );
21429
21430 } catch ( error ) {
21431
21432 console.error( 'THREE.WebGLRenderer: ' + error );
21433
21434 }
21435
21436 var extensions = new THREE.WebGLExtensions( _gl );
21437
21438 extensions.get( 'OES_texture_float' );
21439 extensions.get( 'OES_texture_float_linear' );
21440 extensions.get( 'OES_texture_half_float' );
21441 extensions.get( 'OES_texture_half_float_linear' );
21442 extensions.get( 'OES_standard_derivatives' );
21443 extensions.get( 'ANGLE_instanced_arrays' );
21444
21445 if ( extensions.get( 'OES_element_index_uint' ) ) {
21446
21447 THREE.BufferGeometry.MaxIndex = 4294967296;
21448
21449 }
21450
21451 var capabilities = new THREE.WebGLCapabilities( _gl, extensions, parameters );
21452
21453 var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
21454 var properties = new THREE.WebGLProperties();
21455 var objects = new THREE.WebGLObjects( _gl, properties, this.info );
21456 var programCache = new THREE.WebGLPrograms( this, capabilities );
21457
21458 this.info.programs = programCache.programs;
21459
21460 var bufferRenderer = new THREE.WebGLBufferRenderer( _gl, extensions, _infoRender );
21461 var indexedBufferRenderer = new THREE.WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
21462
21463
21464
21465 function glClearColor( r, g, b, a ) {
21466
21467 if ( _premultipliedAlpha === true ) {
21468
21469 r *= a; g *= a; b *= a;
21470
21471 }
21472
21473 _gl.clearColor( r, g, b, a );
21474
21475 }
21476
21477 function setDefaultGLState() {
21478
21479 state.init();
21480
21481 _gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
21482
21483 glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
21484
21485 }
21486
21487 function resetGLState() {
21488
21489 _currentProgram = null;
21490 _currentCamera = null;
21491
21492 _currentGeometryProgram = '';
21493 _currentMaterialId = - 1;
21494
21495 _lightsNeedUpdate = true;
21496
21497 state.reset();
21498
21499 }
21500
21501 setDefaultGLState();
21502
21503 this.context = _gl;
21504 this.capabilities = capabilities;
21505 this.extensions = extensions;
21506 this.state = state;
21507
21508
21509
21510 var shadowMap = new THREE.WebGLShadowMap( this, lights, objects );
21511
21512 this.shadowMap = shadowMap;
21513
21514
21515
21516
21517 var spritePlugin = new THREE.SpritePlugin( this, sprites );
21518 var lensFlarePlugin = new THREE.LensFlarePlugin( this, lensFlares );
21519
21520
21521
21522 this.getContext = function () {
21523
21524 return _gl;
21525
21526 };
21527
21528 this.getContextAttributes = function () {
21529
21530 return _gl.getContextAttributes();
21531
21532 };
21533
21534 this.forceContextLoss = function () {
21535
21536 extensions.get( 'WEBGL_lose_context' ).loseContext();
21537
21538 };
21539
21540 this.getMaxAnisotropy = ( function () {
21541
21542 var value;
21543
21544 return function getMaxAnisotropy() {
21545
21546 if ( value !== undefined ) return value;
21547
21548 var extension = extensions.get( 'EXT_texture_filter_anisotropic' );
21549
21550 if ( extension !== null ) {
21551
21552 value = _gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );
21553
21554 } else {
21555
21556 value = 0;
21557
21558 }
21559
21560 return value;
21561
21562 }
21563
21564 } )();
21565
21566 this.getPrecision = function () {
21567
21568 return capabilities.precision;
21569
21570 };
21571
21572 this.getPixelRatio = function () {
21573
21574 return pixelRatio;
21575
21576 };
21577
21578 this.setPixelRatio = function ( value ) {
21579
21580 if ( value !== undefined ) pixelRatio = value;
21581
21582 };
21583
21584 this.getSize = function () {
21585
21586 return {
21587 width: _width,
21588 height: _height
21589 };
21590
21591 };
21592
21593 this.setSize = function ( width, height, updateStyle ) {
21594
21595 _width = width;
21596 _height = height;
21597
21598 _canvas.width = width * pixelRatio;
21599 _canvas.height = height * pixelRatio;
21600
21601 if ( updateStyle !== false ) {
21602
21603 _canvas.style.width = width + 'px';
21604 _canvas.style.height = height + 'px';
21605
21606 }
21607
21608 this.setViewport( 0, 0, width, height );
21609
21610 };
21611
21612 this.setViewport = function ( x, y, width, height ) {
21613
21614 _viewportX = x * pixelRatio;
21615 _viewportY = y * pixelRatio;
21616
21617 _viewportWidth = width * pixelRatio;
21618 _viewportHeight = height * pixelRatio;
21619
21620 _gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
21621
21622 };
21623
21624 this.getViewport = function ( dimensions ) {
21625
21626 dimensions.x = _viewportX / pixelRatio;
21627 dimensions.y = _viewportY / pixelRatio;
21628
21629 dimensions.z = _viewportWidth / pixelRatio;
21630 dimensions.w = _viewportHeight / pixelRatio;
21631
21632 };
21633
21634 this.setScissor = function ( x, y, width, height ) {
21635
21636 _gl.scissor(
21637 x * pixelRatio,
21638 y * pixelRatio,
21639 width * pixelRatio,
21640 height * pixelRatio
21641 );
21642
21643 };
21644
21645 this.enableScissorTest = function ( boolean ) {
21646
21647 state.setScissorTest( boolean );
21648
21649 };
21650
21651
21652
21653 this.getClearColor = function () {
21654
21655 return _clearColor;
21656
21657 };
21658
21659 this.setClearColor = function ( color, alpha ) {
21660
21661 _clearColor.set( color );
21662
21663 _clearAlpha = alpha !== undefined ? alpha : 1;
21664
21665 glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
21666
21667 };
21668
21669 this.getClearAlpha = function () {
21670
21671 return _clearAlpha;
21672
21673 };
21674
21675 this.setClearAlpha = function ( alpha ) {
21676
21677 _clearAlpha = alpha;
21678
21679 glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
21680
21681 };
21682
21683 this.clear = function ( color, depth, stencil ) {
21684
21685 var bits = 0;
21686
21687 if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;
21688 if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;
21689 if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;
21690
21691 _gl.clear( bits );
21692
21693 };
21694
21695 this.clearColor = function () {
21696
21697 _gl.clear( _gl.COLOR_BUFFER_BIT );
21698
21699 };
21700
21701 this.clearDepth = function () {
21702
21703 _gl.clear( _gl.DEPTH_BUFFER_BIT );
21704
21705 };
21706
21707 this.clearStencil = function () {
21708
21709 _gl.clear( _gl.STENCIL_BUFFER_BIT );
21710
21711 };
21712
21713 this.clearTarget = function ( renderTarget, color, depth, stencil ) {
21714
21715 this.setRenderTarget( renderTarget );
21716 this.clear( color, depth, stencil );
21717
21718 };
21719
21720
21721
21722 this.resetGLState = resetGLState;
21723
21724 this.dispose = function() {
21725
21726 _canvas.removeEventListener( 'webglcontextlost', onContextLost, false );
21727
21728 };
21729
21730
21731
21732 function onContextLost( event ) {
21733
21734 event.preventDefault();
21735
21736 resetGLState();
21737 setDefaultGLState();
21738
21739 properties.clear();
21740
21741 };
21742
21743 function onTextureDispose( event ) {
21744
21745 var texture = event.target;
21746
21747 texture.removeEventListener( 'dispose', onTextureDispose );
21748
21749 deallocateTexture( texture );
21750
21751 _infoMemory.textures --;
21752
21753
21754 }
21755
21756 function onRenderTargetDispose( event ) {
21757
21758 var renderTarget = event.target;
21759
21760 renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );
21761
21762 deallocateRenderTarget( renderTarget );
21763
21764 _infoMemory.textures --;
21765
21766 }
21767
21768 function onMaterialDispose( event ) {
21769
21770 var material = event.target;
21771
21772 material.removeEventListener( 'dispose', onMaterialDispose );
21773
21774 deallocateMaterial( material );
21775
21776 }
21777
21778
21779
21780 function deallocateTexture( texture ) {
21781
21782 var textureProperties = properties.get( texture );
21783
21784 if ( texture.image && textureProperties.__image__webglTextureCube ) {
21785
21786
21787
21788 _gl.deleteTexture( textureProperties.__image__webglTextureCube );
21789
21790 } else {
21791
21792
21793
21794 if ( textureProperties.__webglInit === undefined ) return;
21795
21796 _gl.deleteTexture( textureProperties.__webglTexture );
21797
21798 }
21799
21800
21801 properties.delete( texture );
21802
21803 }
21804
21805 function deallocateRenderTarget( renderTarget ) {
21806
21807 var renderTargetProperties = properties.get( renderTarget );
21808 var textureProperties = properties.get( renderTarget.texture );
21809
21810 if ( ! renderTarget || textureProperties.__webglTexture === undefined ) return;
21811
21812 _gl.deleteTexture( textureProperties.__webglTexture );
21813
21814 if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
21815
21816 for ( var i = 0; i < 6; i ++ ) {
21817
21818 _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
21819 _gl.deleteRenderbuffer( renderTargetProperties.__webglRenderbuffer[ i ] );
21820
21821 }
21822
21823 } else {
21824
21825 _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
21826 _gl.deleteRenderbuffer( renderTargetProperties.__webglRenderbuffer );
21827
21828 }
21829
21830 properties.delete( renderTarget.texture );
21831 properties.delete( renderTarget );
21832
21833 }
21834
21835 function deallocateMaterial( material ) {
21836
21837 releaseMaterialProgramReference( material );
21838
21839 properties.delete( material );
21840
21841 }
21842
21843
21844 function releaseMaterialProgramReference( material ) {
21845
21846 var programInfo = properties.get( material ).program;
21847
21848 material.program = undefined;
21849
21850 if ( programInfo !== undefined ) {
21851
21852 programCache.releaseProgram( programInfo );
21853
21854 }
21855
21856 }
21857
21858
21859
21860 this.renderBufferImmediate = function ( object, program, material ) {
21861
21862 state.initAttributes();
21863
21864 var buffers = properties.get( object );
21865
21866 if ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();
21867 if ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();
21868 if ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();
21869 if ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();
21870
21871 var attributes = program.getAttributes();
21872
21873 if ( object.hasPositions ) {
21874
21875 _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
21876 _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
21877
21878 state.enableAttribute( attributes.position );
21879 _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
21880
21881 }
21882
21883 if ( object.hasNormals ) {
21884
21885 _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );
21886
21887 if ( material.type !== 'MeshPhongMaterial' && material.shading === THREE.FlatShading ) {
21888
21889 for ( var i = 0, l = object.count * 3; i < l; i += 9 ) {
21890
21891 var array = object.normalArray;
21892
21893 var nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;
21894 var ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;
21895 var nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;
21896
21897 array[ i + 0 ] = nx;
21898 array[ i + 1 ] = ny;
21899 array[ i + 2 ] = nz;
21900
21901 array[ i + 3 ] = nx;
21902 array[ i + 4 ] = ny;
21903 array[ i + 5 ] = nz;
21904
21905 array[ i + 6 ] = nx;
21906 array[ i + 7 ] = ny;
21907 array[ i + 8 ] = nz;
21908
21909 }
21910
21911 }
21912
21913 _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
21914
21915 state.enableAttribute( attributes.normal );
21916
21917 _gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
21918
21919 }
21920
21921 if ( object.hasUvs && material.map ) {
21922
21923 _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
21924 _gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
21925
21926 state.enableAttribute( attributes.uv );
21927
21928 _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
21929
21930 }
21931
21932 if ( object.hasColors && material.vertexColors !== THREE.NoColors ) {
21933
21934 _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
21935 _gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
21936
21937 state.enableAttribute( attributes.color );
21938
21939 _gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
21940
21941 }
21942
21943 state.disableUnusedAttributes();
21944
21945 _gl.drawArrays( _gl.TRIANGLES, 0, object.count );
21946
21947 object.count = 0;
21948
21949 };
21950
21951 this.renderBufferDirect = function ( camera, lights, fog, geometry, material, object, group ) {
21952
21953 setMaterial( material );
21954
21955 var program = setProgram( camera, lights, fog, material, object );
21956
21957 var updateBuffers = false;
21958 var geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;
21959
21960 if ( geometryProgram !== _currentGeometryProgram ) {
21961
21962 _currentGeometryProgram = geometryProgram;
21963 updateBuffers = true;
21964
21965 }
21966
21967
21968
21969 var morphTargetInfluences = object.morphTargetInfluences;
21970
21971 if ( morphTargetInfluences !== undefined ) {
21972
21973 var activeInfluences = [];
21974
21975 for ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {
21976
21977 var influence = morphTargetInfluences[ i ];
21978 activeInfluences.push( [ influence, i ] );
21979
21980 }
21981
21982 activeInfluences.sort( numericalSort );
21983
21984 if ( activeInfluences.length > 8 ) {
21985
21986 activeInfluences.length = 8;
21987
21988 }
21989
21990 var morphAttributes = geometry.morphAttributes;
21991
21992 for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {
21993
21994 var influence = activeInfluences[ i ];
21995 morphInfluences[ i ] = influence[ 0 ];
21996
21997 if ( influence[ 0 ] !== 0 ) {
21998
21999 var index = influence[ 1 ];
22000
22001 if ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );
22002 if ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );
22003
22004 } else {
22005
22006 if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
22007 if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
22008
22009 }
22010
22011 }
22012
22013 var uniforms = program.getUniforms();
22014
22015 if ( uniforms.morphTargetInfluences !== null ) {
22016
22017 _gl.uniform1fv( uniforms.morphTargetInfluences, morphInfluences );
22018
22019 }
22020
22021 updateBuffers = true;
22022
22023 }
22024
22025
22026
22027 var index = geometry.index;
22028 var position = geometry.attributes.position;
22029
22030 if ( material.wireframe === true ) {
22031
22032 index = objects.getWireframeAttribute( geometry );
22033
22034 }
22035
22036 var renderer;
22037
22038 if ( index !== null ) {
22039
22040 renderer = indexedBufferRenderer;
22041 renderer.setIndex( index );
22042
22043 } else {
22044
22045 renderer = bufferRenderer;
22046
22047 }
22048
22049 if ( updateBuffers ) {
22050
22051 setupVertexAttributes( material, program, geometry );
22052
22053 if ( index !== null ) {
22054
22055 _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );
22056
22057 }
22058
22059 }
22060
22061
22062
22063 var dataStart = 0;
22064 var dataCount = Infinity;
22065
22066 if ( index !== null ) {
22067
22068 dataCount = index.count
22069
22070 } else if ( position !== undefined ) {
22071
22072 dataCount = position.count;
22073
22074 }
22075
22076 var rangeStart = geometry.drawRange.start;
22077 var rangeCount = geometry.drawRange.count;
22078
22079 var groupStart = group !== null ? group.start : 0;
22080 var groupCount = group !== null ? group.count : Infinity;
22081
22082 var drawStart = Math.max( dataStart, rangeStart, groupStart );
22083 var drawEnd = Math.min( dataStart + dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
22084
22085 var drawCount = Math.max( 0, drawEnd - drawStart + 1 );
22086
22087
22088
22089 if ( object instanceof THREE.Mesh ) {
22090
22091 if ( material.wireframe === true ) {
22092
22093 state.setLineWidth( material.wireframeLinewidth * pixelRatio );
22094 renderer.setMode( _gl.LINES );
22095
22096 } else {
22097
22098 renderer.setMode( _gl.TRIANGLES );
22099
22100 }
22101
22102 if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) {
22103
22104 renderer.renderInstances( geometry );
22105
22106 } else {
22107
22108 renderer.render( drawStart, drawCount );
22109
22110 }
22111
22112 } else if ( object instanceof THREE.Line ) {
22113
22114 var lineWidth = material.linewidth;
22115
22116 if ( lineWidth === undefined ) lineWidth = 1;
22117
22118 state.setLineWidth( lineWidth * pixelRatio );
22119
22120 if ( object instanceof THREE.LineSegments ) {
22121
22122 renderer.setMode( _gl.LINES );
22123
22124 } else {
22125
22126 renderer.setMode( _gl.LINE_STRIP );
22127
22128 }
22129
22130 renderer.render( drawStart, drawCount );
22131
22132 } else if ( object instanceof THREE.Points ) {
22133
22134 renderer.setMode( _gl.POINTS );
22135 renderer.render( drawStart, drawCount );
22136
22137 }
22138
22139 };
22140
22141 function setupVertexAttributes( material, program, geometry, startIndex ) {
22142
22143 var extension;
22144
22145 if ( geometry instanceof THREE.InstancedBufferGeometry ) {
22146
22147 extension = extensions.get( 'ANGLE_instanced_arrays' );
22148
22149 if ( extension === null ) {
22150
22151 console.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
22152 return;
22153
22154 }
22155
22156 }
22157
22158 if ( startIndex === undefined ) startIndex = 0;
22159
22160 state.initAttributes();
22161
22162 var geometryAttributes = geometry.attributes;
22163
22164 var programAttributes = program.getAttributes();
22165
22166 var materialDefaultAttributeValues = material.defaultAttributeValues;
22167
22168 for ( var name in programAttributes ) {
22169
22170 var programAttribute = programAttributes[ name ];
22171
22172 if ( programAttribute >= 0 ) {
22173
22174 var geometryAttribute = geometryAttributes[ name ];
22175
22176 if ( geometryAttribute !== undefined ) {
22177
22178 var size = geometryAttribute.itemSize;
22179 var buffer = objects.getAttributeBuffer( geometryAttribute );
22180
22181 if ( geometryAttribute instanceof THREE.InterleavedBufferAttribute ) {
22182
22183 var data = geometryAttribute.data;
22184 var stride = data.stride;
22185 var offset = geometryAttribute.offset;
22186
22187 if ( data instanceof THREE.InstancedInterleavedBuffer ) {
22188
22189 state.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );
22190
22191 if ( geometry.maxInstancedCount === undefined ) {
22192
22193 geometry.maxInstancedCount = data.meshPerAttribute * data.count;
22194
22195 }
22196
22197 } else {
22198
22199 state.enableAttribute( programAttribute );
22200
22201 }
22202
22203 _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
22204 _gl.vertexAttribPointer( programAttribute, size, _gl.FLOAT, false, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT );
22205
22206 } else {
22207
22208 if ( geometryAttribute instanceof THREE.InstancedBufferAttribute ) {
22209
22210 state.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );
22211
22212 if ( geometry.maxInstancedCount === undefined ) {
22213
22214 geometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
22215
22216 }
22217
22218 } else {
22219
22220 state.enableAttribute( programAttribute );
22221
22222 }
22223
22224 _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
22225 _gl.vertexAttribPointer( programAttribute, size, _gl.FLOAT, false, 0, startIndex * size * 4 );
22226
22227 }
22228
22229 } else if ( materialDefaultAttributeValues !== undefined ) {
22230
22231 var value = materialDefaultAttributeValues[ name ];
22232
22233 if ( value !== undefined ) {
22234
22235 switch ( value.length ) {
22236
22237 case 2:
22238 _gl.vertexAttrib2fv( programAttribute, value );
22239 break;
22240
22241 case 3:
22242 _gl.vertexAttrib3fv( programAttribute, value );
22243 break;
22244
22245 case 4:
22246 _gl.vertexAttrib4fv( programAttribute, value );
22247 break;
22248
22249 default:
22250 _gl.vertexAttrib1fv( programAttribute, value );
22251
22252 }
22253
22254 }
22255
22256 }
22257
22258 }
22259
22260 }
22261
22262 state.disableUnusedAttributes();
22263
22264 }
22265
22266
22267
22268 function numericalSort ( a, b ) {
22269
22270 return b[ 0 ] - a[ 0 ];
22271
22272 }
22273
22274 function painterSortStable ( a, b ) {
22275
22276 if ( a.object.renderOrder !== b.object.renderOrder ) {
22277
22278 return a.object.renderOrder - b.object.renderOrder;
22279
22280 } else if ( a.material.id !== b.material.id ) {
22281
22282 return a.material.id - b.material.id;
22283
22284 } else if ( a.z !== b.z ) {
22285
22286 return a.z - b.z;
22287
22288 } else {
22289
22290 return a.id - b.id;
22291
22292 }
22293
22294 }
22295
22296 function reversePainterSortStable ( a, b ) {
22297
22298 if ( a.object.renderOrder !== b.object.renderOrder ) {
22299
22300 return a.object.renderOrder - b.object.renderOrder;
22301
22302 } if ( a.z !== b.z ) {
22303
22304 return b.z - a.z;
22305
22306 } else {
22307
22308 return a.id - b.id;
22309
22310 }
22311
22312 }
22313
22314
22315
22316 this.render = function ( scene, camera, renderTarget, forceClear ) {
22317
22318 if ( camera instanceof THREE.Camera === false ) {
22319
22320 console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
22321 return;
22322
22323 }
22324
22325 var fog = scene.fog;
22326
22327
22328
22329 _currentGeometryProgram = '';
22330 _currentMaterialId = - 1;
22331 _currentCamera = null;
22332 _lightsNeedUpdate = true;
22333
22334
22335
22336 if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
22337
22338
22339
22340 if ( camera.parent === null ) camera.updateMatrixWorld();
22341
22342 camera.matrixWorldInverse.getInverse( camera.matrixWorld );
22343
22344 _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
22345 _frustum.setFromMatrix( _projScreenMatrix );
22346
22347 lights.length = 0;
22348
22349 opaqueObjectsLastIndex = - 1;
22350 transparentObjectsLastIndex = - 1;
22351
22352 sprites.length = 0;
22353 lensFlares.length = 0;
22354
22355 projectObject( scene, camera );
22356
22357 opaqueObjects.length = opaqueObjectsLastIndex + 1;
22358 transparentObjects.length = transparentObjectsLastIndex + 1;
22359
22360 if ( _this.sortObjects === true ) {
22361
22362 opaqueObjects.sort( painterSortStable );
22363 transparentObjects.sort( reversePainterSortStable );
22364
22365 }
22366
22367
22368
22369 shadowMap.render( scene );
22370
22371
22372
22373 _infoRender.calls = 0;
22374 _infoRender.vertices = 0;
22375 _infoRender.faces = 0;
22376 _infoRender.points = 0;
22377
22378 this.setRenderTarget( renderTarget );
22379
22380 if ( this.autoClear || forceClear ) {
22381
22382 this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
22383
22384 }
22385
22386
22387
22388 if ( scene.overrideMaterial ) {
22389
22390 var overrideMaterial = scene.overrideMaterial;
22391
22392 renderObjects( opaqueObjects, camera, lights, fog, overrideMaterial );
22393 renderObjects( transparentObjects, camera, lights, fog, overrideMaterial );
22394
22395 } else {
22396
22397
22398
22399 state.setBlending( THREE.NoBlending );
22400 renderObjects( opaqueObjects, camera, lights, fog );
22401
22402
22403
22404 renderObjects( transparentObjects, camera, lights, fog );
22405
22406 }
22407
22408
22409
22410 spritePlugin.render( scene, camera );
22411 lensFlarePlugin.render( scene, camera, _currentWidth, _currentHeight );
22412
22413
22414
22415 if ( renderTarget ) {
22416
22417 var texture = renderTarget.texture;
22418 var isTargetPowerOfTwo = isPowerOfTwo( renderTarget );
22419 if ( texture.generateMipmaps && isTargetPowerOfTwo && texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) {
22420
22421 updateRenderTargetMipmap( renderTarget );
22422
22423 }
22424
22425 }
22426
22427
22428
22429 state.setDepthTest( true );
22430 state.setDepthWrite( true );
22431 state.setColorWrite( true );
22432
22433
22434
22435 };
22436
22437 function pushRenderItem( object, geometry, material, z, group ) {
22438
22439 var array, index;
22440
22441
22442
22443 if ( material.transparent ) {
22444
22445 array = transparentObjects;
22446 index = ++ transparentObjectsLastIndex;
22447
22448 } else {
22449
22450 array = opaqueObjects;
22451 index = ++ opaqueObjectsLastIndex;
22452
22453 }
22454
22455
22456
22457 var renderItem = array[ index ];
22458
22459 if ( renderItem !== undefined ) {
22460
22461 renderItem.id = object.id;
22462 renderItem.object = object;
22463 renderItem.geometry = geometry;
22464 renderItem.material = material;
22465 renderItem.z = _vector3.z;
22466 renderItem.group = group;
22467
22468 } else {
22469
22470 renderItem = {
22471 id: object.id,
22472 object: object,
22473 geometry: geometry,
22474 material: material,
22475 z: _vector3.z,
22476 group: group
22477 };
22478
22479
22480 array.push( renderItem );
22481
22482 }
22483
22484 }
22485
22486 function projectObject( object, camera ) {
22487
22488 if ( object.visible === false ) return;
22489
22490 if ( ( object.channels.mask & camera.channels.mask ) !== 0 ) {
22491
22492 if ( object instanceof THREE.Light ) {
22493
22494 lights.push( object );
22495
22496 } else if ( object instanceof THREE.Sprite ) {
22497
22498 sprites.push( object );
22499
22500 } else if ( object instanceof THREE.LensFlare ) {
22501
22502 lensFlares.push( object );
22503
22504 } else if ( object instanceof THREE.ImmediateRenderObject ) {
22505
22506 if ( _this.sortObjects === true ) {
22507
22508 _vector3.setFromMatrixPosition( object.matrixWorld );
22509 _vector3.applyProjection( _projScreenMatrix );
22510
22511 }
22512
22513 pushRenderItem( object, null, object.material, _vector3.z, null );
22514
22515 } else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.Points ) {
22516
22517 if ( object instanceof THREE.SkinnedMesh ) {
22518
22519 object.skeleton.update();
22520
22521 }
22522
22523 if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {
22524
22525 var material = object.material;
22526
22527 if ( material.visible === true ) {
22528
22529 if ( _this.sortObjects === true ) {
22530
22531 _vector3.setFromMatrixPosition( object.matrixWorld );
22532 _vector3.applyProjection( _projScreenMatrix );
22533
22534 }
22535
22536 var geometry = objects.update( object );
22537
22538 if ( material instanceof THREE.MeshFaceMaterial ) {
22539
22540 var groups = geometry.groups;
22541 var materials = material.materials;
22542
22543 for ( var i = 0, l = groups.length; i < l; i ++ ) {
22544
22545 var group = groups[ i ];
22546 var groupMaterial = materials[ group.materialIndex ];
22547
22548 if ( groupMaterial.visible === true ) {
22549
22550 pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );
22551
22552 }
22553
22554 }
22555
22556 } else {
22557
22558 pushRenderItem( object, geometry, material, _vector3.z, null );
22559
22560 }
22561
22562 }
22563
22564 }
22565
22566 }
22567
22568 }
22569
22570 var children = object.children;
22571
22572 for ( var i = 0, l = children.length; i < l; i ++ ) {
22573
22574 projectObject( children[ i ], camera );
22575
22576 }
22577
22578 }
22579
22580 function renderObjects( renderList, camera, lights, fog, overrideMaterial ) {
22581
22582 for ( var i = 0, l = renderList.length; i < l; i ++ ) {
22583
22584 var renderItem = renderList[ i ];
22585
22586 var object = renderItem.object;
22587 var geometry = renderItem.geometry;
22588 var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
22589 var group = renderItem.group;
22590
22591 object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
22592 object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
22593
22594 if ( object instanceof THREE.ImmediateRenderObject ) {
22595
22596 setMaterial( material );
22597
22598 var program = setProgram( camera, lights, fog, material, object );
22599
22600 _currentGeometryProgram = '';
22601
22602 object.render( function ( object ) {
22603
22604 _this.renderBufferImmediate( object, program, material );
22605
22606 } );
22607
22608 } else {
22609
22610 _this.renderBufferDirect( camera, lights, fog, geometry, material, object, group );
22611
22612 }
22613
22614 }
22615
22616 }
22617
22618 function initMaterial( material, lights, fog, object ) {
22619
22620 var materialProperties = properties.get( material );
22621
22622 var parameters = programCache.getParameters( material, lights, fog, object );
22623 var code = programCache.getProgramCode( material, parameters );
22624
22625 var program = materialProperties.program;
22626 var programChange = true;
22627
22628 if ( program === undefined ) {
22629
22630
22631 material.addEventListener( 'dispose', onMaterialDispose );
22632
22633 } else if ( program.code !== code ) {
22634
22635
22636 releaseMaterialProgramReference( material );
22637
22638 } else if ( parameters.shaderID !== undefined ) {
22639
22640
22641 return;
22642
22643 } else {
22644
22645
22646 programChange = false;
22647
22648 }
22649
22650 if ( programChange ) {
22651
22652 if ( parameters.shaderID ) {
22653
22654 var shader = THREE.ShaderLib[ parameters.shaderID ];
22655
22656 materialProperties.__webglShader = {
22657 name: material.type,
22658 uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
22659 vertexShader: shader.vertexShader,
22660 fragmentShader: shader.fragmentShader
22661 };
22662
22663 } else {
22664
22665 materialProperties.__webglShader = {
22666 name: material.type,
22667 uniforms: material.uniforms,
22668 vertexShader: material.vertexShader,
22669 fragmentShader: material.fragmentShader
22670 };
22671
22672 }
22673
22674 material.__webglShader = materialProperties.__webglShader;
22675
22676 program = programCache.acquireProgram( material, parameters, code );
22677
22678 materialProperties.program = program;
22679 material.program = program;
22680
22681 }
22682
22683 var attributes = program.getAttributes();
22684
22685 if ( material.morphTargets ) {
22686
22687 material.numSupportedMorphTargets = 0;
22688
22689 for ( var i = 0; i < _this.maxMorphTargets; i ++ ) {
22690
22691 if ( attributes[ 'morphTarget' + i ] >= 0 ) {
22692
22693 material.numSupportedMorphTargets ++;
22694
22695 }
22696
22697 }
22698
22699 }
22700
22701 if ( material.morphNormals ) {
22702
22703 material.numSupportedMorphNormals = 0;
22704
22705 for ( i = 0; i < _this.maxMorphNormals; i ++ ) {
22706
22707 if ( attributes[ 'morphNormal' + i ] >= 0 ) {
22708
22709 material.numSupportedMorphNormals ++;
22710
22711 }
22712
22713 }
22714
22715 }
22716
22717 materialProperties.uniformsList = [];
22718
22719 var uniformLocations = materialProperties.program.getUniforms();
22720
22721 for ( var u in materialProperties.__webglShader.uniforms ) {
22722
22723 var location = uniformLocations[ u ];
22724
22725 if ( location ) {
22726
22727 materialProperties.uniformsList.push( [ materialProperties.__webglShader.uniforms[ u ], location ] );
22728
22729 }
22730
22731 }
22732
22733 }
22734
22735 function setMaterial( material ) {
22736
22737 setMaterialFaces( material );
22738
22739 if ( material.transparent === true ) {
22740
22741 state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha );
22742
22743 } else {
22744
22745 state.setBlending( THREE.NoBlending );
22746
22747 }
22748
22749 state.setDepthFunc( material.depthFunc );
22750 state.setDepthTest( material.depthTest );
22751 state.setDepthWrite( material.depthWrite );
22752 state.setColorWrite( material.colorWrite );
22753 state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
22754
22755 }
22756
22757 function setMaterialFaces( material ) {
22758
22759 material.side !== THREE.DoubleSide ? state.enable( _gl.CULL_FACE ) : state.disable( _gl.CULL_FACE );
22760 state.setFlipSided( material.side === THREE.BackSide );
22761
22762 }
22763
22764 function setProgram( camera, lights, fog, material, object ) {
22765
22766 _usedTextureUnits = 0;
22767
22768 var materialProperties = properties.get( material );
22769
22770 if ( material.needsUpdate || ! materialProperties.program ) {
22771
22772 initMaterial( material, lights, fog, object );
22773 material.needsUpdate = false;
22774
22775 }
22776
22777 var refreshProgram = false;
22778 var refreshMaterial = false;
22779 var refreshLights = false;
22780
22781 var program = materialProperties.program,
22782 p_uniforms = program.getUniforms(),
22783 m_uniforms = materialProperties.__webglShader.uniforms;
22784
22785 if ( program.id !== _currentProgram ) {
22786
22787 _gl.useProgram( program.program );
22788 _currentProgram = program.id;
22789
22790 refreshProgram = true;
22791 refreshMaterial = true;
22792 refreshLights = true;
22793
22794 }
22795
22796 if ( material.id !== _currentMaterialId ) {
22797
22798 if ( _currentMaterialId === - 1 ) refreshLights = true;
22799 _currentMaterialId = material.id;
22800
22801 refreshMaterial = true;
22802
22803 }
22804
22805 if ( refreshProgram || camera !== _currentCamera ) {
22806
22807 _gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera.projectionMatrix.elements );
22808
22809 if ( capabilities.logarithmicDepthBuffer ) {
22810
22811 _gl.uniform1f( p_uniforms.logDepthBufFC, 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
22812
22813 }
22814
22815
22816 if ( camera !== _currentCamera ) _currentCamera = camera;
22817
22818
22819
22820
22821 if ( material instanceof THREE.ShaderMaterial ||
22822 material instanceof THREE.MeshPhongMaterial ||
22823 material.envMap ) {
22824
22825 if ( p_uniforms.cameraPosition !== undefined ) {
22826
22827 _vector3.setFromMatrixPosition( camera.matrixWorld );
22828 _gl.uniform3f( p_uniforms.cameraPosition, _vector3.x, _vector3.y, _vector3.z );
22829
22830 }
22831
22832 }
22833
22834 if ( material instanceof THREE.MeshPhongMaterial ||
22835 material instanceof THREE.MeshLambertMaterial ||
22836 material instanceof THREE.MeshBasicMaterial ||
22837 material instanceof THREE.ShaderMaterial ||
22838 material.skinning ) {
22839
22840 if ( p_uniforms.viewMatrix !== undefined ) {
22841
22842 _gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera.matrixWorldInverse.elements );
22843
22844 }
22845
22846 }
22847
22848 }
22849
22850
22851
22852
22853
22854 if ( material.skinning ) {
22855
22856 if ( object.bindMatrix && p_uniforms.bindMatrix !== undefined ) {
22857
22858 _gl.uniformMatrix4fv( p_uniforms.bindMatrix, false, object.bindMatrix.elements );
22859
22860 }
22861
22862 if ( object.bindMatrixInverse && p_uniforms.bindMatrixInverse !== undefined ) {
22863
22864 _gl.uniformMatrix4fv( p_uniforms.bindMatrixInverse, false, object.bindMatrixInverse.elements );
22865
22866 }
22867
22868 if ( capabilities.floatVertexTextures && object.skeleton && object.skeleton.useVertexTexture ) {
22869
22870 if ( p_uniforms.boneTexture !== undefined ) {
22871
22872 var textureUnit = getTextureUnit();
22873
22874 _gl.uniform1i( p_uniforms.boneTexture, textureUnit );
22875 _this.setTexture( object.skeleton.boneTexture, textureUnit );
22876
22877 }
22878
22879 if ( p_uniforms.boneTextureWidth !== undefined ) {
22880
22881 _gl.uniform1i( p_uniforms.boneTextureWidth, object.skeleton.boneTextureWidth );
22882
22883 }
22884
22885 if ( p_uniforms.boneTextureHeight !== undefined ) {
22886
22887 _gl.uniform1i( p_uniforms.boneTextureHeight, object.skeleton.boneTextureHeight );
22888
22889 }
22890
22891 } else if ( object.skeleton && object.skeleton.boneMatrices ) {
22892
22893 if ( p_uniforms.boneGlobalMatrices !== undefined ) {
22894
22895 _gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.skeleton.boneMatrices );
22896
22897 }
22898
22899 }
22900
22901 }
22902
22903 if ( refreshMaterial ) {
22904
22905
22906
22907 if ( fog && material.fog ) {
22908
22909 refreshUniformsFog( m_uniforms, fog );
22910
22911 }
22912
22913 if ( material instanceof THREE.MeshPhongMaterial ||
22914 material instanceof THREE.MeshLambertMaterial ||
22915 material.lights ) {
22916
22917 if ( _lightsNeedUpdate ) {
22918
22919 refreshLights = true;
22920 setupLights( lights, camera );
22921 _lightsNeedUpdate = false;
22922
22923 }
22924
22925 if ( refreshLights ) {
22926
22927 refreshUniformsLights( m_uniforms, _lights );
22928 markUniformsLightsNeedsUpdate( m_uniforms, true );
22929
22930 } else {
22931
22932 markUniformsLightsNeedsUpdate( m_uniforms, false );
22933
22934 }
22935
22936 }
22937
22938 if ( material instanceof THREE.MeshBasicMaterial ||
22939 material instanceof THREE.MeshLambertMaterial ||
22940 material instanceof THREE.MeshPhongMaterial ) {
22941
22942 refreshUniformsCommon( m_uniforms, material );
22943
22944 }
22945
22946
22947
22948 if ( material instanceof THREE.LineBasicMaterial ) {
22949
22950 refreshUniformsLine( m_uniforms, material );
22951
22952 } else if ( material instanceof THREE.LineDashedMaterial ) {
22953
22954 refreshUniformsLine( m_uniforms, material );
22955 refreshUniformsDash( m_uniforms, material );
22956
22957 } else if ( material instanceof THREE.PointsMaterial ) {
22958
22959 refreshUniformsParticle( m_uniforms, material );
22960
22961 } else if ( material instanceof THREE.MeshPhongMaterial ) {
22962
22963 refreshUniformsPhong( m_uniforms, material );
22964
22965 } else if ( material instanceof THREE.MeshDepthMaterial ) {
22966
22967 m_uniforms.mNear.value = camera.near;
22968 m_uniforms.mFar.value = camera.far;
22969 m_uniforms.opacity.value = material.opacity;
22970
22971 } else if ( material instanceof THREE.MeshNormalMaterial ) {
22972
22973 m_uniforms.opacity.value = material.opacity;
22974
22975 }
22976
22977 if ( object.receiveShadow && ! material._shadowPass ) {
22978
22979 refreshUniformsShadow( m_uniforms, lights, camera );
22980
22981 }
22982
22983
22984
22985 loadUniformsGeneric( materialProperties.uniformsList );
22986
22987 }
22988
22989 loadUniformsMatrices( p_uniforms, object );
22990
22991 if ( p_uniforms.modelMatrix !== undefined ) {
22992
22993 _gl.uniformMatrix4fv( p_uniforms.modelMatrix, false, object.matrixWorld.elements );
22994
22995 }
22996
22997 return program;
22998
22999 }
23000
23001
23002
23003 function refreshUniformsCommon ( uniforms, material ) {
23004
23005 uniforms.opacity.value = material.opacity;
23006
23007 uniforms.diffuse.value = material.color;
23008
23009 if ( material.emissive ) {
23010
23011 uniforms.emissive.value = material.emissive;
23012
23013 }
23014
23015 uniforms.map.value = material.map;
23016 uniforms.specularMap.value = material.specularMap;
23017 uniforms.alphaMap.value = material.alphaMap;
23018
23019 if ( material.aoMap ) {
23020
23021 uniforms.aoMap.value = material.aoMap;
23022 uniforms.aoMapIntensity.value = material.aoMapIntensity;
23023
23024 }
23025
23026
23027
23028
23029
23030
23031
23032
23033
23034 var uvScaleMap;
23035
23036 if ( material.map ) {
23037
23038 uvScaleMap = material.map;
23039
23040 } else if ( material.specularMap ) {
23041
23042 uvScaleMap = material.specularMap;
23043
23044 } else if ( material.displacementMap ) {
23045
23046 uvScaleMap = material.displacementMap;
23047
23048 } else if ( material.normalMap ) {
23049
23050 uvScaleMap = material.normalMap;
23051
23052 } else if ( material.bumpMap ) {
23053
23054 uvScaleMap = material.bumpMap;
23055
23056 } else if ( material.alphaMap ) {
23057
23058 uvScaleMap = material.alphaMap;
23059
23060 } else if ( material.emissiveMap ) {
23061
23062 uvScaleMap = material.emissiveMap;
23063
23064 }
23065
23066 if ( uvScaleMap !== undefined ) {
23067
23068 if ( uvScaleMap instanceof THREE.WebGLRenderTarget ) uvScaleMap = uvScaleMap.texture;
23069 var offset = uvScaleMap.offset;
23070 var repeat = uvScaleMap.repeat;
23071
23072 uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
23073
23074 }
23075
23076 uniforms.envMap.value = material.envMap;
23077 uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : - 1;
23078
23079 uniforms.reflectivity.value = material.reflectivity;
23080 uniforms.refractionRatio.value = material.refractionRatio;
23081
23082 }
23083
23084 function refreshUniformsLine ( uniforms, material ) {
23085
23086 uniforms.diffuse.value = material.color;
23087 uniforms.opacity.value = material.opacity;
23088
23089 }
23090
23091 function refreshUniformsDash ( uniforms, material ) {
23092
23093 uniforms.dashSize.value = material.dashSize;
23094 uniforms.totalSize.value = material.dashSize + material.gapSize;
23095 uniforms.scale.value = material.scale;
23096
23097 }
23098
23099 function refreshUniformsParticle ( uniforms, material ) {
23100
23101 uniforms.psColor.value = material.color;
23102 uniforms.opacity.value = material.opacity;
23103 uniforms.size.value = material.size;
23104 uniforms.scale.value = _canvas.height / 2.0;
23105
23106 uniforms.map.value = material.map;
23107
23108 if ( material.map !== null ) {
23109
23110 var offset = material.map.offset;
23111 var repeat = material.map.repeat;
23112
23113 uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
23114
23115 }
23116
23117 }
23118
23119 function refreshUniformsFog ( uniforms, fog ) {
23120
23121 uniforms.fogColor.value = fog.color;
23122
23123 if ( fog instanceof THREE.Fog ) {
23124
23125 uniforms.fogNear.value = fog.near;
23126 uniforms.fogFar.value = fog.far;
23127
23128 } else if ( fog instanceof THREE.FogExp2 ) {
23129
23130 uniforms.fogDensity.value = fog.density;
23131
23132 }
23133
23134 }
23135
23136 function refreshUniformsPhong ( uniforms, material ) {
23137
23138 uniforms.specular.value = material.specular;
23139 uniforms.shininess.value = Math.max( material.shininess, 1e-4 );
23140
23141 if ( material.lightMap ) {
23142
23143 uniforms.lightMap.value = material.lightMap;
23144 uniforms.lightMapIntensity.value = material.lightMapIntensity;
23145
23146 }
23147
23148 if ( material.emissiveMap ) {
23149
23150 uniforms.emissiveMap.value = material.emissiveMap;
23151
23152 }
23153
23154 if ( material.bumpMap ) {
23155
23156 uniforms.bumpMap.value = material.bumpMap;
23157 uniforms.bumpScale.value = material.bumpScale;
23158
23159 }
23160
23161 if ( material.normalMap ) {
23162
23163 uniforms.normalMap.value = material.normalMap;
23164 uniforms.normalScale.value.copy( material.normalScale );
23165
23166 }
23167
23168 if ( material.displacementMap ) {
23169
23170 uniforms.displacementMap.value = material.displacementMap;
23171 uniforms.displacementScale.value = material.displacementScale;
23172 uniforms.displacementBias.value = material.displacementBias;
23173
23174 }
23175
23176 }
23177
23178 function refreshUniformsLights ( uniforms, lights ) {
23179
23180 uniforms.ambientLightColor.value = lights.ambient;
23181
23182 uniforms.directionalLightColor.value = lights.directional.colors;
23183 uniforms.directionalLightDirection.value = lights.directional.positions;
23184
23185 uniforms.pointLightColor.value = lights.point.colors;
23186 uniforms.pointLightPosition.value = lights.point.positions;
23187 uniforms.pointLightDistance.value = lights.point.distances;
23188 uniforms.pointLightDecay.value = lights.point.decays;
23189
23190 uniforms.spotLightColor.value = lights.spot.colors;
23191 uniforms.spotLightPosition.value = lights.spot.positions;
23192 uniforms.spotLightDistance.value = lights.spot.distances;
23193 uniforms.spotLightDirection.value = lights.spot.directions;
23194 uniforms.spotLightAngleCos.value = lights.spot.anglesCos;
23195 uniforms.spotLightExponent.value = lights.spot.exponents;
23196 uniforms.spotLightDecay.value = lights.spot.decays;
23197
23198 uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors;
23199 uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors;
23200 uniforms.hemisphereLightDirection.value = lights.hemi.positions;
23201
23202 }
23203
23204
23205
23206 function markUniformsLightsNeedsUpdate ( uniforms, value ) {
23207
23208 uniforms.ambientLightColor.needsUpdate = value;
23209
23210 uniforms.directionalLightColor.needsUpdate = value;
23211 uniforms.directionalLightDirection.needsUpdate = value;
23212
23213 uniforms.pointLightColor.needsUpdate = value;
23214 uniforms.pointLightPosition.needsUpdate = value;
23215 uniforms.pointLightDistance.needsUpdate = value;
23216 uniforms.pointLightDecay.needsUpdate = value;
23217
23218 uniforms.spotLightColor.needsUpdate = value;
23219 uniforms.spotLightPosition.needsUpdate = value;
23220 uniforms.spotLightDistance.needsUpdate = value;
23221 uniforms.spotLightDirection.needsUpdate = value;
23222 uniforms.spotLightAngleCos.needsUpdate = value;
23223 uniforms.spotLightExponent.needsUpdate = value;
23224 uniforms.spotLightDecay.needsUpdate = value;
23225
23226 uniforms.hemisphereLightSkyColor.needsUpdate = value;
23227 uniforms.hemisphereLightGroundColor.needsUpdate = value;
23228 uniforms.hemisphereLightDirection.needsUpdate = value;
23229
23230 }
23231
23232 function refreshUniformsShadow ( uniforms, lights, camera ) {
23233
23234 if ( uniforms.shadowMatrix ) {
23235
23236 var j = 0;
23237
23238 for ( var i = 0, il = lights.length; i < il; i ++ ) {
23239
23240 var light = lights[ i ];
23241
23242 if ( light.castShadow === true ) {
23243
23244 if ( light instanceof THREE.PointLight || light instanceof THREE.SpotLight || light instanceof THREE.DirectionalLight ) {
23245
23246 var shadow = light.shadow;
23247
23248 if ( light instanceof THREE.PointLight ) {
23249
23250
23251
23252 _vector3.setFromMatrixPosition( light.matrixWorld ).negate();
23253 shadow.matrix.identity().setPosition( _vector3 );
23254
23255
23256 uniforms.shadowDarkness.value[ j ] = - shadow.darkness;
23257
23258 } else {
23259
23260 uniforms.shadowDarkness.value[ j ] = shadow.darkness;
23261
23262 }
23263
23264 uniforms.shadowMatrix.value[ j ] = shadow.matrix;
23265 uniforms.shadowMap.value[ j ] = shadow.map;
23266 uniforms.shadowMapSize.value[ j ] = shadow.mapSize;
23267 uniforms.shadowBias.value[ j ] = shadow.bias;
23268
23269 j ++;
23270
23271 }
23272
23273 }
23274
23275 }
23276
23277 }
23278
23279 }
23280
23281
23282
23283 function loadUniformsMatrices ( uniforms, object ) {
23284
23285 _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object.modelViewMatrix.elements );
23286
23287 if ( uniforms.normalMatrix ) {
23288
23289 _gl.uniformMatrix3fv( uniforms.normalMatrix, false, object.normalMatrix.elements );
23290
23291 }
23292
23293 }
23294
23295 function getTextureUnit() {
23296
23297 var textureUnit = _usedTextureUnits;
23298
23299 if ( textureUnit >= capabilities.maxTextures ) {
23300
23301 console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
23302
23303 }
23304
23305 _usedTextureUnits += 1;
23306
23307 return textureUnit;
23308
23309 }
23310
23311 function loadUniformsGeneric ( uniforms ) {
23312
23313 var texture, textureUnit;
23314
23315 for ( var j = 0, jl = uniforms.length; j < jl; j ++ ) {
23316
23317 var uniform = uniforms[ j ][ 0 ];
23318
23319
23320 if ( uniform.needsUpdate === false ) continue;
23321
23322 var type = uniform.type;
23323 var value = uniform.value;
23324 var location = uniforms[ j ][ 1 ];
23325
23326 switch ( type ) {
23327
23328 case '1i':
23329 _gl.uniform1i( location, value );
23330 break;
23331
23332 case '1f':
23333 _gl.uniform1f( location, value );
23334 break;
23335
23336 case '2f':
23337 _gl.uniform2f( location, value[ 0 ], value[ 1 ] );
23338 break;
23339
23340 case '3f':
23341 _gl.uniform3f( location, value[ 0 ], value[ 1 ], value[ 2 ] );
23342 break;
23343
23344 case '4f':
23345 _gl.uniform4f( location, value[ 0 ], value[ 1 ], value[ 2 ], value[ 3 ] );
23346 break;
23347
23348 case '1iv':
23349 _gl.uniform1iv( location, value );
23350 break;
23351
23352 case '3iv':
23353 _gl.uniform3iv( location, value );
23354 break;
23355
23356 case '1fv':
23357 _gl.uniform1fv( location, value );
23358 break;
23359
23360 case '2fv':
23361 _gl.uniform2fv( location, value );
23362 break;
23363
23364 case '3fv':
23365 _gl.uniform3fv( location, value );
23366 break;
23367
23368 case '4fv':
23369 _gl.uniform4fv( location, value );
23370 break;
23371
23372 case 'Matrix3fv':
23373 _gl.uniformMatrix3fv( location, false, value );
23374 break;
23375
23376 case 'Matrix4fv':
23377 _gl.uniformMatrix4fv( location, false, value );
23378 break;
23379
23380
23381
23382 case 'i':
23383
23384
23385 _gl.uniform1i( location, value );
23386
23387 break;
23388
23389 case 'f':
23390
23391
23392 _gl.uniform1f( location, value );
23393
23394 break;
23395
23396 case 'v2':
23397
23398
23399 _gl.uniform2f( location, value.x, value.y );
23400
23401 break;
23402
23403 case 'v3':
23404
23405
23406 _gl.uniform3f( location, value.x, value.y, value.z );
23407
23408 break;
23409
23410 case 'v4':
23411
23412
23413 _gl.uniform4f( location, value.x, value.y, value.z, value.w );
23414
23415 break;
23416
23417 case 'c':
23418
23419
23420 _gl.uniform3f( location, value.r, value.g, value.b );
23421
23422 break;
23423
23424 case 'iv1':
23425
23426
23427 _gl.uniform1iv( location, value );
23428
23429 break;
23430
23431 case 'iv':
23432
23433
23434 _gl.uniform3iv( location, value );
23435
23436 break;
23437
23438 case 'fv1':
23439
23440
23441 _gl.uniform1fv( location, value );
23442
23443 break;
23444
23445 case 'fv':
23446
23447
23448 _gl.uniform3fv( location, value );
23449
23450 break;
23451
23452 case 'v2v':
23453
23454
23455
23456 if ( uniform._array === undefined ) {
23457
23458 uniform._array = new Float32Array( 2 * value.length );
23459
23460 }
23461
23462 for ( var i = 0, i2 = 0, il = value.length; i < il; i ++, i2 += 2 ) {
23463
23464 uniform._array[ i2 + 0 ] = value[ i ].x;
23465 uniform._array[ i2 + 1 ] = value[ i ].y;
23466
23467 }
23468
23469 _gl.uniform2fv( location, uniform._array );
23470
23471 break;
23472
23473 case 'v3v':
23474
23475
23476
23477 if ( uniform._array === undefined ) {
23478
23479 uniform._array = new Float32Array( 3 * value.length );
23480
23481 }
23482
23483 for ( var i = 0, i3 = 0, il = value.length; i < il; i ++, i3 += 3 ) {
23484
23485 uniform._array[ i3 + 0 ] = value[ i ].x;
23486 uniform._array[ i3 + 1 ] = value[ i ].y;
23487 uniform._array[ i3 + 2 ] = value[ i ].z;
23488
23489 }
23490
23491 _gl.uniform3fv( location, uniform._array );
23492
23493 break;
23494
23495 case 'v4v':
23496
23497
23498
23499 if ( uniform._array === undefined ) {
23500
23501 uniform._array = new Float32Array( 4 * value.length );
23502
23503 }
23504
23505 for ( var i = 0, i4 = 0, il = value.length; i < il; i ++, i4 += 4 ) {
23506
23507 uniform._array[ i4 + 0 ] = value[ i ].x;
23508 uniform._array[ i4 + 1 ] = value[ i ].y;
23509 uniform._array[ i4 + 2 ] = value[ i ].z;
23510 uniform._array[ i4 + 3 ] = value[ i ].w;
23511
23512 }
23513
23514 _gl.uniform4fv( location, uniform._array );
23515
23516 break;
23517
23518 case 'm3':
23519
23520
23521 _gl.uniformMatrix3fv( location, false, value.elements );
23522
23523 break;
23524
23525 case 'm3v':
23526
23527
23528
23529 if ( uniform._array === undefined ) {
23530
23531 uniform._array = new Float32Array( 9 * value.length );
23532
23533 }
23534
23535 for ( var i = 0, il = value.length; i < il; i ++ ) {
23536
23537 value[ i ].flattenToArrayOffset( uniform._array, i * 9 );
23538
23539 }
23540
23541 _gl.uniformMatrix3fv( location, false, uniform._array );
23542
23543 break;
23544
23545 case 'm4':
23546
23547
23548 _gl.uniformMatrix4fv( location, false, value.elements );
23549
23550 break;
23551
23552 case 'm4v':
23553
23554
23555
23556 if ( uniform._array === undefined ) {
23557
23558 uniform._array = new Float32Array( 16 * value.length );
23559
23560 }
23561
23562 for ( var i = 0, il = value.length; i < il; i ++ ) {
23563
23564 value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
23565
23566 }
23567
23568 _gl.uniformMatrix4fv( location, false, uniform._array );
23569
23570 break;
23571
23572 case 't':
23573
23574
23575
23576 texture = value;
23577 textureUnit = getTextureUnit();
23578
23579 _gl.uniform1i( location, textureUnit );
23580
23581 if ( ! texture ) continue;
23582
23583 if ( texture instanceof THREE.CubeTexture ||
23584 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
23585
23586
23587
23588 setCubeTexture( texture, textureUnit );
23589
23590 } else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
23591
23592 setCubeTextureDynamic( texture.texture, textureUnit );
23593
23594 } else if ( texture instanceof THREE.WebGLRenderTarget ) {
23595
23596 _this.setTexture( texture.texture, textureUnit );
23597
23598 } else {
23599
23600 _this.setTexture( texture, textureUnit );
23601
23602 }
23603
23604 break;
23605
23606 case 'tv':
23607
23608
23609
23610 if ( uniform._array === undefined ) {
23611
23612 uniform._array = [];
23613
23614 }
23615
23616 for ( var i = 0, il = uniform.value.length; i < il; i ++ ) {
23617
23618 uniform._array[ i ] = getTextureUnit();
23619
23620 }
23621
23622 _gl.uniform1iv( location, uniform._array );
23623
23624 for ( var i = 0, il = uniform.value.length; i < il; i ++ ) {
23625
23626 texture = uniform.value[ i ];
23627 textureUnit = uniform._array[ i ];
23628
23629 if ( ! texture ) continue;
23630
23631 if ( texture instanceof THREE.CubeTexture ||
23632 ( texture.image instanceof Array && texture.image.length === 6 ) ) {
23633
23634
23635
23636 setCubeTexture( texture, textureUnit );
23637
23638 } else if ( texture instanceof THREE.WebGLRenderTarget ) {
23639
23640 _this.setTexture( texture.texture, textureUnit );
23641
23642 } else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
23643
23644 setCubeTextureDynamic( texture.texture, textureUnit );
23645
23646 } else {
23647
23648 _this.setTexture( texture, textureUnit );
23649
23650 }
23651
23652 }
23653
23654 break;
23655
23656 default:
23657
23658 console.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type );
23659
23660 }
23661
23662 }
23663
23664 }
23665
23666 function setColorLinear( array, offset, color, intensity ) {
23667
23668 array[ offset + 0 ] = color.r * intensity;
23669 array[ offset + 1 ] = color.g * intensity;
23670 array[ offset + 2 ] = color.b * intensity;
23671
23672 }
23673
23674 function setupLights ( lights, camera ) {
23675
23676 var l, ll, light,
23677 r = 0, g = 0, b = 0,
23678 color, skyColor, groundColor,
23679 intensity,
23680 distance,
23681
23682 zlights = _lights,
23683
23684 viewMatrix = camera.matrixWorldInverse,
23685
23686 dirColors = zlights.directional.colors,
23687 dirPositions = zlights.directional.positions,
23688
23689 pointColors = zlights.point.colors,
23690 pointPositions = zlights.point.positions,
23691 pointDistances = zlights.point.distances,
23692 pointDecays = zlights.point.decays,
23693
23694 spotColors = zlights.spot.colors,
23695 spotPositions = zlights.spot.positions,
23696 spotDistances = zlights.spot.distances,
23697 spotDirections = zlights.spot.directions,
23698 spotAnglesCos = zlights.spot.anglesCos,
23699 spotExponents = zlights.spot.exponents,
23700 spotDecays = zlights.spot.decays,
23701
23702 hemiSkyColors = zlights.hemi.skyColors,
23703 hemiGroundColors = zlights.hemi.groundColors,
23704 hemiPositions = zlights.hemi.positions,
23705
23706 dirLength = 0,
23707 pointLength = 0,
23708 spotLength = 0,
23709 hemiLength = 0,
23710
23711 dirCount = 0,
23712 pointCount = 0,
23713 spotCount = 0,
23714 hemiCount = 0,
23715
23716 dirOffset = 0,
23717 pointOffset = 0,
23718 spotOffset = 0,
23719 hemiOffset = 0;
23720
23721 for ( l = 0, ll = lights.length; l < ll; l ++ ) {
23722
23723 light = lights[ l ];
23724
23725 color = light.color;
23726 intensity = light.intensity;
23727 distance = light.distance;
23728
23729 if ( light instanceof THREE.AmbientLight ) {
23730
23731 if ( ! light.visible ) continue;
23732
23733 r += color.r;
23734 g += color.g;
23735 b += color.b;
23736
23737 } else if ( light instanceof THREE.DirectionalLight ) {
23738
23739 dirCount += 1;
23740
23741 if ( ! light.visible ) continue;
23742
23743 _direction.setFromMatrixPosition( light.matrixWorld );
23744 _vector3.setFromMatrixPosition( light.target.matrixWorld );
23745 _direction.sub( _vector3 );
23746 _direction.transformDirection( viewMatrix );
23747
23748 dirOffset = dirLength * 3;
23749
23750 dirPositions[ dirOffset + 0 ] = _direction.x;
23751 dirPositions[ dirOffset + 1 ] = _direction.y;
23752 dirPositions[ dirOffset + 2 ] = _direction.z;
23753
23754 setColorLinear( dirColors, dirOffset, color, intensity );
23755
23756 dirLength += 1;
23757
23758 } else if ( light instanceof THREE.PointLight ) {
23759
23760 pointCount += 1;
23761
23762 if ( ! light.visible ) continue;
23763
23764 pointOffset = pointLength * 3;
23765
23766 setColorLinear( pointColors, pointOffset, color, intensity );
23767
23768 _vector3.setFromMatrixPosition( light.matrixWorld );
23769 _vector3.applyMatrix4( viewMatrix );
23770
23771 pointPositions[ pointOffset + 0 ] = _vector3.x;
23772 pointPositions[ pointOffset + 1 ] = _vector3.y;
23773 pointPositions[ pointOffset + 2 ] = _vector3.z;
23774
23775
23776 pointDistances[ pointLength ] = distance;
23777 pointDecays[ pointLength ] = ( light.distance === 0 ) ? 0.0 : light.decay;
23778
23779 pointLength += 1;
23780
23781 } else if ( light instanceof THREE.SpotLight ) {
23782
23783 spotCount += 1;
23784
23785 if ( ! light.visible ) continue;
23786
23787 spotOffset = spotLength * 3;
23788
23789 setColorLinear( spotColors, spotOffset, color, intensity );
23790
23791 _direction.setFromMatrixPosition( light.matrixWorld );
23792 _vector3.copy( _direction ).applyMatrix4( viewMatrix );
23793
23794 spotPositions[ spotOffset + 0 ] = _vector3.x;
23795 spotPositions[ spotOffset + 1 ] = _vector3.y;
23796 spotPositions[ spotOffset + 2 ] = _vector3.z;
23797
23798 spotDistances[ spotLength ] = distance;
23799
23800 _vector3.setFromMatrixPosition( light.target.matrixWorld );
23801 _direction.sub( _vector3 );
23802 _direction.transformDirection( viewMatrix );
23803
23804 spotDirections[ spotOffset + 0 ] = _direction.x;
23805 spotDirections[ spotOffset + 1 ] = _direction.y;
23806 spotDirections[ spotOffset + 2 ] = _direction.z;
23807
23808 spotAnglesCos[ spotLength ] = Math.cos( light.angle );
23809 spotExponents[ spotLength ] = light.exponent;
23810 spotDecays[ spotLength ] = ( light.distance === 0 ) ? 0.0 : light.decay;
23811
23812 spotLength += 1;
23813
23814 } else if ( light instanceof THREE.HemisphereLight ) {
23815
23816 hemiCount += 1;
23817
23818 if ( ! light.visible ) continue;
23819
23820 _direction.setFromMatrixPosition( light.matrixWorld );
23821 _direction.transformDirection( viewMatrix );
23822
23823 hemiOffset = hemiLength * 3;
23824
23825 hemiPositions[ hemiOffset + 0 ] = _direction.x;
23826 hemiPositions[ hemiOffset + 1 ] = _direction.y;
23827 hemiPositions[ hemiOffset + 2 ] = _direction.z;
23828
23829 skyColor = light.color;
23830 groundColor = light.groundColor;
23831
23832 setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity );
23833 setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity );
23834
23835 hemiLength += 1;
23836
23837 }
23838
23839 }
23840
23841
23842
23843
23844 for ( l = dirLength * 3, ll = Math.max( dirColors.length, dirCount * 3 ); l < ll; l ++ ) dirColors[ l ] = 0.0;
23845 for ( l = pointLength * 3, ll = Math.max( pointColors.length, pointCount * 3 ); l < ll; l ++ ) pointColors[ l ] = 0.0;
23846 for ( l = spotLength * 3, ll = Math.max( spotColors.length, spotCount * 3 ); l < ll; l ++ ) spotColors[ l ] = 0.0;
23847 for ( l = hemiLength * 3, ll = Math.max( hemiSkyColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiSkyColors[ l ] = 0.0;
23848 for ( l = hemiLength * 3, ll = Math.max( hemiGroundColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiGroundColors[ l ] = 0.0;
23849
23850 zlights.directional.length = dirLength;
23851 zlights.point.length = pointLength;
23852 zlights.spot.length = spotLength;
23853 zlights.hemi.length = hemiLength;
23854
23855 zlights.ambient[ 0 ] = r;
23856 zlights.ambient[ 1 ] = g;
23857 zlights.ambient[ 2 ] = b;
23858
23859 }
23860
23861
23862
23863 this.setFaceCulling = function ( cullFace, frontFaceDirection ) {
23864
23865 if ( cullFace === THREE.CullFaceNone ) {
23866
23867 state.disable( _gl.CULL_FACE );
23868
23869 } else {
23870
23871 if ( frontFaceDirection === THREE.FrontFaceDirectionCW ) {
23872
23873 _gl.frontFace( _gl.CW );
23874
23875 } else {
23876
23877 _gl.frontFace( _gl.CCW );
23878
23879 }
23880
23881 if ( cullFace === THREE.CullFaceBack ) {
23882
23883 _gl.cullFace( _gl.BACK );
23884
23885 } else if ( cullFace === THREE.CullFaceFront ) {
23886
23887 _gl.cullFace( _gl.FRONT );
23888
23889 } else {
23890
23891 _gl.cullFace( _gl.FRONT_AND_BACK );
23892
23893 }
23894
23895 state.enable( _gl.CULL_FACE );
23896
23897 }
23898
23899 };
23900
23901
23902
23903 function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
23904
23905 var extension;
23906
23907 if ( isImagePowerOfTwo ) {
23908
23909 _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
23910 _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
23911
23912 _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
23913 _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
23914
23915 } else {
23916
23917 _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
23918 _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
23919
23920 if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) {
23921
23922 console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );
23923
23924 }
23925
23926 _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
23927 _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
23928
23929 if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) {
23930
23931 console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );
23932
23933 }
23934
23935 }
23936
23937 extension = extensions.get( 'EXT_texture_filter_anisotropic' );
23938
23939 if ( extension ) {
23940
23941 if ( texture.type === THREE.FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;
23942 if ( texture.type === THREE.HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;
23943
23944 if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {
23945
23946 _gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _this.getMaxAnisotropy() ) );
23947 properties.get( texture ).__currentAnisotropy = texture.anisotropy;
23948
23949 }
23950
23951 }
23952
23953 }
23954
23955 function uploadTexture( textureProperties, texture, slot ) {
23956
23957 if ( textureProperties.__webglInit === undefined ) {
23958
23959 textureProperties.__webglInit = true;
23960
23961 texture.addEventListener( 'dispose', onTextureDispose );
23962
23963 textureProperties.__webglTexture = _gl.createTexture();
23964
23965 _infoMemory.textures ++;
23966
23967 }
23968
23969 state.activeTexture( _gl.TEXTURE0 + slot );
23970 state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
23971
23972 _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
23973 _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
23974 _gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
23975
23976 texture.image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
23977
23978 if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false ) {
23979
23980 texture.image = makePowerOfTwo( texture.image );
23981
23982 }
23983
23984 var image = texture.image,
23985 isImagePowerOfTwo = isPowerOfTwo( image ),
23986 glFormat = paramThreeToGL( texture.format ),
23987 glType = paramThreeToGL( texture.type );
23988
23989 setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );
23990
23991 var mipmap, mipmaps = texture.mipmaps;
23992
23993 if ( texture instanceof THREE.DataTexture ) {
23994
23995
23996
23997
23998
23999 if ( mipmaps.length > 0 && isImagePowerOfTwo ) {
24000
24001 for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
24002
24003 mipmap = mipmaps[ i ];
24004 state.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
24005
24006 }
24007
24008 texture.generateMipmaps = false;
24009
24010 } else {
24011
24012 state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
24013
24014 }
24015
24016 } else if ( texture instanceof THREE.CompressedTexture ) {
24017
24018 for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
24019
24020 mipmap = mipmaps[ i ];
24021
24022 if ( texture.format !== THREE.RGBAFormat && texture.format !== THREE.RGBFormat ) {
24023
24024 if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {
24025
24026 state.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
24027
24028 } else {
24029
24030 console.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()" );
24031
24032 }
24033
24034 } else {
24035
24036 state.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
24037
24038 }
24039
24040 }
24041
24042 } else {
24043
24044
24045
24046
24047
24048
24049
24050 if ( mipmaps.length > 0 && isImagePowerOfTwo ) {
24051
24052 for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
24053
24054 mipmap = mipmaps[ i ];
24055 state.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );
24056
24057 }
24058
24059 texture.generateMipmaps = false;
24060
24061 } else {
24062
24063 state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
24064
24065 }
24066
24067 }
24068
24069 if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
24070
24071 textureProperties.__version = texture.version;
24072
24073 if ( texture.onUpdate ) texture.onUpdate( texture );
24074
24075 }
24076
24077 this.setTexture = function ( texture, slot ) {
24078
24079 var textureProperties = properties.get( texture );
24080
24081 if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
24082
24083 var image = texture.image;
24084
24085 if ( image === undefined ) {
24086
24087 console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );
24088 return;
24089
24090 }
24091
24092 if ( image.complete === false ) {
24093
24094 console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );
24095 return;
24096
24097 }
24098
24099 uploadTexture( textureProperties, texture, slot );
24100
24101 return;
24102
24103 }
24104
24105 state.activeTexture( _gl.TEXTURE0 + slot );
24106 state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
24107
24108 };
24109
24110 function clampToMaxSize ( image, maxSize ) {
24111
24112 if ( image.width > maxSize || image.height > maxSize ) {
24113
24114
24115
24116
24117 var scale = maxSize / Math.max( image.width, image.height );
24118
24119 var canvas = document.createElement( 'canvas' );
24120 canvas.width = Math.floor( image.width * scale );
24121 canvas.height = Math.floor( image.height * scale );
24122
24123 var context = canvas.getContext( '2d' );
24124 context.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );
24125
24126 console.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );
24127
24128 return canvas;
24129
24130 }
24131
24132 return image;
24133
24134 }
24135
24136 function isPowerOfTwo( image ) {
24137
24138 return THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height );
24139
24140 }
24141
24142 function textureNeedsPowerOfTwo( texture ) {
24143
24144 if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) return true;
24145 if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) return true;
24146
24147 return false;
24148
24149 }
24150
24151 function makePowerOfTwo( image ) {
24152
24153 if ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {
24154
24155 var canvas = document.createElement( 'canvas' );
24156 canvas.width = THREE.Math.nearestPowerOfTwo( image.width );
24157 canvas.height = THREE.Math.nearestPowerOfTwo( image.height );
24158
24159 var context = canvas.getContext( '2d' );
24160 context.drawImage( image, 0, 0, canvas.width, canvas.height );
24161
24162 console.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );
24163
24164 return canvas;
24165
24166 }
24167
24168 return image;
24169
24170 }
24171
24172 function setCubeTexture ( texture, slot ) {
24173
24174 var textureProperties = properties.get( texture );
24175
24176 if ( texture.image.length === 6 ) {
24177
24178 if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
24179
24180 if ( ! textureProperties.__image__webglTextureCube ) {
24181
24182 texture.addEventListener( 'dispose', onTextureDispose );
24183
24184 textureProperties.__image__webglTextureCube = _gl.createTexture();
24185
24186 _infoMemory.textures ++;
24187
24188 }
24189
24190 state.activeTexture( _gl.TEXTURE0 + slot );
24191 state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
24192
24193 _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
24194
24195 var isCompressed = texture instanceof THREE.CompressedTexture;
24196 var isDataTexture = texture.image[ 0 ] instanceof THREE.DataTexture;
24197
24198 var cubeImage = [];
24199
24200 for ( var i = 0; i < 6; i ++ ) {
24201
24202 if ( _this.autoScaleCubemaps && ! isCompressed && ! isDataTexture ) {
24203
24204 cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );
24205
24206 } else {
24207
24208 cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
24209
24210 }
24211
24212 }
24213
24214 var image = cubeImage[ 0 ],
24215 isImagePowerOfTwo = isPowerOfTwo( image ),
24216 glFormat = paramThreeToGL( texture.format ),
24217 glType = paramThreeToGL( texture.type );
24218
24219 setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );
24220
24221 for ( var i = 0; i < 6; i ++ ) {
24222
24223 if ( ! isCompressed ) {
24224
24225 if ( isDataTexture ) {
24226
24227 state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );
24228
24229 } else {
24230
24231 state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
24232
24233 }
24234
24235 } else {
24236
24237 var mipmap, mipmaps = cubeImage[ i ].mipmaps;
24238
24239 for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
24240
24241 mipmap = mipmaps[ j ];
24242
24243 if ( texture.format !== THREE.RGBAFormat && texture.format !== THREE.RGBFormat ) {
24244
24245 if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {
24246
24247 state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
24248
24249 } else {
24250
24251 console.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setCubeTexture()" );
24252
24253 }
24254
24255 } else {
24256
24257 state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
24258
24259 }
24260
24261 }
24262
24263 }
24264
24265 }
24266
24267 if ( texture.generateMipmaps && isImagePowerOfTwo ) {
24268
24269 _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
24270
24271 }
24272
24273 textureProperties.__version = texture.version;
24274
24275 if ( texture.onUpdate ) texture.onUpdate( texture );
24276
24277 } else {
24278
24279 state.activeTexture( _gl.TEXTURE0 + slot );
24280 state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
24281
24282 }
24283
24284 }
24285
24286 }
24287
24288 function setCubeTextureDynamic ( texture, slot ) {
24289
24290 state.activeTexture( _gl.TEXTURE0 + slot );
24291 state.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );
24292
24293 }
24294
24295
24296
24297 function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
24298
24299 _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
24300 _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
24301
24302 }
24303
24304 function setupRenderBuffer ( renderbuffer, renderTarget ) {
24305
24306 _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
24307
24308 if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
24309
24310 _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
24311 _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
24312
24313
24314
24315
24316
24317
24318
24319
24320 } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
24321
24322 _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
24323 _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
24324
24325 } else {
24326
24327 _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
24328
24329 }
24330
24331 }
24332
24333 this.setRenderTarget = function ( renderTarget ) {
24334
24335 var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
24336
24337 if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
24338
24339 var renderTargetProperties = properties.get( renderTarget );
24340 var textureProperties = properties.get( renderTarget.texture );
24341
24342 if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
24343 if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
24344
24345 renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
24346
24347 textureProperties.__webglTexture = _gl.createTexture();
24348
24349 _infoMemory.textures ++;
24350
24351
24352
24353 var isTargetPowerOfTwo = isPowerOfTwo( renderTarget ),
24354 glFormat = paramThreeToGL( renderTarget.texture.format ),
24355 glType = paramThreeToGL( renderTarget.texture.type );
24356
24357 if ( isCube ) {
24358
24359 renderTargetProperties.__webglFramebuffer = [];
24360 renderTargetProperties.__webglRenderbuffer = [];
24361
24362 state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
24363
24364 setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
24365
24366 for ( var i = 0; i < 6; i ++ ) {
24367
24368 renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
24369 renderTargetProperties.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
24370 state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
24371
24372 setupFrameBuffer( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
24373 setupRenderBuffer( renderTargetProperties.__webglRenderbuffer[ i ], renderTarget );
24374
24375 }
24376
24377 if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
24378
24379 } else {
24380
24381 renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
24382
24383 if ( renderTarget.shareDepthFrom ) {
24384
24385 renderTargetProperties.__webglRenderbuffer = renderTarget.shareDepthFrom.__webglRenderbuffer;
24386
24387 } else {
24388
24389 renderTargetProperties.__webglRenderbuffer = _gl.createRenderbuffer();
24390
24391 }
24392
24393 state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
24394 setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );
24395
24396 state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
24397
24398 setupFrameBuffer( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
24399
24400 if ( renderTarget.shareDepthFrom ) {
24401
24402 if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
24403
24404 _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTargetProperties.__webglRenderbuffer );
24405
24406 } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
24407
24408 _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTargetProperties.__webglRenderbuffer );
24409
24410 }
24411
24412 } else {
24413
24414 setupRenderBuffer( renderTargetProperties.__webglRenderbuffer, renderTarget );
24415
24416 }
24417
24418 if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
24419
24420 }
24421
24422
24423
24424 if ( isCube ) {
24425
24426 state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
24427
24428 } else {
24429
24430 state.bindTexture( _gl.TEXTURE_2D, null );
24431
24432 }
24433
24434 _gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
24435 _gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
24436
24437 }
24438
24439 var framebuffer, width, height, vx, vy;
24440
24441 if ( renderTarget ) {
24442
24443 var renderTargetProperties = properties.get( renderTarget );
24444
24445 if ( isCube ) {
24446
24447 framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
24448
24449 } else {
24450
24451 framebuffer = renderTargetProperties.__webglFramebuffer;
24452
24453 }
24454
24455 width = renderTarget.width;
24456 height = renderTarget.height;
24457
24458 vx = 0;
24459 vy = 0;
24460
24461 } else {
24462
24463 framebuffer = null;
24464
24465 width = _viewportWidth;
24466 height = _viewportHeight;
24467
24468 vx = _viewportX;
24469 vy = _viewportY;
24470
24471 }
24472
24473 if ( framebuffer !== _currentFramebuffer ) {
24474
24475 _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
24476 _gl.viewport( vx, vy, width, height );
24477
24478 _currentFramebuffer = framebuffer;
24479
24480 }
24481
24482 if ( isCube ) {
24483
24484 var textureProperties = properties.get( renderTarget.texture );
24485 _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, 0 );
24486
24487 }
24488
24489 _currentWidth = width;
24490 _currentHeight = height;
24491
24492 };
24493
24494 this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {
24495
24496 if ( renderTarget instanceof THREE.WebGLRenderTarget === false ) {
24497
24498 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
24499 return;
24500
24501 }
24502
24503 var framebuffer = properties.get( renderTarget ).__webglFramebuffer;
24504
24505 if ( framebuffer ) {
24506
24507 var restore = false;
24508
24509 if ( framebuffer !== _currentFramebuffer ) {
24510
24511 _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
24512
24513 restore = true;
24514
24515 }
24516
24517 try {
24518
24519 var texture = renderTarget.texture;
24520
24521 if ( texture.format !== THREE.RGBAFormat
24522 && paramThreeToGL( texture.format ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
24523
24524 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );
24525 return;
24526
24527 }
24528
24529 if ( texture.type !== THREE.UnsignedByteType
24530 && paramThreeToGL( texture.type ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE )
24531 && ! ( texture.type === THREE.FloatType && extensions.get( 'WEBGL_color_buffer_float' ) )
24532 && ! ( texture.type === THREE.HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {
24533
24534 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
24535 return;
24536
24537 }
24538
24539 if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {
24540
24541 _gl.readPixels( x, y, width, height, paramThreeToGL( texture.format ), paramThreeToGL( texture.type ), buffer );
24542
24543 } else {
24544
24545 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );
24546
24547 }
24548
24549 } finally {
24550
24551 if ( restore ) {
24552
24553 _gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );
24554
24555 }
24556
24557 }
24558
24559 }
24560
24561 };
24562
24563 function updateRenderTargetMipmap( renderTarget ) {
24564
24565 var target = renderTarget instanceof THREE.WebGLRenderTargetCube ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;
24566 var texture = properties.get( renderTarget.texture ).__webglTexture;
24567
24568 state.bindTexture( target, texture );
24569 _gl.generateMipmap( target );
24570 state.bindTexture( target, null );
24571
24572 }
24573
24574
24575
24576 function filterFallback ( f ) {
24577
24578 if ( f === THREE.NearestFilter || f === THREE.NearestMipMapNearestFilter || f === THREE.NearestMipMapLinearFilter ) {
24579
24580 return _gl.NEAREST;
24581
24582 }
24583
24584 return _gl.LINEAR;
24585
24586 }
24587
24588
24589
24590 function paramThreeToGL ( p ) {
24591
24592 var extension;
24593
24594 if ( p === THREE.RepeatWrapping ) return _gl.REPEAT;
24595 if ( p === THREE.ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
24596 if ( p === THREE.MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;
24597
24598 if ( p === THREE.NearestFilter ) return _gl.NEAREST;
24599 if ( p === THREE.NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;
24600 if ( p === THREE.NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;
24601
24602 if ( p === THREE.LinearFilter ) return _gl.LINEAR;
24603 if ( p === THREE.LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;
24604 if ( p === THREE.LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;
24605
24606 if ( p === THREE.UnsignedByteType ) return _gl.UNSIGNED_BYTE;
24607 if ( p === THREE.UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;
24608 if ( p === THREE.UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;
24609 if ( p === THREE.UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;
24610
24611 if ( p === THREE.ByteType ) return _gl.BYTE;
24612 if ( p === THREE.ShortType ) return _gl.SHORT;
24613 if ( p === THREE.UnsignedShortType ) return _gl.UNSIGNED_SHORT;
24614 if ( p === THREE.IntType ) return _gl.INT;
24615 if ( p === THREE.UnsignedIntType ) return _gl.UNSIGNED_INT;
24616 if ( p === THREE.FloatType ) return _gl.FLOAT;
24617
24618 extension = extensions.get( 'OES_texture_half_float' );
24619
24620 if ( extension !== null ) {
24621
24622 if ( p === THREE.HalfFloatType ) return extension.HALF_FLOAT_OES;
24623
24624 }
24625
24626 if ( p === THREE.AlphaFormat ) return _gl.ALPHA;
24627 if ( p === THREE.RGBFormat ) return _gl.RGB;
24628 if ( p === THREE.RGBAFormat ) return _gl.RGBA;
24629 if ( p === THREE.LuminanceFormat ) return _gl.LUMINANCE;
24630 if ( p === THREE.LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;
24631
24632 if ( p === THREE.AddEquation ) return _gl.FUNC_ADD;
24633 if ( p === THREE.SubtractEquation ) return _gl.FUNC_SUBTRACT;
24634 if ( p === THREE.ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;
24635
24636 if ( p === THREE.ZeroFactor ) return _gl.ZERO;
24637 if ( p === THREE.OneFactor ) return _gl.ONE;
24638 if ( p === THREE.SrcColorFactor ) return _gl.SRC_COLOR;
24639 if ( p === THREE.OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;
24640 if ( p === THREE.SrcAlphaFactor ) return _gl.SRC_ALPHA;
24641 if ( p === THREE.OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;
24642 if ( p === THREE.DstAlphaFactor ) return _gl.DST_ALPHA;
24643 if ( p === THREE.OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;
24644
24645 if ( p === THREE.DstColorFactor ) return _gl.DST_COLOR;
24646 if ( p === THREE.OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;
24647 if ( p === THREE.SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;
24648
24649 extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
24650
24651 if ( extension !== null ) {
24652
24653 if ( p === THREE.RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;
24654 if ( p === THREE.RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;
24655 if ( p === THREE.RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;
24656 if ( p === THREE.RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;
24657
24658 }
24659
24660 extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );
24661
24662 if ( extension !== null ) {
24663
24664 if ( p === THREE.RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
24665 if ( p === THREE.RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
24666 if ( p === THREE.RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
24667 if ( p === THREE.RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
24668
24669 }
24670
24671 extension = extensions.get( 'EXT_blend_minmax' );
24672
24673 if ( extension !== null ) {
24674
24675 if ( p === THREE.MinEquation ) return extension.MIN_EXT;
24676 if ( p === THREE.MaxEquation ) return extension.MAX_EXT;
24677
24678 }
24679
24680 return 0;
24681
24682 }
24683
24684
24685
24686 this.supportsFloatTextures = function () {
24687
24688 console.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).' );
24689 return extensions.get( 'OES_texture_float' );
24690
24691 };
24692
24693 this.supportsHalfFloatTextures = function () {
24694
24695 console.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).' );
24696 return extensions.get( 'OES_texture_half_float' );
24697
24698 };
24699
24700 this.supportsStandardDerivatives = function () {
24701
24702 console.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).' );
24703 return extensions.get( 'OES_standard_derivatives' );
24704
24705 };
24706
24707 this.supportsCompressedTextureS3TC = function () {
24708
24709 console.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).' );
24710 return extensions.get( 'WEBGL_compressed_texture_s3tc' );
24711
24712 };
24713
24714 this.supportsCompressedTexturePVRTC = function () {
24715
24716 console.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).' );
24717 return extensions.get( 'WEBGL_compressed_texture_pvrtc' );
24718
24719 };
24720
24721 this.supportsBlendMinMax = function () {
24722
24723 console.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).' );
24724 return extensions.get( 'EXT_blend_minmax' );
24725
24726 };
24727
24728 this.supportsVertexTextures = function () {
24729
24730 return capabilities.vertexTextures;
24731
24732 };
24733
24734 this.supportsInstancedArrays = function () {
24735
24736 console.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \'ANGLE_instanced_arrays\' ).' );
24737 return extensions.get( 'ANGLE_instanced_arrays' );
24738
24739 };
24740
24741
24742
24743 this.initMaterial = function () {
24744
24745 console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );
24746
24747 };
24748
24749 this.addPrePlugin = function () {
24750
24751 console.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );
24752
24753 };
24754
24755 this.addPostPlugin = function () {
24756
24757 console.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );
24758
24759 };
24760
24761 this.updateShadowMap = function () {
24762
24763 console.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );
24764
24765 };
24766
24767 Object.defineProperties( this, {
24768 shadowMapEnabled: {
24769 get: function () {
24770
24771 return shadowMap.enabled;
24772
24773 },
24774 set: function ( value ) {
24775
24776 console.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );
24777 shadowMap.enabled = value;
24778
24779 }
24780 },
24781 shadowMapType: {
24782 get: function () {
24783
24784 return shadowMap.type;
24785
24786 },
24787 set: function ( value ) {
24788
24789 console.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );
24790 shadowMap.type = value;
24791
24792 }
24793 },
24794 shadowMapCullFace: {
24795 get: function () {
24796
24797 return shadowMap.cullFace;
24798
24799 },
24800 set: function ( value ) {
24801
24802 console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );
24803 shadowMap.cullFace = value;
24804
24805 }
24806 },
24807 shadowMapDebug: {
24808 get: function () {
24809
24810 return shadowMap.debug;
24811
24812 },
24813 set: function ( value ) {
24814
24815 console.warn( 'THREE.WebGLRenderer: .shadowMapDebug is now .shadowMap.debug.' );
24816 shadowMap.debug = value;
24817
24818 }
24819 }
24820 } );
24821
24822 };
24823
24824
24825
24831 THREE.WebGLRenderTarget = function ( width, height, options ) {
24832
24833 this.uuid = THREE.Math.generateUUID();
24834
24835 this.width = width;
24836 this.height = height;
24837
24838 options = options || {};
24839
24840 if ( options.minFilter === undefined ) options.minFilter = THREE.LinearFilter;
24841
24842 this.texture = new THREE.Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy );
24843
24844 this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
24845 this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;
24846
24847 this.shareDepthFrom = options.shareDepthFrom !== undefined ? options.shareDepthFrom : null;
24848
24849 };
24850
24851 THREE.WebGLRenderTarget.prototype = {
24852
24853 constructor: THREE.WebGLRenderTarget,
24854
24855 get wrapS() {
24856
24857 console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );
24858
24859 return this.texture.wrapS;
24860
24861 },
24862
24863 set wrapS( value ) {
24864
24865 console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );
24866
24867 this.texture.wrapS = value;
24868
24869 },
24870
24871 get wrapT() {
24872
24873 console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );
24874
24875 return this.texture.wrapT;
24876
24877 },
24878
24879 set wrapT( value ) {
24880
24881 console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );
24882
24883 this.texture.wrapT = value;
24884
24885 },
24886
24887 get magFilter() {
24888
24889 console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );
24890
24891 return this.texture.magFilter;
24892
24893 },
24894
24895 set magFilter( value ) {
24896
24897 console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );
24898
24899 this.texture.magFilter = value;
24900
24901 },
24902
24903 get minFilter() {
24904
24905 console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );
24906
24907 return this.texture.minFilter;
24908
24909 },
24910
24911 set minFilter( value ) {
24912
24913 console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );
24914
24915 this.texture.minFilter = value;
24916
24917 },
24918
24919 get anisotropy() {
24920
24921 console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );
24922
24923 return this.texture.anisotropy;
24924
24925 },
24926
24927 set anisotropy( value ) {
24928
24929 console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );
24930
24931 this.texture.anisotropy = value;
24932
24933 },
24934
24935 get offset() {
24936
24937 console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );
24938
24939 return this.texture.offset;
24940
24941 },
24942
24943 set offset( value ) {
24944
24945 console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );
24946
24947 this.texture.offset = value;
24948
24949 },
24950
24951 get repeat() {
24952
24953 console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );
24954
24955 return this.texture.repeat;
24956
24957 },
24958
24959 set repeat( value ) {
24960
24961 console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );
24962
24963 this.texture.repeat = value;
24964
24965 },
24966
24967 get format() {
24968
24969 console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );
24970
24971 return this.texture.format;
24972
24973 },
24974
24975 set format( value ) {
24976
24977 console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );
24978
24979 this.texture.format = value;
24980
24981 },
24982
24983 get type() {
24984
24985 console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );
24986
24987 return this.texture.type;
24988
24989 },
24990
24991 set type( value ) {
24992
24993 console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );
24994
24995 this.texture.type = value;
24996
24997 },
24998
24999 get generateMipmaps() {
25000
25001 console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );
25002
25003 return this.texture.generateMipmaps;
25004
25005 },
25006
25007 set generateMipmaps( value ) {
25008
25009 console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );
25010
25011 this.texture.generateMipmaps = value;
25012
25013 },
25014
25015
25016
25017 setSize: function ( width, height ) {
25018
25019 if ( this.width !== width || this.height !== height ) {
25020
25021 this.width = width;
25022 this.height = height;
25023
25024 this.dispose();
25025
25026 }
25027
25028 },
25029
25030 clone: function () {
25031
25032 return new this.constructor().copy( this );
25033
25034 },
25035
25036 copy: function ( source ) {
25037
25038 this.width = source.width;
25039 this.height = source.height;
25040
25041 this.texture = source.texture.clone();
25042
25043 this.depthBuffer = source.depthBuffer;
25044 this.stencilBuffer = source.stencilBuffer;
25045
25046 this.shareDepthFrom = source.shareDepthFrom;
25047
25048 return this;
25049
25050 },
25051
25052 dispose: function () {
25053
25054 this.dispatchEvent( { type: 'dispose' } );
25055
25056 }
25057
25058 };
25059
25060 THREE.EventDispatcher.prototype.apply( THREE.WebGLRenderTarget.prototype );
25061
25062
25063
25068 THREE.WebGLRenderTargetCube = function ( width, height, options ) {
25069
25070 THREE.WebGLRenderTarget.call( this, width, height, options );
25071
25072 this.activeCubeFace = 0;
25073
25074 };
25075
25076 THREE.WebGLRenderTargetCube.prototype = Object.create( THREE.WebGLRenderTarget.prototype );
25077 THREE.WebGLRenderTargetCube.prototype.constructor = THREE.WebGLRenderTargetCube;
25078
25079
25080
25085 THREE.WebGLBufferRenderer = function ( _gl, extensions, _infoRender ) {
25086
25087 var mode;
25088
25089 function setMode( value ) {
25090
25091 mode = value;
25092
25093 }
25094
25095 function render( start, count ) {
25096
25097 _gl.drawArrays( mode, start, count );
25098
25099 _infoRender.calls ++;
25100 _infoRender.vertices += count;
25101 if ( mode === _gl.TRIANGLES ) _infoRender.faces += count / 3;
25102
25103 }
25104
25105 function renderInstances( geometry ) {
25106
25107 var extension = extensions.get( 'ANGLE_instanced_arrays' );
25108
25109 if ( extension === null ) {
25110
25111 console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
25112 return;
25113
25114 }
25115
25116 var position = geometry.attributes.position;
25117
25118 if ( position instanceof THREE.InterleavedBufferAttribute ) {
25119
25120 extension.drawArraysInstancedANGLE( mode, 0, position.data.count, geometry.maxInstancedCount );
25121
25122 } else {
25123
25124 extension.drawArraysInstancedANGLE( mode, 0, position.count, geometry.maxInstancedCount );
25125
25126 }
25127
25128 }
25129
25130 this.setMode = setMode;
25131 this.render = render;
25132 this.renderInstances = renderInstances;
25133
25134 };
25135
25136
25137
25142 THREE.WebGLIndexedBufferRenderer = function ( _gl, extensions, _infoRender ) {
25143
25144 var mode;
25145
25146 function setMode( value ) {
25147
25148 mode = value;
25149
25150 }
25151
25152 var type, size;
25153
25154 function setIndex( index ) {
25155
25156 if ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {
25157
25158 type = _gl.UNSIGNED_INT;
25159 size = 4;
25160
25161 } else {
25162
25163 type = _gl.UNSIGNED_SHORT;
25164 size = 2;
25165
25166 }
25167
25168 }
25169
25170 function render( start, count ) {
25171
25172 _gl.drawElements( mode, count, type, start * size );
25173
25174 _infoRender.calls ++;
25175 _infoRender.vertices += count;
25176 if ( mode === _gl.TRIANGLES ) _infoRender.faces += count / 3;
25177
25178 }
25179
25180 function renderInstances( geometry ) {
25181
25182 var extension = extensions.get( 'ANGLE_instanced_arrays' );
25183
25184 if ( extension === null ) {
25185
25186 console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
25187 return;
25188
25189 }
25190
25191 var index = geometry.index;
25192
25193 extension.drawElementsInstancedANGLE( mode, index.array.length, type, 0, geometry.maxInstancedCount );
25194
25195 }
25196
25197 this.setMode = setMode;
25198 this.setIndex = setIndex;
25199 this.render = render;
25200 this.renderInstances = renderInstances;
25201
25202 };
25203
25204
25205
25210 THREE.WebGLExtensions = function ( gl ) {
25211
25212 var extensions = {};
25213
25214 this.get = function ( name ) {
25215
25216 if ( extensions[ name ] !== undefined ) {
25217
25218 return extensions[ name ];
25219
25220 }
25221
25222 var extension;
25223
25224 switch ( name ) {
25225
25226 case 'EXT_texture_filter_anisotropic':
25227 extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );
25228 break;
25229
25230 case 'WEBGL_compressed_texture_s3tc':
25231 extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );
25232 break;
25233
25234 case 'WEBGL_compressed_texture_pvrtc':
25235 extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );
25236 break;
25237
25238 default:
25239 extension = gl.getExtension( name );
25240
25241 }
25242
25243 if ( extension === null ) {
25244
25245 console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );
25246
25247 }
25248
25249 extensions[ name ] = extension;
25250
25251 return extension;
25252
25253 };
25254
25255 };
25256
25257
25258
25259 THREE.WebGLCapabilities = function ( gl, extensions, parameters ) {
25260
25261 function getMaxPrecision( precision ) {
25262
25263 if ( precision === 'highp' ) {
25264
25265 if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&
25266 gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {
25267
25268 return 'highp';
25269
25270 }
25271
25272 precision = 'mediump';
25273
25274 }
25275
25276 if ( precision === 'mediump' ) {
25277
25278 if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&
25279 gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {
25280
25281 return 'mediump';
25282
25283 }
25284
25285 }
25286
25287 return 'lowp';
25288
25289 }
25290
25291 this.getMaxPrecision = getMaxPrecision;
25292
25293 this.precision = parameters.precision !== undefined ? parameters.precision : 'highp',
25294 this.logarithmicDepthBuffer = parameters.logarithmicDepthBuffer !== undefined ? parameters.logarithmicDepthBuffer : false;
25295
25296 this.maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );
25297 this.maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
25298 this.maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );
25299 this.maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );
25300
25301 this.maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );
25302 this.maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );
25303 this.maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );
25304 this.maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );
25305
25306 this.vertexTextures = this.maxVertexTextures > 0;
25307 this.floatFragmentTextures = !! extensions.get( 'OES_texture_float' );
25308 this.floatVertexTextures = this.vertexTextures && this.floatFragmentTextures;
25309
25310 var _maxPrecision = getMaxPrecision( this.precision );
25311
25312 if ( _maxPrecision !== this.precision ) {
25313
25314 console.warn( 'THREE.WebGLRenderer:', this.precision, 'not supported, using', _maxPrecision, 'instead.' );
25315 this.precision = _maxPrecision;
25316
25317 }
25318
25319 if ( this.logarithmicDepthBuffer ) {
25320
25321 this.logarithmicDepthBuffer = !! extensions.get( 'EXT_frag_depth' );
25322
25323 }
25324
25325 };
25326
25327
25328
25333 THREE.WebGLGeometries = function ( gl, properties, info ) {
25334
25335 var geometries = {};
25336
25337 function get( object ) {
25338
25339 var geometry = object.geometry;
25340
25341 if ( geometries[ geometry.id ] !== undefined ) {
25342
25343 return geometries[ geometry.id ];
25344
25345 }
25346
25347 geometry.addEventListener( 'dispose', onGeometryDispose );
25348
25349 var buffergeometry;
25350
25351 if ( geometry instanceof THREE.BufferGeometry ) {
25352
25353 buffergeometry = geometry;
25354
25355 } else if ( geometry instanceof THREE.Geometry ) {
25356
25357 if ( geometry._bufferGeometry === undefined ) {
25358
25359 geometry._bufferGeometry = new THREE.BufferGeometry().setFromObject( object );
25360
25361 }
25362
25363 buffergeometry = geometry._bufferGeometry;
25364
25365 }
25366
25367 geometries[ geometry.id ] = buffergeometry;
25368
25369 info.memory.geometries ++;
25370
25371 return buffergeometry;
25372
25373 }
25374
25375 function onGeometryDispose( event ) {
25376
25377 var geometry = event.target;
25378 var buffergeometry = geometries[ geometry.id ];
25379
25380 deleteAttributes( buffergeometry.attributes );
25381
25382 geometry.removeEventListener( 'dispose', onGeometryDispose );
25383
25384 delete geometries[ geometry.id ];
25385
25386 var property = properties.get( geometry );
25387 if ( property.wireframe ) deleteAttribute( property.wireframe );
25388
25389 info.memory.geometries --;
25390
25391 }
25392
25393 function getAttributeBuffer( attribute ) {
25394
25395 if ( attribute instanceof THREE.InterleavedBufferAttribute ) {
25396
25397 return properties.get( attribute.data ).__webglBuffer;
25398
25399 }
25400
25401 return properties.get( attribute ).__webglBuffer;
25402
25403 }
25404
25405 function deleteAttribute( attribute ) {
25406
25407 var buffer = getAttributeBuffer( attribute );
25408
25409 if ( buffer !== undefined ) {
25410
25411 gl.deleteBuffer( buffer );
25412 removeAttributeBuffer( attribute );
25413
25414 }
25415
25416 }
25417
25418 function deleteAttributes( attributes ) {
25419
25420 for ( var name in attributes ) {
25421
25422 deleteAttribute( attributes[ name ] );
25423
25424 }
25425
25426 }
25427
25428 function removeAttributeBuffer( attribute ) {
25429
25430 if ( attribute instanceof THREE.InterleavedBufferAttribute ) {
25431
25432 properties.delete( attribute.data );
25433
25434 } else {
25435
25436 properties.delete( attribute );
25437
25438 }
25439
25440 }
25441
25442 this.get = get;
25443
25444 };
25445
25446
25447
25452 THREE.WebGLObjects = function ( gl, properties, info ) {
25453
25454 var geometries = new THREE.WebGLGeometries( gl, properties, info );
25455
25456
25457
25458 function update( object ) {
25459
25460
25461
25462 var geometry = geometries.get( object );
25463
25464 if ( object.geometry instanceof THREE.Geometry ) {
25465
25466 geometry.updateFromObject( object );
25467
25468 }
25469
25470 var index = geometry.index;
25471 var attributes = geometry.attributes;
25472
25473 if ( index !== null ) {
25474
25475 updateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );
25476
25477 }
25478
25479 for ( var name in attributes ) {
25480
25481 updateAttribute( attributes[ name ], gl.ARRAY_BUFFER );
25482
25483 }
25484
25485
25486
25487 var morphAttributes = geometry.morphAttributes;
25488
25489 for ( var name in morphAttributes ) {
25490
25491 var array = morphAttributes[ name ];
25492
25493 for ( var i = 0, l = array.length; i < l; i ++ ) {
25494
25495 updateAttribute( array[ i ], gl.ARRAY_BUFFER );
25496
25497 }
25498
25499 }
25500
25501 return geometry;
25502
25503 }
25504
25505 function updateAttribute( attribute, bufferType ) {
25506
25507 var data = ( attribute instanceof THREE.InterleavedBufferAttribute ) ? attribute.data : attribute;
25508
25509 var attributeProperties = properties.get( data );
25510
25511 if ( attributeProperties.__webglBuffer === undefined ) {
25512
25513 createBuffer( attributeProperties, data, bufferType );
25514
25515 } else if ( attributeProperties.version !== data.version ) {
25516
25517 updateBuffer( attributeProperties, data, bufferType );
25518
25519 }
25520
25521 }
25522
25523 function createBuffer( attributeProperties, data, bufferType ) {
25524
25525 attributeProperties.__webglBuffer = gl.createBuffer();
25526 gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
25527
25528 var usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;
25529
25530 gl.bufferData( bufferType, data.array, usage );
25531
25532 attributeProperties.version = data.version;
25533
25534 }
25535
25536 function updateBuffer( attributeProperties, data, bufferType ) {
25537
25538 gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
25539
25540 if ( data.dynamic === false || data.updateRange.count === - 1 ) {
25541
25542
25543
25544 gl.bufferSubData( bufferType, 0, data.array );
25545
25546 } else if ( data.updateRange.count === 0 ) {
25547
25548 console.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );
25549
25550 } else {
25551
25552 gl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,
25553 data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );
25554
25555 data.updateRange.count = 0;
25556
25557 }
25558
25559 attributeProperties.version = data.version;
25560
25561 }
25562
25563 function getAttributeBuffer( attribute ) {
25564
25565 if ( attribute instanceof THREE.InterleavedBufferAttribute ) {
25566
25567 return properties.get( attribute.data ).__webglBuffer;
25568
25569 }
25570
25571 return properties.get( attribute ).__webglBuffer;
25572
25573 }
25574
25575 function getWireframeAttribute( geometry ) {
25576
25577 var property = properties.get( geometry );
25578
25579 if ( property.wireframe !== undefined ) {
25580
25581 return property.wireframe;
25582
25583 }
25584
25585 var indices = [];
25586
25587 var index = geometry.index;
25588 var attributes = geometry.attributes;
25589 var position = attributes.position;
25590
25591
25592
25593 if ( index !== null ) {
25594
25595 var edges = {};
25596 var array = index.array;
25597
25598 for ( var i = 0, l = array.length; i < l; i += 3 ) {
25599
25600 var a = array[ i + 0 ];
25601 var b = array[ i + 1 ];
25602 var c = array[ i + 2 ];
25603
25604 if ( checkEdge( edges, a, b ) ) indices.push( a, b );
25605 if ( checkEdge( edges, b, c ) ) indices.push( b, c );
25606 if ( checkEdge( edges, c, a ) ) indices.push( c, a );
25607
25608 }
25609
25610 } else {
25611
25612 var array = attributes.position.array;
25613
25614 for ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {
25615
25616 var a = i + 0;
25617 var b = i + 1;
25618 var c = i + 2;
25619
25620 indices.push( a, b, b, c, c, a );
25621
25622 }
25623
25624 }
25625
25626
25627
25628 var TypeArray = position.count > 65535 ? Uint32Array : Uint16Array;
25629 var attribute = new THREE.BufferAttribute( new TypeArray( indices ), 1 );
25630
25631 updateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );
25632
25633 property.wireframe = attribute;
25634
25635 return attribute;
25636
25637 }
25638
25639 function checkEdge( edges, a, b ) {
25640
25641 if ( a > b ) {
25642
25643 var tmp = a;
25644 a = b;
25645 b = tmp;
25646
25647 }
25648
25649 var list = edges[ a ];
25650
25651 if ( list === undefined ) {
25652
25653 edges[ a ] = [ b ];
25654 return true;
25655
25656 } else if ( list.indexOf( b ) === -1 ) {
25657
25658 list.push( b );
25659 return true;
25660
25661 }
25662
25663 return false;
25664
25665 }
25666
25667 this.getAttributeBuffer = getAttributeBuffer;
25668 this.getWireframeAttribute = getWireframeAttribute;
25669
25670 this.update = update;
25671
25672 };
25673
25674
25675
25676 THREE.WebGLProgram = ( function () {
25677
25678 var programIdCount = 0;
25679
25680 function generateDefines( defines ) {
25681
25682 var chunks = [];
25683
25684 for ( var name in defines ) {
25685
25686 var value = defines[ name ];
25687
25688 if ( value === false ) continue;
25689
25690 chunks.push( '#define ' + name + ' ' + value );
25691
25692 }
25693
25694 return chunks.join( '\n' );
25695
25696 }
25697
25698 function fetchUniformLocations( gl, program, identifiers ) {
25699
25700 var uniforms = {};
25701
25702 var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );
25703
25704 for ( var i = 0; i < n; i ++ ) {
25705
25706 var info = gl.getActiveUniform( program, i );
25707 var name = info.name;
25708 var location = gl.getUniformLocation( program, name );
25709
25710
25711
25712 var suffixPos = name.lastIndexOf( '[0]' );
25713 if ( suffixPos !== - 1 && suffixPos === name.length - 3 ) {
25714
25715 uniforms[ name.substr( 0, suffixPos ) ] = location;
25716
25717 }
25718
25719 uniforms[ name ] = location;
25720
25721 }
25722
25723 return uniforms;
25724
25725 }
25726
25727 function fetchAttributeLocations( gl, program, identifiers ) {
25728
25729 var attributes = {};
25730
25731 var n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );
25732
25733 for ( var i = 0; i < n; i ++ ) {
25734
25735 var info = gl.getActiveAttrib( program, i );
25736 var name = info.name;
25737
25738
25739
25740 attributes[ name ] = gl.getAttribLocation( program, name );
25741
25742 }
25743
25744 return attributes;
25745
25746 }
25747
25748 function filterEmptyLine( string ) {
25749
25750 return string !== '';
25751
25752 }
25753
25754 return function WebGLProgram( renderer, code, material, parameters ) {
25755
25756 var gl = renderer.context;
25757
25758 var defines = material.defines;
25759
25760 var vertexShader = material.__webglShader.vertexShader;
25761 var fragmentShader = material.__webglShader.fragmentShader;
25762
25763 var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
25764
25765 if ( parameters.shadowMapType === THREE.PCFShadowMap ) {
25766
25767 shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
25768
25769 } else if ( parameters.shadowMapType === THREE.PCFSoftShadowMap ) {
25770
25771 shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
25772
25773 }
25774
25775 var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
25776 var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
25777 var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
25778
25779 if ( parameters.envMap ) {
25780
25781 switch ( material.envMap.mapping ) {
25782
25783 case THREE.CubeReflectionMapping:
25784 case THREE.CubeRefractionMapping:
25785 envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
25786 break;
25787
25788 case THREE.EquirectangularReflectionMapping:
25789 case THREE.EquirectangularRefractionMapping:
25790 envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';
25791 break;
25792
25793 case THREE.SphericalReflectionMapping:
25794 envMapTypeDefine = 'ENVMAP_TYPE_SPHERE';
25795 break;
25796
25797 }
25798
25799 switch ( material.envMap.mapping ) {
25800
25801 case THREE.CubeRefractionMapping:
25802 case THREE.EquirectangularRefractionMapping:
25803 envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
25804 break;
25805
25806 }
25807
25808 switch ( material.combine ) {
25809
25810 case THREE.MultiplyOperation:
25811 envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
25812 break;
25813
25814 case THREE.MixOperation:
25815 envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
25816 break;
25817
25818 case THREE.AddOperation:
25819 envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
25820 break;
25821
25822 }
25823
25824 }
25825
25826 var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;
25827
25828
25829
25830
25831
25832 var customDefines = generateDefines( defines );
25833
25834
25835
25836 var program = gl.createProgram();
25837
25838 var prefixVertex, prefixFragment;
25839
25840 if ( material instanceof THREE.RawShaderMaterial ) {
25841
25842 prefixVertex = '';
25843 prefixFragment = '';
25844
25845 } else {
25846
25847 prefixVertex = [
25848
25849 'precision ' + parameters.precision + ' float;',
25850 'precision ' + parameters.precision + ' int;',
25851
25852 '#define SHADER_NAME ' + material.__webglShader.name,
25853
25854 customDefines,
25855
25856 parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',
25857
25858 renderer.gammaInput ? '#define GAMMA_INPUT' : '',
25859 renderer.gammaOutput ? '#define GAMMA_OUTPUT' : '',
25860 '#define GAMMA_FACTOR ' + gammaFactorDefine,
25861
25862 '#define MAX_DIR_LIGHTS ' + parameters.maxDirLights,
25863 '#define MAX_POINT_LIGHTS ' + parameters.maxPointLights,
25864 '#define MAX_SPOT_LIGHTS ' + parameters.maxSpotLights,
25865 '#define MAX_HEMI_LIGHTS ' + parameters.maxHemiLights,
25866
25867 '#define MAX_SHADOWS ' + parameters.maxShadows,
25868
25869 '#define MAX_BONES ' + parameters.maxBones,
25870
25871 parameters.map ? '#define USE_MAP' : '',
25872 parameters.envMap ? '#define USE_ENVMAP' : '',
25873 parameters.envMap ? '#define ' + envMapModeDefine : '',
25874 parameters.lightMap ? '#define USE_LIGHTMAP' : '',
25875 parameters.aoMap ? '#define USE_AOMAP' : '',
25876 parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
25877 parameters.bumpMap ? '#define USE_BUMPMAP' : '',
25878 parameters.normalMap ? '#define USE_NORMALMAP' : '',
25879 parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',
25880 parameters.specularMap ? '#define USE_SPECULARMAP' : '',
25881 parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
25882 parameters.vertexColors ? '#define USE_COLOR' : '',
25883
25884 parameters.flatShading ? '#define FLAT_SHADED' : '',
25885
25886 parameters.skinning ? '#define USE_SKINNING' : '',
25887 parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',
25888
25889 parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
25890 parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',
25891 parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
25892 parameters.flipSided ? '#define FLIP_SIDED' : '',
25893
25894 parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
25895 parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
25896 parameters.shadowMapDebug ? '#define SHADOWMAP_DEBUG' : '',
25897 parameters.pointLightShadows > 0 ? '#define POINT_LIGHT_SHADOWS' : '',
25898
25899 parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
25900
25901 parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
25902 parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
25903
25904
25905 'uniform mat4 modelMatrix;',
25906 'uniform mat4 modelViewMatrix;',
25907 'uniform mat4 projectionMatrix;',
25908 'uniform mat4 viewMatrix;',
25909 'uniform mat3 normalMatrix;',
25910 'uniform vec3 cameraPosition;',
25911
25912 'attribute vec3 position;',
25913 'attribute vec3 normal;',
25914 'attribute vec2 uv;',
25915
25916 '#ifdef USE_COLOR',
25917
25918 ' attribute vec3 color;',
25919
25920 '#endif',
25921
25922 '#ifdef USE_MORPHTARGETS',
25923
25924 ' attribute vec3 morphTarget0;',
25925 ' attribute vec3 morphTarget1;',
25926 ' attribute vec3 morphTarget2;',
25927 ' attribute vec3 morphTarget3;',
25928
25929 ' #ifdef USE_MORPHNORMALS',
25930
25931 ' attribute vec3 morphNormal0;',
25932 ' attribute vec3 morphNormal1;',
25933 ' attribute vec3 morphNormal2;',
25934 ' attribute vec3 morphNormal3;',
25935
25936 ' #else',
25937
25938 ' attribute vec3 morphTarget4;',
25939 ' attribute vec3 morphTarget5;',
25940 ' attribute vec3 morphTarget6;',
25941 ' attribute vec3 morphTarget7;',
25942
25943 ' #endif',
25944
25945 '#endif',
25946
25947 '#ifdef USE_SKINNING',
25948
25949 ' attribute vec4 skinIndex;',
25950 ' attribute vec4 skinWeight;',
25951
25952 '#endif',
25953
25954 '\n'
25955
25956 ].filter( filterEmptyLine ).join( '\n' );
25957
25958 prefixFragment = [
25959
25960 parameters.bumpMap || parameters.normalMap || parameters.flatShading || material.derivatives ? '#extension GL_OES_standard_derivatives : enable' : '',
25961 parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',
25962
25963 'precision ' + parameters.precision + ' float;',
25964 'precision ' + parameters.precision + ' int;',
25965
25966 '#define SHADER_NAME ' + material.__webglShader.name,
25967
25968 customDefines,
25969
25970 '#define MAX_DIR_LIGHTS ' + parameters.maxDirLights,
25971 '#define MAX_POINT_LIGHTS ' + parameters.maxPointLights,
25972 '#define MAX_SPOT_LIGHTS ' + parameters.maxSpotLights,
25973 '#define MAX_HEMI_LIGHTS ' + parameters.maxHemiLights,
25974
25975 '#define MAX_SHADOWS ' + parameters.maxShadows,
25976
25977 parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',
25978
25979 renderer.gammaInput ? '#define GAMMA_INPUT' : '',
25980 renderer.gammaOutput ? '#define GAMMA_OUTPUT' : '',
25981 '#define GAMMA_FACTOR ' + gammaFactorDefine,
25982
25983 ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
25984 ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',
25985
25986 parameters.map ? '#define USE_MAP' : '',
25987 parameters.envMap ? '#define USE_ENVMAP' : '',
25988 parameters.envMap ? '#define ' + envMapTypeDefine : '',
25989 parameters.envMap ? '#define ' + envMapModeDefine : '',
25990 parameters.envMap ? '#define ' + envMapBlendingDefine : '',
25991 parameters.lightMap ? '#define USE_LIGHTMAP' : '',
25992 parameters.aoMap ? '#define USE_AOMAP' : '',
25993 parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
25994 parameters.bumpMap ? '#define USE_BUMPMAP' : '',
25995 parameters.normalMap ? '#define USE_NORMALMAP' : '',
25996 parameters.specularMap ? '#define USE_SPECULARMAP' : '',
25997 parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
25998 parameters.vertexColors ? '#define USE_COLOR' : '',
25999
26000 parameters.flatShading ? '#define FLAT_SHADED' : '',
26001
26002 parameters.metal ? '#define METAL' : '',
26003 parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
26004 parameters.flipSided ? '#define FLIP_SIDED' : '',
26005
26006 parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
26007 parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
26008 parameters.shadowMapDebug ? '#define SHADOWMAP_DEBUG' : '',
26009 parameters.pointLightShadows > 0 ? '#define POINT_LIGHT_SHADOWS' : '',
26010
26011 parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
26012 parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
26013
26014 'uniform mat4 viewMatrix;',
26015 'uniform vec3 cameraPosition;',
26016
26017 '\n'
26018
26019 ].filter( filterEmptyLine ).join( '\n' );
26020
26021 }
26022
26023 var vertexGlsl = prefixVertex + vertexShader;
26024 var fragmentGlsl = prefixFragment + fragmentShader;
26025
26026 var glVertexShader = THREE.WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );
26027 var glFragmentShader = THREE.WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );
26028
26029 gl.attachShader( program, glVertexShader );
26030 gl.attachShader( program, glFragmentShader );
26031
26032
26033
26034 if ( material.index0AttributeName !== undefined ) {
26035
26036 gl.bindAttribLocation( program, 0, material.index0AttributeName );
26037
26038 } else if ( parameters.morphTargets === true ) {
26039
26040
26041 gl.bindAttribLocation( program, 0, 'position' );
26042
26043 }
26044
26045 gl.linkProgram( program );
26046
26047 var programLog = gl.getProgramInfoLog( program );
26048 var vertexLog = gl.getShaderInfoLog( glVertexShader );
26049 var fragmentLog = gl.getShaderInfoLog( glFragmentShader );
26050
26051 var runnable = true;
26052 var haveDiagnostics = true;
26053
26054 if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
26055
26056 runnable = false;
26057
26058 console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );
26059
26060 } else if ( programLog !== '' ) {
26061
26062 console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
26063
26064 } else if ( vertexLog === '' || fragmentLog === '' ) {
26065
26066 haveDiagnostics = false;
26067
26068 }
26069
26070 if ( haveDiagnostics ) {
26071
26072 this.diagnostics = {
26073
26074 runnable: runnable,
26075 material: material,
26076
26077 programLog: programLog,
26078
26079 vertexShader: {
26080
26081 log: vertexLog,
26082 prefix: prefixVertex
26083
26084 },
26085
26086 fragmentShader: {
26087
26088 log: fragmentLog,
26089 prefix: prefixFragment
26090
26091 }
26092
26093 };
26094
26095 }
26096
26097
26098
26099 gl.deleteShader( glVertexShader );
26100 gl.deleteShader( glFragmentShader );
26101
26102
26103
26104 var cachedUniforms;
26105
26106 this.getUniforms = function() {
26107
26108 if ( cachedUniforms === undefined ) {
26109
26110 cachedUniforms = fetchUniformLocations( gl, program );
26111
26112 }
26113
26114 return cachedUniforms;
26115
26116 };
26117
26118
26119
26120 var cachedAttributes;
26121
26122 this.getAttributes = function() {
26123
26124 if ( cachedAttributes === undefined ) {
26125
26126 cachedAttributes = fetchAttributeLocations( gl, program );
26127
26128 }
26129
26130 return cachedAttributes;
26131
26132 };
26133
26134
26135
26136 this.destroy = function() {
26137
26138 gl.deleteProgram( program );
26139 this.program = undefined;
26140
26141 };
26142
26143
26144
26145 Object.defineProperties( this, {
26146
26147 uniforms: {
26148 get: function() {
26149
26150 console.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );
26151 return this.getUniforms();
26152
26153 }
26154 },
26155
26156 attributes: {
26157 get: function() {
26158
26159 console.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );
26160 return this.getAttributes();
26161
26162 }
26163 }
26164
26165 } );
26166
26167
26168
26169
26170 this.id = programIdCount ++;
26171 this.code = code;
26172 this.usedTimes = 1;
26173 this.program = program;
26174 this.vertexShader = glVertexShader;
26175 this.fragmentShader = glFragmentShader;
26176
26177 return this;
26178
26179 };
26180
26181 } )();
26182
26183
26184
26185 THREE.WebGLPrograms = function ( renderer, capabilities ) {
26186
26187 var programs = [];
26188
26189 var shaderIDs = {
26190 MeshDepthMaterial: 'depth',
26191 MeshNormalMaterial: 'normal',
26192 MeshBasicMaterial: 'basic',
26193 MeshLambertMaterial: 'lambert',
26194 MeshPhongMaterial: 'phong',
26195 LineBasicMaterial: 'basic',
26196 LineDashedMaterial: 'dashed',
26197 PointsMaterial: 'points'
26198 };
26199
26200 var parameterNames = [
26201 "precision", "supportsVertexTextures", "map", "envMap", "envMapMode",
26202 "lightMap", "aoMap", "emissiveMap", "bumpMap", "normalMap", "displacementMap", "specularMap",
26203 "alphaMap", "combine", "vertexColors", "fog", "useFog", "fogExp",
26204 "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning",
26205 "maxBones", "useVertexTexture", "morphTargets", "morphNormals",
26206 "maxMorphTargets", "maxMorphNormals", "maxDirLights", "maxPointLights",
26207 "maxSpotLights", "maxHemiLights", "maxShadows", "shadowMapEnabled", "pointLightShadows",
26208 "shadowMapType", "shadowMapDebug", "alphaTest", "metal", "doubleSided",
26209 "flipSided"
26210 ];
26211
26212
26213 function allocateBones ( object ) {
26214
26215 if ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {
26216
26217 return 1024;
26218
26219 } else {
26220
26221
26222
26223
26224
26225
26226
26227
26228 var nVertexUniforms = capabilities.maxVertexUniforms;
26229 var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
26230
26231 var maxBones = nVertexMatrices;
26232
26233 if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
26234
26235 maxBones = Math.min( object.skeleton.bones.length, maxBones );
26236
26237 if ( maxBones < object.skeleton.bones.length ) {
26238
26239 console.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );
26240
26241 }
26242
26243 }
26244
26245 return maxBones;
26246
26247 }
26248
26249 }
26250
26251 function allocateLights( lights ) {
26252
26253 var dirLights = 0;
26254 var pointLights = 0;
26255 var spotLights = 0;
26256 var hemiLights = 0;
26257
26258 for ( var l = 0, ll = lights.length; l < ll; l ++ ) {
26259
26260 var light = lights[ l ];
26261
26262 if ( light.visible === false ) continue;
26263
26264 if ( light instanceof THREE.DirectionalLight ) dirLights ++;
26265 if ( light instanceof THREE.PointLight ) pointLights ++;
26266 if ( light instanceof THREE.SpotLight ) spotLights ++;
26267 if ( light instanceof THREE.HemisphereLight ) hemiLights ++;
26268
26269 }
26270
26271 return { 'directional': dirLights, 'point': pointLights, 'spot': spotLights, 'hemi': hemiLights };
26272
26273 }
26274
26275 function allocateShadows( lights ) {
26276
26277 var maxShadows = 0;
26278 var pointLightShadows = 0;
26279
26280 for ( var l = 0, ll = lights.length; l < ll; l ++ ) {
26281
26282 var light = lights[ l ];
26283
26284 if ( ! light.castShadow ) continue;
26285
26286 if ( light instanceof THREE.SpotLight || light instanceof THREE.DirectionalLight ) maxShadows ++;
26287 if ( light instanceof THREE.PointLight ) {
26288
26289 maxShadows ++;
26290 pointLightShadows ++;
26291
26292 }
26293
26294 }
26295
26296 return { 'maxShadows': maxShadows, 'pointLightShadows': pointLightShadows };
26297
26298 }
26299
26300 this.getParameters = function ( material, lights, fog, object ) {
26301
26302 var shaderID = shaderIDs[ material.type ];
26303
26304
26305
26306 var maxLightCount = allocateLights( lights );
26307 var allocatedShadows = allocateShadows( lights );
26308 var maxBones = allocateBones( object );
26309 var precision = renderer.getPrecision();
26310
26311 if ( material.precision !== null ) {
26312
26313 precision = capabilities.getMaxPrecision( material.precision );
26314
26315 if ( precision !== material.precision ) {
26316
26317 console.warn( 'THREE.WebGLRenderer.initMaterial:', material.precision, 'not supported, using', precision, 'instead.' );
26318
26319 }
26320
26321 }
26322
26323 var parameters = {
26324
26325 shaderID: shaderID,
26326
26327 precision: precision,
26328 supportsVertexTextures: capabilities.vertexTextures,
26329
26330 map: !! material.map,
26331 envMap: !! material.envMap,
26332 envMapMode: material.envMap && material.envMap.mapping,
26333 lightMap: !! material.lightMap,
26334 aoMap: !! material.aoMap,
26335 emissiveMap: !! material.emissiveMap,
26336 bumpMap: !! material.bumpMap,
26337 normalMap: !! material.normalMap,
26338 displacementMap: !! material.displacementMap,
26339 specularMap: !! material.specularMap,
26340 alphaMap: !! material.alphaMap,
26341
26342 combine: material.combine,
26343
26344 vertexColors: material.vertexColors,
26345
26346 fog: fog,
26347 useFog: material.fog,
26348 fogExp: fog instanceof THREE.FogExp2,
26349
26350 flatShading: material.shading === THREE.FlatShading,
26351
26352 sizeAttenuation: material.sizeAttenuation,
26353 logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,
26354
26355 skinning: material.skinning,
26356 maxBones: maxBones,
26357 useVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,
26358
26359 morphTargets: material.morphTargets,
26360 morphNormals: material.morphNormals,
26361 maxMorphTargets: renderer.maxMorphTargets,
26362 maxMorphNormals: renderer.maxMorphNormals,
26363
26364 maxDirLights: maxLightCount.directional,
26365 maxPointLights: maxLightCount.point,
26366 maxSpotLights: maxLightCount.spot,
26367 maxHemiLights: maxLightCount.hemi,
26368
26369 maxShadows: allocatedShadows.maxShadows,
26370 pointLightShadows: allocatedShadows.pointLightShadows,
26371 shadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && allocatedShadows.maxShadows > 0,
26372 shadowMapType: renderer.shadowMap.type,
26373 shadowMapDebug: renderer.shadowMap.debug,
26374
26375 alphaTest: material.alphaTest,
26376 metal: material.metal,
26377 doubleSided: material.side === THREE.DoubleSide,
26378 flipSided: material.side === THREE.BackSide
26379
26380 };
26381
26382 return parameters;
26383
26384 };
26385
26386 this.getProgramCode = function ( material, parameters ) {
26387
26388 var chunks = [];
26389
26390 if ( parameters.shaderID ) {
26391
26392 chunks.push( parameters.shaderID );
26393
26394 } else {
26395
26396 chunks.push( material.fragmentShader );
26397 chunks.push( material.vertexShader );
26398
26399 }
26400
26401 if ( material.defines !== undefined ) {
26402
26403 for ( var name in material.defines ) {
26404
26405 chunks.push( name );
26406 chunks.push( material.defines[ name ] );
26407
26408 }
26409
26410 }
26411
26412 for ( var i = 0; i < parameterNames.length; i ++ ) {
26413
26414 var parameterName = parameterNames[ i ];
26415 chunks.push( parameterName );
26416 chunks.push( parameters[ parameterName ] );
26417
26418 }
26419
26420 return chunks.join();
26421
26422 };
26423
26424 this.acquireProgram = function ( material, parameters, code ) {
26425
26426 var program;
26427
26428
26429 for ( var p = 0, pl = programs.length; p < pl; p ++ ) {
26430
26431 var programInfo = programs[ p ];
26432
26433 if ( programInfo.code === code ) {
26434
26435 program = programInfo;
26436 ++ program.usedTimes;
26437
26438 break;
26439
26440 }
26441
26442 }
26443
26444 if ( program === undefined ) {
26445
26446 program = new THREE.WebGLProgram( renderer, code, material, parameters );
26447 programs.push( program );
26448
26449 }
26450
26451 return program;
26452
26453 };
26454
26455 this.releaseProgram = function( program ) {
26456
26457 if ( -- program.usedTimes === 0 ) {
26458
26459
26460 var i = programs.indexOf( program );
26461 programs[ i ] = programs[ programs.length - 1 ];
26462 programs.pop();
26463
26464
26465 program.destroy();
26466
26467 }
26468
26469 };
26470
26471
26472 this.programs = programs;
26473
26474 };
26475
26476
26477
26482 THREE.WebGLProperties = function () {
26483
26484 var properties = {};
26485
26486 this.get = function ( object ) {
26487
26488 var uuid = object.uuid;
26489 var map = properties[ uuid ];
26490
26491 if ( map === undefined ) {
26492
26493 map = {};
26494 properties[ uuid ] = map;
26495
26496 }
26497
26498 return map;
26499
26500 };
26501
26502 this.delete = function ( object ) {
26503
26504 delete properties[ object.uuid ];
26505
26506 };
26507
26508 this.clear = function () {
26509
26510 properties = {};
26511
26512 };
26513
26514 };
26515
26516
26517
26518 THREE.WebGLShader = ( function () {
26519
26520 function addLineNumbers( string ) {
26521
26522 var lines = string.split( '\n' );
26523
26524 for ( var i = 0; i < lines.length; i ++ ) {
26525
26526 lines[ i ] = ( i + 1 ) + ': ' + lines[ i ];
26527
26528 }
26529
26530 return lines.join( '\n' );
26531
26532 }
26533
26534 return function WebGLShader( gl, type, string ) {
26535
26536 var shader = gl.createShader( type );
26537
26538 gl.shaderSource( shader, string );
26539 gl.compileShader( shader );
26540
26541 if ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {
26542
26543 console.error( 'THREE.WebGLShader: Shader couldn\'t compile.' );
26544
26545 }
26546
26547 if ( gl.getShaderInfoLog( shader ) !== '' ) {
26548
26549 console.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );
26550
26551 }
26552
26553
26554
26555
26556 return shader;
26557
26558 };
26559
26560 } )();
26561
26562
26563
26569 THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
26570
26571 var _gl = _renderer.context,
26572 _state = _renderer.state,
26573 _frustum = new THREE.Frustum(),
26574 _projScreenMatrix = new THREE.Matrix4(),
26575
26576 _min = new THREE.Vector3(),
26577 _max = new THREE.Vector3(),
26578
26579 _lookTarget = new THREE.Vector3(),
26580 _lightPositionWorld = new THREE.Vector3(),
26581
26582 _renderList = [],
26583
26584 _MorphingFlag = 1,
26585 _SkinningFlag = 2,
26586
26587 _NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,
26588
26589 _depthMaterials = new Array( _NumberOfMaterialVariants ),
26590 _distanceMaterials = new Array( _NumberOfMaterialVariants );
26591
26592 var cubeDirections = [
26593 new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( - 1, 0, 0 ), new THREE.Vector3( 0, 0, 1 ),
26594 new THREE.Vector3( 0, 0, - 1 ), new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, - 1, 0 )
26595 ];
26596
26597 var cubeUps = [
26598 new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, 1, 0 ),
26599 new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, 0, 1 ), new THREE.Vector3( 0, 0, - 1 )
26600 ];
26601
26602 var cube2DViewPorts = [
26603 new THREE.Vector4(), new THREE.Vector4(), new THREE.Vector4(),
26604 new THREE.Vector4(), new THREE.Vector4(), new THREE.Vector4()
26605 ];
26606
26607 var _vector4 = new THREE.Vector4();
26608
26609
26610
26611 var depthShader = THREE.ShaderLib[ "depthRGBA" ];
26612 var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
26613
26614 var distanceShader = THREE.ShaderLib[ "distanceRGBA" ];
26615 var distanceUniforms = THREE.UniformsUtils.clone( distanceShader.uniforms );
26616
26617 for ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {
26618
26619 var useMorphing = ( i & _MorphingFlag ) !== 0;
26620 var useSkinning = ( i & _SkinningFlag ) !== 0;
26621
26622 var depthMaterial = new THREE.ShaderMaterial( {
26623 uniforms: depthUniforms,
26624 vertexShader: depthShader.vertexShader,
26625 fragmentShader: depthShader.fragmentShader,
26626 morphTargets: useMorphing,
26627 skinning: useSkinning
26628 } );
26629
26630 depthMaterial._shadowPass = true;
26631
26632 _depthMaterials[ i ] = depthMaterial;
26633
26634 var distanceMaterial = new THREE.ShaderMaterial( {
26635 uniforms: distanceUniforms,
26636 vertexShader: distanceShader.vertexShader,
26637 fragmentShader: distanceShader.fragmentShader,
26638 morphTargets: useMorphing,
26639 skinning: useSkinning
26640 } );
26641
26642 distanceMaterial._shadowPass = true;
26643
26644 _distanceMaterials[ i ] = distanceMaterial;
26645
26646 }
26647
26648
26649
26650 var scope = this;
26651
26652 this.enabled = false;
26653
26654 this.autoUpdate = true;
26655 this.needsUpdate = false;
26656
26657 this.type = THREE.PCFShadowMap;
26658 this.cullFace = THREE.CullFaceFront;
26659
26660 this.render = function ( scene ) {
26661
26662 var faceCount, isPointLight;
26663
26664 if ( scope.enabled === false ) return;
26665 if ( scope.autoUpdate === false && scope.needsUpdate === false ) return;
26666
26667
26668 _gl.clearColor( 1, 1, 1, 1 );
26669 _state.disable( _gl.BLEND );
26670 _state.enable( _gl.CULL_FACE );
26671 _gl.frontFace( _gl.CCW );
26672 _gl.cullFace( scope.cullFace === THREE.CullFaceFront ? _gl.FRONT : _gl.BACK );
26673 _state.setDepthTest( true );
26674
26675
26676 _renderer.getViewport( _vector4 );
26677
26678
26679
26680 for ( var i = 0, il = _lights.length; i < il; i ++ ) {
26681
26682 var light = _lights[ i ];
26683
26684 if ( light.castShadow === true ) {
26685
26686 var shadow = light.shadow;
26687 var shadowCamera = shadow.camera;
26688 var shadowMapSize = shadow.mapSize;
26689
26690 if ( light instanceof THREE.PointLight ) {
26691
26692 faceCount = 6;
26693 isPointLight = true;
26694
26695 var vpWidth = shadowMapSize.x / 4.0;
26696 var vpHeight = shadowMapSize.y / 2.0;
26697
26698
26699
26700
26701
26702
26703
26704
26705
26706
26707
26708
26709
26710
26711
26712 cube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );
26713
26714 cube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );
26715
26716 cube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );
26717
26718 cube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );
26719
26720 cube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );
26721
26722 cube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );
26723
26724 } else {
26725
26726 faceCount = 1;
26727 isPointLight = false;
26728
26729 }
26730
26731 if ( shadow.map === null ) {
26732
26733 var shadowFilter = THREE.LinearFilter;
26734
26735 if ( scope.type === THREE.PCFSoftShadowMap ) {
26736
26737 shadowFilter = THREE.NearestFilter;
26738
26739 }
26740
26741 var pars = { minFilter: shadowFilter, magFilter: shadowFilter, format: THREE.RGBAFormat };
26742
26743 shadow.map = new THREE.WebGLRenderTarget( shadowMapSize.x, shadowMapSize.y, pars );
26744 shadow.matrix = new THREE.Matrix4();
26745
26746
26747
26748 if ( light instanceof THREE.SpotLight ) {
26749
26750 shadowCamera.aspect = shadowMapSize.x / shadowMapSize.y;
26751
26752 }
26753
26754 shadowCamera.updateProjectionMatrix();
26755
26756 }
26757
26758 var shadowMap = shadow.map;
26759 var shadowMatrix = shadow.matrix;
26760
26761 _lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
26762 shadowCamera.position.copy( _lightPositionWorld );
26763
26764 _renderer.setRenderTarget( shadowMap );
26765 _renderer.clear();
26766
26767
26768
26769
26770 for ( var face = 0; face < faceCount; face ++ ) {
26771
26772 if ( isPointLight ) {
26773
26774 _lookTarget.copy( shadowCamera.position );
26775 _lookTarget.add( cubeDirections[ face ] );
26776 shadowCamera.up.copy( cubeUps[ face ] );
26777 shadowCamera.lookAt( _lookTarget );
26778 var vpDimensions = cube2DViewPorts[ face ];
26779 _renderer.setViewport( vpDimensions.x, vpDimensions.y, vpDimensions.z, vpDimensions.w );
26780
26781 } else {
26782
26783 _lookTarget.setFromMatrixPosition( light.target.matrixWorld );
26784 shadowCamera.lookAt( _lookTarget );
26785
26786 }
26787
26788 shadowCamera.updateMatrixWorld();
26789 shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );
26790
26791
26792
26793 shadowMatrix.set(
26794 0.5, 0.0, 0.0, 0.5,
26795 0.0, 0.5, 0.0, 0.5,
26796 0.0, 0.0, 0.5, 0.5,
26797 0.0, 0.0, 0.0, 1.0
26798 );
26799
26800 shadowMatrix.multiply( shadowCamera.projectionMatrix );
26801 shadowMatrix.multiply( shadowCamera.matrixWorldInverse );
26802
26803
26804
26805 _projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
26806 _frustum.setFromMatrix( _projScreenMatrix );
26807
26808
26809
26810 _renderList.length = 0;
26811
26812 projectObject( scene, shadowCamera );
26813
26814
26815
26816
26817 for ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {
26818
26819 var object = _renderList[ j ];
26820 var geometry = _objects.update( object );
26821 var material = object.material;
26822
26823 if ( material instanceof THREE.MeshFaceMaterial ) {
26824
26825 var groups = geometry.groups;
26826 var materials = material.materials;
26827
26828 for ( var k = 0, kl = groups.length; k < kl; k ++ ) {
26829
26830 var group = groups[ k ];
26831 var groupMaterial = materials[ group.materialIndex ];
26832
26833 if ( groupMaterial.visible === true ) {
26834
26835 var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );
26836 _renderer.renderBufferDirect( shadowCamera, _lights, null, geometry, depthMaterial, object, group );
26837
26838 }
26839
26840 }
26841
26842 } else {
26843
26844 var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );
26845 _renderer.renderBufferDirect( shadowCamera, _lights, null, geometry, depthMaterial, object, null );
26846
26847 }
26848
26849 }
26850
26851 }
26852
26853
26854
26855 _renderer.resetGLState();
26856
26857 }
26858
26859 }
26860
26861 _renderer.setViewport( _vector4.x, _vector4.y, _vector4.z, _vector4.w );
26862
26863
26864 var clearColor = _renderer.getClearColor(),
26865 clearAlpha = _renderer.getClearAlpha();
26866 _renderer.setClearColor( clearColor, clearAlpha );
26867 _state.enable( _gl.BLEND );
26868
26869 if ( scope.cullFace === THREE.CullFaceFront ) {
26870
26871 _gl.cullFace( _gl.BACK );
26872
26873 }
26874
26875 _renderer.resetGLState();
26876
26877 scope.needsUpdate = false;
26878
26879 };
26880
26881 function getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {
26882
26883 var geometry = object.geometry;
26884
26885 var newMaterial = null;
26886
26887 var materialVariants = _depthMaterials;
26888 var customMaterial = object.customDepthMaterial;
26889
26890 if ( isPointLight ) {
26891
26892 materialVariants = _distanceMaterials;
26893 customMaterial = object.customDistanceMaterial;
26894
26895 }
26896
26897 if ( ! customMaterial ) {
26898
26899 var useMorphing = geometry.morphTargets !== undefined &&
26900 geometry.morphTargets.length > 0 && material.morphTargets;
26901
26902 var useSkinning = object instanceof THREE.SkinnedMesh && material.skinning;
26903
26904 var variantIndex = 0;
26905
26906 if ( useMorphing ) variantIndex |= _MorphingFlag;
26907 if ( useSkinning ) variantIndex |= _SkinningFlag;
26908
26909 newMaterial = materialVariants[ variantIndex ];
26910
26911 } else {
26912
26913 newMaterial = customMaterial;
26914
26915 }
26916
26917 newMaterial.visible = material.visible;
26918 newMaterial.wireframe = material.wireframe;
26919 newMaterial.wireframeLinewidth = material.wireframeLinewidth;
26920
26921 if ( isPointLight && newMaterial.uniforms.lightPos !== undefined ) {
26922
26923 newMaterial.uniforms.lightPos.value.copy( lightPositionWorld );
26924
26925 }
26926
26927 return newMaterial;
26928
26929 }
26930
26931 function projectObject( object, camera ) {
26932
26933 if ( object.visible === false ) return;
26934
26935 if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.Points ) {
26936
26937 if ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {
26938
26939 var material = object.material;
26940
26941 if ( material.visible === true ) {
26942
26943 object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
26944 _renderList.push( object );
26945
26946 }
26947
26948 }
26949
26950 }
26951
26952 var children = object.children;
26953
26954 for ( var i = 0, l = children.length; i < l; i ++ ) {
26955
26956 projectObject( children[ i ], camera );
26957
26958 }
26959
26960 }
26961
26962 };
26963
26964
26965
26970 THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) {
26971
26972 var _this = this;
26973
26974 var newAttributes = new Uint8Array( 16 );
26975 var enabledAttributes = new Uint8Array( 16 );
26976 var attributeDivisors = new Uint8Array( 16 );
26977
26978 var capabilities = {};
26979
26980 var compressedTextureFormats = null;
26981
26982 var currentBlending = null;
26983 var currentBlendEquation = null;
26984 var currentBlendSrc = null;
26985 var currentBlendDst = null;
26986 var currentBlendEquationAlpha = null;
26987 var currentBlendSrcAlpha = null;
26988 var currentBlendDstAlpha = null;
26989
26990 var currentDepthFunc = null;
26991 var currentDepthWrite = null;
26992
26993 var currentColorWrite = null;
26994
26995 var currentFlipSided = null;
26996
26997 var currentLineWidth = null;
26998
26999 var currentPolygonOffsetFactor = null;
27000 var currentPolygonOffsetUnits = null;
27001
27002 var maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );
27003
27004 var currentTextureSlot = undefined;
27005 var currentBoundTextures = {};
27006
27007 this.init = function () {
27008
27009 gl.clearColor( 0, 0, 0, 1 );
27010 gl.clearDepth( 1 );
27011 gl.clearStencil( 0 );
27012
27013 this.enable( gl.DEPTH_TEST );
27014 gl.depthFunc( gl.LEQUAL );
27015
27016 gl.frontFace( gl.CCW );
27017 gl.cullFace( gl.BACK );
27018 this.enable( gl.CULL_FACE );
27019
27020 this.enable( gl.BLEND );
27021 gl.blendEquation( gl.FUNC_ADD );
27022 gl.blendFunc( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA );
27023
27024 };
27025
27026 this.initAttributes = function () {
27027
27028 for ( var i = 0, l = newAttributes.length; i < l; i ++ ) {
27029
27030 newAttributes[ i ] = 0;
27031
27032 }
27033
27034 };
27035
27036 this.enableAttribute = function ( attribute ) {
27037
27038 newAttributes[ attribute ] = 1;
27039
27040 if ( enabledAttributes[ attribute ] === 0 ) {
27041
27042 gl.enableVertexAttribArray( attribute );
27043 enabledAttributes[ attribute ] = 1;
27044
27045 }
27046
27047 if ( attributeDivisors[ attribute ] !== 0 ) {
27048
27049 var extension = extensions.get( 'ANGLE_instanced_arrays' );
27050
27051 extension.vertexAttribDivisorANGLE( attribute, 0 );
27052 attributeDivisors[ attribute ] = 0;
27053
27054 }
27055
27056 };
27057
27058 this.enableAttributeAndDivisor = function ( attribute, meshPerAttribute, extension ) {
27059
27060 newAttributes[ attribute ] = 1;
27061
27062 if ( enabledAttributes[ attribute ] === 0 ) {
27063
27064 gl.enableVertexAttribArray( attribute );
27065 enabledAttributes[ attribute ] = 1;
27066
27067 }
27068
27069 if ( attributeDivisors[ attribute ] !== meshPerAttribute ) {
27070
27071 extension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );
27072 attributeDivisors[ attribute ] = meshPerAttribute;
27073
27074 }
27075
27076 };
27077
27078 this.disableUnusedAttributes = function () {
27079
27080 for ( var i = 0, l = enabledAttributes.length; i < l; i ++ ) {
27081
27082 if ( enabledAttributes[ i ] !== newAttributes[ i ] ) {
27083
27084 gl.disableVertexAttribArray( i );
27085 enabledAttributes[ i ] = 0;
27086
27087 }
27088
27089 }
27090
27091 };
27092
27093 this.enable = function ( id ) {
27094
27095 if ( capabilities[ id ] !== true ) {
27096
27097 gl.enable( id );
27098 capabilities[ id ] = true;
27099
27100 }
27101
27102 };
27103
27104 this.disable = function ( id ) {
27105
27106 if ( capabilities[ id ] !== false ) {
27107
27108 gl.disable( id );
27109 capabilities[ id ] = false;
27110
27111 }
27112
27113 };
27114
27115 this.getCompressedTextureFormats = function () {
27116
27117 if ( compressedTextureFormats === null ) {
27118
27119 compressedTextureFormats = [];
27120
27121 if ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||
27122 extensions.get( 'WEBGL_compressed_texture_s3tc' ) ) {
27123
27124 var formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );
27125
27126 for ( var i = 0; i < formats.length; i ++ ) {
27127
27128 compressedTextureFormats.push( formats[ i ] );
27129
27130 }
27131
27132 }
27133
27134 }
27135
27136 return compressedTextureFormats;
27137
27138 };
27139
27140 this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha ) {
27141
27142 if ( blending !== currentBlending ) {
27143
27144 if ( blending === THREE.NoBlending ) {
27145
27146 this.disable( gl.BLEND );
27147
27148 } else if ( blending === THREE.AdditiveBlending ) {
27149
27150 this.enable( gl.BLEND );
27151 gl.blendEquation( gl.FUNC_ADD );
27152 gl.blendFunc( gl.SRC_ALPHA, gl.ONE );
27153
27154 } else if ( blending === THREE.SubtractiveBlending ) {
27155
27156
27157
27158 this.enable( gl.BLEND );
27159 gl.blendEquation( gl.FUNC_ADD );
27160 gl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );
27161
27162 } else if ( blending === THREE.MultiplyBlending ) {
27163
27164
27165
27166 this.enable( gl.BLEND );
27167 gl.blendEquation( gl.FUNC_ADD );
27168 gl.blendFunc( gl.ZERO, gl.SRC_COLOR );
27169
27170 } else if ( blending === THREE.CustomBlending ) {
27171
27172 this.enable( gl.BLEND );
27173
27174 } else {
27175
27176 this.enable( gl.BLEND );
27177 gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );
27178 gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );
27179
27180 }
27181
27182 currentBlending = blending;
27183
27184 }
27185
27186 if ( blending === THREE.CustomBlending ) {
27187
27188 blendEquationAlpha = blendEquationAlpha || blendEquation;
27189 blendSrcAlpha = blendSrcAlpha || blendSrc;
27190 blendDstAlpha = blendDstAlpha || blendDst;
27191
27192 if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {
27193
27194 gl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );
27195
27196 currentBlendEquation = blendEquation;
27197 currentBlendEquationAlpha = blendEquationAlpha;
27198
27199 }
27200
27201 if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {
27202
27203 gl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );
27204
27205 currentBlendSrc = blendSrc;
27206 currentBlendDst = blendDst;
27207 currentBlendSrcAlpha = blendSrcAlpha;
27208 currentBlendDstAlpha = blendDstAlpha;
27209
27210 }
27211
27212 } else {
27213
27214 currentBlendEquation = null;
27215 currentBlendSrc = null;
27216 currentBlendDst = null;
27217 currentBlendEquationAlpha = null;
27218 currentBlendSrcAlpha = null;
27219 currentBlendDstAlpha = null;
27220
27221 }
27222
27223 };
27224
27225 this.setDepthFunc = function ( depthFunc ) {
27226
27227 if ( currentDepthFunc !== depthFunc ) {
27228
27229 if ( depthFunc ) {
27230
27231 switch ( depthFunc ) {
27232
27233 case THREE.NeverDepth:
27234
27235 gl.depthFunc( gl.NEVER );
27236 break;
27237
27238 case THREE.AlwaysDepth:
27239
27240 gl.depthFunc( gl.ALWAYS );
27241 break;
27242
27243 case THREE.LessDepth:
27244
27245 gl.depthFunc( gl.LESS );
27246 break;
27247
27248 case THREE.LessEqualDepth:
27249
27250 gl.depthFunc( gl.LEQUAL );
27251 break;
27252
27253 case THREE.EqualDepth:
27254
27255 gl.depthFunc( gl.EQUAL );
27256 break;
27257
27258 case THREE.GreaterEqualDepth:
27259
27260 gl.depthFunc( gl.GEQUAL );
27261 break;
27262
27263 case THREE.GreaterDepth:
27264
27265 gl.depthFunc( gl.GREATER );
27266 break;
27267
27268 case THREE.NotEqualDepth:
27269
27270 gl.depthFunc( gl.NOTEQUAL );
27271 break;
27272
27273 default:
27274
27275 gl.depthFunc( gl.LEQUAL );
27276
27277 }
27278
27279 } else {
27280
27281 gl.depthFunc( gl.LEQUAL );
27282
27283 }
27284
27285 currentDepthFunc = depthFunc;
27286
27287 }
27288
27289 };
27290
27291 this.setDepthTest = function ( depthTest ) {
27292
27293 if ( depthTest ) {
27294
27295 this.enable( gl.DEPTH_TEST );
27296
27297 } else {
27298
27299 this.disable( gl.DEPTH_TEST );
27300
27301 }
27302
27303 };
27304
27305 this.setDepthWrite = function ( depthWrite ) {
27306
27307 if ( currentDepthWrite !== depthWrite ) {
27308
27309 gl.depthMask( depthWrite );
27310 currentDepthWrite = depthWrite;
27311
27312 }
27313
27314 };
27315
27316 this.setColorWrite = function ( colorWrite ) {
27317
27318 if ( currentColorWrite !== colorWrite ) {
27319
27320 gl.colorMask( colorWrite, colorWrite, colorWrite, colorWrite );
27321 currentColorWrite = colorWrite;
27322
27323 }
27324
27325 };
27326
27327 this.setFlipSided = function ( flipSided ) {
27328
27329 if ( currentFlipSided !== flipSided ) {
27330
27331 if ( flipSided ) {
27332
27333 gl.frontFace( gl.CW );
27334
27335 } else {
27336
27337 gl.frontFace( gl.CCW );
27338
27339 }
27340
27341 currentFlipSided = flipSided;
27342
27343 }
27344
27345 };
27346
27347 this.setLineWidth = function ( width ) {
27348
27349 if ( width !== currentLineWidth ) {
27350
27351 gl.lineWidth( width );
27352
27353 currentLineWidth = width;
27354
27355 }
27356
27357 };
27358
27359 this.setPolygonOffset = function ( polygonOffset, factor, units ) {
27360
27361 if ( polygonOffset ) {
27362
27363 this.enable( gl.POLYGON_OFFSET_FILL );
27364
27365 } else {
27366
27367 this.disable( gl.POLYGON_OFFSET_FILL );
27368
27369 }
27370
27371 if ( polygonOffset && ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) ) {
27372
27373 gl.polygonOffset( factor, units );
27374
27375 currentPolygonOffsetFactor = factor;
27376 currentPolygonOffsetUnits = units;
27377
27378 }
27379
27380 };
27381
27382 this.setScissorTest = function ( scissorTest ) {
27383
27384 if ( scissorTest ) {
27385
27386 this.enable( gl.SCISSOR_TEST );
27387
27388 } else {
27389
27390 this.disable( gl.SCISSOR_TEST );
27391
27392 }
27393
27394 };
27395
27396
27397
27398 this.activeTexture = function ( webglSlot ) {
27399
27400 if ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;
27401
27402 if ( currentTextureSlot !== webglSlot ) {
27403
27404 gl.activeTexture( webglSlot );
27405 currentTextureSlot = webglSlot;
27406
27407 }
27408
27409 }
27410
27411 this.bindTexture = function ( webglType, webglTexture ) {
27412
27413 if ( currentTextureSlot === undefined ) {
27414
27415 _this.activeTexture();
27416
27417 }
27418
27419 var boundTexture = currentBoundTextures[ currentTextureSlot ];
27420
27421 if ( boundTexture === undefined ) {
27422
27423 boundTexture = { type: undefined, texture: undefined };
27424 currentBoundTextures[ currentTextureSlot ] = boundTexture;
27425
27426 }
27427
27428 if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {
27429
27430 gl.bindTexture( webglType, webglTexture );
27431
27432 boundTexture.type = webglType;
27433 boundTexture.texture = webglTexture;
27434
27435 }
27436
27437 };
27438
27439 this.compressedTexImage2D = function () {
27440
27441 try {
27442
27443 gl.compressedTexImage2D.apply( gl, arguments );
27444
27445 } catch ( error ) {
27446
27447 console.error( error );
27448
27449 }
27450
27451 };
27452
27453 this.texImage2D = function () {
27454
27455 try {
27456
27457 gl.texImage2D.apply( gl, arguments );
27458
27459 } catch ( error ) {
27460
27461 console.error( error );
27462
27463 }
27464
27465 };
27466
27467
27468
27469 this.reset = function () {
27470
27471 for ( var i = 0; i < enabledAttributes.length; i ++ ) {
27472
27473 if ( enabledAttributes[ i ] === 1 ) {
27474
27475 gl.disableVertexAttribArray( i );
27476 enabledAttributes[ i ] = 0;
27477
27478 }
27479
27480 }
27481
27482 capabilities = {};
27483
27484 compressedTextureFormats = null;
27485
27486 currentBlending = null;
27487
27488 currentDepthWrite = null;
27489 currentColorWrite = null;
27490
27491 currentFlipSided = null;
27492
27493 };
27494
27495 };
27496
27497
27498
27504 THREE.LensFlarePlugin = function ( renderer, flares ) {
27505
27506 var gl = renderer.context;
27507 var state = renderer.state;
27508
27509 var vertexBuffer, elementBuffer;
27510 var program, attributes, uniforms;
27511 var hasVertexTexture;
27512
27513 var tempTexture, occlusionTexture;
27514
27515 function init() {
27516
27517 var vertices = new Float32Array( [
27518 - 1, - 1, 0, 0,
27519 1, - 1, 1, 0,
27520 1, 1, 1, 1,
27521 - 1, 1, 0, 1
27522 ] );
27523
27524 var faces = new Uint16Array( [
27525 0, 1, 2,
27526 0, 2, 3
27527 ] );
27528
27529
27530
27531 vertexBuffer = gl.createBuffer();
27532 elementBuffer = gl.createBuffer();
27533
27534 gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
27535 gl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );
27536
27537 gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
27538 gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );
27539
27540
27541
27542 tempTexture = gl.createTexture();
27543 occlusionTexture = gl.createTexture();
27544
27545 state.bindTexture( gl.TEXTURE_2D, tempTexture );
27546 gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );
27547 gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );
27548 gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );
27549 gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
27550 gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
27551
27552 state.bindTexture( gl.TEXTURE_2D, occlusionTexture );
27553 gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );
27554 gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );
27555 gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );
27556 gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
27557 gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
27558
27559 hasVertexTexture = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ) > 0;
27560
27561 var shader;
27562
27563 if ( hasVertexTexture ) {
27564
27565 shader = {
27566
27567 vertexShader: [
27568
27569 "uniform lowp int renderType;",
27570
27571 "uniform vec3 screenPosition;",
27572 "uniform vec2 scale;",
27573 "uniform float rotation;",
27574
27575 "uniform sampler2D occlusionMap;",
27576
27577 "attribute vec2 position;",
27578 "attribute vec2 uv;",
27579
27580 "varying vec2 vUV;",
27581 "varying float vVisibility;",
27582
27583 "void main() {",
27584
27585 "vUV = uv;",
27586
27587 "vec2 pos = position;",
27588
27589 "if ( renderType == 2 ) {",
27590
27591 "vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );",
27592 "visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );",
27593 "visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );",
27594 "visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );",
27595 "visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );",
27596 "visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );",
27597 "visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );",
27598 "visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );",
27599 "visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );",
27600
27601 "vVisibility = visibility.r / 9.0;",
27602 "vVisibility *= 1.0 - visibility.g / 9.0;",
27603 "vVisibility *= visibility.b / 9.0;",
27604 "vVisibility *= 1.0 - visibility.a / 9.0;",
27605
27606 "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
27607 "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
27608
27609 "}",
27610
27611 "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );",
27612
27613 "}"
27614
27615 ].join( "\n" ),
27616
27617 fragmentShader: [
27618
27619 "uniform lowp int renderType;",
27620
27621 "uniform sampler2D map;",
27622 "uniform float opacity;",
27623 "uniform vec3 color;",
27624
27625 "varying vec2 vUV;",
27626 "varying float vVisibility;",
27627
27628 "void main() {",
27629
27630
27631
27632 "if ( renderType == 0 ) {",
27633
27634 "gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );",
27635
27636
27637
27638 "} else if ( renderType == 1 ) {",
27639
27640 "gl_FragColor = texture2D( map, vUV );",
27641
27642
27643
27644 "} else {",
27645
27646 "vec4 texture = texture2D( map, vUV );",
27647 "texture.a *= opacity * vVisibility;",
27648 "gl_FragColor = texture;",
27649 "gl_FragColor.rgb *= color;",
27650
27651 "}",
27652
27653 "}"
27654
27655 ].join( "\n" )
27656
27657 };
27658
27659 } else {
27660
27661 shader = {
27662
27663 vertexShader: [
27664
27665 "uniform lowp int renderType;",
27666
27667 "uniform vec3 screenPosition;",
27668 "uniform vec2 scale;",
27669 "uniform float rotation;",
27670
27671 "attribute vec2 position;",
27672 "attribute vec2 uv;",
27673
27674 "varying vec2 vUV;",
27675
27676 "void main() {",
27677
27678 "vUV = uv;",
27679
27680 "vec2 pos = position;",
27681
27682 "if ( renderType == 2 ) {",
27683
27684 "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
27685 "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
27686
27687 "}",
27688
27689 "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );",
27690
27691 "}"
27692
27693 ].join( "\n" ),
27694
27695 fragmentShader: [
27696
27697 "precision mediump float;",
27698
27699 "uniform lowp int renderType;",
27700
27701 "uniform sampler2D map;",
27702 "uniform sampler2D occlusionMap;",
27703 "uniform float opacity;",
27704 "uniform vec3 color;",
27705
27706 "varying vec2 vUV;",
27707
27708 "void main() {",
27709
27710
27711
27712 "if ( renderType == 0 ) {",
27713
27714 "gl_FragColor = vec4( texture2D( map, vUV ).rgb, 0.0 );",
27715
27716
27717
27718 "} else if ( renderType == 1 ) {",
27719
27720 "gl_FragColor = texture2D( map, vUV );",
27721
27722
27723
27724 "} else {",
27725
27726 "float visibility = texture2D( occlusionMap, vec2( 0.5, 0.1 ) ).a;",
27727 "visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) ).a;",
27728 "visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) ).a;",
27729 "visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) ).a;",
27730 "visibility = ( 1.0 - visibility / 4.0 );",
27731
27732 "vec4 texture = texture2D( map, vUV );",
27733 "texture.a *= opacity * visibility;",
27734 "gl_FragColor = texture;",
27735 "gl_FragColor.rgb *= color;",
27736
27737 "}",
27738
27739 "}"
27740
27741 ].join( "\n" )
27742
27743 };
27744
27745 }
27746
27747 program = createProgram( shader );
27748
27749 attributes = {
27750 vertex: gl.getAttribLocation ( program, "position" ),
27751 uv: gl.getAttribLocation ( program, "uv" )
27752 };
27753
27754 uniforms = {
27755 renderType: gl.getUniformLocation( program, "renderType" ),
27756 map: gl.getUniformLocation( program, "map" ),
27757 occlusionMap: gl.getUniformLocation( program, "occlusionMap" ),
27758 opacity: gl.getUniformLocation( program, "opacity" ),
27759 color: gl.getUniformLocation( program, "color" ),
27760 scale: gl.getUniformLocation( program, "scale" ),
27761 rotation: gl.getUniformLocation( program, "rotation" ),
27762 screenPosition: gl.getUniformLocation( program, "screenPosition" )
27763 };
27764
27765 }
27766
27767
27768
27769
27770
27771
27772
27773 this.render = function ( scene, camera, viewportWidth, viewportHeight ) {
27774
27775 if ( flares.length === 0 ) return;
27776
27777 var tempPosition = new THREE.Vector3();
27778
27779 var invAspect = viewportHeight / viewportWidth,
27780 halfViewportWidth = viewportWidth * 0.5,
27781 halfViewportHeight = viewportHeight * 0.5;
27782
27783 var size = 16 / viewportHeight,
27784 scale = new THREE.Vector2( size * invAspect, size );
27785
27786 var screenPosition = new THREE.Vector3( 1, 1, 0 ),
27787 screenPositionPixels = new THREE.Vector2( 1, 1 );
27788
27789 if ( program === undefined ) {
27790
27791 init();
27792
27793 }
27794
27795 gl.useProgram( program );
27796
27797 state.initAttributes();
27798 state.enableAttribute( attributes.vertex );
27799 state.enableAttribute( attributes.uv );
27800 state.disableUnusedAttributes();
27801
27802
27803
27804
27805 gl.uniform1i( uniforms.occlusionMap, 0 );
27806 gl.uniform1i( uniforms.map, 1 );
27807
27808 gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
27809 gl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );
27810 gl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );
27811
27812 gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
27813
27814 state.disable( gl.CULL_FACE );
27815 gl.depthMask( false );
27816
27817 for ( var i = 0, l = flares.length; i < l; i ++ ) {
27818
27819 size = 16 / viewportHeight;
27820 scale.set( size * invAspect, size );
27821
27822
27823
27824 var flare = flares[ i ];
27825
27826 tempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );
27827
27828 tempPosition.applyMatrix4( camera.matrixWorldInverse );
27829 tempPosition.applyProjection( camera.projectionMatrix );
27830
27831
27832
27833 screenPosition.copy( tempPosition );
27834
27835 screenPositionPixels.x = screenPosition.x * halfViewportWidth + halfViewportWidth;
27836 screenPositionPixels.y = screenPosition.y * halfViewportHeight + halfViewportHeight;
27837
27838
27839
27840 if ( hasVertexTexture || (
27841 screenPositionPixels.x > 0 &&
27842 screenPositionPixels.x < viewportWidth &&
27843 screenPositionPixels.y > 0 &&
27844 screenPositionPixels.y < viewportHeight ) ) {
27845
27846
27847
27848 state.activeTexture( gl.TEXTURE0 );
27849 state.bindTexture( gl.TEXTURE_2D, null );
27850 state.activeTexture( gl.TEXTURE1 );
27851 state.bindTexture( gl.TEXTURE_2D, tempTexture );
27852 gl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 );
27853
27854
27855
27856
27857 gl.uniform1i( uniforms.renderType, 0 );
27858 gl.uniform2f( uniforms.scale, scale.x, scale.y );
27859 gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
27860
27861 state.disable( gl.BLEND );
27862 state.enable( gl.DEPTH_TEST );
27863
27864 gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
27865
27866
27867
27868
27869 state.activeTexture( gl.TEXTURE0 );
27870 state.bindTexture( gl.TEXTURE_2D, occlusionTexture );
27871 gl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 );
27872
27873
27874
27875
27876 gl.uniform1i( uniforms.renderType, 1 );
27877 state.disable( gl.DEPTH_TEST );
27878
27879 state.activeTexture( gl.TEXTURE1 );
27880 state.bindTexture( gl.TEXTURE_2D, tempTexture );
27881 gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
27882
27883
27884
27885
27886 flare.positionScreen.copy( screenPosition );
27887
27888 if ( flare.customUpdateCallback ) {
27889
27890 flare.customUpdateCallback( flare );
27891
27892 } else {
27893
27894 flare.updateLensFlares();
27895
27896 }
27897
27898
27899
27900 gl.uniform1i( uniforms.renderType, 2 );
27901 state.enable( gl.BLEND );
27902
27903 for ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {
27904
27905 var sprite = flare.lensFlares[ j ];
27906
27907 if ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {
27908
27909 screenPosition.x = sprite.x;
27910 screenPosition.y = sprite.y;
27911 screenPosition.z = sprite.z;
27912
27913 size = sprite.size * sprite.scale / viewportHeight;
27914
27915 scale.x = size * invAspect;
27916 scale.y = size;
27917
27918 gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
27919 gl.uniform2f( uniforms.scale, scale.x, scale.y );
27920 gl.uniform1f( uniforms.rotation, sprite.rotation );
27921
27922 gl.uniform1f( uniforms.opacity, sprite.opacity );
27923 gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );
27924
27925 state.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );
27926 renderer.setTexture( sprite.texture, 1 );
27927
27928 gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
27929
27930 }
27931
27932 }
27933
27934 }
27935
27936 }
27937
27938
27939
27940 state.enable( gl.CULL_FACE );
27941 state.enable( gl.DEPTH_TEST );
27942 gl.depthMask( true );
27943
27944 renderer.resetGLState();
27945
27946 };
27947
27948 function createProgram ( shader ) {
27949
27950 var program = gl.createProgram();
27951
27952 var fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );
27953 var vertexShader = gl.createShader( gl.VERTEX_SHADER );
27954
27955 var prefix = "precision " + renderer.getPrecision() + " float;\n";
27956
27957 gl.shaderSource( fragmentShader, prefix + shader.fragmentShader );
27958 gl.shaderSource( vertexShader, prefix + shader.vertexShader );
27959
27960 gl.compileShader( fragmentShader );
27961 gl.compileShader( vertexShader );
27962
27963 gl.attachShader( program, fragmentShader );
27964 gl.attachShader( program, vertexShader );
27965
27966 gl.linkProgram( program );
27967
27968 return program;
27969
27970 }
27971
27972 };
27973
27974
27975
27981 THREE.SpritePlugin = function ( renderer, sprites ) {
27982
27983 var gl = renderer.context;
27984 var state = renderer.state;
27985
27986 var vertexBuffer, elementBuffer;
27987 var program, attributes, uniforms;
27988
27989 var texture;
27990
27991
27992
27993 var spritePosition = new THREE.Vector3();
27994 var spriteRotation = new THREE.Quaternion();
27995 var spriteScale = new THREE.Vector3();
27996
27997 function init() {
27998
27999 var vertices = new Float32Array( [
28000 - 0.5, - 0.5, 0, 0,
28001 0.5, - 0.5, 1, 0,
28002 0.5, 0.5, 1, 1,
28003 - 0.5, 0.5, 0, 1
28004 ] );
28005
28006 var faces = new Uint16Array( [
28007 0, 1, 2,
28008 0, 2, 3
28009 ] );
28010
28011 vertexBuffer = gl.createBuffer();
28012 elementBuffer = gl.createBuffer();
28013
28014 gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
28015 gl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );
28016
28017 gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
28018 gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );
28019
28020 program = createProgram();
28021
28022 attributes = {
28023 position: gl.getAttribLocation ( program, 'position' ),
28024 uv: gl.getAttribLocation ( program, 'uv' )
28025 };
28026
28027 uniforms = {
28028 uvOffset: gl.getUniformLocation( program, 'uvOffset' ),
28029 uvScale: gl.getUniformLocation( program, 'uvScale' ),
28030
28031 rotation: gl.getUniformLocation( program, 'rotation' ),
28032 scale: gl.getUniformLocation( program, 'scale' ),
28033
28034 color: gl.getUniformLocation( program, 'color' ),
28035 map: gl.getUniformLocation( program, 'map' ),
28036 opacity: gl.getUniformLocation( program, 'opacity' ),
28037
28038 modelViewMatrix: gl.getUniformLocation( program, 'modelViewMatrix' ),
28039 projectionMatrix: gl.getUniformLocation( program, 'projectionMatrix' ),
28040
28041 fogType: gl.getUniformLocation( program, 'fogType' ),
28042 fogDensity: gl.getUniformLocation( program, 'fogDensity' ),
28043 fogNear: gl.getUniformLocation( program, 'fogNear' ),
28044 fogFar: gl.getUniformLocation( program, 'fogFar' ),
28045 fogColor: gl.getUniformLocation( program, 'fogColor' ),
28046
28047 alphaTest: gl.getUniformLocation( program, 'alphaTest' )
28048 };
28049
28050 var canvas = document.createElement( 'canvas' );
28051 canvas.width = 8;
28052 canvas.height = 8;
28053
28054 var context = canvas.getContext( '2d' );
28055 context.fillStyle = 'white';
28056 context.fillRect( 0, 0, 8, 8 );
28057
28058 texture = new THREE.Texture( canvas );
28059 texture.needsUpdate = true;
28060
28061 }
28062
28063 this.render = function ( scene, camera ) {
28064
28065 if ( sprites.length === 0 ) return;
28066
28067
28068
28069 if ( program === undefined ) {
28070
28071 init();
28072
28073 }
28074
28075 gl.useProgram( program );
28076
28077 state.initAttributes();
28078 state.enableAttribute( attributes.position );
28079 state.enableAttribute( attributes.uv );
28080 state.disableUnusedAttributes();
28081
28082 state.disable( gl.CULL_FACE );
28083 state.enable( gl.BLEND );
28084
28085 gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
28086 gl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );
28087 gl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );
28088
28089 gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
28090
28091 gl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );
28092
28093 state.activeTexture( gl.TEXTURE0 );
28094 gl.uniform1i( uniforms.map, 0 );
28095
28096 var oldFogType = 0;
28097 var sceneFogType = 0;
28098 var fog = scene.fog;
28099
28100 if ( fog ) {
28101
28102 gl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );
28103
28104 if ( fog instanceof THREE.Fog ) {
28105
28106 gl.uniform1f( uniforms.fogNear, fog.near );
28107 gl.uniform1f( uniforms.fogFar, fog.far );
28108
28109 gl.uniform1i( uniforms.fogType, 1 );
28110 oldFogType = 1;
28111 sceneFogType = 1;
28112
28113 } else if ( fog instanceof THREE.FogExp2 ) {
28114
28115 gl.uniform1f( uniforms.fogDensity, fog.density );
28116
28117 gl.uniform1i( uniforms.fogType, 2 );
28118 oldFogType = 2;
28119 sceneFogType = 2;
28120
28121 }
28122
28123 } else {
28124
28125 gl.uniform1i( uniforms.fogType, 0 );
28126 oldFogType = 0;
28127 sceneFogType = 0;
28128
28129 }
28130
28131
28132
28133
28134 for ( var i = 0, l = sprites.length; i < l; i ++ ) {
28135
28136 var sprite = sprites[ i ];
28137
28138 sprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );
28139 sprite.z = - sprite.modelViewMatrix.elements[ 14 ];
28140
28141 }
28142
28143 sprites.sort( painterSortStable );
28144
28145
28146
28147 var scale = [];
28148
28149 for ( var i = 0, l = sprites.length; i < l; i ++ ) {
28150
28151 var sprite = sprites[ i ];
28152 var material = sprite.material;
28153
28154 gl.uniform1f( uniforms.alphaTest, material.alphaTest );
28155 gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );
28156
28157 sprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );
28158
28159 scale[ 0 ] = spriteScale.x;
28160 scale[ 1 ] = spriteScale.y;
28161
28162 var fogType = 0;
28163
28164 if ( scene.fog && material.fog ) {
28165
28166 fogType = sceneFogType;
28167
28168 }
28169
28170 if ( oldFogType !== fogType ) {
28171
28172 gl.uniform1i( uniforms.fogType, fogType );
28173 oldFogType = fogType;
28174
28175 }
28176
28177 if ( material.map !== null ) {
28178
28179 gl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );
28180 gl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );
28181
28182 } else {
28183
28184 gl.uniform2f( uniforms.uvOffset, 0, 0 );
28185 gl.uniform2f( uniforms.uvScale, 1, 1 );
28186
28187 }
28188
28189 gl.uniform1f( uniforms.opacity, material.opacity );
28190 gl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );
28191
28192 gl.uniform1f( uniforms.rotation, material.rotation );
28193 gl.uniform2fv( uniforms.scale, scale );
28194
28195 state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
28196 state.setDepthTest( material.depthTest );
28197 state.setDepthWrite( material.depthWrite );
28198
28199 if ( material.map && material.map.image && material.map.image.width ) {
28200
28201 renderer.setTexture( material.map, 0 );
28202
28203 } else {
28204
28205 renderer.setTexture( texture, 0 );
28206
28207 }
28208
28209 gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
28210
28211 }
28212
28213
28214
28215 state.enable( gl.CULL_FACE );
28216
28217 renderer.resetGLState();
28218
28219 };
28220
28221 function createProgram () {
28222
28223 var program = gl.createProgram();
28224
28225 var vertexShader = gl.createShader( gl.VERTEX_SHADER );
28226 var fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );
28227
28228 gl.shaderSource( vertexShader, [
28229
28230 'precision ' + renderer.getPrecision() + ' float;',
28231
28232 'uniform mat4 modelViewMatrix;',
28233 'uniform mat4 projectionMatrix;',
28234 'uniform float rotation;',
28235 'uniform vec2 scale;',
28236 'uniform vec2 uvOffset;',
28237 'uniform vec2 uvScale;',
28238
28239 'attribute vec2 position;',
28240 'attribute vec2 uv;',
28241
28242 'varying vec2 vUV;',
28243
28244 'void main() {',
28245
28246 'vUV = uvOffset + uv * uvScale;',
28247
28248 'vec2 alignedPosition = position * scale;',
28249
28250 'vec2 rotatedPosition;',
28251 'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',
28252 'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',
28253
28254 'vec4 finalPosition;',
28255
28256 'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',
28257 'finalPosition.xy += rotatedPosition;',
28258 'finalPosition = projectionMatrix * finalPosition;',
28259
28260 'gl_Position = finalPosition;',
28261
28262 '}'
28263
28264 ].join( '\n' ) );
28265
28266 gl.shaderSource( fragmentShader, [
28267
28268 'precision ' + renderer.getPrecision() + ' float;',
28269
28270 'uniform vec3 color;',
28271 'uniform sampler2D map;',
28272 'uniform float opacity;',
28273
28274 'uniform int fogType;',
28275 'uniform vec3 fogColor;',
28276 'uniform float fogDensity;',
28277 'uniform float fogNear;',
28278 'uniform float fogFar;',
28279 'uniform float alphaTest;',
28280
28281 'varying vec2 vUV;',
28282
28283 'void main() {',
28284
28285 'vec4 texture = texture2D( map, vUV );',
28286
28287 'if ( texture.a < alphaTest ) discard;',
28288
28289 'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',
28290
28291 'if ( fogType > 0 ) {',
28292
28293 'float depth = gl_FragCoord.z / gl_FragCoord.w;',
28294 'float fogFactor = 0.0;',
28295
28296 'if ( fogType == 1 ) {',
28297
28298 'fogFactor = smoothstep( fogNear, fogFar, depth );',
28299
28300 '} else {',
28301
28302 'const float LOG2 = 1.442695;',
28303 'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',
28304 'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',
28305
28306 '}',
28307
28308 'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',
28309
28310 '}',
28311
28312 '}'
28313
28314 ].join( '\n' ) );
28315
28316 gl.compileShader( vertexShader );
28317 gl.compileShader( fragmentShader );
28318
28319 gl.attachShader( program, vertexShader );
28320 gl.attachShader( program, fragmentShader );
28321
28322 gl.linkProgram( program );
28323
28324 return program;
28325
28326 }
28327
28328 function painterSortStable ( a, b ) {
28329
28330 if ( a.z !== b.z ) {
28331
28332 return b.z - a.z;
28333
28334 } else {
28335
28336 return b.id - a.id;
28337
28338 }
28339
28340 }
28341
28342 };
28343
28344
28345
28350 THREE.CurveUtils = {
28351
28352 tangentQuadraticBezier: function ( t, p0, p1, p2 ) {
28353
28354 return 2 * ( 1 - t ) * ( p1 - p0 ) + 2 * t * ( p2 - p1 );
28355
28356 },
28357
28358
28359
28360 tangentCubicBezier: function ( t, p0, p1, p2, p3 ) {
28361
28362 return - 3 * p0 * ( 1 - t ) * ( 1 - t ) +
28363 3 * p1 * ( 1 - t ) * ( 1 - t ) - 6 * t * p1 * ( 1 - t ) +
28364 6 * t * p2 * ( 1 - t ) - 3 * t * t * p2 +
28365 3 * t * t * p3;
28366
28367 },
28368
28369 tangentSpline: function ( t, p0, p1, p2, p3 ) {
28370
28371
28372
28373 var h00 = 6 * t * t - 6 * t;
28374 var h10 = 3 * t * t - 4 * t + 1;
28375 var h01 = - 6 * t * t + 6 * t;
28376 var h11 = 3 * t * t - 2 * t;
28377
28378 return h00 + h10 + h01 + h11;
28379
28380 },
28381
28382
28383
28384 interpolate: function( p0, p1, p2, p3, t ) {
28385
28386 var v0 = ( p2 - p0 ) * 0.5;
28387 var v1 = ( p3 - p1 ) * 0.5;
28388 var t2 = t * t;
28389 var t3 = t * t2;
28390 return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
28391
28392 }
28393
28394 };
28395
28396
28397
28402 THREE.GeometryUtils = {
28403
28404 merge: function ( geometry1, geometry2, materialIndexOffset ) {
28405
28406 console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );
28407
28408 var matrix;
28409
28410 if ( geometry2 instanceof THREE.Mesh ) {
28411
28412 geometry2.matrixAutoUpdate && geometry2.updateMatrix();
28413
28414 matrix = geometry2.matrix;
28415 geometry2 = geometry2.geometry;
28416
28417 }
28418
28419 geometry1.merge( geometry2, matrix, materialIndexOffset );
28420
28421 },
28422
28423 center: function ( geometry ) {
28424
28425 console.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );
28426 return geometry.center();
28427
28428 }
28429
28430 };
28431
28432
28433
28440 THREE.ImageUtils = {
28441
28442 crossOrigin: undefined,
28443
28444 loadTexture: function ( url, mapping, onLoad, onError ) {
28445
28446 console.warn( 'THREE.ImageUtils.loadTexture is being deprecated. Use THREE.TextureLoader() instead.' );
28447
28448 var loader = new THREE.TextureLoader();
28449 loader.setCrossOrigin( this.crossOrigin );
28450
28451 var texture = loader.load( url, onLoad, undefined, onError );
28452
28453 if ( mapping ) texture.mapping = mapping;
28454
28455 return texture;
28456
28457 },
28458
28459 loadTextureCube: function ( urls, mapping, onLoad, onError ) {
28460
28461 console.warn( 'THREE.ImageUtils.loadTextureCube is being deprecated. Use THREE.CubeTextureLoader() instead.' );
28462
28463 var loader = new THREE.CubeTextureLoader();
28464 loader.setCrossOrigin( this.crossOrigin );
28465
28466 var texture = loader.load( urls, onLoad, undefined, onError );
28467
28468 if ( mapping ) texture.mapping = mapping;
28469
28470 return texture;
28471
28472 },
28473
28474 loadCompressedTexture: function () {
28475
28476 console.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' )
28477
28478 },
28479
28480 loadCompressedTextureCube: function () {
28481
28482 console.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' )
28483
28484 }
28485
28486 };
28487
28488
28489
28494 THREE.SceneUtils = {
28495
28496 createMultiMaterialObject: function ( geometry, materials ) {
28497
28498 var group = new THREE.Group();
28499
28500 for ( var i = 0, l = materials.length; i < l; i ++ ) {
28501
28502 group.add( new THREE.Mesh( geometry, materials[ i ] ) );
28503
28504 }
28505
28506 return group;
28507
28508 },
28509
28510 detach: function ( child, parent, scene ) {
28511
28512 child.applyMatrix( parent.matrixWorld );
28513 parent.remove( child );
28514 scene.add( child );
28515
28516 },
28517
28518 attach: function ( child, scene, parent ) {
28519
28520 var matrixWorldInverse = new THREE.Matrix4();
28521 matrixWorldInverse.getInverse( parent.matrixWorld );
28522 child.applyMatrix( matrixWorldInverse );
28523
28524 scene.remove( child );
28525 parent.add( child );
28526
28527 }
28528
28529 };
28530
28531
28532
28537 THREE.ShapeUtils = {
28538
28539
28540
28541 area: function ( contour ) {
28542
28543 var n = contour.length;
28544 var a = 0.0;
28545
28546 for ( var p = n - 1, q = 0; q < n; p = q ++ ) {
28547
28548 a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;
28549
28550 }
28551
28552 return a * 0.5;
28553
28554 },
28555
28556 triangulate: ( function () {
28557
28572 function snip( contour, u, v, w, n, verts ) {
28573
28574 var p;
28575 var ax, ay, bx, by;
28576 var cx, cy, px, py;
28577
28578 ax = contour[ verts[ u ] ].x;
28579 ay = contour[ verts[ u ] ].y;
28580
28581 bx = contour[ verts[ v ] ].x;
28582 by = contour[ verts[ v ] ].y;
28583
28584 cx = contour[ verts[ w ] ].x;
28585 cy = contour[ verts[ w ] ].y;
28586
28587 if ( Number.EPSILON > ( ( ( bx - ax ) * ( cy - ay ) ) - ( ( by - ay ) * ( cx - ax ) ) ) ) return false;
28588
28589 var aX, aY, bX, bY, cX, cY;
28590 var apx, apy, bpx, bpy, cpx, cpy;
28591 var cCROSSap, bCROSScp, aCROSSbp;
28592
28593 aX = cx - bx; aY = cy - by;
28594 bX = ax - cx; bY = ay - cy;
28595 cX = bx - ax; cY = by - ay;
28596
28597 for ( p = 0; p < n; p ++ ) {
28598
28599 px = contour[ verts[ p ] ].x;
28600 py = contour[ verts[ p ] ].y;
28601
28602 if ( ( ( px === ax ) && ( py === ay ) ) ||
28603 ( ( px === bx ) && ( py === by ) ) ||
28604 ( ( px === cx ) && ( py === cy ) ) ) continue;
28605
28606 apx = px - ax; apy = py - ay;
28607 bpx = px - bx; bpy = py - by;
28608 cpx = px - cx; cpy = py - cy;
28609
28610
28611
28612 aCROSSbp = aX * bpy - aY * bpx;
28613 cCROSSap = cX * apy - cY * apx;
28614 bCROSScp = bX * cpy - bY * cpx;
28615
28616 if ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;
28617
28618 }
28619
28620 return true;
28621
28622 }
28623
28624
28625
28626 return function ( contour, indices ) {
28627
28628 var n = contour.length;
28629
28630 if ( n < 3 ) return null;
28631
28632 var result = [],
28633 verts = [],
28634 vertIndices = [];
28635
28636
28637
28638 var u, v, w;
28639
28640 if ( THREE.ShapeUtils.area( contour ) > 0.0 ) {
28641
28642 for ( v = 0; v < n; v ++ ) verts[ v ] = v;
28643
28644 } else {
28645
28646 for ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;
28647
28648 }
28649
28650 var nv = n;
28651
28652
28653
28654 var count = 2 * nv;
28655
28656 for ( v = nv - 1; nv > 2; ) {
28657
28658
28659
28660 if ( ( count -- ) <= 0 ) {
28661
28662
28663
28664
28665
28666
28667 console.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );
28668
28669 if ( indices ) return vertIndices;
28670 return result;
28671
28672 }
28673
28674
28675
28676 u = v; if ( nv <= u ) u = 0;
28677 v = u + 1; if ( nv <= v ) v = 0;
28678 w = v + 1; if ( nv <= w ) w = 0;
28679
28680 if ( snip( contour, u, v, w, nv, verts ) ) {
28681
28682 var a, b, c, s, t;
28683
28684
28685
28686 a = verts[ u ];
28687 b = verts[ v ];
28688 c = verts[ w ];
28689
28690
28691
28692 result.push( [ contour[ a ],
28693 contour[ b ],
28694 contour[ c ] ] );
28695
28696
28697 vertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );
28698
28699
28700
28701 for ( s = v, t = v + 1; t < nv; s ++, t ++ ) {
28702
28703 verts[ s ] = verts[ t ];
28704
28705 }
28706
28707 nv --;
28708
28709
28710
28711 count = 2 * nv;
28712
28713 }
28714
28715 }
28716
28717 if ( indices ) return vertIndices;
28718 return result;
28719
28720 }
28721
28722 } )(),
28723
28724 triangulateShape: function ( contour, holes ) {
28725
28726 function point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {
28727
28728
28729 if ( inSegPt1.x !== inSegPt2.x ) {
28730
28731 if ( inSegPt1.x < inSegPt2.x ) {
28732
28733 return ( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );
28734
28735 } else {
28736
28737 return ( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );
28738
28739 }
28740
28741 } else {
28742
28743 if ( inSegPt1.y < inSegPt2.y ) {
28744
28745 return ( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );
28746
28747 } else {
28748
28749 return ( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );
28750
28751 }
28752
28753 }
28754
28755 }
28756
28757 function intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {
28758
28759 var seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;
28760 var seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;
28761
28762 var seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;
28763 var seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;
28764
28765 var limit = seg1dy * seg2dx - seg1dx * seg2dy;
28766 var perpSeg1 = seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;
28767
28768 if ( Math.abs( limit ) > Number.EPSILON ) {
28769
28770
28771
28772 var perpSeg2;
28773 if ( limit > 0 ) {
28774
28775 if ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) return [];
28776 perpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;
28777 if ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) return [];
28778
28779 } else {
28780
28781 if ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) return [];
28782 perpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;
28783 if ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) return [];
28784
28785 }
28786
28787
28788
28789 if ( perpSeg2 === 0 ) {
28790
28791 if ( ( inExcludeAdjacentSegs ) &&
28792 ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) ) return [];
28793 return [ inSeg1Pt1 ];
28794
28795 }
28796 if ( perpSeg2 === limit ) {
28797
28798 if ( ( inExcludeAdjacentSegs ) &&
28799 ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) ) return [];
28800 return [ inSeg1Pt2 ];
28801
28802 }
28803
28804 if ( perpSeg1 === 0 ) return [ inSeg2Pt1 ];
28805 if ( perpSeg1 === limit ) return [ inSeg2Pt2 ];
28806
28807
28808 var factorSeg1 = perpSeg2 / limit;
28809 return [ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,
28810 y: inSeg1Pt1.y + factorSeg1 * seg1dy } ];
28811
28812 } else {
28813
28814
28815 if ( ( perpSeg1 !== 0 ) ||
28816 ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) return [];
28817
28818
28819 var seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );
28820 var seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );
28821
28822 if ( seg1Pt && seg2Pt ) {
28823
28824 if ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||
28825 ( inSeg1Pt1.y !== inSeg2Pt1.y ) ) return [];
28826 return [ inSeg1Pt1 ];
28827
28828 }
28829
28830 if ( seg1Pt ) {
28831
28832 if ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) ) return [];
28833 return [ inSeg1Pt1 ];
28834
28835 }
28836
28837 if ( seg2Pt ) {
28838
28839 if ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) ) return [];
28840 return [ inSeg2Pt1 ];
28841
28842 }
28843
28844
28845 var seg1min, seg1max, seg1minVal, seg1maxVal;
28846 var seg2min, seg2max, seg2minVal, seg2maxVal;
28847 if ( seg1dx !== 0 ) {
28848
28849
28850 if ( inSeg1Pt1.x < inSeg1Pt2.x ) {
28851
28852 seg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;
28853 seg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;
28854
28855 } else {
28856
28857 seg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;
28858 seg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;
28859
28860 }
28861 if ( inSeg2Pt1.x < inSeg2Pt2.x ) {
28862
28863 seg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;
28864 seg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;
28865
28866 } else {
28867
28868 seg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;
28869 seg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;
28870
28871 }
28872
28873 } else {
28874
28875
28876 if ( inSeg1Pt1.y < inSeg1Pt2.y ) {
28877
28878 seg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;
28879 seg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;
28880
28881 } else {
28882
28883 seg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;
28884 seg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;
28885
28886 }
28887 if ( inSeg2Pt1.y < inSeg2Pt2.y ) {
28888
28889 seg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;
28890 seg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;
28891
28892 } else {
28893
28894 seg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;
28895 seg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;
28896
28897 }
28898
28899 }
28900 if ( seg1minVal <= seg2minVal ) {
28901
28902 if ( seg1maxVal < seg2minVal ) return [];
28903 if ( seg1maxVal === seg2minVal ) {
28904
28905 if ( inExcludeAdjacentSegs ) return [];
28906 return [ seg2min ];
28907
28908 }
28909 if ( seg1maxVal <= seg2maxVal ) return [ seg2min, seg1max ];
28910 return [ seg2min, seg2max ];
28911
28912 } else {
28913
28914 if ( seg1minVal > seg2maxVal ) return [];
28915 if ( seg1minVal === seg2maxVal ) {
28916
28917 if ( inExcludeAdjacentSegs ) return [];
28918 return [ seg1min ];
28919
28920 }
28921 if ( seg1maxVal <= seg2maxVal ) return [ seg1min, seg1max ];
28922 return [ seg1min, seg2max ];
28923
28924 }
28925
28926 }
28927
28928 }
28929
28930 function isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {
28931
28932
28933
28934
28935 var legFromPtX = inLegFromPt.x - inVertex.x, legFromPtY = inLegFromPt.y - inVertex.y;
28936 var legToPtX = inLegToPt.x - inVertex.x, legToPtY = inLegToPt.y - inVertex.y;
28937 var otherPtX = inOtherPt.x - inVertex.x, otherPtY = inOtherPt.y - inVertex.y;
28938
28939
28940 var from2toAngle = legFromPtX * legToPtY - legFromPtY * legToPtX;
28941 var from2otherAngle = legFromPtX * otherPtY - legFromPtY * otherPtX;
28942
28943 if ( Math.abs( from2toAngle ) > Number.EPSILON ) {
28944
28945
28946
28947 var other2toAngle = otherPtX * legToPtY - otherPtY * legToPtX;
28948
28949
28950 if ( from2toAngle > 0 ) {
28951
28952
28953 return ( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );
28954
28955 } else {
28956
28957
28958 return ( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );
28959
28960 }
28961
28962 } else {
28963
28964
28965
28966 return ( from2otherAngle > 0 );
28967
28968 }
28969
28970 }
28971
28972
28973 function removeHoles( contour, holes ) {
28974
28975 var shape = contour.concat();
28976 var hole;
28977
28978 function isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {
28979
28980
28981 var lastShapeIdx = shape.length - 1;
28982
28983 var prevShapeIdx = inShapeIdx - 1;
28984 if ( prevShapeIdx < 0 ) prevShapeIdx = lastShapeIdx;
28985
28986 var nextShapeIdx = inShapeIdx + 1;
28987 if ( nextShapeIdx > lastShapeIdx ) nextShapeIdx = 0;
28988
28989 var insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );
28990 if ( ! insideAngle ) {
28991
28992
28993 return false;
28994
28995 }
28996
28997
28998 var lastHoleIdx = hole.length - 1;
28999
29000 var prevHoleIdx = inHoleIdx - 1;
29001 if ( prevHoleIdx < 0 ) prevHoleIdx = lastHoleIdx;
29002
29003 var nextHoleIdx = inHoleIdx + 1;
29004 if ( nextHoleIdx > lastHoleIdx ) nextHoleIdx = 0;
29005
29006 insideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );
29007 if ( ! insideAngle ) {
29008
29009
29010 return false;
29011
29012 }
29013
29014 return true;
29015
29016 }
29017
29018 function intersectsShapeEdge( inShapePt, inHolePt ) {
29019
29020
29021 var sIdx, nextIdx, intersection;
29022 for ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {
29023
29024 nextIdx = sIdx + 1; nextIdx %= shape.length;
29025 intersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );
29026 if ( intersection.length > 0 ) return true;
29027
29028 }
29029
29030 return false;
29031
29032 }
29033
29034 var indepHoles = [];
29035
29036 function intersectsHoleEdge( inShapePt, inHolePt ) {
29037
29038
29039 var ihIdx, chkHole,
29040 hIdx, nextIdx, intersection;
29041 for ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {
29042
29043 chkHole = holes[ indepHoles[ ihIdx ]];
29044 for ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {
29045
29046 nextIdx = hIdx + 1; nextIdx %= chkHole.length;
29047 intersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );
29048 if ( intersection.length > 0 ) return true;
29049
29050 }
29051
29052 }
29053 return false;
29054
29055 }
29056
29057 var holeIndex, shapeIndex,
29058 shapePt, holePt,
29059 holeIdx, cutKey, failedCuts = [],
29060 tmpShape1, tmpShape2,
29061 tmpHole1, tmpHole2;
29062
29063 for ( var h = 0, hl = holes.length; h < hl; h ++ ) {
29064
29065 indepHoles.push( h );
29066
29067 }
29068
29069 var minShapeIndex = 0;
29070 var counter = indepHoles.length * 2;
29071 while ( indepHoles.length > 0 ) {
29072
29073 counter --;
29074 if ( counter < 0 ) {
29075
29076 console.log( "Infinite Loop! Holes left:" + indepHoles.length + ", Probably Hole outside Shape!" );
29077 break;
29078
29079 }
29080
29081
29082
29083 for ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {
29084
29085 shapePt = shape[ shapeIndex ];
29086 holeIndex = - 1;
29087
29088
29089 for ( var h = 0; h < indepHoles.length; h ++ ) {
29090
29091 holeIdx = indepHoles[ h ];
29092
29093
29094 cutKey = shapePt.x + ":" + shapePt.y + ":" + holeIdx;
29095 if ( failedCuts[ cutKey ] !== undefined ) continue;
29096
29097 hole = holes[ holeIdx ];
29098 for ( var h2 = 0; h2 < hole.length; h2 ++ ) {
29099
29100 holePt = hole[ h2 ];
29101 if ( ! isCutLineInsideAngles( shapeIndex, h2 ) ) continue;
29102 if ( intersectsShapeEdge( shapePt, holePt ) ) continue;
29103 if ( intersectsHoleEdge( shapePt, holePt ) ) continue;
29104
29105 holeIndex = h2;
29106 indepHoles.splice( h, 1 );
29107
29108 tmpShape1 = shape.slice( 0, shapeIndex + 1 );
29109 tmpShape2 = shape.slice( shapeIndex );
29110 tmpHole1 = hole.slice( holeIndex );
29111 tmpHole2 = hole.slice( 0, holeIndex + 1 );
29112
29113 shape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );
29114
29115 minShapeIndex = shapeIndex;
29116
29117
29118
29119
29120 break;
29121
29122 }
29123 if ( holeIndex >= 0 ) break;
29124
29125 failedCuts[ cutKey ] = true;
29126
29127 }
29128 if ( holeIndex >= 0 ) break;
29129
29130 }
29131
29132 }
29133
29134 return shape;
29135
29136 }
29137
29138
29139 var i, il, f, face,
29140 key, index,
29141 allPointsMap = {};
29142
29143
29144
29145 var allpoints = contour.concat();
29146
29147 for ( var h = 0, hl = holes.length; h < hl; h ++ ) {
29148
29149 Array.prototype.push.apply( allpoints, holes[ h ] );
29150
29151 }
29152
29153
29154
29155
29156
29157 for ( i = 0, il = allpoints.length; i < il; i ++ ) {
29158
29159 key = allpoints[ i ].x + ":" + allpoints[ i ].y;
29160
29161 if ( allPointsMap[ key ] !== undefined ) {
29162
29163 console.warn( "THREE.Shape: Duplicate point", key );
29164
29165 }
29166
29167 allPointsMap[ key ] = i;
29168
29169 }
29170
29171
29172 var shapeWithoutHoles = removeHoles( contour, holes );
29173
29174 var triangles = THREE.ShapeUtils.triangulate( shapeWithoutHoles, false );
29175
29176
29177
29178
29179 for ( i = 0, il = triangles.length; i < il; i ++ ) {
29180
29181 face = triangles[ i ];
29182
29183 for ( f = 0; f < 3; f ++ ) {
29184
29185 key = face[ f ].x + ":" + face[ f ].y;
29186
29187 index = allPointsMap[ key ];
29188
29189 if ( index !== undefined ) {
29190
29191 face[ f ] = index;
29192
29193 }
29194
29195 }
29196
29197 }
29198
29199 return triangles.concat();
29200
29201 },
29202
29203 isClockWise: function ( pts ) {
29204
29205 return THREE.ShapeUtils.area( pts ) < 0;
29206
29207 },
29208
29209
29210
29211
29212
29213
29214 b2: ( function () {
29215
29216 function b2p0( t, p ) {
29217
29218 var k = 1 - t;
29219 return k * k * p;
29220
29221 }
29222
29223 function b2p1( t, p ) {
29224
29225 return 2 * ( 1 - t ) * t * p;
29226
29227 }
29228
29229 function b2p2( t, p ) {
29230
29231 return t * t * p;
29232
29233 }
29234
29235 return function ( t, p0, p1, p2 ) {
29236
29237 return b2p0( t, p0 ) + b2p1( t, p1 ) + b2p2( t, p2 );
29238
29239 };
29240
29241 } )(),
29242
29243
29244
29245 b3: ( function () {
29246
29247 function b3p0( t, p ) {
29248
29249 var k = 1 - t;
29250 return k * k * k * p;
29251
29252 }
29253
29254 function b3p1( t, p ) {
29255
29256 var k = 1 - t;
29257 return 3 * k * k * t * p;
29258
29259 }
29260
29261 function b3p2( t, p ) {
29262
29263 var k = 1 - t;
29264 return 3 * k * t * t * p;
29265
29266 }
29267
29268 function b3p3( t, p ) {
29269
29270 return t * t * t * p;
29271
29272 }
29273
29274 return function ( t, p0, p1, p2, p3 ) {
29275
29276 return b3p0( t, p0 ) + b3p1( t, p1 ) + b3p2( t, p2 ) + b3p3( t, p3 );
29277
29278 };
29279
29280 } )()
29281
29282 };
29283
29284
29285
29290 THREE.Audio = function ( listener ) {
29291
29292 THREE.Object3D.call( this );
29293
29294 this.type = 'Audio';
29295
29296 this.context = listener.context;
29297 this.source = this.context.createBufferSource();
29298 this.source.onended = this.onEnded.bind( this );
29299
29300 this.gain = this.context.createGain();
29301 this.gain.connect( this.context.destination );
29302
29303 this.panner = this.context.createPanner();
29304 this.panner.connect( this.gain );
29305
29306 this.autoplay = false;
29307
29308 this.startTime = 0;
29309 this.playbackRate = 1;
29310 this.isPlaying = false;
29311
29312 };
29313
29314 THREE.Audio.prototype = Object.create( THREE.Object3D.prototype );
29315 THREE.Audio.prototype.constructor = THREE.Audio;
29316
29317 THREE.Audio.prototype.load = function ( file ) {
29318
29319 var scope = this;
29320
29321 var request = new XMLHttpRequest();
29322 request.open( 'GET', file, true );
29323 request.responseType = 'arraybuffer';
29324 request.onload = function ( e ) {
29325
29326 scope.context.decodeAudioData( this.response, function ( buffer ) {
29327
29328 scope.source.buffer = buffer;
29329
29330 if ( scope.autoplay ) scope.play();
29331
29332 } );
29333
29334 };
29335 request.send();
29336
29337 return this;
29338
29339 };
29340
29341 THREE.Audio.prototype.play = function () {
29342
29343 if ( this.isPlaying === true ) {
29344
29345 console.warn( 'THREE.Audio: Audio is already playing.' );
29346 return;
29347
29348 }
29349
29350 var source = this.context.createBufferSource();
29351
29352 source.buffer = this.source.buffer;
29353 source.loop = this.source.loop;
29354 source.onended = this.source.onended;
29355 source.start( 0, this.startTime );
29356 source.playbackRate.value = this.playbackRate;
29357
29358 this.isPlaying = true;
29359
29360 this.source = source;
29361
29362 this.connect();
29363
29364 };
29365
29366 THREE.Audio.prototype.pause = function () {
29367
29368 this.source.stop();
29369 this.startTime = this.context.currentTime;
29370
29371 };
29372
29373 THREE.Audio.prototype.stop = function () {
29374
29375 this.source.stop();
29376 this.startTime = 0;
29377
29378 };
29379
29380 THREE.Audio.prototype.connect = function () {
29381
29382 if ( this.filter !== undefined ) {
29383
29384 this.source.connect( this.filter );
29385 this.filter.connect( this.panner );
29386
29387 } else {
29388
29389 this.source.connect( this.panner );
29390
29391 }
29392
29393 };
29394
29395 THREE.Audio.prototype.disconnect = function () {
29396
29397 if ( this.filter !== undefined ) {
29398
29399 this.source.disconnect( this.filter );
29400 this.filter.disconnect( this.panner );
29401
29402 } else {
29403
29404 this.source.disconnect( this.panner );
29405
29406 }
29407
29408 };
29409
29410 THREE.Audio.prototype.setFilter = function ( value ) {
29411
29412 if ( this.isPlaying === true ) {
29413
29414 this.disconnect();
29415 this.filter = value;
29416 this.connect();
29417
29418 } else {
29419
29420 this.filter = value;
29421
29422 }
29423
29424 };
29425
29426 THREE.Audio.prototype.getFilter = function () {
29427
29428 return this.filter;
29429
29430 };
29431
29432 THREE.Audio.prototype.setPlaybackRate = function ( value ) {
29433
29434 this.playbackRate = value;
29435
29436 if ( this.isPlaying === true ) {
29437
29438 this.source.playbackRate.value = this.playbackRate;
29439
29440 }
29441
29442 };
29443
29444 THREE.Audio.prototype.getPlaybackRate = function () {
29445
29446 return this.playbackRate;
29447
29448 };
29449
29450 THREE.Audio.prototype.onEnded = function() {
29451
29452 this.isPlaying = false;
29453
29454 };
29455
29456 THREE.Audio.prototype.setLoop = function ( value ) {
29457
29458 this.source.loop = value;
29459
29460 };
29461
29462 THREE.Audio.prototype.getLoop = function () {
29463
29464 return this.source.loop;
29465
29466 };
29467
29468 THREE.Audio.prototype.setRefDistance = function ( value ) {
29469
29470 this.panner.refDistance = value;
29471
29472 };
29473
29474 THREE.Audio.prototype.getRefDistance = function () {
29475
29476 return this.panner.refDistance;
29477
29478 };
29479
29480 THREE.Audio.prototype.setRolloffFactor = function ( value ) {
29481
29482 this.panner.rolloffFactor = value;
29483
29484 };
29485
29486 THREE.Audio.prototype.getRolloffFactor = function () {
29487
29488 return this.panner.rolloffFactor;
29489
29490 };
29491
29492 THREE.Audio.prototype.setVolume = function ( value ) {
29493
29494 this.gain.gain.value = value;
29495
29496 };
29497
29498 THREE.Audio.prototype.getVolume = function () {
29499
29500 return this.gain.gain.value;
29501
29502 };
29503
29504 THREE.Audio.prototype.updateMatrixWorld = ( function () {
29505
29506 var position = new THREE.Vector3();
29507
29508 return function updateMatrixWorld( force ) {
29509
29510 THREE.Object3D.prototype.updateMatrixWorld.call( this, force );
29511
29512 position.setFromMatrixPosition( this.matrixWorld );
29513
29514 this.panner.setPosition( position.x, position.y, position.z );
29515
29516 };
29517
29518 } )();
29519
29520
29521
29526 THREE.AudioListener = function () {
29527
29528 THREE.Object3D.call( this );
29529
29530 this.type = 'AudioListener';
29531
29532 this.context = new ( window.AudioContext || window.webkitAudioContext )();
29533
29534 };
29535
29536 THREE.AudioListener.prototype = Object.create( THREE.Object3D.prototype );
29537 THREE.AudioListener.prototype.constructor = THREE.AudioListener;
29538
29539 THREE.AudioListener.prototype.updateMatrixWorld = ( function () {
29540
29541 var position = new THREE.Vector3();
29542 var quaternion = new THREE.Quaternion();
29543 var scale = new THREE.Vector3();
29544
29545 var orientation = new THREE.Vector3();
29546
29547 return function updateMatrixWorld( force ) {
29548
29549 THREE.Object3D.prototype.updateMatrixWorld.call( this, force );
29550
29551 var listener = this.context.listener;
29552 var up = this.up;
29553
29554 this.matrixWorld.decompose( position, quaternion, scale );
29555
29556 orientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );
29557
29558 listener.setPosition( position.x, position.y, position.z );
29559 listener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );
29560
29561 };
29562
29563 } )();
29564
29565
29566
29599
29600
29601
29602
29603 THREE.Curve = function () {
29604
29605 };
29606
29607 THREE.Curve.prototype = {
29608
29609 constructor: THREE.Curve,
29610
29611
29612
29613
29614 getPoint: function ( t ) {
29615
29616 console.warn( "THREE.Curve: Warning, getPoint() not implemented!" );
29617 return null;
29618
29619 },
29620
29621
29622
29623
29624 getPointAt: function ( u ) {
29625
29626 var t = this.getUtoTmapping( u );
29627 return this.getPoint( t );
29628
29629 },
29630
29631
29632
29633 getPoints: function ( divisions ) {
29634
29635 if ( ! divisions ) divisions = 5;
29636
29637 var d, pts = [];
29638
29639 for ( d = 0; d <= divisions; d ++ ) {
29640
29641 pts.push( this.getPoint( d / divisions ) );
29642
29643 }
29644
29645 return pts;
29646
29647 },
29648
29649
29650
29651 getSpacedPoints: function ( divisions ) {
29652
29653 if ( ! divisions ) divisions = 5;
29654
29655 var d, pts = [];
29656
29657 for ( d = 0; d <= divisions; d ++ ) {
29658
29659 pts.push( this.getPointAt( d / divisions ) );
29660
29661 }
29662
29663 return pts;
29664
29665 },
29666
29667
29668
29669 getLength: function () {
29670
29671 var lengths = this.getLengths();
29672 return lengths[ lengths.length - 1 ];
29673
29674 },
29675
29676
29677
29678 getLengths: function ( divisions ) {
29679
29680 if ( ! divisions ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;
29681
29682 if ( this.cacheArcLengths
29683 && ( this.cacheArcLengths.length === divisions + 1 )
29684 && ! this.needsUpdate ) {
29685
29686
29687 return this.cacheArcLengths;
29688
29689 }
29690
29691 this.needsUpdate = false;
29692
29693 var cache = [];
29694 var current, last = this.getPoint( 0 );
29695 var p, sum = 0;
29696
29697 cache.push( 0 );
29698
29699 for ( p = 1; p <= divisions; p ++ ) {
29700
29701 current = this.getPoint ( p / divisions );
29702 sum += current.distanceTo( last );
29703 cache.push( sum );
29704 last = current;
29705
29706 }
29707
29708 this.cacheArcLengths = cache;
29709
29710 return cache;
29711
29712 },
29713
29714 updateArcLengths: function() {
29715
29716 this.needsUpdate = true;
29717 this.getLengths();
29718
29719 },
29720
29721
29722
29723 getUtoTmapping: function ( u, distance ) {
29724
29725 var arcLengths = this.getLengths();
29726
29727 var i = 0, il = arcLengths.length;
29728
29729 var targetArcLength;
29730
29731 if ( distance ) {
29732
29733 targetArcLength = distance;
29734
29735 } else {
29736
29737 targetArcLength = u * arcLengths[ il - 1 ];
29738
29739 }
29740
29741
29742
29743
29744
29745 var low = 0, high = il - 1, comparison;
29746
29747 while ( low <= high ) {
29748
29749 i = Math.floor( low + ( high - low ) / 2 );
29750
29751 comparison = arcLengths[ i ] - targetArcLength;
29752
29753 if ( comparison < 0 ) {
29754
29755 low = i + 1;
29756
29757 } else if ( comparison > 0 ) {
29758
29759 high = i - 1;
29760
29761 } else {
29762
29763 high = i;
29764 break;
29765
29766
29767
29768 }
29769
29770 }
29771
29772 i = high;
29773
29774
29775
29776 if ( arcLengths[ i ] === targetArcLength ) {
29777
29778 var t = i / ( il - 1 );
29779 return t;
29780
29781 }
29782
29783
29784
29785 var lengthBefore = arcLengths[ i ];
29786 var lengthAfter = arcLengths[ i + 1 ];
29787
29788 var segmentLength = lengthAfter - lengthBefore;
29789
29790
29791
29792 var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;
29793
29794
29795
29796 var t = ( i + segmentFraction ) / ( il - 1 );
29797
29798 return t;
29799
29800 },
29801
29802
29803
29804
29805
29806
29807 getTangent: function( t ) {
29808
29809 var delta = 0.0001;
29810 var t1 = t - delta;
29811 var t2 = t + delta;
29812
29813
29814
29815 if ( t1 < 0 ) t1 = 0;
29816 if ( t2 > 1 ) t2 = 1;
29817
29818 var pt1 = this.getPoint( t1 );
29819 var pt2 = this.getPoint( t2 );
29820
29821 var vec = pt2.clone().sub( pt1 );
29822 return vec.normalize();
29823
29824 },
29825
29826 getTangentAt: function ( u ) {
29827
29828 var t = this.getUtoTmapping( u );
29829 return this.getTangent( t );
29830
29831 }
29832
29833 }
29834
29835 THREE.Curve.Utils = THREE.CurveUtils;
29836
29837
29838
29839
29840
29841
29842
29843
29844
29845 THREE.Curve.create = function ( constructor, getPointFunc ) {
29846
29847 constructor.prototype = Object.create( THREE.Curve.prototype );
29848 constructor.prototype.constructor = constructor;
29849 constructor.prototype.getPoint = getPointFunc;
29850
29851 return constructor;
29852
29853 };
29854
29855
29856
29862
29863
29864
29865
29866
29867 THREE.CurvePath = function () {
29868
29869 this.curves = [];
29870
29871 this.autoClose = false;
29872
29873 };
29874
29875 THREE.CurvePath.prototype = Object.create( THREE.Curve.prototype );
29876 THREE.CurvePath.prototype.constructor = THREE.CurvePath;
29877
29878 THREE.CurvePath.prototype.add = function ( curve ) {
29879
29880 this.curves.push( curve );
29881
29882 };
29883
29884
29885
29886
29887
29888
29889
29890
29891
29892 THREE.CurvePath.prototype.closePath = function() {
29893
29894
29895
29896
29897 var startPoint = this.curves[ 0 ].getPoint( 0 );
29898 var endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );
29899
29900 if ( ! startPoint.equals( endPoint ) ) {
29901
29902 this.curves.push( new THREE.LineCurve( endPoint, startPoint ) );
29903
29904 }
29905
29906 };
29907
29908
29909
29910
29911
29912
29913
29914
29915
29916
29917 THREE.CurvePath.prototype.getPoint = function( t ) {
29918
29919 var d = t * this.getLength();
29920 var curveLengths = this.getCurveLengths();
29921 var i = 0;
29922
29923
29924
29925 while ( i < curveLengths.length ) {
29926
29927 if ( curveLengths[ i ] >= d ) {
29928
29929 var diff = curveLengths[ i ] - d;
29930 var curve = this.curves[ i ];
29931
29932 var u = 1 - diff / curve.getLength();
29933
29934 return curve.getPointAt( u );
29935
29936 }
29937
29938 i ++;
29939
29940 }
29941
29942 return null;
29943
29944
29945
29946 };
29947
29948
29949
29950
29951
29952
29953
29954
29955
29956
29957 THREE.CurvePath.prototype.getLength = function() {
29958
29959 var lens = this.getCurveLengths();
29960 return lens[ lens.length - 1 ];
29961
29962 };
29963
29964
29965
29966
29967 THREE.CurvePath.prototype.getCurveLengths = function() {
29968
29969
29970
29971 if ( this.cacheLengths && this.cacheLengths.length === this.curves.length ) {
29972
29973 return this.cacheLengths;
29974
29975 }
29976
29977
29978
29979
29980 var lengths = [], sums = 0;
29981
29982 for ( var i = 0, l = this.curves.length; i < l; i ++ ) {
29983
29984 sums += this.curves[ i ].getLength();
29985 lengths.push( sums );
29986
29987 }
29988
29989 this.cacheLengths = lengths;
29990
29991 return lengths;
29992
29993 };
29994
29995
29996
29997
29998
29999
30000
30002
30003 THREE.CurvePath.prototype.createPointsGeometry = function( divisions ) {
30004
30005 var pts = this.getPoints( divisions, true );
30006 return this.createGeometry( pts );
30007
30008 };
30009
30010
30011
30012 THREE.CurvePath.prototype.createSpacedPointsGeometry = function( divisions ) {
30013
30014 var pts = this.getSpacedPoints( divisions, true );
30015 return this.createGeometry( pts );
30016
30017 };
30018
30019 THREE.CurvePath.prototype.createGeometry = function( points ) {
30020
30021 var geometry = new THREE.Geometry();
30022
30023 for ( var i = 0, l = points.length; i < l; i ++ ) {
30024
30025 var point = points[ i ];
30026 geometry.vertices.push( new THREE.Vector3( point.x, point.y, point.z || 0 ) );
30027
30028 }
30029
30030 return geometry;
30031
30032 };
30033
30034
30035
30042 THREE.Path = function ( points ) {
30043
30044 THREE.CurvePath.call( this );
30045
30046 this.actions = [];
30047
30048 if ( points ) {
30049
30050 this.fromPoints( points );
30051
30052 }
30053
30054 };
30055
30056 THREE.Path.prototype = Object.create( THREE.CurvePath.prototype );
30057 THREE.Path.prototype.constructor = THREE.Path;
30058
30059
30060
30061
30062
30063
30064 THREE.Path.prototype.fromPoints = function ( vectors ) {
30065
30066 this.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );
30067
30068 for ( var i = 1, l = vectors.length; i < l; i ++ ) {
30069
30070 this.lineTo( vectors[ i ].x, vectors[ i ].y );
30071
30072 }
30073
30074 };
30075
30076
30077
30078 THREE.Path.prototype.moveTo = function ( x, y ) {
30079
30080 this.actions.push( { action: 'moveTo', args: [ x, y ] } );
30081
30082 };
30083
30084 THREE.Path.prototype.lineTo = function ( x, y ) {
30085
30086 var lastargs = this.actions[ this.actions.length - 1 ].args;
30087
30088 var x0 = lastargs[ lastargs.length - 2 ];
30089 var y0 = lastargs[ lastargs.length - 1 ];
30090
30091 var curve = new THREE.LineCurve( new THREE.Vector2( x0, y0 ), new THREE.Vector2( x, y ) );
30092 this.curves.push( curve );
30093
30094 this.actions.push( { action: 'lineTo', args: [ x, y ] } );
30095
30096 };
30097
30098 THREE.Path.prototype.quadraticCurveTo = function( aCPx, aCPy, aX, aY ) {
30099
30100 var lastargs = this.actions[ this.actions.length - 1 ].args;
30101
30102 var x0 = lastargs[ lastargs.length - 2 ];
30103 var y0 = lastargs[ lastargs.length - 1 ];
30104
30105 var curve = new THREE.QuadraticBezierCurve(
30106 new THREE.Vector2( x0, y0 ),
30107 new THREE.Vector2( aCPx, aCPy ),
30108 new THREE.Vector2( aX, aY )
30109 );
30110
30111 this.curves.push( curve );
30112
30113 this.actions.push( { action: 'quadraticCurveTo', args: [ aCPx, aCPy, aX, aY ] } );
30114
30115 };
30116
30117 THREE.Path.prototype.bezierCurveTo = function( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {
30118
30119 var lastargs = this.actions[ this.actions.length - 1 ].args;
30120
30121 var x0 = lastargs[ lastargs.length - 2 ];
30122 var y0 = lastargs[ lastargs.length - 1 ];
30123
30124 var curve = new THREE.CubicBezierCurve(
30125 new THREE.Vector2( x0, y0 ),
30126 new THREE.Vector2( aCP1x, aCP1y ),
30127 new THREE.Vector2( aCP2x, aCP2y ),
30128 new THREE.Vector2( aX, aY )
30129 );
30130
30131 this.curves.push( curve );
30132
30133 this.actions.push( { action: 'bezierCurveTo', args: [ aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ] } );
30134
30135 };
30136
30137 THREE.Path.prototype.splineThru = function( pts ) {
30138
30139 var args = Array.prototype.slice.call( arguments );
30140
30141 var lastargs = this.actions[ this.actions.length - 1 ].args;
30142
30143 var x0 = lastargs[ lastargs.length - 2 ];
30144 var y0 = lastargs[ lastargs.length - 1 ];
30145
30146 var npts = [ new THREE.Vector2( x0, y0 ) ];
30147 Array.prototype.push.apply( npts, pts );
30148
30149 var curve = new THREE.SplineCurve( npts );
30150 this.curves.push( curve );
30151
30152 this.actions.push( { action: 'splineThru', args: args } );
30153
30154 };
30155
30156
30157
30158 THREE.Path.prototype.arc = function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
30159
30160 var lastargs = this.actions[ this.actions.length - 1 ].args;
30161 var x0 = lastargs[ lastargs.length - 2 ];
30162 var y0 = lastargs[ lastargs.length - 1 ];
30163
30164 this.absarc( aX + x0, aY + y0, aRadius,
30165 aStartAngle, aEndAngle, aClockwise );
30166
30167 };
30168
30169 THREE.Path.prototype.absarc = function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
30170
30171 this.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
30172
30173 };
30174
30175 THREE.Path.prototype.ellipse = function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
30176
30177 var lastargs = this.actions[ this.actions.length - 1 ].args;
30178 var x0 = lastargs[ lastargs.length - 2 ];
30179 var y0 = lastargs[ lastargs.length - 1 ];
30180
30181 this.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );
30182
30183 };
30184
30185
30186 THREE.Path.prototype.absellipse = function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
30187
30188 var args = [
30189 aX, aY,
30190 xRadius, yRadius,
30191 aStartAngle, aEndAngle,
30192 aClockwise,
30193 aRotation || 0
30194 ];
30195
30196 var curve = new THREE.EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );
30197 this.curves.push( curve );
30198
30199 var lastPoint = curve.getPoint( 1 );
30200 args.push( lastPoint.x );
30201 args.push( lastPoint.y );
30202
30203 this.actions.push( { action: 'ellipse', args: args } );
30204
30205 };
30206
30207 THREE.Path.prototype.getSpacedPoints = function ( divisions, closedPath ) {
30208
30209 if ( ! divisions ) divisions = 40;
30210
30211 var points = [];
30212
30213 for ( var i = 0; i < divisions; i ++ ) {
30214
30215 points.push( this.getPoint( i / divisions ) );
30216
30217
30218
30219 }
30220
30221
30222
30223
30224
30225
30226
30227 return points;
30228
30229 };
30230
30231
30232
30233 THREE.Path.prototype.getPoints = function( divisions, closedPath ) {
30234
30235 divisions = divisions || 12;
30236
30237 var b2 = THREE.ShapeUtils.b2;
30238 var b3 = THREE.ShapeUtils.b3;
30239
30240 var points = [];
30241
30242 var cpx, cpy, cpx2, cpy2, cpx1, cpy1, cpx0, cpy0,
30243 laste, tx, ty;
30244
30245 for ( var i = 0, l = this.actions.length; i < l; i ++ ) {
30246
30247 var item = this.actions[ i ];
30248
30249 var action = item.action;
30250 var args = item.args;
30251
30252 switch ( action ) {
30253
30254 case 'moveTo':
30255
30256 points.push( new THREE.Vector2( args[ 0 ], args[ 1 ] ) );
30257
30258 break;
30259
30260 case 'lineTo':
30261
30262 points.push( new THREE.Vector2( args[ 0 ], args[ 1 ] ) );
30263
30264 break;
30265
30266 case 'quadraticCurveTo':
30267
30268 cpx = args[ 2 ];
30269 cpy = args[ 3 ];
30270
30271 cpx1 = args[ 0 ];
30272 cpy1 = args[ 1 ];
30273
30274 if ( points.length > 0 ) {
30275
30276 laste = points[ points.length - 1 ];
30277
30278 cpx0 = laste.x;
30279 cpy0 = laste.y;
30280
30281 } else {
30282
30283 laste = this.actions[ i - 1 ].args;
30284
30285 cpx0 = laste[ laste.length - 2 ];
30286 cpy0 = laste[ laste.length - 1 ];
30287
30288 }
30289
30290 for ( var j = 1; j <= divisions; j ++ ) {
30291
30292 var t = j / divisions;
30293
30294 tx = b2( t, cpx0, cpx1, cpx );
30295 ty = b2( t, cpy0, cpy1, cpy );
30296
30297 points.push( new THREE.Vector2( tx, ty ) );
30298
30299 }
30300
30301 break;
30302
30303 case 'bezierCurveTo':
30304
30305 cpx = args[ 4 ];
30306 cpy = args[ 5 ];
30307
30308 cpx1 = args[ 0 ];
30309 cpy1 = args[ 1 ];
30310
30311 cpx2 = args[ 2 ];
30312 cpy2 = args[ 3 ];
30313
30314 if ( points.length > 0 ) {
30315
30316 laste = points[ points.length - 1 ];
30317
30318 cpx0 = laste.x;
30319 cpy0 = laste.y;
30320
30321 } else {
30322
30323 laste = this.actions[ i - 1 ].args;
30324
30325 cpx0 = laste[ laste.length - 2 ];
30326 cpy0 = laste[ laste.length - 1 ];
30327
30328 }
30329
30330
30331 for ( var j = 1; j <= divisions; j ++ ) {
30332
30333 var t = j / divisions;
30334
30335 tx = b3( t, cpx0, cpx1, cpx2, cpx );
30336 ty = b3( t, cpy0, cpy1, cpy2, cpy );
30337
30338 points.push( new THREE.Vector2( tx, ty ) );
30339
30340 }
30341
30342 break;
30343
30344 case 'splineThru':
30345
30346 laste = this.actions[ i - 1 ].args;
30347
30348 var last = new THREE.Vector2( laste[ laste.length - 2 ], laste[ laste.length - 1 ] );
30349 var spts = [ last ];
30350
30351 var n = divisions * args[ 0 ].length;
30352
30353 spts = spts.concat( args[ 0 ] );
30354
30355 var spline = new THREE.SplineCurve( spts );
30356
30357 for ( var j = 1; j <= n; j ++ ) {
30358
30359 points.push( spline.getPointAt( j / n ) );
30360
30361 }
30362
30363 break;
30364
30365 case 'arc':
30366
30367 var aX = args[ 0 ], aY = args[ 1 ],
30368 aRadius = args[ 2 ],
30369 aStartAngle = args[ 3 ], aEndAngle = args[ 4 ],
30370 aClockwise = !! args[ 5 ];
30371
30372 var deltaAngle = aEndAngle - aStartAngle;
30373 var angle;
30374 var tdivisions = divisions * 2;
30375
30376 for ( var j = 1; j <= tdivisions; j ++ ) {
30377
30378 var t = j / tdivisions;
30379
30380 if ( ! aClockwise ) {
30381
30382 t = 1 - t;
30383
30384 }
30385
30386 angle = aStartAngle + t * deltaAngle;
30387
30388 tx = aX + aRadius * Math.cos( angle );
30389 ty = aY + aRadius * Math.sin( angle );
30390
30391
30392
30393 points.push( new THREE.Vector2( tx, ty ) );
30394
30395 }
30396
30397
30398
30399 break;
30400
30401 case 'ellipse':
30402
30403 var aX = args[ 0 ], aY = args[ 1 ],
30404 xRadius = args[ 2 ],
30405 yRadius = args[ 3 ],
30406 aStartAngle = args[ 4 ], aEndAngle = args[ 5 ],
30407 aClockwise = !! args[ 6 ],
30408 aRotation = args[ 7 ];
30409
30410
30411 var deltaAngle = aEndAngle - aStartAngle;
30412 var angle;
30413 var tdivisions = divisions * 2;
30414
30415 var cos, sin;
30416 if ( aRotation !== 0 ) {
30417
30418 cos = Math.cos( aRotation );
30419 sin = Math.sin( aRotation );
30420
30421 }
30422
30423 for ( var j = 1; j <= tdivisions; j ++ ) {
30424
30425 var t = j / tdivisions;
30426
30427 if ( ! aClockwise ) {
30428
30429 t = 1 - t;
30430
30431 }
30432
30433 angle = aStartAngle + t * deltaAngle;
30434
30435 tx = aX + xRadius * Math.cos( angle );
30436 ty = aY + yRadius * Math.sin( angle );
30437
30438 if ( aRotation !== 0 ) {
30439
30440 var x = tx, y = ty;
30441
30442
30443 tx = ( x - aX ) * cos - ( y - aY ) * sin + aX;
30444 ty = ( x - aX ) * sin + ( y - aY ) * cos + aY;
30445
30446 }
30447
30448
30449
30450 points.push( new THREE.Vector2( tx, ty ) );
30451
30452 }
30453
30454
30455
30456 break;
30457
30458 }
30459
30460 }
30461
30462
30463
30464
30465 var lastPoint = points[ points.length - 1 ];
30466 if ( Math.abs( lastPoint.x - points[ 0 ].x ) < Number.EPSILON &&
30467 Math.abs( lastPoint.y - points[ 0 ].y ) < Number.EPSILON )
30468 points.splice( points.length - 1, 1 );
30469 if ( closedPath ) {
30470
30471 points.push( points[ 0 ] );
30472
30473 }
30474
30475 return points;
30476
30477 };
30478
30479
30480
30481
30482
30483
30484
30485
30486
30487
30488
30489
30490
30491 THREE.Path.prototype.toShapes = function( isCCW, noHoles ) {
30492
30493 function extractSubpaths( inActions ) {
30494
30495 var subPaths = [], lastPath = new THREE.Path();
30496
30497 for ( var i = 0, l = inActions.length; i < l; i ++ ) {
30498
30499 var item = inActions[ i ];
30500
30501 var args = item.args;
30502 var action = item.action;
30503
30504 if ( action === 'moveTo' ) {
30505
30506 if ( lastPath.actions.length !== 0 ) {
30507
30508 subPaths.push( lastPath );
30509 lastPath = new THREE.Path();
30510
30511 }
30512
30513 }
30514
30515 lastPath[ action ].apply( lastPath, args );
30516
30517 }
30518
30519 if ( lastPath.actions.length !== 0 ) {
30520
30521 subPaths.push( lastPath );
30522
30523 }
30524
30525
30526
30527 return subPaths;
30528
30529 }
30530
30531 function toShapesNoHoles( inSubpaths ) {
30532
30533 var shapes = [];
30534
30535 for ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {
30536
30537 var tmpPath = inSubpaths[ i ];
30538
30539 var tmpShape = new THREE.Shape();
30540 tmpShape.actions = tmpPath.actions;
30541 tmpShape.curves = tmpPath.curves;
30542
30543 shapes.push( tmpShape );
30544
30545 }
30546
30547
30548
30549 return shapes;
30550
30551 }
30552
30553 function isPointInsidePolygon( inPt, inPolygon ) {
30554
30555 var polyLen = inPolygon.length;
30556
30557
30558
30559
30560
30561 var inside = false;
30562 for ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {
30563
30564 var edgeLowPt = inPolygon[ p ];
30565 var edgeHighPt = inPolygon[ q ];
30566
30567 var edgeDx = edgeHighPt.x - edgeLowPt.x;
30568 var edgeDy = edgeHighPt.y - edgeLowPt.y;
30569
30570 if ( Math.abs( edgeDy ) > Number.EPSILON ) {
30571
30572
30573 if ( edgeDy < 0 ) {
30574
30575 edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;
30576 edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;
30577
30578 }
30579 if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue;
30580
30581 if ( inPt.y === edgeLowPt.y ) {
30582
30583 if ( inPt.x === edgeLowPt.x ) return true;
30584
30585
30586 } else {
30587
30588 var perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );
30589 if ( perpEdge === 0 ) return true;
30590 if ( perpEdge < 0 ) continue;
30591 inside = ! inside;
30592
30593 }
30594
30595 } else {
30596
30597
30598 if ( inPt.y !== edgeLowPt.y ) continue;
30599
30600 if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||
30601 ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true;
30602
30603
30604 }
30605
30606 }
30607
30608 return inside;
30609
30610 }
30611
30612 var isClockWise = THREE.ShapeUtils.isClockWise;
30613
30614 var subPaths = extractSubpaths( this.actions );
30615 if ( subPaths.length === 0 ) return [];
30616
30617 if ( noHoles === true ) return toShapesNoHoles( subPaths );
30618
30619
30620 var solid, tmpPath, tmpShape, shapes = [];
30621
30622 if ( subPaths.length === 1 ) {
30623
30624 tmpPath = subPaths[ 0 ];
30625 tmpShape = new THREE.Shape();
30626 tmpShape.actions = tmpPath.actions;
30627 tmpShape.curves = tmpPath.curves;
30628 shapes.push( tmpShape );
30629 return shapes;
30630
30631 }
30632
30633 var holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );
30634 holesFirst = isCCW ? ! holesFirst : holesFirst;
30635
30636
30637
30638 var betterShapeHoles = [];
30639 var newShapes = [];
30640 var newShapeHoles = [];
30641 var mainIdx = 0;
30642 var tmpPoints;
30643
30644 newShapes[ mainIdx ] = undefined;
30645 newShapeHoles[ mainIdx ] = [];
30646
30647 for ( var i = 0, l = subPaths.length; i < l; i ++ ) {
30648
30649 tmpPath = subPaths[ i ];
30650 tmpPoints = tmpPath.getPoints();
30651 solid = isClockWise( tmpPoints );
30652 solid = isCCW ? ! solid : solid;
30653
30654 if ( solid ) {
30655
30656 if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++;
30657
30658 newShapes[ mainIdx ] = { s: new THREE.Shape(), p: tmpPoints };
30659 newShapes[ mainIdx ].s.actions = tmpPath.actions;
30660 newShapes[ mainIdx ].s.curves = tmpPath.curves;
30661
30662 if ( holesFirst ) mainIdx ++;
30663 newShapeHoles[ mainIdx ] = [];
30664
30665
30666
30667 } else {
30668
30669 newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );
30670
30671
30672
30673 }
30674
30675 }
30676
30677
30678 if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths );
30679
30680
30681 if ( newShapes.length > 1 ) {
30682
30683 var ambiguous = false;
30684 var toChange = [];
30685
30686 for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {
30687
30688 betterShapeHoles[ sIdx ] = [];
30689
30690 }
30691
30692 for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {
30693
30694 var sho = newShapeHoles[ sIdx ];
30695
30696 for ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {
30697
30698 var ho = sho[ hIdx ];
30699 var hole_unassigned = true;
30700
30701 for ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {
30702
30703 if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {
30704
30705 if ( sIdx !== s2Idx ) toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );
30706 if ( hole_unassigned ) {
30707
30708 hole_unassigned = false;
30709 betterShapeHoles[ s2Idx ].push( ho );
30710
30711 } else {
30712
30713 ambiguous = true;
30714
30715 }
30716
30717 }
30718
30719 }
30720 if ( hole_unassigned ) {
30721
30722 betterShapeHoles[ sIdx ].push( ho );
30723
30724 }
30725
30726 }
30727
30728 }
30729
30730 if ( toChange.length > 0 ) {
30731
30732
30733 if ( ! ambiguous ) newShapeHoles = betterShapeHoles;
30734
30735 }
30736
30737 }
30738
30739 var tmpHoles;
30740
30741 for ( var i = 0, il = newShapes.length; i < il; i ++ ) {
30742
30743 tmpShape = newShapes[ i ].s;
30744 shapes.push( tmpShape );
30745 tmpHoles = newShapeHoles[ i ];
30746
30747 for ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {
30748
30749 tmpShape.holes.push( tmpHoles[ j ].h );
30750
30751 }
30752
30753 }
30754
30755
30756
30757 return shapes;
30758
30759 };
30760
30761
30762
30768
30769
30770
30771
30772
30773
30774 THREE.Shape = function () {
30775
30776 THREE.Path.apply( this, arguments );
30777
30778 this.holes = [];
30779
30780 };
30781
30782 THREE.Shape.prototype = Object.create( THREE.Path.prototype );
30783 THREE.Shape.prototype.constructor = THREE.Shape;
30784
30785
30786
30787 THREE.Shape.prototype.extrude = function ( options ) {
30788
30789 return new THREE.ExtrudeGeometry( this, options );
30790
30791 };
30792
30793
30794
30795 THREE.Shape.prototype.makeGeometry = function ( options ) {
30796
30797 return new THREE.ShapeGeometry( this, options );
30798
30799 };
30800
30801
30802
30803 THREE.Shape.prototype.getPointsHoles = function ( divisions ) {
30804
30805 var holesPts = [];
30806
30807 for ( var i = 0, l = this.holes.length; i < l; i ++ ) {
30808
30809 holesPts[ i ] = this.holes[ i ].getPoints( divisions );
30810
30811 }
30812
30813 return holesPts;
30814
30815 };
30816
30817
30818
30819
30820 THREE.Shape.prototype.extractAllPoints = function ( divisions ) {
30821
30822 return {
30823
30824 shape: this.getPoints( divisions ),
30825 holes: this.getPointsHoles( divisions )
30826
30827 };
30828
30829 };
30830
30831 THREE.Shape.prototype.extractPoints = function ( divisions ) {
30832
30833 return this.extractAllPoints( divisions );
30834
30835 };
30836
30837 THREE.Shape.Utils = THREE.ShapeUtils;
30838
30839
30840
30841
30842
30843
30844
30845 THREE.LineCurve = function ( v1, v2 ) {
30846
30847 this.v1 = v1;
30848 this.v2 = v2;
30849
30850 };
30851
30852 THREE.LineCurve.prototype = Object.create( THREE.Curve.prototype );
30853 THREE.LineCurve.prototype.constructor = THREE.LineCurve;
30854
30855 THREE.LineCurve.prototype.getPoint = function ( t ) {
30856
30857 var point = this.v2.clone().sub( this.v1 );
30858 point.multiplyScalar( t ).add( this.v1 );
30859
30860 return point;
30861
30862 };
30863
30864
30865
30866 THREE.LineCurve.prototype.getPointAt = function ( u ) {
30867
30868 return this.getPoint( u );
30869
30870 };
30871
30872 THREE.LineCurve.prototype.getTangent = function( t ) {
30873
30874 var tangent = this.v2.clone().sub( this.v1 );
30875
30876 return tangent.normalize();
30877
30878 };
30879
30880
30881
30882
30883
30884
30885
30886
30887 THREE.QuadraticBezierCurve = function ( v0, v1, v2 ) {
30888
30889 this.v0 = v0;
30890 this.v1 = v1;
30891 this.v2 = v2;
30892
30893 };
30894
30895 THREE.QuadraticBezierCurve.prototype = Object.create( THREE.Curve.prototype );
30896 THREE.QuadraticBezierCurve.prototype.constructor = THREE.QuadraticBezierCurve;
30897
30898
30899 THREE.QuadraticBezierCurve.prototype.getPoint = function ( t ) {
30900
30901 var b2 = THREE.ShapeUtils.b2;
30902
30903 return new THREE.Vector2(
30904 b2( t, this.v0.x, this.v1.x, this.v2.x ),
30905 b2( t, this.v0.y, this.v1.y, this.v2.y )
30906 );
30907
30908 };
30909
30910
30911 THREE.QuadraticBezierCurve.prototype.getTangent = function( t ) {
30912
30913 var tangentQuadraticBezier = THREE.CurveUtils.tangentQuadraticBezier;
30914
30915 return new THREE.Vector2(
30916 tangentQuadraticBezier( t, this.v0.x, this.v1.x, this.v2.x ),
30917 tangentQuadraticBezier( t, this.v0.y, this.v1.y, this.v2.y )
30918 ).normalize();
30919
30920 };
30921
30922
30923
30924
30925
30926
30927
30928 THREE.CubicBezierCurve = function ( v0, v1, v2, v3 ) {
30929
30930 this.v0 = v0;
30931 this.v1 = v1;
30932 this.v2 = v2;
30933 this.v3 = v3;
30934
30935 };
30936
30937 THREE.CubicBezierCurve.prototype = Object.create( THREE.Curve.prototype );
30938 THREE.CubicBezierCurve.prototype.constructor = THREE.CubicBezierCurve;
30939
30940 THREE.CubicBezierCurve.prototype.getPoint = function ( t ) {
30941
30942 var b3 = THREE.ShapeUtils.b3;
30943
30944 return new THREE.Vector2(
30945 b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),
30946 b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y )
30947 );
30948
30949 };
30950
30951 THREE.CubicBezierCurve.prototype.getTangent = function( t ) {
30952
30953 var tangentCubicBezier = THREE.CurveUtils.tangentCubicBezier;
30954
30955 return new THREE.Vector2(
30956 tangentCubicBezier( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),
30957 tangentCubicBezier( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y )
30958 ).normalize();
30959
30960 };
30961
30962
30963
30964
30965
30966
30967
30968 THREE.SplineCurve = function ( points ) {
30969
30970 this.points = ( points == undefined ) ? [] : points;
30971
30972 };
30973
30974 THREE.SplineCurve.prototype = Object.create( THREE.Curve.prototype );
30975 THREE.SplineCurve.prototype.constructor = THREE.SplineCurve;
30976
30977 THREE.SplineCurve.prototype.getPoint = function ( t ) {
30978
30979 var points = this.points;
30980 var point = ( points.length - 1 ) * t;
30981
30982 var intPoint = Math.floor( point );
30983 var weight = point - intPoint;
30984
30985 var point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];
30986 var point1 = points[ intPoint ];
30987 var point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];
30988 var point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];
30989
30990 var interpolate = THREE.CurveUtils.interpolate;
30991
30992 return new THREE.Vector2(
30993 interpolate( point0.x, point1.x, point2.x, point3.x, weight ),
30994 interpolate( point0.y, point1.y, point2.y, point3.y, weight )
30995 );
30996
30997 };
30998
30999
31000
31001
31002
31003
31004
31005 THREE.EllipseCurve = function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
31006
31007 this.aX = aX;
31008 this.aY = aY;
31009
31010 this.xRadius = xRadius;
31011 this.yRadius = yRadius;
31012
31013 this.aStartAngle = aStartAngle;
31014 this.aEndAngle = aEndAngle;
31015
31016 this.aClockwise = aClockwise;
31017
31018 this.aRotation = aRotation || 0;
31019
31020 };
31021
31022 THREE.EllipseCurve.prototype = Object.create( THREE.Curve.prototype );
31023 THREE.EllipseCurve.prototype.constructor = THREE.EllipseCurve;
31024
31025 THREE.EllipseCurve.prototype.getPoint = function ( t ) {
31026
31027 var deltaAngle = this.aEndAngle - this.aStartAngle;
31028
31029 if ( deltaAngle < 0 ) deltaAngle += Math.PI * 2;
31030 if ( deltaAngle > Math.PI * 2 ) deltaAngle -= Math.PI * 2;
31031
31032 var angle;
31033
31034 if ( this.aClockwise === true ) {
31035
31036 angle = this.aEndAngle + ( 1 - t ) * ( Math.PI * 2 - deltaAngle );
31037
31038 } else {
31039
31040 angle = this.aStartAngle + t * deltaAngle;
31041
31042 }
31043
31044 var x = this.aX + this.xRadius * Math.cos( angle );
31045 var y = this.aY + this.yRadius * Math.sin( angle );
31046
31047 if ( this.aRotation !== 0 ) {
31048
31049 var cos = Math.cos( this.aRotation );
31050 var sin = Math.sin( this.aRotation );
31051
31052 var tx = x, ty = y;
31053
31054
31055 x = ( tx - this.aX ) * cos - ( ty - this.aY ) * sin + this.aX;
31056 y = ( tx - this.aX ) * sin + ( ty - this.aY ) * cos + this.aY;
31057
31058 }
31059
31060 return new THREE.Vector2( x, y );
31061
31062 };
31063
31064
31065
31066
31067
31068
31069
31070 THREE.ArcCurve = function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
31071
31072 THREE.EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
31073
31074 };
31075
31076 THREE.ArcCurve.prototype = Object.create( THREE.EllipseCurve.prototype );
31077 THREE.ArcCurve.prototype.constructor = THREE.ArcCurve;
31078
31079
31080
31081
31082
31083
31084
31085 THREE.LineCurve3 = THREE.Curve.create(
31086
31087 function ( v1, v2 ) {
31088
31089 this.v1 = v1;
31090 this.v2 = v2;
31091
31092 },
31093
31094 function ( t ) {
31095
31096 var vector = new THREE.Vector3();
31097
31098 vector.subVectors( this.v2, this.v1 );
31099 vector.multiplyScalar( t );
31100 vector.add( this.v1 );
31101
31102 return vector;
31103
31104 }
31105
31106 );
31107
31108
31109
31110
31111
31112
31113
31114 THREE.QuadraticBezierCurve3 = THREE.Curve.create(
31115
31116 function ( v0, v1, v2 ) {
31117
31118 this.v0 = v0;
31119 this.v1 = v1;
31120 this.v2 = v2;
31121
31122 },
31123
31124 function ( t ) {
31125
31126 var b2 = THREE.ShapeUtils.b2;
31127
31128 return new THREE.Vector3(
31129 b2( t, this.v0.x, this.v1.x, this.v2.x ),
31130 b2( t, this.v0.y, this.v1.y, this.v2.y ),
31131 b2( t, this.v0.z, this.v1.z, this.v2.z )
31132 );
31133
31134 }
31135
31136 );
31137
31138
31139
31140
31141
31142
31143
31144 THREE.CubicBezierCurve3 = THREE.Curve.create(
31145
31146 function ( v0, v1, v2, v3 ) {
31147
31148 this.v0 = v0;
31149 this.v1 = v1;
31150 this.v2 = v2;
31151 this.v3 = v3;
31152
31153 },
31154
31155 function ( t ) {
31156
31157 var b3 = THREE.ShapeUtils.b3;
31158
31159 return new THREE.Vector3(
31160 b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),
31161 b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y ),
31162 b3( t, this.v0.z, this.v1.z, this.v2.z, this.v3.z )
31163 );
31164
31165 }
31166
31167 );
31168
31169
31170
31171
31172
31173
31174
31175
31176 THREE.SplineCurve3 = THREE.Curve.create(
31177
31178 function ( points ) {
31179
31180 console.warn( 'THREE.SplineCurve3 will be deprecated. Please use THREE.CatmullRomCurve3' );
31181 this.points = ( points == undefined ) ? [] : points;
31182
31183 },
31184
31185 function ( t ) {
31186
31187 var points = this.points;
31188 var point = ( points.length - 1 ) * t;
31189
31190 var intPoint = Math.floor( point );
31191 var weight = point - intPoint;
31192
31193 var point0 = points[ intPoint == 0 ? intPoint : intPoint - 1 ];
31194 var point1 = points[ intPoint ];
31195 var point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];
31196 var point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];
31197
31198 var interpolate = THREE.CurveUtils.interpolate;
31199
31200 return new THREE.Vector3(
31201 interpolate( point0.x, point1.x, point2.x, point3.x, weight ),
31202 interpolate( point0.y, point1.y, point2.y, point3.y, weight ),
31203 interpolate( point0.z, point1.z, point2.z, point3.z, weight )
31204 );
31205
31206 }
31207
31208 );
31209
31210
31211
31223 THREE.CatmullRomCurve3 = ( function() {
31224
31225 var
31226 tmp = new THREE.Vector3(),
31227 px = new CubicPoly(),
31228 py = new CubicPoly(),
31229 pz = new CubicPoly();
31230
31231
31232
31233
31234
31235
31236
31237
31238
31239
31240
31241 function CubicPoly() {
31242
31243 }
31244
31245
31246
31247
31248
31249
31250
31251
31252
31253 CubicPoly.prototype.init = function( x0, x1, t0, t1 ) {
31254
31255 this.c0 = x0;
31256 this.c1 = t0;
31257 this.c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;
31258 this.c3 = 2 * x0 - 2 * x1 + t0 + t1;
31259
31260 };
31261
31262 CubicPoly.prototype.initNonuniformCatmullRom = function( x0, x1, x2, x3, dt0, dt1, dt2 ) {
31263
31264
31265 var t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;
31266 var t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;
31267
31268
31269 t1 *= dt1;
31270 t2 *= dt1;
31271
31272
31273 this.init( x1, x2, t1, t2 );
31274
31275 };
31276
31277
31278 CubicPoly.prototype.initCatmullRom = function( x0, x1, x2, x3, tension ) {
31279
31280 this.init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );
31281
31282 };
31283
31284 CubicPoly.prototype.calc = function( t ) {
31285
31286 var t2 = t * t;
31287 var t3 = t2 * t;
31288 return this.c0 + this.c1 * t + this.c2 * t2 + this.c3 * t3;
31289
31290 };
31291
31292
31293 return THREE.Curve.create(
31294
31295 function ( p ) {
31296
31297 this.points = p || [];
31298
31299 },
31300
31301 function ( t ) {
31302
31303 var points = this.points,
31304 point, intPoint, weight, l;
31305
31306 l = points.length;
31307
31308 if ( l < 2 ) console.log( 'duh, you need at least 2 points' );
31309
31310 point = ( l - 1 ) * t;
31311 intPoint = Math.floor( point );
31312 weight = point - intPoint;
31313
31314 if ( weight === 0 && intPoint === l - 1 ) {
31315
31316 intPoint = l - 2;
31317 weight = 1;
31318
31319 }
31320
31321 var p0, p1, p2, p3;
31322
31323 if ( intPoint === 0 ) {
31324
31325
31326 tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );
31327 p0 = tmp;
31328
31329 } else {
31330
31331 p0 = points[ intPoint - 1 ];
31332
31333 }
31334
31335 p1 = points[ intPoint ];
31336 p2 = points[ intPoint + 1 ];
31337
31338 if ( intPoint + 2 < l ) {
31339
31340 p3 = points[ intPoint + 2 ]
31341
31342 } else {
31343
31344
31345 tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 2 ] );
31346 p3 = tmp;
31347
31348 }
31349
31350 if ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {
31351
31352
31353 var pow = this.type === 'chordal' ? 0.5 : 0.25;
31354 var dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );
31355 var dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );
31356 var dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );
31357
31358
31359 if ( dt1 < 1e-4 ) dt1 = 1.0;
31360 if ( dt0 < 1e-4 ) dt0 = dt1;
31361 if ( dt2 < 1e-4 ) dt2 = dt1;
31362
31363 px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );
31364 py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );
31365 pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );
31366
31367 } else if ( this.type === 'catmullrom' ) {
31368
31369 var tension = this.tension !== undefined ? this.tension : 0.5;
31370 px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );
31371 py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );
31372 pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );
31373
31374 }
31375
31376 var v = new THREE.Vector3(
31377 px.calc( weight ),
31378 py.calc( weight ),
31379 pz.calc( weight )
31380 );
31381
31382 return v;
31383
31384 }
31385
31386 );
31387
31388 } )();
31389
31390
31391
31392
31393
31394
31395
31396
31397 THREE.ClosedSplineCurve3 = THREE.Curve.create(
31398
31399 function ( points ) {
31400
31401 this.points = ( points == undefined ) ? [] : points;
31402
31403 },
31404
31405 function ( t ) {
31406
31407 var points = this.points;
31408 var point = ( points.length - 0 ) * t;
31409
31410 var intPoint = Math.floor( point );
31411 var weight = point - intPoint;
31412
31413 intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;
31414
31415 var point0 = points[ ( intPoint - 1 ) % points.length ];
31416 var point1 = points[ ( intPoint ) % points.length ];
31417 var point2 = points[ ( intPoint + 1 ) % points.length ];
31418 var point3 = points[ ( intPoint + 2 ) % points.length ];
31419
31420 var interpolate = THREE.CurveUtils.interpolate;
31421
31422 return new THREE.Vector3(
31423 interpolate( point0.x, point1.x, point2.x, point3.x, weight ),
31424 interpolate( point0.y, point1.y, point2.y, point3.y, weight ),
31425 interpolate( point0.z, point1.z, point2.z, point3.z, weight )
31426 );
31427
31428 }
31429
31430 );
31431
31432
31433
31439 THREE.BoxGeometry = function ( width, height, depth, widthSegments, heightSegments, depthSegments ) {
31440
31441 THREE.Geometry.call( this );
31442
31443 this.type = 'BoxGeometry';
31444
31445 this.parameters = {
31446 width: width,
31447 height: height,
31448 depth: depth,
31449 widthSegments: widthSegments,
31450 heightSegments: heightSegments,
31451 depthSegments: depthSegments
31452 };
31453
31454 this.widthSegments = widthSegments || 1;
31455 this.heightSegments = heightSegments || 1;
31456 this.depthSegments = depthSegments || 1;
31457
31458 var scope = this;
31459
31460 var width_half = width / 2;
31461 var height_half = height / 2;
31462 var depth_half = depth / 2;
31463
31464 buildPlane( 'z', 'y', - 1, - 1, depth, height, width_half, 0 );
31465 buildPlane( 'z', 'y', 1, - 1, depth, height, - width_half, 1 );
31466 buildPlane( 'x', 'z', 1, 1, width, depth, height_half, 2 );
31467 buildPlane( 'x', 'z', 1, - 1, width, depth, - height_half, 3 );
31468 buildPlane( 'x', 'y', 1, - 1, width, height, depth_half, 4 );
31469 buildPlane( 'x', 'y', - 1, - 1, width, height, - depth_half, 5 );
31470
31471 function buildPlane( u, v, udir, vdir, width, height, depth, materialIndex ) {
31472
31473 var w, ix, iy,
31474 gridX = scope.widthSegments,
31475 gridY = scope.heightSegments,
31476 width_half = width / 2,
31477 height_half = height / 2,
31478 offset = scope.vertices.length;
31479
31480 if ( ( u === 'x' && v === 'y' ) || ( u === 'y' && v === 'x' ) ) {
31481
31482 w = 'z';
31483
31484 } else if ( ( u === 'x' && v === 'z' ) || ( u === 'z' && v === 'x' ) ) {
31485
31486 w = 'y';
31487 gridY = scope.depthSegments;
31488
31489 } else if ( ( u === 'z' && v === 'y' ) || ( u === 'y' && v === 'z' ) ) {
31490
31491 w = 'x';
31492 gridX = scope.depthSegments;
31493
31494 }
31495
31496 var gridX1 = gridX + 1,
31497 gridY1 = gridY + 1,
31498 segment_width = width / gridX,
31499 segment_height = height / gridY,
31500 normal = new THREE.Vector3();
31501
31502 normal[ w ] = depth > 0 ? 1 : - 1;
31503
31504 for ( iy = 0; iy < gridY1; iy ++ ) {
31505
31506 for ( ix = 0; ix < gridX1; ix ++ ) {
31507
31508 var vector = new THREE.Vector3();
31509 vector[ u ] = ( ix * segment_width - width_half ) * udir;
31510 vector[ v ] = ( iy * segment_height - height_half ) * vdir;
31511 vector[ w ] = depth;
31512
31513 scope.vertices.push( vector );
31514
31515 }
31516
31517 }
31518
31519 for ( iy = 0; iy < gridY; iy ++ ) {
31520
31521 for ( ix = 0; ix < gridX; ix ++ ) {
31522
31523 var a = ix + gridX1 * iy;
31524 var b = ix + gridX1 * ( iy + 1 );
31525 var c = ( ix + 1 ) + gridX1 * ( iy + 1 );
31526 var d = ( ix + 1 ) + gridX1 * iy;
31527
31528 var uva = new THREE.Vector2( ix / gridX, 1 - iy / gridY );
31529 var uvb = new THREE.Vector2( ix / gridX, 1 - ( iy + 1 ) / gridY );
31530 var uvc = new THREE.Vector2( ( ix + 1 ) / gridX, 1 - ( iy + 1 ) / gridY );
31531 var uvd = new THREE.Vector2( ( ix + 1 ) / gridX, 1 - iy / gridY );
31532
31533 var face = new THREE.Face3( a + offset, b + offset, d + offset );
31534 face.normal.copy( normal );
31535 face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() );
31536 face.materialIndex = materialIndex;
31537
31538 scope.faces.push( face );
31539 scope.faceVertexUvs[ 0 ].push( [ uva, uvb, uvd ] );
31540
31541 face = new THREE.Face3( b + offset, c + offset, d + offset );
31542 face.normal.copy( normal );
31543 face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() );
31544 face.materialIndex = materialIndex;
31545
31546 scope.faces.push( face );
31547 scope.faceVertexUvs[ 0 ].push( [ uvb.clone(), uvc, uvd.clone() ] );
31548
31549 }
31550
31551 }
31552
31553 }
31554
31555 this.mergeVertices();
31556
31557 };
31558
31559 THREE.BoxGeometry.prototype = Object.create( THREE.Geometry.prototype );
31560 THREE.BoxGeometry.prototype.constructor = THREE.BoxGeometry;
31561
31562 THREE.BoxGeometry.prototype.clone = function () {
31563
31564 var parameters = this.parameters;
31565
31566 return new THREE.BoxGeometry(
31567 parameters.width,
31568 parameters.height,
31569 parameters.depth,
31570 parameters.widthSegments,
31571 parameters.heightSegments,
31572 parameters.depthSegments
31573 );
31574
31575 };
31576
31577 THREE.CubeGeometry = THREE.BoxGeometry;
31578
31579
31580
31585 THREE.CircleGeometry = function ( radius, segments, thetaStart, thetaLength ) {
31586
31587 THREE.Geometry.call( this );
31588
31589 this.type = 'CircleGeometry';
31590
31591 this.parameters = {
31592 radius: radius,
31593 segments: segments,
31594 thetaStart: thetaStart,
31595 thetaLength: thetaLength
31596 };
31597
31598 this.fromBufferGeometry( new THREE.CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );
31599
31600 };
31601
31602 THREE.CircleGeometry.prototype = Object.create( THREE.Geometry.prototype );
31603 THREE.CircleGeometry.prototype.constructor = THREE.CircleGeometry;
31604
31605 THREE.CircleGeometry.prototype.clone = function () {
31606
31607 var parameters = this.parameters;
31608
31609 return new THREE.CircleGeometry(
31610 parameters.radius,
31611 parameters.segments,
31612 parameters.thetaStart,
31613 parameters.thetaLength
31614 );
31615
31616 };
31617
31618
31619
31624 THREE.CircleBufferGeometry = function ( radius, segments, thetaStart, thetaLength ) {
31625
31626 THREE.BufferGeometry.call( this );
31627
31628 this.type = 'CircleBufferGeometry';
31629
31630 this.parameters = {
31631 radius: radius,
31632 segments: segments,
31633 thetaStart: thetaStart,
31634 thetaLength: thetaLength
31635 };
31636
31637 radius = radius || 50;
31638 segments = segments !== undefined ? Math.max( 3, segments ) : 8;
31639
31640 thetaStart = thetaStart !== undefined ? thetaStart : 0;
31641 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
31642
31643 var vertices = segments + 2;
31644
31645 var positions = new Float32Array( vertices * 3 );
31646 var normals = new Float32Array( vertices * 3 );
31647 var uvs = new Float32Array( vertices * 2 );
31648
31649
31650 normals[ 2 ] = 1.0;
31651 uvs[ 0 ] = 0.5;
31652 uvs[ 1 ] = 0.5;
31653
31654 for ( var s = 0, i = 3, ii = 2 ; s <= segments; s ++, i += 3, ii += 2 ) {
31655
31656 var segment = thetaStart + s / segments * thetaLength;
31657
31658 positions[ i ] = radius * Math.cos( segment );
31659 positions[ i + 1 ] = radius * Math.sin( segment );
31660
31661 normals[ i + 2 ] = 1;
31662
31663 uvs[ ii ] = ( positions[ i ] / radius + 1 ) / 2;
31664 uvs[ ii + 1 ] = ( positions[ i + 1 ] / radius + 1 ) / 2;
31665
31666 }
31667
31668 var indices = [];
31669
31670 for ( var i = 1; i <= segments; i ++ ) {
31671
31672 indices.push( i, i + 1, 0 );
31673
31674 }
31675
31676 this.setIndex( new THREE.BufferAttribute( new Uint16Array( indices ), 1 ) );
31677 this.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
31678 this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
31679 this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
31680
31681 this.boundingSphere = new THREE.Sphere( new THREE.Vector3(), radius );
31682
31683 };
31684
31685 THREE.CircleBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
31686 THREE.CircleBufferGeometry.prototype.constructor = THREE.CircleBufferGeometry;
31687
31688 THREE.CircleBufferGeometry.prototype.clone = function () {
31689
31690 var parameters = this.parameters;
31691
31692 return new THREE.CircleBufferGeometry(
31693 parameters.radius,
31694 parameters.segments,
31695 parameters.thetaStart,
31696 parameters.thetaLength
31697 );
31698
31699 };
31700
31701
31702
31707 THREE.CylinderGeometry = function ( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
31708
31709 THREE.Geometry.call( this );
31710
31711 this.type = 'CylinderGeometry';
31712
31713 this.parameters = {
31714 radiusTop: radiusTop,
31715 radiusBottom: radiusBottom,
31716 height: height,
31717 radialSegments: radialSegments,
31718 heightSegments: heightSegments,
31719 openEnded: openEnded,
31720 thetaStart: thetaStart,
31721 thetaLength: thetaLength
31722 };
31723
31724 radiusTop = radiusTop !== undefined ? radiusTop : 20;
31725 radiusBottom = radiusBottom !== undefined ? radiusBottom : 20;
31726 height = height !== undefined ? height : 100;
31727
31728 radialSegments = radialSegments || 8;
31729 heightSegments = heightSegments || 1;
31730
31731 openEnded = openEnded !== undefined ? openEnded : false;
31732 thetaStart = thetaStart !== undefined ? thetaStart : 0;
31733 thetaLength = thetaLength !== undefined ? thetaLength : 2 * Math.PI;
31734
31735 var heightHalf = height / 2;
31736
31737 var x, y, vertices = [], uvs = [];
31738
31739 for ( y = 0; y <= heightSegments; y ++ ) {
31740
31741 var verticesRow = [];
31742 var uvsRow = [];
31743
31744 var v = y / heightSegments;
31745 var radius = v * ( radiusBottom - radiusTop ) + radiusTop;
31746
31747 for ( x = 0; x <= radialSegments; x ++ ) {
31748
31749 var u = x / radialSegments;
31750
31751 var vertex = new THREE.Vector3();
31752 vertex.x = radius * Math.sin( u * thetaLength + thetaStart );
31753 vertex.y = - v * height + heightHalf;
31754 vertex.z = radius * Math.cos( u * thetaLength + thetaStart );
31755
31756 this.vertices.push( vertex );
31757
31758 verticesRow.push( this.vertices.length - 1 );
31759 uvsRow.push( new THREE.Vector2( u, 1 - v ) );
31760
31761 }
31762
31763 vertices.push( verticesRow );
31764 uvs.push( uvsRow );
31765
31766 }
31767
31768 var tanTheta = ( radiusBottom - radiusTop ) / height;
31769 var na, nb;
31770
31771 for ( x = 0; x < radialSegments; x ++ ) {
31772
31773 if ( radiusTop !== 0 ) {
31774
31775 na = this.vertices[ vertices[ 0 ][ x ] ].clone();
31776 nb = this.vertices[ vertices[ 0 ][ x + 1 ] ].clone();
31777
31778 } else {
31779
31780 na = this.vertices[ vertices[ 1 ][ x ] ].clone();
31781 nb = this.vertices[ vertices[ 1 ][ x + 1 ] ].clone();
31782
31783 }
31784
31785 na.setY( Math.sqrt( na.x * na.x + na.z * na.z ) * tanTheta ).normalize();
31786 nb.setY( Math.sqrt( nb.x * nb.x + nb.z * nb.z ) * tanTheta ).normalize();
31787
31788 for ( y = 0; y < heightSegments; y ++ ) {
31789
31790 var v1 = vertices[ y ][ x ];
31791 var v2 = vertices[ y + 1 ][ x ];
31792 var v3 = vertices[ y + 1 ][ x + 1 ];
31793 var v4 = vertices[ y ][ x + 1 ];
31794
31795 var n1 = na.clone();
31796 var n2 = na.clone();
31797 var n3 = nb.clone();
31798 var n4 = nb.clone();
31799
31800 var uv1 = uvs[ y ][ x ].clone();
31801 var uv2 = uvs[ y + 1 ][ x ].clone();
31802 var uv3 = uvs[ y + 1 ][ x + 1 ].clone();
31803 var uv4 = uvs[ y ][ x + 1 ].clone();
31804
31805 this.faces.push( new THREE.Face3( v1, v2, v4, [ n1, n2, n4 ] ) );
31806 this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv4 ] );
31807
31808 this.faces.push( new THREE.Face3( v2, v3, v4, [ n2.clone(), n3, n4.clone() ] ) );
31809 this.faceVertexUvs[ 0 ].push( [ uv2.clone(), uv3, uv4.clone() ] );
31810
31811 }
31812
31813 }
31814
31815
31816
31817 if ( openEnded === false && radiusTop > 0 ) {
31818
31819 this.vertices.push( new THREE.Vector3( 0, heightHalf, 0 ) );
31820
31821 for ( x = 0; x < radialSegments; x ++ ) {
31822
31823 var v1 = vertices[ 0 ][ x ];
31824 var v2 = vertices[ 0 ][ x + 1 ];
31825 var v3 = this.vertices.length - 1;
31826
31827 var n1 = new THREE.Vector3( 0, 1, 0 );
31828 var n2 = new THREE.Vector3( 0, 1, 0 );
31829 var n3 = new THREE.Vector3( 0, 1, 0 );
31830
31831 var uv1 = uvs[ 0 ][ x ].clone();
31832 var uv2 = uvs[ 0 ][ x + 1 ].clone();
31833 var uv3 = new THREE.Vector2( uv2.x, 0 );
31834
31835 this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ], undefined, 1 ) );
31836 this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] );
31837
31838 }
31839
31840 }
31841
31842
31843
31844 if ( openEnded === false && radiusBottom > 0 ) {
31845
31846 this.vertices.push( new THREE.Vector3( 0, - heightHalf, 0 ) );
31847
31848 for ( x = 0; x < radialSegments; x ++ ) {
31849
31850 var v1 = vertices[ heightSegments ][ x + 1 ];
31851 var v2 = vertices[ heightSegments ][ x ];
31852 var v3 = this.vertices.length - 1;
31853
31854 var n1 = new THREE.Vector3( 0, - 1, 0 );
31855 var n2 = new THREE.Vector3( 0, - 1, 0 );
31856 var n3 = new THREE.Vector3( 0, - 1, 0 );
31857
31858 var uv1 = uvs[ heightSegments ][ x + 1 ].clone();
31859 var uv2 = uvs[ heightSegments ][ x ].clone();
31860 var uv3 = new THREE.Vector2( uv2.x, 1 );
31861
31862 this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ], undefined, 2 ) );
31863 this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] );
31864
31865 }
31866
31867 }
31868
31869 this.computeFaceNormals();
31870
31871 };
31872
31873 THREE.CylinderGeometry.prototype = Object.create( THREE.Geometry.prototype );
31874 THREE.CylinderGeometry.prototype.constructor = THREE.CylinderGeometry;
31875
31876 THREE.CylinderGeometry.prototype.clone = function () {
31877
31878 var parameters = this.parameters;
31879
31880 return new THREE.CylinderGeometry(
31881 parameters.radiusTop,
31882 parameters.radiusBottom,
31883 parameters.height,
31884 parameters.radialSegments,
31885 parameters.heightSegments,
31886 parameters.openEnded,
31887 parameters.thetaStart,
31888 parameters.thetaLength
31889 );
31890
31891 };
31892
31893
31894
31899 THREE.EdgesGeometry = function ( geometry, thresholdAngle ) {
31900
31901 THREE.BufferGeometry.call( this );
31902
31903 thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;
31904
31905 var thresholdDot = Math.cos( THREE.Math.degToRad( thresholdAngle ) );
31906
31907 var edge = [ 0, 0 ], hash = {};
31908
31909 function sortFunction( a, b ) {
31910
31911 return a - b;
31912
31913 }
31914
31915 var keys = [ 'a', 'b', 'c' ];
31916
31917 var geometry2;
31918
31919 if ( geometry instanceof THREE.BufferGeometry ) {
31920
31921 geometry2 = new THREE.Geometry();
31922 geometry2.fromBufferGeometry( geometry );
31923
31924 } else {
31925
31926 geometry2 = geometry.clone();
31927
31928 }
31929
31930 geometry2.mergeVertices();
31931 geometry2.computeFaceNormals();
31932
31933 var vertices = geometry2.vertices;
31934 var faces = geometry2.faces;
31935
31936 for ( var i = 0, l = faces.length; i < l; i ++ ) {
31937
31938 var face = faces[ i ];
31939
31940 for ( var j = 0; j < 3; j ++ ) {
31941
31942 edge[ 0 ] = face[ keys[ j ] ];
31943 edge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];
31944 edge.sort( sortFunction );
31945
31946 var key = edge.toString();
31947
31948 if ( hash[ key ] === undefined ) {
31949
31950 hash[ key ] = { vert1: edge[ 0 ], vert2: edge[ 1 ], face1: i, face2: undefined };
31951
31952 } else {
31953
31954 hash[ key ].face2 = i;
31955
31956 }
31957
31958 }
31959
31960 }
31961
31962 var coords = [];
31963
31964 for ( var key in hash ) {
31965
31966 var h = hash[ key ];
31967
31968 if ( h.face2 === undefined || faces[ h.face1 ].normal.dot( faces[ h.face2 ].normal ) <= thresholdDot ) {
31969
31970 var vertex = vertices[ h.vert1 ];
31971 coords.push( vertex.x );
31972 coords.push( vertex.y );
31973 coords.push( vertex.z );
31974
31975 vertex = vertices[ h.vert2 ];
31976 coords.push( vertex.x );
31977 coords.push( vertex.y );
31978 coords.push( vertex.z );
31979
31980 }
31981
31982 }
31983
31984 this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( coords ), 3 ) );
31985
31986 };
31987
31988 THREE.EdgesGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
31989 THREE.EdgesGeometry.prototype.constructor = THREE.EdgesGeometry;
31990
31991
31992
32017 THREE.ExtrudeGeometry = function ( shapes, options ) {
32018
32019 if ( typeof( shapes ) === "undefined" ) {
32020
32021 shapes = [];
32022 return;
32023
32024 }
32025
32026 THREE.Geometry.call( this );
32027
32028 this.type = 'ExtrudeGeometry';
32029
32030 shapes = Array.isArray( shapes ) ? shapes : [ shapes ];
32031
32032 this.addShapeList( shapes, options );
32033
32034 this.computeFaceNormals();
32035
32036
32037
32038
32039
32040
32041
32042
32043
32044 };
32045
32046 THREE.ExtrudeGeometry.prototype = Object.create( THREE.Geometry.prototype );
32047 THREE.ExtrudeGeometry.prototype.constructor = THREE.ExtrudeGeometry;
32048
32049 THREE.ExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {
32050
32051 var sl = shapes.length;
32052
32053 for ( var s = 0; s < sl; s ++ ) {
32054
32055 var shape = shapes[ s ];
32056 this.addShape( shape, options );
32057
32058 }
32059
32060 };
32061
32062 THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) {
32063
32064 var amount = options.amount !== undefined ? options.amount : 100;
32065
32066 var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6;
32067 var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2;
32068 var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
32069
32070 var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true;
32071
32072 var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
32073
32074 var steps = options.steps !== undefined ? options.steps : 1;
32075
32076 var extrudePath = options.extrudePath;
32077 var extrudePts, extrudeByPath = false;
32078
32079
32080 var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : THREE.ExtrudeGeometry.WorldUVGenerator;
32081
32082 var splineTube, binormal, normal, position2;
32083 if ( extrudePath ) {
32084
32085 extrudePts = extrudePath.getSpacedPoints( steps );
32086
32087 extrudeByPath = true;
32088 bevelEnabled = false;
32089
32090
32091
32092
32093
32094
32095 splineTube = options.frames !== undefined ? options.frames : new THREE.TubeGeometry.FrenetFrames( extrudePath, steps, false );
32096
32097
32098
32099 binormal = new THREE.Vector3();
32100 normal = new THREE.Vector3();
32101 position2 = new THREE.Vector3();
32102
32103 }
32104
32105
32106
32107 if ( ! bevelEnabled ) {
32108
32109 bevelSegments = 0;
32110 bevelThickness = 0;
32111 bevelSize = 0;
32112
32113 }
32114
32115
32116
32117 var ahole, h, hl;
32118 var scope = this;
32119
32120 var shapesOffset = this.vertices.length;
32121
32122 var shapePoints = shape.extractPoints( curveSegments );
32123
32124 var vertices = shapePoints.shape;
32125 var holes = shapePoints.holes;
32126
32127 var reverse = ! THREE.ShapeUtils.isClockWise( vertices );
32128
32129 if ( reverse ) {
32130
32131 vertices = vertices.reverse();
32132
32133
32134
32135 for ( h = 0, hl = holes.length; h < hl; h ++ ) {
32136
32137 ahole = holes[ h ];
32138
32139 if ( THREE.ShapeUtils.isClockWise( ahole ) ) {
32140
32141 holes[ h ] = ahole.reverse();
32142
32143 }
32144
32145 }
32146
32147 reverse = false;
32148
32149 }
32150
32151
32152 var faces = THREE.ShapeUtils.triangulateShape( vertices, holes );
32153
32154
32155
32156 var contour = vertices;
32157
32158 for ( h = 0, hl = holes.length; h < hl; h ++ ) {
32159
32160 ahole = holes[ h ];
32161
32162 vertices = vertices.concat( ahole );
32163
32164 }
32165
32166
32167 function scalePt2 ( pt, vec, size ) {
32168
32169 if ( ! vec ) console.error( "THREE.ExtrudeGeometry: vec does not exist" );
32170
32171 return vec.clone().multiplyScalar( size ).add( pt );
32172
32173 }
32174
32175 var b, bs, t, z,
32176 vert, vlen = vertices.length,
32177 face, flen = faces.length;
32178
32179
32180
32181
32182
32183 function getBevelVec( inPt, inPrev, inNext ) {
32184
32185
32186
32187
32188
32189
32190
32191
32192 var v_trans_x, v_trans_y, shrink_by = 1;
32193
32194
32195
32196
32197 var v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;
32198 var v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;
32199
32200 var v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );
32201
32202
32203 var collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );
32204
32205 if ( Math.abs( collinear0 ) > Number.EPSILON ) {
32206
32207
32208
32209
32210
32211 var v_prev_len = Math.sqrt( v_prev_lensq );
32212 var v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );
32213
32214
32215
32216 var ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );
32217 var ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );
32218
32219 var ptNextShift_x = ( inNext.x - v_next_y / v_next_len );
32220 var ptNextShift_y = ( inNext.y + v_next_x / v_next_len );
32221
32222
32223
32224 var sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -
32225 ( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /
32226 ( v_prev_x * v_next_y - v_prev_y * v_next_x );
32227
32228
32229
32230 v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );
32231 v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );
32232
32233
32234
32235 var v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );
32236 if ( v_trans_lensq <= 2 ) {
32237
32238 return new THREE.Vector2( v_trans_x, v_trans_y );
32239
32240 } else {
32241
32242 shrink_by = Math.sqrt( v_trans_lensq / 2 );
32243
32244 }
32245
32246 } else {
32247
32248
32249
32250 var direction_eq = false;
32251 if ( v_prev_x > Number.EPSILON ) {
32252
32253 if ( v_next_x > Number.EPSILON ) {
32254
32255 direction_eq = true;
32256
32257 }
32258
32259 } else {
32260
32261 if ( v_prev_x < - Number.EPSILON ) {
32262
32263 if ( v_next_x < - Number.EPSILON ) {
32264
32265 direction_eq = true;
32266
32267 }
32268
32269 } else {
32270
32271 if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {
32272
32273 direction_eq = true;
32274
32275 }
32276
32277 }
32278
32279 }
32280
32281 if ( direction_eq ) {
32282
32283
32284 v_trans_x = - v_prev_y;
32285 v_trans_y = v_prev_x;
32286 shrink_by = Math.sqrt( v_prev_lensq );
32287
32288 } else {
32289
32290
32291 v_trans_x = v_prev_x;
32292 v_trans_y = v_prev_y;
32293 shrink_by = Math.sqrt( v_prev_lensq / 2 );
32294
32295 }
32296
32297 }
32298
32299 return new THREE.Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );
32300
32301 }
32302
32303
32304 var contourMovements = [];
32305
32306 for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
32307
32308 if ( j === il ) j = 0;
32309 if ( k === il ) k = 0;
32310
32311
32312
32313
32314 contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );
32315
32316 }
32317
32318 var holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();
32319
32320 for ( h = 0, hl = holes.length; h < hl; h ++ ) {
32321
32322 ahole = holes[ h ];
32323
32324 oneHoleMovements = [];
32325
32326 for ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
32327
32328 if ( j === il ) j = 0;
32329 if ( k === il ) k = 0;
32330
32331
32332 oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );
32333
32334 }
32335
32336 holesMovements.push( oneHoleMovements );
32337 verticesMovements = verticesMovements.concat( oneHoleMovements );
32338
32339 }
32340
32341
32342
32343
32344 for ( b = 0; b < bevelSegments; b ++ ) {
32345
32346
32347
32348 t = b / bevelSegments;
32349 z = bevelThickness * ( 1 - t );
32350
32351
32352 bs = bevelSize * ( Math.sin ( t * Math.PI / 2 ) );
32353
32354
32355
32356
32357 for ( i = 0, il = contour.length; i < il; i ++ ) {
32358
32359 vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
32360
32361 v( vert.x, vert.y, - z );
32362
32363 }
32364
32365
32366
32367 for ( h = 0, hl = holes.length; h < hl; h ++ ) {
32368
32369 ahole = holes[ h ];
32370 oneHoleMovements = holesMovements[ h ];
32371
32372 for ( i = 0, il = ahole.length; i < il; i ++ ) {
32373
32374 vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
32375
32376 v( vert.x, vert.y, - z );
32377
32378 }
32379
32380 }
32381
32382 }
32383
32384 bs = bevelSize;
32385
32386
32387
32388 for ( i = 0; i < vlen; i ++ ) {
32389
32390 vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
32391
32392 if ( ! extrudeByPath ) {
32393
32394 v( vert.x, vert.y, 0 );
32395
32396 } else {
32397
32398
32399
32400 normal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );
32401 binormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );
32402
32403 position2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );
32404
32405 v( position2.x, position2.y, position2.z );
32406
32407 }
32408
32409 }
32410
32411
32412
32413
32414 var s;
32415
32416 for ( s = 1; s <= steps; s ++ ) {
32417
32418 for ( i = 0; i < vlen; i ++ ) {
32419
32420 vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
32421
32422 if ( ! extrudeByPath ) {
32423
32424 v( vert.x, vert.y, amount / steps * s );
32425
32426 } else {
32427
32428
32429
32430 normal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );
32431 binormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );
32432
32433 position2.copy( extrudePts[ s ] ).add( normal ).add( binormal );
32434
32435 v( position2.x, position2.y, position2.z );
32436
32437 }
32438
32439 }
32440
32441 }
32442
32443
32444
32445
32446
32447 for ( b = bevelSegments - 1; b >= 0; b -- ) {
32448
32449 t = b / bevelSegments;
32450 z = bevelThickness * ( 1 - t );
32451
32452 bs = bevelSize * Math.sin ( t * Math.PI / 2 );
32453
32454
32455
32456 for ( i = 0, il = contour.length; i < il; i ++ ) {
32457
32458 vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
32459 v( vert.x, vert.y, amount + z );
32460
32461 }
32462
32463
32464
32465 for ( h = 0, hl = holes.length; h < hl; h ++ ) {
32466
32467 ahole = holes[ h ];
32468 oneHoleMovements = holesMovements[ h ];
32469
32470 for ( i = 0, il = ahole.length; i < il; i ++ ) {
32471
32472 vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
32473
32474 if ( ! extrudeByPath ) {
32475
32476 v( vert.x, vert.y, amount + z );
32477
32478 } else {
32479
32480 v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );
32481
32482 }
32483
32484 }
32485
32486 }
32487
32488 }
32489
32490
32491
32492
32493
32494 buildLidFaces();
32495
32496
32497
32498 buildSideFaces();
32499
32500
32502
32503 function buildLidFaces() {
32504
32505 if ( bevelEnabled ) {
32506
32507 var layer = 0;
32508 var offset = vlen * layer;
32509
32510
32511
32512 for ( i = 0; i < flen; i ++ ) {
32513
32514 face = faces[ i ];
32515 f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );
32516
32517 }
32518
32519 layer = steps + bevelSegments * 2;
32520 offset = vlen * layer;
32521
32522
32523
32524 for ( i = 0; i < flen; i ++ ) {
32525
32526 face = faces[ i ];
32527 f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );
32528
32529 }
32530
32531 } else {
32532
32533
32534
32535 for ( i = 0; i < flen; i ++ ) {
32536
32537 face = faces[ i ];
32538 f3( face[ 2 ], face[ 1 ], face[ 0 ] );
32539
32540 }
32541
32542
32543
32544 for ( i = 0; i < flen; i ++ ) {
32545
32546 face = faces[ i ];
32547 f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );
32548
32549 }
32550
32551 }
32552
32553 }
32554
32555
32556
32557 function buildSideFaces() {
32558
32559 var layeroffset = 0;
32560 sidewalls( contour, layeroffset );
32561 layeroffset += contour.length;
32562
32563 for ( h = 0, hl = holes.length; h < hl; h ++ ) {
32564
32565 ahole = holes[ h ];
32566 sidewalls( ahole, layeroffset );
32567
32568
32569 layeroffset += ahole.length;
32570
32571 }
32572
32573 }
32574
32575 function sidewalls( contour, layeroffset ) {
32576
32577 var j, k;
32578 i = contour.length;
32579
32580 while ( -- i >= 0 ) {
32581
32582 j = i;
32583 k = i - 1;
32584 if ( k < 0 ) k = contour.length - 1;
32585
32586
32587
32588 var s = 0, sl = steps + bevelSegments * 2;
32589
32590 for ( s = 0; s < sl; s ++ ) {
32591
32592 var slen1 = vlen * s;
32593 var slen2 = vlen * ( s + 1 );
32594
32595 var a = layeroffset + j + slen1,
32596 b = layeroffset + k + slen1,
32597 c = layeroffset + k + slen2,
32598 d = layeroffset + j + slen2;
32599
32600 f4( a, b, c, d, contour, s, sl, j, k );
32601
32602 }
32603
32604 }
32605
32606 }
32607
32608
32609 function v( x, y, z ) {
32610
32611 scope.vertices.push( new THREE.Vector3( x, y, z ) );
32612
32613 }
32614
32615 function f3( a, b, c ) {
32616
32617 a += shapesOffset;
32618 b += shapesOffset;
32619 c += shapesOffset;
32620
32621 scope.faces.push( new THREE.Face3( a, b, c, null, null, 0 ) );
32622
32623 var uvs = uvgen.generateTopUV( scope, a, b, c );
32624
32625 scope.faceVertexUvs[ 0 ].push( uvs );
32626
32627 }
32628
32629 function f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {
32630
32631 a += shapesOffset;
32632 b += shapesOffset;
32633 c += shapesOffset;
32634 d += shapesOffset;
32635
32636 scope.faces.push( new THREE.Face3( a, b, d, null, null, 1 ) );
32637 scope.faces.push( new THREE.Face3( b, c, d, null, null, 1 ) );
32638
32639 var uvs = uvgen.generateSideWallUV( scope, a, b, c, d );
32640
32641 scope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );
32642 scope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );
32643
32644 }
32645
32646 };
32647
32648 THREE.ExtrudeGeometry.WorldUVGenerator = {
32649
32650 generateTopUV: function ( geometry, indexA, indexB, indexC ) {
32651
32652 var vertices = geometry.vertices;
32653
32654 var a = vertices[ indexA ];
32655 var b = vertices[ indexB ];
32656 var c = vertices[ indexC ];
32657
32658 return [
32659 new THREE.Vector2( a.x, a.y ),
32660 new THREE.Vector2( b.x, b.y ),
32661 new THREE.Vector2( c.x, c.y )
32662 ];
32663
32664 },
32665
32666 generateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {
32667
32668 var vertices = geometry.vertices;
32669
32670 var a = vertices[ indexA ];
32671 var b = vertices[ indexB ];
32672 var c = vertices[ indexC ];
32673 var d = vertices[ indexD ];
32674
32675 if ( Math.abs( a.y - b.y ) < 0.01 ) {
32676
32677 return [
32678 new THREE.Vector2( a.x, 1 - a.z ),
32679 new THREE.Vector2( b.x, 1 - b.z ),
32680 new THREE.Vector2( c.x, 1 - c.z ),
32681 new THREE.Vector2( d.x, 1 - d.z )
32682 ];
32683
32684 } else {
32685
32686 return [
32687 new THREE.Vector2( a.y, 1 - a.z ),
32688 new THREE.Vector2( b.y, 1 - b.z ),
32689 new THREE.Vector2( c.y, 1 - c.z ),
32690 new THREE.Vector2( d.y, 1 - d.z )
32691 ];
32692
32693 }
32694
32695 }
32696 };
32697
32698
32699
32716 THREE.ShapeGeometry = function ( shapes, options ) {
32717
32718 THREE.Geometry.call( this );
32719
32720 this.type = 'ShapeGeometry';
32721
32722 if ( Array.isArray( shapes ) === false ) shapes = [ shapes ];
32723
32724 this.addShapeList( shapes, options );
32725
32726 this.computeFaceNormals();
32727
32728 };
32729
32730 THREE.ShapeGeometry.prototype = Object.create( THREE.Geometry.prototype );
32731 THREE.ShapeGeometry.prototype.constructor = THREE.ShapeGeometry;
32732
32736 THREE.ShapeGeometry.prototype.addShapeList = function ( shapes, options ) {
32737
32738 for ( var i = 0, l = shapes.length; i < l; i ++ ) {
32739
32740 this.addShape( shapes[ i ], options );
32741
32742 }
32743
32744 return this;
32745
32746 };
32747
32751 THREE.ShapeGeometry.prototype.addShape = function ( shape, options ) {
32752
32753 if ( options === undefined ) options = {};
32754 var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
32755
32756 var material = options.material;
32757 var uvgen = options.UVGenerator === undefined ? THREE.ExtrudeGeometry.WorldUVGenerator : options.UVGenerator;
32758
32759
32760
32761 var i, l, hole;
32762
32763 var shapesOffset = this.vertices.length;
32764 var shapePoints = shape.extractPoints( curveSegments );
32765
32766 var vertices = shapePoints.shape;
32767 var holes = shapePoints.holes;
32768
32769 var reverse = ! THREE.ShapeUtils.isClockWise( vertices );
32770
32771 if ( reverse ) {
32772
32773 vertices = vertices.reverse();
32774
32775
32776
32777 for ( i = 0, l = holes.length; i < l; i ++ ) {
32778
32779 hole = holes[ i ];
32780
32781 if ( THREE.ShapeUtils.isClockWise( hole ) ) {
32782
32783 holes[ i ] = hole.reverse();
32784
32785 }
32786
32787 }
32788
32789 reverse = false;
32790
32791 }
32792
32793 var faces = THREE.ShapeUtils.triangulateShape( vertices, holes );
32794
32795
32796
32797 for ( i = 0, l = holes.length; i < l; i ++ ) {
32798
32799 hole = holes[ i ];
32800 vertices = vertices.concat( hole );
32801
32802 }
32803
32804
32805
32806 var vert, vlen = vertices.length;
32807 var face, flen = faces.length;
32808
32809 for ( i = 0; i < vlen; i ++ ) {
32810
32811 vert = vertices[ i ];
32812
32813 this.vertices.push( new THREE.Vector3( vert.x, vert.y, 0 ) );
32814
32815 }
32816
32817 for ( i = 0; i < flen; i ++ ) {
32818
32819 face = faces[ i ];
32820
32821 var a = face[ 0 ] + shapesOffset;
32822 var b = face[ 1 ] + shapesOffset;
32823 var c = face[ 2 ] + shapesOffset;
32824
32825 this.faces.push( new THREE.Face3( a, b, c, null, null, material ) );
32826 this.faceVertexUvs[ 0 ].push( uvgen.generateTopUV( this, a, b, c ) );
32827
32828 }
32829
32830 };
32831
32832
32833
32840
32841
32842
32843
32844
32845
32846
32847 THREE.LatheGeometry = function ( points, segments, phiStart, phiLength ) {
32848
32849 THREE.Geometry.call( this );
32850
32851 this.type = 'LatheGeometry';
32852
32853 this.parameters = {
32854 points: points,
32855 segments: segments,
32856 phiStart: phiStart,
32857 phiLength: phiLength
32858 };
32859
32860 segments = segments || 12;
32861 phiStart = phiStart || 0;
32862 phiLength = phiLength || 2 * Math.PI;
32863
32864 var inversePointLength = 1.0 / ( points.length - 1 );
32865 var inverseSegments = 1.0 / segments;
32866
32867 for ( var i = 0, il = segments; i <= il; i ++ ) {
32868
32869 var phi = phiStart + i * inverseSegments * phiLength;
32870
32871 var c = Math.cos( phi ),
32872 s = Math.sin( phi );
32873
32874 for ( var j = 0, jl = points.length; j < jl; j ++ ) {
32875
32876 var pt = points[ j ];
32877
32878 var vertex = new THREE.Vector3();
32879
32880 vertex.x = c * pt.x - s * pt.y;
32881 vertex.y = s * pt.x + c * pt.y;
32882 vertex.z = pt.z;
32883
32884 this.vertices.push( vertex );
32885
32886 }
32887
32888 }
32889
32890 var np = points.length;
32891
32892 for ( var i = 0, il = segments; i < il; i ++ ) {
32893
32894 for ( var j = 0, jl = points.length - 1; j < jl; j ++ ) {
32895
32896 var base = j + np * i;
32897 var a = base;
32898 var b = base + np;
32899 var c = base + 1 + np;
32900 var d = base + 1;
32901
32902 var u0 = i * inverseSegments;
32903 var v0 = j * inversePointLength;
32904 var u1 = u0 + inverseSegments;
32905 var v1 = v0 + inversePointLength;
32906
32907 this.faces.push( new THREE.Face3( a, b, d ) );
32908
32909 this.faceVertexUvs[ 0 ].push( [
32910
32911 new THREE.Vector2( u0, v0 ),
32912 new THREE.Vector2( u1, v0 ),
32913 new THREE.Vector2( u0, v1 )
32914
32915 ] );
32916
32917 this.faces.push( new THREE.Face3( b, c, d ) );
32918
32919 this.faceVertexUvs[ 0 ].push( [
32920
32921 new THREE.Vector2( u1, v0 ),
32922 new THREE.Vector2( u1, v1 ),
32923 new THREE.Vector2( u0, v1 )
32924
32925 ] );
32926
32927
32928 }
32929
32930 }
32931
32932 this.mergeVertices();
32933 this.computeFaceNormals();
32934 this.computeVertexNormals();
32935
32936 };
32937
32938 THREE.LatheGeometry.prototype = Object.create( THREE.Geometry.prototype );
32939 THREE.LatheGeometry.prototype.constructor = THREE.LatheGeometry;
32940
32941
32942
32948 THREE.PlaneGeometry = function ( width, height, widthSegments, heightSegments ) {
32949
32950 THREE.Geometry.call( this );
32951
32952 this.type = 'PlaneGeometry';
32953
32954 this.parameters = {
32955 width: width,
32956 height: height,
32957 widthSegments: widthSegments,
32958 heightSegments: heightSegments
32959 };
32960
32961 this.fromBufferGeometry( new THREE.PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );
32962
32963 };
32964
32965 THREE.PlaneGeometry.prototype = Object.create( THREE.Geometry.prototype );
32966 THREE.PlaneGeometry.prototype.constructor = THREE.PlaneGeometry;
32967
32968 THREE.PlaneGeometry.prototype.clone = function () {
32969
32970 var parameters = this.parameters;
32971
32972 return new THREE.PlaneGeometry(
32973 parameters.width,
32974 parameters.height,
32975 parameters.widthSegments,
32976 parameters.heightSegments
32977 );
32978
32979 };
32980
32981
32982
32988 THREE.PlaneBufferGeometry = function ( width, height, widthSegments, heightSegments ) {
32989
32990 THREE.BufferGeometry.call( this );
32991
32992 this.type = 'PlaneBufferGeometry';
32993
32994 this.parameters = {
32995 width: width,
32996 height: height,
32997 widthSegments: widthSegments,
32998 heightSegments: heightSegments
32999 };
33000
33001 var width_half = width / 2;
33002 var height_half = height / 2;
33003
33004 var gridX = Math.floor( widthSegments ) || 1;
33005 var gridY = Math.floor( heightSegments ) || 1;
33006
33007 var gridX1 = gridX + 1;
33008 var gridY1 = gridY + 1;
33009
33010 var segment_width = width / gridX;
33011 var segment_height = height / gridY;
33012
33013 var vertices = new Float32Array( gridX1 * gridY1 * 3 );
33014 var normals = new Float32Array( gridX1 * gridY1 * 3 );
33015 var uvs = new Float32Array( gridX1 * gridY1 * 2 );
33016
33017 var offset = 0;
33018 var offset2 = 0;
33019
33020 for ( var iy = 0; iy < gridY1; iy ++ ) {
33021
33022 var y = iy * segment_height - height_half;
33023
33024 for ( var ix = 0; ix < gridX1; ix ++ ) {
33025
33026 var x = ix * segment_width - width_half;
33027
33028 vertices[ offset ] = x;
33029 vertices[ offset + 1 ] = - y;
33030
33031 normals[ offset + 2 ] = 1;
33032
33033 uvs[ offset2 ] = ix / gridX;
33034 uvs[ offset2 + 1 ] = 1 - ( iy / gridY );
33035
33036 offset += 3;
33037 offset2 += 2;
33038
33039 }
33040
33041 }
33042
33043 offset = 0;
33044
33045 var indices = new ( ( vertices.length / 3 ) > 65535 ? Uint32Array : Uint16Array )( gridX * gridY * 6 );
33046
33047 for ( var iy = 0; iy < gridY; iy ++ ) {
33048
33049 for ( var ix = 0; ix < gridX; ix ++ ) {
33050
33051 var a = ix + gridX1 * iy;
33052 var b = ix + gridX1 * ( iy + 1 );
33053 var c = ( ix + 1 ) + gridX1 * ( iy + 1 );
33054 var d = ( ix + 1 ) + gridX1 * iy;
33055
33056 indices[ offset ] = a;
33057 indices[ offset + 1 ] = b;
33058 indices[ offset + 2 ] = d;
33059
33060 indices[ offset + 3 ] = b;
33061 indices[ offset + 4 ] = c;
33062 indices[ offset + 5 ] = d;
33063
33064 offset += 6;
33065
33066 }
33067
33068 }
33069
33070 this.setIndex( new THREE.BufferAttribute( indices, 1 ) );
33071 this.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
33072 this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
33073 this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
33074
33075 };
33076
33077 THREE.PlaneBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
33078 THREE.PlaneBufferGeometry.prototype.constructor = THREE.PlaneBufferGeometry;
33079
33080 THREE.PlaneBufferGeometry.prototype.clone = function () {
33081
33082 var parameters = this.parameters;
33083
33084 return new THREE.PlaneBufferGeometry(
33085 parameters.width,
33086 parameters.height,
33087 parameters.widthSegments,
33088 parameters.heightSegments
33089 );
33090
33091 };
33092
33093
33094
33099 THREE.RingGeometry = function ( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
33100
33101 THREE.Geometry.call( this );
33102
33103 this.type = 'RingGeometry';
33104
33105 this.parameters = {
33106 innerRadius: innerRadius,
33107 outerRadius: outerRadius,
33108 thetaSegments: thetaSegments,
33109 phiSegments: phiSegments,
33110 thetaStart: thetaStart,
33111 thetaLength: thetaLength
33112 };
33113
33114 innerRadius = innerRadius || 0;
33115 outerRadius = outerRadius || 50;
33116
33117 thetaStart = thetaStart !== undefined ? thetaStart : 0;
33118 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
33119
33120 thetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;
33121 phiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 8;
33122
33123 var i, o, uvs = [], radius = innerRadius, radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );
33124
33125 for ( i = 0; i < phiSegments + 1; i ++ ) {
33126
33127
33128
33129 for ( o = 0; o < thetaSegments + 1; o ++ ) {
33130
33131
33132
33133 var vertex = new THREE.Vector3();
33134 var segment = thetaStart + o / thetaSegments * thetaLength;
33135 vertex.x = radius * Math.cos( segment );
33136 vertex.y = radius * Math.sin( segment );
33137
33138 this.vertices.push( vertex );
33139 uvs.push( new THREE.Vector2( ( vertex.x / outerRadius + 1 ) / 2, ( vertex.y / outerRadius + 1 ) / 2 ) );
33140
33141 }
33142
33143 radius += radiusStep;
33144
33145 }
33146
33147 var n = new THREE.Vector3( 0, 0, 1 );
33148
33149 for ( i = 0; i < phiSegments; i ++ ) {
33150
33151
33152
33153 var thetaSegment = i * ( thetaSegments + 1 );
33154
33155 for ( o = 0; o < thetaSegments ; o ++ ) {
33156
33157
33158
33159 var segment = o + thetaSegment;
33160
33161 var v1 = segment;
33162 var v2 = segment + thetaSegments + 1;
33163 var v3 = segment + thetaSegments + 2;
33164
33165 this.faces.push( new THREE.Face3( v1, v2, v3, [ n.clone(), n.clone(), n.clone() ] ) );
33166 this.faceVertexUvs[ 0 ].push( [ uvs[ v1 ].clone(), uvs[ v2 ].clone(), uvs[ v3 ].clone() ] );
33167
33168 v1 = segment;
33169 v2 = segment + thetaSegments + 2;
33170 v3 = segment + 1;
33171
33172 this.faces.push( new THREE.Face3( v1, v2, v3, [ n.clone(), n.clone(), n.clone() ] ) );
33173 this.faceVertexUvs[ 0 ].push( [ uvs[ v1 ].clone(), uvs[ v2 ].clone(), uvs[ v3 ].clone() ] );
33174
33175 }
33176
33177 }
33178
33179 this.computeFaceNormals();
33180
33181 this.boundingSphere = new THREE.Sphere( new THREE.Vector3(), radius );
33182
33183 };
33184
33185 THREE.RingGeometry.prototype = Object.create( THREE.Geometry.prototype );
33186 THREE.RingGeometry.prototype.constructor = THREE.RingGeometry;
33187
33188 THREE.RingGeometry.prototype.clone = function () {
33189
33190 var parameters = this.parameters;
33191
33192 return new THREE.RingGeometry(
33193 parameters.innerRadius,
33194 parameters.outerRadius,
33195 parameters.thetaSegments,
33196 parameters.phiSegments,
33197 parameters.thetaStart,
33198 parameters.thetaLength
33199 );
33200
33201 };
33202
33203
33204
33209 THREE.SphereGeometry = function ( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
33210
33211 THREE.Geometry.call( this );
33212
33213 this.type = 'SphereGeometry';
33214
33215 this.parameters = {
33216 radius: radius,
33217 widthSegments: widthSegments,
33218 heightSegments: heightSegments,
33219 phiStart: phiStart,
33220 phiLength: phiLength,
33221 thetaStart: thetaStart,
33222 thetaLength: thetaLength
33223 };
33224
33225 this.fromBufferGeometry( new THREE.SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );
33226
33227 };
33228
33229 THREE.SphereGeometry.prototype = Object.create( THREE.Geometry.prototype );
33230 THREE.SphereGeometry.prototype.constructor = THREE.SphereGeometry;
33231
33232 THREE.SphereGeometry.prototype.clone = function () {
33233
33234 var parameters = this.parameters;
33235
33236 return new THREE.SphereGeometry(
33237 parameters.radius,
33238 parameters.widthSegments,
33239 parameters.heightSegments,
33240 parameters.phiStart,
33241 parameters.phiLength,
33242 parameters.thetaStart,
33243 parameters.thetaLength
33244 );
33245
33246 };
33247
33248
33249
33255 THREE.SphereBufferGeometry = function ( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
33256
33257 THREE.BufferGeometry.call( this );
33258
33259 this.type = 'SphereBufferGeometry';
33260
33261 this.parameters = {
33262 radius: radius,
33263 widthSegments: widthSegments,
33264 heightSegments: heightSegments,
33265 phiStart: phiStart,
33266 phiLength: phiLength,
33267 thetaStart: thetaStart,
33268 thetaLength: thetaLength
33269 };
33270
33271 radius = radius || 50;
33272
33273 widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );
33274 heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );
33275
33276 phiStart = phiStart !== undefined ? phiStart : 0;
33277 phiLength = phiLength !== undefined ? phiLength : Math.PI * 2;
33278
33279 thetaStart = thetaStart !== undefined ? thetaStart : 0;
33280 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI;
33281
33282 var thetaEnd = thetaStart + thetaLength;
33283
33284 var vertexCount = ( ( widthSegments + 1 ) * ( heightSegments + 1 ) );
33285
33286 var positions = new THREE.BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );
33287 var normals = new THREE.BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );
33288 var uvs = new THREE.BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );
33289
33290 var index = 0, vertices = [], normal = new THREE.Vector3();
33291
33292 for ( var y = 0; y <= heightSegments; y ++ ) {
33293
33294 var verticesRow = [];
33295
33296 var v = y / heightSegments;
33297
33298 for ( var x = 0; x <= widthSegments; x ++ ) {
33299
33300 var u = x / widthSegments;
33301
33302 var px = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
33303 var py = radius * Math.cos( thetaStart + v * thetaLength );
33304 var pz = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
33305
33306 normal.set( px, py, pz ).normalize();
33307
33308 positions.setXYZ( index, px, py, pz );
33309 normals.setXYZ( index, normal.x, normal.y, normal.z );
33310 uvs.setXY( index, u, 1 - v );
33311
33312 verticesRow.push( index );
33313
33314 index ++;
33315
33316 }
33317
33318 vertices.push( verticesRow );
33319
33320 }
33321
33322 var indices = [];
33323
33324 for ( var y = 0; y < heightSegments; y ++ ) {
33325
33326 for ( var x = 0; x < widthSegments; x ++ ) {
33327
33328 var v1 = vertices[ y ][ x + 1 ];
33329 var v2 = vertices[ y ][ x ];
33330 var v3 = vertices[ y + 1 ][ x ];
33331 var v4 = vertices[ y + 1 ][ x + 1 ];
33332
33333 if ( y !== 0 || thetaStart > 0 ) indices.push( v1, v2, v4 );
33334 if ( y !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( v2, v3, v4 );
33335
33336 }
33337
33338 }
33339
33340 this.setIndex( new ( positions.count > 65535 ? THREE.Uint32Attribute : THREE.Uint16Attribute )( indices, 1 ) );
33341 this.addAttribute( 'position', positions );
33342 this.addAttribute( 'normal', normals );
33343 this.addAttribute( 'uv', uvs );
33344
33345 this.boundingSphere = new THREE.Sphere( new THREE.Vector3(), radius );
33346
33347 };
33348
33349 THREE.SphereBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
33350 THREE.SphereBufferGeometry.prototype.constructor = THREE.SphereBufferGeometry;
33351
33352 THREE.SphereBufferGeometry.prototype.clone = function () {
33353
33354 var parameters = this.parameters;
33355
33356 return new THREE.SphereBufferGeometry(
33357 parameters.radius,
33358 parameters.widthSegments,
33359 parameters.heightSegments,
33360 parameters.phiStart,
33361 parameters.phiLength,
33362 parameters.thetaStart,
33363 parameters.thetaLength
33364 );
33365
33366 };
33367
33368
33369
33376 THREE.TorusGeometry = function ( radius, tube, radialSegments, tubularSegments, arc ) {
33377
33378 THREE.Geometry.call( this );
33379
33380 this.type = 'TorusGeometry';
33381
33382 this.parameters = {
33383 radius: radius,
33384 tube: tube,
33385 radialSegments: radialSegments,
33386 tubularSegments: tubularSegments,
33387 arc: arc
33388 };
33389
33390 radius = radius || 100;
33391 tube = tube || 40;
33392 radialSegments = radialSegments || 8;
33393 tubularSegments = tubularSegments || 6;
33394 arc = arc || Math.PI * 2;
33395
33396 var center = new THREE.Vector3(), uvs = [], normals = [];
33397
33398 for ( var j = 0; j <= radialSegments; j ++ ) {
33399
33400 for ( var i = 0; i <= tubularSegments; i ++ ) {
33401
33402 var u = i / tubularSegments * arc;
33403 var v = j / radialSegments * Math.PI * 2;
33404
33405 center.x = radius * Math.cos( u );
33406 center.y = radius * Math.sin( u );
33407
33408 var vertex = new THREE.Vector3();
33409 vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );
33410 vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );
33411 vertex.z = tube * Math.sin( v );
33412
33413 this.vertices.push( vertex );
33414
33415 uvs.push( new THREE.Vector2( i / tubularSegments, j / radialSegments ) );
33416 normals.push( vertex.clone().sub( center ).normalize() );
33417
33418 }
33419
33420 }
33421
33422 for ( var j = 1; j <= radialSegments; j ++ ) {
33423
33424 for ( var i = 1; i <= tubularSegments; i ++ ) {
33425
33426 var a = ( tubularSegments + 1 ) * j + i - 1;
33427 var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;
33428 var c = ( tubularSegments + 1 ) * ( j - 1 ) + i;
33429 var d = ( tubularSegments + 1 ) * j + i;
33430
33431 var face = new THREE.Face3( a, b, d, [ normals[ a ].clone(), normals[ b ].clone(), normals[ d ].clone() ] );
33432 this.faces.push( face );
33433 this.faceVertexUvs[ 0 ].push( [ uvs[ a ].clone(), uvs[ b ].clone(), uvs[ d ].clone() ] );
33434
33435 face = new THREE.Face3( b, c, d, [ normals[ b ].clone(), normals[ c ].clone(), normals[ d ].clone() ] );
33436 this.faces.push( face );
33437 this.faceVertexUvs[ 0 ].push( [ uvs[ b ].clone(), uvs[ c ].clone(), uvs[ d ].clone() ] );
33438
33439 }
33440
33441 }
33442
33443 this.computeFaceNormals();
33444
33445 };
33446
33447 THREE.TorusGeometry.prototype = Object.create( THREE.Geometry.prototype );
33448 THREE.TorusGeometry.prototype.constructor = THREE.TorusGeometry;
33449
33450 THREE.TorusGeometry.prototype.clone = function () {
33451
33452 var parameters = this.parameters;
33453
33454 return new THREE.TorusGeometry(
33455 parameters.radius,
33456 parameters.tube,
33457 parameters.radialSegments,
33458 parameters.tubularSegments,
33459 parameters.arc
33460 );
33461
33462 };
33463
33464
33465
33471 THREE.TorusKnotGeometry = function ( radius, tube, radialSegments, tubularSegments, p, q, heightScale ) {
33472
33473 THREE.Geometry.call( this );
33474
33475 this.type = 'TorusKnotGeometry';
33476
33477 this.parameters = {
33478 radius: radius,
33479 tube: tube,
33480 radialSegments: radialSegments,
33481 tubularSegments: tubularSegments,
33482 p: p,
33483 q: q,
33484 heightScale: heightScale
33485 };
33486
33487 radius = radius || 100;
33488 tube = tube || 40;
33489 radialSegments = radialSegments || 64;
33490 tubularSegments = tubularSegments || 8;
33491 p = p || 2;
33492 q = q || 3;
33493 heightScale = heightScale || 1;
33494
33495 var grid = new Array( radialSegments );
33496 var tang = new THREE.Vector3();
33497 var n = new THREE.Vector3();
33498 var bitan = new THREE.Vector3();
33499
33500 for ( var i = 0; i < radialSegments; ++ i ) {
33501
33502 grid[ i ] = new Array( tubularSegments );
33503 var u = i / radialSegments * 2 * p * Math.PI;
33504 var p1 = getPos( u, q, p, radius, heightScale );
33505 var p2 = getPos( u + 0.01, q, p, radius, heightScale );
33506 tang.subVectors( p2, p1 );
33507 n.addVectors( p2, p1 );
33508
33509 bitan.crossVectors( tang, n );
33510 n.crossVectors( bitan, tang );
33511 bitan.normalize();
33512 n.normalize();
33513
33514 for ( var j = 0; j < tubularSegments; ++ j ) {
33515
33516 var v = j / tubularSegments * 2 * Math.PI;
33517 var cx = - tube * Math.cos( v );
33518 var cy = tube * Math.sin( v );
33519
33520 var pos = new THREE.Vector3();
33521 pos.x = p1.x + cx * n.x + cy * bitan.x;
33522 pos.y = p1.y + cx * n.y + cy * bitan.y;
33523 pos.z = p1.z + cx * n.z + cy * bitan.z;
33524
33525 grid[ i ][ j ] = this.vertices.push( pos ) - 1;
33526
33527 }
33528
33529 }
33530
33531 for ( var i = 0; i < radialSegments; ++ i ) {
33532
33533 for ( var j = 0; j < tubularSegments; ++ j ) {
33534
33535 var ip = ( i + 1 ) % radialSegments;
33536 var jp = ( j + 1 ) % tubularSegments;
33537
33538 var a = grid[ i ][ j ];
33539 var b = grid[ ip ][ j ];
33540 var c = grid[ ip ][ jp ];
33541 var d = grid[ i ][ jp ];
33542
33543 var uva = new THREE.Vector2( i / radialSegments, j / tubularSegments );
33544 var uvb = new THREE.Vector2( ( i + 1 ) / radialSegments, j / tubularSegments );
33545 var uvc = new THREE.Vector2( ( i + 1 ) / radialSegments, ( j + 1 ) / tubularSegments );
33546 var uvd = new THREE.Vector2( i / radialSegments, ( j + 1 ) / tubularSegments );
33547
33548 this.faces.push( new THREE.Face3( a, b, d ) );
33549 this.faceVertexUvs[ 0 ].push( [ uva, uvb, uvd ] );
33550
33551 this.faces.push( new THREE.Face3( b, c, d ) );
33552 this.faceVertexUvs[ 0 ].push( [ uvb.clone(), uvc, uvd.clone() ] );
33553
33554 }
33555
33556 }
33557
33558 this.computeFaceNormals();
33559 this.computeVertexNormals();
33560
33561 function getPos( u, in_q, in_p, radius, heightScale ) {
33562
33563 var cu = Math.cos( u );
33564 var su = Math.sin( u );
33565 var quOverP = in_q / in_p * u;
33566 var cs = Math.cos( quOverP );
33567
33568 var tx = radius * ( 2 + cs ) * 0.5 * cu;
33569 var ty = radius * ( 2 + cs ) * su * 0.5;
33570 var tz = heightScale * radius * Math.sin( quOverP ) * 0.5;
33571
33572 return new THREE.Vector3( tx, ty, tz );
33573
33574 }
33575
33576 };
33577
33578 THREE.TorusKnotGeometry.prototype = Object.create( THREE.Geometry.prototype );
33579 THREE.TorusKnotGeometry.prototype.constructor = THREE.TorusKnotGeometry;
33580
33581 THREE.TorusKnotGeometry.prototype.clone = function () {
33582
33583 var parameters = this.parameters;
33584
33585 return new THREE.TorusKnotGeometry(
33586 parameters.radius,
33587 parameters.tube,
33588 parameters.radialSegments,
33589 parameters.tubularSegments,
33590 parameters.p,
33591 parameters.q,
33592 parameters.heightScale
33593 );
33594
33595 };
33596
33597
33598
33613 THREE.TubeGeometry = function ( path, segments, radius, radialSegments, closed, taper ) {
33614
33615 THREE.Geometry.call( this );
33616
33617 this.type = 'TubeGeometry';
33618
33619 this.parameters = {
33620 path: path,
33621 segments: segments,
33622 radius: radius,
33623 radialSegments: radialSegments,
33624 closed: closed,
33625 taper: taper
33626 };
33627
33628 segments = segments || 64;
33629 radius = radius || 1;
33630 radialSegments = radialSegments || 8;
33631 closed = closed || false;
33632 taper = taper || THREE.TubeGeometry.NoTaper;
33633
33634 var grid = [];
33635
33636 var scope = this,
33637
33638 tangent,
33639 normal,
33640 binormal,
33641
33642 numpoints = segments + 1,
33643
33644 u, v, r,
33645
33646 cx, cy,
33647 pos, pos2 = new THREE.Vector3(),
33648 i, j,
33649 ip, jp,
33650 a, b, c, d,
33651 uva, uvb, uvc, uvd;
33652
33653 var frames = new THREE.TubeGeometry.FrenetFrames( path, segments, closed ),
33654 tangents = frames.tangents,
33655 normals = frames.normals,
33656 binormals = frames.binormals;
33657
33658
33659 this.tangents = tangents;
33660 this.normals = normals;
33661 this.binormals = binormals;
33662
33663 function vert( x, y, z ) {
33664
33665 return scope.vertices.push( new THREE.Vector3( x, y, z ) ) - 1;
33666
33667 }
33668
33669
33670
33671 for ( i = 0; i < numpoints; i ++ ) {
33672
33673 grid[ i ] = [];
33674
33675 u = i / ( numpoints - 1 );
33676
33677 pos = path.getPointAt( u );
33678
33679 tangent = tangents[ i ];
33680 normal = normals[ i ];
33681 binormal = binormals[ i ];
33682
33683 r = radius * taper( u );
33684
33685 for ( j = 0; j < radialSegments; j ++ ) {
33686
33687 v = j / radialSegments * 2 * Math.PI;
33688
33689 cx = - r * Math.cos( v );
33690 cy = r * Math.sin( v );
33691
33692 pos2.copy( pos );
33693 pos2.x += cx * normal.x + cy * binormal.x;
33694 pos2.y += cx * normal.y + cy * binormal.y;
33695 pos2.z += cx * normal.z + cy * binormal.z;
33696
33697 grid[ i ][ j ] = vert( pos2.x, pos2.y, pos2.z );
33698
33699 }
33700
33701 }
33702
33703
33704
33705
33706 for ( i = 0; i < segments; i ++ ) {
33707
33708 for ( j = 0; j < radialSegments; j ++ ) {
33709
33710 ip = ( closed ) ? ( i + 1 ) % segments : i + 1;
33711 jp = ( j + 1 ) % radialSegments;
33712
33713 a = grid[ i ][ j ];
33714 b = grid[ ip ][ j ];
33715 c = grid[ ip ][ jp ];
33716 d = grid[ i ][ jp ];
33717
33718 uva = new THREE.Vector2( i / segments, j / radialSegments );
33719 uvb = new THREE.Vector2( ( i + 1 ) / segments, j / radialSegments );
33720 uvc = new THREE.Vector2( ( i + 1 ) / segments, ( j + 1 ) / radialSegments );
33721 uvd = new THREE.Vector2( i / segments, ( j + 1 ) / radialSegments );
33722
33723 this.faces.push( new THREE.Face3( a, b, d ) );
33724 this.faceVertexUvs[ 0 ].push( [ uva, uvb, uvd ] );
33725
33726 this.faces.push( new THREE.Face3( b, c, d ) );
33727 this.faceVertexUvs[ 0 ].push( [ uvb.clone(), uvc, uvd.clone() ] );
33728
33729 }
33730
33731 }
33732
33733 this.computeFaceNormals();
33734 this.computeVertexNormals();
33735
33736 };
33737
33738 THREE.TubeGeometry.prototype = Object.create( THREE.Geometry.prototype );
33739 THREE.TubeGeometry.prototype.constructor = THREE.TubeGeometry;
33740 THREE.TubeGeometry.prototype.clone = function() {
33741
33742 return new this.constructor( this.parameters.path,
33743 this.parameters.segments, this.parameters.radius, this.parameters.radialSegments,
33744 this.parameters.closed, this.parameters.taper
33745 );
33746
33747 };
33748
33749 THREE.TubeGeometry.NoTaper = function ( u ) {
33750
33751 return 1;
33752
33753 };
33754
33755 THREE.TubeGeometry.SinusoidalTaper = function ( u ) {
33756
33757 return Math.sin( Math.PI * u );
33758
33759 };
33760
33761
33762 THREE.TubeGeometry.FrenetFrames = function ( path, segments, closed ) {
33763
33764 var normal = new THREE.Vector3(),
33765
33766 tangents = [],
33767 normals = [],
33768 binormals = [],
33769
33770 vec = new THREE.Vector3(),
33771 mat = new THREE.Matrix4(),
33772
33773 numpoints = segments + 1,
33774 theta,
33775 smallest,
33776
33777 tx, ty, tz,
33778 i, u;
33779
33780
33781
33782 this.tangents = tangents;
33783 this.normals = normals;
33784 this.binormals = binormals;
33785
33786
33787
33788 for ( i = 0; i < numpoints; i ++ ) {
33789
33790 u = i / ( numpoints - 1 );
33791
33792 tangents[ i ] = path.getTangentAt( u );
33793 tangents[ i ].normalize();
33794
33795 }
33796
33797 initialNormal3();
33798
33799
33800
33801
33802
33803
33804
33805
33806
33807
33808
33809
33810
33811
33812
33813
33814
33815
33816
33817
33818
33819
33820
33821
33822
33823 function initialNormal3() {
33824
33825
33826
33827
33828 normals[ 0 ] = new THREE.Vector3();
33829 binormals[ 0 ] = new THREE.Vector3();
33830 smallest = Number.MAX_VALUE;
33831 tx = Math.abs( tangents[ 0 ].x );
33832 ty = Math.abs( tangents[ 0 ].y );
33833 tz = Math.abs( tangents[ 0 ].z );
33834
33835 if ( tx <= smallest ) {
33836
33837 smallest = tx;
33838 normal.set( 1, 0, 0 );
33839
33840 }
33841
33842 if ( ty <= smallest ) {
33843
33844 smallest = ty;
33845 normal.set( 0, 1, 0 );
33846
33847 }
33848
33849 if ( tz <= smallest ) {
33850
33851 normal.set( 0, 0, 1 );
33852
33853 }
33854
33855 vec.crossVectors( tangents[ 0 ], normal ).normalize();
33856
33857 normals[ 0 ].crossVectors( tangents[ 0 ], vec );
33858 binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );
33859
33860 }
33861
33862
33863
33864
33865 for ( i = 1; i < numpoints; i ++ ) {
33866
33867 normals[ i ] = normals[ i - 1 ].clone();
33868
33869 binormals[ i ] = binormals[ i - 1 ].clone();
33870
33871 vec.crossVectors( tangents[ i - 1 ], tangents[ i ] );
33872
33873 if ( vec.length() > Number.EPSILON ) {
33874
33875 vec.normalize();
33876
33877 theta = Math.acos( THREE.Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) );
33878
33879 normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );
33880
33881 }
33882
33883 binormals[ i ].crossVectors( tangents[ i ], normals[ i ] );
33884
33885 }
33886
33887
33888
33889
33890 if ( closed ) {
33891
33892 theta = Math.acos( THREE.Math.clamp( normals[ 0 ].dot( normals[ numpoints - 1 ] ), - 1, 1 ) );
33893 theta /= ( numpoints - 1 );
33894
33895 if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ numpoints - 1 ] ) ) > 0 ) {
33896
33897 theta = - theta;
33898
33899 }
33900
33901 for ( i = 1; i < numpoints; i ++ ) {
33902
33903
33904 normals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );
33905 binormals[ i ].crossVectors( tangents[ i ], normals[ i ] );
33906
33907 }
33908
33909 }
33910
33911 };
33912
33913
33914
33921 THREE.PolyhedronGeometry = function ( vertices, indices, radius, detail ) {
33922
33923 THREE.Geometry.call( this );
33924
33925 this.type = 'PolyhedronGeometry';
33926
33927 this.parameters = {
33928 vertices: vertices,
33929 indices: indices,
33930 radius: radius,
33931 detail: detail
33932 };
33933
33934 radius = radius || 1;
33935 detail = detail || 0;
33936
33937 var that = this;
33938
33939 for ( var i = 0, l = vertices.length; i < l; i += 3 ) {
33940
33941 prepare( new THREE.Vector3( vertices[ i ], vertices[ i + 1 ], vertices[ i + 2 ] ) );
33942
33943 }
33944
33945 var p = this.vertices;
33946
33947 var faces = [];
33948
33949 for ( var i = 0, j = 0, l = indices.length; i < l; i += 3, j ++ ) {
33950
33951 var v1 = p[ indices[ i ] ];
33952 var v2 = p[ indices[ i + 1 ] ];
33953 var v3 = p[ indices[ i + 2 ] ];
33954
33955 faces[ j ] = new THREE.Face3( v1.index, v2.index, v3.index, [ v1.clone(), v2.clone(), v3.clone() ], undefined, j );
33956
33957 }
33958
33959 var centroid = new THREE.Vector3();
33960
33961 for ( var i = 0, l = faces.length; i < l; i ++ ) {
33962
33963 subdivide( faces[ i ], detail );
33964
33965 }
33966
33967
33968
33969
33970 for ( var i = 0, l = this.faceVertexUvs[ 0 ].length; i < l; i ++ ) {
33971
33972 var uvs = this.faceVertexUvs[ 0 ][ i ];
33973
33974 var x0 = uvs[ 0 ].x;
33975 var x1 = uvs[ 1 ].x;
33976 var x2 = uvs[ 2 ].x;
33977
33978 var max = Math.max( x0, x1, x2 );
33979 var min = Math.min( x0, x1, x2 );
33980
33981 if ( max > 0.9 && min < 0.1 ) {
33982
33983
33984
33985 if ( x0 < 0.2 ) uvs[ 0 ].x += 1;
33986 if ( x1 < 0.2 ) uvs[ 1 ].x += 1;
33987 if ( x2 < 0.2 ) uvs[ 2 ].x += 1;
33988
33989 }
33990
33991 }
33992
33993
33994
33995
33996 for ( var i = 0, l = this.vertices.length; i < l; i ++ ) {
33997
33998 this.vertices[ i ].multiplyScalar( radius );
33999
34000 }
34001
34002
34003
34004
34005 this.mergeVertices();
34006
34007 this.computeFaceNormals();
34008
34009 this.boundingSphere = new THREE.Sphere( new THREE.Vector3(), radius );
34010
34011
34012
34013
34014 function prepare( vector ) {
34015
34016 var vertex = vector.normalize().clone();
34017 vertex.index = that.vertices.push( vertex ) - 1;
34018
34019
34020
34021 var u = azimuth( vector ) / 2 / Math.PI + 0.5;
34022 var v = inclination( vector ) / Math.PI + 0.5;
34023 vertex.uv = new THREE.Vector2( u, 1 - v );
34024
34025 return vertex;
34026
34027 }
34028
34029
34030
34031
34032 function make( v1, v2, v3, materialIndex ) {
34033
34034 var face = new THREE.Face3( v1.index, v2.index, v3.index, [ v1.clone(), v2.clone(), v3.clone() ], undefined, materialIndex );
34035 that.faces.push( face );
34036
34037 centroid.copy( v1 ).add( v2 ).add( v3 ).divideScalar( 3 );
34038
34039 var azi = azimuth( centroid );
34040
34041 that.faceVertexUvs[ 0 ].push( [
34042 correctUV( v1.uv, v1, azi ),
34043 correctUV( v2.uv, v2, azi ),
34044 correctUV( v3.uv, v3, azi )
34045 ] );
34046
34047 }
34048
34049
34050
34051
34052 function subdivide( face, detail ) {
34053
34054 var cols = Math.pow( 2, detail );
34055 var a = prepare( that.vertices[ face.a ] );
34056 var b = prepare( that.vertices[ face.b ] );
34057 var c = prepare( that.vertices[ face.c ] );
34058 var v = [];
34059
34060 var materialIndex = face.materialIndex;
34061
34062
34063
34064 for ( var i = 0 ; i <= cols; i ++ ) {
34065
34066 v[ i ] = [];
34067
34068 var aj = prepare( a.clone().lerp( c, i / cols ) );
34069 var bj = prepare( b.clone().lerp( c, i / cols ) );
34070 var rows = cols - i;
34071
34072 for ( var j = 0; j <= rows; j ++ ) {
34073
34074 if ( j === 0 && i === cols ) {
34075
34076 v[ i ][ j ] = aj;
34077
34078 } else {
34079
34080 v[ i ][ j ] = prepare( aj.clone().lerp( bj, j / rows ) );
34081
34082 }
34083
34084 }
34085
34086 }
34087
34088
34089
34090 for ( var i = 0; i < cols ; i ++ ) {
34091
34092 for ( var j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {
34093
34094 var k = Math.floor( j / 2 );
34095
34096 if ( j % 2 === 0 ) {
34097
34098 make(
34099 v[ i ][ k + 1 ],
34100 v[ i + 1 ][ k ],
34101 v[ i ][ k ],
34102 materialIndex
34103 );
34104
34105 } else {
34106
34107 make(
34108 v[ i ][ k + 1 ],
34109 v[ i + 1 ][ k + 1 ],
34110 v[ i + 1 ][ k ],
34111 materialIndex
34112 );
34113
34114 }
34115
34116 }
34117
34118 }
34119
34120 }
34121
34122
34123
34124
34125 function azimuth( vector ) {
34126
34127 return Math.atan2( vector.z, - vector.x );
34128
34129 }
34130
34131
34132
34133
34134 function inclination( vector ) {
34135
34136 return Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );
34137
34138 }
34139
34140
34141
34142
34143 function correctUV( uv, vector, azimuth ) {
34144
34145 if ( ( azimuth < 0 ) && ( uv.x === 1 ) ) uv = new THREE.Vector2( uv.x - 1, uv.y );
34146 if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) uv = new THREE.Vector2( azimuth / 2 / Math.PI + 0.5, uv.y );
34147 return uv.clone();
34148
34149 }
34150
34151
34152 };
34153
34154 THREE.PolyhedronGeometry.prototype = Object.create( THREE.Geometry.prototype );
34155 THREE.PolyhedronGeometry.prototype.constructor = THREE.PolyhedronGeometry;
34156
34157 THREE.PolyhedronGeometry.prototype.clone = function () {
34158
34159 var parameters = this.parameters;
34160
34161 return new THREE.PolyhedronGeometry(
34162 parameters.vertices,
34163 parameters.indices,
34164 parameters.radius,
34165 parameters.detail
34166 );
34167
34168 };
34169
34170
34171
34176 THREE.DodecahedronGeometry = function ( radius, detail ) {
34177
34178 var t = ( 1 + Math.sqrt( 5 ) ) / 2;
34179 var r = 1 / t;
34180
34181 var vertices = [
34182
34183
34184 - 1, - 1, - 1, - 1, - 1, 1,
34185 - 1, 1, - 1, - 1, 1, 1,
34186 1, - 1, - 1, 1, - 1, 1,
34187 1, 1, - 1, 1, 1, 1,
34188
34189
34190 0, - r, - t, 0, - r, t,
34191 0, r, - t, 0, r, t,
34192
34193
34194 - r, - t, 0, - r, t, 0,
34195 r, - t, 0, r, t, 0,
34196
34197
34198 - t, 0, - r, t, 0, - r,
34199 - t, 0, r, t, 0, r
34200 ];
34201
34202 var indices = [
34203 3, 11, 7, 3, 7, 15, 3, 15, 13,
34204 7, 19, 17, 7, 17, 6, 7, 6, 15,
34205 17, 4, 8, 17, 8, 10, 17, 10, 6,
34206 8, 0, 16, 8, 16, 2, 8, 2, 10,
34207 0, 12, 1, 0, 1, 18, 0, 18, 16,
34208 6, 10, 2, 6, 2, 13, 6, 13, 15,
34209 2, 16, 18, 2, 18, 3, 2, 3, 13,
34210 18, 1, 9, 18, 9, 11, 18, 11, 3,
34211 4, 14, 12, 4, 12, 0, 4, 0, 8,
34212 11, 9, 5, 11, 5, 19, 11, 19, 7,
34213 19, 5, 14, 19, 14, 4, 19, 4, 17,
34214 1, 12, 14, 1, 14, 5, 1, 5, 9
34215 ];
34216
34217 THREE.PolyhedronGeometry.call( this, vertices, indices, radius, detail );
34218
34219 this.type = 'DodecahedronGeometry';
34220
34221 this.parameters = {
34222 radius: radius,
34223 detail: detail
34224 };
34225
34226 };
34227
34228 THREE.DodecahedronGeometry.prototype = Object.create( THREE.PolyhedronGeometry.prototype );
34229 THREE.DodecahedronGeometry.prototype.constructor = THREE.DodecahedronGeometry;
34230
34231 THREE.DodecahedronGeometry.prototype.clone = function () {
34232
34233 var parameters = this.parameters;
34234
34235 return new THREE.DodecahedronGeometry(
34236 parameters.radius,
34237 parameters.detail
34238 );
34239
34240 };
34241
34242
34243
34248 THREE.IcosahedronGeometry = function ( radius, detail ) {
34249
34250 var t = ( 1 + Math.sqrt( 5 ) ) / 2;
34251
34252 var vertices = [
34253 - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,
34254 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,
34255 t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1
34256 ];
34257
34258 var indices = [
34259 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,
34260 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,
34261 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,
34262 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1
34263 ];
34264
34265 THREE.PolyhedronGeometry.call( this, vertices, indices, radius, detail );
34266
34267 this.type = 'IcosahedronGeometry';
34268
34269 this.parameters = {
34270 radius: radius,
34271 detail: detail
34272 };
34273
34274 };
34275
34276 THREE.IcosahedronGeometry.prototype = Object.create( THREE.PolyhedronGeometry.prototype );
34277 THREE.IcosahedronGeometry.prototype.constructor = THREE.IcosahedronGeometry;
34278
34279 THREE.IcosahedronGeometry.prototype.clone = function () {
34280
34281 var parameters = this.parameters;
34282
34283 return new THREE.IcosahedronGeometry(
34284 parameters.radius,
34285 parameters.detail
34286 );
34287
34288 };
34289
34290
34291
34296 THREE.OctahedronGeometry = function ( radius, detail ) {
34297
34298 var vertices = [
34299 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1
34300 ];
34301
34302 var indices = [
34303 0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2
34304 ];
34305
34306 THREE.PolyhedronGeometry.call( this, vertices, indices, radius, detail );
34307
34308 this.type = 'OctahedronGeometry';
34309
34310 this.parameters = {
34311 radius: radius,
34312 detail: detail
34313 };
34314
34315 };
34316
34317 THREE.OctahedronGeometry.prototype = Object.create( THREE.PolyhedronGeometry.prototype );
34318 THREE.OctahedronGeometry.prototype.constructor = THREE.OctahedronGeometry;
34319
34320 THREE.OctahedronGeometry.prototype.clone = function () {
34321
34322 var parameters = this.parameters;
34323
34324 return new THREE.OctahedronGeometry(
34325 parameters.radius,
34326 parameters.detail
34327 );
34328
34329 };
34330
34331
34332
34337 THREE.TetrahedronGeometry = function ( radius, detail ) {
34338
34339 var vertices = [
34340 1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1
34341 ];
34342
34343 var indices = [
34344 2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1
34345 ];
34346
34347 THREE.PolyhedronGeometry.call( this, vertices, indices, radius, detail );
34348
34349 this.type = 'TetrahedronGeometry';
34350
34351 this.parameters = {
34352 radius: radius,
34353 detail: detail
34354 };
34355
34356 };
34357
34358 THREE.TetrahedronGeometry.prototype = Object.create( THREE.PolyhedronGeometry.prototype );
34359 THREE.TetrahedronGeometry.prototype.constructor = THREE.TetrahedronGeometry;
34360
34361 THREE.TetrahedronGeometry.prototype.clone = function () {
34362
34363 var parameters = this.parameters;
34364
34365 return new THREE.TetrahedronGeometry(
34366 parameters.radius,
34367 parameters.detail
34368 );
34369
34370 };
34371
34372
34373
34383 THREE.ParametricGeometry = function ( func, slices, stacks ) {
34384
34385 THREE.Geometry.call( this );
34386
34387 this.type = 'ParametricGeometry';
34388
34389 this.parameters = {
34390 func: func,
34391 slices: slices,
34392 stacks: stacks
34393 };
34394
34395 var verts = this.vertices;
34396 var faces = this.faces;
34397 var uvs = this.faceVertexUvs[ 0 ];
34398
34399 var i, j, p;
34400 var u, v;
34401
34402 var sliceCount = slices + 1;
34403
34404 for ( i = 0; i <= stacks; i ++ ) {
34405
34406 v = i / stacks;
34407
34408 for ( j = 0; j <= slices; j ++ ) {
34409
34410 u = j / slices;
34411
34412 p = func( u, v );
34413 verts.push( p );
34414
34415 }
34416
34417 }
34418
34419 var a, b, c, d;
34420 var uva, uvb, uvc, uvd;
34421
34422 for ( i = 0; i < stacks; i ++ ) {
34423
34424 for ( j = 0; j < slices; j ++ ) {
34425
34426 a = i * sliceCount + j;
34427 b = i * sliceCount + j + 1;
34428 c = ( i + 1 ) * sliceCount + j + 1;
34429 d = ( i + 1 ) * sliceCount + j;
34430
34431 uva = new THREE.Vector2( j / slices, i / stacks );
34432 uvb = new THREE.Vector2( ( j + 1 ) / slices, i / stacks );
34433 uvc = new THREE.Vector2( ( j + 1 ) / slices, ( i + 1 ) / stacks );
34434 uvd = new THREE.Vector2( j / slices, ( i + 1 ) / stacks );
34435
34436 faces.push( new THREE.Face3( a, b, d ) );
34437 uvs.push( [ uva, uvb, uvd ] );
34438
34439 faces.push( new THREE.Face3( b, c, d ) );
34440 uvs.push( [ uvb.clone(), uvc, uvd.clone() ] );
34441
34442 }
34443
34444 }
34445
34446
34447
34448
34449
34450
34451
34452 this.computeFaceNormals();
34453 this.computeVertexNormals();
34454
34455 };
34456
34457 THREE.ParametricGeometry.prototype = Object.create( THREE.Geometry.prototype );
34458 THREE.ParametricGeometry.prototype.constructor = THREE.ParametricGeometry;
34459
34460
34461
34466 THREE.WireframeGeometry = function ( geometry ) {
34467
34468 THREE.BufferGeometry.call( this );
34469
34470 var edge = [ 0, 0 ], hash = {};
34471
34472 function sortFunction( a, b ) {
34473
34474 return a - b;
34475
34476 }
34477
34478 var keys = [ 'a', 'b', 'c' ];
34479
34480 if ( geometry instanceof THREE.Geometry ) {
34481
34482 var vertices = geometry.vertices;
34483 var faces = geometry.faces;
34484 var numEdges = 0;
34485
34486
34487 var edges = new Uint32Array( 6 * faces.length );
34488
34489 for ( var i = 0, l = faces.length; i < l; i ++ ) {
34490
34491 var face = faces[ i ];
34492
34493 for ( var j = 0; j < 3; j ++ ) {
34494
34495 edge[ 0 ] = face[ keys[ j ] ];
34496 edge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];
34497 edge.sort( sortFunction );
34498
34499 var key = edge.toString();
34500
34501 if ( hash[ key ] === undefined ) {
34502
34503 edges[ 2 * numEdges ] = edge[ 0 ];
34504 edges[ 2 * numEdges + 1 ] = edge[ 1 ];
34505 hash[ key ] = true;
34506 numEdges ++;
34507
34508 }
34509
34510 }
34511
34512 }
34513
34514 var coords = new Float32Array( numEdges * 2 * 3 );
34515
34516 for ( var i = 0, l = numEdges; i < l; i ++ ) {
34517
34518 for ( var j = 0; j < 2; j ++ ) {
34519
34520 var vertex = vertices[ edges [ 2 * i + j ] ];
34521
34522 var index = 6 * i + 3 * j;
34523 coords[ index + 0 ] = vertex.x;
34524 coords[ index + 1 ] = vertex.y;
34525 coords[ index + 2 ] = vertex.z;
34526
34527 }
34528
34529 }
34530
34531 this.addAttribute( 'position', new THREE.BufferAttribute( coords, 3 ) );
34532
34533 } else if ( geometry instanceof THREE.BufferGeometry ) {
34534
34535 if ( geometry.index !== null ) {
34536
34537
34538
34539 var indices = geometry.index.array;
34540 var vertices = geometry.attributes.position;
34541 var drawcalls = geometry.drawcalls;
34542 var numEdges = 0;
34543
34544 if ( drawcalls.length === 0 ) {
34545
34546 geometry.addGroup( 0, indices.length );
34547
34548 }
34549
34550
34551 var edges = new Uint32Array( 2 * indices.length );
34552
34553 for ( var o = 0, ol = drawcalls.length; o < ol; ++ o ) {
34554
34555 var drawcall = drawcalls[ o ];
34556
34557 var start = drawcall.start;
34558 var count = drawcall.count;
34559
34560 for ( var i = start, il = start + count; i < il; i += 3 ) {
34561
34562 for ( var j = 0; j < 3; j ++ ) {
34563
34564 edge[ 0 ] = indices[ i + j ];
34565 edge[ 1 ] = indices[ i + ( j + 1 ) % 3 ];
34566 edge.sort( sortFunction );
34567
34568 var key = edge.toString();
34569
34570 if ( hash[ key ] === undefined ) {
34571
34572 edges[ 2 * numEdges ] = edge[ 0 ];
34573 edges[ 2 * numEdges + 1 ] = edge[ 1 ];
34574 hash[ key ] = true;
34575 numEdges ++;
34576
34577 }
34578
34579 }
34580
34581 }
34582
34583 }
34584
34585 var coords = new Float32Array( numEdges * 2 * 3 );
34586
34587 for ( var i = 0, l = numEdges; i < l; i ++ ) {
34588
34589 for ( var j = 0; j < 2; j ++ ) {
34590
34591 var index = 6 * i + 3 * j;
34592 var index2 = edges[ 2 * i + j ];
34593
34594 coords[ index + 0 ] = vertices.getX( index2 );
34595 coords[ index + 1 ] = vertices.getY( index2 );
34596 coords[ index + 2 ] = vertices.getZ( index2 );
34597
34598 }
34599
34600 }
34601
34602 this.addAttribute( 'position', new THREE.BufferAttribute( coords, 3 ) );
34603
34604 } else {
34605
34606
34607
34608 var vertices = geometry.attributes.position.array;
34609 var numEdges = vertices.length / 3;
34610 var numTris = numEdges / 3;
34611
34612 var coords = new Float32Array( numEdges * 2 * 3 );
34613
34614 for ( var i = 0, l = numTris; i < l; i ++ ) {
34615
34616 for ( var j = 0; j < 3; j ++ ) {
34617
34618 var index = 18 * i + 6 * j;
34619
34620 var index1 = 9 * i + 3 * j;
34621 coords[ index + 0 ] = vertices[ index1 ];
34622 coords[ index + 1 ] = vertices[ index1 + 1 ];
34623 coords[ index + 2 ] = vertices[ index1 + 2 ];
34624
34625 var index2 = 9 * i + 3 * ( ( j + 1 ) % 3 );
34626 coords[ index + 3 ] = vertices[ index2 ];
34627 coords[ index + 4 ] = vertices[ index2 + 1 ];
34628 coords[ index + 5 ] = vertices[ index2 + 2 ];
34629
34630 }
34631
34632 }
34633
34634 this.addAttribute( 'position', new THREE.BufferAttribute( coords, 3 ) );
34635
34636 }
34637
34638 }
34639
34640 };
34641
34642 THREE.WireframeGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
34643 THREE.WireframeGeometry.prototype.constructor = THREE.WireframeGeometry;
34644
34645
34646
34652 THREE.AxisHelper = function ( size ) {
34653
34654 size = size || 1;
34655
34656 var vertices = new Float32Array( [
34657 0, 0, 0, size, 0, 0,
34658 0, 0, 0, 0, size, 0,
34659 0, 0, 0, 0, 0, size
34660 ] );
34661
34662 var colors = new Float32Array( [
34663 1, 0, 0, 1, 0.6, 0,
34664 0, 1, 0, 0.6, 1, 0,
34665 0, 0, 1, 0, 0.6, 1
34666 ] );
34667
34668 var geometry = new THREE.BufferGeometry();
34669 geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
34670 geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
34671
34672 var material = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors } );
34673
34674 THREE.LineSegments.call( this, geometry, material );
34675
34676 };
34677
34678 THREE.AxisHelper.prototype = Object.create( THREE.LineSegments.prototype );
34679 THREE.AxisHelper.prototype.constructor = THREE.AxisHelper;
34680
34681
34682
34699 THREE.ArrowHelper = ( function () {
34700
34701 var lineGeometry = new THREE.Geometry();
34702 lineGeometry.vertices.push( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 1, 0 ) );
34703
34704 var coneGeometry = new THREE.CylinderGeometry( 0, 0.5, 1, 5, 1 );
34705 coneGeometry.translate( 0, - 0.5, 0 );
34706
34707 return function ArrowHelper( dir, origin, length, color, headLength, headWidth ) {
34708
34709
34710
34711 THREE.Object3D.call( this );
34712
34713 if ( color === undefined ) color = 0xffff00;
34714 if ( length === undefined ) length = 1;
34715 if ( headLength === undefined ) headLength = 0.2 * length;
34716 if ( headWidth === undefined ) headWidth = 0.2 * headLength;
34717
34718 this.position.copy( origin );
34719
34720 if ( headLength < length ) {
34721 this.line = new THREE.Line( lineGeometry, new THREE.LineBasicMaterial( { color: color } ) );
34722 this.line.matrixAutoUpdate = false;
34723 this.add( this.line );
34724 }
34725
34726 this.cone = new THREE.Mesh( coneGeometry, new THREE.MeshBasicMaterial( { color: color } ) );
34727 this.cone.matrixAutoUpdate = false;
34728 this.add( this.cone );
34729
34730 this.setDirection( dir );
34731 this.setLength( length, headLength, headWidth );
34732
34733 }
34734
34735 }() );
34736
34737 THREE.ArrowHelper.prototype = Object.create( THREE.Object3D.prototype );
34738 THREE.ArrowHelper.prototype.constructor = THREE.ArrowHelper;
34739
34740 THREE.ArrowHelper.prototype.setDirection = ( function () {
34741
34742 var axis = new THREE.Vector3();
34743 var radians;
34744
34745 return function setDirection( dir ) {
34746
34747
34748
34749 if ( dir.y > 0.99999 ) {
34750
34751 this.quaternion.set( 0, 0, 0, 1 );
34752
34753 } else if ( dir.y < - 0.99999 ) {
34754
34755 this.quaternion.set( 1, 0, 0, 0 );
34756
34757 } else {
34758
34759 axis.set( dir.z, 0, - dir.x ).normalize();
34760
34761 radians = Math.acos( dir.y );
34762
34763 this.quaternion.setFromAxisAngle( axis, radians );
34764
34765 }
34766
34767 };
34768
34769 }() );
34770
34771 THREE.ArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {
34772
34773 if ( headLength === undefined ) headLength = 0.2 * length;
34774 if ( headWidth === undefined ) headWidth = 0.2 * headLength;
34775
34776 if ( headLength < length ){
34777 this.line.scale.set( 1, length - headLength, 1 );
34778 this.line.updateMatrix();
34779 }
34780
34781 this.cone.scale.set( headWidth, headLength, headWidth );
34782 this.cone.position.y = length;
34783 this.cone.updateMatrix();
34784
34785 };
34786
34787 THREE.ArrowHelper.prototype.setColor = function ( color ) {
34788
34789 if ( this.line !== undefined ) this.line.material.color.set( color );
34790 this.cone.material.color.set( color );
34791
34792 };
34793
34794
34795
34800 THREE.BoxHelper = function ( object ) {
34801
34802 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 ] );
34803 var positions = new Float32Array( 8 * 3 );
34804
34805 var geometry = new THREE.BufferGeometry();
34806 geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );
34807 geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
34808
34809 THREE.LineSegments.call( this, geometry, new THREE.LineBasicMaterial( { color: 0xffff00 } ) );
34810
34811 if ( object !== undefined ) {
34812
34813 this.update( object );
34814
34815 }
34816
34817 };
34818
34819 THREE.BoxHelper.prototype = Object.create( THREE.LineSegments.prototype );
34820 THREE.BoxHelper.prototype.constructor = THREE.BoxHelper;
34821
34822 THREE.BoxHelper.prototype.update = ( function () {
34823
34824 var box = new THREE.Box3();
34825
34826 return function ( object ) {
34827
34828 box.setFromObject( object );
34829
34830 if ( box.empty() ) return;
34831
34832 var min = box.min;
34833 var max = box.max;
34834
34835
34836
34837
34838
34839
34840
34841
34842
34843
34844
34845
34846
34847
34848
34849
34850
34851 var position = this.geometry.attributes.position;
34852 var array = position.array;
34853
34854 array[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;
34855 array[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;
34856 array[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;
34857 array[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;
34858 array[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;
34859 array[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;
34860 array[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;
34861 array[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;
34862
34863 position.needsUpdate = true;
34864
34865 this.geometry.computeBoundingSphere();
34866
34867 }
34868
34869 } )();
34870
34871
34872
34877
34878
34879 THREE.BoundingBoxHelper = function ( object, hex ) {
34880
34881 var color = ( hex !== undefined ) ? hex : 0x888888;
34882
34883 this.object = object;
34884
34885 this.box = new THREE.Box3();
34886
34887 THREE.Mesh.call( this, new THREE.BoxGeometry( 1, 1, 1 ), new THREE.MeshBasicMaterial( { color: color, wireframe: true } ) );
34888
34889 };
34890
34891 THREE.BoundingBoxHelper.prototype = Object.create( THREE.Mesh.prototype );
34892 THREE.BoundingBoxHelper.prototype.constructor = THREE.BoundingBoxHelper;
34893
34894 THREE.BoundingBoxHelper.prototype.update = function () {
34895
34896 this.box.setFromObject( this.object );
34897
34898 this.box.size( this.scale );
34899
34900 this.box.center( this.position );
34901
34902 };
34903
34904
34905
34915 THREE.CameraHelper = function ( camera ) {
34916
34917 var geometry = new THREE.Geometry();
34918 var material = new THREE.LineBasicMaterial( { color: 0xffffff, vertexColors: THREE.FaceColors } );
34919
34920 var pointMap = {};
34921
34922
34923
34924 var hexFrustum = 0xffaa00;
34925 var hexCone = 0xff0000;
34926 var hexUp = 0x00aaff;
34927 var hexTarget = 0xffffff;
34928 var hexCross = 0x333333;
34929
34930
34931
34932 addLine( "n1", "n2", hexFrustum );
34933 addLine( "n2", "n4", hexFrustum );
34934 addLine( "n4", "n3", hexFrustum );
34935 addLine( "n3", "n1", hexFrustum );
34936
34937
34938
34939 addLine( "f1", "f2", hexFrustum );
34940 addLine( "f2", "f4", hexFrustum );
34941 addLine( "f4", "f3", hexFrustum );
34942 addLine( "f3", "f1", hexFrustum );
34943
34944
34945
34946 addLine( "n1", "f1", hexFrustum );
34947 addLine( "n2", "f2", hexFrustum );
34948 addLine( "n3", "f3", hexFrustum );
34949 addLine( "n4", "f4", hexFrustum );
34950
34951
34952
34953 addLine( "p", "n1", hexCone );
34954 addLine( "p", "n2", hexCone );
34955 addLine( "p", "n3", hexCone );
34956 addLine( "p", "n4", hexCone );
34957
34958
34959
34960 addLine( "u1", "u2", hexUp );
34961 addLine( "u2", "u3", hexUp );
34962 addLine( "u3", "u1", hexUp );
34963
34964
34965
34966 addLine( "c", "t", hexTarget );
34967 addLine( "p", "c", hexCross );
34968
34969
34970
34971 addLine( "cn1", "cn2", hexCross );
34972 addLine( "cn3", "cn4", hexCross );
34973
34974 addLine( "cf1", "cf2", hexCross );
34975 addLine( "cf3", "cf4", hexCross );
34976
34977 function addLine( a, b, hex ) {
34978
34979 addPoint( a, hex );
34980 addPoint( b, hex );
34981
34982 }
34983
34984 function addPoint( id, hex ) {
34985
34986 geometry.vertices.push( new THREE.Vector3() );
34987 geometry.colors.push( new THREE.Color( hex ) );
34988
34989 if ( pointMap[ id ] === undefined ) {
34990
34991 pointMap[ id ] = [];
34992
34993 }
34994
34995 pointMap[ id ].push( geometry.vertices.length - 1 );
34996
34997 }
34998
34999 THREE.LineSegments.call( this, geometry, material );
35000
35001 this.camera = camera;
35002 this.camera.updateProjectionMatrix();
35003
35004 this.matrix = camera.matrixWorld;
35005 this.matrixAutoUpdate = false;
35006
35007 this.pointMap = pointMap;
35008
35009 this.update();
35010
35011 };
35012
35013 THREE.CameraHelper.prototype = Object.create( THREE.LineSegments.prototype );
35014 THREE.CameraHelper.prototype.constructor = THREE.CameraHelper;
35015
35016 THREE.CameraHelper.prototype.update = function () {
35017
35018 var geometry, pointMap;
35019
35020 var vector = new THREE.Vector3();
35021 var camera = new THREE.Camera();
35022
35023 function setPoint( point, x, y, z ) {
35024
35025 vector.set( x, y, z ).unproject( camera );
35026
35027 var points = pointMap[ point ];
35028
35029 if ( points !== undefined ) {
35030
35031 for ( var i = 0, il = points.length; i < il; i ++ ) {
35032
35033 geometry.vertices[ points[ i ] ].copy( vector );
35034
35035 }
35036
35037 }
35038
35039 }
35040
35041 return function () {
35042
35043 geometry = this.geometry;
35044 pointMap = this.pointMap;
35045
35046 var w = 1, h = 1;
35047
35048
35049
35050
35051 camera.projectionMatrix.copy( this.camera.projectionMatrix );
35052
35053
35054
35055 setPoint( "c", 0, 0, - 1 );
35056 setPoint( "t", 0, 0, 1 );
35057
35058
35059
35060 setPoint( "n1", - w, - h, - 1 );
35061 setPoint( "n2", w, - h, - 1 );
35062 setPoint( "n3", - w, h, - 1 );
35063 setPoint( "n4", w, h, - 1 );
35064
35065
35066
35067 setPoint( "f1", - w, - h, 1 );
35068 setPoint( "f2", w, - h, 1 );
35069 setPoint( "f3", - w, h, 1 );
35070 setPoint( "f4", w, h, 1 );
35071
35072
35073
35074 setPoint( "u1", w * 0.7, h * 1.1, - 1 );
35075 setPoint( "u2", - w * 0.7, h * 1.1, - 1 );
35076 setPoint( "u3", 0, h * 2, - 1 );
35077
35078
35079
35080 setPoint( "cf1", - w, 0, 1 );
35081 setPoint( "cf2", w, 0, 1 );
35082 setPoint( "cf3", 0, - h, 1 );
35083 setPoint( "cf4", 0, h, 1 );
35084
35085 setPoint( "cn1", - w, 0, - 1 );
35086 setPoint( "cn2", w, 0, - 1 );
35087 setPoint( "cn3", 0, - h, - 1 );
35088 setPoint( "cn4", 0, h, - 1 );
35089
35090 geometry.verticesNeedUpdate = true;
35091
35092 };
35093
35094 }();
35095
35096
35097
35104 THREE.DirectionalLightHelper = function ( light, size ) {
35105
35106 THREE.Object3D.call( this );
35107
35108 this.light = light;
35109 this.light.updateMatrixWorld();
35110
35111 this.matrix = light.matrixWorld;
35112 this.matrixAutoUpdate = false;
35113
35114 size = size || 1;
35115
35116 var geometry = new THREE.Geometry();
35117 geometry.vertices.push(
35118 new THREE.Vector3( - size, size, 0 ),
35119 new THREE.Vector3( size, size, 0 ),
35120 new THREE.Vector3( size, - size, 0 ),
35121 new THREE.Vector3( - size, - size, 0 ),
35122 new THREE.Vector3( - size, size, 0 )
35123 );
35124
35125 var material = new THREE.LineBasicMaterial( { fog: false } );
35126 material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );
35127
35128 this.lightPlane = new THREE.Line( geometry, material );
35129 this.add( this.lightPlane );
35130
35131 geometry = new THREE.Geometry();
35132 geometry.vertices.push(
35133 new THREE.Vector3(),
35134 new THREE.Vector3()
35135 );
35136
35137 material = new THREE.LineBasicMaterial( { fog: false } );
35138 material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );
35139
35140 this.targetLine = new THREE.Line( geometry, material );
35141 this.add( this.targetLine );
35142
35143 this.update();
35144
35145 };
35146
35147 THREE.DirectionalLightHelper.prototype = Object.create( THREE.Object3D.prototype );
35148 THREE.DirectionalLightHelper.prototype.constructor = THREE.DirectionalLightHelper;
35149
35150 THREE.DirectionalLightHelper.prototype.dispose = function () {
35151
35152 this.lightPlane.geometry.dispose();
35153 this.lightPlane.material.dispose();
35154 this.targetLine.geometry.dispose();
35155 this.targetLine.material.dispose();
35156
35157 };
35158
35159 THREE.DirectionalLightHelper.prototype.update = function () {
35160
35161 var v1 = new THREE.Vector3();
35162 var v2 = new THREE.Vector3();
35163 var v3 = new THREE.Vector3();
35164
35165 return function () {
35166
35167 v1.setFromMatrixPosition( this.light.matrixWorld );
35168 v2.setFromMatrixPosition( this.light.target.matrixWorld );
35169 v3.subVectors( v2, v1 );
35170
35171 this.lightPlane.lookAt( v3 );
35172 this.lightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );
35173
35174 this.targetLine.geometry.vertices[ 1 ].copy( v3 );
35175 this.targetLine.geometry.verticesNeedUpdate = true;
35176 this.targetLine.material.color.copy( this.lightPlane.material.color );
35177
35178 };
35179
35180 }();
35181
35182
35183
35194 THREE.EdgesHelper = function ( object, hex, thresholdAngle ) {
35195
35196 var color = ( hex !== undefined ) ? hex : 0xffffff;
35197
35198 THREE.LineSegments.call( this, new THREE.EdgesGeometry( object.geometry, thresholdAngle ), new THREE.LineBasicMaterial( { color: color } ) );
35199
35200 this.matrix = object.matrixWorld;
35201 this.matrixAutoUpdate = false;
35202
35203 };
35204
35205 THREE.EdgesHelper.prototype = Object.create( THREE.LineSegments.prototype );
35206 THREE.EdgesHelper.prototype.constructor = THREE.EdgesHelper;
35207
35208
35209
35215 THREE.FaceNormalsHelper = function ( object, size, hex, linewidth ) {
35216
35217
35218
35219 this.object = object;
35220
35221 this.size = ( size !== undefined ) ? size : 1;
35222
35223 var color = ( hex !== undefined ) ? hex : 0xffff00;
35224
35225 var width = ( linewidth !== undefined ) ? linewidth : 1;
35226
35227
35228
35229 var nNormals = 0;
35230
35231 var objGeometry = this.object.geometry;
35232
35233 if ( objGeometry instanceof THREE.Geometry ) {
35234
35235 nNormals = objGeometry.faces.length;
35236
35237 } else {
35238
35239 console.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );
35240
35241 }
35242
35243
35244
35245 var geometry = new THREE.BufferGeometry();
35246
35247 var positions = new THREE.Float32Attribute( nNormals * 2 * 3, 3 );
35248
35249 geometry.addAttribute( 'position', positions );
35250
35251 THREE.LineSegments.call( this, geometry, new THREE.LineBasicMaterial( { color: color, linewidth: width } ) );
35252
35253
35254
35255 this.matrixAutoUpdate = false;
35256 this.update();
35257
35258 };
35259
35260 THREE.FaceNormalsHelper.prototype = Object.create( THREE.LineSegments.prototype );
35261 THREE.FaceNormalsHelper.prototype.constructor = THREE.FaceNormalsHelper;
35262
35263 THREE.FaceNormalsHelper.prototype.update = ( function () {
35264
35265 var v1 = new THREE.Vector3();
35266 var v2 = new THREE.Vector3();
35267 var normalMatrix = new THREE.Matrix3();
35268
35269 return function update() {
35270
35271 this.object.updateMatrixWorld( true );
35272
35273 normalMatrix.getNormalMatrix( this.object.matrixWorld );
35274
35275 var matrixWorld = this.object.matrixWorld;
35276
35277 var position = this.geometry.attributes.position;
35278
35279
35280
35281 var objGeometry = this.object.geometry;
35282
35283 var vertices = objGeometry.vertices;
35284
35285 var faces = objGeometry.faces;
35286
35287 var idx = 0;
35288
35289 for ( var i = 0, l = faces.length; i < l; i ++ ) {
35290
35291 var face = faces[ i ];
35292
35293 var normal = face.normal;
35294
35295 v1.copy( vertices[ face.a ] )
35296 .add( vertices[ face.b ] )
35297 .add( vertices[ face.c ] )
35298 .divideScalar( 3 )
35299 .applyMatrix4( matrixWorld );
35300
35301 v2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );
35302
35303 position.setXYZ( idx, v1.x, v1.y, v1.z );
35304
35305 idx = idx + 1;
35306
35307 position.setXYZ( idx, v2.x, v2.y, v2.z );
35308
35309 idx = idx + 1;
35310
35311 }
35312
35313 position.needsUpdate = true;
35314
35315 return this;
35316
35317 }
35318
35319 }() );
35320
35321
35322
35327 THREE.GridHelper = function ( size, step ) {
35328
35329 var geometry = new THREE.Geometry();
35330 var material = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors } );
35331
35332 this.color1 = new THREE.Color( 0x444444 );
35333 this.color2 = new THREE.Color( 0x888888 );
35334
35335 for ( var i = - size; i <= size; i += step ) {
35336
35337 geometry.vertices.push(
35338 new THREE.Vector3( - size, 0, i ), new THREE.Vector3( size, 0, i ),
35339 new THREE.Vector3( i, 0, - size ), new THREE.Vector3( i, 0, size )
35340 );
35341
35342 var color = i === 0 ? this.color1 : this.color2;
35343
35344 geometry.colors.push( color, color, color, color );
35345
35346 }
35347
35348 THREE.LineSegments.call( this, geometry, material );
35349
35350 };
35351
35352 THREE.GridHelper.prototype = Object.create( THREE.LineSegments.prototype );
35353 THREE.GridHelper.prototype.constructor = THREE.GridHelper;
35354
35355 THREE.GridHelper.prototype.setColors = function( colorCenterLine, colorGrid ) {
35356
35357 this.color1.set( colorCenterLine );
35358 this.color2.set( colorGrid );
35359
35360 this.geometry.colorsNeedUpdate = true;
35361
35362 };
35363
35364
35365
35371 THREE.HemisphereLightHelper = function ( light, sphereSize ) {
35372
35373 THREE.Object3D.call( this );
35374
35375 this.light = light;
35376 this.light.updateMatrixWorld();
35377
35378 this.matrix = light.matrixWorld;
35379 this.matrixAutoUpdate = false;
35380
35381 this.colors = [ new THREE.Color(), new THREE.Color() ];
35382
35383 var geometry = new THREE.SphereGeometry( sphereSize, 4, 2 );
35384 geometry.rotateX( - Math.PI / 2 );
35385
35386 for ( var i = 0, il = 8; i < il; i ++ ) {
35387
35388 geometry.faces[ i ].color = this.colors[ i < 4 ? 0 : 1 ];
35389
35390 }
35391
35392 var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, wireframe: true } );
35393
35394 this.lightSphere = new THREE.Mesh( geometry, material );
35395 this.add( this.lightSphere );
35396
35397 this.update();
35398
35399 };
35400
35401 THREE.HemisphereLightHelper.prototype = Object.create( THREE.Object3D.prototype );
35402 THREE.HemisphereLightHelper.prototype.constructor = THREE.HemisphereLightHelper;
35403
35404 THREE.HemisphereLightHelper.prototype.dispose = function () {
35405
35406 this.lightSphere.geometry.dispose();
35407 this.lightSphere.material.dispose();
35408
35409 };
35410
35411 THREE.HemisphereLightHelper.prototype.update = function () {
35412
35413 var vector = new THREE.Vector3();
35414
35415 return function () {
35416
35417 this.colors[ 0 ].copy( this.light.color ).multiplyScalar( this.light.intensity );
35418 this.colors[ 1 ].copy( this.light.groundColor ).multiplyScalar( this.light.intensity );
35419
35420 this.lightSphere.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );
35421 this.lightSphere.geometry.colorsNeedUpdate = true;
35422
35423 }
35424
35425 }();
35426
35427
35428
35434 THREE.PointLightHelper = function ( light, sphereSize ) {
35435
35436 this.light = light;
35437 this.light.updateMatrixWorld();
35438
35439 var geometry = new THREE.SphereGeometry( sphereSize, 4, 2 );
35440 var material = new THREE.MeshBasicMaterial( { wireframe: true, fog: false } );
35441 material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );
35442
35443 THREE.Mesh.call( this, geometry, material );
35444
35445 this.matrix = this.light.matrixWorld;
35446 this.matrixAutoUpdate = false;
35447
35448
35449
35450
35451
35452
35453
35454
35455
35456
35457
35458
35459
35460
35461
35462
35463
35464
35465
35466
35467
35468
35469
35470 };
35471
35472 THREE.PointLightHelper.prototype = Object.create( THREE.Mesh.prototype );
35473 THREE.PointLightHelper.prototype.constructor = THREE.PointLightHelper;
35474
35475 THREE.PointLightHelper.prototype.dispose = function () {
35476
35477 this.geometry.dispose();
35478 this.material.dispose();
35479
35480 };
35481
35482 THREE.PointLightHelper.prototype.update = function () {
35483
35484 this.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );
35485
35486
35487
35488
35489
35490
35491
35492
35493
35494
35495
35496
35497
35498
35499
35500
35501 };
35502
35503
35504
35512 THREE.SkeletonHelper = function ( object ) {
35513
35514 this.bones = this.getBoneList( object );
35515
35516 var geometry = new THREE.Geometry();
35517
35518 for ( var i = 0; i < this.bones.length; i ++ ) {
35519
35520 var bone = this.bones[ i ];
35521
35522 if ( bone.parent instanceof THREE.Bone ) {
35523
35524 geometry.vertices.push( new THREE.Vector3() );
35525 geometry.vertices.push( new THREE.Vector3() );
35526 geometry.colors.push( new THREE.Color( 0, 0, 1 ) );
35527 geometry.colors.push( new THREE.Color( 0, 1, 0 ) );
35528
35529 }
35530
35531 }
35532
35533 geometry.dynamic = true;
35534
35535 var material = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors, depthTest: false, depthWrite: false, transparent: true } );
35536
35537 THREE.LineSegments.call( this, geometry, material );
35538
35539 this.root = object;
35540
35541 this.matrix = object.matrixWorld;
35542 this.matrixAutoUpdate = false;
35543
35544 this.update();
35545
35546 };
35547
35548
35549 THREE.SkeletonHelper.prototype = Object.create( THREE.LineSegments.prototype );
35550 THREE.SkeletonHelper.prototype.constructor = THREE.SkeletonHelper;
35551
35552 THREE.SkeletonHelper.prototype.getBoneList = function( object ) {
35553
35554 var boneList = [];
35555
35556 if ( object instanceof THREE.Bone ) {
35557
35558 boneList.push( object );
35559
35560 }
35561
35562 for ( var i = 0; i < object.children.length; i ++ ) {
35563
35564 boneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );
35565
35566 }
35567
35568 return boneList;
35569
35570 };
35571
35572 THREE.SkeletonHelper.prototype.update = function () {
35573
35574 var geometry = this.geometry;
35575
35576 var matrixWorldInv = new THREE.Matrix4().getInverse( this.root.matrixWorld );
35577
35578 var boneMatrix = new THREE.Matrix4();
35579
35580 var j = 0;
35581
35582 for ( var i = 0; i < this.bones.length; i ++ ) {
35583
35584 var bone = this.bones[ i ];
35585
35586 if ( bone.parent instanceof THREE.Bone ) {
35587
35588 boneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );
35589 geometry.vertices[ j ].setFromMatrixPosition( boneMatrix );
35590
35591 boneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );
35592 geometry.vertices[ j + 1 ].setFromMatrixPosition( boneMatrix );
35593
35594 j += 2;
35595
35596 }
35597
35598 }
35599
35600 geometry.verticesNeedUpdate = true;
35601
35602 geometry.computeBoundingSphere();
35603
35604 };
35605
35606
35607
35614 THREE.SpotLightHelper = function ( light ) {
35615
35616 THREE.Object3D.call( this );
35617
35618 this.light = light;
35619 this.light.updateMatrixWorld();
35620
35621 this.matrix = light.matrixWorld;
35622 this.matrixAutoUpdate = false;
35623
35624 var geometry = new THREE.CylinderGeometry( 0, 1, 1, 8, 1, true );
35625
35626 geometry.translate( 0, - 0.5, 0 );
35627 geometry.rotateX( - Math.PI / 2 );
35628
35629 var material = new THREE.MeshBasicMaterial( { wireframe: true, fog: false } );
35630
35631 this.cone = new THREE.Mesh( geometry, material );
35632 this.add( this.cone );
35633
35634 this.update();
35635
35636 };
35637
35638 THREE.SpotLightHelper.prototype = Object.create( THREE.Object3D.prototype );
35639 THREE.SpotLightHelper.prototype.constructor = THREE.SpotLightHelper;
35640
35641 THREE.SpotLightHelper.prototype.dispose = function () {
35642
35643 this.cone.geometry.dispose();
35644 this.cone.material.dispose();
35645
35646 };
35647
35648 THREE.SpotLightHelper.prototype.update = function () {
35649
35650 var vector = new THREE.Vector3();
35651 var vector2 = new THREE.Vector3();
35652
35653 return function () {
35654
35655 var coneLength = this.light.distance ? this.light.distance : 10000;
35656 var coneWidth = coneLength * Math.tan( this.light.angle );
35657
35658 this.cone.scale.set( coneWidth, coneWidth, coneLength );
35659
35660 vector.setFromMatrixPosition( this.light.matrixWorld );
35661 vector2.setFromMatrixPosition( this.light.target.matrixWorld );
35662
35663 this.cone.lookAt( vector2.sub( vector ) );
35664
35665 this.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );
35666
35667 };
35668
35669 }();
35670
35671
35672
35678 THREE.VertexNormalsHelper = function ( object, size, hex, linewidth ) {
35679
35680 this.object = object;
35681
35682 this.size = ( size !== undefined ) ? size : 1;
35683
35684 var color = ( hex !== undefined ) ? hex : 0xff0000;
35685
35686 var width = ( linewidth !== undefined ) ? linewidth : 1;
35687
35688
35689
35690 var nNormals = 0;
35691
35692 var objGeometry = this.object.geometry;
35693
35694 if ( objGeometry instanceof THREE.Geometry ) {
35695
35696 nNormals = objGeometry.faces.length * 3;
35697
35698 } else if ( objGeometry instanceof THREE.BufferGeometry ) {
35699
35700 nNormals = objGeometry.attributes.normal.count
35701
35702 }
35703
35704
35705
35706 var geometry = new THREE.BufferGeometry();
35707
35708 var positions = new THREE.Float32Attribute( nNormals * 2 * 3, 3 );
35709
35710 geometry.addAttribute( 'position', positions );
35711
35712 THREE.LineSegments.call( this, geometry, new THREE.LineBasicMaterial( { color: color, linewidth: width } ) );
35713
35714
35715
35716 this.matrixAutoUpdate = false;
35717
35718 this.update();
35719
35720 };
35721
35722 THREE.VertexNormalsHelper.prototype = Object.create( THREE.LineSegments.prototype );
35723 THREE.VertexNormalsHelper.prototype.constructor = THREE.VertexNormalsHelper;
35724
35725 THREE.VertexNormalsHelper.prototype.update = ( function () {
35726
35727 var v1 = new THREE.Vector3();
35728 var v2 = new THREE.Vector3();
35729 var normalMatrix = new THREE.Matrix3();
35730
35731 return function update() {
35732
35733 var keys = [ 'a', 'b', 'c' ];
35734
35735 this.object.updateMatrixWorld( true );
35736
35737 normalMatrix.getNormalMatrix( this.object.matrixWorld );
35738
35739 var matrixWorld = this.object.matrixWorld;
35740
35741 var position = this.geometry.attributes.position;
35742
35743
35744
35745 var objGeometry = this.object.geometry;
35746
35747 if ( objGeometry instanceof THREE.Geometry ) {
35748
35749 var vertices = objGeometry.vertices;
35750
35751 var faces = objGeometry.faces;
35752
35753 var idx = 0;
35754
35755 for ( var i = 0, l = faces.length; i < l; i ++ ) {
35756
35757 var face = faces[ i ];
35758
35759 for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
35760
35761 var vertex = vertices[ face[ keys[ j ] ] ];
35762
35763 var normal = face.vertexNormals[ j ];
35764
35765 v1.copy( vertex ).applyMatrix4( matrixWorld );
35766
35767 v2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );
35768
35769 position.setXYZ( idx, v1.x, v1.y, v1.z );
35770
35771 idx = idx + 1;
35772
35773 position.setXYZ( idx, v2.x, v2.y, v2.z );
35774
35775 idx = idx + 1;
35776
35777 }
35778
35779 }
35780
35781 } else if ( objGeometry instanceof THREE.BufferGeometry ) {
35782
35783 var objPos = objGeometry.attributes.position;
35784
35785 var objNorm = objGeometry.attributes.normal;
35786
35787 var idx = 0;
35788
35789
35790
35791 for ( var j = 0, jl = objPos.count; j < jl; j ++ ) {
35792
35793 v1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );
35794
35795 v2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );
35796
35797 v2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );
35798
35799 position.setXYZ( idx, v1.x, v1.y, v1.z );
35800
35801 idx = idx + 1;
35802
35803 position.setXYZ( idx, v2.x, v2.y, v2.z );
35804
35805 idx = idx + 1;
35806
35807 }
35808
35809 }
35810
35811 position.needsUpdate = true;
35812
35813 return this;
35814
35815 }
35816
35817 }() );
35818
35819
35820
35825 THREE.WireframeHelper = function ( object, hex ) {
35826
35827 var color = ( hex !== undefined ) ? hex : 0xffffff;
35828
35829 THREE.LineSegments.call( this, new THREE.WireframeGeometry( object.geometry ), new THREE.LineBasicMaterial( { color: color } ) );
35830
35831 this.matrix = object.matrixWorld;
35832 this.matrixAutoUpdate = false;
35833
35834 };
35835
35836 THREE.WireframeHelper.prototype = Object.create( THREE.LineSegments.prototype );
35837 THREE.WireframeHelper.prototype.constructor = THREE.WireframeHelper;
35838
35839
35840
35845 THREE.ImmediateRenderObject = function ( material ) {
35846
35847 THREE.Object3D.call( this );
35848
35849 this.material = material;
35850 this.render = function ( renderCallback ) {};
35851
35852 };
35853
35854 THREE.ImmediateRenderObject.prototype = Object.create( THREE.Object3D.prototype );
35855 THREE.ImmediateRenderObject.prototype.constructor = THREE.ImmediateRenderObject;
35856
35857
35858
35863 THREE.MorphBlendMesh = function( geometry, material ) {
35864
35865 THREE.Mesh.call( this, geometry, material );
35866
35867 this.animationsMap = {};
35868 this.animationsList = [];
35869
35870
35871
35872
35873 var numFrames = this.geometry.morphTargets.length;
35874
35875 var name = "__default";
35876
35877 var startFrame = 0;
35878 var endFrame = numFrames - 1;
35879
35880 var fps = numFrames / 1;
35881
35882 this.createAnimation( name, startFrame, endFrame, fps );
35883 this.setAnimationWeight( name, 1 );
35884
35885 };
35886
35887 THREE.MorphBlendMesh.prototype = Object.create( THREE.Mesh.prototype );
35888 THREE.MorphBlendMesh.prototype.constructor = THREE.MorphBlendMesh;
35889
35890 THREE.MorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {
35891
35892 var animation = {
35893
35894 start: start,
35895 end: end,
35896
35897 length: end - start + 1,
35898
35899 fps: fps,
35900 duration: ( end - start ) / fps,
35901
35902 lastFrame: 0,
35903 currentFrame: 0,
35904
35905 active: false,
35906
35907 time: 0,
35908 direction: 1,
35909 weight: 1,
35910
35911 directionBackwards: false,
35912 mirroredLoop: false
35913
35914 };
35915
35916 this.animationsMap[ name ] = animation;
35917 this.animationsList.push( animation );
35918
35919 };
35920
35921 THREE.MorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {
35922
35923 var pattern = /([a-z]+)_?(\d+)/;
35924
35925 var firstAnimation, frameRanges = {};
35926
35927 var geometry = this.geometry;
35928
35929 for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {
35930
35931 var morph = geometry.morphTargets[ i ];
35932 var chunks = morph.name.match( pattern );
35933
35934 if ( chunks && chunks.length > 1 ) {
35935
35936 var name = chunks[ 1 ];
35937
35938 if ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };
35939
35940 var range = frameRanges[ name ];
35941
35942 if ( i < range.start ) range.start = i;
35943 if ( i > range.end ) range.end = i;
35944
35945 if ( ! firstAnimation ) firstAnimation = name;
35946
35947 }
35948
35949 }
35950
35951 for ( var name in frameRanges ) {
35952
35953 var range = frameRanges[ name ];
35954 this.createAnimation( name, range.start, range.end, fps );
35955
35956 }
35957
35958 this.firstAnimation = firstAnimation;
35959
35960 };
35961
35962 THREE.MorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {
35963
35964 var animation = this.animationsMap[ name ];
35965
35966 if ( animation ) {
35967
35968 animation.direction = 1;
35969 animation.directionBackwards = false;
35970
35971 }
35972
35973 };
35974
35975 THREE.MorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {
35976
35977 var animation = this.animationsMap[ name ];
35978
35979 if ( animation ) {
35980
35981 animation.direction = - 1;
35982 animation.directionBackwards = true;
35983
35984 }
35985
35986 };
35987
35988 THREE.MorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {
35989
35990 var animation = this.animationsMap[ name ];
35991
35992 if ( animation ) {
35993
35994 animation.fps = fps;
35995 animation.duration = ( animation.end - animation.start ) / animation.fps;
35996
35997 }
35998
35999 };
36000
36001 THREE.MorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {
36002
36003 var animation = this.animationsMap[ name ];
36004
36005 if ( animation ) {
36006
36007 animation.duration = duration;
36008 animation.fps = ( animation.end - animation.start ) / animation.duration;
36009
36010 }
36011
36012 };
36013
36014 THREE.MorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {
36015
36016 var animation = this.animationsMap[ name ];
36017
36018 if ( animation ) {
36019
36020 animation.weight = weight;
36021
36022 }
36023
36024 };
36025
36026 THREE.MorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {
36027
36028 var animation = this.animationsMap[ name ];
36029
36030 if ( animation ) {
36031
36032 animation.time = time;
36033
36034 }
36035
36036 };
36037
36038 THREE.MorphBlendMesh.prototype.getAnimationTime = function ( name ) {
36039
36040 var time = 0;
36041
36042 var animation = this.animationsMap[ name ];
36043
36044 if ( animation ) {
36045
36046 time = animation.time;
36047
36048 }
36049
36050 return time;
36051
36052 };
36053
36054 THREE.MorphBlendMesh.prototype.getAnimationDuration = function ( name ) {
36055
36056 var duration = - 1;
36057
36058 var animation = this.animationsMap[ name ];
36059
36060 if ( animation ) {
36061
36062 duration = animation.duration;
36063
36064 }
36065
36066 return duration;
36067
36068 };
36069
36070 THREE.MorphBlendMesh.prototype.playAnimation = function ( name ) {
36071
36072 var animation = this.animationsMap[ name ];
36073
36074 if ( animation ) {
36075
36076 animation.time = 0;
36077 animation.active = true;
36078
36079 } else {
36080
36081 console.warn( "THREE.MorphBlendMesh: animation[" + name + "] undefined in .playAnimation()" );
36082
36083 }
36084
36085 };
36086
36087 THREE.MorphBlendMesh.prototype.stopAnimation = function ( name ) {
36088
36089 var animation = this.animationsMap[ name ];
36090
36091 if ( animation ) {
36092
36093 animation.active = false;
36094
36095 }
36096
36097 };
36098
36099 THREE.MorphBlendMesh.prototype.update = function ( delta ) {
36100
36101 for ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {
36102
36103 var animation = this.animationsList[ i ];
36104
36105 if ( ! animation.active ) continue;
36106
36107 var frameTime = animation.duration / animation.length;
36108
36109 animation.time += animation.direction * delta;
36110
36111 if ( animation.mirroredLoop ) {
36112
36113 if ( animation.time > animation.duration || animation.time < 0 ) {
36114
36115 animation.direction *= - 1;
36116
36117 if ( animation.time > animation.duration ) {
36118
36119 animation.time = animation.duration;
36120 animation.directionBackwards = true;
36121
36122 }
36123
36124 if ( animation.time < 0 ) {
36125
36126 animation.time = 0;
36127 animation.directionBackwards = false;
36128
36129 }
36130
36131 }
36132
36133 } else {
36134
36135 animation.time = animation.time % animation.duration;
36136
36137 if ( animation.time < 0 ) animation.time += animation.duration;
36138
36139 }
36140
36141 var keyframe = animation.start + THREE.Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );
36142 var weight = animation.weight;
36143
36144 if ( keyframe !== animation.currentFrame ) {
36145
36146 this.morphTargetInfluences[ animation.lastFrame ] = 0;
36147 this.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;
36148
36149 this.morphTargetInfluences[ keyframe ] = 0;
36150
36151 animation.lastFrame = animation.currentFrame;
36152 animation.currentFrame = keyframe;
36153
36154 }
36155
36156 var mix = ( animation.time % frameTime ) / frameTime;
36157
36158 if ( animation.directionBackwards ) mix = 1 - mix;
36159
36160 if ( animation.currentFrame !== animation.lastFrame ) {
36161
36162 this.morphTargetInfluences[ animation.currentFrame ] = mix * weight;
36163 this.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;
36164
36165 } else {
36166
36167 this.morphTargetInfluences[ animation.currentFrame ] = weight;
36168
36169 }
36170
36171 }
36172
36173 };
36174