1/** 2 * @license 3 * Copyright 2010-2021 Three.js Authors 4 * SPDX-License-Identifier: MIT 5 */ 6(function (global, factory) { 7 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 8 typeof define === 'function' && define.amd ? define(['exports'], factory) : 9 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.THREE = {})); 10})(this, (function (exports) { 'use strict'; 11 12 const REVISION = '136'; 13 const MOUSE = { 14 LEFT: 0, 15 MIDDLE: 1, 16 RIGHT: 2, 17 ROTATE: 0, 18 DOLLY: 1, 19 PAN: 2 20 }; 21 const TOUCH = { 22 ROTATE: 0, 23 PAN: 1, 24 DOLLY_PAN: 2, 25 DOLLY_ROTATE: 3 26 }; 27 const CullFaceNone = 0; 28 const CullFaceBack = 1; 29 const CullFaceFront = 2; 30 const CullFaceFrontBack = 3; 31 const BasicShadowMap = 0; 32 const PCFShadowMap = 1; 33 const PCFSoftShadowMap = 2; 34 const VSMShadowMap = 3; 35 const FrontSide = 0; 36 const BackSide = 1; 37 const DoubleSide = 2; 38 const FlatShading = 1; 39 const SmoothShading = 2; 40 const NoBlending = 0; 41 const NormalBlending = 1; 42 const AdditiveBlending = 2; 43 const SubtractiveBlending = 3; 44 const MultiplyBlending = 4; 45 const CustomBlending = 5; 46 const AddEquation = 100; 47 const SubtractEquation = 101; 48 const ReverseSubtractEquation = 102; 49 const MinEquation = 103; 50 const MaxEquation = 104; 51 const ZeroFactor = 200; 52 const OneFactor = 201; 53 const SrcColorFactor = 202; 54 const OneMinusSrcColorFactor = 203; 55 const SrcAlphaFactor = 204; 56 const OneMinusSrcAlphaFactor = 205; 57 const DstAlphaFactor = 206; 58 const OneMinusDstAlphaFactor = 207; 59 const DstColorFactor = 208; 60 const OneMinusDstColorFactor = 209; 61 const SrcAlphaSaturateFactor = 210; 62 const NeverDepth = 0; 63 const AlwaysDepth = 1; 64 const LessDepth = 2; 65 const LessEqualDepth = 3; 66 const EqualDepth = 4; 67 const GreaterEqualDepth = 5; 68 const GreaterDepth = 6; 69 const NotEqualDepth = 7; 70 const MultiplyOperation = 0; 71 const MixOperation = 1; 72 const AddOperation = 2; 73 const NoToneMapping = 0; 74 const LinearToneMapping = 1; 75 const ReinhardToneMapping = 2; 76 const CineonToneMapping = 3; 77 const ACESFilmicToneMapping = 4; 78 const CustomToneMapping = 5; 79 const UVMapping = 300; 80 const CubeReflectionMapping = 301; 81 const CubeRefractionMapping = 302; 82 const EquirectangularReflectionMapping = 303; 83 const EquirectangularRefractionMapping = 304; 84 const CubeUVReflectionMapping = 306; 85 const CubeUVRefractionMapping = 307; 86 const RepeatWrapping = 1000; 87 const ClampToEdgeWrapping = 1001; 88 const MirroredRepeatWrapping = 1002; 89 const NearestFilter = 1003; 90 const NearestMipmapNearestFilter = 1004; 91 const NearestMipMapNearestFilter = 1004; 92 const NearestMipmapLinearFilter = 1005; 93 const NearestMipMapLinearFilter = 1005; 94 const LinearFilter = 1006; 95 const LinearMipmapNearestFilter = 1007; 96 const LinearMipMapNearestFilter = 1007; 97 const LinearMipmapLinearFilter = 1008; 98 const LinearMipMapLinearFilter = 1008; 99 const UnsignedByteType = 1009; 100 const ByteType = 1010; 101 const ShortType = 1011; 102 const UnsignedShortType = 1012; 103 const IntType = 1013; 104 const UnsignedIntType = 1014; 105 const FloatType = 1015; 106 const HalfFloatType = 1016; 107 const UnsignedShort4444Type = 1017; 108 const UnsignedShort5551Type = 1018; 109 const UnsignedShort565Type = 1019; 110 const UnsignedInt248Type = 1020; 111 const AlphaFormat = 1021; 112 const RGBFormat = 1022; 113 const RGBAFormat = 1023; 114 const LuminanceFormat = 1024; 115 const LuminanceAlphaFormat = 1025; 116 const DepthFormat = 1026; 117 const DepthStencilFormat = 1027; 118 const RedFormat = 1028; 119 const RedIntegerFormat = 1029; 120 const RGFormat = 1030; 121 const RGIntegerFormat = 1031; 122 const RGBIntegerFormat = 1032; 123 const RGBAIntegerFormat = 1033; 124 const RGB_S3TC_DXT1_Format = 33776; 125 const RGBA_S3TC_DXT1_Format = 33777; 126 const RGBA_S3TC_DXT3_Format = 33778; 127 const RGBA_S3TC_DXT5_Format = 33779; 128 const RGB_PVRTC_4BPPV1_Format = 35840; 129 const RGB_PVRTC_2BPPV1_Format = 35841; 130 const RGBA_PVRTC_4BPPV1_Format = 35842; 131 const RGBA_PVRTC_2BPPV1_Format = 35843; 132 const RGB_ETC1_Format = 36196; 133 const RGB_ETC2_Format = 37492; 134 const RGBA_ETC2_EAC_Format = 37496; 135 const RGBA_ASTC_4x4_Format = 37808; 136 const RGBA_ASTC_5x4_Format = 37809; 137 const RGBA_ASTC_5x5_Format = 37810; 138 const RGBA_ASTC_6x5_Format = 37811; 139 const RGBA_ASTC_6x6_Format = 37812; 140 const RGBA_ASTC_8x5_Format = 37813; 141 const RGBA_ASTC_8x6_Format = 37814; 142 const RGBA_ASTC_8x8_Format = 37815; 143 const RGBA_ASTC_10x5_Format = 37816; 144 const RGBA_ASTC_10x6_Format = 37817; 145 const RGBA_ASTC_10x8_Format = 37818; 146 const RGBA_ASTC_10x10_Format = 37819; 147 const RGBA_ASTC_12x10_Format = 37820; 148 const RGBA_ASTC_12x12_Format = 37821; 149 const RGBA_BPTC_Format = 36492; 150 const SRGB8_ALPHA8_ASTC_4x4_Format = 37840; 151 const SRGB8_ALPHA8_ASTC_5x4_Format = 37841; 152 const SRGB8_ALPHA8_ASTC_5x5_Format = 37842; 153 const SRGB8_ALPHA8_ASTC_6x5_Format = 37843; 154 const SRGB8_ALPHA8_ASTC_6x6_Format = 37844; 155 const SRGB8_ALPHA8_ASTC_8x5_Format = 37845; 156 const SRGB8_ALPHA8_ASTC_8x6_Format = 37846; 157 const SRGB8_ALPHA8_ASTC_8x8_Format = 37847; 158 const SRGB8_ALPHA8_ASTC_10x5_Format = 37848; 159 const SRGB8_ALPHA8_ASTC_10x6_Format = 37849; 160 const SRGB8_ALPHA8_ASTC_10x8_Format = 37850; 161 const SRGB8_ALPHA8_ASTC_10x10_Format = 37851; 162 const SRGB8_ALPHA8_ASTC_12x10_Format = 37852; 163 const SRGB8_ALPHA8_ASTC_12x12_Format = 37853; 164 const LoopOnce = 2200; 165 const LoopRepeat = 2201; 166 const LoopPingPong = 2202; 167 const InterpolateDiscrete = 2300; 168 const InterpolateLinear = 2301; 169 const InterpolateSmooth = 2302; 170 const ZeroCurvatureEnding = 2400; 171 const ZeroSlopeEnding = 2401; 172 const WrapAroundEnding = 2402; 173 const NormalAnimationBlendMode = 2500; 174 const AdditiveAnimationBlendMode = 2501; 175 const TrianglesDrawMode = 0; 176 const TriangleStripDrawMode = 1; 177 const TriangleFanDrawMode = 2; 178 const LinearEncoding = 3000; 179 const sRGBEncoding = 3001; 180 const BasicDepthPacking = 3200; 181 const RGBADepthPacking = 3201; 182 const TangentSpaceNormalMap = 0;
vendor: 5,189 bytes, lines 183-356
183 const ObjectSpaceNormalMap = 1; 184 const ZeroStencilOp = 0; 185 const KeepStencilOp = 7680; 186 const ReplaceStencilOp = 7681; 187 const IncrementStencilOp = 7682; 188 const DecrementStencilOp = 7683; 189 const IncrementWrapStencilOp = 34055; 190 const DecrementWrapStencilOp = 34056; 191 const InvertStencilOp = 5386; 192 const NeverStencilFunc = 512; 193 const LessStencilFunc = 513; 194 const EqualStencilFunc = 514; 195 const LessEqualStencilFunc = 515; 196 const GreaterStencilFunc = 516; 197 const NotEqualStencilFunc = 517; 198 const GreaterEqualStencilFunc = 518; 199 const AlwaysStencilFunc = 519; 200 const StaticDrawUsage = 35044; 201 const DynamicDrawUsage = 35048; 202 const StreamDrawUsage = 35040; 203 const StaticReadUsage = 35045; 204 const DynamicReadUsage = 35049; 205 const StreamReadUsage = 35041; 206 const StaticCopyUsage = 35046; 207 const DynamicCopyUsage = 35050; 208 const StreamCopyUsage = 35042; 209 const GLSL1 = '100'; 210 const GLSL3 = '300 es'; 211 212 /** 213 * https://github.com/mrdoob/eventdispatcher.js/ 214 */ 215 class EventDispatcher { 216 addEventListener(type, listener) { 217 if (this._listeners === undefined) this._listeners = {}; 218 const listeners = this._listeners; 219 220 if (listeners[type] === undefined) { 221 listeners[type] = []; 222 } 223 224 if (listeners[type].indexOf(listener) === -1) { 225 listeners[type].push(listener); 226 } 227 } 228 229 hasEventListener(type, listener) { 230 if (this._listeners === undefined) return false; 231 const listeners = this._listeners; 232 return listeners[type] !== undefined && listeners[type].indexOf(listener) !== -1; 233 } 234 235 removeEventListener(type, listener) { 236 if (this._listeners === undefined) return; 237 const listeners = this._listeners; 238 const listenerArray = listeners[type]; 239 240 if (listenerArray !== undefined) { 241 const index = listenerArray.indexOf(listener); 242 243 if (index !== -1) { 244 listenerArray.splice(index, 1); 245 } 246 } 247 } 248 249 dispatchEvent(event) { 250 if (this._listeners === undefined) return; 251 const listeners = this._listeners; 252 const listenerArray = listeners[event.type]; 253 254 if (listenerArray !== undefined) { 255 event.target = this; // Make a copy, in case listeners are removed while iterating. 256 257 const array = listenerArray.slice(0); 258 259 for (let i = 0, l = array.length; i < l; i++) { 260 array[i].call(this, event); 261 } 262 263 event.target = null; 264 } 265 } 266 267 } 268 269 const _lut = []; 270 271 for (let i = 0; i < 256; i++) { 272 _lut[i] = (i < 16 ? '0' : '') + i.toString(16); 273 } 274 275 let _seed = 1234567; 276 const DEG2RAD = Math.PI / 180; 277 const RAD2DEG = 180 / Math.PI; // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 278 279 function generateUUID() { 280 const d0 = Math.random() * 0xffffffff | 0; 281 const d1 = Math.random() * 0xffffffff | 0; 282 const d2 = Math.random() * 0xffffffff | 0; 283 const d3 = Math.random() * 0xffffffff | 0; 284 const uuid = _lut[d0 & 0xff] + _lut[d0 >> 8 & 0xff] + _lut[d0 >> 16 & 0xff] + _lut[d0 >> 24 & 0xff] + '-' + _lut[d1 & 0xff] + _lut[d1 >> 8 & 0xff] + '-' + _lut[d1 >> 16 & 0x0f | 0x40] + _lut[d1 >> 24 & 0xff] + '-' + _lut[d2 & 0x3f | 0x80] + _lut[d2 >> 8 & 0xff] + '-' + _lut[d2 >> 16 & 0xff] + _lut[d2 >> 24 & 0xff] + _lut[d3 & 0xff] + _lut[d3 >> 8 & 0xff] + _lut[d3 >> 16 & 0xff] + _lut[d3 >> 24 & 0xff]; // .toUpperCase() here flattens concatenated strings to save heap memory space. 285 286 return uuid.toUpperCase(); 287 } 288 289 function clamp(value, min, max) { 290 return Math.max(min, Math.min(max, value)); 291 } // compute euclidian modulo of m % n 292 // https://en.wikipedia.org/wiki/Modulo_operation 293 294 295 function euclideanModulo(n, m) { 296 return (n % m + m) % m; 297 } // Linear mapping from range <a1, a2> to range <b1, b2> 298 299 300 function mapLinear(x, a1, a2, b1, b2) { 301 return b1 + (x - a1) * (b2 - b1) / (a2 - a1); 302 } // https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/inverse-lerp-a-super-useful-yet-often-overlooked-function-r5230/ 303 304 305 function inverseLerp(x, y, value) { 306 if (x !== y) { 307 return (value - x) / (y - x); 308 } else { 309 return 0; 310 } 311 } // https://en.wikipedia.org/wiki/Linear_interpolation 312 313 314 function lerp(x, y, t) { 315 return (1 - t) * x + t * y; 316 } // http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/ 317 318 319 function damp(x, y, lambda, dt) { 320 return lerp(x, y, 1 - Math.exp(-lambda * dt)); 321 } // https://www.desmos.com/calculator/vcsjnyz7x4 322 323 324 function pingpong(x, length = 1) { 325 return length - Math.abs(euclideanModulo(x, length * 2) - length); 326 } // http://en.wikipedia.org/wiki/Smoothstep 327 328 329 function smoothstep(x, min, max) { 330 if (x <= min) return 0; 331 if (x >= max) return 1; 332 x = (x - min) / (max - min); 333 return x * x * (3 - 2 * x); 334 } 335 336 function smootherstep(x, min, max) { 337 if (x <= min) return 0; 338 if (x >= max) return 1; 339 x = (x - min) / (max - min); 340 return x * x * x * (x * (x * 6 - 15) + 10); 341 } // Random integer from <low, high> interval 342 343 344 function randInt(low, high) { 345 return low + Math.floor(Math.random() * (high - low + 1)); 346 } // Random float from <low, high> interval 347 348 349 function randFloat(low, high) { 350 return low + Math.random() * (high - low); 351 } // Random float from <-range/2, range/2> interval 352 353 354 function randFloatSpread(range) { 355 return range * (0.5 - Math.random()); 356 }
356 // Deterministic pseudo-random float in the interval [ 0, 1 ] 357 358 359 function seededRandom(s) { 360 if (s !== undefined) _seed = s % 2147483647; // Park-Miller algorithm 361 362 _seed = _seed * 16807 % 2147483647; 363 return (_seed - 1) / 2147483646; 364 } 365 366 function degToRad(degrees) { 367 return degrees * DEG2RAD; 368 } 369 370 function radToDeg(radians) { 371 return radians * RAD2DEG; 372 } 373 374 function isPowerOfTwo(value) { 375 return (value & value - 1) === 0 && value !== 0; 376 } 377 378 function ceilPowerOfTwo(value) { 379 return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2)); 380 } 381 382 function floorPowerOfTwo(value) { 383 return Math.pow(2, Math.floor(Math.log(value) / Math.LN2)); 384 } 385 386 function setQuaternionFromProperEuler(q, a, b, c, order) { 387 // Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles 388 // rotations are applied to the axes in the order specified by 'order' 389 // rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c' 390 // angles are in radians 391 const cos = Math.cos; 392 const sin = Math.sin;
vendor: 11,516 bytes, lines 393-986
393 const c2 = cos(b / 2); 394 const s2 = sin(b / 2); 395 const c13 = cos((a + c) / 2); 396 const s13 = sin((a + c) / 2); 397 const c1_3 = cos((a - c) / 2); 398 const s1_3 = sin((a - c) / 2); 399 const c3_1 = cos((c - a) / 2); 400 const s3_1 = sin((c - a) / 2); 401 402 switch (order) { 403 case 'XYX': 404 q.set(c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13); 405 break; 406 407 case 'YZY': 408 q.set(s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13); 409 break; 410 411 case 'ZXZ': 412 q.set(s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13); 413 break; 414 415 case 'XZX': 416 q.set(c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13); 417 break; 418 419 case 'YXY': 420 q.set(s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13); 421 break; 422 423 case 'ZYZ': 424 q.set(s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13); 425 break; 426 427 default: 428 console.warn('THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order); 429 } 430 } 431 432 var MathUtils = /*#__PURE__*/Object.freeze({ 433 __proto__: null, 434 DEG2RAD: DEG2RAD, 435 RAD2DEG: RAD2DEG, 436 generateUUID: generateUUID, 437 clamp: clamp, 438 euclideanModulo: euclideanModulo, 439 mapLinear: mapLinear, 440 inverseLerp: inverseLerp, 441 lerp: lerp, 442 damp: damp, 443 pingpong: pingpong, 444 smoothstep: smoothstep, 445 smootherstep: smootherstep, 446 randInt: randInt, 447 randFloat: randFloat, 448 randFloatSpread: randFloatSpread, 449 seededRandom: seededRandom, 450 degToRad: degToRad, 451 radToDeg: radToDeg, 452 isPowerOfTwo: isPowerOfTwo, 453 ceilPowerOfTwo: ceilPowerOfTwo, 454 floorPowerOfTwo: floorPowerOfTwo, 455 setQuaternionFromProperEuler: setQuaternionFromProperEuler 456 }); 457 458 class Vector2 { 459 constructor(x = 0, y = 0) { 460 this.x = x; 461 this.y = y; 462 } 463 464 get width() { 465 return this.x; 466 } 467 468 set width(value) { 469 this.x = value; 470 } 471 472 get height() { 473 return this.y; 474 } 475 476 set height(value) { 477 this.y = value; 478 } 479 480 set(x, y) { 481 this.x = x; 482 this.y = y; 483 return this; 484 } 485 486 setScalar(scalar) { 487 this.x = scalar; 488 this.y = scalar; 489 return this; 490 } 491 492 setX(x) { 493 this.x = x; 494 return this; 495 } 496 497 setY(y) { 498 this.y = y; 499 return this; 500 } 501 502 setComponent(index, value) { 503 switch (index) { 504 case 0: 505 this.x = value; 506 break; 507 508 case 1: 509 this.y = value; 510 break; 511 512 default: 513 throw new Error('index is out of range: ' + index); 514 } 515 516 return this; 517 } 518 519 getComponent(index) { 520 switch (index) { 521 case 0: 522 return this.x; 523 524 case 1: 525 return this.y; 526 527 default: 528 throw new Error('index is out of range: ' + index); 529 } 530 } 531 532 clone() { 533 return new this.constructor(this.x, this.y); 534 } 535 536 copy(v) { 537 this.x = v.x; 538 this.y = v.y; 539 return this; 540 } 541 542 add(v, w) { 543 if (w !== undefined) { 544 console.warn('THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.'); 545 return this.addVectors(v, w); 546 } 547 548 this.x += v.x; 549 this.y += v.y; 550 return this; 551 } 552 553 addScalar(s) { 554 this.x += s; 555 this.y += s; 556 return this; 557 } 558 559 addVectors(a, b) { 560 this.x = a.x + b.x; 561 this.y = a.y + b.y; 562 return this; 563 } 564 565 addScaledVector(v, s) { 566 this.x += v.x * s; 567 this.y += v.y * s; 568 return this; 569 } 570 571 sub(v, w) { 572 if (w !== undefined) { 573 console.warn('THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.'); 574 return this.subVectors(v, w); 575 } 576 577 this.x -= v.x; 578 this.y -= v.y; 579 return this; 580 } 581 582 subScalar(s) { 583 this.x -= s; 584 this.y -= s; 585 return this; 586 } 587 588 subVectors(a, b) { 589 this.x = a.x - b.x; 590 this.y = a.y - b.y; 591 return this; 592 } 593 594 multiply(v) { 595 this.x *= v.x; 596 this.y *= v.y; 597 return this; 598 } 599 600 multiplyScalar(scalar) { 601 this.x *= scalar; 602 this.y *= scalar; 603 return this; 604 } 605 606 divide(v) { 607 this.x /= v.x; 608 this.y /= v.y; 609 return this; 610 } 611 612 divideScalar(scalar) { 613 return this.multiplyScalar(1 / scalar); 614 } 615 616 applyMatrix3(m) { 617 const x = this.x, 618 y = this.y; 619 const e = m.elements; 620 this.x = e[0] * x + e[3] * y + e[6]; 621 this.y = e[1] * x + e[4] * y + e[7]; 622 return this; 623 } 624 625 min(v) { 626 this.x = Math.min(this.x, v.x); 627 this.y = Math.min(this.y, v.y); 628 return this; 629 } 630 631 max(v) { 632 this.x = Math.max(this.x, v.x); 633 this.y = Math.max(this.y, v.y); 634 return this; 635 } 636 637 clamp(min, max) { 638 // assumes min < max, componentwise 639 this.x = Math.max(min.x, Math.min(max.x, this.x)); 640 this.y = Math.max(min.y, Math.min(max.y, this.y)); 641 return this; 642 } 643 644 clampScalar(minVal, maxVal) { 645 this.x = Math.max(minVal, Math.min(maxVal, this.x)); 646 this.y = Math.max(minVal, Math.min(maxVal, this.y)); 647 return this; 648 } 649 650 clampLength(min, max) { 651 const length = this.length(); 652 return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length))); 653 } 654 655 floor() { 656 this.x = Math.floor(this.x); 657 this.y = Math.floor(this.y); 658 return this; 659 } 660 661 ceil() { 662 this.x = Math.ceil(this.x); 663 this.y = Math.ceil(this.y); 664 return this; 665 } 666 667 round() { 668 this.x = Math.round(this.x); 669 this.y = Math.round(this.y); 670 return this; 671 } 672 673 roundToZero() { 674 this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x); 675 this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y); 676 return this; 677 } 678 679 negate() { 680 this.x = -this.x; 681 this.y = -this.y; 682 return this; 683 } 684 685 dot(v) { 686 return this.x * v.x + this.y * v.y; 687 } 688 689 cross(v) { 690 return this.x * v.y - this.y * v.x; 691 } 692 693 lengthSq() { 694 return this.x * this.x + this.y * this.y; 695 } 696 697 length() { 698 return Math.sqrt(this.x * this.x + this.y * this.y); 699 } 700 701 manhattanLength() { 702 return Math.abs(this.x) + Math.abs(this.y); 703 } 704 705 normalize() { 706 return this.divideScalar(this.length() || 1); 707 } 708 709 angle() { 710 // computes the angle in radians with respect to the positive x-axis 711 const angle = Math.atan2(-this.y, -this.x) + Math.PI; 712 return angle; 713 } 714 715 distanceTo(v) { 716 return Math.sqrt(this.distanceToSquared(v)); 717 } 718 719 distanceToSquared(v) { 720 const dx = this.x - v.x, 721 dy = this.y - v.y; 722 return dx * dx + dy * dy; 723 } 724 725 manhattanDistanceTo(v) { 726 return Math.abs(this.x - v.x) + Math.abs(this.y - v.y); 727 } 728 729 setLength(length) { 730 return this.normalize().multiplyScalar(length); 731 } 732 733 lerp(v, alpha) { 734 this.x += (v.x - this.x) * alpha; 735 this.y += (v.y - this.y) * alpha; 736 return this; 737 } 738 739 lerpVectors(v1, v2, alpha) { 740 this.x = v1.x + (v2.x - v1.x) * alpha; 741 this.y = v1.y + (v2.y - v1.y) * alpha; 742 return this; 743 } 744 745 equals(v) { 746 return v.x === this.x && v.y === this.y; 747 } 748 749 fromArray(array, offset = 0) { 750 this.x = array[offset]; 751 this.y = array[offset + 1]; 752 return this; 753 } 754 755 toArray(array = [], offset = 0) { 756 array[offset] = this.x; 757 array[offset + 1] = this.y; 758 return array; 759 } 760 761 fromBufferAttribute(attribute, index, offset) { 762 if (offset !== undefined) { 763 console.warn('THREE.Vector2: offset has been removed from .fromBufferAttribute().'); 764 } 765 766 this.x = attribute.getX(index); 767 this.y = attribute.getY(index); 768 return this; 769 } 770 771 rotateAround(center, angle) { 772 const c = Math.cos(angle), 773 s = Math.sin(angle); 774 const x = this.x - center.x; 775 const y = this.y - center.y; 776 this.x = x * c - y * s + center.x; 777 this.y = x * s + y * c + center.y; 778 return this; 779 } 780 781 random() { 782 this.x = Math.random(); 783 this.y = Math.random(); 784 return this; 785 } 786 787 *[Symbol.iterator]() { 788 yield this.x; 789 yield this.y; 790 } 791 792 } 793 794 Vector2.prototype.isVector2 = true; 795 796 class Matrix3 { 797 constructor() { 798 this.elements = [1, 0, 0, 0, 1, 0, 0, 0, 1]; 799 800 if (arguments.length > 0) { 801 console.error('THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.'); 802 } 803 } 804 805 set(n11, n12, n13, n21, n22, n23, n31, n32, n33) { 806 const te = this.elements; 807 te[0] = n11; 808 te[1] = n21; 809 te[2] = n31; 810 te[3] = n12; 811 te[4] = n22; 812 te[5] = n32; 813 te[6] = n13; 814 te[7] = n23; 815 te[8] = n33; 816 return this; 817 } 818 819 identity() { 820 this.set(1, 0, 0, 0, 1, 0, 0, 0, 1); 821 return this; 822 } 823 824 copy(m) { 825 const te = this.elements; 826 const me = m.elements; 827 te[0] = me[0]; 828 te[1] = me[1]; 829 te[2] = me[2]; 830 te[3] = me[3]; 831 te[4] = me[4]; 832 te[5] = me[5]; 833 te[6] = me[6]; 834 te[7] = me[7]; 835 te[8] = me[8]; 836 return this; 837 } 838 839 extractBasis(xAxis, yAxis, zAxis) { 840 xAxis.setFromMatrix3Column(this, 0); 841 yAxis.setFromMatrix3Column(this, 1); 842 zAxis.setFromMatrix3Column(this, 2); 843 return this; 844 } 845 846 setFromMatrix4(m) { 847 const me = m.elements; 848 this.set(me[0], me[4], me[8], me[1], me[5], me[9], me[2], me[6], me[10]); 849 return this; 850 } 851 852 multiply(m) { 853 return this.multiplyMatrices(this, m); 854 } 855 856 premultiply(m) { 857 return this.multiplyMatrices(m, this); 858 } 859 860 multiplyMatrices(a, b) { 861 const ae = a.elements; 862 const be = b.elements; 863 const te = this.elements; 864 const a11 = ae[0], 865 a12 = ae[3], 866 a13 = ae[6]; 867 const a21 = ae[1], 868 a22 = ae[4], 869 a23 = ae[7]; 870 const a31 = ae[2], 871 a32 = ae[5], 872 a33 = ae[8]; 873 const b11 = be[0], 874 b12 = be[3], 875 b13 = be[6]; 876 const b21 = be[1], 877 b22 = be[4], 878 b23 = be[7]; 879 const b31 = be[2], 880 b32 = be[5], 881 b33 = be[8]; 882 te[0] = a11 * b11 + a12 * b21 + a13 * b31; 883 te[3] = a11 * b12 + a12 * b22 + a13 * b32; 884 te[6] = a11 * b13 + a12 * b23 + a13 * b33; 885 te[1] = a21 * b11 + a22 * b21 + a23 * b31; 886 te[4] = a21 * b12 + a22 * b22 + a23 * b32; 887 te[7] = a21 * b13 + a22 * b23 + a23 * b33; 888 te[2] = a31 * b11 + a32 * b21 + a33 * b31; 889 te[5] = a31 * b12 + a32 * b22 + a33 * b32; 890 te[8] = a31 * b13 + a32 * b23 + a33 * b33; 891 return this; 892 } 893 894 multiplyScalar(s) { 895 const te = this.elements; 896 te[0] *= s; 897 te[3] *= s; 898 te[6] *= s; 899 te[1] *= s; 900 te[4] *= s; 901 te[7] *= s; 902 te[2] *= s; 903 te[5] *= s; 904 te[8] *= s; 905 return this; 906 } 907 908 determinant() { 909 const te = this.elements; 910 const a = te[0], 911 b = te[1], 912 c = te[2], 913 d = te[3], 914 e = te[4], 915 f = te[5], 916 g = te[6], 917 h = te[7], 918 i = te[8]; 919 return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; 920 } 921 922 invert() { 923 const te = this.elements, 924 n11 = te[0], 925 n21 = te[1], 926 n31 = te[2], 927 n12 = te[3], 928 n22 = te[4], 929 n32 = te[5], 930 n13 = te[6], 931 n23 = te[7], 932 n33 = te[8], 933 t11 = n33 * n22 - n32 * n23, 934 t12 = n32 * n13 - n33 * n12, 935 t13 = n23 * n12 - n22 * n13, 936 det = n11 * t11 + n21 * t12 + n31 * t13; 937 if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0); 938 const detInv = 1 / det; 939 te[0] = t11 * detInv; 940 te[1] = (n31 * n23 - n33 * n21) * detInv; 941 te[2] = (n32 * n21 - n31 * n22) * detInv; 942 te[3] = t12 * detInv; 943 te[4] = (n33 * n11 - n31 * n13) * detInv; 944 te[5] = (n31 * n12 - n32 * n11) * detInv; 945 te[6] = t13 * detInv; 946 te[7] = (n21 * n13 - n23 * n11) * detInv; 947 te[8] = (n22 * n11 - n21 * n12) * detInv; 948 return this; 949 } 950 951 transpose() { 952 let tmp; 953 const m = this.elements; 954 tmp = m[1]; 955 m[1] = m[3]; 956 m[3] = tmp; 957 tmp = m[2]; 958 m[2] = m[6]; 959 m[6] = tmp; 960 tmp = m[5]; 961 m[5] = m[7]; 962 m[7] = tmp; 963 return this; 964 } 965 966 getNormalMatrix(matrix4) { 967 return this.setFromMatrix4(matrix4).invert().transpose(); 968 } 969 970 transposeIntoArray(r) { 971 const m = this.elements; 972 r[0] = m[0]; 973 r[1] = m[3]; 974 r[2] = m[6]; 975 r[3] = m[1]; 976 r[4] = m[4]; 977 r[5] = m[7]; 978 r[6] = m[2]; 979 r[7] = m[5]; 980 r[8] = m[8]; 981 return this; 982 } 983 984 setUvTransform(tx, ty, sx, sy, rotation, cx, cy) { 985 const c = Math.cos(rotation); 986 const s = Math.sin(rotation);
987 this.set(sx * c, sx * s, -sx * (c * cx + s * cy) + cx + tx, -sy * s, sy * c, -sy * (-s * cx + c * cy) + cy + ty, 0, 0, 1); 988 return this; 989 } 990 991 scale(sx, sy) { 992 const te = this.elements; 993 te[0] *= sx; 994 te[3] *= sx; 995 te[6] *= sx; 996 te[1] *= sy; 997 te[4] *= sy; 998 te[7] *= sy; 999 return this; 1000 } 1001 1002 rotate(theta) { 1003 const c = Math.cos(theta); 1004 const s = Math.sin(theta); 1005 const te = this.elements; 1006 const a11 = te[0], 1007 a12 = te[3], 1008 a13 = te[6]; 1009 const a21 = te[1], 1010 a22 = te[4], 1011 a23 = te[7]; 1012 te[0] = c * a11 + s * a21; 1013 te[3] = c * a12 + s * a22; 1014 te[6] = c * a13 + s * a23; 1015 te[1] = -s * a11 + c * a21; 1016 te[4] = -s * a12 + c * a22; 1017 te[7] = -s * a13 + c * a23; 1018 return this; 1019 } 1020 1021 translate(tx, ty) { 1022 const te = this.elements; 1023 te[0] += tx * te[2]; 1024 te[3] += tx * te[5]; 1025 te[6] += tx * te[8]; 1026 te[1] += ty * te[2]; 1027 te[4] += ty * te[5]; 1028 te[7] += ty * te[8]; 1029 return this; 1030 } 1031 1032 equals(matrix) { 1033 const te = this.elements; 1034 const me = matrix.elements; 1035 1036 for (let i = 0; i < 9; i++) { 1037 if (te[i] !== me[i]) return false; 1038 } 1039 1040 return true; 1041 } 1042 1043 fromArray(array, offset = 0) { 1044 for (let i = 0; i < 9; i++) { 1045 this.elements[i] = array[i + offset]; 1046 } 1047 1048 return this; 1049 } 1050 1051 toArray(array = [], offset = 0) { 1052 const te = this.elements; 1053 array[offset] = te[0]; 1054 array[offset + 1] = te[1]; 1055 array[offset + 2] = te[2]; 1056 array[offset + 3] = te[3]; 1057 array[offset + 4] = te[4]; 1058 array[offset + 5] = te[5]; 1059 array[offset + 6] = te[6]; 1060 array[offset + 7] = te[7]; 1061 array[offset + 8] = te[8]; 1062 return array; 1063 } 1064 1065 clone() { 1066 return new this.constructor().fromArray(this.elements); 1067 } 1068 1069 } 1070 1071 Matrix3.prototype.isMatrix3 = true; 1072 1073 function arrayMax(array) { 1074 if (array.length === 0) return -Infinity; 1075 let max = array[0]; 1076 1077 for (let i = 1, l = array.length; i < l; ++i) { 1078 if (array[i] > max) max = array[i]; 1079 } 1080 1081 return max; 1082 } 1083 1084 const TYPED_ARRAYS = { 1085 Int8Array: Int8Array, 1086 Uint8Array: Uint8Array, 1087 Uint8ClampedArray: Uint8ClampedArray, 1088 Int16Array: Int16Array, 1089 Uint16Array: Uint16Array, 1090 Int32Array: Int32Array, 1091 Uint32Array: Uint32Array, 1092 Float32Array: Float32Array, 1093 Float64Array: Float64Array 1094 }; 1095 1096 function getTypedArray(type, buffer) { 1097 return new TYPED_ARRAYS[type](buffer); 1098 } 1099 1100 function createElementNS(name) { 1101 return document.createElementNS('http://www.w3.org/1999/xhtml', name); 1102 } 1103 1104 let _canvas; 1105 1106 class ImageUtils { 1107 static getDataURL(image) { 1108 if (/^data:/i.test(image.src)) { 1109 return image.src; 1110 } 1111 1112 if (typeof HTMLCanvasElement == 'undefined') { 1113 return image.src; 1114 } 1115 1116 let canvas; 1117 1118 if (image instanceof HTMLCanvasElement) { 1119 canvas = image; 1120 } else { 1121 if (_canvas === undefined) _canvas = createElementNS('canvas'); 1122 _canvas.width = image.width; 1123 _canvas.height = image.height; 1124 1125 const context = _canvas.getContext('2d'); 1126 1127 if (image instanceof ImageData) { 1128 context.putImageData(image, 0, 0); 1129 } else { 1130 context.drawImage(image, 0, 0, image.width, image.height); 1131 } 1132 1133 canvas = _canvas; 1134 } 1135 1136 if (canvas.width > 2048 || canvas.height > 2048) { 1137 console.warn('THREE.ImageUtils.getDataURL: Image converted to jpg for performance reasons', image); 1138 return canvas.toDataURL('image/jpeg', 0.6); 1139 } else { 1140 return canvas.toDataURL('image/png'); 1141 } 1142 } 1143 1144 } 1145 1146 let textureId = 0; 1147 1148 class Texture extends EventDispatcher { 1149 constructor(image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = 1, encoding = LinearEncoding) { 1150 super(); 1151 Object.defineProperty(this, 'id', { 1152 value: textureId++ 1153 }); 1154 this.uuid = generateUUID(); 1155 this.name = ''; 1156 this.image = image; 1157 this.mipmaps = []; 1158 this.mapping = mapping; 1159 this.wrapS = wrapS; 1160 this.wrapT = wrapT; 1161 this.magFilter = magFilter; 1162 this.minFilter = minFilter; 1163 this.anisotropy = anisotropy; 1164 this.format = format; 1165 this.internalFormat = null; 1166 this.type = type; 1167 this.offset = new Vector2(0, 0); 1168 this.repeat = new Vector2(1, 1); 1169 this.center = new Vector2(0, 0); 1170 this.rotation = 0; 1171 this.matrixAutoUpdate = true; 1172 this.matrix = new Matrix3(); 1173 this.generateMipmaps = true; 1174 this.premultiplyAlpha = false;
vendor: 13,438 bytes, lines 1175-1765
1175 this.flipY = true; 1176 this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) 1177 // Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap. 1178 // 1179 // Also changing the encoding after already used by a Material will not automatically make the Material 1180 // update. You need to explicitly call Material.needsUpdate to trigger it to recompile. 1181 1182 this.encoding = encoding; 1183 this.userData = {}; 1184 this.version = 0; 1185 this.onUpdate = null; 1186 this.isRenderTargetTexture = false; 1187 } 1188 1189 updateMatrix() { 1190 this.matrix.setUvTransform(this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y); 1191 } 1192 1193 clone() { 1194 return new this.constructor().copy(this); 1195 } 1196 1197 copy(source) { 1198 this.name = source.name; 1199 this.image = source.image; 1200 this.mipmaps = source.mipmaps.slice(0); 1201 this.mapping = source.mapping; 1202 this.wrapS = source.wrapS; 1203 this.wrapT = source.wrapT; 1204 this.magFilter = source.magFilter; 1205 this.minFilter = source.minFilter; 1206 this.anisotropy = source.anisotropy; 1207 this.format = source.format; 1208 this.internalFormat = source.internalFormat; 1209 this.type = source.type; 1210 this.offset.copy(source.offset); 1211 this.repeat.copy(source.repeat); 1212 this.center.copy(source.center); 1213 this.rotation = source.rotation; 1214 this.matrixAutoUpdate = source.matrixAutoUpdate; 1215 this.matrix.copy(source.matrix); 1216 this.generateMipmaps = source.generateMipmaps; 1217 this.premultiplyAlpha = source.premultiplyAlpha; 1218 this.flipY = source.flipY; 1219 this.unpackAlignment = source.unpackAlignment; 1220 this.encoding = source.encoding; 1221 this.userData = JSON.parse(JSON.stringify(source.userData)); 1222 return this; 1223 } 1224 1225 toJSON(meta) { 1226 const isRootObject = meta === undefined || typeof meta === 'string'; 1227 1228 if (!isRootObject && meta.textures[this.uuid] !== undefined) { 1229 return meta.textures[this.uuid]; 1230 } 1231 1232 const output = { 1233 metadata: { 1234 version: 4.5, 1235 type: 'Texture', 1236 generator: 'Texture.toJSON' 1237 }, 1238 uuid: this.uuid, 1239 name: this.name, 1240 mapping: this.mapping, 1241 repeat: [this.repeat.x, this.repeat.y], 1242 offset: [this.offset.x, this.offset.y], 1243 center: [this.center.x, this.center.y], 1244 rotation: this.rotation, 1245 wrap: [this.wrapS, this.wrapT], 1246 format: this.format, 1247 type: this.type, 1248 encoding: this.encoding, 1249 minFilter: this.minFilter, 1250 magFilter: this.magFilter, 1251 anisotropy: this.anisotropy, 1252 flipY: this.flipY, 1253 premultiplyAlpha: this.premultiplyAlpha, 1254 unpackAlignment: this.unpackAlignment 1255 }; 1256 1257 if (this.image !== undefined) { 1258 // TODO: Move to THREE.Image 1259 const image = this.image; 1260 1261 if (image.uuid === undefined) { 1262 image.uuid = generateUUID(); // UGH 1263 } 1264 1265 if (!isRootObject && meta.images[image.uuid] === undefined) { 1266 let url; 1267 1268 if (Array.isArray(image)) { 1269 // process array of images e.g. CubeTexture 1270 url = []; 1271 1272 for (let i = 0, l = image.length; i < l; i++) { 1273 // check cube texture with data textures 1274 if (image[i].isDataTexture) { 1275 url.push(serializeImage(image[i].image)); 1276 } else { 1277 url.push(serializeImage(image[i])); 1278 } 1279 } 1280 } else { 1281 // process single image 1282 url = serializeImage(image); 1283 } 1284 1285 meta.images[image.uuid] = { 1286 uuid: image.uuid, 1287 url: url 1288 }; 1289 } 1290 1291 output.image = image.uuid; 1292 } 1293 1294 if (JSON.stringify(this.userData) !== '{}') output.userData = this.userData; 1295 1296 if (!isRootObject) { 1297 meta.textures[this.uuid] = output; 1298 } 1299 1300 return output; 1301 } 1302 1303 dispose() { 1304 this.dispatchEvent({ 1305 type: 'dispose' 1306 }); 1307 } 1308 1309 transformUv(uv) { 1310 if (this.mapping !== UVMapping) return uv; 1311 uv.applyMatrix3(this.matrix); 1312 1313 if (uv.x < 0 || uv.x > 1) { 1314 switch (this.wrapS) { 1315 case RepeatWrapping: 1316 uv.x = uv.x - Math.floor(uv.x); 1317 break; 1318 1319 case ClampToEdgeWrapping: 1320 uv.x = uv.x < 0 ? 0 : 1; 1321 break; 1322 1323 case MirroredRepeatWrapping: 1324 if (Math.abs(Math.floor(uv.x) % 2) === 1) { 1325 uv.x = Math.ceil(uv.x) - uv.x; 1326 } else { 1327 uv.x = uv.x - Math.floor(uv.x); 1328 } 1329 1330 break; 1331 } 1332 } 1333 1334 if (uv.y < 0 || uv.y > 1) { 1335 switch (this.wrapT) { 1336 case RepeatWrapping: 1337 uv.y = uv.y - Math.floor(uv.y); 1338 break; 1339 1340 case ClampToEdgeWrapping: 1341 uv.y = uv.y < 0 ? 0 : 1; 1342 break; 1343 1344 case MirroredRepeatWrapping: 1345 if (Math.abs(Math.floor(uv.y) % 2) === 1) { 1346 uv.y = Math.ceil(uv.y) - uv.y; 1347 } else { 1348 uv.y = uv.y - Math.floor(uv.y); 1349 } 1350 1351 break; 1352 } 1353 } 1354 1355 if (this.flipY) { 1356 uv.y = 1 - uv.y; 1357 } 1358 1359 return uv; 1360 } 1361 1362 set needsUpdate(value) { 1363 if (value === true) this.version++; 1364 } 1365 1366 } 1367 1368 Texture.DEFAULT_IMAGE = undefined; 1369 Texture.DEFAULT_MAPPING = UVMapping; 1370 Texture.prototype.isTexture = true; 1371 1372 function serializeImage(image) { 1373 if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) { 1374 // default images 1375 return ImageUtils.getDataURL(image); 1376 } else { 1377 if (image.data) { 1378 // images of DataTexture 1379 return { 1380 data: Array.prototype.slice.call(image.data), 1381 width: image.width, 1382 height: image.height, 1383 type: image.data.constructor.name 1384 }; 1385 } else { 1386 console.warn('THREE.Texture: Unable to serialize Texture.'); 1387 return {}; 1388 } 1389 } 1390 } 1391 1392 class Vector4 { 1393 constructor(x = 0, y = 0, z = 0, w = 1) { 1394 this.x = x; 1395 this.y = y; 1396 this.z = z; 1397 this.w = w; 1398 } 1399 1400 get width() { 1401 return this.z; 1402 } 1403 1404 set width(value) { 1405 this.z = value; 1406 } 1407 1408 get height() { 1409 return this.w; 1410 } 1411 1412 set height(value) { 1413 this.w = value; 1414 } 1415 1416 set(x, y, z, w) { 1417 this.x = x; 1418 this.y = y; 1419 this.z = z; 1420 this.w = w; 1421 return this; 1422 } 1423 1424 setScalar(scalar) { 1425 this.x = scalar; 1426 this.y = scalar; 1427 this.z = scalar; 1428 this.w = scalar; 1429 return this; 1430 } 1431 1432 setX(x) { 1433 this.x = x; 1434 return this; 1435 } 1436 1437 setY(y) { 1438 this.y = y; 1439 return this; 1440 } 1441 1442 setZ(z) { 1443 this.z = z; 1444 return this; 1445 } 1446 1447 setW(w) { 1448 this.w = w; 1449 return this; 1450 } 1451 1452 setComponent(index, value) { 1453 switch (index) { 1454 case 0: 1455 this.x = value; 1456 break; 1457 1458 case 1: 1459 this.y = value; 1460 break; 1461 1462 case 2: 1463 this.z = value; 1464 break; 1465 1466 case 3: 1467 this.w = value; 1468 break; 1469 1470 default: 1471 throw new Error('index is out of range: ' + index); 1472 } 1473 1474 return this; 1475 } 1476 1477 getComponent(index) { 1478 switch (index) { 1479 case 0: 1480 return this.x; 1481 1482 case 1: 1483 return this.y; 1484 1485 case 2: 1486 return this.z; 1487 1488 case 3: 1489 return this.w; 1490 1491 default: 1492 throw new Error('index is out of range: ' + index); 1493 } 1494 } 1495 1496 clone() { 1497 return new this.constructor(this.x, this.y, this.z, this.w); 1498 } 1499 1500 copy(v) { 1501 this.x = v.x; 1502 this.y = v.y; 1503 this.z = v.z; 1504 this.w = v.w !== undefined ? v.w : 1; 1505 return this; 1506 } 1507 1508 add(v, w) { 1509 if (w !== undefined) { 1510 console.warn('THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.'); 1511 return this.addVectors(v, w); 1512 } 1513 1514 this.x += v.x; 1515 this.y += v.y; 1516 this.z += v.z; 1517 this.w += v.w; 1518 return this; 1519 } 1520 1521 addScalar(s) { 1522 this.x += s; 1523 this.y += s; 1524 this.z += s; 1525 this.w += s; 1526 return this; 1527 } 1528 1529 addVectors(a, b) { 1530 this.x = a.x + b.x; 1531 this.y = a.y + b.y; 1532 this.z = a.z + b.z; 1533 this.w = a.w + b.w; 1534 return this; 1535 } 1536 1537 addScaledVector(v, s) { 1538 this.x += v.x * s; 1539 this.y += v.y * s; 1540 this.z += v.z * s; 1541 this.w += v.w * s; 1542 return this; 1543 } 1544 1545 sub(v, w) { 1546 if (w !== undefined) { 1547 console.warn('THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.'); 1548 return this.subVectors(v, w); 1549 } 1550 1551 this.x -= v.x; 1552 this.y -= v.y; 1553 this.z -= v.z; 1554 this.w -= v.w; 1555 return this; 1556 } 1557 1558 subScalar(s) { 1559 this.x -= s; 1560 this.y -= s; 1561 this.z -= s; 1562 this.w -= s; 1563 return this; 1564 } 1565 1566 subVectors(a, b) { 1567 this.x = a.x - b.x; 1568 this.y = a.y - b.y; 1569 this.z = a.z - b.z; 1570 this.w = a.w - b.w; 1571 return this; 1572 } 1573 1574 multiply(v) { 1575 this.x *= v.x; 1576 this.y *= v.y; 1577 this.z *= v.z; 1578 this.w *= v.w; 1579 return this; 1580 } 1581 1582 multiplyScalar(scalar) { 1583 this.x *= scalar; 1584 this.y *= scalar; 1585 this.z *= scalar; 1586 this.w *= scalar; 1587 return this; 1588 } 1589 1590 applyMatrix4(m) { 1591 const x = this.x, 1592 y = this.y, 1593 z = this.z, 1594 w = this.w; 1595 const e = m.elements; 1596 this.x = e[0] * x + e[4] * y + e[8] * z + e[12] * w; 1597 this.y = e[1] * x + e[5] * y + e[9] * z + e[13] * w; 1598 this.z = e[2] * x + e[6] * y + e[10] * z + e[14] * w; 1599 this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w; 1600 return this; 1601 } 1602 1603 divideScalar(scalar) { 1604 return this.multiplyScalar(1 / scalar); 1605 } 1606 1607 setAxisAngleFromQuaternion(q) { 1608 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm 1609 // q is assumed to be normalized 1610 this.w = 2 * Math.acos(q.w); 1611 const s = Math.sqrt(1 - q.w * q.w); 1612 1613 if (s < 0.0001) { 1614 this.x = 1; 1615 this.y = 0; 1616 this.z = 0; 1617 } else { 1618 this.x = q.x / s; 1619 this.y = q.y / s; 1620 this.z = q.z / s; 1621 } 1622 1623 return this; 1624 } 1625 1626 setAxisAngleFromRotationMatrix(m) { 1627 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm 1628 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) 1629 let angle, x, y, z; // variables for result 1630 1631 const epsilon = 0.01, 1632 // margin to allow for rounding errors 1633 epsilon2 = 0.1, 1634 // margin to distinguish between 0 and 180 degrees 1635 te = m.elements, 1636 m11 = te[0], 1637 m12 = te[4], 1638 m13 = te[8], 1639 m21 = te[1], 1640 m22 = te[5], 1641 m23 = te[9], 1642 m31 = te[2], 1643 m32 = te[6], 1644 m33 = te[10]; 1645 1646 if (Math.abs(m12 - m21) < epsilon && Math.abs(m13 - m31) < epsilon && Math.abs(m23 - m32) < epsilon) { 1647 // singularity found 1648 // first check for identity matrix which must have +1 for all terms 1649 // in leading diagonal and zero in other terms 1650 if (Math.abs(m12 + m21) < epsilon2 && Math.abs(m13 + m31) < epsilon2 && Math.abs(m23 + m32) < epsilon2 && Math.abs(m11 + m22 + m33 - 3) < epsilon2) { 1651 // this singularity is identity matrix so angle = 0 1652 this.set(1, 0, 0, 0); 1653 return this; // zero angle, arbitrary axis 1654 } // otherwise this singularity is angle = 180 1655 1656 1657 angle = Math.PI; 1658 const xx = (m11 + 1) / 2; 1659 const yy = (m22 + 1) / 2; 1660 const zz = (m33 + 1) / 2; 1661 const xy = (m12 + m21) / 4; 1662 const xz = (m13 + m31) / 4; 1663 const yz = (m23 + m32) / 4; 1664 1665 if (xx > yy && xx > zz) { 1666 // m11 is the largest diagonal term 1667 if (xx < epsilon) { 1668 x = 0; 1669 y = 0.707106781; 1670 z = 0.707106781; 1671 } else { 1672 x = Math.sqrt(xx); 1673 y = xy / x; 1674 z = xz / x; 1675 } 1676 } else if (yy > zz) { 1677 // m22 is the largest diagonal term 1678 if (yy < epsilon) { 1679 x = 0.707106781; 1680 y = 0; 1681 z = 0.707106781; 1682 } else { 1683 y = Math.sqrt(yy); 1684 x = xy / y; 1685 z = yz / y; 1686 } 1687 } else { 1688 // m33 is the largest diagonal term so base result on this 1689 if (zz < epsilon) { 1690 x = 0.707106781; 1691 y = 0.707106781; 1692 z = 0; 1693 } else { 1694 z = Math.sqrt(zz); 1695 x = xz / z; 1696 y = yz / z; 1697 } 1698 } 1699 1700 this.set(x, y, z, angle); 1701 return this; // return 180 deg rotation 1702 } // as we have reached here there are no singularities so we can handle normally 1703 1704 1705 let s = Math.sqrt((m32 - m23) * (m32 - m23) + (m13 - m31) * (m13 - m31) + (m21 - m12) * (m21 - m12)); // used to normalize 1706 1707 if (Math.abs(s) < 0.001) s = 1; // prevent divide by zero, should not happen if matrix is orthogonal and should be 1708 // caught by singularity test above, but I've left it in just in case 1709 1710 this.x = (m32 - m23) / s; 1711 this.y = (m13 - m31) / s; 1712 this.z = (m21 - m12) / s; 1713 this.w = Math.acos((m11 + m22 + m33 - 1) / 2); 1714 return this; 1715 } 1716 1717 min(v) { 1718 this.x = Math.min(this.x, v.x); 1719 this.y = Math.min(this.y, v.y); 1720 this.z = Math.min(this.z, v.z); 1721 this.w = Math.min(this.w, v.w); 1722 return this; 1723 } 1724 1725 max(v) { 1726 this.x = Math.max(this.x, v.x); 1727 this.y = Math.max(this.y, v.y); 1728 this.z = Math.max(this.z, v.z); 1729 this.w = Math.max(this.w, v.w); 1730 return this; 1731 } 1732 1733 clamp(min, max) { 1734 // assumes min < max, componentwise 1735 this.x = Math.max(min.x, Math.min(max.x, this.x)); 1736 this.y = Math.max(min.y, Math.min(max.y, this.y)); 1737 this.z = Math.max(min.z, Math.min(max.z, this.z)); 1738 this.w = Math.max(min.w, Math.min(max.w, this.w)); 1739 return this; 1740 } 1741 1742 clampScalar(minVal, maxVal) { 1743 this.x = Math.max(minVal, Math.min(maxVal, this.x)); 1744 this.y = Math.max(minVal, Math.min(maxVal, this.y)); 1745 this.z = Math.max(minVal, Math.min(maxVal, this.z)); 1746 this.w = Math.max(minVal, Math.min(maxVal, this.w)); 1747 return this; 1748 } 1749 1750 clampLength(min, max) { 1751 const length = this.length(); 1752 return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length))); 1753 } 1754 1755 floor() { 1756 this.x = Math.floor(this.x); 1757 this.y = Math.floor(this.y); 1758 this.z = Math.floor(this.z); 1759 this.w = Math.floor(this.w); 1760 return this; 1761 } 1762 1763 ceil() { 1764 this.x = Math.ceil(this.x); 1765 this.y = Math.ceil(this.y);
1766 this.z = Math.ceil(this.z); 1767 this.w = Math.ceil(this.w); 1768 return this; 1769 } 1770 1771 round() { 1772 this.x = Math.round(this.x); 1773 this.y = Math.round(this.y); 1774 this.z = Math.round(this.z); 1775 this.w = Math.round(this.w); 1776 return this; 1777 } 1778 1779 roundToZero() { 1780 this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x); 1781 this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y); 1782 this.z = this.z < 0 ? Math.ceil(this.z) : Math.floor(this.z); 1783 this.w = this.w < 0 ? Math.ceil(this.w) : Math.floor(this.w); 1784 return this; 1785 } 1786 1787 negate() { 1788 this.x = -this.x; 1789 this.y = -this.y; 1790 this.z = -this.z; 1791 this.w = -this.w; 1792 return this; 1793 } 1794 1795 dot(v) { 1796 return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; 1797 } 1798 1799 lengthSq() { 1800 return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; 1801 } 1802 1803 length() { 1804 return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); 1805 } 1806 1807 manhattanLength() { 1808 return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z) + Math.abs(this.w); 1809 } 1810 1811 normalize() { 1812 return this.divideScalar(this.length() || 1); 1813 } 1814 1815 setLength(length) { 1816 return this.normalize().multiplyScalar(length); 1817 } 1818 1819 lerp(v, alpha) { 1820 this.x += (v.x - this.x) * alpha; 1821 this.y += (v.y - this.y) * alpha; 1822 this.z += (v.z - this.z) * alpha; 1823 this.w += (v.w - this.w) * alpha; 1824 return this; 1825 } 1826 1827 lerpVectors(v1, v2, alpha) { 1828 this.x = v1.x + (v2.x - v1.x) * alpha; 1829 this.y = v1.y + (v2.y - v1.y) * alpha; 1830 this.z = v1.z + (v2.z - v1.z) * alpha; 1831 this.w = v1.w + (v2.w - v1.w) * alpha; 1832 return this; 1833 } 1834 1835 equals(v) { 1836 return v.x === this.x && v.y === this.y && v.z === this.z && v.w === this.w; 1837 } 1838 1839 fromArray(array, offset = 0) { 1840 this.x = array[offset]; 1841 this.y = array[offset + 1]; 1842 this.z = array[offset + 2]; 1843 this.w = array[offset + 3]; 1844 return this; 1845 } 1846 1847 toArray(array = [], offset = 0) { 1848 array[offset] = this.x; 1849 array[offset + 1] = this.y; 1850 array[offset + 2] = this.z; 1851 array[offset + 3] = this.w; 1852 return array; 1853 } 1854 1855 fromBufferAttribute(attribute, index, offset) { 1856 if (offset !== undefined) { 1857 console.warn('THREE.Vector4: offset has been removed from .fromBufferAttribute().'); 1858 } 1859 1860 this.x = attribute.getX(index); 1861 this.y = attribute.getY(index); 1862 this.z = attribute.getZ(index); 1863 this.w = attribute.getW(index); 1864 return this; 1865 } 1866 1867 random() { 1868 this.x = Math.random(); 1869 this.y = Math.random(); 1870 this.z = Math.random(); 1871 this.w = Math.random(); 1872 return this; 1873 } 1874 1875 *[Symbol.iterator]() { 1876 yield this.x; 1877 yield this.y; 1878 yield this.z; 1879 yield this.w; 1880 } 1881 1882 } 1883 1884 Vector4.prototype.isVector4 = true; 1885 1886 /* 1887 In options, we can specify: 1888 * Texture parameters for an auto-generated target texture 1889 * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers 1890 */ 1891 1892 class WebGLRenderTarget extends EventDispatcher { 1893 constructor(width, height, options = {}) { 1894 super(); 1895 this.width = width; 1896 this.height = height; 1897 this.depth = 1; 1898 this.scissor = new Vector4(0, 0, width, height); 1899 this.scissorTest = false; 1900 this.viewport = new Vector4(0, 0, width, height); 1901 this.texture = new Texture(undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding); 1902 this.texture.isRenderTargetTexture = true; 1903 this.texture.image = { 1904 width: width, 1905 height: height, 1906 depth: 1 1907 }; 1908 this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; 1909 this.texture.internalFormat = options.internalFormat !== undefined ? options.internalFormat : null; 1910 this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; 1911 this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; 1912 this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : false; 1913 this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null; 1914 } 1915 1916 setTexture(texture) { 1917 texture.image = { 1918 width: this.width, 1919 height: this.height, 1920 depth: this.depth 1921 }; 1922 this.texture = texture; 1923 } 1924 1925 setSize(width, height, depth = 1) { 1926 if (this.width !== width || this.height !== height || this.depth !== depth) { 1927 this.width = width; 1928 this.height = height; 1929 this.depth = depth; 1930 this.texture.image.width = width; 1931 this.texture.image.height = height; 1932 this.texture.image.depth = depth; 1933 this.dispose(); 1934 } 1935 1936 this.viewport.set(0, 0, width, height); 1937 this.scissor.set(0, 0, width, height); 1938 } 1939 1940 clone() { 1941 return new this.constructor().copy(this); 1942 } 1943 1944 copy(source) { 1945 this.width = source.width; 1946 this.height = source.height; 1947 this.depth = source.depth; 1948 this.viewport.copy(source.viewport); 1949 this.texture = source.texture.clone(); 1950 this.texture.image = { ...this.texture.image 1951 }; // See #20328. 1952 1953 this.depthBuffer = source.depthBuffer; 1954 this.stencilBuffer = source.stencilBuffer; 1955 this.depthTexture = source.depthTexture; 1956 return this; 1957 } 1958 1959 dispose() { 1960 this.dispatchEvent({ 1961 type: 'dispose' 1962 }); 1963 } 1964 1965 } 1966 1967 WebGLRenderTarget.prototype.isWebGLRenderTarget = true; 1968 1969 class WebGLMultipleRenderTargets extends WebGLRenderTarget { 1970 constructor(width, height, count) { 1971 super(width, height); 1972 const texture = this.texture; 1973 this.texture = []; 1974 1975 for (let i = 0; i < count; i++) { 1976 this.texture[i] = texture.clone(); 1977 } 1978 } 1979 1980 setSize(width, height, depth = 1) { 1981 if (this.width !== width || this.height !== height || this.depth !== depth) { 1982 this.width = width; 1983 this.height = height; 1984 this.depth = depth; 1985 1986 for (let i = 0, il = this.texture.length; i < il; i++) { 1987 this.texture[i].image.width = width; 1988 this.texture[i].image.height = height; 1989 this.texture[i].image.depth = depth; 1990 } 1991 1992 this.dispose(); 1993 } 1994 1995 this.viewport.set(0, 0, width, height); 1996 this.scissor.set(0, 0, width, height); 1997 return this; 1998 } 1999 2000 copy(source) { 2001 this.dispose(); 2002 this.width = source.width; 2003 this.height = source.height; 2004 this.depth = source.depth; 2005 this.viewport.set(0, 0, this.width, this.height); 2006 this.scissor.set(0, 0, this.width, this.height); 2007 this.depthBuffer = source.depthBuffer; 2008 this.stencilBuffer = source.stencilBuffer; 2009 this.depthTexture = source.depthTexture; 2010 this.texture.length = 0; 2011 2012 for (let i = 0, il = source.texture.length; i < il; i++) { 2013 this.texture[i] = source.texture[i].clone(); 2014 } 2015 2016 return this; 2017 } 2018 2019 } 2020 2021 WebGLMultipleRenderTargets.prototype.isWebGLMultipleRenderTargets = true; 2022 2023 class WebGLMultisampleRenderTarget extends WebGLRenderTarget { 2024 constructor(width, height, options = {}) { 2025 super(width, height, options); 2026 this.samples = 4; 2027 this.ignoreDepthForMultisampleCopy = options.ignoreDepth !== undefined ? options.ignoreDepth : true; 2028 this.useRenderToTexture = options.useRenderToTexture !== undefined ? options.useRenderToTexture : false;
vendor: 31,738 bytes, lines 2029-3366
2029 this.useRenderbuffer = this.useRenderToTexture === false; 2030 } 2031 2032 copy(source) { 2033 super.copy.call(this, source); 2034 this.samples = source.samples; 2035 this.useRenderToTexture = source.useRenderToTexture; 2036 this.useRenderbuffer = source.useRenderbuffer; 2037 return this; 2038 } 2039 2040 } 2041 2042 WebGLMultisampleRenderTarget.prototype.isWebGLMultisampleRenderTarget = true; 2043 2044 class Quaternion { 2045 constructor(x = 0, y = 0, z = 0, w = 1) { 2046 this._x = x; 2047 this._y = y; 2048 this._z = z; 2049 this._w = w; 2050 } 2051 2052 static slerp(qa, qb, qm, t) { 2053 console.warn('THREE.Quaternion: Static .slerp() has been deprecated. Use qm.slerpQuaternions( qa, qb, t ) instead.'); 2054 return qm.slerpQuaternions(qa, qb, t); 2055 } 2056 2057 static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) { 2058 // fuzz-free, array-based Quaternion SLERP operation 2059 let x0 = src0[srcOffset0 + 0], 2060 y0 = src0[srcOffset0 + 1], 2061 z0 = src0[srcOffset0 + 2], 2062 w0 = src0[srcOffset0 + 3]; 2063 const x1 = src1[srcOffset1 + 0], 2064 y1 = src1[srcOffset1 + 1], 2065 z1 = src1[srcOffset1 + 2], 2066 w1 = src1[srcOffset1 + 3]; 2067 2068 if (t === 0) { 2069 dst[dstOffset + 0] = x0; 2070 dst[dstOffset + 1] = y0; 2071 dst[dstOffset + 2] = z0; 2072 dst[dstOffset + 3] = w0; 2073 return; 2074 } 2075 2076 if (t === 1) { 2077 dst[dstOffset + 0] = x1; 2078 dst[dstOffset + 1] = y1; 2079 dst[dstOffset + 2] = z1; 2080 dst[dstOffset + 3] = w1; 2081 return; 2082 } 2083 2084 if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) { 2085 let s = 1 - t; 2086 const cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, 2087 dir = cos >= 0 ? 1 : -1, 2088 sqrSin = 1 - cos * cos; // Skip the Slerp for tiny steps to avoid numeric problems: 2089 2090 if (sqrSin > Number.EPSILON) { 2091 const sin = Math.sqrt(sqrSin), 2092 len = Math.atan2(sin, cos * dir); 2093 s = Math.sin(s * len) / sin; 2094 t = Math.sin(t * len) / sin; 2095 } 2096 2097 const tDir = t * dir; 2098 x0 = x0 * s + x1 * tDir; 2099 y0 = y0 * s + y1 * tDir; 2100 z0 = z0 * s + z1 * tDir; 2101 w0 = w0 * s + w1 * tDir; // Normalize in case we just did a lerp: 2102 2103 if (s === 1 - t) { 2104 const f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0); 2105 x0 *= f; 2106 y0 *= f; 2107 z0 *= f; 2108 w0 *= f; 2109 } 2110 } 2111 2112 dst[dstOffset] = x0; 2113 dst[dstOffset + 1] = y0; 2114 dst[dstOffset + 2] = z0; 2115 dst[dstOffset + 3] = w0; 2116 } 2117 2118 static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) { 2119 const x0 = src0[srcOffset0]; 2120 const y0 = src0[srcOffset0 + 1]; 2121 const z0 = src0[srcOffset0 + 2]; 2122 const w0 = src0[srcOffset0 + 3]; 2123 const x1 = src1[srcOffset1]; 2124 const y1 = src1[srcOffset1 + 1]; 2125 const z1 = src1[srcOffset1 + 2]; 2126 const w1 = src1[srcOffset1 + 3]; 2127 dst[dstOffset] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1; 2128 dst[dstOffset + 1] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1; 2129 dst[dstOffset + 2] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1; 2130 dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1; 2131 return dst; 2132 } 2133 2134 get x() { 2135 return this._x; 2136 } 2137 2138 set x(value) { 2139 this._x = value; 2140 2141 this._onChangeCallback(); 2142 } 2143 2144 get y() { 2145 return this._y; 2146 } 2147 2148 set y(value) { 2149 this._y = value; 2150 2151 this._onChangeCallback(); 2152 } 2153 2154 get z() { 2155 return this._z; 2156 } 2157 2158 set z(value) { 2159 this._z = value; 2160 2161 this._onChangeCallback(); 2162 } 2163 2164 get w() { 2165 return this._w; 2166 } 2167 2168 set w(value) { 2169 this._w = value; 2170 2171 this._onChangeCallback(); 2172 } 2173 2174 set(x, y, z, w) { 2175 this._x = x; 2176 this._y = y; 2177 this._z = z; 2178 this._w = w; 2179 2180 this._onChangeCallback(); 2181 2182 return this; 2183 } 2184 2185 clone() { 2186 return new this.constructor(this._x, this._y, this._z, this._w); 2187 } 2188 2189 copy(quaternion) { 2190 this._x = quaternion.x; 2191 this._y = quaternion.y; 2192 this._z = quaternion.z; 2193 this._w = quaternion.w; 2194 2195 this._onChangeCallback(); 2196 2197 return this; 2198 } 2199 2200 setFromEuler(euler, update) { 2201 if (!(euler && euler.isEuler)) { 2202 throw new Error('THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.'); 2203 } 2204 2205 const x = euler._x, 2206 y = euler._y, 2207 z = euler._z, 2208 order = euler._order; // http://www.mathworks.com/matlabcentral/fileexchange/ 2209 // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ 2210 // content/SpinCalc.m 2211 2212 const cos = Math.cos; 2213 const sin = Math.sin; 2214 const c1 = cos(x / 2); 2215 const c2 = cos(y / 2); 2216 const c3 = cos(z / 2); 2217 const s1 = sin(x / 2); 2218 const s2 = sin(y / 2); 2219 const s3 = sin(z / 2); 2220 2221 switch (order) { 2222 case 'XYZ': 2223 this._x = s1 * c2 * c3 + c1 * s2 * s3; 2224 this._y = c1 * s2 * c3 - s1 * c2 * s3; 2225 this._z = c1 * c2 * s3 + s1 * s2 * c3; 2226 this._w = c1 * c2 * c3 - s1 * s2 * s3; 2227 break; 2228 2229 case 'YXZ': 2230 this._x = s1 * c2 * c3 + c1 * s2 * s3; 2231 this._y = c1 * s2 * c3 - s1 * c2 * s3; 2232 this._z = c1 * c2 * s3 - s1 * s2 * c3; 2233 this._w = c1 * c2 * c3 + s1 * s2 * s3; 2234 break; 2235 2236 case 'ZXY': 2237 this._x = s1 * c2 * c3 - c1 * s2 * s3; 2238 this._y = c1 * s2 * c3 + s1 * c2 * s3; 2239 this._z = c1 * c2 * s3 + s1 * s2 * c3; 2240 this._w = c1 * c2 * c3 - s1 * s2 * s3; 2241 break; 2242 2243 case 'ZYX': 2244 this._x = s1 * c2 * c3 - c1 * s2 * s3; 2245 this._y = c1 * s2 * c3 + s1 * c2 * s3; 2246 this._z = c1 * c2 * s3 - s1 * s2 * c3; 2247 this._w = c1 * c2 * c3 + s1 * s2 * s3; 2248 break; 2249 2250 case 'YZX': 2251 this._x = s1 * c2 * c3 + c1 * s2 * s3; 2252 this._y = c1 * s2 * c3 + s1 * c2 * s3; 2253 this._z = c1 * c2 * s3 - s1 * s2 * c3; 2254 this._w = c1 * c2 * c3 - s1 * s2 * s3; 2255 break; 2256 2257 case 'XZY': 2258 this._x = s1 * c2 * c3 - c1 * s2 * s3; 2259 this._y = c1 * s2 * c3 - s1 * c2 * s3; 2260 this._z = c1 * c2 * s3 + s1 * s2 * c3; 2261 this._w = c1 * c2 * c3 + s1 * s2 * s3; 2262 break; 2263 2264 default: 2265 console.warn('THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order); 2266 } 2267 2268 if (update !== false) this._onChangeCallback(); 2269 return this; 2270 } 2271 2272 setFromAxisAngle(axis, angle) { 2273 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm 2274 // assumes axis is normalized 2275 const halfAngle = angle / 2, 2276 s = Math.sin(halfAngle); 2277 this._x = axis.x * s; 2278 this._y = axis.y * s; 2279 this._z = axis.z * s; 2280 this._w = Math.cos(halfAngle); 2281 2282 this._onChangeCallback(); 2283 2284 return this; 2285 } 2286 2287 setFromRotationMatrix(m) { 2288 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm 2289 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) 2290 const te = m.elements, 2291 m11 = te[0], 2292 m12 = te[4], 2293 m13 = te[8], 2294 m21 = te[1], 2295 m22 = te[5], 2296 m23 = te[9], 2297 m31 = te[2], 2298 m32 = te[6], 2299 m33 = te[10], 2300 trace = m11 + m22 + m33; 2301 2302 if (trace > 0) { 2303 const s = 0.5 / Math.sqrt(trace + 1.0); 2304 this._w = 0.25 / s; 2305 this._x = (m32 - m23) * s; 2306 this._y = (m13 - m31) * s; 2307 this._z = (m21 - m12) * s; 2308 } else if (m11 > m22 && m11 > m33) { 2309 const s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33); 2310 this._w = (m32 - m23) / s; 2311 this._x = 0.25 * s; 2312 this._y = (m12 + m21) / s; 2313 this._z = (m13 + m31) / s; 2314 } else if (m22 > m33) { 2315 const s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33); 2316 this._w = (m13 - m31) / s; 2317 this._x = (m12 + m21) / s; 2318 this._y = 0.25 * s; 2319 this._z = (m23 + m32) / s; 2320 } else { 2321 const s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22); 2322 this._w = (m21 - m12) / s; 2323 this._x = (m13 + m31) / s; 2324 this._y = (m23 + m32) / s; 2325 this._z = 0.25 * s; 2326 } 2327 2328 this._onChangeCallback(); 2329 2330 return this; 2331 } 2332 2333 setFromUnitVectors(vFrom, vTo) { 2334 // assumes direction vectors vFrom and vTo are normalized 2335 let r = vFrom.dot(vTo) + 1; 2336 2337 if (r < Number.EPSILON) { 2338 // vFrom and vTo point in opposite directions 2339 r = 0; 2340 2341 if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) { 2342 this._x = -vFrom.y; 2343 this._y = vFrom.x; 2344 this._z = 0; 2345 this._w = r; 2346 } else { 2347 this._x = 0; 2348 this._y = -vFrom.z; 2349 this._z = vFrom.y; 2350 this._w = r; 2351 } 2352 } else { 2353 // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3 2354 this._x = vFrom.y * vTo.z - vFrom.z * vTo.y; 2355 this._y = vFrom.z * vTo.x - vFrom.x * vTo.z; 2356 this._z = vFrom.x * vTo.y - vFrom.y * vTo.x; 2357 this._w = r; 2358 } 2359 2360 return this.normalize(); 2361 } 2362 2363 angleTo(q) { 2364 return 2 * Math.acos(Math.abs(clamp(this.dot(q), -1, 1))); 2365 } 2366 2367 rotateTowards(q, step) { 2368 const angle = this.angleTo(q); 2369 if (angle === 0) return this; 2370 const t = Math.min(1, step / angle); 2371 this.slerp(q, t); 2372 return this; 2373 } 2374 2375 identity() { 2376 return this.set(0, 0, 0, 1); 2377 } 2378 2379 invert() { 2380 // quaternion is assumed to have unit length 2381 return this.conjugate(); 2382 } 2383 2384 conjugate() { 2385 this._x *= -1; 2386 this._y *= -1; 2387 this._z *= -1; 2388 2389 this._onChangeCallback(); 2390 2391 return this; 2392 } 2393 2394 dot(v) { 2395 return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; 2396 } 2397 2398 lengthSq() { 2399 return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; 2400 } 2401 2402 length() { 2403 return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w); 2404 } 2405 2406 normalize() { 2407 let l = this.length(); 2408 2409 if (l === 0) { 2410 this._x = 0; 2411 this._y = 0; 2412 this._z = 0; 2413 this._w = 1; 2414 } else { 2415 l = 1 / l; 2416 this._x = this._x * l; 2417 this._y = this._y * l; 2418 this._z = this._z * l; 2419 this._w = this._w * l; 2420 } 2421 2422 this._onChangeCallback(); 2423 2424 return this; 2425 } 2426 2427 multiply(q, p) { 2428 if (p !== undefined) { 2429 console.warn('THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.'); 2430 return this.multiplyQuaternions(q, p); 2431 } 2432 2433 return this.multiplyQuaternions(this, q); 2434 } 2435 2436 premultiply(q) { 2437 return this.multiplyQuaternions(q, this); 2438 } 2439 2440 multiplyQuaternions(a, b) { 2441 // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm 2442 const qax = a._x, 2443 qay = a._y, 2444 qaz = a._z, 2445 qaw = a._w; 2446 const qbx = b._x, 2447 qby = b._y, 2448 qbz = b._z, 2449 qbw = b._w; 2450 this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; 2451 this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; 2452 this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; 2453 this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; 2454 2455 this._onChangeCallback(); 2456 2457 return this; 2458 } 2459 2460 slerp(qb, t) { 2461 if (t === 0) return this; 2462 if (t === 1) return this.copy(qb); 2463 const x = this._x, 2464 y = this._y, 2465 z = this._z, 2466 w = this._w; // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ 2467 2468 let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; 2469 2470 if (cosHalfTheta < 0) { 2471 this._w = -qb._w; 2472 this._x = -qb._x; 2473 this._y = -qb._y; 2474 this._z = -qb._z; 2475 cosHalfTheta = -cosHalfTheta; 2476 } else { 2477 this.copy(qb); 2478 } 2479 2480 if (cosHalfTheta >= 1.0) { 2481 this._w = w; 2482 this._x = x; 2483 this._y = y; 2484 this._z = z; 2485 return this; 2486 } 2487 2488 const sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta; 2489 2490 if (sqrSinHalfTheta <= Number.EPSILON) { 2491 const s = 1 - t; 2492 this._w = s * w + t * this._w; 2493 this._x = s * x + t * this._x; 2494 this._y = s * y + t * this._y; 2495 this._z = s * z + t * this._z; 2496 this.normalize(); 2497 2498 this._onChangeCallback(); 2499 2500 return this; 2501 } 2502 2503 const sinHalfTheta = Math.sqrt(sqrSinHalfTheta); 2504 const halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta); 2505 const ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta, 2506 ratioB = Math.sin(t * halfTheta) / sinHalfTheta; 2507 this._w = w * ratioA + this._w * ratioB; 2508 this._x = x * ratioA + this._x * ratioB; 2509 this._y = y * ratioA + this._y * ratioB; 2510 this._z = z * ratioA + this._z * ratioB; 2511 2512 this._onChangeCallback(); 2513 2514 return this; 2515 } 2516 2517 slerpQuaternions(qa, qb, t) { 2518 this.copy(qa).slerp(qb, t); 2519 } 2520 2521 random() { 2522 // Derived from http://planning.cs.uiuc.edu/node198.html 2523 // Note, this source uses w, x, y, z ordering, 2524 // so we swap the order below. 2525 const u1 = Math.random(); 2526 const sqrt1u1 = Math.sqrt(1 - u1); 2527 const sqrtu1 = Math.sqrt(u1); 2528 const u2 = 2 * Math.PI * Math.random(); 2529 const u3 = 2 * Math.PI * Math.random(); 2530 return this.set(sqrt1u1 * Math.cos(u2), sqrtu1 * Math.sin(u3), sqrtu1 * Math.cos(u3), sqrt1u1 * Math.sin(u2)); 2531 } 2532 2533 equals(quaternion) { 2534 return quaternion._x === this._x && quaternion._y === this._y && quaternion._z === this._z && quaternion._w === this._w; 2535 } 2536 2537 fromArray(array, offset = 0) { 2538 this._x = array[offset]; 2539 this._y = array[offset + 1]; 2540 this._z = array[offset + 2]; 2541 this._w = array[offset + 3]; 2542 2543 this._onChangeCallback(); 2544 2545 return this; 2546 } 2547 2548 toArray(array = [], offset = 0) { 2549 array[offset] = this._x; 2550 array[offset + 1] = this._y; 2551 array[offset + 2] = this._z; 2552 array[offset + 3] = this._w; 2553 return array; 2554 } 2555 2556 fromBufferAttribute(attribute, index) { 2557 this._x = attribute.getX(index); 2558 this._y = attribute.getY(index); 2559 this._z = attribute.getZ(index); 2560 this._w = attribute.getW(index); 2561 return this; 2562 } 2563 2564 _onChange(callback) { 2565 this._onChangeCallback = callback; 2566 return this; 2567 } 2568 2569 _onChangeCallback() {} 2570 2571 } 2572 2573 Quaternion.prototype.isQuaternion = true; 2574 2575 class Vector3 { 2576 constructor(x = 0, y = 0, z = 0) { 2577 this.x = x; 2578 this.y = y; 2579 this.z = z; 2580 } 2581 2582 set(x, y, z) { 2583 if (z === undefined) z = this.z; // sprite.scale.set(x,y) 2584 2585 this.x = x; 2586 this.y = y; 2587 this.z = z; 2588 return this; 2589 } 2590 2591 setScalar(scalar) { 2592 this.x = scalar; 2593 this.y = scalar; 2594 this.z = scalar; 2595 return this; 2596 } 2597 2598 setX(x) { 2599 this.x = x; 2600 return this; 2601 } 2602 2603 setY(y) { 2604 this.y = y; 2605 return this; 2606 } 2607 2608 setZ(z) { 2609 this.z = z; 2610 return this; 2611 } 2612 2613 setComponent(index, value) { 2614 switch (index) { 2615 case 0: 2616 this.x = value; 2617 break; 2618 2619 case 1: 2620 this.y = value; 2621 break; 2622 2623 case 2: 2624 this.z = value; 2625 break; 2626 2627 default: 2628 throw new Error('index is out of range: ' + index); 2629 } 2630 2631 return this; 2632 } 2633 2634 getComponent(index) { 2635 switch (index) { 2636 case 0: 2637 return this.x; 2638 2639 case 1: 2640 return this.y; 2641 2642 case 2: 2643 return this.z; 2644 2645 default: 2646 throw new Error('index is out of range: ' + index); 2647 } 2648 } 2649 2650 clone() { 2651 return new this.constructor(this.x, this.y, this.z); 2652 } 2653 2654 copy(v) { 2655 this.x = v.x; 2656 this.y = v.y; 2657 this.z = v.z; 2658 return this; 2659 } 2660 2661 add(v, w) { 2662 if (w !== undefined) { 2663 console.warn('THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.'); 2664 return this.addVectors(v, w); 2665 } 2666 2667 this.x += v.x; 2668 this.y += v.y; 2669 this.z += v.z; 2670 return this; 2671 } 2672 2673 addScalar(s) { 2674 this.x += s; 2675 this.y += s; 2676 this.z += s; 2677 return this; 2678 } 2679 2680 addVectors(a, b) { 2681 this.x = a.x + b.x; 2682 this.y = a.y + b.y; 2683 this.z = a.z + b.z; 2684 return this; 2685 } 2686 2687 addScaledVector(v, s) { 2688 this.x += v.x * s; 2689 this.y += v.y * s; 2690 this.z += v.z * s; 2691 return this; 2692 } 2693 2694 sub(v, w) { 2695 if (w !== undefined) { 2696 console.warn('THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.'); 2697 return this.subVectors(v, w); 2698 } 2699 2700 this.x -= v.x; 2701 this.y -= v.y; 2702 this.z -= v.z; 2703 return this; 2704 } 2705 2706 subScalar(s) { 2707 this.x -= s; 2708 this.y -= s; 2709 this.z -= s; 2710 return this; 2711 } 2712 2713 subVectors(a, b) { 2714 this.x = a.x - b.x; 2715 this.y = a.y - b.y; 2716 this.z = a.z - b.z; 2717 return this; 2718 } 2719 2720 multiply(v, w) { 2721 if (w !== undefined) { 2722 console.warn('THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.'); 2723 return this.multiplyVectors(v, w); 2724 } 2725 2726 this.x *= v.x; 2727 this.y *= v.y; 2728 this.z *= v.z; 2729 return this; 2730 } 2731 2732 multiplyScalar(scalar) { 2733 this.x *= scalar; 2734 this.y *= scalar; 2735 this.z *= scalar; 2736 return this; 2737 } 2738 2739 multiplyVectors(a, b) { 2740 this.x = a.x * b.x; 2741 this.y = a.y * b.y; 2742 this.z = a.z * b.z; 2743 return this; 2744 } 2745 2746 applyEuler(euler) { 2747 if (!(euler && euler.isEuler)) { 2748 console.error('THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.'); 2749 } 2750 2751 return this.applyQuaternion(_quaternion$4.setFromEuler(euler)); 2752 } 2753 2754 applyAxisAngle(axis, angle) { 2755 return this.applyQuaternion(_quaternion$4.setFromAxisAngle(axis, angle)); 2756 } 2757 2758 applyMatrix3(m) { 2759 const x = this.x, 2760 y = this.y, 2761 z = this.z; 2762 const e = m.elements; 2763 this.x = e[0] * x + e[3] * y + e[6] * z; 2764 this.y = e[1] * x + e[4] * y + e[7] * z; 2765 this.z = e[2] * x + e[5] * y + e[8] * z; 2766 return this; 2767 } 2768 2769 applyNormalMatrix(m) { 2770 return this.applyMatrix3(m).normalize(); 2771 } 2772 2773 applyMatrix4(m) { 2774 const x = this.x, 2775 y = this.y, 2776 z = this.z; 2777 const e = m.elements; 2778 const w = 1 / (e[3] * x + e[7] * y + e[11] * z + e[15]); 2779 this.x = (e[0] * x + e[4] * y + e[8] * z + e[12]) * w; 2780 this.y = (e[1] * x + e[5] * y + e[9] * z + e[13]) * w; 2781 this.z = (e[2] * x + e[6] * y + e[10] * z + e[14]) * w; 2782 return this; 2783 } 2784 2785 applyQuaternion(q) { 2786 const x = this.x, 2787 y = this.y, 2788 z = this.z; 2789 const qx = q.x, 2790 qy = q.y, 2791 qz = q.z, 2792 qw = q.w; // calculate quat * vector 2793 2794 const ix = qw * x + qy * z - qz * y; 2795 const iy = qw * y + qz * x - qx * z; 2796 const iz = qw * z + qx * y - qy * x; 2797 const iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat 2798 2799 this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; 2800 this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; 2801 this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; 2802 return this; 2803 } 2804 2805 project(camera) { 2806 return this.applyMatrix4(camera.matrixWorldInverse).applyMatrix4(camera.projectionMatrix); 2807 } 2808 2809 unproject(camera) { 2810 return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld); 2811 } 2812 2813 transformDirection(m) { 2814 // input: THREE.Matrix4 affine matrix 2815 // vector interpreted as a direction 2816 const x = this.x, 2817 y = this.y, 2818 z = this.z; 2819 const e = m.elements; 2820 this.x = e[0] * x + e[4] * y + e[8] * z; 2821 this.y = e[1] * x + e[5] * y + e[9] * z; 2822 this.z = e[2] * x + e[6] * y + e[10] * z; 2823 return this.normalize(); 2824 } 2825 2826 divide(v) { 2827 this.x /= v.x; 2828 this.y /= v.y; 2829 this.z /= v.z; 2830 return this; 2831 } 2832 2833 divideScalar(scalar) { 2834 return this.multiplyScalar(1 / scalar); 2835 } 2836 2837 min(v) { 2838 this.x = Math.min(this.x, v.x); 2839 this.y = Math.min(this.y, v.y); 2840 this.z = Math.min(this.z, v.z); 2841 return this; 2842 } 2843 2844 max(v) { 2845 this.x = Math.max(this.x, v.x); 2846 this.y = Math.max(this.y, v.y); 2847 this.z = Math.max(this.z, v.z); 2848 return this; 2849 } 2850 2851 clamp(min, max) { 2852 // assumes min < max, componentwise 2853 this.x = Math.max(min.x, Math.min(max.x, this.x)); 2854 this.y = Math.max(min.y, Math.min(max.y, this.y)); 2855 this.z = Math.max(min.z, Math.min(max.z, this.z)); 2856 return this; 2857 } 2858 2859 clampScalar(minVal, maxVal) { 2860 this.x = Math.max(minVal, Math.min(maxVal, this.x)); 2861 this.y = Math.max(minVal, Math.min(maxVal, this.y)); 2862 this.z = Math.max(minVal, Math.min(maxVal, this.z)); 2863 return this; 2864 } 2865 2866 clampLength(min, max) { 2867 const length = this.length(); 2868 return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length))); 2869 } 2870 2871 floor() { 2872 this.x = Math.floor(this.x); 2873 this.y = Math.floor(this.y); 2874 this.z = Math.floor(this.z); 2875 return this; 2876 } 2877 2878 ceil() { 2879 this.x = Math.ceil(this.x); 2880 this.y = Math.ceil(this.y); 2881 this.z = Math.ceil(this.z); 2882 return this; 2883 } 2884 2885 round() { 2886 this.x = Math.round(this.x); 2887 this.y = Math.round(this.y); 2888 this.z = Math.round(this.z); 2889 return this; 2890 } 2891 2892 roundToZero() { 2893 this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x); 2894 this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y); 2895 this.z = this.z < 0 ? Math.ceil(this.z) : Math.floor(this.z); 2896 return this; 2897 } 2898 2899 negate() { 2900 this.x = -this.x; 2901 this.y = -this.y; 2902 this.z = -this.z; 2903 return this; 2904 } 2905 2906 dot(v) { 2907 return this.x * v.x + this.y * v.y + this.z * v.z; 2908 } // TODO lengthSquared? 2909 2910 2911 lengthSq() { 2912 return this.x * this.x + this.y * this.y + this.z * this.z; 2913 } 2914 2915 length() { 2916 return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); 2917 } 2918 2919 manhattanLength() { 2920 return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z); 2921 } 2922 2923 normalize() { 2924 return this.divideScalar(this.length() || 1); 2925 } 2926 2927 setLength(length) { 2928 return this.normalize().multiplyScalar(length); 2929 } 2930 2931 lerp(v, alpha) { 2932 this.x += (v.x - this.x) * alpha; 2933 this.y += (v.y - this.y) * alpha; 2934 this.z += (v.z - this.z) * alpha; 2935 return this; 2936 } 2937 2938 lerpVectors(v1, v2, alpha) { 2939 this.x = v1.x + (v2.x - v1.x) * alpha; 2940 this.y = v1.y + (v2.y - v1.y) * alpha; 2941 this.z = v1.z + (v2.z - v1.z) * alpha; 2942 return this; 2943 } 2944 2945 cross(v, w) { 2946 if (w !== undefined) { 2947 console.warn('THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.'); 2948 return this.crossVectors(v, w); 2949 } 2950 2951 return this.crossVectors(this, v); 2952 } 2953 2954 crossVectors(a, b) { 2955 const ax = a.x, 2956 ay = a.y, 2957 az = a.z; 2958 const bx = b.x, 2959 by = b.y, 2960 bz = b.z; 2961 this.x = ay * bz - az * by; 2962 this.y = az * bx - ax * bz; 2963 this.z = ax * by - ay * bx; 2964 return this; 2965 } 2966 2967 projectOnVector(v) { 2968 const denominator = v.lengthSq(); 2969 if (denominator === 0) return this.set(0, 0, 0); 2970 const scalar = v.dot(this) / denominator; 2971 return this.copy(v).multiplyScalar(scalar); 2972 } 2973 2974 projectOnPlane(planeNormal) { 2975 _vector$c.copy(this).projectOnVector(planeNormal); 2976 2977 return this.sub(_vector$c); 2978 } 2979 2980 reflect(normal) { 2981 // reflect incident vector off plane orthogonal to normal 2982 // normal is assumed to have unit length 2983 return this.sub(_vector$c.copy(normal).multiplyScalar(2 * this.dot(normal))); 2984 } 2985 2986 angleTo(v) { 2987 const denominator = Math.sqrt(this.lengthSq() * v.lengthSq()); 2988 if (denominator === 0) return Math.PI / 2; 2989 const theta = this.dot(v) / denominator; // clamp, to handle numerical problems 2990 2991 return Math.acos(clamp(theta, -1, 1)); 2992 } 2993 2994 distanceTo(v) { 2995 return Math.sqrt(this.distanceToSquared(v)); 2996 } 2997 2998 distanceToSquared(v) { 2999 const dx = this.x - v.x, 3000 dy = this.y - v.y, 3001 dz = this.z - v.z; 3002 return dx * dx + dy * dy + dz * dz; 3003 } 3004 3005 manhattanDistanceTo(v) { 3006 return Math.abs(this.x - v.x) + Math.abs(this.y - v.y) + Math.abs(this.z - v.z); 3007 } 3008 3009 setFromSpherical(s) { 3010 return this.setFromSphericalCoords(s.radius, s.phi, s.theta); 3011 } 3012 3013 setFromSphericalCoords(radius, phi, theta) { 3014 const sinPhiRadius = Math.sin(phi) * radius; 3015 this.x = sinPhiRadius * Math.sin(theta); 3016 this.y = Math.cos(phi) * radius; 3017 this.z = sinPhiRadius * Math.cos(theta); 3018 return this; 3019 } 3020 3021 setFromCylindrical(c) { 3022 return this.setFromCylindricalCoords(c.radius, c.theta, c.y); 3023 } 3024 3025 setFromCylindricalCoords(radius, theta, y) { 3026 this.x = radius * Math.sin(theta); 3027 this.y = y; 3028 this.z = radius * Math.cos(theta); 3029 return this; 3030 } 3031 3032 setFromMatrixPosition(m) { 3033 const e = m.elements; 3034 this.x = e[12]; 3035 this.y = e[13]; 3036 this.z = e[14]; 3037 return this; 3038 } 3039 3040 setFromMatrixScale(m) { 3041 const sx = this.setFromMatrixColumn(m, 0).length(); 3042 const sy = this.setFromMatrixColumn(m, 1).length(); 3043 const sz = this.setFromMatrixColumn(m, 2).length(); 3044 this.x = sx; 3045 this.y = sy; 3046 this.z = sz; 3047 return this; 3048 } 3049 3050 setFromMatrixColumn(m, index) { 3051 return this.fromArray(m.elements, index * 4); 3052 } 3053 3054 setFromMatrix3Column(m, index) { 3055 return this.fromArray(m.elements, index * 3); 3056 } 3057 3058 equals(v) { 3059 return v.x === this.x && v.y === this.y && v.z === this.z; 3060 } 3061 3062 fromArray(array, offset = 0) { 3063 this.x = array[offset]; 3064 this.y = array[offset + 1]; 3065 this.z = array[offset + 2]; 3066 return this; 3067 } 3068 3069 toArray(array = [], offset = 0) { 3070 array[offset] = this.x; 3071 array[offset + 1] = this.y; 3072 array[offset + 2] = this.z; 3073 return array; 3074 } 3075 3076 fromBufferAttribute(attribute, index, offset) { 3077 if (offset !== undefined) { 3078 console.warn('THREE.Vector3: offset has been removed from .fromBufferAttribute().'); 3079 } 3080 3081 this.x = attribute.getX(index); 3082 this.y = attribute.getY(index); 3083 this.z = attribute.getZ(index); 3084 return this; 3085 } 3086 3087 random() { 3088 this.x = Math.random(); 3089 this.y = Math.random(); 3090 this.z = Math.random(); 3091 return this; 3092 } 3093 3094 randomDirection() { 3095 // Derived from https://mathworld.wolfram.com/SpherePointPicking.html 3096 const u = (Math.random() - 0.5) * 2; 3097 const t = Math.random() * Math.PI * 2; 3098 const f = Math.sqrt(1 - u ** 2); 3099 this.x = f * Math.cos(t); 3100 this.y = f * Math.sin(t); 3101 this.z = u; 3102 return this; 3103 } 3104 3105 *[Symbol.iterator]() { 3106 yield this.x; 3107 yield this.y; 3108 yield this.z; 3109 } 3110 3111 } 3112 3113 Vector3.prototype.isVector3 = true; 3114 3115 const _vector$c = /*@__PURE__*/new Vector3(); 3116 3117 const _quaternion$4 = /*@__PURE__*/new Quaternion(); 3118 3119 class Box3 { 3120 constructor(min = new Vector3(+Infinity, +Infinity, +Infinity), max = new Vector3(-Infinity, -Infinity, -Infinity)) { 3121 this.min = min; 3122 this.max = max; 3123 } 3124 3125 set(min, max) { 3126 this.min.copy(min); 3127 this.max.copy(max); 3128 return this; 3129 } 3130 3131 setFromArray(array) { 3132 let minX = +Infinity; 3133 let minY = +Infinity; 3134 let minZ = +Infinity; 3135 let maxX = -Infinity; 3136 let maxY = -Infinity; 3137 let maxZ = -Infinity; 3138 3139 for (let i = 0, l = array.length; i < l; i += 3) { 3140 const x = array[i]; 3141 const y = array[i + 1]; 3142 const z = array[i + 2]; 3143 if (x < minX) minX = x; 3144 if (y < minY) minY = y; 3145 if (z < minZ) minZ = z; 3146 if (x > maxX) maxX = x; 3147 if (y > maxY) maxY = y; 3148 if (z > maxZ) maxZ = z; 3149 } 3150 3151 this.min.set(minX, minY, minZ); 3152 this.max.set(maxX, maxY, maxZ); 3153 return this; 3154 } 3155 3156 setFromBufferAttribute(attribute) { 3157 let minX = +Infinity; 3158 let minY = +Infinity; 3159 let minZ = +Infinity; 3160 let maxX = -Infinity; 3161 let maxY = -Infinity; 3162 let maxZ = -Infinity; 3163 3164 for (let i = 0, l = attribute.count; i < l; i++) { 3165 const x = attribute.getX(i); 3166 const y = attribute.getY(i); 3167 const z = attribute.getZ(i); 3168 if (x < minX) minX = x; 3169 if (y < minY) minY = y; 3170 if (z < minZ) minZ = z; 3171 if (x > maxX) maxX = x; 3172 if (y > maxY) maxY = y; 3173 if (z > maxZ) maxZ = z; 3174 } 3175 3176 this.min.set(minX, minY, minZ); 3177 this.max.set(maxX, maxY, maxZ); 3178 return this; 3179 } 3180 3181 setFromPoints(points) { 3182 this.makeEmpty(); 3183 3184 for (let i = 0, il = points.length; i < il; i++) { 3185 this.expandByPoint(points[i]); 3186 } 3187 3188 return this; 3189 } 3190 3191 setFromCenterAndSize(center, size) { 3192 const halfSize = _vector$b.copy(size).multiplyScalar(0.5); 3193 3194 this.min.copy(center).sub(halfSize); 3195 this.max.copy(center).add(halfSize); 3196 return this; 3197 } 3198 3199 setFromObject(object) { 3200 this.makeEmpty(); 3201 return this.expandByObject(object); 3202 } 3203 3204 clone() { 3205 return new this.constructor().copy(this); 3206 } 3207 3208 copy(box) { 3209 this.min.copy(box.min); 3210 this.max.copy(box.max); 3211 return this; 3212 } 3213 3214 makeEmpty() { 3215 this.min.x = this.min.y = this.min.z = +Infinity; 3216 this.max.x = this.max.y = this.max.z = -Infinity; 3217 return this; 3218 } 3219 3220 isEmpty() { 3221 // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes 3222 return this.max.x < this.min.x || this.max.y < this.min.y || this.max.z < this.min.z; 3223 } 3224 3225 getCenter(target) { 3226 return this.isEmpty() ? target.set(0, 0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5); 3227 } 3228 3229 getSize(target) { 3230 return this.isEmpty() ? target.set(0, 0, 0) : target.subVectors(this.max, this.min); 3231 } 3232 3233 expandByPoint(point) { 3234 this.min.min(point); 3235 this.max.max(point); 3236 return this; 3237 } 3238 3239 expandByVector(vector) { 3240 this.min.sub(vector); 3241 this.max.add(vector); 3242 return this; 3243 } 3244 3245 expandByScalar(scalar) { 3246 this.min.addScalar(-scalar); 3247 this.max.addScalar(scalar); 3248 return this; 3249 } 3250 3251 expandByObject(object) { 3252 // Computes the world-axis-aligned bounding box of an object (including its children), 3253 // accounting for both the object's, and children's, world transforms 3254 object.updateWorldMatrix(false, false); 3255 const geometry = object.geometry; 3256 3257 if (geometry !== undefined) { 3258 if (geometry.boundingBox === null) { 3259 geometry.computeBoundingBox(); 3260 } 3261 3262 _box$3.copy(geometry.boundingBox); 3263 3264 _box$3.applyMatrix4(object.matrixWorld); 3265 3266 this.union(_box$3); 3267 } 3268 3269 const children = object.children; 3270 3271 for (let i = 0, l = children.length; i < l; i++) { 3272 this.expandByObject(children[i]); 3273 } 3274 3275 return this; 3276 } 3277 3278 containsPoint(point) { 3279 return point.x < this.min.x || point.x > this.max.x || point.y < this.min.y || point.y > this.max.y || point.z < this.min.z || point.z > this.max.z ? false : true; 3280 } 3281 3282 containsBox(box) { 3283 return this.min.x <= box.min.x && box.max.x <= this.max.x && this.min.y <= box.min.y && box.max.y <= this.max.y && this.min.z <= box.min.z && box.max.z <= this.max.z; 3284 } 3285 3286 getParameter(point, target) { 3287 // This can potentially have a divide by zero if the box 3288 // has a size dimension of 0. 3289 return target.set((point.x - this.min.x) / (this.max.x - this.min.x), (point.y - this.min.y) / (this.max.y - this.min.y), (point.z - this.min.z) / (this.max.z - this.min.z)); 3290 } 3291 3292 intersectsBox(box) { 3293 // using 6 splitting planes to rule out intersections. 3294 return box.max.x < this.min.x || box.min.x > this.max.x || box.max.y < this.min.y || box.min.y > this.max.y || box.max.z < this.min.z || box.min.z > this.max.z ? false : true; 3295 } 3296 3297 intersectsSphere(sphere) { 3298 // Find the point on the AABB closest to the sphere center. 3299 this.clampPoint(sphere.center, _vector$b); // If that point is inside the sphere, the AABB and sphere intersect. 3300 3301 return _vector$b.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius; 3302 } 3303 3304 intersectsPlane(plane) { 3305 // We compute the minimum and maximum dot product values. If those values 3306 // are on the same side (back or front) of the plane, then there is no intersection. 3307 let min, max; 3308 3309 if (plane.normal.x > 0) { 3310 min = plane.normal.x * this.min.x; 3311 max = plane.normal.x * this.max.x; 3312 } else { 3313 min = plane.normal.x * this.max.x; 3314 max = plane.normal.x * this.min.x; 3315 } 3316 3317 if (plane.normal.y > 0) { 3318 min += plane.normal.y * this.min.y; 3319 max += plane.normal.y * this.max.y; 3320 } else { 3321 min += plane.normal.y * this.max.y; 3322 max += plane.normal.y * this.min.y; 3323 } 3324 3325 if (plane.normal.z > 0) { 3326 min += plane.normal.z * this.min.z; 3327 max += plane.normal.z * this.max.z; 3328 } else { 3329 min += plane.normal.z * this.max.z; 3330 max += plane.normal.z * this.min.z; 3331 } 3332 3333 return min <= -plane.constant && max >= -plane.constant; 3334 } 3335 3336 intersectsTriangle(triangle) { 3337 if (this.isEmpty()) { 3338 return false; 3339 } // compute box center and extents 3340 3341 3342 this.getCenter(_center); 3343 3344 _extents.subVectors(this.max, _center); // translate triangle to aabb origin 3345 3346 3347 _v0$2.subVectors(triangle.a, _center); 3348 3349 _v1$7.subVectors(triangle.b, _center); 3350 3351 _v2$3.subVectors(triangle.c, _center); // compute edge vectors for triangle 3352 3353 3354 _f0.subVectors(_v1$7, _v0$2); 3355 3356 _f1.subVectors(_v2$3, _v1$7); 3357 3358 _f2.subVectors(_v0$2, _v2$3); // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb 3359 // make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation 3360 // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned) 3361 3362 3363 let axes = [0, -_f0.z, _f0.y, 0, -_f1.z, _f1.y, 0, -_f2.z, _f2.y, _f0.z, 0, -_f0.x, _f1.z, 0, -_f1.x, _f2.z, 0, -_f2.x, -_f0.y, _f0.x, 0, -_f1.y, _f1.x, 0, -_f2.y, _f2.x, 0]; 3364 3365 if (!satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents)) { 3366 return false;
vendor: 4,321 bytes, lines 3367-3518
3367 } // test 3 face normals from the aabb 3368 3369 3370 axes = [1, 0, 0, 0, 1, 0, 0, 0, 1]; 3371 3372 if (!satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents)) { 3373 return false; 3374 } // finally testing the face normal of the triangle 3375 // use already existing triangle edge vectors here 3376 3377 3378 _triangleNormal.crossVectors(_f0, _f1); 3379 3380 axes = [_triangleNormal.x, _triangleNormal.y, _triangleNormal.z]; 3381 return satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents); 3382 } 3383 3384 clampPoint(point, target) { 3385 return target.copy(point).clamp(this.min, this.max); 3386 } 3387 3388 distanceToPoint(point) { 3389 const clampedPoint = _vector$b.copy(point).clamp(this.min, this.max); 3390 3391 return clampedPoint.sub(point).length(); 3392 } 3393 3394 getBoundingSphere(target) { 3395 this.getCenter(target.center); 3396 target.radius = this.getSize(_vector$b).length() * 0.5; 3397 return target; 3398 } 3399 3400 intersect(box) { 3401 this.min.max(box.min); 3402 this.max.min(box.max); // ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values. 3403 3404 if (this.isEmpty()) this.makeEmpty(); 3405 return this; 3406 } 3407 3408 union(box) { 3409 this.min.min(box.min); 3410 this.max.max(box.max); 3411 return this; 3412 } 3413 3414 applyMatrix4(matrix) { 3415 // transform of empty box is an empty box. 3416 if (this.isEmpty()) return this; // NOTE: I am using a binary pattern to specify all 2^3 combinations below 3417 3418 _points[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(matrix); // 000 3419 3420 3421 _points[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(matrix); // 001 3422 3423 3424 _points[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(matrix); // 010 3425 3426 3427 _points[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(matrix); // 011 3428 3429 3430 _points[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(matrix); // 100 3431 3432 3433 _points[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(matrix); // 101 3434 3435 3436 _points[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(matrix); // 110 3437 3438 3439 _points[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(matrix); // 111 3440 3441 3442 this.setFromPoints(_points); 3443 return this; 3444 } 3445 3446 translate(offset) { 3447 this.min.add(offset); 3448 this.max.add(offset); 3449 return this; 3450 } 3451 3452 equals(box) { 3453 return box.min.equals(this.min) && box.max.equals(this.max); 3454 } 3455 3456 } 3457 3458 Box3.prototype.isBox3 = true; 3459 const _points = [/*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3()]; 3460 3461 const _vector$b = /*@__PURE__*/new Vector3(); 3462 3463 const _box$3 = /*@__PURE__*/new Box3(); // triangle centered vertices 3464 3465 3466 const _v0$2 = /*@__PURE__*/new Vector3(); 3467 3468 const _v1$7 = /*@__PURE__*/new Vector3(); 3469 3470 const _v2$3 = /*@__PURE__*/new Vector3(); // triangle edge vectors 3471 3472 3473 const _f0 = /*@__PURE__*/new Vector3(); 3474 3475 const _f1 = /*@__PURE__*/new Vector3(); 3476 3477 const _f2 = /*@__PURE__*/new Vector3(); 3478 3479 const _center = /*@__PURE__*/new Vector3(); 3480 3481 const _extents = /*@__PURE__*/new Vector3(); 3482 3483 const _triangleNormal = /*@__PURE__*/new Vector3(); 3484 3485 const _testAxis = /*@__PURE__*/new Vector3(); 3486 3487 function satForAxes(axes, v0, v1, v2, extents) { 3488 for (let i = 0, j = axes.length - 3; i <= j; i += 3) { 3489 _testAxis.fromArray(axes, i); // project the aabb onto the seperating axis 3490 3491 3492 const r = extents.x * Math.abs(_testAxis.x) + extents.y * Math.abs(_testAxis.y) + extents.z * Math.abs(_testAxis.z); // project all 3 vertices of the triangle onto the seperating axis 3493 3494 const p0 = v0.dot(_testAxis); 3495 const p1 = v1.dot(_testAxis); 3496 const p2 = v2.dot(_testAxis); // actual test, basically see if either of the most extreme of the triangle points intersects r 3497 3498 if (Math.max(-Math.max(p0, p1, p2), Math.min(p0, p1, p2)) > r) { 3499 // points of the projected triangle are outside the projected half-length of the aabb 3500 // the axis is seperating and we can exit 3501 return false; 3502 } 3503 } 3504 3505 return true; 3506 } 3507 3508 const _box$2 = /*@__PURE__*/new Box3(); 3509 3510 const _v1$6 = /*@__PURE__*/new Vector3(); 3511 3512 const _toFarthestPoint = /*@__PURE__*/new Vector3(); 3513 3514 const _toPoint = /*@__PURE__*/new Vector3(); 3515 3516 class Sphere { 3517 constructor(center = new Vector3(), radius = -1) { 3518 this.center = center;
vendor: 4,848 bytes, lines 3519-3711
3519 this.radius = radius; 3520 } 3521 3522 set(center, radius) { 3523 this.center.copy(center); 3524 this.radius = radius; 3525 return this; 3526 } 3527 3528 setFromPoints(points, optionalCenter) { 3529 const center = this.center; 3530 3531 if (optionalCenter !== undefined) { 3532 center.copy(optionalCenter); 3533 } else { 3534 _box$2.setFromPoints(points).getCenter(center); 3535 } 3536 3537 let maxRadiusSq = 0; 3538 3539 for (let i = 0, il = points.length; i < il; i++) { 3540 maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(points[i])); 3541 } 3542 3543 this.radius = Math.sqrt(maxRadiusSq); 3544 return this; 3545 } 3546 3547 copy(sphere) { 3548 this.center.copy(sphere.center); 3549 this.radius = sphere.radius; 3550 return this; 3551 } 3552 3553 isEmpty() { 3554 return this.radius < 0; 3555 } 3556 3557 makeEmpty() { 3558 this.center.set(0, 0, 0); 3559 this.radius = -1; 3560 return this; 3561 } 3562 3563 containsPoint(point) { 3564 return point.distanceToSquared(this.center) <= this.radius * this.radius; 3565 } 3566 3567 distanceToPoint(point) { 3568 return point.distanceTo(this.center) - this.radius; 3569 } 3570 3571 intersectsSphere(sphere) { 3572 const radiusSum = this.radius + sphere.radius; 3573 return sphere.center.distanceToSquared(this.center) <= radiusSum * radiusSum; 3574 } 3575 3576 intersectsBox(box) { 3577 return box.intersectsSphere(this); 3578 } 3579 3580 intersectsPlane(plane) { 3581 return Math.abs(plane.distanceToPoint(this.center)) <= this.radius; 3582 } 3583 3584 clampPoint(point, target) { 3585 const deltaLengthSq = this.center.distanceToSquared(point); 3586 target.copy(point); 3587 3588 if (deltaLengthSq > this.radius * this.radius) { 3589 target.sub(this.center).normalize(); 3590 target.multiplyScalar(this.radius).add(this.center); 3591 } 3592 3593 return target; 3594 } 3595 3596 getBoundingBox(target) { 3597 if (this.isEmpty()) { 3598 // Empty sphere produces empty bounding box 3599 target.makeEmpty(); 3600 return target; 3601 } 3602 3603 target.set(this.center, this.center); 3604 target.expandByScalar(this.radius); 3605 return target; 3606 } 3607 3608 applyMatrix4(matrix) { 3609 this.center.applyMatrix4(matrix); 3610 this.radius = this.radius * matrix.getMaxScaleOnAxis(); 3611 return this; 3612 } 3613 3614 translate(offset) { 3615 this.center.add(offset); 3616 return this; 3617 } 3618 3619 expandByPoint(point) { 3620 // from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L649-L671 3621 _toPoint.subVectors(point, this.center); 3622 3623 const lengthSq = _toPoint.lengthSq(); 3624 3625 if (lengthSq > this.radius * this.radius) { 3626 const length = Math.sqrt(lengthSq); 3627 const missingRadiusHalf = (length - this.radius) * 0.5; // Nudge this sphere towards the target point. Add half the missing distance to radius, 3628 // and the other half to position. This gives a tighter enclosure, instead of if 3629 // the whole missing distance were just added to radius. 3630 3631 this.center.add(_toPoint.multiplyScalar(missingRadiusHalf / length)); 3632 this.radius += missingRadiusHalf; 3633 } 3634 3635 return this; 3636 } 3637 3638 union(sphere) { 3639 // from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L759-L769 3640 // To enclose another sphere into this sphere, we only need to enclose two points: 3641 // 1) Enclose the farthest point on the other sphere into this sphere. 3642 // 2) Enclose the opposite point of the farthest point into this sphere. 3643 if (this.center.equals(sphere.center) === true) { 3644 _toFarthestPoint.set(0, 0, 1).multiplyScalar(sphere.radius); 3645 } else { 3646 _toFarthestPoint.subVectors(sphere.center, this.center).normalize().multiplyScalar(sphere.radius); 3647 } 3648 3649 this.expandByPoint(_v1$6.copy(sphere.center).add(_toFarthestPoint)); 3650 this.expandByPoint(_v1$6.copy(sphere.center).sub(_toFarthestPoint)); 3651 return this; 3652 } 3653 3654 equals(sphere) { 3655 return sphere.center.equals(this.center) && sphere.radius === this.radius; 3656 } 3657 3658 clone() { 3659 return new this.constructor().copy(this); 3660 } 3661 3662 } 3663 3664 const _vector$a = /*@__PURE__*/new Vector3(); 3665 3666 const _segCenter = /*@__PURE__*/new Vector3(); 3667 3668 const _segDir = /*@__PURE__*/new Vector3(); 3669 3670 const _diff = /*@__PURE__*/new Vector3(); 3671 3672 const _edge1 = /*@__PURE__*/new Vector3(); 3673 3674 const _edge2 = /*@__PURE__*/new Vector3(); 3675 3676 const _normal$1 = /*@__PURE__*/new Vector3(); 3677 3678 class Ray { 3679 constructor(origin = new Vector3(), direction = new Vector3(0, 0, -1)) { 3680 this.origin = origin; 3681 this.direction = direction; 3682 } 3683 3684 set(origin, direction) { 3685 this.origin.copy(origin); 3686 this.direction.copy(direction); 3687 return this; 3688 } 3689 3690 copy(ray) { 3691 this.origin.copy(ray.origin); 3692 this.direction.copy(ray.direction); 3693 return this; 3694 } 3695 3696 at(t, target) { 3697 return target.copy(this.direction).multiplyScalar(t).add(this.origin); 3698 } 3699 3700 lookAt(v) { 3701 this.direction.copy(v).sub(this.origin).normalize(); 3702 return this; 3703 } 3704 3705 recast(t) { 3706 this.origin.copy(this.at(t, _vector$a)); 3707 return this; 3708 } 3709 3710 closestPointToPoint(point, target) { 3711 target.subVectors(point, this.origin);
vendor: 28,216 bytes, lines 3712-4812
3712 const directionDistance = target.dot(this.direction); 3713 3714 if (directionDistance < 0) { 3715 return target.copy(this.origin); 3716 } 3717 3718 return target.copy(this.direction).multiplyScalar(directionDistance).add(this.origin); 3719 } 3720 3721 distanceToPoint(point) { 3722 return Math.sqrt(this.distanceSqToPoint(point)); 3723 } 3724 3725 distanceSqToPoint(point) { 3726 const directionDistance = _vector$a.subVectors(point, this.origin).dot(this.direction); // point behind the ray 3727 3728 3729 if (directionDistance < 0) { 3730 return this.origin.distanceToSquared(point); 3731 } 3732 3733 _vector$a.copy(this.direction).multiplyScalar(directionDistance).add(this.origin); 3734 3735 return _vector$a.distanceToSquared(point); 3736 } 3737 3738 distanceSqToSegment(v0, v1, optionalPointOnRay, optionalPointOnSegment) { 3739 // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteDistRaySegment.h 3740 // It returns the min distance between the ray and the segment 3741 // defined by v0 and v1 3742 // It can also set two optional targets : 3743 // - The closest point on the ray 3744 // - The closest point on the segment 3745 _segCenter.copy(v0).add(v1).multiplyScalar(0.5); 3746 3747 _segDir.copy(v1).sub(v0).normalize(); 3748 3749 _diff.copy(this.origin).sub(_segCenter); 3750 3751 const segExtent = v0.distanceTo(v1) * 0.5; 3752 const a01 = -this.direction.dot(_segDir); 3753 3754 const b0 = _diff.dot(this.direction); 3755 3756 const b1 = -_diff.dot(_segDir); 3757 3758 const c = _diff.lengthSq(); 3759 3760 const det = Math.abs(1 - a01 * a01); 3761 let s0, s1, sqrDist, extDet; 3762 3763 if (det > 0) { 3764 // The ray and segment are not parallel. 3765 s0 = a01 * b1 - b0; 3766 s1 = a01 * b0 - b1; 3767 extDet = segExtent * det; 3768 3769 if (s0 >= 0) { 3770 if (s1 >= -extDet) { 3771 if (s1 <= extDet) { 3772 // region 0 3773 // Minimum at interior points of ray and segment. 3774 const invDet = 1 / det; 3775 s0 *= invDet; 3776 s1 *= invDet; 3777 sqrDist = s0 * (s0 + a01 * s1 + 2 * b0) + s1 * (a01 * s0 + s1 + 2 * b1) + c; 3778 } else { 3779 // region 1 3780 s1 = segExtent; 3781 s0 = Math.max(0, -(a01 * s1 + b0)); 3782 sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; 3783 } 3784 } else { 3785 // region 5 3786 s1 = -segExtent; 3787 s0 = Math.max(0, -(a01 * s1 + b0)); 3788 sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; 3789 } 3790 } else { 3791 if (s1 <= -extDet) { 3792 // region 4 3793 s0 = Math.max(0, -(-a01 * segExtent + b0)); 3794 s1 = s0 > 0 ? -segExtent : Math.min(Math.max(-segExtent, -b1), segExtent); 3795 sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; 3796 } else if (s1 <= extDet) { 3797 // region 3 3798 s0 = 0; 3799 s1 = Math.min(Math.max(-segExtent, -b1), segExtent); 3800 sqrDist = s1 * (s1 + 2 * b1) + c; 3801 } else { 3802 // region 2 3803 s0 = Math.max(0, -(a01 * segExtent + b0)); 3804 s1 = s0 > 0 ? segExtent : Math.min(Math.max(-segExtent, -b1), segExtent); 3805 sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; 3806 } 3807 } 3808 } else { 3809 // Ray and segment are parallel. 3810 s1 = a01 > 0 ? -segExtent : segExtent; 3811 s0 = Math.max(0, -(a01 * s1 + b0)); 3812 sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; 3813 } 3814 3815 if (optionalPointOnRay) { 3816 optionalPointOnRay.copy(this.direction).multiplyScalar(s0).add(this.origin); 3817 } 3818 3819 if (optionalPointOnSegment) { 3820 optionalPointOnSegment.copy(_segDir).multiplyScalar(s1).add(_segCenter); 3821 } 3822 3823 return sqrDist; 3824 } 3825 3826 intersectSphere(sphere, target) { 3827 _vector$a.subVectors(sphere.center, this.origin); 3828 3829 const tca = _vector$a.dot(this.direction); 3830 3831 const d2 = _vector$a.dot(_vector$a) - tca * tca; 3832 const radius2 = sphere.radius * sphere.radius; 3833 if (d2 > radius2) return null; 3834 const thc = Math.sqrt(radius2 - d2); // t0 = first intersect point - entrance on front of sphere 3835 3836 const t0 = tca - thc; // t1 = second intersect point - exit point on back of sphere 3837 3838 const t1 = tca + thc; // test to see if both t0 and t1 are behind the ray - if so, return null 3839 3840 if (t0 < 0 && t1 < 0) return null; // test to see if t0 is behind the ray: 3841 // if it is, the ray is inside the sphere, so return the second exit point scaled by t1, 3842 // in order to always return an intersect point that is in front of the ray. 3843 3844 if (t0 < 0) return this.at(t1, target); // else t0 is in front of the ray, so return the first collision point scaled by t0 3845 3846 return this.at(t0, target); 3847 } 3848 3849 intersectsSphere(sphere) { 3850 return this.distanceSqToPoint(sphere.center) <= sphere.radius * sphere.radius; 3851 } 3852 3853 distanceToPlane(plane) { 3854 const denominator = plane.normal.dot(this.direction); 3855 3856 if (denominator === 0) { 3857 // line is coplanar, return origin 3858 if (plane.distanceToPoint(this.origin) === 0) { 3859 return 0; 3860 } // Null is preferable to undefined since undefined means.... it is undefined 3861 3862 3863 return null; 3864 } 3865 3866 const t = -(this.origin.dot(plane.normal) + plane.constant) / denominator; // Return if the ray never intersects the plane 3867 3868 return t >= 0 ? t : null; 3869 } 3870 3871 intersectPlane(plane, target) { 3872 const t = this.distanceToPlane(plane); 3873 3874 if (t === null) { 3875 return null; 3876 } 3877 3878 return this.at(t, target); 3879 } 3880 3881 intersectsPlane(plane) { 3882 // check if the ray lies on the plane first 3883 const distToPoint = plane.distanceToPoint(this.origin); 3884 3885 if (distToPoint === 0) { 3886 return true; 3887 } 3888 3889 const denominator = plane.normal.dot(this.direction); 3890 3891 if (denominator * distToPoint < 0) { 3892 return true; 3893 } // ray origin is behind the plane (and is pointing behind it) 3894 3895 3896 return false; 3897 } 3898 3899 intersectBox(box, target) { 3900 let tmin, tmax, tymin, tymax, tzmin, tzmax; 3901 const invdirx = 1 / this.direction.x, 3902 invdiry = 1 / this.direction.y, 3903 invdirz = 1 / this.direction.z; 3904 const origin = this.origin; 3905 3906 if (invdirx >= 0) { 3907 tmin = (box.min.x - origin.x) * invdirx; 3908 tmax = (box.max.x - origin.x) * invdirx; 3909 } else { 3910 tmin = (box.max.x - origin.x) * invdirx; 3911 tmax = (box.min.x - origin.x) * invdirx; 3912 } 3913 3914 if (invdiry >= 0) { 3915 tymin = (box.min.y - origin.y) * invdiry; 3916 tymax = (box.max.y - origin.y) * invdiry; 3917 } else { 3918 tymin = (box.max.y - origin.y) * invdiry; 3919 tymax = (box.min.y - origin.y) * invdiry; 3920 } 3921 3922 if (tmin > tymax || tymin > tmax) return null; // These lines also handle the case where tmin or tmax is NaN 3923 // (result of 0 * Infinity). x !== x returns true if x is NaN 3924 3925 if (tymin > tmin || tmin !== tmin) tmin = tymin; 3926 if (tymax < tmax || tmax !== tmax) tmax = tymax; 3927 3928 if (invdirz >= 0) { 3929 tzmin = (box.min.z - origin.z) * invdirz; 3930 tzmax = (box.max.z - origin.z) * invdirz; 3931 } else { 3932 tzmin = (box.max.z - origin.z) * invdirz; 3933 tzmax = (box.min.z - origin.z) * invdirz; 3934 } 3935 3936 if (tmin > tzmax || tzmin > tmax) return null; 3937 if (tzmin > tmin || tmin !== tmin) tmin = tzmin; 3938 if (tzmax < tmax || tmax !== tmax) tmax = tzmax; //return point closest to the ray (positive side) 3939 3940 if (tmax < 0) return null; 3941 return this.at(tmin >= 0 ? tmin : tmax, target); 3942 } 3943 3944 intersectsBox(box) { 3945 return this.intersectBox(box, _vector$a) !== null; 3946 } 3947 3948 intersectTriangle(a, b, c, backfaceCulling, target) { 3949 // Compute the offset origin, edges, and normal. 3950 // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h 3951 _edge1.subVectors(b, a); 3952 3953 _edge2.subVectors(c, a); 3954 3955 _normal$1.crossVectors(_edge1, _edge2); // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, 3956 // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by 3957 // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) 3958 // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) 3959 // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) 3960 3961 3962 let DdN = this.direction.dot(_normal$1); 3963 let sign; 3964 3965 if (DdN > 0) { 3966 if (backfaceCulling) return null; 3967 sign = 1; 3968 } else if (DdN < 0) { 3969 sign = -1; 3970 DdN = -DdN; 3971 } else { 3972 return null; 3973 } 3974 3975 _diff.subVectors(this.origin, a); 3976 3977 const DdQxE2 = sign * this.direction.dot(_edge2.crossVectors(_diff, _edge2)); // b1 < 0, no intersection 3978 3979 if (DdQxE2 < 0) { 3980 return null; 3981 } 3982 3983 const DdE1xQ = sign * this.direction.dot(_edge1.cross(_diff)); // b2 < 0, no intersection 3984 3985 if (DdE1xQ < 0) { 3986 return null; 3987 } // b1+b2 > 1, no intersection 3988 3989 3990 if (DdQxE2 + DdE1xQ > DdN) { 3991 return null; 3992 } // Line intersects triangle, check if ray does. 3993 3994 3995 const QdN = -sign * _diff.dot(_normal$1); // t < 0, no intersection 3996 3997 3998 if (QdN < 0) { 3999 return null; 4000 } // Ray intersects triangle. 4001 4002 4003 return this.at(QdN / DdN, target); 4004 } 4005 4006 applyMatrix4(matrix4) { 4007 this.origin.applyMatrix4(matrix4); 4008 this.direction.transformDirection(matrix4); 4009 return this; 4010 } 4011 4012 equals(ray) { 4013 return ray.origin.equals(this.origin) && ray.direction.equals(this.direction); 4014 } 4015 4016 clone() { 4017 return new this.constructor().copy(this); 4018 } 4019 4020 } 4021 4022 class Matrix4 { 4023 constructor() { 4024 this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; 4025 4026 if (arguments.length > 0) { 4027 console.error('THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.'); 4028 } 4029 } 4030 4031 set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) { 4032 const te = this.elements; 4033 te[0] = n11; 4034 te[4] = n12; 4035 te[8] = n13; 4036 te[12] = n14; 4037 te[1] = n21; 4038 te[5] = n22; 4039 te[9] = n23; 4040 te[13] = n24; 4041 te[2] = n31; 4042 te[6] = n32; 4043 te[10] = n33; 4044 te[14] = n34; 4045 te[3] = n41; 4046 te[7] = n42; 4047 te[11] = n43; 4048 te[15] = n44; 4049 return this; 4050 } 4051 4052 identity() { 4053 this.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); 4054 return this; 4055 } 4056 4057 clone() { 4058 return new Matrix4().fromArray(this.elements); 4059 } 4060 4061 copy(m) { 4062 const te = this.elements; 4063 const me = m.elements; 4064 te[0] = me[0]; 4065 te[1] = me[1]; 4066 te[2] = me[2]; 4067 te[3] = me[3]; 4068 te[4] = me[4]; 4069 te[5] = me[5]; 4070 te[6] = me[6]; 4071 te[7] = me[7]; 4072 te[8] = me[8]; 4073 te[9] = me[9]; 4074 te[10] = me[10]; 4075 te[11] = me[11]; 4076 te[12] = me[12]; 4077 te[13] = me[13]; 4078 te[14] = me[14]; 4079 te[15] = me[15]; 4080 return this; 4081 } 4082 4083 copyPosition(m) { 4084 const te = this.elements, 4085 me = m.elements; 4086 te[12] = me[12]; 4087 te[13] = me[13]; 4088 te[14] = me[14]; 4089 return this; 4090 } 4091 4092 setFromMatrix3(m) { 4093 const me = m.elements; 4094 this.set(me[0], me[3], me[6], 0, me[1], me[4], me[7], 0, me[2], me[5], me[8], 0, 0, 0, 0, 1); 4095 return this; 4096 } 4097 4098 extractBasis(xAxis, yAxis, zAxis) { 4099 xAxis.setFromMatrixColumn(this, 0); 4100 yAxis.setFromMatrixColumn(this, 1); 4101 zAxis.setFromMatrixColumn(this, 2); 4102 return this; 4103 } 4104 4105 makeBasis(xAxis, yAxis, zAxis) { 4106 this.set(xAxis.x, yAxis.x, zAxis.x, 0, xAxis.y, yAxis.y, zAxis.y, 0, xAxis.z, yAxis.z, zAxis.z, 0, 0, 0, 0, 1); 4107 return this; 4108 } 4109 4110 extractRotation(m) { 4111 // this method does not support reflection matrices 4112 const te = this.elements; 4113 const me = m.elements; 4114 4115 const scaleX = 1 / _v1$5.setFromMatrixColumn(m, 0).length(); 4116 4117 const scaleY = 1 / _v1$5.setFromMatrixColumn(m, 1).length(); 4118 4119 const scaleZ = 1 / _v1$5.setFromMatrixColumn(m, 2).length(); 4120 4121 te[0] = me[0] * scaleX; 4122 te[1] = me[1] * scaleX; 4123 te[2] = me[2] * scaleX; 4124 te[3] = 0; 4125 te[4] = me[4] * scaleY; 4126 te[5] = me[5] * scaleY; 4127 te[6] = me[6] * scaleY; 4128 te[7] = 0; 4129 te[8] = me[8] * scaleZ; 4130 te[9] = me[9] * scaleZ; 4131 te[10] = me[10] * scaleZ; 4132 te[11] = 0; 4133 te[12] = 0; 4134 te[13] = 0; 4135 te[14] = 0; 4136 te[15] = 1; 4137 return this; 4138 } 4139 4140 makeRotationFromEuler(euler) { 4141 if (!(euler && euler.isEuler)) { 4142 console.error('THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.'); 4143 } 4144 4145 const te = this.elements; 4146 const x = euler.x, 4147 y = euler.y, 4148 z = euler.z; 4149 const a = Math.cos(x), 4150 b = Math.sin(x); 4151 const c = Math.cos(y), 4152 d = Math.sin(y); 4153 const e = Math.cos(z), 4154 f = Math.sin(z); 4155 4156 if (euler.order === 'XYZ') { 4157 const ae = a * e, 4158 af = a * f, 4159 be = b * e, 4160 bf = b * f; 4161 te[0] = c * e; 4162 te[4] = -c * f; 4163 te[8] = d; 4164 te[1] = af + be * d; 4165 te[5] = ae - bf * d; 4166 te[9] = -b * c; 4167 te[2] = bf - ae * d; 4168 te[6] = be + af * d; 4169 te[10] = a * c; 4170 } else if (euler.order === 'YXZ') { 4171 const ce = c * e, 4172 cf = c * f, 4173 de = d * e, 4174 df = d * f; 4175 te[0] = ce + df * b; 4176 te[4] = de * b - cf; 4177 te[8] = a * d; 4178 te[1] = a * f; 4179 te[5] = a * e; 4180 te[9] = -b; 4181 te[2] = cf * b - de; 4182 te[6] = df + ce * b; 4183 te[10] = a * c; 4184 } else if (euler.order === 'ZXY') { 4185 const ce = c * e, 4186 cf = c * f, 4187 de = d * e, 4188 df = d * f; 4189 te[0] = ce - df * b; 4190 te[4] = -a * f; 4191 te[8] = de + cf * b; 4192 te[1] = cf + de * b; 4193 te[5] = a * e; 4194 te[9] = df - ce * b; 4195 te[2] = -a * d; 4196 te[6] = b; 4197 te[10] = a * c; 4198 } else if (euler.order === 'ZYX') { 4199 const ae = a * e, 4200 af = a * f, 4201 be = b * e, 4202 bf = b * f; 4203 te[0] = c * e; 4204 te[4] = be * d - af; 4205 te[8] = ae * d + bf; 4206 te[1] = c * f; 4207 te[5] = bf * d + ae; 4208 te[9] = af * d - be; 4209 te[2] = -d; 4210 te[6] = b * c; 4211 te[10] = a * c; 4212 } else if (euler.order === 'YZX') { 4213 const ac = a * c, 4214 ad = a * d, 4215 bc = b * c, 4216 bd = b * d; 4217 te[0] = c * e; 4218 te[4] = bd - ac * f; 4219 te[8] = bc * f + ad; 4220 te[1] = f; 4221 te[5] = a * e; 4222 te[9] = -b * e; 4223 te[2] = -d * e; 4224 te[6] = ad * f + bc; 4225 te[10] = ac - bd * f; 4226 } else if (euler.order === 'XZY') { 4227 const ac = a * c, 4228 ad = a * d, 4229 bc = b * c, 4230 bd = b * d; 4231 te[0] = c * e; 4232 te[4] = -f; 4233 te[8] = d * e; 4234 te[1] = ac * f + bd; 4235 te[5] = a * e; 4236 te[9] = ad * f - bc; 4237 te[2] = bc * f - ad; 4238 te[6] = b * e; 4239 te[10] = bd * f + ac; 4240 } // bottom row 4241 4242 4243 te[3] = 0; 4244 te[7] = 0; 4245 te[11] = 0; // last column 4246 4247 te[12] = 0; 4248 te[13] = 0; 4249 te[14] = 0; 4250 te[15] = 1; 4251 return this; 4252 } 4253 4254 makeRotationFromQuaternion(q) { 4255 return this.compose(_zero, q, _one); 4256 } 4257 4258 lookAt(eye, target, up) { 4259 const te = this.elements; 4260 4261 _z.subVectors(eye, target); 4262 4263 if (_z.lengthSq() === 0) { 4264 // eye and target are in the same position 4265 _z.z = 1; 4266 } 4267 4268 _z.normalize(); 4269 4270 _x.crossVectors(up, _z); 4271 4272 if (_x.lengthSq() === 0) { 4273 // up and z are parallel 4274 if (Math.abs(up.z) === 1) { 4275 _z.x += 0.0001; 4276 } else { 4277 _z.z += 0.0001; 4278 } 4279 4280 _z.normalize(); 4281 4282 _x.crossVectors(up, _z); 4283 } 4284 4285 _x.normalize(); 4286 4287 _y.crossVectors(_z, _x); 4288 4289 te[0] = _x.x; 4290 te[4] = _y.x; 4291 te[8] = _z.x; 4292 te[1] = _x.y; 4293 te[5] = _y.y; 4294 te[9] = _z.y; 4295 te[2] = _x.z; 4296 te[6] = _y.z; 4297 te[10] = _z.z; 4298 return this; 4299 } 4300 4301 multiply(m, n) { 4302 if (n !== undefined) { 4303 console.warn('THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.'); 4304 return this.multiplyMatrices(m, n); 4305 } 4306 4307 return this.multiplyMatrices(this, m); 4308 } 4309 4310 premultiply(m) { 4311 return this.multiplyMatrices(m, this); 4312 } 4313 4314 multiplyMatrices(a, b) { 4315 const ae = a.elements; 4316 const be = b.elements; 4317 const te = this.elements; 4318 const a11 = ae[0], 4319 a12 = ae[4], 4320 a13 = ae[8], 4321 a14 = ae[12]; 4322 const a21 = ae[1], 4323 a22 = ae[5], 4324 a23 = ae[9], 4325 a24 = ae[13]; 4326 const a31 = ae[2], 4327 a32 = ae[6], 4328 a33 = ae[10], 4329 a34 = ae[14]; 4330 const a41 = ae[3], 4331 a42 = ae[7], 4332 a43 = ae[11], 4333 a44 = ae[15]; 4334 const b11 = be[0], 4335 b12 = be[4], 4336 b13 = be[8], 4337 b14 = be[12]; 4338 const b21 = be[1], 4339 b22 = be[5], 4340 b23 = be[9], 4341 b24 = be[13]; 4342 const b31 = be[2], 4343 b32 = be[6], 4344 b33 = be[10], 4345 b34 = be[14]; 4346 const b41 = be[3], 4347 b42 = be[7], 4348 b43 = be[11], 4349 b44 = be[15]; 4350 te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; 4351 te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; 4352 te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; 4353 te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; 4354 te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; 4355 te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; 4356 te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; 4357 te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; 4358 te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; 4359 te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; 4360 te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; 4361 te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; 4362 te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; 4363 te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; 4364 te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; 4365 te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; 4366 return this; 4367 } 4368 4369 multiplyScalar(s) { 4370 const te = this.elements; 4371 te[0] *= s; 4372 te[4] *= s; 4373 te[8] *= s; 4374 te[12] *= s; 4375 te[1] *= s; 4376 te[5] *= s; 4377 te[9] *= s; 4378 te[13] *= s; 4379 te[2] *= s; 4380 te[6] *= s; 4381 te[10] *= s; 4382 te[14] *= s; 4383 te[3] *= s; 4384 te[7] *= s; 4385 te[11] *= s; 4386 te[15] *= s; 4387 return this; 4388 } 4389 4390 determinant() { 4391 const te = this.elements; 4392 const n11 = te[0], 4393 n12 = te[4], 4394 n13 = te[8], 4395 n14 = te[12]; 4396 const n21 = te[1], 4397 n22 = te[5], 4398 n23 = te[9], 4399 n24 = te[13]; 4400 const n31 = te[2], 4401 n32 = te[6], 4402 n33 = te[10], 4403 n34 = te[14]; 4404 const n41 = te[3], 4405 n42 = te[7], 4406 n43 = te[11], 4407 n44 = te[15]; //TODO: make this more efficient 4408 //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm ) 4409 4410 return n41 * (+n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34) + n42 * (+n11 * n23 * n34 - n11 * n24 * n33 + n14 * n21 * n33 - n13 * n21 * n34 + n13 * n24 * n31 - n14 * n23 * n31) + n43 * (+n11 * n24 * n32 - n11 * n22 * n34 - n14 * n21 * n32 + n12 * n21 * n34 + n14 * n22 * n31 - n12 * n24 * n31) + n44 * (-n13 * n22 * n31 - n11 * n23 * n32 + n11 * n22 * n33 + n13 * n21 * n32 - n12 * n21 * n33 + n12 * n23 * n31); 4411 } 4412 4413 transpose() { 4414 const te = this.elements; 4415 let tmp; 4416 tmp = te[1]; 4417 te[1] = te[4]; 4418 te[4] = tmp; 4419 tmp = te[2]; 4420 te[2] = te[8]; 4421 te[8] = tmp; 4422 tmp = te[6]; 4423 te[6] = te[9]; 4424 te[9] = tmp; 4425 tmp = te[3]; 4426 te[3] = te[12]; 4427 te[12] = tmp; 4428 tmp = te[7]; 4429 te[7] = te[13]; 4430 te[13] = tmp; 4431 tmp = te[11]; 4432 te[11] = te[14]; 4433 te[14] = tmp; 4434 return this; 4435 } 4436 4437 setPosition(x, y, z) { 4438 const te = this.elements; 4439 4440 if (x.isVector3) { 4441 te[12] = x.x; 4442 te[13] = x.y; 4443 te[14] = x.z; 4444 } else { 4445 te[12] = x; 4446 te[13] = y; 4447 te[14] = z; 4448 } 4449 4450 return this; 4451 } 4452 4453 invert() { 4454 // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm 4455 const te = this.elements, 4456 n11 = te[0], 4457 n21 = te[1], 4458 n31 = te[2], 4459 n41 = te[3], 4460 n12 = te[4], 4461 n22 = te[5], 4462 n32 = te[6], 4463 n42 = te[7], 4464 n13 = te[8], 4465 n23 = te[9], 4466 n33 = te[10], 4467 n43 = te[11], 4468 n14 = te[12], 4469 n24 = te[13], 4470 n34 = te[14], 4471 n44 = te[15], 4472 t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, 4473 t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, 4474 t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, 4475 t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; 4476 const det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; 4477 if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 4478 const detInv = 1 / det; 4479 te[0] = t11 * detInv; 4480 te[1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * detInv; 4481 te[2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * detInv; 4482 te[3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * detInv; 4483 te[4] = t12 * detInv; 4484 te[5] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * detInv; 4485 te[6] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * detInv; 4486 te[7] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * detInv; 4487 te[8] = t13 * detInv; 4488 te[9] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * detInv; 4489 te[10] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * detInv; 4490 te[11] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * detInv; 4491 te[12] = t14 * detInv; 4492 te[13] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * detInv; 4493 te[14] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * detInv; 4494 te[15] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * detInv; 4495 return this; 4496 } 4497 4498 scale(v) { 4499 const te = this.elements; 4500 const x = v.x, 4501 y = v.y, 4502 z = v.z; 4503 te[0] *= x; 4504 te[4] *= y; 4505 te[8] *= z; 4506 te[1] *= x; 4507 te[5] *= y; 4508 te[9] *= z; 4509 te[2] *= x; 4510 te[6] *= y; 4511 te[10] *= z; 4512 te[3] *= x; 4513 te[7] *= y; 4514 te[11] *= z; 4515 return this; 4516 } 4517 4518 getMaxScaleOnAxis() { 4519 const te = this.elements; 4520 const scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2]; 4521 const scaleYSq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6]; 4522 const scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10]; 4523 return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq)); 4524 } 4525 4526 makeTranslation(x, y, z) { 4527 this.set(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1); 4528 return this; 4529 } 4530 4531 makeRotationX(theta) { 4532 const c = Math.cos(theta), 4533 s = Math.sin(theta); 4534 this.set(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1); 4535 return this; 4536 } 4537 4538 makeRotationY(theta) { 4539 const c = Math.cos(theta), 4540 s = Math.sin(theta); 4541 this.set(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1); 4542 return this; 4543 } 4544 4545 makeRotationZ(theta) { 4546 const c = Math.cos(theta), 4547 s = Math.sin(theta); 4548 this.set(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); 4549 return this; 4550 } 4551 4552 makeRotationAxis(axis, angle) { 4553 // Based on http://www.gamedev.net/reference/articles/article1199.asp 4554 const c = Math.cos(angle); 4555 const s = Math.sin(angle); 4556 const t = 1 - c; 4557 const x = axis.x, 4558 y = axis.y, 4559 z = axis.z; 4560 const tx = t * x, 4561 ty = t * y; 4562 this.set(tx * x + c, tx * y - s * z, tx * z + s * y, 0, tx * y + s * z, ty * y + c, ty * z - s * x, 0, tx * z - s * y, ty * z + s * x, t * z * z + c, 0, 0, 0, 0, 1); 4563 return this; 4564 } 4565 4566 makeScale(x, y, z) { 4567 this.set(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1); 4568 return this; 4569 } 4570 4571 makeShear(xy, xz, yx, yz, zx, zy) { 4572 this.set(1, yx, zx, 0, xy, 1, zy, 0, xz, yz, 1, 0, 0, 0, 0, 1); 4573 return this; 4574 } 4575 4576 compose(position, quaternion, scale) { 4577 const te = this.elements; 4578 const x = quaternion._x, 4579 y = quaternion._y, 4580 z = quaternion._z, 4581 w = quaternion._w; 4582 const x2 = x + x, 4583 y2 = y + y, 4584 z2 = z + z; 4585 const xx = x * x2, 4586 xy = x * y2, 4587 xz = x * z2; 4588 const yy = y * y2, 4589 yz = y * z2, 4590 zz = z * z2; 4591 const wx = w * x2, 4592 wy = w * y2, 4593 wz = w * z2; 4594 const sx = scale.x, 4595 sy = scale.y, 4596 sz = scale.z; 4597 te[0] = (1 - (yy + zz)) * sx; 4598 te[1] = (xy + wz) * sx; 4599 te[2] = (xz - wy) * sx; 4600 te[3] = 0; 4601 te[4] = (xy - wz) * sy; 4602 te[5] = (1 - (xx + zz)) * sy; 4603 te[6] = (yz + wx) * sy; 4604 te[7] = 0; 4605 te[8] = (xz + wy) * sz; 4606 te[9] = (yz - wx) * sz; 4607 te[10] = (1 - (xx + yy)) * sz; 4608 te[11] = 0; 4609 te[12] = position.x; 4610 te[13] = position.y; 4611 te[14] = position.z; 4612 te[15] = 1; 4613 return this; 4614 } 4615 4616 decompose(position, quaternion, scale) { 4617 const te = this.elements; 4618 4619 let sx = _v1$5.set(te[0], te[1], te[2]).length(); 4620 4621 const sy = _v1$5.set(te[4], te[5], te[6]).length(); 4622 4623 const sz = _v1$5.set(te[8], te[9], te[10]).length(); // if determine is negative, we need to invert one scale 4624 4625 4626 const det = this.determinant(); 4627 if (det < 0) sx = -sx; 4628 position.x = te[12]; 4629 position.y = te[13]; 4630 position.z = te[14]; // scale the rotation part 4631 4632 _m1$2.copy(this); 4633 4634 const invSX = 1 / sx; 4635 const invSY = 1 / sy; 4636 const invSZ = 1 / sz; 4637 _m1$2.elements[0] *= invSX; 4638 _m1$2.elements[1] *= invSX; 4639 _m1$2.elements[2] *= invSX; 4640 _m1$2.elements[4] *= invSY; 4641 _m1$2.elements[5] *= invSY; 4642 _m1$2.elements[6] *= invSY; 4643 _m1$2.elements[8] *= invSZ; 4644 _m1$2.elements[9] *= invSZ; 4645 _m1$2.elements[10] *= invSZ; 4646 quaternion.setFromRotationMatrix(_m1$2); 4647 scale.x = sx; 4648 scale.y = sy; 4649 scale.z = sz; 4650 return this; 4651 } 4652 4653 makePerspective(left, right, top, bottom, near, far) { 4654 if (far === undefined) { 4655 console.warn('THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.'); 4656 } 4657 4658 const te = this.elements; 4659 const x = 2 * near / (right - left); 4660 const y = 2 * near / (top - bottom); 4661 const a = (right + left) / (right - left); 4662 const b = (top + bottom) / (top - bottom); 4663 const c = -(far + near) / (far - near); 4664 const d = -2 * far * near / (far - near); 4665 te[0] = x; 4666 te[4] = 0; 4667 te[8] = a; 4668 te[12] = 0; 4669 te[1] = 0; 4670 te[5] = y; 4671 te[9] = b; 4672 te[13] = 0; 4673 te[2] = 0; 4674 te[6] = 0; 4675 te[10] = c; 4676 te[14] = d; 4677 te[3] = 0; 4678 te[7] = 0; 4679 te[11] = -1; 4680 te[15] = 0; 4681 return this; 4682 } 4683 4684 makeOrthographic(left, right, top, bottom, near, far) { 4685 const te = this.elements; 4686 const w = 1.0 / (right - left); 4687 const h = 1.0 / (top - bottom); 4688 const p = 1.0 / (far - near); 4689 const x = (right + left) * w; 4690 const y = (top + bottom) * h; 4691 const z = (far + near) * p; 4692 te[0] = 2 * w; 4693 te[4] = 0; 4694 te[8] = 0; 4695 te[12] = -x; 4696 te[1] = 0; 4697 te[5] = 2 * h; 4698 te[9] = 0; 4699 te[13] = -y; 4700 te[2] = 0; 4701 te[6] = 0; 4702 te[10] = -2 * p; 4703 te[14] = -z; 4704 te[3] = 0; 4705 te[7] = 0; 4706 te[11] = 0; 4707 te[15] = 1; 4708 return this; 4709 } 4710 4711 equals(matrix) { 4712 const te = this.elements; 4713 const me = matrix.elements; 4714 4715 for (let i = 0; i < 16; i++) { 4716 if (te[i] !== me[i]) return false; 4717 } 4718 4719 return true; 4720 } 4721 4722 fromArray(array, offset = 0) { 4723 for (let i = 0; i < 16; i++) { 4724 this.elements[i] = array[i + offset]; 4725 } 4726 4727 return this; 4728 } 4729 4730 toArray(array = [], offset = 0) { 4731 const te = this.elements; 4732 array[offset] = te[0]; 4733 array[offset + 1] = te[1]; 4734 array[offset + 2] = te[2]; 4735 array[offset + 3] = te[3]; 4736 array[offset + 4] = te[4]; 4737 array[offset + 5] = te[5]; 4738 array[offset + 6] = te[6]; 4739 array[offset + 7] = te[7]; 4740 array[offset + 8] = te[8]; 4741 array[offset + 9] = te[9]; 4742 array[offset + 10] = te[10]; 4743 array[offset + 11] = te[11]; 4744 array[offset + 12] = te[12]; 4745 array[offset + 13] = te[13]; 4746 array[offset + 14] = te[14]; 4747 array[offset + 15] = te[15]; 4748 return array; 4749 } 4750 4751 } 4752 4753 Matrix4.prototype.isMatrix4 = true; 4754 4755 const _v1$5 = /*@__PURE__*/new Vector3(); 4756 4757 const _m1$2 = /*@__PURE__*/new Matrix4(); 4758 4759 const _zero = /*@__PURE__*/new Vector3(0, 0, 0); 4760 4761 const _one = /*@__PURE__*/new Vector3(1, 1, 1); 4762 4763 const _x = /*@__PURE__*/new Vector3(); 4764 4765 const _y = /*@__PURE__*/new Vector3(); 4766 4767 const _z = /*@__PURE__*/new Vector3(); 4768 4769 const _matrix$1 = /*@__PURE__*/new Matrix4(); 4770 4771 const _quaternion$3 = /*@__PURE__*/new Quaternion(); 4772 4773 class Euler { 4774 constructor(x = 0, y = 0, z = 0, order = Euler.DefaultOrder) { 4775 this._x = x; 4776 this._y = y; 4777 this._z = z; 4778 this._order = order; 4779 } 4780 4781 get x() { 4782 return this._x; 4783 } 4784 4785 set x(value) { 4786 this._x = value; 4787 4788 this._onChangeCallback(); 4789 } 4790 4791 get y() { 4792 return this._y; 4793 } 4794 4795 set y(value) { 4796 this._y = value; 4797 4798 this._onChangeCallback(); 4799 } 4800 4801 get z() { 4802 return this._z; 4803 } 4804 4805 set z(value) { 4806 this._z = value; 4807 4808 this._onChangeCallback(); 4809 } 4810 4811 get order() { 4812 return this._order;
vendor: 4,161 bytes, lines 4813-5014
4813 } 4814 4815 set order(value) { 4816 this._order = value; 4817 4818 this._onChangeCallback(); 4819 } 4820 4821 set(x, y, z, order = this._order) { 4822 this._x = x; 4823 this._y = y; 4824 this._z = z; 4825 this._order = order; 4826 4827 this._onChangeCallback(); 4828 4829 return this; 4830 } 4831 4832 clone() { 4833 return new this.constructor(this._x, this._y, this._z, this._order); 4834 } 4835 4836 copy(euler) { 4837 this._x = euler._x; 4838 this._y = euler._y; 4839 this._z = euler._z; 4840 this._order = euler._order; 4841 4842 this._onChangeCallback(); 4843 4844 return this; 4845 } 4846 4847 setFromRotationMatrix(m, order = this._order, update = true) { 4848 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) 4849 const te = m.elements; 4850 const m11 = te[0], 4851 m12 = te[4], 4852 m13 = te[8]; 4853 const m21 = te[1], 4854 m22 = te[5], 4855 m23 = te[9]; 4856 const m31 = te[2], 4857 m32 = te[6], 4858 m33 = te[10]; 4859 4860 switch (order) { 4861 case 'XYZ': 4862 this._y = Math.asin(clamp(m13, -1, 1)); 4863 4864 if (Math.abs(m13) < 0.9999999) { 4865 this._x = Math.atan2(-m23, m33); 4866 this._z = Math.atan2(-m12, m11); 4867 } else { 4868 this._x = Math.atan2(m32, m22); 4869 this._z = 0; 4870 } 4871 4872 break; 4873 4874 case 'YXZ': 4875 this._x = Math.asin(-clamp(m23, -1, 1)); 4876 4877 if (Math.abs(m23) < 0.9999999) { 4878 this._y = Math.atan2(m13, m33); 4879 this._z = Math.atan2(m21, m22); 4880 } else { 4881 this._y = Math.atan2(-m31, m11); 4882 this._z = 0; 4883 } 4884 4885 break; 4886 4887 case 'ZXY': 4888 this._x = Math.asin(clamp(m32, -1, 1)); 4889 4890 if (Math.abs(m32) < 0.9999999) { 4891 this._y = Math.atan2(-m31, m33); 4892 this._z = Math.atan2(-m12, m22); 4893 } else { 4894 this._y = 0; 4895 this._z = Math.atan2(m21, m11); 4896 } 4897 4898 break; 4899 4900 case 'ZYX': 4901 this._y = Math.asin(-clamp(m31, -1, 1)); 4902 4903 if (Math.abs(m31) < 0.9999999) { 4904 this._x = Math.atan2(m32, m33); 4905 this._z = Math.atan2(m21, m11); 4906 } else { 4907 this._x = 0; 4908 this._z = Math.atan2(-m12, m22); 4909 } 4910 4911 break; 4912 4913 case 'YZX': 4914 this._z = Math.asin(clamp(m21, -1, 1)); 4915 4916 if (Math.abs(m21) < 0.9999999) { 4917 this._x = Math.atan2(-m23, m22); 4918 this._y = Math.atan2(-m31, m11); 4919 } else { 4920 this._x = 0; 4921 this._y = Math.atan2(m13, m33); 4922 } 4923 4924 break; 4925 4926 case 'XZY': 4927 this._z = Math.asin(-clamp(m12, -1, 1)); 4928 4929 if (Math.abs(m12) < 0.9999999) { 4930 this._x = Math.atan2(m32, m22); 4931 this._y = Math.atan2(m13, m11); 4932 } else { 4933 this._x = Math.atan2(-m23, m33); 4934 this._y = 0; 4935 } 4936 4937 break; 4938 4939 default: 4940 console.warn('THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order); 4941 } 4942 4943 this._order = order; 4944 if (update === true) this._onChangeCallback(); 4945 return this; 4946 } 4947 4948 setFromQuaternion(q, order, update) { 4949 _matrix$1.makeRotationFromQuaternion(q); 4950 4951 return this.setFromRotationMatrix(_matrix$1, order, update); 4952 } 4953 4954 setFromVector3(v, order = this._order) { 4955 return this.set(v.x, v.y, v.z, order); 4956 } 4957 4958 reorder(newOrder) { 4959 // WARNING: this discards revolution information -bhouston 4960 _quaternion$3.setFromEuler(this); 4961 4962 return this.setFromQuaternion(_quaternion$3, newOrder); 4963 } 4964 4965 equals(euler) { 4966 return euler._x === this._x && euler._y === this._y && euler._z === this._z && euler._order === this._order; 4967 } 4968 4969 fromArray(array) { 4970 this._x = array[0]; 4971 this._y = array[1]; 4972 this._z = array[2]; 4973 if (array[3] !== undefined) this._order = array[3]; 4974 4975 this._onChangeCallback(); 4976 4977 return this; 4978 } 4979 4980 toArray(array = [], offset = 0) { 4981 array[offset] = this._x; 4982 array[offset + 1] = this._y; 4983 array[offset + 2] = this._z; 4984 array[offset + 3] = this._order; 4985 return array; 4986 } 4987 4988 toVector3(optionalResult) { 4989 if (optionalResult) { 4990 return optionalResult.set(this._x, this._y, this._z); 4991 } else { 4992 return new Vector3(this._x, this._y, this._z); 4993 } 4994 } 4995 4996 _onChange(callback) { 4997 this._onChangeCallback = callback; 4998 return this; 4999 } 5000 5001 _onChangeCallback() {} 5002 5003 } 5004 5005 Euler.prototype.isEuler = true; 5006 Euler.DefaultOrder = 'XYZ'; 5007 Euler.RotationOrders = ['XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX']; 5008 5009 class Layers { 5010 constructor() { 5011 this.mask = 1 | 0; 5012 } 5013 5014 set(channel) {
vendor: 1,067 bytes, lines 5015-5076
5015 this.mask = (1 << channel | 0) >>> 0; 5016 } 5017 5018 enable(channel) { 5019 this.mask |= 1 << channel | 0; 5020 } 5021 5022 enableAll() { 5023 this.mask = 0xffffffff | 0; 5024 } 5025 5026 toggle(channel) { 5027 this.mask ^= 1 << channel | 0; 5028 } 5029 5030 disable(channel) { 5031 this.mask &= ~(1 << channel | 0); 5032 } 5033 5034 disableAll() { 5035 this.mask = 0; 5036 } 5037 5038 test(layers) { 5039 return (this.mask & layers.mask) !== 0; 5040 } 5041 5042 isEnabled(channel) { 5043 return (this.mask & (1 << channel | 0)) !== 0; 5044 } 5045 5046 } 5047 5048 let _object3DId = 0; 5049 5050 const _v1$4 = /*@__PURE__*/new Vector3(); 5051 5052 const _q1 = /*@__PURE__*/new Quaternion(); 5053 5054 const _m1$1 = /*@__PURE__*/new Matrix4(); 5055 5056 const _target = /*@__PURE__*/new Vector3(); 5057 5058 const _position$3 = /*@__PURE__*/new Vector3(); 5059 5060 const _scale$2 = /*@__PURE__*/new Vector3(); 5061 5062 const _quaternion$2 = /*@__PURE__*/new Quaternion(); 5063 5064 const _xAxis = /*@__PURE__*/new Vector3(1, 0, 0); 5065 5066 const _yAxis = /*@__PURE__*/new Vector3(0, 1, 0); 5067 5068 const _zAxis = /*@__PURE__*/new Vector3(0, 0, 1); 5069 5070 const _addedEvent = { 5071 type: 'added' 5072 }; 5073 const _removedEvent = { 5074 type: 'removed' 5075 }; 5076
vendor: 16,537 bytes, lines 5077-5742
5077 class Object3D extends EventDispatcher { 5078 constructor() { 5079 super(); 5080 Object.defineProperty(this, 'id', { 5081 value: _object3DId++ 5082 }); 5083 this.uuid = generateUUID(); 5084 this.name = ''; 5085 this.type = 'Object3D'; 5086 this.parent = null; 5087 this.children = []; 5088 this.up = Object3D.DefaultUp.clone(); 5089 const position = new Vector3(); 5090 const rotation = new Euler(); 5091 const quaternion = new Quaternion(); 5092 const scale = new Vector3(1, 1, 1); 5093 5094 function onRotationChange() { 5095 quaternion.setFromEuler(rotation, false); 5096 } 5097 5098 function onQuaternionChange() { 5099 rotation.setFromQuaternion(quaternion, undefined, false); 5100 } 5101 5102 rotation._onChange(onRotationChange); 5103 5104 quaternion._onChange(onQuaternionChange); 5105 5106 Object.defineProperties(this, { 5107 position: { 5108 configurable: true, 5109 enumerable: true, 5110 value: position 5111 }, 5112 rotation: { 5113 configurable: true, 5114 enumerable: true, 5115 value: rotation 5116 }, 5117 quaternion: { 5118 configurable: true, 5119 enumerable: true, 5120 value: quaternion 5121 }, 5122 scale: { 5123 configurable: true, 5124 enumerable: true, 5125 value: scale 5126 }, 5127 modelViewMatrix: { 5128 value: new Matrix4() 5129 }, 5130 normalMatrix: { 5131 value: new Matrix3() 5132 } 5133 }); 5134 this.matrix = new Matrix4(); 5135 this.matrixWorld = new Matrix4(); 5136 this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; 5137 this.matrixWorldNeedsUpdate = false; 5138 this.layers = new Layers(); 5139 this.visible = true; 5140 this.castShadow = false; 5141 this.receiveShadow = false; 5142 this.frustumCulled = true; 5143 this.renderOrder = 0; 5144 this.animations = []; 5145 this.userData = {}; 5146 } 5147 5148 onBeforeRender() {} 5149 5150 onAfterRender() {} 5151 5152 applyMatrix4(matrix) { 5153 if (this.matrixAutoUpdate) this.updateMatrix(); 5154 this.matrix.premultiply(matrix); 5155 this.matrix.decompose(this.position, this.quaternion, this.scale); 5156 } 5157 5158 applyQuaternion(q) { 5159 this.quaternion.premultiply(q); 5160 return this; 5161 } 5162 5163 setRotationFromAxisAngle(axis, angle) { 5164 // assumes axis is normalized 5165 this.quaternion.setFromAxisAngle(axis, angle); 5166 } 5167 5168 setRotationFromEuler(euler) { 5169 this.quaternion.setFromEuler(euler, true); 5170 } 5171 5172 setRotationFromMatrix(m) { 5173 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) 5174 this.quaternion.setFromRotationMatrix(m); 5175 } 5176 5177 setRotationFromQuaternion(q) { 5178 // assumes q is normalized 5179 this.quaternion.copy(q); 5180 } 5181 5182 rotateOnAxis(axis, angle) { 5183 // rotate object on axis in object space 5184 // axis is assumed to be normalized 5185 _q1.setFromAxisAngle(axis, angle); 5186 5187 this.quaternion.multiply(_q1); 5188 return this; 5189 } 5190 5191 rotateOnWorldAxis(axis, angle) { 5192 // rotate object on axis in world space 5193 // axis is assumed to be normalized 5194 // method assumes no rotated parent 5195 _q1.setFromAxisAngle(axis, angle); 5196 5197 this.quaternion.premultiply(_q1); 5198 return this; 5199 } 5200 5201 rotateX(angle) { 5202 return this.rotateOnAxis(_xAxis, angle); 5203 } 5204 5205 rotateY(angle) { 5206 return this.rotateOnAxis(_yAxis, angle); 5207 } 5208 5209 rotateZ(angle) { 5210 return this.rotateOnAxis(_zAxis, angle); 5211 } 5212 5213 translateOnAxis(axis, distance) { 5214 // translate object by distance along axis in object space 5215 // axis is assumed to be normalized 5216 _v1$4.copy(axis).applyQuaternion(this.quaternion); 5217 5218 this.position.add(_v1$4.multiplyScalar(distance)); 5219 return this; 5220 } 5221 5222 translateX(distance) { 5223 return this.translateOnAxis(_xAxis, distance); 5224 } 5225 5226 translateY(distance) { 5227 return this.translateOnAxis(_yAxis, distance); 5228 } 5229 5230 translateZ(distance) { 5231 return this.translateOnAxis(_zAxis, distance); 5232 } 5233 5234 localToWorld(vector) { 5235 return vector.applyMatrix4(this.matrixWorld); 5236 } 5237 5238 worldToLocal(vector) { 5239 return vector.applyMatrix4(_m1$1.copy(this.matrixWorld).invert()); 5240 } 5241 5242 lookAt(x, y, z) { 5243 // This method does not support objects having non-uniformly-scaled parent(s) 5244 if (x.isVector3) { 5245 _target.copy(x); 5246 } else { 5247 _target.set(x, y, z); 5248 } 5249 5250 const parent = this.parent; 5251 this.updateWorldMatrix(true, false); 5252 5253 _position$3.setFromMatrixPosition(this.matrixWorld); 5254 5255 if (this.isCamera || this.isLight) { 5256 _m1$1.lookAt(_position$3, _target, this.up); 5257 } else { 5258 _m1$1.lookAt(_target, _position$3, this.up); 5259 } 5260 5261 this.quaternion.setFromRotationMatrix(_m1$1); 5262 5263 if (parent) { 5264 _m1$1.extractRotation(parent.matrixWorld); 5265 5266 _q1.setFromRotationMatrix(_m1$1); 5267 5268 this.quaternion.premultiply(_q1.invert()); 5269 } 5270 } 5271 5272 add(object) { 5273 if (arguments.length > 1) { 5274 for (let i = 0; i < arguments.length; i++) { 5275 this.add(arguments[i]); 5276 } 5277 5278 return this; 5279 } 5280 5281 if (object === this) { 5282 console.error('THREE.Object3D.add: object can\'t be added as a child of itself.', object); 5283 return this; 5284 } 5285 5286 if (object && object.isObject3D) { 5287 if (object.parent !== null) { 5288 object.parent.remove(object); 5289 } 5290 5291 object.parent = this; 5292 this.children.push(object); 5293 object.dispatchEvent(_addedEvent); 5294 } else { 5295 console.error('THREE.Object3D.add: object not an instance of THREE.Object3D.', object); 5296 } 5297 5298 return this; 5299 } 5300 5301 remove(object) { 5302 if (arguments.length > 1) { 5303 for (let i = 0; i < arguments.length; i++) { 5304 this.remove(arguments[i]); 5305 } 5306 5307 return this; 5308 } 5309 5310 const index = this.children.indexOf(object); 5311 5312 if (index !== -1) { 5313 object.parent = null; 5314 this.children.splice(index, 1); 5315 object.dispatchEvent(_removedEvent); 5316 } 5317 5318 return this; 5319 } 5320 5321 removeFromParent() { 5322 const parent = this.parent; 5323 5324 if (parent !== null) { 5325 parent.remove(this); 5326 } 5327 5328 return this; 5329 } 5330 5331 clear() { 5332 for (let i = 0; i < this.children.length; i++) { 5333 const object = this.children[i]; 5334 object.parent = null; 5335 object.dispatchEvent(_removedEvent); 5336 } 5337 5338 this.children.length = 0; 5339 return this; 5340 } 5341 5342 attach(object) { 5343 // adds object as a child of this, while maintaining the object's world transform 5344 // Note: This method does not support scene graphs having non-uniformly-scaled nodes(s) 5345 this.updateWorldMatrix(true, false); 5346 5347 _m1$1.copy(this.matrixWorld).invert(); 5348 5349 if (object.parent !== null) { 5350 object.parent.updateWorldMatrix(true, false); 5351 5352 _m1$1.multiply(object.parent.matrixWorld); 5353 } 5354 5355 object.applyMatrix4(_m1$1); 5356 this.add(object); 5357 object.updateWorldMatrix(false, true); 5358 return this; 5359 } 5360 5361 getObjectById(id) { 5362 return this.getObjectByProperty('id', id); 5363 } 5364 5365 getObjectByName(name) { 5366 return this.getObjectByProperty('name', name); 5367 } 5368 5369 getObjectByProperty(name, value) { 5370 if (this[name] === value) return this; 5371 5372 for (let i = 0, l = this.children.length; i < l; i++) { 5373 const child = this.children[i]; 5374 const object = child.getObjectByProperty(name, value); 5375 5376 if (object !== undefined) { 5377 return object; 5378 } 5379 } 5380 5381 return undefined; 5382 } 5383 5384 getWorldPosition(target) { 5385 this.updateWorldMatrix(true, false); 5386 return target.setFromMatrixPosition(this.matrixWorld); 5387 } 5388 5389 getWorldQuaternion(target) { 5390 this.updateWorldMatrix(true, false); 5391 this.matrixWorld.decompose(_position$3, target, _scale$2); 5392 return target; 5393 } 5394 5395 getWorldScale(target) { 5396 this.updateWorldMatrix(true, false); 5397 this.matrixWorld.decompose(_position$3, _quaternion$2, target); 5398 return target; 5399 } 5400 5401 getWorldDirection(target) { 5402 this.updateWorldMatrix(true, false); 5403 const e = this.matrixWorld.elements; 5404 return target.set(e[8], e[9], e[10]).normalize(); 5405 } 5406 5407 raycast() {} 5408 5409 traverse(callback) { 5410 callback(this); 5411 const children = this.children; 5412 5413 for (let i = 0, l = children.length; i < l; i++) { 5414 children[i].traverse(callback); 5415 } 5416 } 5417 5418 traverseVisible(callback) { 5419 if (this.visible === false) return; 5420 callback(this); 5421 const children = this.children; 5422 5423 for (let i = 0, l = children.length; i < l; i++) { 5424 children[i].traverseVisible(callback); 5425 } 5426 } 5427 5428 traverseAncestors(callback) { 5429 const parent = this.parent; 5430 5431 if (parent !== null) { 5432 callback(parent); 5433 parent.traverseAncestors(callback); 5434 } 5435 } 5436 5437 updateMatrix() { 5438 this.matrix.compose(this.position, this.quaternion, this.scale); 5439 this.matrixWorldNeedsUpdate = true; 5440 } 5441 5442 updateMatrixWorld(force) { 5443 if (this.matrixAutoUpdate) this.updateMatrix(); 5444 5445 if (this.matrixWorldNeedsUpdate || force) { 5446 if (this.parent === null) { 5447 this.matrixWorld.copy(this.matrix); 5448 } else { 5449 this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix); 5450 } 5451 5452 this.matrixWorldNeedsUpdate = false; 5453 force = true; 5454 } // update children 5455 5456 5457 const children = this.children; 5458 5459 for (let i = 0, l = children.length; i < l; i++) { 5460 children[i].updateMatrixWorld(force); 5461 } 5462 } 5463 5464 updateWorldMatrix(updateParents, updateChildren) { 5465 const parent = this.parent; 5466 5467 if (updateParents === true && parent !== null) { 5468 parent.updateWorldMatrix(true, false); 5469 } 5470 5471 if (this.matrixAutoUpdate) this.updateMatrix(); 5472 5473 if (this.parent === null) { 5474 this.matrixWorld.copy(this.matrix); 5475 } else { 5476 this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix); 5477 } // update children 5478 5479 5480 if (updateChildren === true) { 5481 const children = this.children; 5482 5483 for (let i = 0, l = children.length; i < l; i++) { 5484 children[i].updateWorldMatrix(false, true); 5485 } 5486 } 5487 } 5488 5489 toJSON(meta) { 5490 // meta is a string when called from JSON.stringify 5491 const isRootObject = meta === undefined || typeof meta === 'string'; 5492 const output = {}; // meta is a hash used to collect geometries, materials. 5493 // not providing it implies that this is the root object 5494 // being serialized. 5495 5496 if (isRootObject) { 5497 // initialize meta obj 5498 meta = { 5499 geometries: {}, 5500 materials: {}, 5501 textures: {}, 5502 images: {}, 5503 shapes: {}, 5504 skeletons: {}, 5505 animations: {} 5506 }; 5507 output.metadata = { 5508 version: 4.5, 5509 type: 'Object', 5510 generator: 'Object3D.toJSON' 5511 }; 5512 } // standard Object3D serialization 5513 5514 5515 const object = {}; 5516 object.uuid = this.uuid; 5517 object.type = this.type; 5518 if (this.name !== '') object.name = this.name; 5519 if (this.castShadow === true) object.castShadow = true; 5520 if (this.receiveShadow === true) object.receiveShadow = true; 5521 if (this.visible === false) object.visible = false; 5522 if (this.frustumCulled === false) object.frustumCulled = false; 5523 if (this.renderOrder !== 0) object.renderOrder = this.renderOrder; 5524 if (JSON.stringify(this.userData) !== '{}') object.userData = this.userData; 5525 object.layers = this.layers.mask; 5526 object.matrix = this.matrix.toArray(); 5527 if (this.matrixAutoUpdate === false) object.matrixAutoUpdate = false; // object specific properties 5528 5529 if (this.isInstancedMesh) { 5530 object.type = 'InstancedMesh'; 5531 object.count = this.count; 5532 object.instanceMatrix = this.instanceMatrix.toJSON(); 5533 if (this.instanceColor !== null) object.instanceColor = this.instanceColor.toJSON(); 5534 } // 5535 5536 5537 function serialize(library, element) { 5538 if (library[element.uuid] === undefined) { 5539 library[element.uuid] = element.toJSON(meta); 5540 } 5541 5542 return element.uuid; 5543 } 5544 5545 if (this.isScene) { 5546 if (this.background) { 5547 if (this.background.isColor) { 5548 object.background = this.background.toJSON(); 5549 } else if (this.background.isTexture) { 5550 object.background = this.background.toJSON(meta).uuid; 5551 } 5552 } 5553 5554 if (this.environment && this.environment.isTexture) { 5555 object.environment = this.environment.toJSON(meta).uuid; 5556 } 5557 } else if (this.isMesh || this.isLine || this.isPoints) { 5558 object.geometry = serialize(meta.geometries, this.geometry); 5559 const parameters = this.geometry.parameters; 5560 5561 if (parameters !== undefined && parameters.shapes !== undefined) { 5562 const shapes = parameters.shapes; 5563 5564 if (Array.isArray(shapes)) { 5565 for (let i = 0, l = shapes.length; i < l; i++) { 5566 const shape = shapes[i]; 5567 serialize(meta.shapes, shape); 5568 } 5569 } else { 5570 serialize(meta.shapes, shapes); 5571 } 5572 } 5573 } 5574 5575 if (this.isSkinnedMesh) { 5576 object.bindMode = this.bindMode; 5577 object.bindMatrix = this.bindMatrix.toArray(); 5578 5579 if (this.skeleton !== undefined) { 5580 serialize(meta.skeletons, this.skeleton); 5581 object.skeleton = this.skeleton.uuid; 5582 } 5583 } 5584 5585 if (this.material !== undefined) { 5586 if (Array.isArray(this.material)) { 5587 const uuids = []; 5588 5589 for (let i = 0, l = this.material.length; i < l; i++) { 5590 uuids.push(serialize(meta.materials, this.material[i])); 5591 } 5592 5593 object.material = uuids; 5594 } else { 5595 object.material = serialize(meta.materials, this.material); 5596 } 5597 } // 5598 5599 5600 if (this.children.length > 0) { 5601 object.children = []; 5602 5603 for (let i = 0; i < this.children.length; i++) { 5604 object.children.push(this.children[i].toJSON(meta).object); 5605 } 5606 } // 5607 5608 5609 if (this.animations.length > 0) { 5610 object.animations = []; 5611 5612 for (let i = 0; i < this.animations.length; i++) { 5613 const animation = this.animations[i]; 5614 object.animations.push(serialize(meta.animations, animation)); 5615 } 5616 } 5617 5618 if (isRootObject) { 5619 const geometries = extractFromCache(meta.geometries); 5620 const materials = extractFromCache(meta.materials); 5621 const textures = extractFromCache(meta.textures); 5622 const images = extractFromCache(meta.images); 5623 const shapes = extractFromCache(meta.shapes); 5624 const skeletons = extractFromCache(meta.skeletons); 5625 const animations = extractFromCache(meta.animations); 5626 if (geometries.length > 0) output.geometries = geometries; 5627 if (materials.length > 0) output.materials = materials; 5628 if (textures.length > 0) output.textures = textures; 5629 if (images.length > 0) output.images = images; 5630 if (shapes.length > 0) output.shapes = shapes; 5631 if (skeletons.length > 0) output.skeletons = skeletons; 5632 if (animations.length > 0) output.animations = animations; 5633 } 5634 5635 output.object = object; 5636 return output; // extract data from the cache hash 5637 // remove metadata on each item 5638 // and return as array 5639 5640 function extractFromCache(cache) { 5641 const values = []; 5642 5643 for (const key in cache) { 5644 const data = cache[key]; 5645 delete data.metadata; 5646 values.push(data); 5647 } 5648 5649 return values; 5650 } 5651 } 5652 5653 clone(recursive) { 5654 return new this.constructor().copy(this, recursive); 5655 } 5656 5657 copy(source, recursive = true) { 5658 this.name = source.name; 5659 this.up.copy(source.up); 5660 this.position.copy(source.position); 5661 this.rotation.order = source.rotation.order; 5662 this.quaternion.copy(source.quaternion); 5663 this.scale.copy(source.scale); 5664 this.matrix.copy(source.matrix); 5665 this.matrixWorld.copy(source.matrixWorld); 5666 this.matrixAutoUpdate = source.matrixAutoUpdate; 5667 this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; 5668 this.layers.mask = source.layers.mask; 5669 this.visible = source.visible; 5670 this.castShadow = source.castShadow; 5671 this.receiveShadow = source.receiveShadow; 5672 this.frustumCulled = source.frustumCulled; 5673 this.renderOrder = source.renderOrder; 5674 this.userData = JSON.parse(JSON.stringify(source.userData)); 5675 5676 if (recursive === true) { 5677 for (let i = 0; i < source.children.length; i++) { 5678 const child = source.children[i]; 5679 this.add(child.clone()); 5680 } 5681 } 5682 5683 return this; 5684 } 5685 5686 } 5687 5688 Object3D.DefaultUp = new Vector3(0, 1, 0); 5689 Object3D.DefaultMatrixAutoUpdate = true; 5690 Object3D.prototype.isObject3D = true; 5691 5692 const _v0$1 = /*@__PURE__*/new Vector3(); 5693 5694 const _v1$3 = /*@__PURE__*/new Vector3(); 5695 5696 const _v2$2 = /*@__PURE__*/new Vector3(); 5697 5698 const _v3$1 = /*@__PURE__*/new Vector3(); 5699 5700 const _vab = /*@__PURE__*/new Vector3(); 5701 5702 const _vac = /*@__PURE__*/new Vector3(); 5703 5704 const _vbc = /*@__PURE__*/new Vector3(); 5705 5706 const _vap = /*@__PURE__*/new Vector3(); 5707 5708 const _vbp = /*@__PURE__*/new Vector3(); 5709 5710 const _vcp = /*@__PURE__*/new Vector3(); 5711 5712 class Triangle { 5713 constructor(a = new Vector3(), b = new Vector3(), c = new Vector3()) { 5714 this.a = a; 5715 this.b = b; 5716 this.c = c; 5717 } 5718 5719 static getNormal(a, b, c, target) { 5720 target.subVectors(c, b); 5721 5722 _v0$1.subVectors(a, b); 5723 5724 target.cross(_v0$1); 5725 const targetLengthSq = target.lengthSq(); 5726 5727 if (targetLengthSq > 0) { 5728 return target.multiplyScalar(1 / Math.sqrt(targetLengthSq)); 5729 } 5730 5731 return target.set(0, 0, 0); 5732 } // static/instance method to calculate barycentric coordinates 5733 // based on: http://www.blackpawn.com/texts/pointinpoly/default.html 5734 5735 5736 static getBarycoord(point, a, b, c, target) { 5737 _v0$1.subVectors(c, a); 5738 5739 _v1$3.subVectors(b, a); 5740 5741 _v2$2.subVectors(point, a); 5742
vendor: 15,538 bytes, lines 5743-6207
5743 const dot00 = _v0$1.dot(_v0$1); 5744 5745 const dot01 = _v0$1.dot(_v1$3); 5746 5747 const dot02 = _v0$1.dot(_v2$2); 5748 5749 const dot11 = _v1$3.dot(_v1$3); 5750 5751 const dot12 = _v1$3.dot(_v2$2); 5752 5753 const denom = dot00 * dot11 - dot01 * dot01; // collinear or singular triangle 5754 5755 if (denom === 0) { 5756 // arbitrary location outside of triangle? 5757 // not sure if this is the best idea, maybe should be returning undefined 5758 return target.set(-2, -1, -1); 5759 } 5760 5761 const invDenom = 1 / denom; 5762 const u = (dot11 * dot02 - dot01 * dot12) * invDenom; 5763 const v = (dot00 * dot12 - dot01 * dot02) * invDenom; // barycentric coordinates must always sum to 1 5764 5765 return target.set(1 - u - v, v, u); 5766 } 5767 5768 static containsPoint(point, a, b, c) { 5769 this.getBarycoord(point, a, b, c, _v3$1); 5770 return _v3$1.x >= 0 && _v3$1.y >= 0 && _v3$1.x + _v3$1.y <= 1; 5771 } 5772 5773 static getUV(point, p1, p2, p3, uv1, uv2, uv3, target) { 5774 this.getBarycoord(point, p1, p2, p3, _v3$1); 5775 target.set(0, 0); 5776 target.addScaledVector(uv1, _v3$1.x); 5777 target.addScaledVector(uv2, _v3$1.y); 5778 target.addScaledVector(uv3, _v3$1.z); 5779 return target; 5780 } 5781 5782 static isFrontFacing(a, b, c, direction) { 5783 _v0$1.subVectors(c, b); 5784 5785 _v1$3.subVectors(a, b); // strictly front facing 5786 5787 5788 return _v0$1.cross(_v1$3).dot(direction) < 0 ? true : false; 5789 } 5790 5791 set(a, b, c) { 5792 this.a.copy(a); 5793 this.b.copy(b); 5794 this.c.copy(c); 5795 return this; 5796 } 5797 5798 setFromPointsAndIndices(points, i0, i1, i2) { 5799 this.a.copy(points[i0]); 5800 this.b.copy(points[i1]); 5801 this.c.copy(points[i2]); 5802 return this; 5803 } 5804 5805 setFromAttributeAndIndices(attribute, i0, i1, i2) { 5806 this.a.fromBufferAttribute(attribute, i0); 5807 this.b.fromBufferAttribute(attribute, i1); 5808 this.c.fromBufferAttribute(attribute, i2); 5809 return this; 5810 } 5811 5812 clone() { 5813 return new this.constructor().copy(this); 5814 } 5815 5816 copy(triangle) { 5817 this.a.copy(triangle.a); 5818 this.b.copy(triangle.b); 5819 this.c.copy(triangle.c); 5820 return this; 5821 } 5822 5823 getArea() { 5824 _v0$1.subVectors(this.c, this.b); 5825 5826 _v1$3.subVectors(this.a, this.b); 5827 5828 return _v0$1.cross(_v1$3).length() * 0.5; 5829 } 5830 5831 getMidpoint(target) { 5832 return target.addVectors(this.a, this.b).add(this.c).multiplyScalar(1 / 3); 5833 } 5834 5835 getNormal(target) { 5836 return Triangle.getNormal(this.a, this.b, this.c, target); 5837 } 5838 5839 getPlane(target) { 5840 return target.setFromCoplanarPoints(this.a, this.b, this.c); 5841 } 5842 5843 getBarycoord(point, target) { 5844 return Triangle.getBarycoord(point, this.a, this.b, this.c, target); 5845 } 5846 5847 getUV(point, uv1, uv2, uv3, target) { 5848 return Triangle.getUV(point, this.a, this.b, this.c, uv1, uv2, uv3, target); 5849 } 5850 5851 containsPoint(point) { 5852 return Triangle.containsPoint(point, this.a, this.b, this.c); 5853 } 5854 5855 isFrontFacing(direction) { 5856 return Triangle.isFrontFacing(this.a, this.b, this.c, direction); 5857 } 5858 5859 intersectsBox(box) { 5860 return box.intersectsTriangle(this); 5861 } 5862 5863 closestPointToPoint(p, target) { 5864 const a = this.a, 5865 b = this.b, 5866 c = this.c; 5867 let v, w; // algorithm thanks to Real-Time Collision Detection by Christer Ericson, 5868 // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc., 5869 // under the accompanying license; see chapter 5.1.5 for detailed explanation. 5870 // basically, we're distinguishing which of the voronoi regions of the triangle 5871 // the point lies in with the minimum amount of redundant computation. 5872 5873 _vab.subVectors(b, a); 5874 5875 _vac.subVectors(c, a); 5876 5877 _vap.subVectors(p, a); 5878 5879 const d1 = _vab.dot(_vap); 5880 5881 const d2 = _vac.dot(_vap); 5882 5883 if (d1 <= 0 && d2 <= 0) { 5884 // vertex region of A; barycentric coords (1, 0, 0) 5885 return target.copy(a); 5886 } 5887 5888 _vbp.subVectors(p, b); 5889 5890 const d3 = _vab.dot(_vbp); 5891 5892 const d4 = _vac.dot(_vbp); 5893 5894 if (d3 >= 0 && d4 <= d3) { 5895 // vertex region of B; barycentric coords (0, 1, 0) 5896 return target.copy(b); 5897 } 5898 5899 const vc = d1 * d4 - d3 * d2; 5900 5901 if (vc <= 0 && d1 >= 0 && d3 <= 0) { 5902 v = d1 / (d1 - d3); // edge region of AB; barycentric coords (1-v, v, 0) 5903 5904 return target.copy(a).addScaledVector(_vab, v); 5905 } 5906 5907 _vcp.subVectors(p, c); 5908 5909 const d5 = _vab.dot(_vcp); 5910 5911 const d6 = _vac.dot(_vcp); 5912 5913 if (d6 >= 0 && d5 <= d6) { 5914 // vertex region of C; barycentric coords (0, 0, 1) 5915 return target.copy(c); 5916 } 5917 5918 const vb = d5 * d2 - d1 * d6; 5919 5920 if (vb <= 0 && d2 >= 0 && d6 <= 0) { 5921 w = d2 / (d2 - d6); // edge region of AC; barycentric coords (1-w, 0, w) 5922 5923 return target.copy(a).addScaledVector(_vac, w); 5924 } 5925 5926 const va = d3 * d6 - d5 * d4; 5927 5928 if (va <= 0 && d4 - d3 >= 0 && d5 - d6 >= 0) { 5929 _vbc.subVectors(c, b); 5930 5931 w = (d4 - d3) / (d4 - d3 + (d5 - d6)); // edge region of BC; barycentric coords (0, 1-w, w) 5932 5933 return target.copy(b).addScaledVector(_vbc, w); // edge region of BC 5934 } // face region 5935 5936 5937 const denom = 1 / (va + vb + vc); // u = va * denom 5938 5939 v = vb * denom; 5940 w = vc * denom; 5941 return target.copy(a).addScaledVector(_vab, v).addScaledVector(_vac, w); 5942 } 5943 5944 equals(triangle) { 5945 return triangle.a.equals(this.a) && triangle.b.equals(this.b) && triangle.c.equals(this.c); 5946 } 5947 5948 } 5949 5950 let materialId = 0; 5951 5952 class Material extends EventDispatcher { 5953 constructor() { 5954 super(); 5955 Object.defineProperty(this, 'id', { 5956 value: materialId++ 5957 }); 5958 this.uuid = generateUUID(); 5959 this.name = ''; 5960 this.type = 'Material'; 5961 this.fog = true; 5962 this.blending = NormalBlending; 5963 this.side = FrontSide; 5964 this.vertexColors = false; 5965 this.opacity = 1; 5966 this.format = RGBAFormat; 5967 this.transparent = false; 5968 this.blendSrc = SrcAlphaFactor; 5969 this.blendDst = OneMinusSrcAlphaFactor; 5970 this.blendEquation = AddEquation; 5971 this.blendSrcAlpha = null; 5972 this.blendDstAlpha = null; 5973 this.blendEquationAlpha = null; 5974 this.depthFunc = LessEqualDepth; 5975 this.depthTest = true; 5976 this.depthWrite = true; 5977 this.stencilWriteMask = 0xff; 5978 this.stencilFunc = AlwaysStencilFunc; 5979 this.stencilRef = 0; 5980 this.stencilFuncMask = 0xff; 5981 this.stencilFail = KeepStencilOp; 5982 this.stencilZFail = KeepStencilOp; 5983 this.stencilZPass = KeepStencilOp; 5984 this.stencilWrite = false; 5985 this.clippingPlanes = null; 5986 this.clipIntersection = false; 5987 this.clipShadows = false; 5988 this.shadowSide = null; 5989 this.colorWrite = true; 5990 this.precision = null; // override the renderer's default precision for this material 5991 5992 this.polygonOffset = false; 5993 this.polygonOffsetFactor = 0; 5994 this.polygonOffsetUnits = 0; 5995 this.dithering = false; 5996 this.alphaToCoverage = false; 5997 this.premultipliedAlpha = false; 5998 this.visible = true; 5999 this.toneMapped = true; 6000 this.userData = {}; 6001 this.version = 0; 6002 this._alphaTest = 0; 6003 } 6004 6005 get alphaTest() { 6006 return this._alphaTest; 6007 } 6008 6009 set alphaTest(value) { 6010 if (this._alphaTest > 0 !== value > 0) { 6011 this.version++; 6012 } 6013 6014 this._alphaTest = value; 6015 } 6016 6017 onBuild() {} 6018 6019 onBeforeRender() {} 6020 6021 onBeforeCompile() {} 6022 6023 customProgramCacheKey() { 6024 return this.onBeforeCompile.toString(); 6025 } 6026 6027 setValues(values) { 6028 if (values === undefined) return; 6029 6030 for (const key in values) { 6031 const newValue = values[key]; 6032 6033 if (newValue === undefined) { 6034 console.warn('THREE.Material: \'' + key + '\' parameter is undefined.'); 6035 continue; 6036 } // for backward compatability if shading is set in the constructor 6037 6038 6039 if (key === 'shading') { 6040 console.warn('THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.'); 6041 this.flatShading = newValue === FlatShading ? true : false; 6042 continue; 6043 } 6044 6045 const currentValue = this[key]; 6046 6047 if (currentValue === undefined) { 6048 console.warn('THREE.' + this.type + ': \'' + key + '\' is not a property of this material.'); 6049 continue; 6050 } 6051 6052 if (currentValue && currentValue.isColor) { 6053 currentValue.set(newValue); 6054 } else if (currentValue && currentValue.isVector3 && newValue && newValue.isVector3) { 6055 currentValue.copy(newValue); 6056 } else { 6057 this[key] = newValue; 6058 } 6059 } 6060 } 6061 6062 toJSON(meta) { 6063 const isRoot = meta === undefined || typeof meta === 'string'; 6064 6065 if (isRoot) { 6066 meta = { 6067 textures: {}, 6068 images: {} 6069 }; 6070 } 6071 6072 const data = { 6073 metadata: { 6074 version: 4.5, 6075 type: 'Material', 6076 generator: 'Material.toJSON' 6077 } 6078 }; // standard Material serialization 6079 6080 data.uuid = this.uuid; 6081 data.type = this.type; 6082 if (this.name !== '') data.name = this.name; 6083 if (this.color && this.color.isColor) data.color = this.color.getHex(); 6084 if (this.roughness !== undefined) data.roughness = this.roughness; 6085 if (this.metalness !== undefined) data.metalness = this.metalness; 6086 if (this.sheen !== undefined) data.sheen = this.sheen; 6087 if (this.sheenColor && this.sheenColor.isColor) data.sheenColor = this.sheenColor.getHex(); 6088 if (this.sheenRoughness !== undefined) data.sheenRoughness = this.sheenRoughness; 6089 if (this.emissive && this.emissive.isColor) data.emissive = this.emissive.getHex(); 6090 if (this.emissiveIntensity && this.emissiveIntensity !== 1) data.emissiveIntensity = this.emissiveIntensity; 6091 if (this.specular && this.specular.isColor) data.specular = this.specular.getHex(); 6092 if (this.specularIntensity !== undefined) data.specularIntensity = this.specularIntensity; 6093 if (this.specularColor && this.specularColor.isColor) data.specularColor = this.specularColor.getHex(); 6094 if (this.shininess !== undefined) data.shininess = this.shininess; 6095 if (this.clearcoat !== undefined) data.clearcoat = this.clearcoat; 6096 if (this.clearcoatRoughness !== undefined) data.clearcoatRoughness = this.clearcoatRoughness; 6097 6098 if (this.clearcoatMap && this.clearcoatMap.isTexture) { 6099 data.clearcoatMap = this.clearcoatMap.toJSON(meta).uuid; 6100 } 6101 6102 if (this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture) { 6103 data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON(meta).uuid; 6104 } 6105 6106 if (this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture) { 6107 data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON(meta).uuid; 6108 data.clearcoatNormalScale = this.clearcoatNormalScale.toArray(); 6109 } 6110 6111 if (this.map && this.map.isTexture) data.map = this.map.toJSON(meta).uuid; 6112 if (this.matcap && this.matcap.isTexture) data.matcap = this.matcap.toJSON(meta).uuid; 6113 if (this.alphaMap && this.alphaMap.isTexture) data.alphaMap = this.alphaMap.toJSON(meta).uuid; 6114 6115 if (this.lightMap && this.lightMap.isTexture) { 6116 data.lightMap = this.lightMap.toJSON(meta).uuid; 6117 data.lightMapIntensity = this.lightMapIntensity; 6118 } 6119 6120 if (this.aoMap && this.aoMap.isTexture) { 6121 data.aoMap = this.aoMap.toJSON(meta).uuid; 6122 data.aoMapIntensity = this.aoMapIntensity; 6123 } 6124 6125 if (this.bumpMap && this.bumpMap.isTexture) { 6126 data.bumpMap = this.bumpMap.toJSON(meta).uuid; 6127 data.bumpScale = this.bumpScale; 6128 } 6129 6130 if (this.normalMap && this.normalMap.isTexture) { 6131 data.normalMap = this.normalMap.toJSON(meta).uuid; 6132 data.normalMapType = this.normalMapType; 6133 data.normalScale = this.normalScale.toArray(); 6134 } 6135 6136 if (this.displacementMap && this.displacementMap.isTexture) { 6137 data.displacementMap = this.displacementMap.toJSON(meta).uuid; 6138 data.displacementScale = this.displacementScale; 6139 data.displacementBias = this.displacementBias; 6140 } 6141 6142 if (this.roughnessMap && this.roughnessMap.isTexture) data.roughnessMap = this.roughnessMap.toJSON(meta).uuid; 6143 if (this.metalnessMap && this.metalnessMap.isTexture) data.metalnessMap = this.metalnessMap.toJSON(meta).uuid; 6144 if (this.emissiveMap && this.emissiveMap.isTexture) data.emissiveMap = this.emissiveMap.toJSON(meta).uuid; 6145 if (this.specularMap && this.specularMap.isTexture) data.specularMap = this.specularMap.toJSON(meta).uuid; 6146 if (this.specularIntensityMap && this.specularIntensityMap.isTexture) data.specularIntensityMap = this.specularIntensityMap.toJSON(meta).uuid; 6147 if (this.specularColorMap && this.specularColorMap.isTexture) data.specularColorMap = this.specularColorMap.toJSON(meta).uuid; 6148 6149 if (this.envMap && this.envMap.isTexture) { 6150 data.envMap = this.envMap.toJSON(meta).uuid; 6151 if (this.combine !== undefined) data.combine = this.combine; 6152 } 6153 6154 if (this.envMapIntensity !== undefined) data.envMapIntensity = this.envMapIntensity; 6155 if (this.reflectivity !== undefined) data.reflectivity = this.reflectivity; 6156 if (this.refractionRatio !== undefined) data.refractionRatio = this.refractionRatio; 6157 6158 if (this.gradientMap && this.gradientMap.isTexture) { 6159 data.gradientMap = this.gradientMap.toJSON(meta).uuid; 6160 } 6161 6162 if (this.transmission !== undefined) data.transmission = this.transmission; 6163 if (this.transmissionMap && this.transmissionMap.isTexture) data.transmissionMap = this.transmissionMap.toJSON(meta).uuid; 6164 if (this.thickness !== undefined) data.thickness = this.thickness; 6165 if (this.thicknessMap && this.thicknessMap.isTexture) data.thicknessMap = this.thicknessMap.toJSON(meta).uuid; 6166 if (this.attenuationDistance !== undefined) data.attenuationDistance = this.attenuationDistance; 6167 if (this.attenuationColor !== undefined) data.attenuationColor = this.attenuationColor.getHex(); 6168 if (this.size !== undefined) data.size = this.size; 6169 if (this.shadowSide !== null) data.shadowSide = this.shadowSide; 6170 if (this.sizeAttenuation !== undefined) data.sizeAttenuation = this.sizeAttenuation; 6171 if (this.blending !== NormalBlending) data.blending = this.blending; 6172 if (this.side !== FrontSide) data.side = this.side; 6173 if (this.vertexColors) data.vertexColors = true; 6174 if (this.opacity < 1) data.opacity = this.opacity; 6175 if (this.format !== RGBAFormat) data.format = this.format; 6176 if (this.transparent === true) data.transparent = this.transparent; 6177 data.depthFunc = this.depthFunc; 6178 data.depthTest = this.depthTest; 6179 data.depthWrite = this.depthWrite; 6180 data.colorWrite = this.colorWrite; 6181 data.stencilWrite = this.stencilWrite; 6182 data.stencilWriteMask = this.stencilWriteMask; 6183 data.stencilFunc = this.stencilFunc; 6184 data.stencilRef = this.stencilRef; 6185 data.stencilFuncMask = this.stencilFuncMask; 6186 data.stencilFail = this.stencilFail; 6187 data.stencilZFail = this.stencilZFail; 6188 data.stencilZPass = this.stencilZPass; // rotation (SpriteMaterial) 6189 6190 if (this.rotation && this.rotation !== 0) data.rotation = this.rotation; 6191 if (this.polygonOffset === true) data.polygonOffset = true; 6192 if (this.polygonOffsetFactor !== 0) data.polygonOffsetFactor = this.polygonOffsetFactor; 6193 if (this.polygonOffsetUnits !== 0) data.polygonOffsetUnits = this.polygonOffsetUnits; 6194 if (this.linewidth && this.linewidth !== 1) data.linewidth = this.linewidth; 6195 if (this.dashSize !== undefined) data.dashSize = this.dashSize; 6196 if (this.gapSize !== undefined) data.gapSize = this.gapSize; 6197 if (this.scale !== undefined) data.scale = this.scale; 6198 if (this.dithering === true) data.dithering = true; 6199 if (this.alphaTest > 0) data.alphaTest = this.alphaTest; 6200 if (this.alphaToCoverage === true) data.alphaToCoverage = this.alphaToCoverage; 6201 if (this.premultipliedAlpha === true) data.premultipliedAlpha = this.premultipliedAlpha; 6202 if (this.wireframe === true) data.wireframe = this.wireframe; 6203 if (this.wireframeLinewidth > 1) data.wireframeLinewidth = this.wireframeLinewidth; 6204 if (this.wireframeLinecap !== 'round') data.wireframeLinecap = this.wireframeLinecap; 6205 if (this.wireframeLinejoin !== 'round') data.wireframeLinejoin = this.wireframeLinejoin; 6206 if (this.flatShading === true) data.flatShading = this.flatShading; 6207 if (this.visible === false) data.visible = false;
6208 if (this.toneMapped === false) data.toneMapped = false; 6209 if (JSON.stringify(this.userData) !== '{}') data.userData = this.userData; // TODO: Copied from Object3D.toJSON 6210 6211 function extractFromCache(cache) { 6212 const values = []; 6213 6214 for (const key in cache) { 6215 const data = cache[key]; 6216 delete data.metadata; 6217 values.push(data); 6218 } 6219 6220 return values; 6221 } 6222 6223 if (isRoot) { 6224 const textures = extractFromCache(meta.textures); 6225 const images = extractFromCache(meta.images); 6226 if (textures.length > 0) data.textures = textures; 6227 if (images.length > 0) data.images = images; 6228 } 6229 6230 return data; 6231 } 6232 6233 clone() { 6234 return new this.constructor().copy(this); 6235 } 6236 6237 copy(source) { 6238 this.name = source.name; 6239 this.fog = source.fog; 6240 this.blending = source.blending; 6241 this.side = source.side; 6242 this.vertexColors = source.vertexColors; 6243 this.opacity = source.opacity; 6244 this.format = source.format; 6245 this.transparent = source.transparent; 6246 this.blendSrc = source.blendSrc; 6247 this.blendDst = source.blendDst; 6248 this.blendEquation = source.blendEquation; 6249 this.blendSrcAlpha = source.blendSrcAlpha; 6250 this.blendDstAlpha = source.blendDstAlpha; 6251 this.blendEquationAlpha = source.blendEquationAlpha; 6252 this.depthFunc = source.depthFunc; 6253 this.depthTest = source.depthTest; 6254 this.depthWrite = source.depthWrite; 6255 this.stencilWriteMask = source.stencilWriteMask; 6256 this.stencilFunc = source.stencilFunc; 6257 this.stencilRef = source.stencilRef; 6258 this.stencilFuncMask = source.stencilFuncMask; 6259 this.stencilFail = source.stencilFail; 6260 this.stencilZFail = source.stencilZFail; 6261 this.stencilZPass = source.stencilZPass; 6262 this.stencilWrite = source.stencilWrite; 6263 const srcPlanes = source.clippingPlanes; 6264 let dstPlanes = null; 6265 6266 if (srcPlanes !== null) { 6267 const n = srcPlanes.length; 6268 dstPlanes = new Array(n); 6269 6270 for (let i = 0; i !== n; ++i) { 6271 dstPlanes[i] = srcPlanes[i].clone(); 6272 } 6273 } 6274 6275 this.clippingPlanes = dstPlanes; 6276 this.clipIntersection = source.clipIntersection; 6277 this.clipShadows = source.clipShadows; 6278 this.shadowSide = source.shadowSide; 6279 this.colorWrite = source.colorWrite; 6280 this.precision = source.precision; 6281 this.polygonOffset = source.polygonOffset; 6282 this.polygonOffsetFactor = source.polygonOffsetFactor; 6283 this.polygonOffsetUnits = source.polygonOffsetUnits; 6284 this.dithering = source.dithering; 6285 this.alphaTest = source.alphaTest; 6286 this.alphaToCoverage = source.alphaToCoverage; 6287 this.premultipliedAlpha = source.premultipliedAlpha; 6288 this.visible = source.visible; 6289 this.toneMapped = source.toneMapped; 6290 this.userData = JSON.parse(JSON.stringify(source.userData)); 6291 return this; 6292 } 6293 6294 dispose() { 6295 this.dispatchEvent({ 6296 type: 'dispose' 6297 }); 6298 } 6299 6300 set needsUpdate(value) { 6301 if (value === true) this.version++; 6302 } 6303 6304 } 6305 6306 Material.prototype.isMaterial = true; 6307 6308 const _colorKeywords = { 6309 'aliceblue': 0xF0F8FF, 6310 'antiquewhite': 0xFAEBD7, 6311 'aqua': 0x00FFFF, 6312 'aquamarine': 0x7FFFD4, 6313 'azure': 0xF0FFFF, 6314 'beige': 0xF5F5DC, 6315 'bisque': 0xFFE4C4, 6316 'black': 0x000000, 6317 'blanchedalmond': 0xFFEBCD, 6318 'blue': 0x0000FF, 6319 'blueviolet': 0x8A2BE2, 6320 'brown': 0xA52A2A, 6321 'burlywood': 0xDEB887, 6322 'cadetblue': 0x5F9EA0, 6323 'chartreuse': 0x7FFF00, 6324 'chocolate': 0xD2691E, 6325 'coral': 0xFF7F50, 6326 'cornflowerblue': 0x6495ED, 6327 'cornsilk': 0xFFF8DC, 6328 'crimson': 0xDC143C, 6329 'cyan': 0x00FFFF, 6330 'darkblue': 0x00008B, 6331 'darkcyan': 0x008B8B, 6332 'darkgoldenrod': 0xB8860B, 6333 'darkgray': 0xA9A9A9, 6334 'darkgreen': 0x006400, 6335 'darkgrey': 0xA9A9A9, 6336 'darkkhaki': 0xBDB76B, 6337 'darkmagenta': 0x8B008B, 6338 'darkolivegreen': 0x556B2F, 6339 'darkorange': 0xFF8C00, 6340 'darkorchid': 0x9932CC, 6341 'darkred': 0x8B0000, 6342 'darksalmon': 0xE9967A, 6343 'darkseagreen': 0x8FBC8F, 6344 'darkslateblue': 0x483D8B, 6345 'darkslategray': 0x2F4F4F, 6346 'darkslategrey': 0x2F4F4F, 6347 'darkturquoise': 0x00CED1, 6348 'darkviolet': 0x9400D3, 6349 'deeppink': 0xFF1493, 6350 'deepskyblue': 0x00BFFF, 6351 'dimgray': 0x696969, 6352 'dimgrey': 0x696969, 6353 'dodgerblue': 0x1E90FF, 6354 'firebrick': 0xB22222, 6355 'floralwhite': 0xFFFAF0, 6356 'forestgreen': 0x228B22, 6357 'fuchsia': 0xFF00FF, 6358 'gainsboro': 0xDCDCDC, 6359 'ghostwhite': 0xF8F8FF, 6360 'gold': 0xFFD700, 6361 'goldenrod': 0xDAA520, 6362 'gray': 0x808080, 6363 'green': 0x008000, 6364 'greenyellow': 0xADFF2F, 6365 'grey': 0x808080, 6366 'honeydew': 0xF0FFF0, 6367 'hotpink': 0xFF69B4, 6368 'indianred': 0xCD5C5C, 6369 'indigo': 0x4B0082, 6370 'ivory': 0xFFFFF0, 6371 'khaki': 0xF0E68C, 6372 'lavender': 0xE6E6FA, 6373 'lavenderblush': 0xFFF0F5, 6374 'lawngreen': 0x7CFC00, 6375 'lemonchiffon': 0xFFFACD, 6376 'lightblue': 0xADD8E6, 6377 'lightcoral': 0xF08080, 6378 'lightcyan': 0xE0FFFF, 6379 'lightgoldenrodyellow': 0xFAFAD2, 6380 'lightgray': 0xD3D3D3, 6381 'lightgreen': 0x90EE90, 6382 'lightgrey': 0xD3D3D3, 6383 'lightpink': 0xFFB6C1, 6384 'lightsalmon': 0xFFA07A, 6385 'lightseagreen': 0x20B2AA, 6386 'lightskyblue': 0x87CEFA, 6387 'lightslategray': 0x778899, 6388 'lightslategrey': 0x778899, 6389 'lightsteelblue': 0xB0C4DE, 6390 'lightyellow': 0xFFFFE0, 6391 'lime': 0x00FF00, 6392 'limegreen': 0x32CD32, 6393 'linen': 0xFAF0E6, 6394 'magenta': 0xFF00FF, 6395 'maroon': 0x800000, 6396 'mediumaquamarine': 0x66CDAA, 6397 'mediumblue': 0x0000CD, 6398 'mediumorchid': 0xBA55D3, 6399 'mediumpurple': 0x9370DB, 6400 'mediumseagreen': 0x3CB371, 6401 'mediumslateblue': 0x7B68EE, 6402 'mediumspringgreen': 0x00FA9A, 6403 'mediumturquoise': 0x48D1CC, 6404 'mediumvioletred': 0xC71585, 6405 'midnightblue': 0x191970, 6406 'mintcream': 0xF5FFFA, 6407 'mistyrose': 0xFFE4E1, 6408 'moccasin': 0xFFE4B5, 6409 'navajowhite': 0xFFDEAD, 6410 'navy': 0x000080, 6411 'oldlace': 0xFDF5E6, 6412 'olive': 0x808000, 6413 'olivedrab': 0x6B8E23, 6414 'orange': 0xFFA500, 6415 'orangered': 0xFF4500, 6416 'orchid': 0xDA70D6, 6417 'palegoldenrod': 0xEEE8AA, 6418 'palegreen': 0x98FB98, 6419 'paleturquoise': 0xAFEEEE, 6420 'palevioletred': 0xDB7093, 6421 'papayawhip': 0xFFEFD5, 6422 'peachpuff': 0xFFDAB9, 6423 'peru': 0xCD853F, 6424 'pink': 0xFFC0CB, 6425 'plum': 0xDDA0DD, 6426 'powderblue': 0xB0E0E6, 6427 'purple': 0x800080,
vendor: 8,788 bytes, lines 6428-6828
6428 'rebeccapurple': 0x663399, 6429 'red': 0xFF0000, 6430 'rosybrown': 0xBC8F8F, 6431 'royalblue': 0x4169E1, 6432 'saddlebrown': 0x8B4513, 6433 'salmon': 0xFA8072, 6434 'sandybrown': 0xF4A460, 6435 'seagreen': 0x2E8B57, 6436 'seashell': 0xFFF5EE, 6437 'sienna': 0xA0522D, 6438 'silver': 0xC0C0C0, 6439 'skyblue': 0x87CEEB, 6440 'slateblue': 0x6A5ACD, 6441 'slategray': 0x708090, 6442 'slategrey': 0x708090, 6443 'snow': 0xFFFAFA, 6444 'springgreen': 0x00FF7F, 6445 'steelblue': 0x4682B4, 6446 'tan': 0xD2B48C, 6447 'teal': 0x008080, 6448 'thistle': 0xD8BFD8, 6449 'tomato': 0xFF6347, 6450 'turquoise': 0x40E0D0, 6451 'violet': 0xEE82EE, 6452 'wheat': 0xF5DEB3, 6453 'white': 0xFFFFFF, 6454 'whitesmoke': 0xF5F5F5, 6455 'yellow': 0xFFFF00, 6456 'yellowgreen': 0x9ACD32 6457 }; 6458 const _hslA = { 6459 h: 0, 6460 s: 0, 6461 l: 0 6462 }; 6463 const _hslB = { 6464 h: 0, 6465 s: 0, 6466 l: 0 6467 }; 6468 6469 function hue2rgb(p, q, t) { 6470 if (t < 0) t += 1; 6471 if (t > 1) t -= 1; 6472 if (t < 1 / 6) return p + (q - p) * 6 * t; 6473 if (t < 1 / 2) return q; 6474 if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t); 6475 return p; 6476 } 6477 6478 function SRGBToLinear(c) { 6479 return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4); 6480 } 6481 6482 function LinearToSRGB(c) { 6483 return c < 0.0031308 ? c * 12.92 : 1.055 * Math.pow(c, 0.41666) - 0.055; 6484 } 6485 6486 class Color { 6487 constructor(r, g, b) { 6488 if (g === undefined && b === undefined) { 6489 // r is THREE.Color, hex or string 6490 return this.set(r); 6491 } 6492 6493 return this.setRGB(r, g, b); 6494 } 6495 6496 set(value) { 6497 if (value && value.isColor) { 6498 this.copy(value); 6499 } else if (typeof value === 'number') { 6500 this.setHex(value); 6501 } else if (typeof value === 'string') { 6502 this.setStyle(value); 6503 } 6504 6505 return this; 6506 } 6507 6508 setScalar(scalar) { 6509 this.r = scalar; 6510 this.g = scalar; 6511 this.b = scalar; 6512 return this; 6513 } 6514 6515 setHex(hex) { 6516 hex = Math.floor(hex); 6517 this.r = (hex >> 16 & 255) / 255; 6518 this.g = (hex >> 8 & 255) / 255; 6519 this.b = (hex & 255) / 255; 6520 return this; 6521 } 6522 6523 setRGB(r, g, b) { 6524 this.r = r; 6525 this.g = g; 6526 this.b = b; 6527 return this; 6528 } 6529 6530 setHSL(h, s, l) { 6531 // h,s,l ranges are in 0.0 - 1.0 6532 h = euclideanModulo(h, 1); 6533 s = clamp(s, 0, 1); 6534 l = clamp(l, 0, 1); 6535 6536 if (s === 0) { 6537 this.r = this.g = this.b = l; 6538 } else { 6539 const p = l <= 0.5 ? l * (1 + s) : l + s - l * s; 6540 const q = 2 * l - p; 6541 this.r = hue2rgb(q, p, h + 1 / 3); 6542 this.g = hue2rgb(q, p, h); 6543 this.b = hue2rgb(q, p, h - 1 / 3); 6544 } 6545 6546 return this; 6547 } 6548 6549 setStyle(style) { 6550 function handleAlpha(string) { 6551 if (string === undefined) return; 6552 6553 if (parseFloat(string) < 1) { 6554 console.warn('THREE.Color: Alpha component of ' + style + ' will be ignored.'); 6555 } 6556 } 6557 6558 let m; 6559 6560 if (m = /^((?:rgb|hsl)a?)\(([^\)]*)\)/.exec(style)) { 6561 // rgb / hsl 6562 let color; 6563 const name = m[1]; 6564 const components = m[2]; 6565 6566 switch (name) { 6567 case 'rgb': 6568 case 'rgba': 6569 if (color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { 6570 // rgb(255,0,0) rgba(255,0,0,0.5) 6571 this.r = Math.min(255, parseInt(color[1], 10)) / 255; 6572 this.g = Math.min(255, parseInt(color[2], 10)) / 255; 6573 this.b = Math.min(255, parseInt(color[3], 10)) / 255; 6574 handleAlpha(color[4]); 6575 return this; 6576 } 6577 6578 if (color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { 6579 // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) 6580 this.r = Math.min(100, parseInt(color[1], 10)) / 100; 6581 this.g = Math.min(100, parseInt(color[2], 10)) / 100; 6582 this.b = Math.min(100, parseInt(color[3], 10)) / 100; 6583 handleAlpha(color[4]); 6584 return this; 6585 } 6586 6587 break; 6588 6589 case 'hsl': 6590 case 'hsla': 6591 if (color = /^\s*(\d*\.?\d+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { 6592 // hsl(120,50%,50%) hsla(120,50%,50%,0.5) 6593 const h = parseFloat(color[1]) / 360; 6594 const s = parseInt(color[2], 10) / 100; 6595 const l = parseInt(color[3], 10) / 100; 6596 handleAlpha(color[4]); 6597 return this.setHSL(h, s, l); 6598 } 6599 6600 break; 6601 } 6602 } else if (m = /^\#([A-Fa-f\d]+)$/.exec(style)) { 6603 // hex color 6604 const hex = m[1]; 6605 const size = hex.length; 6606 6607 if (size === 3) { 6608 // #ff0 6609 this.r = parseInt(hex.charAt(0) + hex.charAt(0), 16) / 255; 6610 this.g = parseInt(hex.charAt(1) + hex.charAt(1), 16) / 255; 6611 this.b = parseInt(hex.charAt(2) + hex.charAt(2), 16) / 255; 6612 return this; 6613 } else if (size === 6) { 6614 // #ff0000 6615 this.r = parseInt(hex.charAt(0) + hex.charAt(1), 16) / 255; 6616 this.g = parseInt(hex.charAt(2) + hex.charAt(3), 16) / 255; 6617 this.b = parseInt(hex.charAt(4) + hex.charAt(5), 16) / 255; 6618 return this; 6619 } 6620 } 6621 6622 if (style && style.length > 0) { 6623 return this.setColorName(style); 6624 } 6625 6626 return this; 6627 } 6628 6629 setColorName(style) { 6630 // color keywords 6631 const hex = _colorKeywords[style.toLowerCase()]; 6632 6633 if (hex !== undefined) { 6634 // red 6635 this.setHex(hex); 6636 } else { 6637 // unknown color 6638 console.warn('THREE.Color: Unknown color ' + style); 6639 } 6640 6641 return this; 6642 } 6643 6644 clone() { 6645 return new this.constructor(this.r, this.g, this.b); 6646 } 6647 6648 copy(color) { 6649 this.r = color.r; 6650 this.g = color.g; 6651 this.b = color.b; 6652 return this; 6653 } 6654 6655 copySRGBToLinear(color) { 6656 this.r = SRGBToLinear(color.r); 6657 this.g = SRGBToLinear(color.g); 6658 this.b = SRGBToLinear(color.b); 6659 return this; 6660 } 6661 6662 copyLinearToSRGB(color) { 6663 this.r = LinearToSRGB(color.r); 6664 this.g = LinearToSRGB(color.g); 6665 this.b = LinearToSRGB(color.b); 6666 return this; 6667 } 6668 6669 convertSRGBToLinear() { 6670 this.copySRGBToLinear(this); 6671 return this; 6672 } 6673 6674 convertLinearToSRGB() { 6675 this.copyLinearToSRGB(this); 6676 return this; 6677 } 6678 6679 getHex() { 6680 return this.r * 255 << 16 ^ this.g * 255 << 8 ^ this.b * 255 << 0; 6681 } 6682 6683 getHexString() { 6684 return ('000000' + this.getHex().toString(16)).slice(-6); 6685 } 6686 6687 getHSL(target) { 6688 // h,s,l ranges are in 0.0 - 1.0 6689 const r = this.r, 6690 g = this.g, 6691 b = this.b; 6692 const max = Math.max(r, g, b); 6693 const min = Math.min(r, g, b); 6694 let hue, saturation; 6695 const lightness = (min + max) / 2.0; 6696 6697 if (min === max) { 6698 hue = 0; 6699 saturation = 0; 6700 } else { 6701 const delta = max - min; 6702 saturation = lightness <= 0.5 ? delta / (max + min) : delta / (2 - max - min); 6703 6704 switch (max) { 6705 case r: 6706 hue = (g - b) / delta + (g < b ? 6 : 0); 6707 break; 6708 6709 case g: 6710 hue = (b - r) / delta + 2; 6711 break; 6712 6713 case b: 6714 hue = (r - g) / delta + 4; 6715 break; 6716 } 6717 6718 hue /= 6; 6719 } 6720 6721 target.h = hue; 6722 target.s = saturation; 6723 target.l = lightness; 6724 return target; 6725 } 6726 6727 getStyle() { 6728 return 'rgb(' + (this.r * 255 | 0) + ',' + (this.g * 255 | 0) + ',' + (this.b * 255 | 0) + ')'; 6729 } 6730 6731 offsetHSL(h, s, l) { 6732 this.getHSL(_hslA); 6733 _hslA.h += h; 6734 _hslA.s += s; 6735 _hslA.l += l; 6736 this.setHSL(_hslA.h, _hslA.s, _hslA.l); 6737 return this; 6738 } 6739 6740 add(color) { 6741 this.r += color.r; 6742 this.g += color.g; 6743 this.b += color.b; 6744 return this; 6745 } 6746 6747 addColors(color1, color2) { 6748 this.r = color1.r + color2.r; 6749 this.g = color1.g + color2.g; 6750 this.b = color1.b + color2.b; 6751 return this; 6752 } 6753 6754 addScalar(s) { 6755 this.r += s; 6756 this.g += s; 6757 this.b += s; 6758 return this; 6759 } 6760 6761 sub(color) { 6762 this.r = Math.max(0, this.r - color.r); 6763 this.g = Math.max(0, this.g - color.g); 6764 this.b = Math.max(0, this.b - color.b); 6765 return this; 6766 } 6767 6768 multiply(color) { 6769 this.r *= color.r; 6770 this.g *= color.g; 6771 this.b *= color.b; 6772 return this; 6773 } 6774 6775 multiplyScalar(s) { 6776 this.r *= s; 6777 this.g *= s; 6778 this.b *= s; 6779 return this; 6780 } 6781 6782 lerp(color, alpha) { 6783 this.r += (color.r - this.r) * alpha; 6784 this.g += (color.g - this.g) * alpha; 6785 this.b += (color.b - this.b) * alpha; 6786 return this; 6787 } 6788 6789 lerpColors(color1, color2, alpha) { 6790 this.r = color1.r + (color2.r - color1.r) * alpha; 6791 this.g = color1.g + (color2.g - color1.g) * alpha; 6792 this.b = color1.b + (color2.b - color1.b) * alpha; 6793 return this; 6794 } 6795 6796 lerpHSL(color, alpha) { 6797 this.getHSL(_hslA); 6798 color.getHSL(_hslB); 6799 const h = lerp(_hslA.h, _hslB.h, alpha); 6800 const s = lerp(_hslA.s, _hslB.s, alpha); 6801 const l = lerp(_hslA.l, _hslB.l, alpha); 6802 this.setHSL(h, s, l); 6803 return this; 6804 } 6805 6806 equals(c) { 6807 return c.r === this.r && c.g === this.g && c.b === this.b; 6808 } 6809 6810 fromArray(array, offset = 0) { 6811 this.r = array[offset]; 6812 this.g = array[offset + 1]; 6813 this.b = array[offset + 2]; 6814 return this; 6815 } 6816 6817 toArray(array = [], offset = 0) { 6818 array[offset] = this.r; 6819 array[offset + 1] = this.g; 6820 array[offset + 2] = this.b; 6821 return array; 6822 } 6823 6824 fromBufferAttribute(attribute, index) { 6825 this.r = attribute.getX(index); 6826 this.g = attribute.getY(index); 6827 this.b = attribute.getZ(index); 6828
6829 if (attribute.normalized === true) { 6830 // assuming Uint8Array 6831 this.r /= 255; 6832 this.g /= 255; 6833 this.b /= 255; 6834 } 6835 6836 return this; 6837 } 6838 6839 toJSON() { 6840 return this.getHex(); 6841 } 6842 6843 } 6844 6845 Color.NAMES = _colorKeywords; 6846 Color.prototype.isColor = true; 6847 Color.prototype.r = 1; 6848 Color.prototype.g = 1; 6849 Color.prototype.b = 1; 6850 6851 /** 6852 * parameters = { 6853 * color: <hex>, 6854 * opacity: <float>, 6855 * map: new THREE.Texture( <Image> ), 6856 * 6857 * lightMap: new THREE.Texture( <Image> ), 6858 * lightMapIntensity: <float> 6859 * 6860 * aoMap: new THREE.Texture( <Image> ), 6861 * aoMapIntensity: <float> 6862 * 6863 * specularMap: new THREE.Texture( <Image> ), 6864 * 6865 * alphaMap: new THREE.Texture( <Image> ), 6866 * 6867 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), 6868 * combine: THREE.Multiply, 6869 * reflectivity: <float>, 6870 * refractionRatio: <float>, 6871 * 6872 * depthTest: <bool>, 6873 * depthWrite: <bool>, 6874 * 6875 * wireframe: <boolean>, 6876 * wireframeLinewidth: <float>, 6877 * } 6878 */ 6879 6880 class MeshBasicMaterial extends Material { 6881 constructor(parameters) { 6882 super(); 6883 this.type = 'MeshBasicMaterial'; 6884 this.color = new Color(0xffffff); // emissive 6885 6886 this.map = null; 6887 this.lightMap = null; 6888 this.lightMapIntensity = 1.0; 6889 this.aoMap = null; 6890 this.aoMapIntensity = 1.0; 6891 this.specularMap = null; 6892 this.alphaMap = null; 6893 this.envMap = null; 6894 this.combine = MultiplyOperation; 6895 this.reflectivity = 1; 6896 this.refractionRatio = 0.98; 6897 this.wireframe = false; 6898 this.wireframeLinewidth = 1; 6899 this.wireframeLinecap = 'round'; 6900 this.wireframeLinejoin = 'round'; 6901 this.setValues(parameters); 6902 } 6903 6904 copy(source) { 6905 super.copy(source); 6906 this.color.copy(source.color); 6907 this.map = source.map; 6908 this.lightMap = source.lightMap; 6909 this.lightMapIntensity = source.lightMapIntensity; 6910 this.aoMap = source.aoMap; 6911 this.aoMapIntensity = source.aoMapIntensity; 6912 this.specularMap = source.specularMap; 6913 this.alphaMap = source.alphaMap; 6914 this.envMap = source.envMap; 6915 this.combine = source.combine; 6916 this.reflectivity = source.reflectivity; 6917 this.refractionRatio = source.refractionRatio; 6918 this.wireframe = source.wireframe; 6919 this.wireframeLinewidth = source.wireframeLinewidth; 6920 this.wireframeLinecap = source.wireframeLinecap; 6921 this.wireframeLinejoin = source.wireframeLinejoin; 6922 return this; 6923 } 6924 6925 } 6926 6927 MeshBasicMaterial.prototype.isMeshBasicMaterial = true; 6928 6929 const _vector$9 = /*@__PURE__*/new Vector3(); 6930 6931 const _vector2$1 = /*@__PURE__*/new Vector2(); 6932 6933 class BufferAttribute { 6934 constructor(array, itemSize, normalized) { 6935 if (Array.isArray(array)) { 6936 throw new TypeError('THREE.BufferAttribute: array should be a Typed Array.'); 6937 } 6938 6939 this.name = ''; 6940 this.array = array; 6941 this.itemSize = itemSize; 6942 this.count = array !== undefined ? array.length / itemSize : 0; 6943 this.normalized = normalized === true; 6944 this.usage = StaticDrawUsage; 6945 this.updateRange = { 6946 offset: 0, 6947 count: -1 6948 }; 6949 this.version = 0; 6950 } 6951 6952 onUploadCallback() {} 6953 6954 set needsUpdate(value) { 6955 if (value === true) this.version++; 6956 } 6957 6958 setUsage(value) { 6959 this.usage = value; 6960 return this; 6961 } 6962 6963 copy(source) { 6964 this.name = source.name; 6965 this.array = new source.array.constructor(source.array); 6966 this.itemSize = source.itemSize; 6967 this.count = source.count; 6968 this.normalized = source.normalized; 6969 this.usage = source.usage; 6970 return this; 6971 } 6972 6973 copyAt(index1, attribute, index2) { 6974 index1 *= this.itemSize; 6975 index2 *= attribute.itemSize; 6976 6977 for (let i = 0, l = this.itemSize; i < l; i++) { 6978 this.array[index1 + i] = attribute.array[index2 + i]; 6979 } 6980 6981 return this; 6982 } 6983 6984 copyArray(array) { 6985 this.array.set(array); 6986 return this; 6987 } 6988 6989 copyColorsArray(colors) { 6990 const array = this.array; 6991 let offset = 0; 6992 6993 for (let i = 0, l = colors.length; i < l; i++) { 6994 let color = colors[i]; 6995 6996 if (color === undefined) { 6997 console.warn('THREE.BufferAttribute.copyColorsArray(): color is undefined', i); 6998 color = new Color(); 6999 } 7000 7001 array[offset++] = color.r; 7002 array[offset++] = color.g; 7003 array[offset++] = color.b; 7004 } 7005 7006 return this; 7007 } 7008 7009 copyVector2sArray(vectors) { 7010 const array = this.array; 7011 let offset = 0; 7012 7013 for (let i = 0, l = vectors.length; i < l; i++) { 7014 let vector = vectors[i]; 7015 7016 if (vector === undefined) { 7017 console.warn('THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i); 7018 vector = new Vector2(); 7019 } 7020 7021 array[offset++] = vector.x; 7022 array[offset++] = vector.y; 7023 } 7024 7025 return this; 7026 } 7027 7028 copyVector3sArray(vectors) { 7029 const array = this.array; 7030 let offset = 0; 7031 7032 for (let i = 0, l = vectors.length; i < l; i++) { 7033 let vector = vectors[i]; 7034 7035 if (vector === undefined) { 7036 console.warn('THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i); 7037 vector = new Vector3(); 7038 } 7039 7040 array[offset++] = vector.x; 7041 array[offset++] = vector.y; 7042 array[offset++] = vector.z; 7043 } 7044 7045 return this; 7046 } 7047 7048 copyVector4sArray(vectors) { 7049 const array = this.array; 7050 let offset = 0; 7051 7052 for (let i = 0, l = vectors.length; i < l; i++) { 7053 let vector = vectors[i]; 7054 7055 if (vector === undefined) { 7056 console.warn('THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i); 7057 vector = new Vector4(); 7058 } 7059 7060 array[offset++] = vector.x; 7061 array[offset++] = vector.y; 7062 array[offset++] = vector.z; 7063 array[offset++] = vector.w; 7064 } 7065 7066 return this; 7067 } 7068 7069 applyMatrix3(m) { 7070 if (this.itemSize === 2) { 7071 for (let i = 0, l = this.count; i < l; i++) { 7072 _vector2$1.fromBufferAttribute(this, i); 7073 7074 _vector2$1.applyMatrix3(m); 7075 7076 this.setXY(i, _vector2$1.x, _vector2$1.y); 7077 } 7078 } else if (this.itemSize === 3) { 7079 for (let i = 0, l = this.count; i < l; i++) { 7080 _vector$9.fromBufferAttribute(this, i); 7081 7082 _vector$9.applyMatrix3(m); 7083 7084 this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); 7085 } 7086 } 7087 7088 return this; 7089 } 7090 7091 applyMatrix4(m) { 7092 for (let i = 0, l = this.count; i < l; i++) { 7093 _vector$9.x = this.getX(i); 7094 _vector$9.y = this.getY(i); 7095 _vector$9.z = this.getZ(i); 7096 7097 _vector$9.applyMatrix4(m); 7098 7099 this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); 7100 } 7101 7102 return this; 7103 } 7104 7105 applyNormalMatrix(m) { 7106 for (let i = 0, l = this.count; i < l; i++) { 7107 _vector$9.x = this.getX(i); 7108 _vector$9.y = this.getY(i); 7109 _vector$9.z = this.getZ(i); 7110 7111 _vector$9.applyNormalMatrix(m); 7112 7113 this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); 7114 } 7115 7116 return this; 7117 } 7118 7119 transformDirection(m) { 7120 for (let i = 0, l = this.count; i < l; i++) { 7121 _vector$9.x = this.getX(i); 7122 _vector$9.y = this.getY(i); 7123 _vector$9.z = this.getZ(i); 7124 7125 _vector$9.transformDirection(m); 7126 7127 this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); 7128 } 7129 7130 return this; 7131 } 7132 7133 set(value, offset = 0) { 7134 this.array.set(value, offset); 7135 return this; 7136 } 7137 7138 getX(index) { 7139 return this.array[index * this.itemSize]; 7140 } 7141 7142 setX(index, x) { 7143 this.array[index * this.itemSize] = x; 7144 return this; 7145 } 7146 7147 getY(index) { 7148 return this.array[index * this.itemSize + 1]; 7149 } 7150 7151 setY(index, y) { 7152 this.array[index * this.itemSize + 1] = y; 7153 return this; 7154 } 7155 7156 getZ(index) { 7157 return this.array[index * this.itemSize + 2]; 7158 } 7159 7160 setZ(index, z) { 7161 this.array[index * this.itemSize + 2] = z; 7162 return this; 7163 } 7164 7165 getW(index) { 7166 return this.array[index * this.itemSize + 3]; 7167 } 7168 7169 setW(index, w) { 7170 this.array[index * this.itemSize + 3] = w; 7171 return this; 7172 } 7173 7174 setXY(index, x, y) { 7175 index *= this.itemSize; 7176 this.array[index + 0] = x; 7177 this.array[index + 1] = y; 7178 return this; 7179 } 7180 7181 setXYZ(index, x, y, z) { 7182 index *= this.itemSize; 7183 this.array[index + 0] = x; 7184 this.array[index + 1] = y; 7185 this.array[index + 2] = z; 7186 return this; 7187 } 7188 7189 setXYZW(index, x, y, z, w) { 7190 index *= this.itemSize; 7191 this.array[index + 0] = x; 7192 this.array[index + 1] = y; 7193 this.array[index + 2] = z; 7194 this.array[index + 3] = w; 7195 return this; 7196 } 7197 7198 onUpload(callback) { 7199 this.onUploadCallback = callback; 7200 return this; 7201 } 7202 7203 clone() { 7204 return new this.constructor(this.array, this.itemSize).copy(this); 7205 } 7206 7207 toJSON() { 7208 const data = { 7209 itemSize: this.itemSize, 7210 type: this.array.constructor.name, 7211 array: Array.prototype.slice.call(this.array), 7212 normalized: this.normalized 7213 }; 7214 if (this.name !== '') data.name = this.name; 7215 if (this.usage !== StaticDrawUsage) data.usage = this.usage; 7216 if (this.updateRange.offset !== 0 || this.updateRange.count !== -1) data.updateRange = this.updateRange; 7217 return data; 7218 } 7219 7220 } 7221 7222 BufferAttribute.prototype.isBufferAttribute = true; // 7223 7224 class Int8BufferAttribute extends BufferAttribute { 7225 constructor(array, itemSize, normalized) { 7226 super(new Int8Array(array), itemSize, normalized); 7227 } 7228 7229 } 7230 7231 class Uint8BufferAttribute extends BufferAttribute { 7232 constructor(array, itemSize, normalized) { 7233 super(new Uint8Array(array), itemSize, normalized); 7234 } 7235 7236 } 7237 7238 class Uint8ClampedBufferAttribute extends BufferAttribute { 7239 constructor(array, itemSize, normalized) { 7240 super(new Uint8ClampedArray(array), itemSize, normalized); 7241 } 7242 7243 } 7244 7245 class Int16BufferAttribute extends BufferAttribute { 7246 constructor(array, itemSize, normalized) { 7247 super(new Int16Array(array), itemSize, normalized); 7248 } 7249 7250 } 7251 7252 class Uint16BufferAttribute extends BufferAttribute { 7253 constructor(array, itemSize, normalized) { 7254 super(new Uint16Array(array), itemSize, normalized); 7255 } 7256 7257 } 7258 7259 class Int32BufferAttribute extends BufferAttribute { 7260 constructor(array, itemSize, normalized) { 7261 super(new Int32Array(array), itemSize, normalized); 7262 } 7263 7264 } 7265 7266 class Uint32BufferAttribute extends BufferAttribute { 7267 constructor(array, itemSize, normalized) { 7268 super(new Uint32Array(array), itemSize, normalized); 7269 } 7270 7271 } 7272 7273 class Float16BufferAttribute extends BufferAttribute { 7274 constructor(array, itemSize, normalized) { 7275 super(new Uint16Array(array), itemSize, normalized); 7276 } 7277 7278 } 7279 7280 Float16BufferAttribute.prototype.isFloat16BufferAttribute = true; 7281 7282 class Float32BufferAttribute extends BufferAttribute { 7283 constructor(array, itemSize, normalized) { 7284 super(new Float32Array(array), itemSize, normalized); 7285 } 7286 7287 } 7288 7289 class Float64BufferAttribute extends BufferAttribute { 7290 constructor(array, itemSize, normalized) { 7291 super(new Float64Array(array), itemSize, normalized); 7292 } 7293 7294 } // 7295 7296 let _id$1 = 0; 7297 7298 const _m1 = /*@__PURE__*/new Matrix4(); 7299 7300 const _obj = /*@__PURE__*/new Object3D(); 7301 7302 const _offset = /*@__PURE__*/new Vector3(); 7303 7304 const _box$1 = /*@__PURE__*/new Box3(); 7305 7306 const _boxMorphTargets = /*@__PURE__*/new Box3(); 7307 7308 const _vector$8 = /*@__PURE__*/new Vector3(); 7309
vendor: 3,875 bytes, lines 7310-7500
7310 class BufferGeometry extends EventDispatcher { 7311 constructor() { 7312 super(); 7313 Object.defineProperty(this, 'id', { 7314 value: _id$1++ 7315 }); 7316 this.uuid = generateUUID(); 7317 this.name = ''; 7318 this.type = 'BufferGeometry'; 7319 this.index = null; 7320 this.attributes = {}; 7321 this.morphAttributes = {}; 7322 this.morphTargetsRelative = false; 7323 this.groups = []; 7324 this.boundingBox = null; 7325 this.boundingSphere = null; 7326 this.drawRange = { 7327 start: 0, 7328 count: Infinity 7329 }; 7330 this.userData = {}; 7331 } 7332 7333 getIndex() { 7334 return this.index; 7335 } 7336 7337 setIndex(index) { 7338 if (Array.isArray(index)) { 7339 this.index = new (arrayMax(index) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute)(index, 1); 7340 } else { 7341 this.index = index; 7342 } 7343 7344 return this; 7345 } 7346 7347 getAttribute(name) { 7348 return this.attributes[name]; 7349 } 7350 7351 setAttribute(name, attribute) { 7352 this.attributes[name] = attribute; 7353 return this; 7354 } 7355 7356 deleteAttribute(name) { 7357 delete this.attributes[name]; 7358 return this; 7359 } 7360 7361 hasAttribute(name) { 7362 return this.attributes[name] !== undefined; 7363 } 7364 7365 addGroup(start, count, materialIndex = 0) { 7366 this.groups.push({ 7367 start: start, 7368 count: count, 7369 materialIndex: materialIndex 7370 }); 7371 } 7372 7373 clearGroups() { 7374 this.groups = []; 7375 } 7376 7377 setDrawRange(start, count) { 7378 this.drawRange.start = start; 7379 this.drawRange.count = count; 7380 } 7381 7382 applyMatrix4(matrix) { 7383 const position = this.attributes.position; 7384 7385 if (position !== undefined) { 7386 position.applyMatrix4(matrix); 7387 position.needsUpdate = true; 7388 } 7389 7390 const normal = this.attributes.normal; 7391 7392 if (normal !== undefined) { 7393 const normalMatrix = new Matrix3().getNormalMatrix(matrix); 7394 normal.applyNormalMatrix(normalMatrix); 7395 normal.needsUpdate = true; 7396 } 7397 7398 const tangent = this.attributes.tangent; 7399 7400 if (tangent !== undefined) { 7401 tangent.transformDirection(matrix); 7402 tangent.needsUpdate = true; 7403 } 7404 7405 if (this.boundingBox !== null) { 7406 this.computeBoundingBox(); 7407 } 7408 7409 if (this.boundingSphere !== null) { 7410 this.computeBoundingSphere(); 7411 } 7412 7413 return this; 7414 } 7415 7416 applyQuaternion(q) { 7417 _m1.makeRotationFromQuaternion(q); 7418 7419 this.applyMatrix4(_m1); 7420 return this; 7421 } 7422 7423 rotateX(angle) { 7424 // rotate geometry around world x-axis 7425 _m1.makeRotationX(angle); 7426 7427 this.applyMatrix4(_m1); 7428 return this; 7429 } 7430 7431 rotateY(angle) { 7432 // rotate geometry around world y-axis 7433 _m1.makeRotationY(angle); 7434 7435 this.applyMatrix4(_m1); 7436 return this; 7437 } 7438 7439 rotateZ(angle) { 7440 // rotate geometry around world z-axis 7441 _m1.makeRotationZ(angle); 7442 7443 this.applyMatrix4(_m1); 7444 return this; 7445 } 7446 7447 translate(x, y, z) { 7448 // translate geometry 7449 _m1.makeTranslation(x, y, z); 7450 7451 this.applyMatrix4(_m1); 7452 return this; 7453 } 7454 7455 scale(x, y, z) { 7456 // scale geometry 7457 _m1.makeScale(x, y, z); 7458 7459 this.applyMatrix4(_m1); 7460 return this; 7461 } 7462 7463 lookAt(vector) { 7464 _obj.lookAt(vector); 7465 7466 _obj.updateMatrix(); 7467 7468 this.applyMatrix4(_obj.matrix); 7469 return this; 7470 } 7471 7472 center() { 7473 this.computeBoundingBox(); 7474 this.boundingBox.getCenter(_offset).negate(); 7475 this.translate(_offset.x, _offset.y, _offset.z); 7476 return this; 7477 } 7478 7479 setFromPoints(points) { 7480 const position = []; 7481 7482 for (let i = 0, l = points.length; i < l; i++) { 7483 const point = points[i]; 7484 position.push(point.x, point.y, point.z || 0); 7485 } 7486 7487 this.setAttribute('position', new Float32BufferAttribute(position, 3)); 7488 return this; 7489 } 7490 7491 computeBoundingBox() { 7492 if (this.boundingBox === null) { 7493 this.boundingBox = new Box3(); 7494 } 7495 7496 const position = this.attributes.position; 7497 const morphAttributesPosition = this.morphAttributes.position; 7498 7499 if (position && position.isGLBufferAttribute) { 7500 console.error('THREE.BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box. Alternatively set "mesh.frustumCulled" to "fal
vendor: 1,673 bytes, lines 7500-7546
7500se".', this); 7501 this.boundingBox.set(new Vector3(-Infinity, -Infinity, -Infinity), new Vector3(+Infinity, +Infinity, +Infinity)); 7502 return; 7503 } 7504 7505 if (position !== undefined) { 7506 this.boundingBox.setFromBufferAttribute(position); // process morph attributes if present 7507 7508 if (morphAttributesPosition) { 7509 for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { 7510 const morphAttribute = morphAttributesPosition[i]; 7511 7512 _box$1.setFromBufferAttribute(morphAttribute); 7513 7514 if (this.morphTargetsRelative) { 7515 _vector$8.addVectors(this.boundingBox.min, _box$1.min); 7516 7517 this.boundingBox.expandByPoint(_vector$8); 7518 7519 _vector$8.addVectors(this.boundingBox.max, _box$1.max); 7520 7521 this.boundingBox.expandByPoint(_vector$8); 7522 } else { 7523 this.boundingBox.expandByPoint(_box$1.min); 7524 this.boundingBox.expandByPoint(_box$1.max); 7525 } 7526 } 7527 } 7528 } else { 7529 this.boundingBox.makeEmpty(); 7530 } 7531 7532 if (isNaN(this.boundingBox.min.x) || isNaN(this.boundingBox.min.y) || isNaN(this.boundingBox.min.z)) { 7533 console.error('THREE.BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this); 7534 } 7535 } 7536 7537 computeBoundingSphere() { 7538 if (this.boundingSphere === null) { 7539 this.boundingSphere = new Sphere(); 7540 } 7541 7542 const position = this.attributes.position; 7543 const morphAttributesPosition = this.morphAttributes.position; 7544 7545 if (position && position.isGLBufferAttribute) { 7546 console.error('THREE.BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere. Alternatively set "mesh.frustumCulled" to "fal
vendor: 4,316 bytes, lines 7546-7688
7546se".', this); 7547 this.boundingSphere.set(new Vector3(), Infinity); 7548 return; 7549 } 7550 7551 if (position) { 7552 // first, find the center of the bounding sphere 7553 const center = this.boundingSphere.center; 7554 7555 _box$1.setFromBufferAttribute(position); // process morph attributes if present 7556 7557 7558 if (morphAttributesPosition) { 7559 for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { 7560 const morphAttribute = morphAttributesPosition[i]; 7561 7562 _boxMorphTargets.setFromBufferAttribute(morphAttribute); 7563 7564 if (this.morphTargetsRelative) { 7565 _vector$8.addVectors(_box$1.min, _boxMorphTargets.min); 7566 7567 _box$1.expandByPoint(_vector$8); 7568 7569 _vector$8.addVectors(_box$1.max, _boxMorphTargets.max); 7570 7571 _box$1.expandByPoint(_vector$8); 7572 } else { 7573 _box$1.expandByPoint(_boxMorphTargets.min); 7574 7575 _box$1.expandByPoint(_boxMorphTargets.max); 7576 } 7577 } 7578 } 7579 7580 _box$1.getCenter(center); // second, try to find a boundingSphere with a radius smaller than the 7581 // boundingSphere of the boundingBox: sqrt(3) smaller in the best case 7582 7583 7584 let maxRadiusSq = 0; 7585 7586 for (let i = 0, il = position.count; i < il; i++) { 7587 _vector$8.fromBufferAttribute(position, i); 7588 7589 maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8)); 7590 } // process morph attributes if present 7591 7592 7593 if (morphAttributesPosition) { 7594 for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { 7595 const morphAttribute = morphAttributesPosition[i]; 7596 const morphTargetsRelative = this.morphTargetsRelative; 7597 7598 for (let j = 0, jl = morphAttribute.count; j < jl; j++) { 7599 _vector$8.fromBufferAttribute(morphAttribute, j); 7600 7601 if (morphTargetsRelative) { 7602 _offset.fromBufferAttribute(position, j); 7603 7604 _vector$8.add(_offset); 7605 } 7606 7607 maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8)); 7608 } 7609 } 7610 } 7611 7612 this.boundingSphere.radius = Math.sqrt(maxRadiusSq); 7613 7614 if (isNaN(this.boundingSphere.radius)) { 7615 console.error('THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this); 7616 } 7617 } 7618 } 7619 7620 computeTangents() { 7621 const index = this.index; 7622 const attributes = this.attributes; // based on http://www.terathon.com/code/tangent.html 7623 // (per vertex tangents) 7624 7625 if (index === null || attributes.position === undefined || attributes.normal === undefined || attributes.uv === undefined) { 7626 console.error('THREE.BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)'); 7627 return; 7628 } 7629 7630 const indices = index.array; 7631 const positions = attributes.position.array; 7632 const normals = attributes.normal.array; 7633 const uvs = attributes.uv.array; 7634 const nVertices = positions.length / 3; 7635 7636 if (attributes.tangent === undefined) { 7637 this.setAttribute('tangent', new BufferAttribute(new Float32Array(4 * nVertices), 4)); 7638 } 7639 7640 const tangents = attributes.tangent.array; 7641 const tan1 = [], 7642 tan2 = []; 7643 7644 for (let i = 0; i < nVertices; i++) { 7645 tan1[i] = new Vector3(); 7646 tan2[i] = new Vector3(); 7647 } 7648 7649 const vA = new Vector3(), 7650 vB = new Vector3(), 7651 vC = new Vector3(), 7652 uvA = new Vector2(), 7653 uvB = new Vector2(), 7654 uvC = new Vector2(), 7655 sdir = new Vector3(), 7656 tdir = new Vector3(); 7657 7658 function handleTriangle(a, b, c) { 7659 vA.fromArray(positions, a * 3); 7660 vB.fromArray(positions, b * 3); 7661 vC.fromArray(positions, c * 3); 7662 uvA.fromArray(uvs, a * 2); 7663 uvB.fromArray(uvs, b * 2); 7664 uvC.fromArray(uvs, c * 2); 7665 vB.sub(vA); 7666 vC.sub(vA); 7667 uvB.sub(uvA); 7668 uvC.sub(uvA); 7669 const r = 1.0 / (uvB.x * uvC.y - uvC.x * uvB.y); // silently ignore degenerate uv triangles having coincident or colinear vertices 7670 7671 if (!isFinite(r)) return; 7672 sdir.copy(vB).multiplyScalar(uvC.y).addScaledVector(vC, -uvB.y).multiplyScalar(r); 7673 tdir.copy(vC).multiplyScalar(uvB.x).addScaledVector(vB, -uvC.x).multiplyScalar(r); 7674 tan1[a].add(sdir); 7675 tan1[b].add(sdir); 7676 tan1[c].add(sdir); 7677 tan2[a].add(tdir); 7678 tan2[b].add(tdir); 7679 tan2[c].add(tdir); 7680 } 7681 7682 let groups = this.groups; 7683 7684 if (groups.length === 0) { 7685 groups = [{ 7686 start: 0, 7687 count: indices.length 7688 }
vendor: 7,918 bytes, lines 7688-7958
7688]; 7689 } 7690 7691 for (let i = 0, il = groups.length; i < il; ++i) { 7692 const group = groups[i]; 7693 const start = group.start; 7694 const count = group.count; 7695 7696 for (let j = start, jl = start + count; j < jl; j += 3) { 7697 handleTriangle(indices[j + 0], indices[j + 1], indices[j + 2]); 7698 } 7699 } 7700 7701 const tmp = new Vector3(), 7702 tmp2 = new Vector3(); 7703 const n = new Vector3(), 7704 n2 = new Vector3(); 7705 7706 function handleVertex(v) { 7707 n.fromArray(normals, v * 3); 7708 n2.copy(n); 7709 const t = tan1[v]; // Gram-Schmidt orthogonalize 7710 7711 tmp.copy(t); 7712 tmp.sub(n.multiplyScalar(n.dot(t))).normalize(); // Calculate handedness 7713 7714 tmp2.crossVectors(n2, t); 7715 const test = tmp2.dot(tan2[v]); 7716 const w = test < 0.0 ? -1.0 : 1.0; 7717 tangents[v * 4] = tmp.x; 7718 tangents[v * 4 + 1] = tmp.y; 7719 tangents[v * 4 + 2] = tmp.z; 7720 tangents[v * 4 + 3] = w; 7721 } 7722 7723 for (let i = 0, il = groups.length; i < il; ++i) { 7724 const group = groups[i]; 7725 const start = group.start; 7726 const count = group.count; 7727 7728 for (let j = start, jl = start + count; j < jl; j += 3) { 7729 handleVertex(indices[j + 0]); 7730 handleVertex(indices[j + 1]); 7731 handleVertex(indices[j + 2]); 7732 } 7733 } 7734 } 7735 7736 computeVertexNormals() { 7737 const index = this.index; 7738 const positionAttribute = this.getAttribute('position'); 7739 7740 if (positionAttribute !== undefined) { 7741 let normalAttribute = this.getAttribute('normal'); 7742 7743 if (normalAttribute === undefined) { 7744 normalAttribute = new BufferAttribute(new Float32Array(positionAttribute.count * 3), 3); 7745 this.setAttribute('normal', normalAttribute); 7746 } else { 7747 // reset existing normals to zero 7748 for (let i = 0, il = normalAttribute.count; i < il; i++) { 7749 normalAttribute.setXYZ(i, 0, 0, 0); 7750 } 7751 } 7752 7753 const pA = new Vector3(), 7754 pB = new Vector3(), 7755 pC = new Vector3(); 7756 const nA = new Vector3(), 7757 nB = new Vector3(), 7758 nC = new Vector3(); 7759 const cb = new Vector3(), 7760 ab = new Vector3(); // indexed elements 7761 7762 if (index) { 7763 for (let i = 0, il = index.count; i < il; i += 3) { 7764 const vA = index.getX(i + 0); 7765 const vB = index.getX(i + 1); 7766 const vC = index.getX(i + 2); 7767 pA.fromBufferAttribute(positionAttribute, vA); 7768 pB.fromBufferAttribute(positionAttribute, vB); 7769 pC.fromBufferAttribute(positionAttribute, vC); 7770 cb.subVectors(pC, pB); 7771 ab.subVectors(pA, pB); 7772 cb.cross(ab); 7773 nA.fromBufferAttribute(normalAttribute, vA); 7774 nB.fromBufferAttribute(normalAttribute, vB); 7775 nC.fromBufferAttribute(normalAttribute, vC); 7776 nA.add(cb); 7777 nB.add(cb); 7778 nC.add(cb); 7779 normalAttribute.setXYZ(vA, nA.x, nA.y, nA.z); 7780 normalAttribute.setXYZ(vB, nB.x, nB.y, nB.z); 7781 normalAttribute.setXYZ(vC, nC.x, nC.y, nC.z); 7782 } 7783 } else { 7784 // non-indexed elements (unconnected triangle soup) 7785 for (let i = 0, il = positionAttribute.count; i < il; i += 3) { 7786 pA.fromBufferAttribute(positionAttribute, i + 0); 7787 pB.fromBufferAttribute(positionAttribute, i + 1); 7788 pC.fromBufferAttribute(positionAttribute, i + 2); 7789 cb.subVectors(pC, pB); 7790 ab.subVectors(pA, pB); 7791 cb.cross(ab); 7792 normalAttribute.setXYZ(i + 0, cb.x, cb.y, cb.z); 7793 normalAttribute.setXYZ(i + 1, cb.x, cb.y, cb.z); 7794 normalAttribute.setXYZ(i + 2, cb.x, cb.y, cb.z); 7795 } 7796 } 7797 7798 this.normalizeNormals(); 7799 normalAttribute.needsUpdate = true; 7800 } 7801 } 7802 7803 merge(geometry, offset) { 7804 if (!(geometry && geometry.isBufferGeometry)) { 7805 console.error('THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry); 7806 return; 7807 } 7808 7809 if (offset === undefined) { 7810 offset = 0; 7811 console.warn('THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.'); 7812 } 7813 7814 const attributes = this.attributes; 7815 7816 for (const key in attributes) { 7817 if (geometry.attributes[key] === undefined) continue; 7818 const attribute1 = attributes[key]; 7819 const attributeArray1 = attribute1.array; 7820 const attribute2 = geometry.attributes[key]; 7821 const attributeArray2 = attribute2.array; 7822 const attributeOffset = attribute2.itemSize * offset; 7823 const length = Math.min(attributeArray2.length, attributeArray1.length - attributeOffset); 7824 7825 for (let i = 0, j = attributeOffset; i < length; i++, j++) { 7826 attributeArray1[j] = attributeArray2[i]; 7827 } 7828 } 7829 7830 return this; 7831 } 7832 7833 normalizeNormals() { 7834 const normals = this.attributes.normal; 7835 7836 for (let i = 0, il = normals.count; i < il; i++) { 7837 _vector$8.fromBufferAttribute(normals, i); 7838 7839 _vector$8.normalize(); 7840 7841 normals.setXYZ(i, _vector$8.x, _vector$8.y, _vector$8.z); 7842 } 7843 } 7844 7845 toNonIndexed() { 7846 function convertBufferAttribute(attribute, indices) { 7847 const array = attribute.array; 7848 const itemSize = attribute.itemSize; 7849 const normalized = attribute.normalized; 7850 const array2 = new array.constructor(indices.length * itemSize); 7851 let index = 0, 7852 index2 = 0; 7853 7854 for (let i = 0, l = indices.length; i < l; i++) { 7855 if (attribute.isInterleavedBufferAttribute) { 7856 index = indices[i] * attribute.data.stride + attribute.offset; 7857 } else { 7858 index = indices[i] * itemSize; 7859 } 7860 7861 for (let j = 0; j < itemSize; j++) { 7862 array2[index2++] = array[index++]; 7863 } 7864 } 7865 7866 return new BufferAttribute(array2, itemSize, normalized); 7867 } // 7868 7869 7870 if (this.index === null) { 7871 console.warn('THREE.BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed.'); 7872 return this; 7873 } 7874 7875 const geometry2 = new BufferGeometry(); 7876 const indices = this.index.array; 7877 const attributes = this.attributes; // attributes 7878 7879 for (const name in attributes) { 7880 const attribute = attributes[name]; 7881 const newAttribute = convertBufferAttribute(attribute, indices); 7882 geometry2.setAttribute(name, newAttribute); 7883 } // morph attributes 7884 7885 7886 const morphAttributes = this.morphAttributes; 7887 7888 for (const name in morphAttributes) { 7889 const morphArray = []; 7890 const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes 7891 7892 for (let i = 0, il = morphAttribute.length; i < il; i++) { 7893 const attribute = morphAttribute[i]; 7894 const newAttribute = convertBufferAttribute(attribute, indices); 7895 morphArray.push(newAttribute); 7896 } 7897 7898 geometry2.morphAttributes[name] = morphArray; 7899 } 7900 7901 geometry2.morphTargetsRelative = this.morphTargetsRelative; // groups 7902 7903 const groups = this.groups; 7904 7905 for (let i = 0, l = groups.length; i < l; i++) { 7906 const group = groups[i]; 7907 geometry2.addGroup(group.start, group.count, group.materialIndex); 7908 } 7909 7910 return geometry2; 7911 } 7912 7913 toJSON() { 7914 const data = { 7915 metadata: { 7916 version: 4.5, 7917 type: 'BufferGeometry', 7918 generator: 'BufferGeometry.toJSON' 7919 } 7920 }; // standard BufferGeometry serialization 7921 7922 data.uuid = this.uuid; 7923 data.type = this.type; 7924 if (this.name !== '') data.name = this.name; 7925 if (Object.keys(this.userData).length > 0) data.userData = this.userData; 7926 7927 if (this.parameters !== undefined) { 7928 const parameters = this.parameters; 7929 7930 for (const key in parameters) { 7931 if (parameters[key] !== undefined) data[key] = parameters[key]; 7932 } 7933 7934 return data; 7935 } // for simplicity the code assumes attributes are not shared across geometries, see #15811 7936 7937 7938 data.data = { 7939 attributes: {} 7940 }; 7941 const index = this.index; 7942 7943 if (index !== null) { 7944 data.data.index = { 7945 type: index.array.constructor.name, 7946 array: Array.prototype.slice.call(index.array) 7947 }; 7948 } 7949 7950 const attributes = this.attributes; 7951 7952 for (const key in attributes) { 7953 const attribute = attributes[key]; 7954 data.data.attributes[key] = attribute.toJSON(data.data); 7955 } 7956 7957 const morphAttributes = {}; 7958 let hasMorphAttributes = false;
vendor: 4,544 bytes, lines 7959-8149
7959 7960 for (const key in this.morphAttributes) { 7961 const attributeArray = this.morphAttributes[key]; 7962 const array = []; 7963 7964 for (let i = 0, il = attributeArray.length; i < il; i++) { 7965 const attribute = attributeArray[i]; 7966 array.push(attribute.toJSON(data.data)); 7967 } 7968 7969 if (array.length > 0) { 7970 morphAttributes[key] = array; 7971 hasMorphAttributes = true; 7972 } 7973 } 7974 7975 if (hasMorphAttributes) { 7976 data.data.morphAttributes = morphAttributes; 7977 data.data.morphTargetsRelative = this.morphTargetsRelative; 7978 } 7979 7980 const groups = this.groups; 7981 7982 if (groups.length > 0) { 7983 data.data.groups = JSON.parse(JSON.stringify(groups)); 7984 } 7985 7986 const boundingSphere = this.boundingSphere; 7987 7988 if (boundingSphere !== null) { 7989 data.data.boundingSphere = { 7990 center: boundingSphere.center.toArray(), 7991 radius: boundingSphere.radius 7992 }; 7993 } 7994 7995 return data; 7996 } 7997 7998 clone() { 7999 return new this.constructor().copy(this); 8000 } 8001 8002 copy(source) { 8003 // reset 8004 this.index = null; 8005 this.attributes = {}; 8006 this.morphAttributes = {}; 8007 this.groups = []; 8008 this.boundingBox = null; 8009 this.boundingSphere = null; // used for storing cloned, shared data 8010 8011 const data = {}; // name 8012 8013 this.name = source.name; // index 8014 8015 const index = source.index; 8016 8017 if (index !== null) { 8018 this.setIndex(index.clone(data)); 8019 } // attributes 8020 8021 8022 const attributes = source.attributes; 8023 8024 for (const name in attributes) { 8025 const attribute = attributes[name]; 8026 this.setAttribute(name, attribute.clone(data)); 8027 } // morph attributes 8028 8029 8030 const morphAttributes = source.morphAttributes; 8031 8032 for (const name in morphAttributes) { 8033 const array = []; 8034 const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes 8035 8036 for (let i = 0, l = morphAttribute.length; i < l; i++) { 8037 array.push(morphAttribute[i].clone(data)); 8038 } 8039 8040 this.morphAttributes[name] = array; 8041 } 8042 8043 this.morphTargetsRelative = source.morphTargetsRelative; // groups 8044 8045 const groups = source.groups; 8046 8047 for (let i = 0, l = groups.length; i < l; i++) { 8048 const group = groups[i]; 8049 this.addGroup(group.start, group.count, group.materialIndex); 8050 } // bounding box 8051 8052 8053 const boundingBox = source.boundingBox; 8054 8055 if (boundingBox !== null) { 8056 this.boundingBox = boundingBox.clone(); 8057 } // bounding sphere 8058 8059 8060 const boundingSphere = source.boundingSphere; 8061 8062 if (boundingSphere !== null) { 8063 this.boundingSphere = boundingSphere.clone(); 8064 } // draw range 8065 8066 8067 this.drawRange.start = source.drawRange.start; 8068 this.drawRange.count = source.drawRange.count; // user data 8069 8070 this.userData = source.userData; // geometry generator parameters 8071 8072 if (source.parameters !== undefined) this.parameters = Object.assign({}, source.parameters); 8073 return this; 8074 } 8075 8076 dispose() { 8077 this.dispatchEvent({ 8078 type: 'dispose' 8079 }); 8080 } 8081 8082 } 8083 8084 BufferGeometry.prototype.isBufferGeometry = true; 8085 8086 const _inverseMatrix$2 = /*@__PURE__*/new Matrix4(); 8087 8088 const _ray$2 = /*@__PURE__*/new Ray(); 8089 8090 const _sphere$3 = /*@__PURE__*/new Sphere(); 8091 8092 const _vA$1 = /*@__PURE__*/new Vector3(); 8093 8094 const _vB$1 = /*@__PURE__*/new Vector3(); 8095 8096 const _vC$1 = /*@__PURE__*/new Vector3(); 8097 8098 const _tempA = /*@__PURE__*/new Vector3(); 8099 8100 const _tempB = /*@__PURE__*/new Vector3(); 8101 8102 const _tempC = /*@__PURE__*/new Vector3(); 8103 8104 const _morphA = /*@__PURE__*/new Vector3(); 8105 8106 const _morphB = /*@__PURE__*/new Vector3(); 8107 8108 const _morphC = /*@__PURE__*/new Vector3(); 8109 8110 const _uvA$1 = /*@__PURE__*/new Vector2(); 8111 8112 const _uvB$1 = /*@__PURE__*/new Vector2(); 8113 8114 const _uvC$1 = /*@__PURE__*/new Vector2(); 8115 8116 const _intersectionPoint = /*@__PURE__*/new Vector3(); 8117 8118 const _intersectionPointWorld = /*@__PURE__*/new Vector3(); 8119 8120 class Mesh extends Object3D { 8121 constructor(geometry = new BufferGeometry(), material = new MeshBasicMaterial()) { 8122 super(); 8123 this.type = 'Mesh'; 8124 this.geometry = geometry; 8125 this.material = material; 8126 this.updateMorphTargets(); 8127 } 8128 8129 copy(source) { 8130 super.copy(source); 8131 8132 if (source.morphTargetInfluences !== undefined) { 8133 this.morphTargetInfluences = source.morphTargetInfluences.slice(); 8134 } 8135 8136 if (source.morphTargetDictionary !== undefined) { 8137 this.morphTargetDictionary = Object.assign({}, source.morphTargetDictionary); 8138 } 8139 8140 this.material = source.material; 8141 this.geometry = source.geometry; 8142 return this; 8143 } 8144 8145 updateMorphTargets() { 8146 const geometry = this.geometry; 8147 8148 if (geometry.isBufferGeometry) { 8149 const morphAttributes = geometry.morphAttributes;
vendor: 12,234 bytes, lines 8150-8529
8150 const keys = Object.keys(morphAttributes); 8151 8152 if (keys.length > 0) { 8153 const morphAttribute = morphAttributes[keys[0]]; 8154 8155 if (morphAttribute !== undefined) { 8156 this.morphTargetInfluences = []; 8157 this.morphTargetDictionary = {}; 8158 8159 for (let m = 0, ml = morphAttribute.length; m < ml; m++) { 8160 const name = morphAttribute[m].name || String(m); 8161 this.morphTargetInfluences.push(0); 8162 this.morphTargetDictionary[name] = m; 8163 } 8164 } 8165 } 8166 } else { 8167 const morphTargets = geometry.morphTargets; 8168 8169 if (morphTargets !== undefined && morphTargets.length > 0) { 8170 console.error('THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.'); 8171 } 8172 } 8173 } 8174 8175 raycast(raycaster, intersects) { 8176 const geometry = this.geometry; 8177 const material = this.material; 8178 const matrixWorld = this.matrixWorld; 8179 if (material === undefined) return; // Checking boundingSphere distance to ray 8180 8181 if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); 8182 8183 _sphere$3.copy(geometry.boundingSphere); 8184 8185 _sphere$3.applyMatrix4(matrixWorld); 8186 8187 if (raycaster.ray.intersectsSphere(_sphere$3) === false) return; // 8188 8189 _inverseMatrix$2.copy(matrixWorld).invert(); 8190 8191 _ray$2.copy(raycaster.ray).applyMatrix4(_inverseMatrix$2); // Check boundingBox before continuing 8192 8193 8194 if (geometry.boundingBox !== null) { 8195 if (_ray$2.intersectsBox(geometry.boundingBox) === false) return; 8196 } 8197 8198 let intersection; 8199 8200 if (geometry.isBufferGeometry) { 8201 const index = geometry.index; 8202 const position = geometry.attributes.position; 8203 const morphPosition = geometry.morphAttributes.position; 8204 const morphTargetsRelative = geometry.morphTargetsRelative; 8205 const uv = geometry.attributes.uv; 8206 const uv2 = geometry.attributes.uv2; 8207 const groups = geometry.groups; 8208 const drawRange = geometry.drawRange; 8209 8210 if (index !== null) { 8211 // indexed buffer geometry 8212 if (Array.isArray(material)) { 8213 for (let i = 0, il = groups.length; i < il; i++) { 8214 const group = groups[i]; 8215 const groupMaterial = material[group.materialIndex]; 8216 const start = Math.max(group.start, drawRange.start); 8217 const end = Math.min(index.count, Math.min(group.start + group.count, drawRange.start + drawRange.count)); 8218 8219 for (let j = start, jl = end; j < jl; j += 3) { 8220 const a = index.getX(j); 8221 const b = index.getX(j + 1); 8222 const c = index.getX(j + 2); 8223 intersection = checkBufferGeometryIntersection(this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c); 8224 8225 if (intersection) { 8226 intersection.faceIndex = Math.floor(j / 3); // triangle number in indexed buffer semantics 8227 8228 intersection.face.materialIndex = group.materialIndex; 8229 intersects.push(intersection); 8230 } 8231 } 8232 } 8233 } else { 8234 const start = Math.max(0, drawRange.start); 8235 const end = Math.min(index.count, drawRange.start + drawRange.count); 8236 8237 for (let i = start, il = end; i < il; i += 3) { 8238 const a = index.getX(i); 8239 const b = index.getX(i + 1); 8240 const c = index.getX(i + 2); 8241 intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c); 8242 8243 if (intersection) { 8244 intersection.faceIndex = Math.floor(i / 3); // triangle number in indexed buffer semantics 8245 8246 intersects.push(intersection); 8247 } 8248 } 8249 } 8250 } else if (position !== undefined) { 8251 // non-indexed buffer geometry 8252 if (Array.isArray(material)) { 8253 for (let i = 0, il = groups.length; i < il; i++) { 8254 const group = groups[i]; 8255 const groupMaterial = material[group.materialIndex]; 8256 const start = Math.max(group.start, drawRange.start); 8257 const end = Math.min(position.count, Math.min(group.start + group.count, drawRange.start + drawRange.count)); 8258 8259 for (let j = start, jl = end; j < jl; j += 3) { 8260 const a = j; 8261 const b = j + 1; 8262 const c = j + 2; 8263 intersection = checkBufferGeometryIntersection(this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c); 8264 8265 if (intersection) { 8266 intersection.faceIndex = Math.floor(j / 3); // triangle number in non-indexed buffer semantics 8267 8268 intersection.face.materialIndex = group.materialIndex; 8269 intersects.push(intersection); 8270 } 8271 } 8272 } 8273 } else { 8274 const start = Math.max(0, drawRange.start); 8275 const end = Math.min(position.count, drawRange.start + drawRange.count); 8276 8277 for (let i = start, il = end; i < il; i += 3) { 8278 const a = i; 8279 const b = i + 1; 8280 const c = i + 2; 8281 intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c); 8282 8283 if (intersection) { 8284 intersection.faceIndex = Math.floor(i / 3); // triangle number in non-indexed buffer semantics 8285 8286 intersects.push(intersection); 8287 } 8288 } 8289 } 8290 } 8291 } else if (geometry.isGeometry) { 8292 console.error('THREE.Mesh.raycast() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.'); 8293 } 8294 } 8295 8296 } 8297 8298 Mesh.prototype.isMesh = true; 8299 8300 function checkIntersection(object, material, raycaster, ray, pA, pB, pC, point) { 8301 let intersect; 8302 8303 if (material.side === BackSide) { 8304 intersect = ray.intersectTriangle(pC, pB, pA, true, point); 8305 } else { 8306 intersect = ray.intersectTriangle(pA, pB, pC, material.side !== DoubleSide, point); 8307 } 8308 8309 if (intersect === null) return null; 8310 8311 _intersectionPointWorld.copy(point); 8312 8313 _intersectionPointWorld.applyMatrix4(object.matrixWorld); 8314 8315 const distance = raycaster.ray.origin.distanceTo(_intersectionPointWorld); 8316 if (distance < raycaster.near || distance > raycaster.far) return null; 8317 return { 8318 distance: distance, 8319 point: _intersectionPointWorld.clone(), 8320 object: object 8321 }; 8322 } 8323 8324 function checkBufferGeometryIntersection(object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c) { 8325 _vA$1.fromBufferAttribute(position, a); 8326 8327 _vB$1.fromBufferAttribute(position, b); 8328 8329 _vC$1.fromBufferAttribute(position, c); 8330 8331 const morphInfluences = object.morphTargetInfluences; 8332 8333 if (morphPosition && morphInfluences) { 8334 _morphA.set(0, 0, 0); 8335 8336 _morphB.set(0, 0, 0); 8337 8338 _morphC.set(0, 0, 0); 8339 8340 for (let i = 0, il = morphPosition.length; i < il; i++) { 8341 const influence = morphInfluences[i]; 8342 const morphAttribute = morphPosition[i]; 8343 if (influence === 0) continue; 8344 8345 _tempA.fromBufferAttribute(morphAttribute, a); 8346 8347 _tempB.fromBufferAttribute(morphAttribute, b); 8348 8349 _tempC.fromBufferAttribute(morphAttribute, c); 8350 8351 if (morphTargetsRelative) { 8352 _morphA.addScaledVector(_tempA, influence); 8353 8354 _morphB.addScaledVector(_tempB, influence); 8355 8356 _morphC.addScaledVector(_tempC, influence); 8357 } else { 8358 _morphA.addScaledVector(_tempA.sub(_vA$1), influence); 8359 8360 _morphB.addScaledVector(_tempB.sub(_vB$1), influence); 8361 8362 _morphC.addScaledVector(_tempC.sub(_vC$1), influence); 8363 } 8364 } 8365 8366 _vA$1.add(_morphA); 8367 8368 _vB$1.add(_morphB); 8369 8370 _vC$1.add(_morphC); 8371 } 8372 8373 if (object.isSkinnedMesh) { 8374 object.boneTransform(a, _vA$1); 8375 object.boneTransform(b, _vB$1); 8376 object.boneTransform(c, _vC$1); 8377 } 8378 8379 const intersection = checkIntersection(object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint); 8380 8381 if (intersection) { 8382 if (uv) { 8383 _uvA$1.fromBufferAttribute(uv, a); 8384 8385 _uvB$1.fromBufferAttribute(uv, b); 8386 8387 _uvC$1.fromBufferAttribute(uv, c); 8388 8389 intersection.uv = Triangle.getUV(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2()); 8390 } 8391 8392 if (uv2) { 8393 _uvA$1.fromBufferAttribute(uv2, a); 8394 8395 _uvB$1.fromBufferAttribute(uv2, b); 8396 8397 _uvC$1.fromBufferAttribute(uv2, c); 8398 8399 intersection.uv2 = Triangle.getUV(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2()); 8400 } 8401 8402 const face = { 8403 a: a, 8404 b: b, 8405 c: c, 8406 normal: new Vector3(), 8407 materialIndex: 0 8408 }; 8409 Triangle.getNormal(_vA$1, _vB$1, _vC$1, face.normal); 8410 intersection.face = face; 8411 } 8412 8413 return intersection; 8414 } 8415 8416 class BoxGeometry extends BufferGeometry { 8417 constructor(width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1) { 8418 super(); 8419 this.type = 'BoxGeometry'; 8420 this.parameters = { 8421 width: width, 8422 height: height, 8423 depth: depth, 8424 widthSegments: widthSegments, 8425 heightSegments: heightSegments, 8426 depthSegments: depthSegments 8427 }; 8428 const scope = this; // segments 8429 8430 widthSegments = Math.floor(widthSegments); 8431 heightSegments = Math.floor(heightSegments); 8432 depthSegments = Math.floor(depthSegments); // buffers 8433 8434 const indices = []; 8435 const vertices = []; 8436 const normals = []; 8437 const uvs = []; // helper variables 8438 8439 let numberOfVertices = 0; 8440 let groupStart = 0; // build each side of the box geometry 8441 8442 buildPlane('z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0); // px 8443 8444 buildPlane('z', 'y', 'x', 1, -1, depth, height, -width, depthSegments, heightSegments, 1); // nx 8445 8446 buildPlane('x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2); // py 8447 8448 buildPlane('x', 'z', 'y', 1, -1, width, depth, -height, widthSegments, depthSegments, 3); // ny 8449 8450 buildPlane('x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4); // pz 8451 8452 buildPlane('x', 'y', 'z', -1, -1, width, height, -depth, widthSegments, heightSegments, 5); // nz 8453 // build geometry 8454 8455 this.setIndex(indices); 8456 this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 8457 this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); 8458 this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); 8459 8460 function buildPlane(u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex) { 8461 const segmentWidth = width / gridX; 8462 const segmentHeight = height / gridY; 8463 const widthHalf = width / 2; 8464 const heightHalf = height / 2; 8465 const depthHalf = depth / 2; 8466 const gridX1 = gridX + 1; 8467 const gridY1 = gridY + 1; 8468 let vertexCounter = 0; 8469 let groupCount = 0; 8470 const vector = new Vector3(); // generate vertices, normals and uvs 8471 8472 for (let iy = 0; iy < gridY1; iy++) { 8473 const y = iy * segmentHeight - heightHalf; 8474 8475 for (let ix = 0; ix < gridX1; ix++) { 8476 const x = ix * segmentWidth - widthHalf; // set values to correct vector component 8477 8478 vector[u] = x * udir; 8479 vector[v] = y * vdir; 8480 vector[w] = depthHalf; // now apply vector to vertex buffer 8481 8482 vertices.push(vector.x, vector.y, vector.z); // set values to correct vector component 8483 8484 vector[u] = 0; 8485 vector[v] = 0; 8486 vector[w] = depth > 0 ? 1 : -1; // now apply vector to normal buffer 8487 8488 normals.push(vector.x, vector.y, vector.z); // uvs 8489 8490 uvs.push(ix / gridX); 8491 uvs.push(1 - iy / gridY); // counters 8492 8493 vertexCounter += 1; 8494 } 8495 } // indices 8496 // 1. you need three indices to draw a single face 8497 // 2. a single segment consists of two faces 8498 // 3. so we need to generate six (2*3) indices per segment 8499 8500 8501 for (let iy = 0; iy < gridY; iy++) { 8502 for (let ix = 0; ix < gridX; ix++) { 8503 const a = numberOfVertices + ix + gridX1 * iy; 8504 const b = numberOfVertices + ix + gridX1 * (iy + 1); 8505 const c = numberOfVertices + (ix + 1) + gridX1 * (iy + 1); 8506 const d = numberOfVertices + (ix + 1) + gridX1 * iy; // faces 8507 8508 indices.push(a, b, d); 8509 indices.push(b, c, d); // increase counter 8510 8511 groupCount += 6; 8512 } 8513 } // add a group to the geometry. this will ensure multi material support 8514 8515 8516 scope.addGroup(groupStart, groupCount, materialIndex); // calculate new start value for groups 8517 8518 groupStart += groupCount; // update total number of vertices 8519 8520 numberOfVertices += vertexCounter; 8521 } 8522 } 8523 8524 static fromJSON(data) { 8525 return new BoxGeometry(data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments); 8526 } 8527 8528 } 8529
vendor: 11,407 bytes, lines 8530-8951
8530 /** 8531 * Uniform Utilities 8532 */ 8533 function cloneUniforms(src) { 8534 const dst = {}; 8535 8536 for (const u in src) { 8537 dst[u] = {}; 8538 8539 for (const p in src[u]) { 8540 const property = src[u][p]; 8541 8542 if (property && (property.isColor || property.isMatrix3 || property.isMatrix4 || property.isVector2 || property.isVector3 || property.isVector4 || property.isTexture || property.isQuaternion)) { 8543 dst[u][p] = property.clone(); 8544 } else if (Array.isArray(property)) { 8545 dst[u][p] = property.slice(); 8546 } else { 8547 dst[u][p] = property; 8548 } 8549 } 8550 } 8551 8552 return dst; 8553 } 8554 function mergeUniforms(uniforms) { 8555 const merged = {}; 8556 8557 for (let u = 0; u < uniforms.length; u++) { 8558 const tmp = cloneUniforms(uniforms[u]); 8559 8560 for (const p in tmp) { 8561 merged[p] = tmp[p]; 8562 } 8563 } 8564 8565 return merged; 8566 } // Legacy 8567 8568 const UniformsUtils = { 8569 clone: cloneUniforms, 8570 merge: mergeUniforms 8571 }; 8572 8573 var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; 8574 8575 var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; 8576 8577 /** 8578 * parameters = { 8579 * defines: { "label" : "value" }, 8580 * uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } }, 8581 * 8582 * fragmentShader: <string>, 8583 * vertexShader: <string>, 8584 * 8585 * wireframe: <boolean>, 8586 * wireframeLinewidth: <float>, 8587 * 8588 * lights: <bool> 8589 * } 8590 */ 8591 8592 class ShaderMaterial extends Material { 8593 constructor(parameters) { 8594 super(); 8595 this.type = 'ShaderMaterial'; 8596 this.defines = {}; 8597 this.uniforms = {}; 8598 this.vertexShader = default_vertex; 8599 this.fragmentShader = default_fragment; 8600 this.linewidth = 1; 8601 this.wireframe = false; 8602 this.wireframeLinewidth = 1; 8603 this.fog = false; // set to use scene fog 8604 8605 this.lights = false; // set to use scene lights 8606 8607 this.clipping = false; // set to use user-defined clipping planes 8608 8609 this.extensions = { 8610 derivatives: false, 8611 // set to use derivatives 8612 fragDepth: false, 8613 // set to use fragment depth values 8614 drawBuffers: false, 8615 // set to use draw buffers 8616 shaderTextureLOD: false // set to use shader texture LOD 8617 8618 }; // When rendered geometry doesn't include these attributes but the material does, 8619 // use these default values in WebGL. This avoids errors when buffer data is missing. 8620 8621 this.defaultAttributeValues = { 8622 'color': [1, 1, 1], 8623 'uv': [0, 0], 8624 'uv2': [0, 0] 8625 }; 8626 this.index0AttributeName = undefined; 8627 this.uniformsNeedUpdate = false; 8628 this.glslVersion = null; 8629 8630 if (parameters !== undefined) { 8631 if (parameters.attributes !== undefined) { 8632 console.error('THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.'); 8633 } 8634 8635 this.setValues(parameters); 8636 } 8637 } 8638 8639 copy(source) { 8640 super.copy(source); 8641 this.fragmentShader = source.fragmentShader; 8642 this.vertexShader = source.vertexShader; 8643 this.uniforms = cloneUniforms(source.uniforms); 8644 this.defines = Object.assign({}, source.defines); 8645 this.wireframe = source.wireframe; 8646 this.wireframeLinewidth = source.wireframeLinewidth; 8647 this.lights = source.lights; 8648 this.clipping = source.clipping; 8649 this.extensions = Object.assign({}, source.extensions); 8650 this.glslVersion = source.glslVersion; 8651 return this; 8652 } 8653 8654 toJSON(meta) { 8655 const data = super.toJSON(meta); 8656 data.glslVersion = this.glslVersion; 8657 data.uniforms = {}; 8658 8659 for (const name in this.uniforms) { 8660 const uniform = this.uniforms[name]; 8661 const value = uniform.value; 8662 8663 if (value && value.isTexture) { 8664 data.uniforms[name] = { 8665 type: 't', 8666 value: value.toJSON(meta).uuid 8667 }; 8668 } else if (value && value.isColor) { 8669 data.uniforms[name] = { 8670 type: 'c', 8671 value: value.getHex() 8672 }; 8673 } else if (value && value.isVector2) { 8674 data.uniforms[name] = { 8675 type: 'v2', 8676 value: value.toArray() 8677 }; 8678 } else if (value && value.isVector3) { 8679 data.uniforms[name] = { 8680 type: 'v3', 8681 value: value.toArray() 8682 }; 8683 } else if (value && value.isVector4) { 8684 data.uniforms[name] = { 8685 type: 'v4', 8686 value: value.toArray() 8687 }; 8688 } else if (value && value.isMatrix3) { 8689 data.uniforms[name] = { 8690 type: 'm3', 8691 value: value.toArray() 8692 }; 8693 } else if (value && value.isMatrix4) { 8694 data.uniforms[name] = { 8695 type: 'm4', 8696 value: value.toArray() 8697 }; 8698 } else { 8699 data.uniforms[name] = { 8700 value: value 8701 }; // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far 8702 } 8703 } 8704 8705 if (Object.keys(this.defines).length > 0) data.defines = this.defines; 8706 data.vertexShader = this.vertexShader; 8707 data.fragmentShader = this.fragmentShader; 8708 const extensions = {}; 8709 8710 for (const key in this.extensions) { 8711 if (this.extensions[key] === true) extensions[key] = true; 8712 } 8713 8714 if (Object.keys(extensions).length > 0) data.extensions = extensions; 8715 return data; 8716 } 8717 8718 } 8719 8720 ShaderMaterial.prototype.isShaderMaterial = true; 8721 8722 class Camera extends Object3D { 8723 constructor() { 8724 super(); 8725 this.type = 'Camera'; 8726 this.matrixWorldInverse = new Matrix4(); 8727 this.projectionMatrix = new Matrix4(); 8728 this.projectionMatrixInverse = new Matrix4(); 8729 } 8730 8731 copy(source, recursive) { 8732 super.copy(source, recursive); 8733 this.matrixWorldInverse.copy(source.matrixWorldInverse); 8734 this.projectionMatrix.copy(source.projectionMatrix); 8735 this.projectionMatrixInverse.copy(source.projectionMatrixInverse); 8736 return this; 8737 } 8738 8739 getWorldDirection(target) { 8740 this.updateWorldMatrix(true, false); 8741 const e = this.matrixWorld.elements; 8742 return target.set(-e[8], -e[9], -e[10]).normalize(); 8743 } 8744 8745 updateMatrixWorld(force) { 8746 super.updateMatrixWorld(force); 8747 this.matrixWorldInverse.copy(this.matrixWorld).invert(); 8748 } 8749 8750 updateWorldMatrix(updateParents, updateChildren) { 8751 super.updateWorldMatrix(updateParents, updateChildren); 8752 this.matrixWorldInverse.copy(this.matrixWorld).invert(); 8753 } 8754 8755 clone() { 8756 return new this.constructor().copy(this); 8757 } 8758 8759 } 8760 8761 Camera.prototype.isCamera = true; 8762 8763 class PerspectiveCamera extends Camera { 8764 constructor(fov = 50, aspect = 1, near = 0.1, far = 2000) { 8765 super(); 8766 this.type = 'PerspectiveCamera'; 8767 this.fov = fov; 8768 this.zoom = 1; 8769 this.near = near; 8770 this.far = far; 8771 this.focus = 10; 8772 this.aspect = aspect; 8773 this.view = null; 8774 this.filmGauge = 35; // width of the film (default in millimeters) 8775 8776 this.filmOffset = 0; // horizontal film offset (same unit as gauge) 8777 8778 this.updateProjectionMatrix(); 8779 } 8780 8781 copy(source, recursive) { 8782 super.copy(source, recursive); 8783 this.fov = source.fov; 8784 this.zoom = source.zoom; 8785 this.near = source.near; 8786 this.far = source.far; 8787 this.focus = source.focus; 8788 this.aspect = source.aspect; 8789 this.view = source.view === null ? null : Object.assign({}, source.view); 8790 this.filmGauge = source.filmGauge; 8791 this.filmOffset = source.filmOffset; 8792 return this; 8793 } 8794 /** 8795 * Sets the FOV by focal length in respect to the current .filmGauge. 8796 * 8797 * The default film gauge is 35, so that the focal length can be specified for 8798 * a 35mm (full frame) camera. 8799 * 8800 * Values for focal length and film gauge must have the same unit. 8801 */ 8802 8803 8804 setFocalLength(focalLength) { 8805 /** see {@link http://www.bobatkins.com/photography/technical/field_of_view.html} */ 8806 const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; 8807 this.fov = RAD2DEG * 2 * Math.atan(vExtentSlope); 8808 this.updateProjectionMatrix(); 8809 } 8810 /** 8811 * Calculates the focal length from the current .fov and .filmGauge. 8812 */ 8813 8814 8815 getFocalLength() { 8816 const vExtentSlope = Math.tan(DEG2RAD * 0.5 * this.fov); 8817 return 0.5 * this.getFilmHeight() / vExtentSlope; 8818 } 8819 8820 getEffectiveFOV() { 8821 return RAD2DEG * 2 * Math.atan(Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom); 8822 } 8823 8824 getFilmWidth() { 8825 // film not completely covered in portrait format (aspect < 1) 8826 return this.filmGauge * Math.min(this.aspect, 1); 8827 } 8828 8829 getFilmHeight() { 8830 // film not completely covered in landscape format (aspect > 1) 8831 return this.filmGauge / Math.max(this.aspect, 1); 8832 } 8833 /** 8834 * Sets an offset in a larger frustum. This is useful for multi-window or 8835 * multi-monitor/multi-machine setups. 8836 * 8837 * For example, if you have 3x2 monitors and each monitor is 1920x1080 and 8838 * the monitors are in grid like this 8839 * 8840 * +---+---+---+ 8841 * | A | B | C | 8842 * +---+---+---+ 8843 * | D | E | F | 8844 * +---+---+---+ 8845 * 8846 * then for each monitor you would call it like this 8847 * 8848 * const w = 1920; 8849 * const h = 1080; 8850 * const fullWidth = w * 3; 8851 * const fullHeight = h * 2; 8852 * 8853 * --A-- 8854 * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); 8855 * --B-- 8856 * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); 8857 * --C-- 8858 * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); 8859 * --D-- 8860 * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); 8861 * --E-- 8862 * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); 8863 * --F-- 8864 * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); 8865 * 8866 * Note there is no reason monitors have to be the same size or in a grid. 8867 */ 8868 8869 8870 setViewOffset(fullWidth, fullHeight, x, y, width, height) { 8871 this.aspect = fullWidth / fullHeight; 8872 8873 if (this.view === null) { 8874 this.view = { 8875 enabled: true, 8876 fullWidth: 1, 8877 fullHeight: 1, 8878 offsetX: 0, 8879 offsetY: 0, 8880 width: 1, 8881 height: 1 8882 }; 8883 } 8884 8885 this.view.enabled = true; 8886 this.view.fullWidth = fullWidth; 8887 this.view.fullHeight = fullHeight; 8888 this.view.offsetX = x; 8889 this.view.offsetY = y; 8890 this.view.width = width; 8891 this.view.height = height; 8892 this.updateProjectionMatrix(); 8893 } 8894 8895 clearViewOffset() { 8896 if (this.view !== null) { 8897 this.view.enabled = false; 8898 } 8899 8900 this.updateProjectionMatrix(); 8901 } 8902 8903 updateProjectionMatrix() { 8904 const near = this.near; 8905 let top = near * Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom; 8906 let height = 2 * top; 8907 let width = this.aspect * height; 8908 let left = -0.5 * width; 8909 const view = this.view; 8910 8911 if (this.view !== null && this.view.enabled) { 8912 const fullWidth = view.fullWidth, 8913 fullHeight = view.fullHeight; 8914 left += view.offsetX * width / fullWidth; 8915 top -= view.offsetY * height / fullHeight; 8916 width *= view.width / fullWidth; 8917 height *= view.height / fullHeight; 8918 } 8919 8920 const skew = this.filmOffset; 8921 if (skew !== 0) left += near * skew / this.getFilmWidth(); 8922 this.projectionMatrix.makePerspective(left, left + width, top, top - height, near, this.far); 8923 this.projectionMatrixInverse.copy(this.projectionMatrix).invert(); 8924 } 8925 8926 toJSON(meta) { 8927 const data = super.toJSON(meta); 8928 data.object.fov = this.fov; 8929 data.object.zoom = this.zoom; 8930 data.object.near = this.near; 8931 data.object.far = this.far; 8932 data.object.focus = this.focus; 8933 data.object.aspect = this.aspect; 8934 if (this.view !== null) data.object.view = Object.assign({}, this.view); 8935 data.object.filmGauge = this.filmGauge; 8936 data.object.filmOffset = this.filmOffset; 8937 return data; 8938 } 8939 8940 } 8941 8942 PerspectiveCamera.prototype.isPerspectiveCamera = true; 8943 8944 const fov = 90, 8945 aspect = 1; 8946 8947 class CubeCamera extends Object3D { 8948 constructor(near, far, renderTarget) { 8949 super(); 8950 this.type = 'CubeCamera'; 8951
8952 if (renderTarget.isWebGLCubeRenderTarget !== true) { 8953 console.error('THREE.CubeCamera: The constructor now expects an instance of WebGLCubeRenderTarget as third parameter.'); 8954 return; 8955 } 8956 8957 this.renderTarget = renderTarget; 8958 const cameraPX = new PerspectiveCamera(fov, aspect, near, far); 8959 cameraPX.layers = this.layers; 8960 cameraPX.up.set(0, -1, 0); 8961 cameraPX.lookAt(new Vector3(1, 0, 0)); 8962 this.add(cameraPX); 8963 const cameraNX = new PerspectiveCamera(fov, aspect, near, far); 8964 cameraNX.layers = this.layers; 8965 cameraNX.up.set(0, -1, 0); 8966 cameraNX.lookAt(new Vector3(-1, 0, 0)); 8967 this.add(cameraNX); 8968 const cameraPY = new PerspectiveCamera(fov, aspect, near, far); 8969 cameraPY.layers = this.layers; 8970 cameraPY.up.set(0, 0, 1); 8971 cameraPY.lookAt(new Vector3(0, 1, 0)); 8972 this.add(cameraPY); 8973 const cameraNY = new PerspectiveCamera(fov, aspect, near, far); 8974 cameraNY.layers = this.layers; 8975 cameraNY.up.set(0, 0, -1); 8976 cameraNY.lookAt(new Vector3(0, -1, 0)); 8977 this.add(cameraNY); 8978 const cameraPZ = new PerspectiveCamera(fov, aspect, near, far); 8979 cameraPZ.layers = this.layers; 8980 cameraPZ.up.set(0, -1, 0); 8981 cameraPZ.lookAt(new Vector3(0, 0, 1)); 8982 this.add(cameraPZ); 8983 const cameraNZ = new PerspectiveCamera(fov, aspect, near, far); 8984 cameraNZ.layers = this.layers; 8985 cameraNZ.up.set(0, -1, 0); 8986 cameraNZ.lookAt(new Vector3(0, 0, -1)); 8987 this.add(cameraNZ); 8988 } 8989 8990 update(renderer, scene) { 8991 if (this.parent === null) this.updateMatrixWorld(); 8992 const renderTarget = this.renderTarget; 8993 const [cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ] = this.children; 8994 const currentXrEnabled = renderer.xr.enabled; 8995 const currentRenderTarget = renderer.getRenderTarget(); 8996 renderer.xr.enabled = false; 8997 const generateMipmaps = renderTarget.texture.generateMipmaps; 8998 renderTarget.texture.generateMipmaps = false; 8999 renderer.setRenderTarget(renderTarget, 0); 9000 renderer.render(scene, cameraPX); 9001 renderer.setRenderTarget(renderTarget, 1); 9002 renderer.render(scene, cameraNX); 9003 renderer.setRenderTarget(renderTarget, 2); 9004 renderer.render(scene, cameraPY); 9005 renderer.setRenderTarget(renderTarget, 3); 9006 renderer.render(scene, cameraNY); 9007 renderer.setRenderTarget(renderTarget, 4); 9008 renderer.render(scene, cameraPZ); 9009 renderTarget.texture.generateMipmaps = generateMipmaps; 9010 renderer.setRenderTarget(renderTarget, 5); 9011 renderer.render(scene, cameraNZ); 9012 renderer.setRenderTarget(currentRenderTarget); 9013 renderer.xr.enabled = currentXrEnabled; 9014 } 9015 9016 } 9017 9018 class CubeTexture extends Texture { 9019 constructor(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding) { 9020 images = images !== undefined ? images : []; 9021 mapping = mapping !== undefined ? mapping : CubeReflectionMapping; 9022 super(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding); 9023 this.flipY = false; 9024 } 9025 9026 get images() { 9027 return this.image; 9028 } 9029 9030 set images(value) { 9031 this.image = value; 9032 } 9033 9034 } 9035 9036 CubeTexture.prototype.isCubeTexture = true; 9037 9038 class WebGLCubeRenderTarget extends WebGLRenderTarget { 9039 constructor(size, options, dummy) { 9040 if (Number.isInteger(options)) { 9041 console.warn('THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )'); 9042 options = dummy; 9043 } 9044 9045 super(size, size, options); 9046 options = options || {}; // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) 9047 // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, 9048 // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly. 9049 // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped 9050 // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture 9051 // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures). 9052 9053 this.texture = new CubeTexture(undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding); 9054 this.texture.isRenderTargetTexture = true; 9055 this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;
vendor: 4,431 bytes, lines 9056-9237
9056 this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; 9057 this.texture._needsFlipEnvMap = false; 9058 } 9059 9060 fromEquirectangularTexture(renderer, texture) { 9061 this.texture.type = texture.type; 9062 this.texture.format = RGBAFormat; // see #18859 9063 9064 this.texture.encoding = texture.encoding; 9065 this.texture.generateMipmaps = texture.generateMipmaps; 9066 this.texture.minFilter = texture.minFilter; 9067 this.texture.magFilter = texture.magFilter; 9068 const shader = { 9069 uniforms: { 9070 tEquirect: { 9071 value: null 9072 } 9073 }, 9074 vertexShader: 9075 /* glsl */ 9076 ` 9077 9078 varying vec3 vWorldDirection; 9079 9080 vec3 transformDirection( in vec3 dir, in mat4 matrix ) { 9081 9082 return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); 9083 9084 } 9085 9086 void main() { 9087 9088 vWorldDirection = transformDirection( position, modelMatrix ); 9089 9090 #include <begin_vertex> 9091 #include <project_vertex> 9092 9093 } 9094 `, 9095 fragmentShader: 9096 /* glsl */ 9097 ` 9098 9099 uniform sampler2D tEquirect; 9100 9101 varying vec3 vWorldDirection; 9102 9103 #include <common> 9104 9105 void main() { 9106 9107 vec3 direction = normalize( vWorldDirection ); 9108 9109 vec2 sampleUV = equirectUv( direction ); 9110 9111 gl_FragColor = texture2D( tEquirect, sampleUV ); 9112 9113 } 9114 ` 9115 }; 9116 const geometry = new BoxGeometry(5, 5, 5); 9117 const material = new ShaderMaterial({ 9118 name: 'CubemapFromEquirect', 9119 uniforms: cloneUniforms(shader.uniforms), 9120 vertexShader: shader.vertexShader, 9121 fragmentShader: shader.fragmentShader, 9122 side: BackSide, 9123 blending: NoBlending 9124 }); 9125 material.uniforms.tEquirect.value = texture; 9126 const mesh = new Mesh(geometry, material); 9127 const currentMinFilter = texture.minFilter; // Avoid blurred poles 9128 9129 if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter; 9130 const camera = new CubeCamera(1, 10, this); 9131 camera.update(renderer, mesh); 9132 texture.minFilter = currentMinFilter; 9133 mesh.geometry.dispose(); 9134 mesh.material.dispose(); 9135 return this; 9136 } 9137 9138 clear(renderer, color, depth, stencil) { 9139 const currentRenderTarget = renderer.getRenderTarget(); 9140 9141 for (let i = 0; i < 6; i++) { 9142 renderer.setRenderTarget(this, i); 9143 renderer.clear(color, depth, stencil); 9144 } 9145 9146 renderer.setRenderTarget(currentRenderTarget); 9147 } 9148 9149 } 9150 9151 WebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true; 9152 9153 const _vector1 = /*@__PURE__*/new Vector3(); 9154 9155 const _vector2 = /*@__PURE__*/new Vector3(); 9156 9157 const _normalMatrix = /*@__PURE__*/new Matrix3(); 9158 9159 class Plane { 9160 constructor(normal = new Vector3(1, 0, 0), constant = 0) { 9161 // normal is assumed to be normalized 9162 this.normal = normal; 9163 this.constant = constant; 9164 } 9165 9166 set(normal, constant) { 9167 this.normal.copy(normal); 9168 this.constant = constant; 9169 return this; 9170 } 9171 9172 setComponents(x, y, z, w) { 9173 this.normal.set(x, y, z); 9174 this.constant = w; 9175 return this; 9176 } 9177 9178 setFromNormalAndCoplanarPoint(normal, point) { 9179 this.normal.copy(normal); 9180 this.constant = -point.dot(this.normal); 9181 return this; 9182 } 9183 9184 setFromCoplanarPoints(a, b, c) { 9185 const normal = _vector1.subVectors(c, b).cross(_vector2.subVectors(a, b)).normalize(); // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? 9186 9187 9188 this.setFromNormalAndCoplanarPoint(normal, a); 9189 return this; 9190 } 9191 9192 copy(plane) { 9193 this.normal.copy(plane.normal); 9194 this.constant = plane.constant; 9195 return this; 9196 } 9197 9198 normalize() { 9199 // Note: will lead to a divide by zero if the plane is invalid. 9200 const inverseNormalLength = 1.0 / this.normal.length(); 9201 this.normal.multiplyScalar(inverseNormalLength); 9202 this.constant *= inverseNormalLength; 9203 return this; 9204 } 9205 9206 negate() { 9207 this.constant *= -1; 9208 this.normal.negate(); 9209 return this; 9210 } 9211 9212 distanceToPoint(point) { 9213 return this.normal.dot(point) + this.constant; 9214 } 9215 9216 distanceToSphere(sphere) { 9217 return this.distanceToPoint(sphere.center) - sphere.radius; 9218 } 9219 9220 projectPoint(point, target) { 9221 return target.copy(this.normal).multiplyScalar(-this.distanceToPoint(point)).add(point); 9222 } 9223 9224 intersectLine(line, target) { 9225 const direction = line.delta(_vector1); 9226 const denominator = this.normal.dot(direction); 9227 9228 if (denominator === 0) { 9229 // line is coplanar, return origin 9230 if (this.distanceToPoint(line.start) === 0) { 9231 return target.copy(line.start); 9232 } // Unsure if this is the correct method to handle this case. 9233 9234 9235 return null; 9236 } 9237
vendor: 4,188 bytes, lines 9238-9396
9238 const t = -(line.start.dot(this.normal) + this.constant) / denominator; 9239 9240 if (t < 0 || t > 1) { 9241 return null; 9242 } 9243 9244 return target.copy(direction).multiplyScalar(t).add(line.start); 9245 } 9246 9247 intersectsLine(line) { 9248 // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. 9249 const startSign = this.distanceToPoint(line.start); 9250 const endSign = this.distanceToPoint(line.end); 9251 return startSign < 0 && endSign > 0 || endSign < 0 && startSign > 0; 9252 } 9253 9254 intersectsBox(box) { 9255 return box.intersectsPlane(this); 9256 } 9257 9258 intersectsSphere(sphere) { 9259 return sphere.intersectsPlane(this); 9260 } 9261 9262 coplanarPoint(target) { 9263 return target.copy(this.normal).multiplyScalar(-this.constant); 9264 } 9265 9266 applyMatrix4(matrix, optionalNormalMatrix) { 9267 const normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix(matrix); 9268 9269 const referencePoint = this.coplanarPoint(_vector1).applyMatrix4(matrix); 9270 const normal = this.normal.applyMatrix3(normalMatrix).normalize(); 9271 this.constant = -referencePoint.dot(normal); 9272 return this; 9273 } 9274 9275 translate(offset) { 9276 this.constant -= offset.dot(this.normal); 9277 return this; 9278 } 9279 9280 equals(plane) { 9281 return plane.normal.equals(this.normal) && plane.constant === this.constant; 9282 } 9283 9284 clone() { 9285 return new this.constructor().copy(this); 9286 } 9287 9288 } 9289 9290 Plane.prototype.isPlane = true; 9291 9292 const _sphere$2 = /*@__PURE__*/new Sphere(); 9293 9294 const _vector$7 = /*@__PURE__*/new Vector3(); 9295 9296 class Frustum { 9297 constructor(p0 = new Plane(), p1 = new Plane(), p2 = new Plane(), p3 = new Plane(), p4 = new Plane(), p5 = new Plane()) { 9298 this.planes = [p0, p1, p2, p3, p4, p5]; 9299 } 9300 9301 set(p0, p1, p2, p3, p4, p5) { 9302 const planes = this.planes; 9303 planes[0].copy(p0); 9304 planes[1].copy(p1); 9305 planes[2].copy(p2); 9306 planes[3].copy(p3); 9307 planes[4].copy(p4); 9308 planes[5].copy(p5); 9309 return this; 9310 } 9311 9312 copy(frustum) { 9313 const planes = this.planes; 9314 9315 for (let i = 0; i < 6; i++) { 9316 planes[i].copy(frustum.planes[i]); 9317 } 9318 9319 return this; 9320 } 9321 9322 setFromProjectionMatrix(m) { 9323 const planes = this.planes; 9324 const me = m.elements; 9325 const me0 = me[0], 9326 me1 = me[1], 9327 me2 = me[2], 9328 me3 = me[3]; 9329 const me4 = me[4], 9330 me5 = me[5], 9331 me6 = me[6], 9332 me7 = me[7]; 9333 const me8 = me[8], 9334 me9 = me[9], 9335 me10 = me[10], 9336 me11 = me[11]; 9337 const me12 = me[12], 9338 me13 = me[13], 9339 me14 = me[14], 9340 me15 = me[15]; 9341 planes[0].setComponents(me3 - me0, me7 - me4, me11 - me8, me15 - me12).normalize(); 9342 planes[1].setComponents(me3 + me0, me7 + me4, me11 + me8, me15 + me12).normalize(); 9343 planes[2].setComponents(me3 + me1, me7 + me5, me11 + me9, me15 + me13).normalize(); 9344 planes[3].setComponents(me3 - me1, me7 - me5, me11 - me9, me15 - me13).normalize(); 9345 planes[4].setComponents(me3 - me2, me7 - me6, me11 - me10, me15 - me14).normalize(); 9346 planes[5].setComponents(me3 + me2, me7 + me6, me11 + me10, me15 + me14).normalize(); 9347 return this; 9348 } 9349 9350 intersectsObject(object) { 9351 const geometry = object.geometry; 9352 if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); 9353 9354 _sphere$2.copy(geometry.boundingSphere).applyMatrix4(object.matrixWorld); 9355 9356 return this.intersectsSphere(_sphere$2); 9357 } 9358 9359 intersectsSprite(sprite) { 9360 _sphere$2.center.set(0, 0, 0); 9361 9362 _sphere$2.radius = 0.7071067811865476; 9363 9364 _sphere$2.applyMatrix4(sprite.matrixWorld); 9365 9366 return this.intersectsSphere(_sphere$2); 9367 } 9368 9369 intersectsSphere(sphere) { 9370 const planes = this.planes; 9371 const center = sphere.center; 9372 const negRadius = -sphere.radius; 9373 9374 for (let i = 0; i < 6; i++) { 9375 const distance = planes[i].distanceToPoint(center); 9376 9377 if (distance < negRadius) { 9378 return false; 9379 } 9380 } 9381 9382 return true; 9383 } 9384 9385 intersectsBox(box) { 9386 const planes = this.planes; 9387 9388 for (let i = 0; i < 6; i++) { 9389 const plane = planes[i]; // corner at max distance 9390 9391 _vector$7.x = plane.normal.x > 0 ? box.max.x : box.min.x; 9392 _vector$7.y = plane.normal.y > 0 ? box.max.y : box.min.y; 9393 _vector$7.z = plane.normal.z > 0 ? box.max.z : box.min.z; 9394 9395 if (plane.distanceToPoint(_vector$7) < 0) { 9396 return false;
vendor: 8,848 bytes, lines 9397-9645
9397 } 9398 } 9399 9400 return true; 9401 } 9402 9403 containsPoint(point) { 9404 const planes = this.planes; 9405 9406 for (let i = 0; i < 6; i++) { 9407 if (planes[i].distanceToPoint(point) < 0) { 9408 return false; 9409 } 9410 } 9411 9412 return true; 9413 } 9414 9415 clone() { 9416 return new this.constructor().copy(this); 9417 } 9418 9419 } 9420 9421 function WebGLAnimation() { 9422 let context = null; 9423 let isAnimating = false; 9424 let animationLoop = null; 9425 let requestId = null; 9426 9427 function onAnimationFrame(time, frame) { 9428 animationLoop(time, frame); 9429 requestId = context.requestAnimationFrame(onAnimationFrame); 9430 } 9431 9432 return { 9433 start: function () { 9434 if (isAnimating === true) return; 9435 if (animationLoop === null) return; 9436 requestId = context.requestAnimationFrame(onAnimationFrame); 9437 isAnimating = true; 9438 }, 9439 stop: function () { 9440 context.cancelAnimationFrame(requestId); 9441 isAnimating = false; 9442 }, 9443 setAnimationLoop: function (callback) { 9444 animationLoop = callback; 9445 }, 9446 setContext: function (value) { 9447 context = value; 9448 } 9449 }; 9450 } 9451 9452 function WebGLAttributes(gl, capabilities) { 9453 const isWebGL2 = capabilities.isWebGL2; 9454 const buffers = new WeakMap(); 9455 9456 function createBuffer(attribute, bufferType) { 9457 const array = attribute.array; 9458 const usage = attribute.usage; 9459 const buffer = gl.createBuffer(); 9460 gl.bindBuffer(bufferType, buffer); 9461 gl.bufferData(bufferType, array, usage); 9462 attribute.onUploadCallback(); 9463 let type = gl.FLOAT; 9464 9465 if (array instanceof Float32Array) { 9466 type = gl.FLOAT; 9467 } else if (array instanceof Float64Array) { 9468 console.warn('THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.'); 9469 } else if (array instanceof Uint16Array) { 9470 if (attribute.isFloat16BufferAttribute) { 9471 if (isWebGL2) { 9472 type = gl.HALF_FLOAT; 9473 } else { 9474 console.warn('THREE.WebGLAttributes: Usage of Float16BufferAttribute requires WebGL2.'); 9475 } 9476 } else { 9477 type = gl.UNSIGNED_SHORT; 9478 } 9479 } else if (array instanceof Int16Array) { 9480 type = gl.SHORT; 9481 } else if (array instanceof Uint32Array) { 9482 type = gl.UNSIGNED_INT; 9483 } else if (array instanceof Int32Array) { 9484 type = gl.INT; 9485 } else if (array instanceof Int8Array) { 9486 type = gl.BYTE; 9487 } else if (array instanceof Uint8Array) { 9488 type = gl.UNSIGNED_BYTE; 9489 } else if (array instanceof Uint8ClampedArray) { 9490 type = gl.UNSIGNED_BYTE; 9491 } 9492 9493 return { 9494 buffer: buffer, 9495 type: type, 9496 bytesPerElement: array.BYTES_PER_ELEMENT, 9497 version: attribute.version 9498 }; 9499 } 9500 9501 function updateBuffer(buffer, attribute, bufferType) { 9502 const array = attribute.array; 9503 const updateRange = attribute.updateRange; 9504 gl.bindBuffer(bufferType, buffer); 9505 9506 if (updateRange.count === -1) { 9507 // Not using update ranges 9508 gl.bufferSubData(bufferType, 0, array); 9509 } else { 9510 if (isWebGL2) { 9511 gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array, updateRange.offset, updateRange.count); 9512 } else { 9513 gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array.subarray(updateRange.offset, updateRange.offset + updateRange.count)); 9514 } 9515 9516 updateRange.count = -1; // reset range 9517 } 9518 } // 9519 9520 9521 function get(attribute) { 9522 if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; 9523 return buffers.get(attribute); 9524 } 9525 9526 function remove(attribute) { 9527 if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; 9528 const data = buffers.get(attribute); 9529 9530 if (data) { 9531 gl.deleteBuffer(data.buffer); 9532 buffers.delete(attribute); 9533 } 9534 } 9535 9536 function update(attribute, bufferType) { 9537 if (attribute.isGLBufferAttribute) { 9538 const cached = buffers.get(attribute); 9539 9540 if (!cached || cached.version < attribute.version) { 9541 buffers.set(attribute, { 9542 buffer: attribute.buffer, 9543 type: attribute.type, 9544 bytesPerElement: attribute.elementSize, 9545 version: attribute.version 9546 }); 9547 } 9548 9549 return; 9550 } 9551 9552 if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; 9553 const data = buffers.get(attribute); 9554 9555 if (data === undefined) { 9556 buffers.set(attribute, createBuffer(attribute, bufferType)); 9557 } else if (data.version < attribute.version) { 9558 updateBuffer(data.buffer, attribute, bufferType); 9559 data.version = attribute.version; 9560 } 9561 } 9562 9563 return { 9564 get: get, 9565 remove: remove, 9566 update: update 9567 }; 9568 } 9569 9570 class PlaneGeometry extends BufferGeometry { 9571 constructor(width = 1, height = 1, widthSegments = 1, heightSegments = 1) { 9572 super(); 9573 this.type = 'PlaneGeometry'; 9574 this.parameters = { 9575 width: width, 9576 height: height, 9577 widthSegments: widthSegments, 9578 heightSegments: heightSegments 9579 }; 9580 const width_half = width / 2; 9581 const height_half = height / 2; 9582 const gridX = Math.floor(widthSegments); 9583 const gridY = Math.floor(heightSegments); 9584 const gridX1 = gridX + 1; 9585 const gridY1 = gridY + 1; 9586 const segment_width = width / gridX; 9587 const segment_height = height / gridY; // 9588 9589 const indices = []; 9590 const vertices = []; 9591 const normals = []; 9592 const uvs = []; 9593 9594 for (let iy = 0; iy < gridY1; iy++) { 9595 const y = iy * segment_height - height_half; 9596 9597 for (let ix = 0; ix < gridX1; ix++) { 9598 const x = ix * segment_width - width_half; 9599 vertices.push(x, -y, 0); 9600 normals.push(0, 0, 1); 9601 uvs.push(ix / gridX); 9602 uvs.push(1 - iy / gridY); 9603 } 9604 } 9605 9606 for (let iy = 0; iy < gridY; iy++) { 9607 for (let ix = 0; ix < gridX; ix++) { 9608 const a = ix + gridX1 * iy; 9609 const b = ix + gridX1 * (iy + 1); 9610 const c = ix + 1 + gridX1 * (iy + 1); 9611 const d = ix + 1 + gridX1 * iy; 9612 indices.push(a, b, d); 9613 indices.push(b, c, d); 9614 } 9615 } 9616 9617 this.setIndex(indices); 9618 this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 9619 this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); 9620 this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); 9621 } 9622 9623 static fromJSON(data) { 9624 return new PlaneGeometry(data.width, data.height, data.widthSegments, data.heightSegments); 9625 } 9626 9627 } 9628 9629 var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif"; 9630 9631 var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; 9632 9633 var alphatest_fragment = "#ifdef USE_ALPHATEST\n\tif ( diffuseColor.a < alphaTest ) discard;\n#endif"; 9634 9635 var alphatest_pars_fragment = "#ifdef USE_ALPHATEST\n\tuniform float alphaTest;\n#endif"; 9636 9637 var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n\t#endif\n#endif"; 9638 9639 var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; 9640 9641 var begin_vertex = "vec3 transformed = vec3( position );"; 9642 9643 var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif"; 9644 9645 var bsdfs = "vec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( V * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;
9645\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_BlinnPhong( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, 1.0, dotVH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n\tfloat alpha = pow2( roughness );\n\tfloat invAlpha = 1.0 / alpha;\n\tfloat cos2h = dotNH * dotNH;\n\tfloat sin2h = max( 1.0 - cos2h, 0.0078125 );\n\treturn ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n\treturn saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\n}\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat D = D_Charlie( sheenRoughness, dotNH );\n\tfloat V = V_Neubelt( dotNV, dotNL );\n\treturn sheenColor * ( D * V );\n}\n#endif"; 9646 9647 var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 ) * faceDirection;\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif"; 9648 9649 var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif"; 9650 9651 var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; 9652 9653 var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif"; 9654 9655 var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif"; 9656 9657 var color_fragment = "#if defined( USE_COLOR_ALPHA )\n\tdiffuseColor *= vColor;\n#elif defined( USE_COLOR )\n\tdiffuseColor.rgb *= vColor;\n#endif"; 9658 9659 var color_pars_fragment = "#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR )\n\tvarying vec3 vColor;\n#endif"; 9660 9661 var color_pars_vertex = "#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvarying vec3 vColor;\n#endif"; 9662 9663 var color_vertex = "#if defined( USE_COLOR_ALPHA )\n\tvColor = vec4( 1.0 );\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvColor = vec3( 1.0 );\n#endif\n#ifdef USE_COLOR\n\tvColor *= color;\n#endif\n#ifdef USE_INSTANCING_COLOR\n\tvColor.xyz *= instanceColor.xyz;\n#endif"; 9664 9665 var common = "#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement( a ) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}"; 9666 9667 var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_maxMipLevel 8.0\n\t#define cubeUV_minMipLevel 4.0\n\t#define cubeUV_maxTileSize 256.0\n\t#define cubeUV_minTileSize 16.0\n\tfloat getFace( vec3 direction ) {\n\t\tvec3 absDirection = abs( direction );\n\t\tfloat face = - 1.0;\n\t\tif ( absDirection.x > absDirection.z ) {\n\t\t\tif ( absDirection.x > absDirection.y )\n\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t} else {\n\t\t\tif ( absDirection.z > absDirection.y )\n\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t}\n\t\treturn face;\n\t}\n\tvec2 getUV( vec3 direction, float face ) {\n\t\tvec2 uv;\n\t\tif ( face == 0.0 ) {\n\t\t\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 1.0 ) {\n\t\t\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n\t\t} else if ( face == 2.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\n\t\t} else if ( face == 3.0 ) {\n\t\t\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 4.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\n\t\t} else {\n\t\t\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\n\t\t}\n\t\treturn 0.5 * ( uv + 1.0 );\n\t}\n\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n\t\tfloat face = getFace( direction );\n\t\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n\t\tmipInt = max( mipInt, cubeUV_minMipLevel );\n\t\tfloat faceSize = exp2( mipInt );\n\t\tfloat texelSize = 1.0 / ( 3.0 * cubeUV_maxTileSize );\n\t\tvec2 uv = getUV( direction, face ) * ( faceSize - 1.0 ) + 0.5;\n\t\tif ( face > 2.0 ) {\n\t\t\tuv.y += faceSize;\n\t\t\tface -= 3.0;\n\t\t}\n\t\tuv.x += face * faceSize;\n\t\tif ( mipInt < cubeUV_maxMipLevel ) {\n\t\t\tuv.y += 2.0 * cubeUV_maxTileSize;\n\t\t}\n\t\tuv.y += filterInt * 2.0 * cubeUV_minTileSize;\n\t\tuv.x += 3.0 * max( 0.0, cubeUV_maxTileSize - 2.0 * faceSize );\n\t\tuv *= texelSize;\n\t\treturn texture2D( envMap, uv ).rgb;\n\t}\n\t#define r0 1.0\n\t#define v0 0.339\n\t#define m0 - 2.0\n\t#define r1 0.8\n\t#define v1 0.276\n\t#define m1 - 1.0\n\t#define r4 0.4\n\t#define v4 0.046\n\t#define m4 2.0\n\t#define r5 0.305\n\t#define v5 0.016\n\t#define m5 3.0\n\t#define r6 0.21\n\t#define v6 0.0038\n\t#define m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= r1 ) {\n\t\t\tmip = ( r0 - roughness ) * ( m1 - m0 ) / ( r0 - r1 ) + m0;\n\t\t} else if ( roughness >= r4 ) {\n\t\t\tmip = ( r1 - roughness ) * ( m4 - m1 ) / ( r1 - r4 ) + m1;\n\t\t} else if ( roughness >= r5 ) {\n\t\t\tmip = ( r4 - roughness ) * ( m5 - m4 ) / ( r4 - r5 ) + m4;\n\t\t} else if ( roughness >= r6 ) {\n\t\t\tmip = ( r5 - roughness ) * ( m6 - m5 ) / ( r5 - r6 ) + m5;\n\t\t} else {\n\t\t\tmip = - 2.0 * log2( 1.16 * roughness );\t\t}\n\t\treturn mip;\n\t}\n\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n\t\tfloat mip = clamp( roughnessToMip( roughness ), m0, cubeUV_maxMipLevel );\n\t\tfloat mipF = fract( mip );\n\t\tfloat mipInt = floor( mip );\n\t\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n\t\tif ( mipF == 0.0 ) {\n\t\t\treturn vec4( color0, 1.0 );\n\t\t} else {\n\t\t\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n\t\t\treturn vec4( mix( color0, color1, mipF ), 1.0 );\n\t\t}\n\t}\n#endif"; 9668 9669 var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_INSTANCING\n\tmat3 m = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );\n\ttransformedNormal = m * transformedNormal;\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif"; 9670 9671 var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif"; 9672 9673 var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + dis
9673placementBias );\n#endif"; 9674 9675 var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif"; 9676 9677 var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif"; 9678 9679 var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; 9680 9681 var encodings_pars_fragment = "vec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}"; 9682 9683 var envmap_fragment = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t\tenvColor = envMapTexelToLinear( envColor );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif"; 9684 9685 var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif"; 9686 9687 var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif"; 9688 9689 var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif"; 9690 9691 var envmap_vertex = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t}
9691 else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif"; 9692 9693 var fog_vertex = "#ifdef USE_FOG\n\tvFogDepth = - mvPosition.z;\n#endif"; 9694 9695 var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float vFogDepth;\n#endif"; 9696 9697 var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif"; 9698 9699 var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float vFogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif"; 9700 9701 var gradientmap_pars_fragment = "#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}"; 9702 9703 var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\tvec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tlightMapIrradiance *= PI;\n\t#endif\n\treflectedLight.indirectDiffuse += lightMapIrradiance;\n#endif"; 9704 9705 var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif"; 9706 9707 var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\nvIndirectFront += getAmbientLightIrradiance( ambientLightColor );\nvIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal );\n#ifdef DOUBLE_SIDED\n\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\n\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal );\n#endif\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointLightInfo( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotLightInfo( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalLightInfo( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal );\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif"; 9708 9709 var lights_pars_begin = "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {\n\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\t#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\tif ( cutoffDistance > 0.0 ) {\n\t\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\t}\n\t\treturn distanceFalloff;\n\t#else\n\t\tif ( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\t\treturn pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t\t}\n\t\treturn 1.0;\n\t#endif\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalLightInfo( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t}
9709\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif"; 9710 9711 var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP )\n\t#ifdef ENVMAP_MODE_REFRACTION\n\t\tuniform float refractionRatio;\n\t#endif\n\tvec3 getIBLIrradiance( const in vec3 normal ) {\n\t\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );\n\t\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\tvec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n\t\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 reflectVec;\n\t\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\t\treflectVec = reflect( - viewDir, normal );\n\t\t\t\treflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t\t#else\n\t\t\t\treflectVec = refract( - viewDir, normal, refractionRatio );\n\t\t\t#endif\n\t\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n\t\t\treturn envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n#endif"; 9712 9713 var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;"; 9714 9715 var lights_toon_pars_fragment = "varying vec3 vViewPosition;\nstruct ToonMaterial {\n\tvec3 diffuseColor;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon\n#define Material_LightProbeLOD( material )\t(0)"; 9716 9717 var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; 9718 9719 var lights_phong_pars_fragment = "varying vec3 vViewPosition;\nstruct BlinnPhongMaterial {\n\tvec3 diffuseColor;\n\tvec3 specularColor;\n\tfloat specularShininess;\n\tfloat specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot
9719( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)"; 9720 9721 var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\t#ifdef SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULARINTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vUv ).a;\n\t\t#endif\n\t\t#ifdef USE_SPECULARCOLORMAP\n\t\t\tspecularColorFactor *= specularColorMapTexelToLinear( texture2D( specularColorMap, vUv ) ).rgb;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( ior - 1.0 ) / ( ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;
9721\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tmaterial.sheenColor *= sheenColorMapTexelToLinear( texture2D( sheenColorMap, vUv ) ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vUv ).a;\n\t#endif\n#endif"; 9722 9723 var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n};\nvec3 clearcoatSpecular = vec3( 0.0 );\nvec3 sheenSpecular = vec3( 0.0 );\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness) {\
9723n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\tvec3 FssEss = specularColor * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.roughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness );\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );
9723\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tcomputeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}"; 9724 9725 var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef USE_CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointLightInfo( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotLightInfo( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalLightInfo( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry.normal );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif"; 9726 9727 var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getIBLIrradiance( geometry.normal );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getIBLRadiance( geometry.viewDir, geometry.normal, material.roughness );\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatRadiance += getIBLRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness );\n\t#endif\n#endif"; 9728 9729 var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif"; 9730 9731 var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; 9732 9733 var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif"; 9734 9735 var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t\tvarying float vIsPerspective;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif"; 9736 9737 var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n\t#else\n\t\tif ( isPerspectiveMatrix( projectionMatrix ) ) {\n\t\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\t\tgl_Position.z *= gl_Position.w;\n\t\t}\n\t#endif\n#endif"; 9738 9739 var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif"; 9740 9741 var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif"; 9742 9743 var map_particle_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n#endif\n#ifdef USE_MAP\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif"; 9744 9745 var map_particle_pars_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tuniform mat3 uvTransform;\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; 9746 9747 var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif"; 9748 9749 var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif"; 9750 9751 var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t\tif ( morphTargetInfluences[ i ] > 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1, 2 ) * morphTargetInfluences[ i ];\n\t\t}\n\t#else\n\t\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\n\t\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\n\t\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\n\t\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\n\t#endif\n#endif"; 9752 9753 var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\tuniform float morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tuniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\t\tuniform sampler2DArray morphTargetsTexture;\n\t\tuniform vec2 morphTargetsTextureSize;\n\t\tvec3 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset, const in int stride ) {\n\t\t\tfloat texelIndex = float( vertexIndex * stride + offset );\n\t\t\tfloat y = floor( texelIndex / morphTargetsTextureSize.x );\n\t\t\tfloat x = texelIndex - y * morphTargetsTextureSize.x;\n\t\t\tvec3 morphUV = vec3( ( x + 0.5 ) / morphTargetsTextureSize.x, y / morphTargetsTextureSize.y, morphTargetIndex );\n\t\t\treturn texture( morphTargetsTexture, morphUV ).xyz;\n\t\t}\n\t#else\n\t\t#ifndef USE_MORPHNORMALS\n\t\t\tuniform float morphTargetInfluences[ 8 ];\n\t\t#else\n\t\t\tuniform float morphTargetInfluences[ 4 ];\n\t\t#endif\n\t#endif\n#endif"; 9754 9755 var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t\t#ifndef USE_MORPHNORMALS\n\t\t\t\tif ( morphTargetInfluences[ i ] > 0.0 ) transformed += getMorph( gl_VertexID, i, 0, 1 ) * morphTargetInfluences[ i ];\n\t\t\t#else\n\t\t\t\tif ( morphTargetInfluences[ i ] > 0.0 ) transformed += getMorph( gl_VertexID, i, 0, 2 ) * morphTargetInfluences[ i ];\n\t\t\t#endif\n\t\t}\n\t#else\n\t\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\t\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\t\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\t\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t\t#ifndef USE_MORPHNORMALS\n\t\t\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\t\t\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\t\t\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\t\t\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t\t#endif\n\t#endif\n#endif"; 9756 9757 var normal_fragment_begin = "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * faceDirection;\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * faceDirection;\n\t\t\tbitangent = bitangent * faceDirection;\n\t\t#endif\n\t\t#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;"; 9758 9759 var normal_fragment_maps = "#ifdef OBJECTSPACE_NORMALMAP\n\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * faceDirection;\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\t#ifdef USE_TANGENT\n\t\tnormal = normalize( vTBN * mapN );
9759\n\t#else\n\t\tnormal = perturbNormal2Arb( - vViewPosition, normal, mapN, faceDirection );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif"; 9760 9761 var normal_pars_fragment = "#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif"; 9762 9763 var normal_pars_vertex = "#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif"; 9764 9765 var normal_vertex = "#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif"; 9766 9767 var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN, float faceDirection ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tvec3 N = surf_norm;\n\t\tvec3 q1perp = cross( q1, N );\n\t\tvec3 q0perp = cross( N, q0 );\n\t\tvec3 T = q1perp * st0.x + q0perp * st1.x;\n\t\tvec3 B = q1perp * st0.y + q0perp * st1.y;\n\t\tfloat det = max( dot( T, T ), dot( B, B ) );\n\t\tfloat scale = ( det == 0.0 ) ? 0.0 : faceDirection * inversesqrt( det );\n\t\treturn normalize( T * ( mapN.x * scale ) + B * ( mapN.y * scale ) + N * mapN.z );\n\t}\n#endif"; 9768 9769 var clearcoat_normal_fragment_begin = "#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif"; 9770 9771 var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\t#ifdef USE_TANGENT\n\t\tclearcoatNormal = normalize( vTBN * clearcoatMapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN, faceDirection );\n\t#endif\n#endif"; 9772 9773 var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif"; 9774 9775 var output_fragment = "#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= transmissionAlpha + 0.1;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );"; 9776 9777 var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nvec4 pack2HalfToRGBA( vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) );\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );\n}\nvec2 unpackRGBATo2Half( vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}"; 9778 9779 var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif"; 9780 9781 var project_vertex = "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;"; 9782 9783 var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; 9784 9785 var dithering_pars_fragment = "#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif"; 9786 9787 var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif"; 9788 9789 var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; 9790 9791 var shadowmap_pars_fragment =
vendor: 6,176 bytes, line 9791
9791"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx = texelSize.x;\n\t\t\tfloat dy = texelSize.y;\n\t\t\tvec2 uv = shadowCoord.xy;\n\t\t\tvec2 f = fract( uv * shadowMapSize + 0.5 );\n\t\t\tuv -= f * texelSize;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t\t
9791 texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t f.y )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif"; 9792 9793 var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif"; 9794 9795 var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS >
9795 0 || NUM_SPOT_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0\n\t\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\tvec4 shadowWorldPosition;\n\t#endif\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n#endif"; 9796 9797 var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}"; 9798 9799 var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif"; 9800 9801 var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform highp sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif"; 9802 9803 var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif"; 9804 9805 var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif"; 9806 9807 var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif"; 9808 9809 var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif"; 9810 9811 var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif"; 9812 9813 var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;
9813\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3( 1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108, 1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605, 1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }"; 9814 9815 var transmission_fragment = "#ifdef USE_TRANSMISSION\n\tfloat transmissionAlpha = 1.0;\n\tfloat transmissionFactor = transmission;\n\tfloat thicknessFactor = thickness;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\ttransmissionFactor *= texture2D( transmissionMap, vUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tthicknessFactor *= texture2D( thicknessMap, vUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmission = getIBLVolumeRefraction(\n\t\tn, v, roughnessFactor, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor,\n\t\tattenuationColor, attenuationDistance );\n\ttotalDiffuse = mix( totalDiffuse, transmission.rgb, transmissionFactor );\n\ttransmissionAlpha = mix( transmissionAlpha, transmission.a, transmissionFactor );\n#endif"; 9816 9817 var transmission_pars_fragment = "#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tvec3 getVolumeTransmissionRay( vec3 n, vec3 v, float thickness, float ior, mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( float roughness, float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( vec2 fragCoord, float roughness, float ior ) {\n\t\tfloat framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\treturn texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#else\n\t\t\treturn texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#endif\n\t}\n\tvec3 applyVolumeAttenuation( vec3 radiance, float transmissionDistance, vec3 attenuationColor, float attenuationDistance ) {\n\t\tif ( attenuationDistance == 0.0 ) {\n\t\t\treturn radiance;\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance * radiance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( vec3 n, vec3 v, float roughness, vec3 diffuseColor, vec3 specularColor, float specularF90,\n\t\tvec3 position, mat4 modelMatrix, mat4 viewMatrix, mat4 projMatrix, float ior, float thickness,\n\t\tvec3 attenuationColor, float attenuationDistance ) {\n\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\trefractionCoords += 1.0;\n\t\trefractionCoords /= 2.0;\n\t\tvec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\tvec3 attenuatedColor = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );\n\t}\n#endif"; 9818 9819 var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif"; 9820 9821 var uv_pars_vertex = "#ifdef USE_UV\n\t#ifdef UVS_VERTEX_ONLY\n\t\tvec2 vUv;\n\t#else\n\t\tvarying vec2 vUv;\n\t#endif\n\tuniform mat3 uvTransform;\n#endif"; 9822 9823 var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; 9824 9825 var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; 9826 9827 var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n\tuniform mat3 uv2Transform;\n#endif"; 9828 9829 var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif"; 9830 9831 var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION )\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif"; 9832 9833 const vertex$g = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}"; 9834 const fragment$g = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}"; 9835 9836 const vertex$f = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\tgl_Position.z = gl_Position.w;\n}"; 9837 const fragment$f = "#include <envmap_common_pars_fragment>\nuniform float opacity;\nvarying vec3 vWorldDirection;\n#include <cube_uv_reflection_fragment>\nvoid main() {\n\tvec3 vReflect = vWorldDirection;\n\t#include <envmap_fragment>\n\tgl_FragColor = envColor;\n\tgl_FragColor.a *= opacity;\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}"; 9838 9839 const vertex$e = "#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvHighPrecisionZW = gl_Position.zw;\n}"; 9840 const fragment$e = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#endif\n}"; 9841 9842 const vertex$d = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}"; 9843 const fragment$d = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}"; 9844 9845 const vertex$c = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}"; 9846 const fragment$c = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV = equirectUv( direction );\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}"; 9847 9848 const vertex$b = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\tvLineDistance = scale * lineDistance;\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}"; 9849 const fragment$b = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}"; 9850 9851 const vertex$a = "#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinbase_vertex>\n\t\t#include <skinnormal_vertex>\n\t\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}"; 9852 const fragment$a = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <envmap_fragment>\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}"; 9853 9854 const vertex$9 = "#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <lights_lambert_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}"; 9855 const fragment$9 = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLi
9855ghtBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <emissivemap_fragment>\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include <lightmap_fragment>\n\treflectedLight.indirectDiffuse *= BRDF_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}"; 9856 9857 const vertex$8 = "#define MATCAP\nvarying vec3 vViewPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <color_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n\tvViewPosition = - mvPosition.xyz;\n}"; 9858 const fragment$8 = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <fog_pars_fragment>\n#include <normal_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;
9858\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t\tmatcapColor = matcapTexelToLinear( matcapColor );\n\t#else\n\t\tvec4 matcapColor = vec4( 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}"; 9859 9860 const vertex$7 = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}"; 9861 const fragment$7 = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <normal_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}"; 9862 9863 const vertex$6 = "#define PHONG\nvarying vec3 vViewPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}"; 9864 const fragment$6 = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}"; 9865 9866 const vertex$5 = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}"; 9867 const fragment$5 = "#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULARINTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n\t#ifdef USE_SPECULARCOLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;
9867\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_physical_pars_fragment>\n#include <transmission_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <clearcoat_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <clearcoat_normal_fragment_begin>\n\t#include <clearcoat_normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t#include <transmission_fragment>\n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\n\t\toutgoingLight = outgoingLight * sheenEnergyComp + sheenSpecular;\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + clearcoatSpecular * material.clearcoat;
vendor: 16,384 bytes, lines 9867-10240
9867\n\t#endif\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}"; 9868 9869 const vertex$4 = "#define TOON\nvarying vec3 vViewPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}"; 9870 const fragment$4 = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_toon_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_toon_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}"; 9871 9872 const vertex$3 = "uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n}"; 9873 const fragment$3 = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}"; 9874 9875 const vertex$2 = "#include <common>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}"; 9876 const fragment$2 = "uniform vec3 color;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}"; 9877 9878 const vertex$1 = "uniform float rotation;\nuniform vec2 center;\n#include <common>\n#include <uv_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}"; 9879 const fragment$1 = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}"; 9880 9881 const ShaderChunk = { 9882 alphamap_fragment: alphamap_fragment, 9883 alphamap_pars_fragment: alphamap_pars_fragment, 9884 alphatest_fragment: alphatest_fragment, 9885 alphatest_pars_fragment: alphatest_pars_fragment, 9886 aomap_fragment: aomap_fragment, 9887 aomap_pars_fragment: aomap_pars_fragment, 9888 begin_vertex: begin_vertex, 9889 beginnormal_vertex: beginnormal_vertex, 9890 bsdfs: bsdfs, 9891 bumpmap_pars_fragment: bumpmap_pars_fragment, 9892 clipping_planes_fragment: clipping_planes_fragment, 9893 clipping_planes_pars_fragment: clipping_planes_pars_fragment, 9894 clipping_planes_pars_vertex: clipping_planes_pars_vertex, 9895 clipping_planes_vertex: clipping_planes_vertex, 9896 color_fragment: color_fragment, 9897 color_pars_fragment: color_pars_fragment, 9898 color_pars_vertex: color_pars_vertex, 9899 color_vertex: color_vertex, 9900 common: common, 9901 cube_uv_reflection_fragment: cube_uv_reflection_fragment, 9902 defaultnormal_vertex: defaultnormal_vertex, 9903 displacementmap_pars_vertex: displacementmap_pars_vertex, 9904 displacementmap_vertex: displacementmap_vertex, 9905 emissivemap_fragment: emissivemap_fragment, 9906 emissivemap_pars_fragment: emissivemap_pars_fragment, 9907 encodings_fragment: encodings_fragment, 9908 encodings_pars_fragment: encodings_pars_fragment, 9909 envmap_fragment: envmap_fragment, 9910 envmap_common_pars_fragment: envmap_common_pars_fragment, 9911 envmap_pars_fragment: envmap_pars_fragment, 9912 envmap_pars_vertex: envmap_pars_vertex, 9913 envmap_physical_pars_fragment: envmap_physical_pars_fragment, 9914 envmap_vertex: envmap_vertex, 9915 fog_vertex: fog_vertex, 9916 fog_pars_vertex: fog_pars_vertex, 9917 fog_fragment: fog_fragment, 9918 fog_pars_fragment: fog_pars_fragment, 9919 gradientmap_pars_fragment: gradientmap_pars_fragment, 9920 lightmap_fragment: lightmap_fragment, 9921 lightmap_pars_fragment: lightmap_pars_fragment, 9922 lights_lambert_vertex: lights_lambert_vertex, 9923 lights_pars_begin: lights_pars_begin, 9924 lights_toon_fragment: lights_toon_fragment, 9925 lights_toon_pars_fragment: lights_toon_pars_fragment, 9926 lights_phong_fragment: lights_phong_fragment, 9927 lights_phong_pars_fragment: lights_phong_pars_fragment, 9928 lights_physical_fragment: lights_physical_fragment, 9929 lights_physical_pars_fragment: lights_physical_pars_fragment, 9930 lights_fragment_begin: lights_fragment_begin, 9931 lights_fragment_maps: lights_fragment_maps, 9932 lights_fragment_end: lights_fragment_end, 9933 logdepthbuf_fragment: logdepthbuf_fragment, 9934 logdepthbuf_pars_fragment: logdepthbuf_pars_fragment, 9935 logdepthbuf_pars_vertex: logdepthbuf_pars_vertex, 9936 logdepthbuf_vertex: logdepthbuf_vertex, 9937 map_fragment: map_fragment, 9938 map_pars_fragment: map_pars_fragment, 9939 map_particle_fragment: map_particle_fragment, 9940 map_particle_pars_fragment: map_particle_pars_fragment, 9941 metalnessmap_fragment: metalnessmap_fragment, 9942 metalnessmap_pars_fragment: metalnessmap_pars_fragment, 9943 morphnormal_vertex: morphnormal_vertex, 9944 morphtarget_pars_vertex: morphtarget_pars_vertex, 9945 morphtarget_vertex: morphtarget_vertex, 9946 normal_fragment_begin: normal_fragment_begin, 9947 normal_fragment_maps: normal_fragment_maps, 9948 normal_pars_fragment: normal_pars_fragment, 9949 normal_pars_vertex: normal_pars_vertex, 9950 normal_vertex: normal_vertex, 9951 normalmap_pars_fragment: normalmap_pars_fragment, 9952 clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin, 9953 clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps, 9954 clearcoat_pars_fragment: clearcoat_pars_fragment, 9955 output_fragment: output_fragment, 9956 packing: packing, 9957 premultiplied_alpha_fragment: premultiplied_alpha_fragment, 9958 project_vertex: project_vertex, 9959 dithering_fragment: dithering_fragment, 9960 dithering_pars_fragment: dithering_pars_fragment, 9961 roughnessmap_fragment: roughnessmap_fragment, 9962 roughnessmap_pars_fragment: roughnessmap_pars_fragment, 9963 shadowmap_pars_fragment: shadowmap_pars_fragment, 9964 shadowmap_pars_vertex: shadowmap_pars_vertex, 9965 shadowmap_vertex: shadowmap_vertex, 9966 shadowmask_pars_fragment: shadowmask_pars_fragment, 9967 skinbase_vertex: skinbase_vertex, 9968 skinning_pars_vertex: skinning_pars_vertex, 9969 skinning_vertex: skinning_vertex, 9970 skinnormal_vertex: skinnormal_vertex, 9971 specularmap_fragment: specularmap_fragment, 9972 specularmap_pars_fragment: specularmap_pars_fragment, 9973 tonemapping_fragment: tonemapping_fragment, 9974 tonemapping_pars_fragment: tonemapping_pars_fragment, 9975 transmission_fragment: transmission_fragment, 9976 transmission_pars_fragment: transmission_pars_fragment, 9977 uv_pars_fragment: uv_pars_fragment, 9978 uv_pars_vertex: uv_pars_vertex, 9979 uv_vertex: uv_vertex, 9980 uv2_pars_fragment: uv2_pars_fragment, 9981 uv2_pars_vertex: uv2_pars_vertex, 9982 uv2_vertex: uv2_vertex, 9983 worldpos_vertex: worldpos_vertex, 9984 background_vert: vertex$g, 9985 background_frag: fragment$g, 9986 cube_vert: vertex$f, 9987 cube_frag: fragment$f, 9988 depth_vert: vertex$e, 9989 depth_frag: fragment$e, 9990 distanceRGBA_vert: vertex$d, 9991 distanceRGBA_frag: fragment$d, 9992 equirect_vert: vertex$c, 9993 equirect_frag: fragment$c, 9994 linedashed_vert: vertex$b, 9995 linedashed_frag: fragment$b, 9996 meshbasic_vert: vertex$a, 9997 meshbasic_frag: fragment$a, 9998 meshlambert_vert: vertex$9, 9999 meshlambert_frag: fragment$9, 10000 meshmatcap_vert: vertex$8, 10001 meshmatcap_frag: fragment$8, 10002 meshnormal_vert: vertex$7, 10003 meshnormal_frag: fragment$7, 10004 meshphong_vert: vertex$6, 10005 meshphong_frag: fragment$6, 10006 meshphysical_vert: vertex$5, 10007 meshphysical_frag: fragment$5, 10008 meshtoon_vert: vertex$4, 10009 meshtoon_frag: fragment$4, 10010 points_vert: vertex$3, 10011 points_frag: fragment$3, 10012 shadow_vert: vertex$2, 10013 shadow_frag: fragment$2, 10014 sprite_vert: vertex$1, 10015 sprite_frag: fragment$1 10016 }; 10017 10018 /** 10019 * Uniforms library for shared webgl shaders 10020 */ 10021 10022 const UniformsLib = { 10023 common: { 10024 diffuse: { 10025 value: new Color(0xffffff) 10026 }, 10027 opacity: { 10028 value: 1.0 10029 }, 10030 map: { 10031 value: null 10032 }, 10033 uvTransform: { 10034 value: new Matrix3() 10035 }, 10036 uv2Transform: { 10037 value: new Matrix3() 10038 }, 10039 alphaMap: { 10040 value: null 10041 }, 10042 alphaTest: { 10043 value: 0 10044 } 10045 }, 10046 specularmap: { 10047 specularMap: { 10048 value: null 10049 } 10050 }, 10051 envmap: { 10052 envMap: { 10053 value: null 10054 }, 10055 flipEnvMap: { 10056 value: -1 10057 }, 10058 reflectivity: { 10059 value: 1.0 10060 }, 10061 // basic, lambert, phong 10062 ior: { 10063 value: 1.5 10064 }, 10065 // standard, physical 10066 refractionRatio: { 10067 value: 0.98 10068 } 10069 }, 10070 aomap: { 10071 aoMap: { 10072 value: null 10073 }, 10074 aoMapIntensity: { 10075 value: 1 10076 } 10077 }, 10078 lightmap: { 10079 lightMap: { 10080 value: null 10081 }, 10082 lightMapIntensity: { 10083 value: 1 10084 } 10085 }, 10086 emissivemap: { 10087 emissiveMap: { 10088 value: null 10089 } 10090 }, 10091 bumpmap: { 10092 bumpMap: { 10093 value: null 10094 }, 10095 bumpScale: { 10096 value: 1 10097 } 10098 }, 10099 normalmap: { 10100 normalMap: { 10101 value: null 10102 }, 10103 normalScale: { 10104 value: new Vector2(1, 1) 10105 } 10106 }, 10107 displacementmap: { 10108 displacementMap: { 10109 value: null 10110 }, 10111 displacementScale: { 10112 value: 1 10113 }, 10114 displacementBias: { 10115 value: 0 10116 } 10117 }, 10118 roughnessmap: { 10119 roughnessMap: { 10120 value: null 10121 } 10122 }, 10123 metalnessmap: { 10124 metalnessMap: { 10125 value: null 10126 } 10127 }, 10128 gradientmap: { 10129 gradientMap: { 10130 value: null 10131 } 10132 }, 10133 fog: { 10134 fogDensity: { 10135 value: 0.00025 10136 }, 10137 fogNear: { 10138 value: 1 10139 }, 10140 fogFar: { 10141 value: 2000 10142 }, 10143 fogColor: { 10144 value: new Color(0xffffff) 10145 } 10146 }, 10147 lights: { 10148 ambientLightColor: { 10149 value: [] 10150 }, 10151 lightProbe: { 10152 value: [] 10153 }, 10154 directionalLights: { 10155 value: [], 10156 properties: { 10157 direction: {}, 10158 color: {} 10159 } 10160 }, 10161 directionalLightShadows: { 10162 value: [], 10163 properties: { 10164 shadowBias: {}, 10165 shadowNormalBias: {}, 10166 shadowRadius: {}, 10167 shadowMapSize: {} 10168 } 10169 }, 10170 directionalShadowMap: { 10171 value: [] 10172 }, 10173 directionalShadowMatrix: { 10174 value: [] 10175 }, 10176 spotLights: { 10177 value: [], 10178 properties: { 10179 color: {}, 10180 position: {}, 10181 direction: {}, 10182 distance: {}, 10183 coneCos: {}, 10184 penumbraCos: {}, 10185 decay: {} 10186 } 10187 }, 10188 spotLightShadows: { 10189 value: [], 10190 properties: { 10191 shadowBias: {}, 10192 shadowNormalBias: {}, 10193 shadowRadius: {}, 10194 shadowMapSize: {} 10195 } 10196 }, 10197 spotShadowMap: { 10198 value: [] 10199 }, 10200 spotShadowMatrix: { 10201 value: [] 10202 }, 10203 pointLights: { 10204 value: [], 10205 properties: { 10206 color: {}, 10207 position: {}, 10208 decay: {}, 10209 distance: {} 10210 } 10211 }, 10212 pointLightShadows: { 10213 value: [], 10214 properties: { 10215 shadowBias: {}, 10216 shadowNormalBias: {}, 10217 shadowRadius: {}, 10218 shadowMapSize: {}, 10219 shadowCameraNear: {}, 10220 shadowCameraFar: {} 10221 } 10222 }, 10223 pointShadowMap: { 10224 value: [] 10225 }, 10226 pointShadowMatrix: { 10227 value: [] 10228 }, 10229 hemisphereLights: { 10230 value: [], 10231 properties: { 10232 direction: {}, 10233 skyColor: {}, 10234 groundColor: {} 10235 } 10236 }, 10237 // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src 10238 rectAreaLights: { 10239 value: [], 10240
vendor: 16,735 bytes, lines 10240-10874
10240 properties: { 10241 color: {}, 10242 position: {}, 10243 width: {}, 10244 height: {} 10245 } 10246 }, 10247 ltc_1: { 10248 value: null 10249 }, 10250 ltc_2: { 10251 value: null 10252 } 10253 }, 10254 points: { 10255 diffuse: { 10256 value: new Color(0xffffff) 10257 }, 10258 opacity: { 10259 value: 1.0 10260 }, 10261 size: { 10262 value: 1.0 10263 }, 10264 scale: { 10265 value: 1.0 10266 }, 10267 map: { 10268 value: null 10269 }, 10270 alphaMap: { 10271 value: null 10272 }, 10273 alphaTest: { 10274 value: 0 10275 }, 10276 uvTransform: { 10277 value: new Matrix3() 10278 } 10279 }, 10280 sprite: { 10281 diffuse: { 10282 value: new Color(0xffffff) 10283 }, 10284 opacity: { 10285 value: 1.0 10286 }, 10287 center: { 10288 value: new Vector2(0.5, 0.5) 10289 }, 10290 rotation: { 10291 value: 0.0 10292 }, 10293 map: { 10294 value: null 10295 }, 10296 alphaMap: { 10297 value: null 10298 }, 10299 alphaTest: { 10300 value: 0 10301 }, 10302 uvTransform: { 10303 value: new Matrix3() 10304 } 10305 } 10306 }; 10307 10308 const ShaderLib = { 10309 basic: { 10310 uniforms: mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.fog]), 10311 vertexShader: ShaderChunk.meshbasic_vert, 10312 fragmentShader: ShaderChunk.meshbasic_frag 10313 }, 10314 lambert: { 10315 uniforms: mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.fog, UniformsLib.lights, { 10316 emissive: { 10317 value: new Color(0x000000) 10318 } 10319 }]), 10320 vertexShader: ShaderChunk.meshlambert_vert, 10321 fragmentShader: ShaderChunk.meshlambert_frag 10322 }, 10323 phong: { 10324 uniforms: mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.fog, UniformsLib.lights, { 10325 emissive: { 10326 value: new Color(0x000000) 10327 }, 10328 specular: { 10329 value: new Color(0x111111) 10330 }, 10331 shininess: { 10332 value: 30 10333 } 10334 }]), 10335 vertexShader: ShaderChunk.meshphong_vert, 10336 fragmentShader: ShaderChunk.meshphong_frag 10337 }, 10338 standard: { 10339 uniforms: mergeUniforms([UniformsLib.common, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.roughnessmap, UniformsLib.metalnessmap, UniformsLib.fog, UniformsLib.lights, { 10340 emissive: { 10341 value: new Color(0x000000) 10342 }, 10343 roughness: { 10344 value: 1.0 10345 }, 10346 metalness: { 10347 value: 0.0 10348 }, 10349 envMapIntensity: { 10350 value: 1 10351 } // temporary 10352 10353 }]), 10354 vertexShader: ShaderChunk.meshphysical_vert, 10355 fragmentShader: ShaderChunk.meshphysical_frag 10356 }, 10357 toon: { 10358 uniforms: mergeUniforms([UniformsLib.common, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.gradientmap, UniformsLib.fog, UniformsLib.lights, { 10359 emissive: { 10360 value: new Color(0x000000) 10361 } 10362 }]), 10363 vertexShader: ShaderChunk.meshtoon_vert, 10364 fragmentShader: ShaderChunk.meshtoon_frag 10365 }, 10366 matcap: { 10367 uniforms: mergeUniforms([UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.fog, { 10368 matcap: { 10369 value: null 10370 } 10371 }]), 10372 vertexShader: ShaderChunk.meshmatcap_vert, 10373 fragmentShader: ShaderChunk.meshmatcap_frag 10374 }, 10375 points: { 10376 uniforms: mergeUniforms([UniformsLib.points, UniformsLib.fog]), 10377 vertexShader: ShaderChunk.points_vert, 10378 fragmentShader: ShaderChunk.points_frag 10379 }, 10380 dashed: { 10381 uniforms: mergeUniforms([UniformsLib.common, UniformsLib.fog, { 10382 scale: { 10383 value: 1 10384 }, 10385 dashSize: { 10386 value: 1 10387 }, 10388 totalSize: { 10389 value: 2 10390 } 10391 }]), 10392 vertexShader: ShaderChunk.linedashed_vert, 10393 fragmentShader: ShaderChunk.linedashed_frag 10394 }, 10395 depth: { 10396 uniforms: mergeUniforms([UniformsLib.common, UniformsLib.displacementmap]), 10397 vertexShader: ShaderChunk.depth_vert, 10398 fragmentShader: ShaderChunk.depth_frag 10399 }, 10400 normal: { 10401 uniforms: mergeUniforms([UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, { 10402 opacity: { 10403 value: 1.0 10404 } 10405 }]), 10406 vertexShader: ShaderChunk.meshnormal_vert, 10407 fragmentShader: ShaderChunk.meshnormal_frag 10408 }, 10409 sprite: { 10410 uniforms: mergeUniforms([UniformsLib.sprite, UniformsLib.fog]), 10411 vertexShader: ShaderChunk.sprite_vert, 10412 fragmentShader: ShaderChunk.sprite_frag 10413 }, 10414 background: { 10415 uniforms: { 10416 uvTransform: { 10417 value: new Matrix3() 10418 }, 10419 t2D: { 10420 value: null 10421 } 10422 }, 10423 vertexShader: ShaderChunk.background_vert, 10424 fragmentShader: ShaderChunk.background_frag 10425 }, 10426 10427 /* ------------------------------------------------------------------------- 10428 // Cube map shader 10429 ------------------------------------------------------------------------- */ 10430 cube: { 10431 uniforms: mergeUniforms([UniformsLib.envmap, { 10432 opacity: { 10433 value: 1.0 10434 } 10435 }]), 10436 vertexShader: ShaderChunk.cube_vert, 10437 fragmentShader: ShaderChunk.cube_frag 10438 }, 10439 equirect: { 10440 uniforms: { 10441 tEquirect: { 10442 value: null 10443 } 10444 }, 10445 vertexShader: ShaderChunk.equirect_vert, 10446 fragmentShader: ShaderChunk.equirect_frag 10447 }, 10448 distanceRGBA: { 10449 uniforms: mergeUniforms([UniformsLib.common, UniformsLib.displacementmap, { 10450 referencePosition: { 10451 value: new Vector3() 10452 }, 10453 nearDistance: { 10454 value: 1 10455 }, 10456 farDistance: { 10457 value: 1000 10458 } 10459 }]), 10460 vertexShader: ShaderChunk.distanceRGBA_vert, 10461 fragmentShader: ShaderChunk.distanceRGBA_frag 10462 }, 10463 shadow: { 10464 uniforms: mergeUniforms([UniformsLib.lights, UniformsLib.fog, { 10465 color: { 10466 value: new Color(0x00000) 10467 }, 10468 opacity: { 10469 value: 1.0 10470 } 10471 }]), 10472 vertexShader: ShaderChunk.shadow_vert, 10473 fragmentShader: ShaderChunk.shadow_frag 10474 } 10475 }; 10476 ShaderLib.physical = { 10477 uniforms: mergeUniforms([ShaderLib.standard.uniforms, { 10478 clearcoat: { 10479 value: 0 10480 }, 10481 clearcoatMap: { 10482 value: null 10483 }, 10484 clearcoatRoughness: { 10485 value: 0 10486 }, 10487 clearcoatRoughnessMap: { 10488 value: null 10489 }, 10490 clearcoatNormalScale: { 10491 value: new Vector2(1, 1) 10492 }, 10493 clearcoatNormalMap: { 10494 value: null 10495 }, 10496 sheen: { 10497 value: 0 10498 }, 10499 sheenColor: { 10500 value: new Color(0x000000) 10501 }, 10502 sheenColorMap: { 10503 value: null 10504 }, 10505 sheenRoughness: { 10506 value: 0 10507 }, 10508 sheenRoughnessMap: { 10509 value: null 10510 }, 10511 transmission: { 10512 value: 0 10513 }, 10514 transmissionMap: { 10515 value: null 10516 }, 10517 transmissionSamplerSize: { 10518 value: new Vector2() 10519 }, 10520 transmissionSamplerMap: { 10521 value: null 10522 }, 10523 thickness: { 10524 value: 0 10525 }, 10526 thicknessMap: { 10527 value: null 10528 }, 10529 attenuationDistance: { 10530 value: 0 10531 }, 10532 attenuationColor: { 10533 value: new Color(0x000000) 10534 }, 10535 specularIntensity: { 10536 value: 0 10537 }, 10538 specularIntensityMap: { 10539 value: null 10540 }, 10541 specularColor: { 10542 value: new Color(1, 1, 1) 10543 }, 10544 specularColorMap: { 10545 value: null 10546 } 10547 }]), 10548 vertexShader: ShaderChunk.meshphysical_vert, 10549 fragmentShader: ShaderChunk.meshphysical_frag 10550 }; 10551 10552 function WebGLBackground(renderer, cubemaps, state, objects, premultipliedAlpha) { 10553 const clearColor = new Color(0x000000); 10554 let clearAlpha = 0; 10555 let planeMesh; 10556 let boxMesh; 10557 let currentBackground = null; 10558 let currentBackgroundVersion = 0; 10559 let currentTonemapping = null; 10560 10561 function render(renderList, scene) { 10562 let forceClear = false; 10563 let background = scene.isScene === true ? scene.background : null; 10564 10565 if (background && background.isTexture) { 10566 background = cubemaps.get(background); 10567 } // Ignore background in AR 10568 // TODO: Reconsider this. 10569 10570 10571 const xr = renderer.xr; 10572 const session = xr.getSession && xr.getSession(); 10573 10574 if (session && session.environmentBlendMode === 'additive') { 10575 background = null; 10576 } 10577 10578 if (background === null) { 10579 setClear(clearColor, clearAlpha); 10580 } else if (background && background.isColor) { 10581 setClear(background, 1); 10582 forceClear = true; 10583 } 10584 10585 if (renderer.autoClear || forceClear) { 10586 renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil); 10587 } 10588 10589 if (background && (background.isCubeTexture || background.mapping === CubeUVReflectionMapping)) { 10590 if (boxMesh === undefined) { 10591 boxMesh = new Mesh(new BoxGeometry(1, 1, 1), new ShaderMaterial({ 10592 name: 'BackgroundCubeMaterial', 10593 uniforms: cloneUniforms(ShaderLib.cube.uniforms), 10594 vertexShader: ShaderLib.cube.vertexShader, 10595 fragmentShader: ShaderLib.cube.fragmentShader, 10596 side: BackSide, 10597 depthTest: false, 10598 depthWrite: false, 10599 fog: false 10600 })); 10601 boxMesh.geometry.deleteAttribute('normal'); 10602 boxMesh.geometry.deleteAttribute('uv'); 10603 10604 boxMesh.onBeforeRender = function (renderer, scene, camera) { 10605 this.matrixWorld.copyPosition(camera.matrixWorld); 10606 }; // enable code injection for non-built-in material 10607 10608 10609 Object.defineProperty(boxMesh.material, 'envMap', { 10610 get: function () { 10611 return this.uniforms.envMap.value; 10612 } 10613 }); 10614 objects.update(boxMesh); 10615 } 10616 10617 boxMesh.material.uniforms.envMap.value = background; 10618 boxMesh.material.uniforms.flipEnvMap.value = background.isCubeTexture && background.isRenderTargetTexture === false ? -1 : 1; 10619 10620 if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) { 10621 boxMesh.material.needsUpdate = true; 10622 currentBackground = background; 10623 currentBackgroundVersion = background.version; 10624 currentTonemapping = renderer.toneMapping; 10625 } // push to the pre-sorted opaque render list 10626 10627 10628 renderList.unshift(boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null); 10629 } else if (background && background.isTexture) { 10630 if (planeMesh === undefined) { 10631 planeMesh = new Mesh(new PlaneGeometry(2, 2), new ShaderMaterial({ 10632 name: 'BackgroundMaterial', 10633 uniforms: cloneUniforms(ShaderLib.background.uniforms), 10634 vertexShader: ShaderLib.background.vertexShader, 10635 fragmentShader: ShaderLib.background.fragmentShader, 10636 side: FrontSide, 10637 depthTest: false, 10638 depthWrite: false, 10639 fog: false 10640 })); 10641 planeMesh.geometry.deleteAttribute('normal'); // enable code injection for non-built-in material 10642 10643 Object.defineProperty(planeMesh.material, 'map', { 10644 get: function () { 10645 return this.uniforms.t2D.value; 10646 } 10647 }); 10648 objects.update(planeMesh); 10649 } 10650 10651 planeMesh.material.uniforms.t2D.value = background; 10652 10653 if (background.matrixAutoUpdate === true) { 10654 background.updateMatrix(); 10655 } 10656 10657 planeMesh.material.uniforms.uvTransform.value.copy(background.matrix); 10658 10659 if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) { 10660 planeMesh.material.needsUpdate = true; 10661 currentBackground = background; 10662 currentBackgroundVersion = background.version; 10663 currentTonemapping = renderer.toneMapping; 10664 } // push to the pre-sorted opaque render list 10665 10666 10667 renderList.unshift(planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null); 10668 } 10669 } 10670 10671 function setClear(color, alpha) { 10672 state.buffers.color.setClear(color.r, color.g, color.b, alpha, premultipliedAlpha); 10673 } 10674 10675 return { 10676 getClearColor: function () { 10677 return clearColor; 10678 }, 10679 setClearColor: function (color, alpha = 1) { 10680 clearColor.set(color); 10681 clearAlpha = alpha; 10682 setClear(clearColor, clearAlpha); 10683 }, 10684 getClearAlpha: function () { 10685 return clearAlpha; 10686 }, 10687 setClearAlpha: function (alpha) { 10688 clearAlpha = alpha; 10689 setClear(clearColor, clearAlpha); 10690 }, 10691 render: render 10692 }; 10693 } 10694 10695 function WebGLBindingStates(gl, extensions, attributes, capabilities) { 10696 const maxVertexAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); 10697 const extension = capabilities.isWebGL2 ? null : extensions.get('OES_vertex_array_object'); 10698 const vaoAvailable = capabilities.isWebGL2 || extension !== null; 10699 const bindingStates = {}; 10700 const defaultState = createBindingState(null); 10701 let currentState = defaultState; 10702 10703 function setup(object, material, program, geometry, index) { 10704 let updateBuffers = false; 10705 10706 if (vaoAvailable) { 10707 const state = getBindingState(geometry, program, material); 10708 10709 if (currentState !== state) { 10710 currentState = state; 10711 bindVertexArrayObject(currentState.object); 10712 } 10713 10714 updateBuffers = needsUpdate(geometry, index); 10715 if (updateBuffers) saveCache(geometry, index); 10716 } else { 10717 const wireframe = material.wireframe === true; 10718 10719 if (currentState.geometry !== geometry.id || currentState.program !== program.id || currentState.wireframe !== wireframe) { 10720 currentState.geometry = geometry.id; 10721 currentState.program = program.id; 10722 currentState.wireframe = wireframe; 10723 updateBuffers = true; 10724 } 10725 } 10726 10727 if (object.isInstancedMesh === true) { 10728 updateBuffers = true; 10729 } 10730 10731 if (index !== null) { 10732 attributes.update(index, gl.ELEMENT_ARRAY_BUFFER); 10733 } 10734 10735 if (updateBuffers) { 10736 setupVertexAttributes(object, material, program, geometry); 10737 10738 if (index !== null) { 10739 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, attributes.get(index).buffer); 10740 } 10741 } 10742 } 10743 10744 function createVertexArrayObject() { 10745 if (capabilities.isWebGL2) return gl.createVertexArray(); 10746 return extension.createVertexArrayOES(); 10747 } 10748 10749 function bindVertexArrayObject(vao) { 10750 if (capabilities.isWebGL2) return gl.bindVertexArray(vao); 10751 return extension.bindVertexArrayOES(vao); 10752 } 10753 10754 function deleteVertexArrayObject(vao) { 10755 if (capabilities.isWebGL2) return gl.deleteVertexArray(vao); 10756 return extension.deleteVertexArrayOES(vao); 10757 } 10758 10759 function getBindingState(geometry, program, material) { 10760 const wireframe = material.wireframe === true; 10761 let programMap = bindingStates[geometry.id]; 10762 10763 if (programMap === undefined) { 10764 programMap = {}; 10765 bindingStates[geometry.id] = programMap; 10766 } 10767 10768 let stateMap = programMap[program.id]; 10769 10770 if (stateMap === undefined) { 10771 stateMap = {}; 10772 programMap[program.id] = stateMap; 10773 } 10774 10775 let state = stateMap[wireframe]; 10776 10777 if (state === undefined) { 10778 state = createBindingState(createVertexArrayObject()); 10779 stateMap[wireframe] = state; 10780 } 10781 10782 return state; 10783 } 10784 10785 function createBindingState(vao) { 10786 const newAttributes = []; 10787 const enabledAttributes = []; 10788 const attributeDivisors = []; 10789 10790 for (let i = 0; i < maxVertexAttributes; i++) { 10791 newAttributes[i] = 0; 10792 enabledAttributes[i] = 0; 10793 attributeDivisors[i] = 0; 10794 } 10795 10796 return { 10797 // for backward compatibility on non-VAO support browser 10798 geometry: null, 10799 program: null, 10800 wireframe: false, 10801 newAttributes: newAttributes, 10802 enabledAttributes: enabledAttributes, 10803 attributeDivisors: attributeDivisors, 10804 object: vao, 10805 attributes: {}, 10806 index: null 10807 }; 10808 } 10809 10810 function needsUpdate(geometry, index) { 10811 const cachedAttributes = currentState.attributes; 10812 const geometryAttributes = geometry.attributes; 10813 let attributesNum = 0; 10814 10815 for (const key in geometryAttributes) { 10816 const cachedAttribute = cachedAttributes[key]; 10817 const geometryAttribute = geometryAttributes[key]; 10818 if (cachedAttribute === undefined) return true; 10819 if (cachedAttribute.attribute !== geometryAttribute) return true; 10820 if (cachedAttribute.data !== geometryAttribute.data) return true; 10821 attributesNum++; 10822 } 10823 10824 if (currentState.attributesNum !== attributesNum) return true; 10825 if (currentState.index !== index) return true; 10826 return false; 10827 } 10828 10829 function saveCache(geometry, index) { 10830 const cache = {}; 10831 const attributes = geometry.attributes; 10832 let attributesNum = 0; 10833 10834 for (const key in attributes) { 10835 const attribute = attributes[key]; 10836 const data = {}; 10837 data.attribute = attribute; 10838 10839 if (attribute.data) { 10840 data.data = attribute.data; 10841 } 10842 10843 cache[key] = data; 10844 attributesNum++; 10845 } 10846 10847 currentState.attributes = cache; 10848 currentState.attributesNum = attributesNum; 10849 currentState.index = index; 10850 } 10851 10852 function initAttributes() { 10853 const newAttributes = currentState.newAttributes; 10854 10855 for (let i = 0, il = newAttributes.length; i < il; i++) { 10856 newAttributes[i] = 0; 10857 } 10858 } 10859 10860 function enableAttribute(attribute) { 10861 enableAttributeAndDivisor(attribute, 0); 10862 } 10863 10864 function enableAttributeAndDivisor(attribute, meshPerAttribute) { 10865 const newAttributes = currentState.newAttributes; 10866 const enabledAttributes = currentState.enabledAttributes; 10867 const attributeDivisors = currentState.attributeDivisors; 10868 newAttributes[attribute] = 1; 10869 10870 if (enabledAttributes[attribute] === 0) { 10871 gl.enableVertexAttribArray(attribute); 10872 enabledAttributes[attribute] = 1; 10873 } 10874
vendor: 10,716 bytes, lines 10875-11188
10875 if (attributeDivisors[attribute] !== meshPerAttribute) { 10876 const extension = capabilities.isWebGL2 ? gl : extensions.get('ANGLE_instanced_arrays'); 10877 extension[capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE'](attribute, meshPerAttribute); 10878 attributeDivisors[attribute] = meshPerAttribute; 10879 } 10880 } 10881 10882 function disableUnusedAttributes() { 10883 const newAttributes = currentState.newAttributes; 10884 const enabledAttributes = currentState.enabledAttributes; 10885 10886 for (let i = 0, il = enabledAttributes.length; i < il; i++) { 10887 if (enabledAttributes[i] !== newAttributes[i]) { 10888 gl.disableVertexAttribArray(i); 10889 enabledAttributes[i] = 0; 10890 } 10891 } 10892 } 10893 10894 function vertexAttribPointer(index, size, type, normalized, stride, offset) { 10895 if (capabilities.isWebGL2 === true && (type === gl.INT || type === gl.UNSIGNED_INT)) { 10896 gl.vertexAttribIPointer(index, size, type, stride, offset); 10897 } else { 10898 gl.vertexAttribPointer(index, size, type, normalized, stride, offset); 10899 } 10900 } 10901 10902 function setupVertexAttributes(object, material, program, geometry) { 10903 if (capabilities.isWebGL2 === false && (object.isInstancedMesh || geometry.isInstancedBufferGeometry)) { 10904 if (extensions.get('ANGLE_instanced_arrays') === null) return; 10905 } 10906 10907 initAttributes(); 10908 const geometryAttributes = geometry.attributes; 10909 const programAttributes = program.getAttributes(); 10910 const materialDefaultAttributeValues = material.defaultAttributeValues; 10911 10912 for (const name in programAttributes) { 10913 const programAttribute = programAttributes[name]; 10914 10915 if (programAttribute.location >= 0) { 10916 let geometryAttribute = geometryAttributes[name]; 10917 10918 if (geometryAttribute === undefined) { 10919 if (name === 'instanceMatrix' && object.instanceMatrix) geometryAttribute = object.instanceMatrix; 10920 if (name === 'instanceColor' && object.instanceColor) geometryAttribute = object.instanceColor; 10921 } 10922 10923 if (geometryAttribute !== undefined) { 10924 const normalized = geometryAttribute.normalized; 10925 const size = geometryAttribute.itemSize; 10926 const attribute = attributes.get(geometryAttribute); // TODO Attribute may not be available on context restore 10927 10928 if (attribute === undefined) continue; 10929 const buffer = attribute.buffer; 10930 const type = attribute.type; 10931 const bytesPerElement = attribute.bytesPerElement; 10932 10933 if (geometryAttribute.isInterleavedBufferAttribute) { 10934 const data = geometryAttribute.data; 10935 const stride = data.stride; 10936 const offset = geometryAttribute.offset; 10937 10938 if (data && data.isInstancedInterleavedBuffer) { 10939 for (let i = 0; i < programAttribute.locationSize; i++) { 10940 enableAttributeAndDivisor(programAttribute.location + i, data.meshPerAttribute); 10941 } 10942 10943 if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) { 10944 geometry._maxInstanceCount = data.meshPerAttribute * data.count; 10945 } 10946 } else { 10947 for (let i = 0; i < programAttribute.locationSize; i++) { 10948 enableAttribute(programAttribute.location + i); 10949 } 10950 } 10951 10952 gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 10953 10954 for (let i = 0; i < programAttribute.locationSize; i++) { 10955 vertexAttribPointer(programAttribute.location + i, size / programAttribute.locationSize, type, normalized, stride * bytesPerElement, (offset + size / programAttribute.locationSize * i) * bytesPerElement); 10956 } 10957 } else { 10958 if (geometryAttribute.isInstancedBufferAttribute) { 10959 for (let i = 0; i < programAttribute.locationSize; i++) { 10960 enableAttributeAndDivisor(programAttribute.location + i, geometryAttribute.meshPerAttribute); 10961 } 10962 10963 if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) { 10964 geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count; 10965 } 10966 } else { 10967 for (let i = 0; i < programAttribute.locationSize; i++) { 10968 enableAttribute(programAttribute.location + i); 10969 } 10970 } 10971 10972 gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 10973 10974 for (let i = 0; i < programAttribute.locationSize; i++) { 10975 vertexAttribPointer(programAttribute.location + i, size / programAttribute.locationSize, type, normalized, size * bytesPerElement, size / programAttribute.locationSize * i * bytesPerElement); 10976 } 10977 } 10978 } else if (materialDefaultAttributeValues !== undefined) { 10979 const value = materialDefaultAttributeValues[name]; 10980 10981 if (value !== undefined) { 10982 switch (value.length) { 10983 case 2: 10984 gl.vertexAttrib2fv(programAttribute.location, value); 10985 break; 10986 10987 case 3: 10988 gl.vertexAttrib3fv(programAttribute.location, value); 10989 break; 10990 10991 case 4: 10992 gl.vertexAttrib4fv(programAttribute.location, value); 10993 break; 10994 10995 default: 10996 gl.vertexAttrib1fv(programAttribute.location, value); 10997 } 10998 } 10999 } 11000 } 11001 } 11002 11003 disableUnusedAttributes(); 11004 } 11005 11006 function dispose() { 11007 reset(); 11008 11009 for (const geometryId in bindingStates) { 11010 const programMap = bindingStates[geometryId]; 11011 11012 for (const programId in programMap) { 11013 const stateMap = programMap[programId]; 11014 11015 for (const wireframe in stateMap) { 11016 deleteVertexArrayObject(stateMap[wireframe].object); 11017 delete stateMap[wireframe]; 11018 } 11019 11020 delete programMap[programId]; 11021 } 11022 11023 delete bindingStates[geometryId]; 11024 } 11025 } 11026 11027 function releaseStatesOfGeometry(geometry) { 11028 if (bindingStates[geometry.id] === undefined) return; 11029 const programMap = bindingStates[geometry.id]; 11030 11031 for (const programId in programMap) { 11032 const stateMap = programMap[programId]; 11033 11034 for (const wireframe in stateMap) { 11035 deleteVertexArrayObject(stateMap[wireframe].object); 11036 delete stateMap[wireframe]; 11037 } 11038 11039 delete programMap[programId]; 11040 } 11041 11042 delete bindingStates[geometry.id]; 11043 } 11044 11045 function releaseStatesOfProgram(program) { 11046 for (const geometryId in bindingStates) { 11047 const programMap = bindingStates[geometryId]; 11048 if (programMap[program.id] === undefined) continue; 11049 const stateMap = programMap[program.id]; 11050 11051 for (const wireframe in stateMap) { 11052 deleteVertexArrayObject(stateMap[wireframe].object); 11053 delete stateMap[wireframe]; 11054 } 11055 11056 delete programMap[program.id]; 11057 } 11058 } 11059 11060 function reset() { 11061 resetDefaultState(); 11062 if (currentState === defaultState) return; 11063 currentState = defaultState; 11064 bindVertexArrayObject(currentState.object); 11065 } // for backward-compatilibity 11066 11067 11068 function resetDefaultState() { 11069 defaultState.geometry = null; 11070 defaultState.program = null; 11071 defaultState.wireframe = false; 11072 } 11073 11074 return { 11075 setup: setup, 11076 reset: reset, 11077 resetDefaultState: resetDefaultState, 11078 dispose: dispose, 11079 releaseStatesOfGeometry: releaseStatesOfGeometry, 11080 releaseStatesOfProgram: releaseStatesOfProgram, 11081 initAttributes: initAttributes, 11082 enableAttribute: enableAttribute, 11083 disableUnusedAttributes: disableUnusedAttributes 11084 }; 11085 } 11086 11087 function WebGLBufferRenderer(gl, extensions, info, capabilities) { 11088 const isWebGL2 = capabilities.isWebGL2; 11089 let mode; 11090 11091 function setMode(value) { 11092 mode = value; 11093 } 11094 11095 function render(start, count) { 11096 gl.drawArrays(mode, start, count); 11097 info.update(count, mode, 1); 11098 } 11099 11100 function renderInstances(start, count, primcount) { 11101 if (primcount === 0) return; 11102 let extension, methodName; 11103 11104 if (isWebGL2) { 11105 extension = gl; 11106 methodName = 'drawArraysInstanced'; 11107 } else { 11108 extension = extensions.get('ANGLE_instanced_arrays'); 11109 methodName = 'drawArraysInstancedANGLE'; 11110 11111 if (extension === null) { 11112 console.error('THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.'); 11113 return; 11114 } 11115 } 11116 11117 extension[methodName](mode, start, count, primcount); 11118 info.update(count, mode, primcount); 11119 } // 11120 11121 11122 this.setMode = setMode; 11123 this.render = render; 11124 this.renderInstances = renderInstances; 11125 } 11126 11127 function WebGLCapabilities(gl, extensions, parameters) { 11128 let maxAnisotropy; 11129 11130 function getMaxAnisotropy() { 11131 if (maxAnisotropy !== undefined) return maxAnisotropy; 11132 11133 if (extensions.has('EXT_texture_filter_anisotropic') === true) { 11134 const extension = extensions.get('EXT_texture_filter_anisotropic'); 11135 maxAnisotropy = gl.getParameter(extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT); 11136 } else { 11137 maxAnisotropy = 0; 11138 } 11139 11140 return maxAnisotropy; 11141 } 11142 11143 function getMaxPrecision(precision) { 11144 if (precision === 'highp') { 11145 if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision > 0) { 11146 return 'highp'; 11147 } 11148 11149 precision = 'mediump'; 11150 } 11151 11152 if (precision === 'mediump') { 11153 if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT).precision > 0) { 11154 return 'mediump'; 11155 } 11156 } 11157 11158 return 'lowp'; 11159 } 11160 11161 const isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext || typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext; 11162 let precision = parameters.precision !== undefined ? parameters.precision : 'highp'; 11163 const maxPrecision = getMaxPrecision(precision); 11164 11165 if (maxPrecision !== precision) { 11166 console.warn('THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.'); 11167 precision = maxPrecision; 11168 } 11169 11170 const drawBuffers = isWebGL2 || extensions.has('WEBGL_draw_buffers'); 11171 const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; 11172 const maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); 11173 const maxVertexTextures = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS); 11174 const maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); 11175 const maxCubemapSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); 11176 const maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); 11177 const maxVertexUniforms = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS); 11178 const maxVaryings = gl.getParameter(gl.MAX_VARYING_VECTORS); 11179 const maxFragmentUniforms = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS); 11180 const vertexTextures = maxVertexTextures > 0; 11181 const floatFragmentTextures = isWebGL2 || extensions.has('OES_texture_float'); 11182 const floatVertexTextures = vertexTextures && floatFragmentTextures; 11183 const maxSamples = isWebGL2 ? gl.getParameter(gl.MAX_SAMPLES) : 0; 11184 return { 11185 isWebGL2: isWebGL2, 11186 drawBuffers: drawBuffers, 11187 getMaxAnisotropy: getMaxAnisotropy, 11188 getMaxPrecision: getMaxPrecision,
vendor: 1,698 bytes, lines 11189-11244
11189 precision: precision, 11190 logarithmicDepthBuffer: logarithmicDepthBuffer, 11191 maxTextures: maxTextures, 11192 maxVertexTextures: maxVertexTextures, 11193 maxTextureSize: maxTextureSize, 11194 maxCubemapSize: maxCubemapSize, 11195 maxAttributes: maxAttributes, 11196 maxVertexUniforms: maxVertexUniforms, 11197 maxVaryings: maxVaryings, 11198 maxFragmentUniforms: maxFragmentUniforms, 11199 vertexTextures: vertexTextures, 11200 floatFragmentTextures: floatFragmentTextures, 11201 floatVertexTextures: floatVertexTextures, 11202 maxSamples: maxSamples 11203 }; 11204 } 11205 11206 function WebGLClipping(properties) { 11207 const scope = this; 11208 let globalState = null, 11209 numGlobalPlanes = 0, 11210 localClippingEnabled = false, 11211 renderingShadows = false; 11212 const plane = new Plane(), 11213 viewNormalMatrix = new Matrix3(), 11214 uniform = { 11215 value: null, 11216 needsUpdate: false 11217 }; 11218 this.uniform = uniform; 11219 this.numPlanes = 0; 11220 this.numIntersection = 0; 11221 11222 this.init = function (planes, enableLocalClipping, camera) { 11223 const enabled = planes.length !== 0 || enableLocalClipping || // enable state of previous frame - the clipping code has to 11224 // run another frame in order to reset the state: 11225 numGlobalPlanes !== 0 || localClippingEnabled; 11226 localClippingEnabled = enableLocalClipping; 11227 globalState = projectPlanes(planes, camera, 0); 11228 numGlobalPlanes = planes.length; 11229 return enabled; 11230 }; 11231 11232 this.beginShadows = function () { 11233 renderingShadows = true; 11234 projectPlanes(null); 11235 }; 11236 11237 this.endShadows = function () { 11238 renderingShadows = false; 11239 resetGlobalState(); 11240 }; 11241 11242 this.setState = function (material, camera, useCache) { 11243 const planes = material.clippingPlanes, 11244 clipIntersection = material.clipIntersection,
vendor: 5,162 bytes, lines 11245-11434
11245 clipShadows = material.clipShadows; 11246 const materialProperties = properties.get(material); 11247 11248 if (!localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && !clipShadows) { 11249 // there's no local clipping 11250 if (renderingShadows) { 11251 // there's no global clipping 11252 projectPlanes(null); 11253 } else { 11254 resetGlobalState(); 11255 } 11256 } else { 11257 const nGlobal = renderingShadows ? 0 : numGlobalPlanes, 11258 lGlobal = nGlobal * 4; 11259 let dstArray = materialProperties.clippingState || null; 11260 uniform.value = dstArray; // ensure unique state 11261 11262 dstArray = projectPlanes(planes, camera, lGlobal, useCache); 11263 11264 for (let i = 0; i !== lGlobal; ++i) { 11265 dstArray[i] = globalState[i]; 11266 } 11267 11268 materialProperties.clippingState = dstArray; 11269 this.numIntersection = clipIntersection ? this.numPlanes : 0; 11270 this.numPlanes += nGlobal; 11271 } 11272 }; 11273 11274 function resetGlobalState() { 11275 if (uniform.value !== globalState) { 11276 uniform.value = globalState; 11277 uniform.needsUpdate = numGlobalPlanes > 0; 11278 } 11279 11280 scope.numPlanes = numGlobalPlanes; 11281 scope.numIntersection = 0; 11282 } 11283 11284 function projectPlanes(planes, camera, dstOffset, skipTransform) { 11285 const nPlanes = planes !== null ? planes.length : 0; 11286 let dstArray = null; 11287 11288 if (nPlanes !== 0) { 11289 dstArray = uniform.value; 11290 11291 if (skipTransform !== true || dstArray === null) { 11292 const flatSize = dstOffset + nPlanes * 4, 11293 viewMatrix = camera.matrixWorldInverse; 11294 viewNormalMatrix.getNormalMatrix(viewMatrix); 11295 11296 if (dstArray === null || dstArray.length < flatSize) { 11297 dstArray = new Float32Array(flatSize); 11298 } 11299 11300 for (let i = 0, i4 = dstOffset; i !== nPlanes; ++i, i4 += 4) { 11301 plane.copy(planes[i]).applyMatrix4(viewMatrix, viewNormalMatrix); 11302 plane.normal.toArray(dstArray, i4); 11303 dstArray[i4 + 3] = plane.constant; 11304 } 11305 } 11306 11307 uniform.value = dstArray; 11308 uniform.needsUpdate = true; 11309 } 11310 11311 scope.numPlanes = nPlanes; 11312 scope.numIntersection = 0; 11313 return dstArray; 11314 } 11315 } 11316 11317 function WebGLCubeMaps(renderer) { 11318 let cubemaps = new WeakMap(); 11319 11320 function mapTextureMapping(texture, mapping) { 11321 if (mapping === EquirectangularReflectionMapping) { 11322 texture.mapping = CubeReflectionMapping; 11323 } else if (mapping === EquirectangularRefractionMapping) { 11324 texture.mapping = CubeRefractionMapping; 11325 } 11326 11327 return texture; 11328 } 11329 11330 function get(texture) { 11331 if (texture && texture.isTexture && texture.isRenderTargetTexture === false) { 11332 const mapping = texture.mapping; 11333 11334 if (mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping) { 11335 if (cubemaps.has(texture)) { 11336 const cubemap = cubemaps.get(texture).texture; 11337 return mapTextureMapping(cubemap, texture.mapping); 11338 } else { 11339 const image = texture.image; 11340 11341 if (image && image.height > 0) { 11342 const currentRenderTarget = renderer.getRenderTarget(); 11343 const renderTarget = new WebGLCubeRenderTarget(image.height / 2); 11344 renderTarget.fromEquirectangularTexture(renderer, texture); 11345 cubemaps.set(texture, renderTarget); 11346 renderer.setRenderTarget(currentRenderTarget); 11347 texture.addEventListener('dispose', onTextureDispose); 11348 return mapTextureMapping(renderTarget.texture, texture.mapping); 11349 } else { 11350 // image not yet ready. try the conversion next frame 11351 return null; 11352 } 11353 } 11354 } 11355 } 11356 11357 return texture; 11358 } 11359 11360 function onTextureDispose(event) { 11361 const texture = event.target; 11362 texture.removeEventListener('dispose', onTextureDispose); 11363 const cubemap = cubemaps.get(texture); 11364 11365 if (cubemap !== undefined) { 11366 cubemaps.delete(texture); 11367 cubemap.dispose(); 11368 } 11369 } 11370 11371 function dispose() { 11372 cubemaps = new WeakMap(); 11373 } 11374 11375 return { 11376 get: get, 11377 dispose: dispose 11378 }; 11379 } 11380 11381 class OrthographicCamera extends Camera { 11382 constructor(left = -1, right = 1, top = 1, bottom = -1, near = 0.1, far = 2000) { 11383 super(); 11384 this.type = 'OrthographicCamera'; 11385 this.zoom = 1; 11386 this.view = null; 11387 this.left = left; 11388 this.right = right; 11389 this.top = top; 11390 this.bottom = bottom; 11391 this.near = near; 11392 this.far = far; 11393 this.updateProjectionMatrix(); 11394 } 11395 11396 copy(source, recursive) { 11397 super.copy(source, recursive); 11398 this.left = source.left; 11399 this.right = source.right; 11400 this.top = source.top; 11401 this.bottom = source.bottom; 11402 this.near = source.near; 11403 this.far = source.far; 11404 this.zoom = source.zoom; 11405 this.view = source.view === null ? null : Object.assign({}, source.view); 11406 return this; 11407 } 11408 11409 setViewOffset(fullWidth, fullHeight, x, y, width, height) { 11410 if (this.view === null) { 11411 this.view = { 11412 enabled: true, 11413 fullWidth: 1, 11414 fullHeight: 1, 11415 offsetX: 0, 11416 offsetY: 0, 11417 width: 1, 11418 height: 1 11419 }; 11420 } 11421 11422 this.view.enabled = true; 11423 this.view.fullWidth = fullWidth; 11424 this.view.fullHeight = fullHeight; 11425 this.view.offsetX = x; 11426 this.view.offsetY = y; 11427 this.view.width = width; 11428 this.view.height = height; 11429 this.updateProjectionMatrix(); 11430 } 11431 11432 clearViewOffset() { 11433 if (this.view !== null) { 11434 this.view.enabled = false;
vendor: 7,091 bytes, lines 11435-11645
11435 } 11436 11437 this.updateProjectionMatrix(); 11438 } 11439 11440 updateProjectionMatrix() { 11441 const dx = (this.right - this.left) / (2 * this.zoom); 11442 const dy = (this.top - this.bottom) / (2 * this.zoom); 11443 const cx = (this.right + this.left) / 2; 11444 const cy = (this.top + this.bottom) / 2; 11445 let left = cx - dx; 11446 let right = cx + dx; 11447 let top = cy + dy; 11448 let bottom = cy - dy; 11449 11450 if (this.view !== null && this.view.enabled) { 11451 const scaleW = (this.right - this.left) / this.view.fullWidth / this.zoom; 11452 const scaleH = (this.top - this.bottom) / this.view.fullHeight / this.zoom; 11453 left += scaleW * this.view.offsetX; 11454 right = left + scaleW * this.view.width; 11455 top -= scaleH * this.view.offsetY; 11456 bottom = top - scaleH * this.view.height; 11457 } 11458 11459 this.projectionMatrix.makeOrthographic(left, right, top, bottom, this.near, this.far); 11460 this.projectionMatrixInverse.copy(this.projectionMatrix).invert(); 11461 } 11462 11463 toJSON(meta) { 11464 const data = super.toJSON(meta); 11465 data.object.zoom = this.zoom; 11466 data.object.left = this.left; 11467 data.object.right = this.right; 11468 data.object.top = this.top; 11469 data.object.bottom = this.bottom; 11470 data.object.near = this.near; 11471 data.object.far = this.far; 11472 if (this.view !== null) data.object.view = Object.assign({}, this.view); 11473 return data; 11474 } 11475 11476 } 11477 11478 OrthographicCamera.prototype.isOrthographicCamera = true; 11479 11480 class RawShaderMaterial extends ShaderMaterial { 11481 constructor(parameters) { 11482 super(parameters); 11483 this.type = 'RawShaderMaterial'; 11484 } 11485 11486 } 11487 11488 RawShaderMaterial.prototype.isRawShaderMaterial = true; 11489 11490 const LOD_MIN = 4; 11491 const LOD_MAX = 8; 11492 const SIZE_MAX = Math.pow(2, LOD_MAX); // The standard deviations (radians) associated with the extra mips. These are 11493 // chosen to approximate a Trowbridge-Reitz distribution function times the 11494 // geometric shadowing function. These sigma values squared must match the 11495 // variance #defines in cube_uv_reflection_fragment.glsl.js. 11496 11497 const EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; 11498 const TOTAL_LODS = LOD_MAX - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; // The maximum length of the blur for loop. Smaller sigmas will use fewer 11499 // samples and exit early, but not recompile the shader. 11500 11501 const MAX_SAMPLES = 20; 11502 const ENCODINGS = { 11503 [LinearEncoding]: 0, 11504 [sRGBEncoding]: 1 11505 }; 11506 11507 const _flatCamera = /*@__PURE__*/new OrthographicCamera(); 11508 11509 const { 11510 _lodPlanes, 11511 _sizeLods, 11512 _sigmas 11513 } = /*@__PURE__*/_createPlanes(); 11514 11515 const _clearColor = /*@__PURE__*/new Color(); 11516 11517 let _oldTarget = null; // Golden Ratio 11518 11519 const PHI = (1 + Math.sqrt(5)) / 2; 11520 const INV_PHI = 1 / PHI; // Vertices of a dodecahedron (except the opposites, which represent the 11521 // same axis), used as axis directions evenly spread on a sphere. 11522 11523 const _axisDirections = [/*@__PURE__*/new Vector3(1, 1, 1), /*@__PURE__*/new Vector3(-1, 1, 1), /*@__PURE__*/new Vector3(1, 1, -1), /*@__PURE__*/new Vector3(-1, 1, -1), /*@__PURE__*/new Vector3(0, PHI, INV_PHI), /*@__PURE__*/new Vector3(0, PHI, -INV_PHI), /*@__PURE__*/new Vector3(INV_PHI, 0, PHI), /*@__PURE__*/new Vector3(-INV_PHI, 0, PHI), /*@__PURE__*/new Vector3(PHI, INV_PHI, 0), /*@__PURE__*/new Vector3(-PHI, INV_PHI, 0)]; 11524 /** 11525 * This class generates a Prefiltered, Mipmapped Radiance Environment Map 11526 * (PMREM) from a cubeMap environment texture. This allows different levels of 11527 * blur to be quickly accessed based on material roughness. It is packed into a 11528 * special CubeUV format that allows us to perform custom interpolation so that 11529 * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap 11530 * chain, it only goes down to the LOD_MIN level (above), and then creates extra 11531 * even more filtered 'mips' at the same LOD_MIN resolution, associated with 11532 * higher roughness levels. In this way we maintain resolution to smoothly 11533 * interpolate diffuse lighting while limiting sampling computation. 11534 * 11535 * Paper: Fast, Accurate Image-Based Lighting 11536 * https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view 11537 */ 11538 11539 class PMREMGenerator { 11540 constructor(renderer) { 11541 this._renderer = renderer; 11542 this._pingPongRenderTarget = null; 11543 this._blurMaterial = _getBlurShader(MAX_SAMPLES); 11544 this._equirectShader = null; 11545 this._cubemapShader = null; 11546 11547 this._compileMaterial(this._blurMaterial); 11548 } 11549 /** 11550 * Generates a PMREM from a supplied Scene, which can be faster than using an 11551 * image if networking bandwidth is low. Optional sigma specifies a blur radius 11552 * in radians to be applied to the scene before PMREM generation. Optional near 11553 * and far planes ensure the scene is rendered in its entirety (the cubeCamera 11554 * is placed at the origin). 11555 */ 11556 11557 11558 fromScene(scene, sigma = 0, near = 0.1, far = 100) { 11559 _oldTarget = this._renderer.getRenderTarget(); 11560 11561 const cubeUVRenderTarget = this._allocateTargets(); 11562 11563 this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget); 11564 11565 if (sigma > 0) { 11566 this._blur(cubeUVRenderTarget, 0, 0, sigma); 11567 } 11568 11569 this._applyPMREM(cubeUVRenderTarget); 11570 11571 this._cleanup(cubeUVRenderTarget); 11572 11573 return cubeUVRenderTarget; 11574 } 11575 /** 11576 * Generates a PMREM from an equirectangular texture, which can be either LDR 11577 * or HDR. The ideal input image size is 1k (1024 x 512), 11578 * as this matches best with the 256 x 256 cubemap output. 11579 */ 11580 11581 11582 fromEquirectangular(equirectangular) { 11583 return this._fromTexture(equirectangular); 11584 } 11585 /** 11586 * Generates a PMREM from an cubemap texture, which can be either LDR 11587 * or HDR. The ideal input cube size is 256 x 256, 11588 * as this matches best with the 256 x 256 cubemap output. 11589 */ 11590 11591 11592 fromCubemap(cubemap) { 11593 return this._fromTexture(cubemap); 11594 } 11595 /** 11596 * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during 11597 * your texture's network fetch for increased concurrency. 11598 */ 11599 11600 11601 compileCubemapShader() { 11602 if (this._cubemapShader === null) { 11603 this._cubemapShader = _getCubemapShader(); 11604 11605 this._compileMaterial(this._cubemapShader); 11606 } 11607 } 11608 /** 11609 * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during 11610 * your texture's network fetch for increased concurrency. 11611 */ 11612 11613 11614 compileEquirectangularShader() { 11615 if (this._equirectShader === null) { 11616 this._equirectShader = _getEquirectShader(); 11617 11618 this._compileMaterial(this._equirectShader); 11619 } 11620 } 11621 /** 11622 * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, 11623 * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on 11624 * one of them will cause any others to also become unusable. 11625 */ 11626 11627 11628 dispose() { 11629 this._blurMaterial.dispose(); 11630 11631 if (this._cubemapShader !== null) this._cubemapShader.dispose(); 11632 if (this._equirectShader !== null) this._equirectShader.dispose(); 11633 11634 for (let i = 0; i < _lodPlanes.length; i++) { 11635 _lodPlanes[i].dispose(); 11636 } 11637 } // private interface 11638 11639 11640 _cleanup(outputTarget) { 11641 this._pingPongRenderTarget.dispose(); 11642 11643 this._renderer.setRenderTarget(_oldTarget); 11644 11645 outputTarget.scissorTest = false;
11646 11647 _setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height); 11648 } 11649 11650 _fromTexture(texture) { 11651 _oldTarget = this._renderer.getRenderTarget(); 11652 11653 const cubeUVRenderTarget = this._allocateTargets(texture); 11654 11655 this._textureToCubeUV(texture, cubeUVRenderTarget); 11656 11657 this._applyPMREM(cubeUVRenderTarget); 11658 11659 this._cleanup(cubeUVRenderTarget); 11660 11661 return cubeUVRenderTarget; 11662 } 11663 11664 _allocateTargets(texture) { 11665 // warning: null texture is valid 11666 const params = { 11667 magFilter: LinearFilter, 11668 minFilter: LinearFilter, 11669 generateMipmaps: false, 11670 type: HalfFloatType, 11671 format: RGBAFormat, 11672 encoding: LinearEncoding, 11673 depthBuffer: false 11674 }; 11675 11676 const cubeUVRenderTarget = _createRenderTarget(params); 11677 11678 cubeUVRenderTarget.depthBuffer = texture ? false : true; 11679 this._pingPongRenderTarget = _createRenderTarget(params); 11680 return cubeUVRenderTarget; 11681 } 11682 11683 _compileMaterial(material) { 11684 const tmpMesh = new Mesh(_lodPlanes[0], material); 11685 11686 this._renderer.compile(tmpMesh, _flatCamera); 11687 } 11688 11689 _sceneToCubeUV(scene, near, far, cubeUVRenderTarget) { 11690 const fov = 90; 11691 const aspect = 1; 11692 const cubeCamera = new PerspectiveCamera(fov, aspect, near, far); 11693 const upSign = [1, -1, 1, 1, 1, 1]; 11694 const forwardSign = [1, 1, 1, -1, -1, -1]; 11695 const renderer = this._renderer; 11696 const originalAutoClear = renderer.autoClear; 11697 const toneMapping = renderer.toneMapping; 11698 renderer.getClearColor(_clearColor); 11699 renderer.toneMapping = NoToneMapping; 11700 renderer.autoClear = false; 11701 const backgroundMaterial = new MeshBasicMaterial({
11702 name: 'PMREM.Background', 11703 side: BackSide, 11704 depthWrite: false, 11705 depthTest: false 11706 }); 11707 const backgroundBox = new Mesh(new BoxGeometry(), backgroundMaterial); 11708 let useSolidColor = false; 11709 const background = scene.background; 11710 11711 if (background) { 11712 if (background.isColor) { 11713 backgroundMaterial.color.copy(background); 11714 scene.background = null; 11715 useSolidColor = true; 11716 } 11717 } else { 11718 backgroundMaterial.color.copy(_clearColor); 11719 useSolidColor = true; 11720 } 11721 11722 for (let i = 0; i < 6; i++) { 11723 const col = i % 3; 11724 11725 if (col == 0) { 11726 cubeCamera.up.set(0, upSign[i], 0); 11727 cubeCamera.lookAt(forwardSign[i], 0, 0); 11728 } else if (col == 1) { 11729 cubeCamera.up.set(0, 0, upSign[i]); 11730 cubeCamera.lookAt(0, forwardSign[i], 0); 11731 } else { 11732 cubeCamera.up.set(0, upSign[i], 0); 11733 cubeCamera.lookAt(0, 0, forwardSign[i]); 11734 } 11735 11736 _setViewport(cubeUVRenderTarget, col * SIZE_MAX, i > 2 ? SIZE_MAX : 0, SIZE_MAX, SIZE_MAX); 11737 11738 renderer.setRenderTarget(cubeUVRenderTarget); 11739 11740 if (useSolidColor) { 11741 renderer.render(backgroundBox, cubeCamera); 11742 } 11743 11744 renderer.render(scene, cubeCamera); 11745 } 11746 11747 backgroundBox.geometry.dispose(); 11748 backgroundBox.material.dispose(); 11749 renderer.toneMapping = toneMapping; 11750 renderer.autoClear = originalAutoClear; 11751 scene.background = background; 11752 } 11753 11754 _setEncoding(uniform, texture) { 11755 if (this._renderer.capabilities.isWebGL2 === true && texture.format === RGBAFormat && texture.type === UnsignedByteType && texture.encoding === sRGBEncoding) { 11756 uniform.value = ENCODINGS[LinearEncoding]; 11757 } else { 11758 uniform.value = ENCODINGS[texture.encoding]; 11759 } 11760 } 11761 11762 _textureToCubeUV(texture, cubeUVRenderTarget) { 11763 const renderer = this._renderer; 11764 const isCubeTexture = texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping; 11765 11766 if (isCubeTexture) { 11767 if (this._cubemapShader == null) { 11768 this._cubemapShader = _getCubemapShader(); 11769 } 11770 } else { 11771 if (this._equirectShader == null) { 11772 this._equirectShader = _getEquirectShader(); 11773 } 11774 } 11775 11776 const material = isCubeTexture ? this._cubemapShader : this._equirectShader; 11777 const mesh = new Mesh(_lodPlanes[0], material); 11778 const uniforms = material.uniforms; 11779 uniforms['envMap'].value = texture; 11780 11781 if (!isCubeTexture) { 11782 uniforms['texelSize'].value.set(1.0 / texture.image.width, 1.0 / texture.image.height); 11783 } 11784 11785 this._setEncoding(uniforms['inputEncoding'], texture); 11786 11787 _setViewport(cubeUVRenderTarget, 0, 0, 3 * SIZE_MAX, 2 * SIZE_MAX); 11788 11789 renderer.setRenderTarget(cubeUVRenderTarget); 11790 renderer.render(mesh, _flatCamera); 11791 } 11792 11793 _applyPMREM(cubeUVRenderTarget) { 11794 const renderer = this._renderer; 11795 const autoClear = renderer.autoClear; 11796 renderer.autoClear = false; 11797 11798 for (let i = 1; i < TOTAL_LODS; i++) { 11799 const sigma = Math.sqrt(_sigmas[i] * _sigmas[i] - _sigmas[i - 1] * _sigmas[i - 1]); 11800 const poleAxis = _axisDirections[(i - 1) % _axisDirections.length]; 11801 11802 this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis); 11803 } 11804 11805 renderer.autoClear = autoClear; 11806 } 11807 /** 11808 * This is a two-pass Gaussian blur for a cubemap. Normally this is done 11809 * vertically and horizontally, but this breaks down on a cube. Here we apply 11810 * the blur latitudinally (around the poles), and then longitudinally (towards 11811 * the poles) to approximate the orthogonally-separable blur. It is least 11812 * accurate at the poles, but still does a decent job. 11813 */ 11814 11815 11816 _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) { 11817 const pingPongRenderTarget = this._pingPongRenderTarget; 11818 11819 this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis); 11820 11821 this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis); 11822 } 11823 11824 _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) { 11825 const renderer = this._renderer; 11826 const blurMaterial = this._blurMaterial; 11827 11828 if (direction !== 'latitudinal' && direction !== 'longitudinal') { 11829 console.error('blur direction must be either latitudinal or longitudinal!'); 11830 } // Number of standard deviations at which to cut off the discrete approximation. 11831 11832 11833 const STANDARD_DEVIATIONS = 3; 11834 const blurMesh = new Mesh(_lodPlanes[lodOut], blurMaterial); 11835 const blurUniforms = blurMaterial.uniforms; 11836 const pixels = _sizeLods[lodIn] - 1;
vendor: 4,190 bytes, lines 11837-11974
11837 const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : 2 * Math.PI / (2 * MAX_SAMPLES - 1); 11838 const sigmaPixels = sigmaRadians / radiansPerPixel; 11839 const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES; 11840 11841 if (samples > MAX_SAMPLES) { 11842 console.warn(`sigmaRadians, ${sigmaRadians}, is too large and will clip, as it requested ${samples} samples when the maximum is set to ${MAX_SAMPLES}`); 11843 } 11844 11845 const weights = []; 11846 let sum = 0; 11847 11848 for (let i = 0; i < MAX_SAMPLES; ++i) { 11849 const x = i / sigmaPixels; 11850 const weight = Math.exp(-x * x / 2); 11851 weights.push(weight); 11852 11853 if (i == 0) { 11854 sum += weight; 11855 } else if (i < samples) { 11856 sum += 2 * weight; 11857 } 11858 } 11859 11860 for (let i = 0; i < weights.length; i++) { 11861 weights[i] = weights[i] / sum; 11862 } 11863 11864 blurUniforms['envMap'].value = targetIn.texture; 11865 blurUniforms['samples'].value = samples; 11866 blurUniforms['weights'].value = weights; 11867 blurUniforms['latitudinal'].value = direction === 'latitudinal'; 11868 11869 if (poleAxis) { 11870 blurUniforms['poleAxis'].value = poleAxis; 11871 } 11872 11873 blurUniforms['dTheta'].value = radiansPerPixel; 11874 blurUniforms['mipInt'].value = LOD_MAX - lodIn; 11875 const outputSize = _sizeLods[lodOut]; 11876 const x = 3 * Math.max(0, SIZE_MAX - 2 * outputSize); 11877 const y = (lodOut === 0 ? 0 : 2 * SIZE_MAX) + 2 * outputSize * (lodOut > LOD_MAX - LOD_MIN ? lodOut - LOD_MAX + LOD_MIN : 0); 11878 11879 _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize); 11880 11881 renderer.setRenderTarget(targetOut); 11882 renderer.render(blurMesh, _flatCamera); 11883 } 11884 11885 } 11886 11887 function _createPlanes() { 11888 const _lodPlanes = []; 11889 const _sizeLods = []; 11890 const _sigmas = []; 11891 let lod = LOD_MAX; 11892 11893 for (let i = 0; i < TOTAL_LODS; i++) { 11894 const sizeLod = Math.pow(2, lod); 11895 11896 _sizeLods.push(sizeLod); 11897 11898 let sigma = 1.0 / sizeLod; 11899 11900 if (i > LOD_MAX - LOD_MIN) { 11901 sigma = EXTRA_LOD_SIGMA[i - LOD_MAX + LOD_MIN - 1]; 11902 } else if (i == 0) { 11903 sigma = 0; 11904 } 11905 11906 _sigmas.push(sigma); 11907 11908 const texelSize = 1.0 / (sizeLod - 1); 11909 const min = -texelSize / 2; 11910 const max = 1 + texelSize / 2; 11911 const uv1 = [min, min, max, min, max, max, min, min, max, max, min, max]; 11912 const cubeFaces = 6; 11913 const vertices = 6; 11914 const positionSize = 3; 11915 const uvSize = 2; 11916 const faceIndexSize = 1; 11917 const position = new Float32Array(positionSize * vertices * cubeFaces); 11918 const uv = new Float32Array(uvSize * vertices * cubeFaces); 11919 const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces); 11920 11921 for (let face = 0; face < cubeFaces; face++) { 11922 const x = face % 3 * 2 / 3 - 1; 11923 const y = face > 2 ? 0 : -1; 11924 const coordinates = [x, y, 0, x + 2 / 3, y, 0, x + 2 / 3, y + 1, 0, x, y, 0, x + 2 / 3, y + 1, 0, x, y + 1, 0]; 11925 position.set(coordinates, positionSize * vertices * face); 11926 uv.set(uv1, uvSize * vertices * face); 11927 const fill = [face, face, face, face, face, face]; 11928 faceIndex.set(fill, faceIndexSize * vertices * face); 11929 } 11930 11931 const planes = new BufferGeometry(); 11932 planes.setAttribute('position', new BufferAttribute(position, positionSize)); 11933 planes.setAttribute('uv', new BufferAttribute(uv, uvSize)); 11934 planes.setAttribute('faceIndex', new BufferAttribute(faceIndex, faceIndexSize)); 11935 11936 _lodPlanes.push(planes); 11937 11938 if (lod > LOD_MIN) { 11939 lod--; 11940 } 11941 } 11942 11943 return { 11944 _lodPlanes, 11945 _sizeLods, 11946 _sigmas 11947 }; 11948 } 11949 11950 function _createRenderTarget(params) { 11951 const cubeUVRenderTarget = new WebGLRenderTarget(3 * SIZE_MAX, 3 * SIZE_MAX, params); 11952 cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; 11953 cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; 11954 cubeUVRenderTarget.scissorTest = true; 11955 return cubeUVRenderTarget; 11956 } 11957 11958 function _setViewport(target, x, y, width, height) { 11959 target.viewport.set(x, y, width, height); 11960 target.scissor.set(x, y, width, height); 11961 } 11962 11963 function _getBlurShader(maxSamples) { 11964 const weights = new Float32Array(maxSamples); 11965 const poleAxis = new Vector3(0, 1, 0); 11966 const shaderMaterial = new RawShaderMaterial({ 11967 name: 'SphericalGaussianBlur', 11968 defines: { 11969 'n': maxSamples 11970 }, 11971 uniforms: { 11972 'envMap': { 11973 value: null 11974 },
11975 'samples': { 11976 value: 1 11977 }, 11978 'weights': { 11979 value: weights 11980 }, 11981 'latitudinal': { 11982 value: false 11983 }, 11984 'dTheta': { 11985 value: 0 11986 }, 11987 'mipInt': { 11988 value: 0 11989 }, 11990 'poleAxis': { 11991 value: poleAxis 11992 } 11993 }, 11994 vertexShader: _getCommonVertexShader(), 11995 fragmentShader: 11996 /* glsl */ 11997 ` 11998 11999 precision mediump float; 12000 precision mediump int; 12001 12002 varying vec3 vOutputDirection; 12003 12004 uniform sampler2D envMap; 12005 uniform int samples; 12006 uniform float weights[ n ]; 12007 uniform bool latitudinal; 12008 uniform float dTheta; 12009 uniform float mipInt; 12010 uniform vec3 poleAxis; 12011 12012 ${_getEncodings()} 12013 12014 #define ENVMAP_TYPE_CUBE_UV 12015 #include <cube_uv_reflection_fragment> 12016 12017 vec3 getSample( float theta, vec3 axis ) { 12018 12019 float cosTheta = cos( theta ); 12020 // Rodrigues' axis-angle rotation 12021 vec3 sampleDirection = vOutputDirection * cosTheta 12022 + cross( axis, vOutputDirection ) * sin( theta ) 12023 + axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta ); 12024 12025 return bilinearCubeUV( envMap, sampleDirection, mipInt ); 12026 12027 } 12028 12029 void main() { 12030 12031 vec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection ); 12032 12033 if ( all( equal( axis, vec3( 0.0 ) ) ) ) { 12034 12035 axis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x ); 12036 12037 } 12038 12039 axis = normalize( axis ); 12040 12041 gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 ); 12042 gl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis ); 12043 12044 for ( int i = 1; i < n; i++ ) { 12045 12046 if ( i >= samples ) { 12047 12048 break; 12049 12050 } 12051 12052 float theta = dTheta * float( i ); 12053 gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis ); 12054 gl_FragColor.rgb += weights[ i ] * getSample( theta, axis ); 12055 12056 } 12057 12058 } 12059 `, 12060 blending: NoBlending, 12061 depthTest: false, 12062 depthWrite: false 12063 }); 12064 return shaderMaterial; 12065 } 12066 12067 function _getEquirectShader() { 12068 const texelSize = new Vector2(1, 1); 12069 const shaderMaterial = new RawShaderMaterial({ 12070 name: 'EquirectangularToCubeUV', 12071 uniforms: { 12072 'envMap': { 12073 value: null 12074 }, 12075 'texelSize': { 12076 value: texelSize 12077 }, 12078 'inputEncoding': { 12079 value: ENCODINGS[LinearEncoding] 12080 } 12081 }, 12082 vertexShader: _getCommonVertexShader(), 12083 fragmentShader: 12084 /* glsl */ 12085 ` 12086 12087 precision mediump float; 12088 precision mediump int; 12089 12090 varying vec3 vOutputDirection; 12091 12092 uniform sampler2D envMap; 12093 uniform vec2 texelSize; 12094 12095 ${_getEncodings()} 12096 12097 #include <common> 12098 12099 void main() { 12100 12101 gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 ); 12102 12103 vec3 outputDirection = normalize( vOutputDirection ); 12104 vec2 uv = equirectUv( outputDirection ); 12105 12106 vec2 f = fract( uv / texelSize - 0.5 ); 12107 uv -= f * texelSize; 12108 vec3 tl = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb; 12109 uv.x += texelSize.x; 12110 vec3 tr = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb; 12111 uv.y += texelSize.y; 12112 vec3 br = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb; 12113 uv.x -= texelSize.x; 12114 vec3 bl = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb; 12115 12116 vec3 tm = mix( tl, tr, f.x ); 12117 vec3 bm = mix( bl, br, f.x ); 12118 gl_FragColor.rgb = mix( tm, bm, f.y ); 12119 12120 } 12121 `, 12122 blending: NoBlending, 12123 depthTest: false, 12124 depthWrite: false 12125 }); 12126 return shaderMaterial; 12127 } 12128 12129 function _getCubemapShader() { 12130 const shaderMaterial = new RawShaderMaterial({ 12131 name: 'CubemapToCubeUV', 12132 uniforms: { 12133 'envMap': { 12134 value: null 12135 }, 12136 'inputEncoding': { 12137 value: ENCODINGS[LinearEncoding] 12138 } 12139 }, 12140 vertexShader: _getCommonVertexShader(), 12141 fragmentShader: 12142 /* glsl */ 12143 ` 12144 12145 precision mediump float; 12146 precision mediump int; 12147 12148 varying vec3 vOutputDirection; 12149 12150 uniform samplerCube envMap; 12151 12152 ${_getEncodings()} 12153 12154 void main() { 12155 12156 gl_FragColor = envMapTexelToLinear( textureCube( envMap, vec3( - vOutputDirection.x, vOutputDirection.yz ) ) ); 12157 12158 } 12159 `, 12160 blending: NoBlending, 12161 depthTest: false, 12162 depthWrite: false 12163 }); 12164 return shaderMaterial; 12165 } 12166 12167 function _getCommonVertexShader() { 12168 return ( 12169 /* glsl */ 12170 ` 12171 12172 precision mediump float; 12173 precision mediump int; 12174 12175 attribute vec3 position; 12176 attribute vec2 uv; 12177 attribute float faceIndex; 12178 12179 varying vec3 vOutputDirection; 12180 12181 // RH coordinate system; PMREM face-indexing convention 12182 vec3 getDirection( vec2 uv, float face ) { 12183 12184 uv = 2.0 * uv - 1.0; 12185 12186 vec3 direction = vec3( uv, 1.0 ); 12187 12188 if ( face == 0.0 ) { 12189 12190 direction = direction.zyx; // ( 1, v, u ) pos x 12191 12192 } else if ( face == 1.0 ) { 12193 12194 direction = direction.xzy; 12195 direction.xz *= -1.0; // ( -u, 1, -v ) pos y 12196 12197 } else if ( face == 2.0 ) { 12198 12199 direction.x *= -1.0; // ( -u, v, 1 ) pos z 12200 12201 } else if ( face == 3.0 ) { 12202 12203 direction = direction.zyx; 12204 direction.xz *= -1.0; // ( -1, v, -u ) neg x 12205 12206 } else if ( face == 4.0 ) { 12207 12208 direction = direction.xzy; 12209 direction.xy *= -1.0; // ( -u, -1, v ) neg y 12210 12211 } else if ( face == 5.0 ) { 12212 12213 direction.z *= -1.0; // ( u, v, -1 ) neg z 12214 12215 } 12216 12217 return direction; 12218 12219 } 12220 12221 void main() { 12222 12223 vOutputDirection = getDirection( uv, faceIndex ); 12224 gl_Position = vec4( position, 1.0 ); 12225 12226 } 12227 ` 12228 ); 12229 } 12230 12231 function _getEncodings() { 12232 return ( 12233 /* glsl */ 12234 ` 12235 12236 uniform int inputEncoding; 12237 12238 #include <encodings_pars_fragment> 12239 12240 vec4 inputTexelToLinear( vec4 value ) { 12241 12242 if ( inputEncoding == 0 ) { 12243 12244 return value; 12245 12246 } else { 12247 12248 return sRGBToLinear( value ); 12249 12250 } 12251 12252 } 12253 12254 vec4 envMapTexelToLinear( vec4 color ) { 12255 12256 return inputTexelToLinear( color ); 12257 12258 } 12259 ` 12260 ); 12261 } 12262 12263 function WebGLCubeUVMaps(renderer) {
12264 let cubeUVmaps = new WeakMap(); 12265 let pmremGenerator = null; 12266 12267 function get(texture) { 12268 if (texture && texture.isTexture && texture.isRenderTargetTexture === false) { 12269 const mapping = texture.mapping; 12270 const isEquirectMap = mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping; 12271 const isCubeMap = mapping === CubeReflectionMapping || mapping === CubeRefractionMapping; 12272 12273 if (isEquirectMap || isCubeMap) { 12274 // equirect/cube map to cubeUV conversion 12275 if (cubeUVmaps.has(texture)) { 12276 return cubeUVmaps.get(texture).texture; 12277 } else { 12278 const image = texture.image; 12279 12280 if (isEquirectMap && image && image.height > 0 || isCubeMap && image && isCubeTextureComplete(image)) { 12281 const currentRenderTarget = renderer.getRenderTarget(); 12282 if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer); 12283 const renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture) : pmremGenerator.fromCubemap(texture); 12284 cubeUVmaps.set(texture, renderTarget); 12285 renderer.setRenderTarget(currentRenderTarget); 12286 texture.addEventListener('dispose', onTextureDispose); 12287 return renderTarget.texture; 12288 } else { 12289 // image not yet ready. try the conversion next frame 12290 return null; 12291 } 12292 } 12293 } 12294 } 12295 12296 return texture; 12297 } 12298 12299 function isCubeTextureComplete(image) { 12300 let count = 0; 12301 const length = 6; 12302 12303 for (let i = 0; i < length; i++) { 12304 if (image[i] !== undefined) count++; 12305 } 12306 12307 return count === length; 12308 } 12309 12310 function onTextureDispose(event) { 12311 const texture = event.target; 12312 texture.removeEventListener('dispose', onTextureDispose); 12313 const cubemapUV = cubeUVmaps.get(texture); 12314 12315 if (cubemapUV !== undefined) { 12316 cubeUVmaps.delete(texture); 12317 cubemapUV.dispose(); 12318 } 12319 } 12320 12321 function dispose() { 12322 cubeUVmaps = new WeakMap(); 12323 12324 if (pmremGenerator !== null) { 12325 pmremGenerator.dispose(); 12326 pmremGenerator = null; 12327 } 12328 } 12329 12330 return { 12331 get: get, 12332 dispose: dispose 12333 }; 12334 } 12335 12336 function WebGLExtensions(gl) { 12337 const extensions = {}; 12338 12339 function getExtension(name) { 12340 if (extensions[name] !== undefined) { 12341 return extensions[name]; 12342 } 12343 12344 let extension; 12345 12346 switch (name) { 12347 case 'WEBGL_depth_texture': 12348 extension = gl.getExtension('WEBGL_depth_texture') || gl.getExtension('MOZ_WEBGL_depth_texture') || gl.getExtension('WEBKIT_WEBGL_depth_texture'); 12349 break; 12350 12351 case 'EXT_texture_filter_anisotropic': 12352 extension = gl.getExtension('EXT_texture_filter_anisotropic') || gl.getExtension('MOZ_EXT_texture_filter_anisotropic') || gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic'); 12353 break; 12354 12355 case 'WEBGL_compressed_texture_s3tc': 12356 extension = gl.getExtension('WEBGL_compressed_texture_s3tc') || gl.getExtension('MOZ_WEBGL_compressed_texture_s3tc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc'); 12357 break; 12358 12359 case 'WEBGL_compressed_texture_pvrtc': 12360 extension = gl.getExtension('WEBGL_compressed_texture_pvrtc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc'); 12361 break; 12362 12363 default: 12364 extension = gl.getExtension(name); 12365 } 12366 12367 extensions[name] = extension; 12368 return extension; 12369 } 12370 12371 return { 12372 has: function (name) { 12373 return getExtension(name) !== null; 12374 }, 12375 init: function (capabilities) { 12376 if (capabilities.isWebGL2) { 12377 getExtension('EXT_color_buffer_float'); 12378 } else { 12379 getExtension('WEBGL_depth_texture'); 12380 getExtension('OES_texture_float'); 12381 getExtension('OES_texture_half_float'); 12382 getExtension('OES_texture_half_float_linear'); 12383 getExtension('OES_standard_derivatives'); 12384 getExtension('OES_element_index_uint'); 12385 getExtension('OES_vertex_array_object'); 12386 getExtension('ANGLE_instanced_arrays'); 12387 } 12388 12389 getExtension('OES_texture_float_linear'); 12390 getExtension('EXT_color_buffer_half_float'); 12391 getExtension('WEBGL_multisampled_render_to_texture'); 12392 }, 12393 get: function (name) { 12394 const extension = getExtension(name); 12395 12396 if (extension === null) { 12397 console.warn('THREE.WebGLRenderer: ' + name + ' extension not supported.'); 12398 } 12399 12400 return extension; 12401 } 12402 }; 12403 } 12404 12405 function WebGLGeometries(gl, attributes, info, bindingStates) { 12406 const geometries = {};
vendor: 4,198 bytes, lines 12407-12562
12407 const wireframeAttributes = new WeakMap(); 12408 12409 function onGeometryDispose(event) { 12410 const geometry = event.target; 12411 12412 if (geometry.index !== null) { 12413 attributes.remove(geometry.index); 12414 } 12415 12416 for (const name in geometry.attributes) { 12417 attributes.remove(geometry.attributes[name]); 12418 } 12419 12420 geometry.removeEventListener('dispose', onGeometryDispose); 12421 delete geometries[geometry.id]; 12422 const attribute = wireframeAttributes.get(geometry); 12423 12424 if (attribute) { 12425 attributes.remove(attribute); 12426 wireframeAttributes.delete(geometry); 12427 } 12428 12429 bindingStates.releaseStatesOfGeometry(geometry); 12430 12431 if (geometry.isInstancedBufferGeometry === true) { 12432 delete geometry._maxInstanceCount; 12433 } // 12434 12435 12436 info.memory.geometries--; 12437 } 12438 12439 function get(object, geometry) { 12440 if (geometries[geometry.id] === true) return geometry; 12441 geometry.addEventListener('dispose', onGeometryDispose); 12442 geometries[geometry.id] = true; 12443 info.memory.geometries++; 12444 return geometry; 12445 } 12446 12447 function update(geometry) { 12448 const geometryAttributes = geometry.attributes; // Updating index buffer in VAO now. See WebGLBindingStates. 12449 12450 for (const name in geometryAttributes) { 12451 attributes.update(geometryAttributes[name], gl.ARRAY_BUFFER); 12452 } // morph targets 12453 12454 12455 const morphAttributes = geometry.morphAttributes; 12456 12457 for (const name in morphAttributes) { 12458 const array = morphAttributes[name]; 12459 12460 for (let i = 0, l = array.length; i < l; i++) { 12461 attributes.update(array[i], gl.ARRAY_BUFFER); 12462 } 12463 } 12464 } 12465 12466 function updateWireframeAttribute(geometry) { 12467 const indices = []; 12468 const geometryIndex = geometry.index; 12469 const geometryPosition = geometry.attributes.position; 12470 let version = 0; 12471 12472 if (geometryIndex !== null) { 12473 const array = geometryIndex.array; 12474 version = geometryIndex.version; 12475 12476 for (let i = 0, l = array.length; i < l; i += 3) { 12477 const a = array[i + 0]; 12478 const b = array[i + 1]; 12479 const c = array[i + 2]; 12480 indices.push(a, b, b, c, c, a); 12481 } 12482 } else { 12483 const array = geometryPosition.array; 12484 version = geometryPosition.version; 12485 12486 for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) { 12487 const a = i + 0; 12488 const b = i + 1; 12489 const c = i + 2; 12490 indices.push(a, b, b, c, c, a); 12491 } 12492 } 12493 12494 const attribute = new (arrayMax(indices) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1); 12495 attribute.version = version; // Updating index buffer in VAO now. See WebGLBindingStates 12496 // 12497 12498 const previousAttribute = wireframeAttributes.get(geometry); 12499 if (previousAttribute) attributes.remove(previousAttribute); // 12500 12501 wireframeAttributes.set(geometry, attribute); 12502 } 12503 12504 function getWireframeAttribute(geometry) { 12505 const currentAttribute = wireframeAttributes.get(geometry); 12506 12507 if (currentAttribute) { 12508 const geometryIndex = geometry.index; 12509 12510 if (geometryIndex !== null) { 12511 // if the attribute is obsolete, create a new one 12512 if (currentAttribute.version < geometryIndex.version) { 12513 updateWireframeAttribute(geometry); 12514 } 12515 } 12516 } else { 12517 updateWireframeAttribute(geometry); 12518 } 12519 12520 return wireframeAttributes.get(geometry); 12521 } 12522 12523 return { 12524 get: get, 12525 update: update, 12526 getWireframeAttribute: getWireframeAttribute 12527 }; 12528 } 12529 12530 function WebGLIndexedBufferRenderer(gl, extensions, info, capabilities) { 12531 const isWebGL2 = capabilities.isWebGL2; 12532 let mode; 12533 12534 function setMode(value) { 12535 mode = value; 12536 } 12537 12538 let type, bytesPerElement; 12539 12540 function setIndex(value) { 12541 type = value.type; 12542 bytesPerElement = value.bytesPerElement; 12543 } 12544 12545 function render(start, count) { 12546 gl.drawElements(mode, count, type, start * bytesPerElement); 12547 info.update(count, mode, 1); 12548 } 12549 12550 function renderInstances(start, count, primcount) { 12551 if (primcount === 0) return; 12552 let extension, methodName; 12553 12554 if (isWebGL2) { 12555 extension = gl; 12556 methodName = 'drawElementsInstanced'; 12557 } else { 12558 extension = extensions.get('ANGLE_instanced_arrays'); 12559 methodName = 'drawElementsInstancedANGLE'; 12560 12561 if (extension === null) { 12562 console.error('THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_
12562instanced_arrays.'); 12563 return; 12564 } 12565 } 12566 12567 extension[methodName](mode, count, type, start * bytesPerElement, primcount); 12568 info.update(count, mode, primcount); 12569 } // 12570 12571 12572 this.setMode = setMode; 12573 this.setIndex = setIndex; 12574 this.render = render; 12575 this.renderInstances = renderInstances; 12576 } 12577 12578 function WebGLInfo(gl) { 12579 const memory = { 12580 geometries: 0, 12581 textures: 0 12582 }; 12583 const render = { 12584 frame: 0, 12585 calls: 0, 12586 triangles: 0, 12587 points: 0, 12588 lines: 0 12589 }; 12590 12591 function update(count, mode, instanceCount) { 12592 render.calls++; 12593 12594 switch (mode) { 12595 case gl.TRIANGLES: 12596 render.triangles += instanceCount * (count / 3); 12597 break; 12598 12599 case gl.LINES: 12600 render.lines += instanceCount * (count / 2); 12601 break; 12602 12603 case gl.LINE_STRIP: 12604 render.lines += instanceCount * (count - 1); 12605 break; 12606 12607 case gl.LINE_LOOP: 12608 render.lines += instanceCount * count; 12609 break; 12610 12611 case gl.POINTS: 12612 render.points += instanceCount * count; 12613 break; 12614 12615 default: 12616 console.error('THREE.WebGLInfo: Unknown draw mode:', mode); 12617 break; 12618 } 12619 } 12620 12621 function reset() { 12622 render.frame++; 12623 render.calls = 0; 12624 render.triangles = 0; 12625 render.points = 0; 12626 render.lines = 0; 12627 } 12628 12629 return { 12630 memory: memory, 12631 render: render, 12632 programs: null, 12633 autoReset: true, 12634 reset: reset, 12635 update: update 12636 }; 12637 } 12638 12639 class DataTexture2DArray extends Texture { 12640 constructor(data = null, width = 1, height = 1, depth = 1) { 12641 super(null); 12642 this.image = { 12643 data, 12644 width, 12645 height, 12646 depth 12647 }; 12648 this.magFilter = NearestFilter; 12649 this.minFilter = NearestFilter; 12650 this.wrapR = ClampToEdgeWrapping; 12651 this.generateMipmaps = false; 12652 this.flipY = false; 12653 this.unpackAlignment = 1; 12654 } 12655 12656 } 12657 12658 DataTexture2DArray.prototype.isDataTexture2DArray = true; 12659 12660 function numericalSort(a, b) { 12661 return a[0] - b[0]; 12662 } 12663 12664 function absNumericalSort(a, b) { 12665 return Math.abs(b[1]) - Math.abs(a[1]); 12666 } 12667 12668 function denormalize(morph, attribute) { 12669 let denominator = 1; 12670 const array = attribute.isInterleavedBufferAttribute ? attribute.data.array : attribute.array; 12671 if (array instanceof Int8Array) denominator = 127;else if (array instanceof Int16Array) denominator = 32767;else if (array instanceof Int32Array) denominator = 2147483647;else console.error('THREE.WebGLMorphtargets: Unsupported morph attribute data type: ', array); 12672 morph.divideScalar(denominator); 12673 } 12674 12675 function WebGLMorphtargets(gl, capabilities, textures) { 12676 const influencesList = {}; 12677 const morphInfluences = new Float32Array(8); 12678 const morphTextures = new WeakMap(); 12679 const morph = new Vector3(); 12680 const workInfluences = []; 12681 12682 for (let i = 0; i < 8; i++) { 12683 workInfluences[i] = [i, 0]; 12684 } 12685 12686 function update(object, geometry, material, program) { 12687 const objectInfluences = object.morphTargetInfluences; 12688 12689 if (capabilities.isWebGL2 === true) { 12690 // instead of using attributes, the WebGL 2 code path encodes morph targets 12691 // into an array of data textures. Each layer represents a single morph target.
12692 const numberOfMorphTargets = geometry.morphAttributes.position.length; 12693 let entry = morphTextures.get(geometry); 12694 12695 if (entry === undefined || entry.count !== numberOfMorphTargets) { 12696 if (entry !== undefined) entry.texture.dispose(); 12697 const hasMorphNormals = geometry.morphAttributes.normal !== undefined; 12698 const morphTargets = geometry.morphAttributes.position; 12699 const morphNormals = geometry.morphAttributes.normal || []; 12700 const numberOfVertices = geometry.attributes.position.count; 12701 const numberOfVertexData = hasMorphNormals === true ? 2 : 1; // (v,n) vs. (v) 12702 12703 let width = numberOfVertices * numberOfVertexData; 12704 let height = 1; 12705 12706 if (width > capabilities.maxTextureSize) { 12707 height = Math.ceil(width / capabilities.maxTextureSize); 12708 width = capabilities.maxTextureSize; 12709 } 12710 12711 const buffer = new Float32Array(width * height * 4 * numberOfMorphTargets); 12712 const texture = new DataTexture2DArray(buffer, width, height, numberOfMorphTargets); 12713 texture.format = RGBAFormat; // using RGBA since RGB might be emulated (and is thus slower) 12714 12715 texture.type = FloatType; 12716 texture.needsUpdate = true; // fill buffer 12717 12718 const vertexDataStride = numberOfVertexData * 4; 12719 12720 for (let i = 0;
vendor: 5,716 bytes, lines 12720-12889
12720 i < numberOfMorphTargets; i++) { 12721 const morphTarget = morphTargets[i]; 12722 const morphNormal = morphNormals[i]; 12723 const offset = width * height * 4 * i; 12724 12725 for (let j = 0; j < morphTarget.count; j++) { 12726 morph.fromBufferAttribute(morphTarget, j); 12727 if (morphTarget.normalized === true) denormalize(morph, morphTarget); 12728 const stride = j * vertexDataStride; 12729 buffer[offset + stride + 0] = morph.x; 12730 buffer[offset + stride + 1] = morph.y; 12731 buffer[offset + stride + 2] = morph.z; 12732 buffer[offset + stride + 3] = 0; 12733 12734 if (hasMorphNormals === true) { 12735 morph.fromBufferAttribute(morphNormal, j); 12736 if (morphNormal.normalized === true) denormalize(morph, morphNormal); 12737 buffer[offset + stride + 4] = morph.x; 12738 buffer[offset + stride + 5] = morph.y; 12739 buffer[offset + stride + 6] = morph.z; 12740 buffer[offset + stride + 7] = 0; 12741 } 12742 } 12743 } 12744 12745 entry = { 12746 count: numberOfMorphTargets, 12747 texture: texture, 12748 size: new Vector2(width, height) 12749 }; 12750 morphTextures.set(geometry, entry); 12751 } // 12752 12753 12754 let morphInfluencesSum = 0; 12755 12756 for (let i = 0; i < objectInfluences.length; i++) { 12757 morphInfluencesSum += objectInfluences[i]; 12758 } 12759 12760 const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; 12761 program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence); 12762 program.getUniforms().setValue(gl, 'morphTargetInfluences', objectInfluences); 12763 program.getUniforms().setValue(gl, 'morphTargetsTexture', entry.texture, textures); 12764 program.getUniforms().setValue(gl, 'morphTargetsTextureSize', entry.size); 12765 } else { 12766 // When object doesn't have morph target influences defined, we treat it as a 0-length array 12767 // This is important to make sure we set up morphTargetBaseInfluence / morphTargetInfluences 12768 const length = objectInfluences === undefined ? 0 : objectInfluences.length; 12769 let influences = influencesList[geometry.id]; 12770 12771 if (influences === undefined || influences.length !== length) { 12772 // initialise list 12773 influences = []; 12774 12775 for (let i = 0; i < length; i++) { 12776 influences[i] = [i, 0]; 12777 } 12778 12779 influencesList[geometry.id] = influences; 12780 } // Collect influences 12781 12782 12783 for (let i = 0; i < length; i++) { 12784 const influence = influences[i]; 12785 influence[0] = i; 12786 influence[1] = objectInfluences[i]; 12787 } 12788 12789 influences.sort(absNumericalSort); 12790 12791 for (let i = 0; i < 8; i++) { 12792 if (i < length && influences[i][1]) { 12793 workInfluences[i][0] = influences[i][0]; 12794 workInfluences[i][1] = influences[i][1]; 12795 } else { 12796 workInfluences[i][0] = Number.MAX_SAFE_INTEGER; 12797 workInfluences[i][1] = 0; 12798 } 12799 } 12800 12801 workInfluences.sort(numericalSort); 12802 const morphTargets = geometry.morphAttributes.position; 12803 const morphNormals = geometry.morphAttributes.normal; 12804 let morphInfluencesSum = 0; 12805 12806 for (let i = 0; i < 8; i++) { 12807 const influence = workInfluences[i]; 12808 const index = influence[0]; 12809 const value = influence[1]; 12810 12811 if (index !== Number.MAX_SAFE_INTEGER && value) { 12812 if (morphTargets && geometry.getAttribute('morphTarget' + i) !== morphTargets[index]) { 12813 geometry.setAttribute('morphTarget' + i, morphTargets[index]); 12814 } 12815 12816 if (morphNormals && geometry.getAttribute('morphNormal' + i) !== morphNormals[index]) { 12817 geometry.setAttribute('morphNormal' + i, morphNormals[index]); 12818 } 12819 12820 morphInfluences[i] = value; 12821 morphInfluencesSum += value; 12822 } else { 12823 if (morphTargets && geometry.hasAttribute('morphTarget' + i) === true) { 12824 geometry.deleteAttribute('morphTarget' + i); 12825 } 12826 12827 if (morphNormals && geometry.hasAttribute('morphNormal' + i) === true) { 12828 geometry.deleteAttribute('morphNormal' + i); 12829 } 12830 12831 morphInfluences[i] = 0; 12832 } 12833 } // GLSL shader uses formula baseinfluence * base + sum(target * influence) 12834 // This allows us to switch between absolute morphs and relative morphs without changing shader code 12835 // When baseinfluence = 1 - sum(influence), the above is equivalent to sum((target - base) * influence) 12836 12837 12838 const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; 12839 program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence); 12840 program.getUniforms().setValue(gl, 'morphTargetInfluences', morphInfluences); 12841 } 12842 } 12843 12844 return { 12845 update: update 12846 }; 12847 } 12848 12849 function WebGLObjects(gl, geometries, attributes, info) { 12850 let updateMap = new WeakMap(); 12851 12852 function update(object) { 12853 const frame = info.render.frame; 12854 const geometry = object.geometry; 12855 const buffergeometry = geometries.get(object, geometry); // Update once per frame 12856 12857 if (updateMap.get(buffergeometry) !== frame) { 12858 geometries.update(buffergeometry); 12859 updateMap.set(buffergeometry, frame); 12860 } 12861 12862 if (object.isInstancedMesh) { 12863 if (object.hasEventListener('dispose', onInstancedMeshDispose) === false) { 12864 object.addEventListener('dispose', onInstancedMeshDispose); 12865 } 12866 12867 attributes.update(object.instanceMatrix, gl.ARRAY_BUFFER); 12868 12869 if (object.instanceColor !== null) { 12870 attributes.update(object.instanceColor, gl.ARRAY_BUFFER); 12871 } 12872 } 12873 12874 return buffergeometry; 12875 } 12876 12877 function dispose() { 12878 updateMap = new WeakMap(); 12879 } 12880 12881 function onInstancedMeshDispose(event) { 12882 const instancedMesh = event.target; 12883 instancedMesh.removeEventListener('dispose', onInstancedMeshDispose); 12884 attributes.remove(instancedMesh.instanceMatrix); 12885 if (instancedMesh.instanceColor !== null) attributes.remove(instancedMesh.instanceColor); 12886 } 12887 12888 return { 12889 update: update,
vendor: 6,609 bytes, lines 12890-13159
12890 dispose: dispose 12891 }; 12892 } 12893 12894 class DataTexture3D extends Texture { 12895 constructor(data = null, width = 1, height = 1, depth = 1) { 12896 // We're going to add .setXXX() methods for setting properties later. 12897 // Users can still set in DataTexture3D directly. 12898 // 12899 // const texture = new THREE.DataTexture3D( data, width, height, depth ); 12900 // texture.anisotropy = 16; 12901 // 12902 // See #14839 12903 super(null); 12904 this.image = { 12905 data, 12906 width, 12907 height, 12908 depth 12909 }; 12910 this.magFilter = NearestFilter; 12911 this.minFilter = NearestFilter; 12912 this.wrapR = ClampToEdgeWrapping; 12913 this.generateMipmaps = false; 12914 this.flipY = false; 12915 this.unpackAlignment = 1; 12916 } 12917 12918 } 12919 12920 DataTexture3D.prototype.isDataTexture3D = true; 12921 12922 /** 12923 * Uniforms of a program. 12924 * Those form a tree structure with a special top-level container for the root, 12925 * which you get by calling 'new WebGLUniforms( gl, program )'. 12926 * 12927 * 12928 * Properties of inner nodes including the top-level container: 12929 * 12930 * .seq - array of nested uniforms 12931 * .map - nested uniforms by name 12932 * 12933 * 12934 * Methods of all nodes except the top-level container: 12935 * 12936 * .setValue( gl, value, [textures] ) 12937 * 12938 * uploads a uniform value(s) 12939 * the 'textures' parameter is needed for sampler uniforms 12940 * 12941 * 12942 * Static methods of the top-level container (textures factorizations): 12943 * 12944 * .upload( gl, seq, values, textures ) 12945 * 12946 * sets uniforms in 'seq' to 'values[id].value' 12947 * 12948 * .seqWithValue( seq, values ) : filteredSeq 12949 * 12950 * filters 'seq' entries with corresponding entry in values 12951 * 12952 * 12953 * Methods of the top-level container (textures factorizations): 12954 * 12955 * .setValue( gl, name, value, textures ) 12956 * 12957 * sets uniform with name 'name' to 'value' 12958 * 12959 * .setOptional( gl, obj, prop ) 12960 * 12961 * like .set for an optional property of the object 12962 * 12963 */ 12964 const emptyTexture = new Texture(); 12965 const emptyTexture2dArray = new DataTexture2DArray(); 12966 const emptyTexture3d = new DataTexture3D(); 12967 const emptyCubeTexture = new CubeTexture(); // --- Utilities --- 12968 // Array Caches (provide typed arrays for temporary by size) 12969 12970 const arrayCacheF32 = []; 12971 const arrayCacheI32 = []; // Float32Array caches used for uploading Matrix uniforms 12972 12973 const mat4array = new Float32Array(16); 12974 const mat3array = new Float32Array(9); 12975 const mat2array = new Float32Array(4); // Flattening for arrays of vectors and matrices 12976 12977 function flatten(array, nBlocks, blockSize) { 12978 const firstElem = array[0]; 12979 if (firstElem <= 0 || firstElem > 0) return array; // unoptimized: ! isNaN( firstElem ) 12980 // see http://jacksondunstan.com/articles/983 12981 12982 const n = nBlocks * blockSize; 12983 let r = arrayCacheF32[n]; 12984 12985 if (r === undefined) { 12986 r = new Float32Array(n); 12987 arrayCacheF32[n] = r; 12988 } 12989 12990 if (nBlocks !== 0) { 12991 firstElem.toArray(r, 0); 12992 12993 for (let i = 1, offset = 0; i !== nBlocks; ++i) { 12994 offset += blockSize; 12995 array[i].toArray(r, offset); 12996 } 12997 } 12998 12999 return r; 13000 } 13001 13002 function arraysEqual(a, b) { 13003 if (a.length !== b.length) return false; 13004 13005 for (let i = 0, l = a.length; i < l; i++) { 13006 if (a[i] !== b[i]) return false; 13007 } 13008 13009 return true; 13010 } 13011 13012 function copyArray(a, b) { 13013 for (let i = 0, l = b.length; i < l; i++) { 13014 a[i] = b[i]; 13015 } 13016 } // Texture unit allocation 13017 13018 13019 function allocTexUnits(textures, n) { 13020 let r = arrayCacheI32[n]; 13021 13022 if (r === undefined) { 13023 r = new Int32Array(n); 13024 arrayCacheI32[n] = r; 13025 } 13026 13027 for (let i = 0; i !== n; ++i) { 13028 r[i] = textures.allocateTextureUnit(); 13029 } 13030 13031 return r; 13032 } // --- Setters --- 13033 // Note: Defining these methods externally, because they come in a bunch 13034 // and this way their names minify. 13035 // Single scalar 13036 13037 13038 function setValueV1f(gl, v) { 13039 const cache = this.cache; 13040 if (cache[0] === v) return; 13041 gl.uniform1f(this.addr, v); 13042 cache[0] = v; 13043 } // Single float vector (from flat array or THREE.VectorN) 13044 13045 13046 function setValueV2f(gl, v) { 13047 const cache = this.cache; 13048 13049 if (v.x !== undefined) { 13050 if (cache[0] !== v.x || cache[1] !== v.y) { 13051 gl.uniform2f(this.addr, v.x, v.y); 13052 cache[0] = v.x; 13053 cache[1] = v.y; 13054 } 13055 } else { 13056 if (arraysEqual(cache, v)) return; 13057 gl.uniform2fv(this.addr, v); 13058 copyArray(cache, v); 13059 } 13060 } 13061 13062 function setValueV3f(gl, v) { 13063 const cache = this.cache; 13064 13065 if (v.x !== undefined) { 13066 if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) { 13067 gl.uniform3f(this.addr, v.x, v.y, v.z); 13068 cache[0] = v.x; 13069 cache[1] = v.y; 13070 cache[2] = v.z; 13071 } 13072 } else if (v.r !== undefined) { 13073 if (cache[0] !== v.r || cache[1] !== v.g || cache[2] !== v.b) { 13074 gl.uniform3f(this.addr, v.r, v.g, v.b); 13075 cache[0] = v.r; 13076 cache[1] = v.g; 13077 cache[2] = v.b; 13078 } 13079 } else { 13080 if (arraysEqual(cache, v)) return; 13081 gl.uniform3fv(this.addr, v); 13082 copyArray(cache, v); 13083 } 13084 } 13085 13086 function setValueV4f(gl, v) { 13087 const cache = this.cache; 13088 13089 if (v.x !== undefined) { 13090 if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z || cache[3] !== v.w) { 13091 gl.uniform4f(this.addr, v.x, v.y, v.z, v.w); 13092 cache[0] = v.x; 13093 cache[1] = v.y; 13094 cache[2] = v.z; 13095 cache[3] = v.w; 13096 } 13097 } else { 13098 if (arraysEqual(cache, v)) return; 13099 gl.uniform4fv(this.addr, v); 13100 copyArray(cache, v); 13101 } 13102 } // Single matrix (from flat array or THREE.MatrixN) 13103 13104 13105 function setValueM2(gl, v) { 13106 const cache = this.cache; 13107 const elements = v.elements; 13108 13109 if (elements === undefined) { 13110 if (arraysEqual(cache, v)) return; 13111 gl.uniformMatrix2fv(this.addr, false, v); 13112 copyArray(cache, v); 13113 } else { 13114 if (arraysEqual(cache, elements)) return; 13115 mat2array.set(elements); 13116 gl.uniformMatrix2fv(this.addr, false, mat2array); 13117 copyArray(cache, elements); 13118 } 13119 } 13120 13121 function setValueM3(gl, v) { 13122 const cache = this.cache; 13123 const elements = v.elements; 13124 13125 if (elements === undefined) { 13126 if (arraysEqual(cache, v)) return; 13127 gl.uniformMatrix3fv(this.addr, false, v); 13128 copyArray(cache, v); 13129 } else { 13130 if (arraysEqual(cache, elements)) return; 13131 mat3array.set(elements); 13132 gl.uniformMatrix3fv(this.addr, false, mat3array); 13133 copyArray(cache, elements); 13134 } 13135 } 13136 13137 function setValueM4(gl, v) { 13138 const cache = this.cache; 13139 const elements = v.elements; 13140 13141 if (elements === undefined) { 13142 if (arraysEqual(cache, v)) return; 13143 gl.uniformMatrix4fv(this.addr, false, v); 13144 copyArray(cache, v); 13145 } else { 13146 if (arraysEqual(cache, elements)) return; 13147 mat4array.set(elements); 13148 gl.uniformMatrix4fv(this.addr, false, mat4array); 13149 copyArray(cache, elements); 13150 } 13151 } // Single integer / boolean 13152 13153 13154 function setValueV1i(gl, v) { 13155 const cache = this.cache; 13156 if (cache[0] === v) return; 13157 gl.uniform1i(this.addr, v); 13158 cache[0] = v; 13159 }
vendor: 20,137 bytes, lines 13159-13945
13159 // Single integer / boolean vector (from flat array) 13160 13161 13162 function setValueV2i(gl, v) { 13163 const cache = this.cache; 13164 if (arraysEqual(cache, v)) return; 13165 gl.uniform2iv(this.addr, v); 13166 copyArray(cache, v); 13167 } 13168 13169 function setValueV3i(gl, v) { 13170 const cache = this.cache; 13171 if (arraysEqual(cache, v)) return; 13172 gl.uniform3iv(this.addr, v); 13173 copyArray(cache, v); 13174 } 13175 13176 function setValueV4i(gl, v) { 13177 const cache = this.cache; 13178 if (arraysEqual(cache, v)) return; 13179 gl.uniform4iv(this.addr, v); 13180 copyArray(cache, v); 13181 } // Single unsigned integer 13182 13183 13184 function setValueV1ui(gl, v) { 13185 const cache = this.cache; 13186 if (cache[0] === v) return; 13187 gl.uniform1ui(this.addr, v); 13188 cache[0] = v; 13189 } // Single unsigned integer vector (from flat array) 13190 13191 13192 function setValueV2ui(gl, v) { 13193 const cache = this.cache; 13194 if (arraysEqual(cache, v)) return; 13195 gl.uniform2uiv(this.addr, v); 13196 copyArray(cache, v); 13197 } 13198 13199 function setValueV3ui(gl, v) { 13200 const cache = this.cache; 13201 if (arraysEqual(cache, v)) return; 13202 gl.uniform3uiv(this.addr, v); 13203 copyArray(cache, v); 13204 } 13205 13206 function setValueV4ui(gl, v) { 13207 const cache = this.cache; 13208 if (arraysEqual(cache, v)) return; 13209 gl.uniform4uiv(this.addr, v); 13210 copyArray(cache, v); 13211 } // Single texture (2D / Cube) 13212 13213 13214 function setValueT1(gl, v, textures) { 13215 const cache = this.cache; 13216 const unit = textures.allocateTextureUnit(); 13217 13218 if (cache[0] !== unit) { 13219 gl.uniform1i(this.addr, unit); 13220 cache[0] = unit; 13221 } 13222 13223 textures.safeSetTexture2D(v || emptyTexture, unit); 13224 } 13225 13226 function setValueT3D1(gl, v, textures) { 13227 const cache = this.cache; 13228 const unit = textures.allocateTextureUnit(); 13229 13230 if (cache[0] !== unit) { 13231 gl.uniform1i(this.addr, unit); 13232 cache[0] = unit; 13233 } 13234 13235 textures.setTexture3D(v || emptyTexture3d, unit); 13236 } 13237 13238 function setValueT6(gl, v, textures) { 13239 const cache = this.cache; 13240 const unit = textures.allocateTextureUnit(); 13241 13242 if (cache[0] !== unit) { 13243 gl.uniform1i(this.addr, unit); 13244 cache[0] = unit; 13245 } 13246 13247 textures.safeSetTextureCube(v || emptyCubeTexture, unit); 13248 } 13249 13250 function setValueT2DArray1(gl, v, textures) { 13251 const cache = this.cache; 13252 const unit = textures.allocateTextureUnit(); 13253 13254 if (cache[0] !== unit) { 13255 gl.uniform1i(this.addr, unit); 13256 cache[0] = unit; 13257 } 13258 13259 textures.setTexture2DArray(v || emptyTexture2dArray, unit); 13260 } // Helper to pick the right setter for the singular case 13261 13262 13263 function getSingularSetter(type) { 13264 switch (type) { 13265 case 0x1406: 13266 return setValueV1f; 13267 // FLOAT 13268 13269 case 0x8b50: 13270 return setValueV2f; 13271 // _VEC2 13272 13273 case 0x8b51: 13274 return setValueV3f; 13275 // _VEC3 13276 13277 case 0x8b52: 13278 return setValueV4f; 13279 // _VEC4 13280 13281 case 0x8b5a: 13282 return setValueM2; 13283 // _MAT2 13284 13285 case 0x8b5b: 13286 return setValueM3; 13287 // _MAT3 13288 13289 case 0x8b5c: 13290 return setValueM4; 13291 // _MAT4 13292 13293 case 0x1404: 13294 case 0x8b56: 13295 return setValueV1i; 13296 // INT, BOOL 13297 13298 case 0x8b53: 13299 case 0x8b57: 13300 return setValueV2i; 13301 // _VEC2 13302 13303 case 0x8b54: 13304 case 0x8b58: 13305 return setValueV3i; 13306 // _VEC3 13307 13308 case 0x8b55: 13309 case 0x8b59: 13310 return setValueV4i; 13311 // _VEC4 13312 13313 case 0x1405: 13314 return setValueV1ui; 13315 // UINT 13316 13317 case 0x8dc6: 13318 return setValueV2ui; 13319 // _VEC2 13320 13321 case 0x8dc7: 13322 return setValueV3ui; 13323 // _VEC3 13324 13325 case 0x8dc8: 13326 return setValueV4ui; 13327 // _VEC4 13328 13329 case 0x8b5e: // SAMPLER_2D 13330 13331 case 0x8d66: // SAMPLER_EXTERNAL_OES 13332 13333 case 0x8dca: // INT_SAMPLER_2D 13334 13335 case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D 13336 13337 case 0x8b62: 13338 // SAMPLER_2D_SHADOW 13339 return setValueT1; 13340 13341 case 0x8b5f: // SAMPLER_3D 13342 13343 case 0x8dcb: // INT_SAMPLER_3D 13344 13345 case 0x8dd3: 13346 // UNSIGNED_INT_SAMPLER_3D 13347 return setValueT3D1; 13348 13349 case 0x8b60: // SAMPLER_CUBE 13350 13351 case 0x8dcc: // INT_SAMPLER_CUBE 13352 13353 case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE 13354 13355 case 0x8dc5: 13356 // SAMPLER_CUBE_SHADOW 13357 return setValueT6; 13358 13359 case 0x8dc1: // SAMPLER_2D_ARRAY 13360 13361 case 0x8dcf: // INT_SAMPLER_2D_ARRAY 13362 13363 case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY 13364 13365 case 0x8dc4: 13366 // SAMPLER_2D_ARRAY_SHADOW 13367 return setValueT2DArray1; 13368 } 13369 } // Array of scalars 13370 13371 13372 function setValueV1fArray(gl, v) { 13373 gl.uniform1fv(this.addr, v); 13374 } // Array of vectors (from flat array or array of THREE.VectorN) 13375 13376 13377 function setValueV2fArray(gl, v) { 13378 const data = flatten(v, this.size, 2); 13379 gl.uniform2fv(this.addr, data); 13380 } 13381 13382 function setValueV3fArray(gl, v) { 13383 const data = flatten(v, this.size, 3); 13384 gl.uniform3fv(this.addr, data); 13385 } 13386 13387 function setValueV4fArray(gl, v) { 13388 const data = flatten(v, this.size, 4); 13389 gl.uniform4fv(this.addr, data); 13390 } // Array of matrices (from flat array or array of THREE.MatrixN) 13391 13392 13393 function setValueM2Array(gl, v) { 13394 const data = flatten(v, this.size, 4); 13395 gl.uniformMatrix2fv(this.addr, false, data); 13396 } 13397 13398 function setValueM3Array(gl, v) { 13399 const data = flatten(v, this.size, 9); 13400 gl.uniformMatrix3fv(this.addr, false, data); 13401 } 13402 13403 function setValueM4Array(gl, v) { 13404 const data = flatten(v, this.size, 16); 13405 gl.uniformMatrix4fv(this.addr, false, data); 13406 } // Array of integer / boolean 13407 13408 13409 function setValueV1iArray(gl, v) { 13410 gl.uniform1iv(this.addr, v); 13411 } // Array of integer / boolean vectors (from flat array) 13412 13413 13414 function setValueV2iArray(gl, v) { 13415 gl.uniform2iv(this.addr, v); 13416 } 13417 13418 function setValueV3iArray(gl, v) { 13419 gl.uniform3iv(this.addr, v); 13420 } 13421 13422 function setValueV4iArray(gl, v) { 13423 gl.uniform4iv(this.addr, v); 13424 } // Array of unsigned integer 13425 13426 13427 function setValueV1uiArray(gl, v) { 13428 gl.uniform1uiv(this.addr, v); 13429 } // Array of unsigned integer vectors (from flat array) 13430 13431 13432 function setValueV2uiArray(gl, v) { 13433 gl.uniform2uiv(this.addr, v); 13434 } 13435 13436 function setValueV3uiArray(gl, v) { 13437 gl.uniform3uiv(this.addr, v); 13438 } 13439 13440 function setValueV4uiArray(gl, v) { 13441 gl.uniform4uiv(this.addr, v); 13442 } // Array of textures (2D / 3D / Cube / 2DArray) 13443 13444 13445 function setValueT1Array(gl, v, textures) { 13446 const n = v.length; 13447 const units = allocTexUnits(textures, n); 13448 gl.uniform1iv(this.addr, units); 13449 13450 for (let i = 0; i !== n; ++i) { 13451 textures.safeSetTexture2D(v[i] || emptyTexture, units[i]); 13452 } 13453 } 13454 13455 function setValueT3DArray(gl, v, textures) { 13456 const n = v.length; 13457 const units = allocTexUnits(textures, n); 13458 gl.uniform1iv(this.addr, units); 13459 13460 for (let i = 0; i !== n; ++i) { 13461 textures.setTexture3D(v[i] || emptyTexture3d, units[i]); 13462 } 13463 } 13464 13465 function setValueT6Array(gl, v, textures) { 13466 const n = v.length; 13467 const units = allocTexUnits(textures, n); 13468 gl.uniform1iv(this.addr, units); 13469 13470 for (let i = 0; i !== n; ++i) { 13471 textures.safeSetTextureCube(v[i] || emptyCubeTexture, units[i]); 13472 } 13473 } 13474 13475 function setValueT2DArrayArray(gl, v, textures) { 13476 const n = v.length; 13477 const units = allocTexUnits(textures, n); 13478 gl.uniform1iv(this.addr, units); 13479 13480 for (let i = 0; i !== n; ++i) { 13481 textures.setTexture2DArray(v[i] || emptyTexture2dArray, units[i]); 13482 } 13483 } // Helper to pick the right setter for a pure (bottom-level) array 13484 13485 13486 function getPureArraySetter(type) { 13487 switch (type) { 13488 case 0x1406: 13489 return setValueV1fArray; 13490 // FLOAT 13491 13492 case 0x8b50: 13493 return setValueV2fArray; 13494 // _VEC2 13495 13496 case 0x8b51: 13497 return setValueV3fArray; 13498 // _VEC3 13499 13500 case 0x8b52: 13501 return setValueV4fArray; 13502 // _VEC4 13503 13504 case 0x8b5a: 13505 return setValueM2Array; 13506 // _MAT2 13507 13508 case 0x8b5b: 13509 return setValueM3Array; 13510 // _MAT3 13511 13512 case 0x8b5c: 13513 return setValueM4Array; 13514 // _MAT4 13515 13516 case 0x1404: 13517 case 0x8b56: 13518 return setValueV1iArray; 13519 // INT, BOOL 13520 13521 case 0x8b53: 13522 case 0x8b57: 13523 return setValueV2iArray; 13524 // _VEC2 13525 13526 case 0x8b54: 13527 case 0x8b58: 13528 return setValueV3iArray; 13529 // _VEC3 13530 13531 case 0x8b55: 13532 case 0x8b59: 13533 return setValueV4iArray; 13534 // _VEC4 13535 13536 case 0x1405: 13537 return setValueV1uiArray; 13538 // UINT 13539 13540 case 0x8dc6: 13541 return setValueV2uiArray; 13542 // _VEC2 13543 13544 case 0x8dc7: 13545 return setValueV3uiArray; 13546 // _VEC3 13547 13548 case 0x8dc8: 13549 return setValueV4uiArray; 13550 // _VEC4 13551 13552 case 0x8b5e: // SAMPLER_2D 13553 13554 case 0x8d66: // SAMPLER_EXTERNAL_OES 13555 13556 case 0x8dca: // INT_SAMPLER_2D 13557 13558 case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D 13559 13560 case 0x8b62: 13561 // SAMPLER_2D_SHADOW 13562 return setValueT1Array; 13563 13564 case 0x8b5f: // SAMPLER_3D 13565 13566 case 0x8dcb: // INT_SAMPLER_3D 13567 13568 case 0x8dd3: 13569 // UNSIGNED_INT_SAMPLER_3D 13570 return setValueT3DArray; 13571 13572 case 0x8b60: // SAMPLER_CUBE 13573 13574 case 0x8dcc: // INT_SAMPLER_CUBE 13575 13576 case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE 13577 13578 case 0x8dc5: 13579 // SAMPLER_CUBE_SHADOW 13580 return setValueT6Array; 13581 13582 case 0x8dc1: // SAMPLER_2D_ARRAY 13583 13584 case 0x8dcf: // INT_SAMPLER_2D_ARRAY 13585 13586 case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY 13587 13588 case 0x8dc4: 13589 // SAMPLER_2D_ARRAY_SHADOW 13590 return setValueT2DArrayArray; 13591 } 13592 } // --- Uniform Classes --- 13593 13594 13595 function SingleUniform(id, activeInfo, addr) { 13596 this.id = id; 13597 this.addr = addr; 13598 this.cache = []; 13599 this.setValue = getSingularSetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG 13600 } 13601 13602 function PureArrayUniform(id, activeInfo, addr) { 13603 this.id = id; 13604 this.addr = addr; 13605 this.cache = []; 13606 this.size = activeInfo.size; 13607 this.setValue = getPureArraySetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG 13608 } 13609 13610 PureArrayUniform.prototype.updateCache = function (data) { 13611 const cache = this.cache; 13612 13613 if (data instanceof Float32Array && cache.length !== data.length) { 13614 this.cache = new Float32Array(data.length); 13615 } 13616 13617 copyArray(cache, data); 13618 }; 13619 13620 function StructuredUniform(id) { 13621 this.id = id; 13622 this.seq = []; 13623 this.map = {}; 13624 } 13625 13626 StructuredUniform.prototype.setValue = function (gl, value, textures) { 13627 const seq = this.seq; 13628 13629 for (let i = 0, n = seq.length; i !== n; ++i) { 13630 const u = seq[i]; 13631 u.setValue(gl, value[u.id], textures); 13632 } 13633 }; // --- Top-level --- 13634 // Parser - builds up the property tree from the path strings 13635 13636 13637 const RePathPart = /(\w+)(\])?(\[|\.)?/g; // extracts 13638 // - the identifier (member name or array index) 13639 // - followed by an optional right bracket (found when array index) 13640 // - followed by an optional left bracket or dot (type of subscript) 13641 // 13642 // Note: These portions can be read in a non-overlapping fashion and 13643 // allow straightforward parsing of the hierarchy that WebGL encodes 13644 // in the uniform names. 13645 13646 function addUniform(container, uniformObject) { 13647 container.seq.push(uniformObject); 13648 container.map[uniformObject.id] = uniformObject; 13649 } 13650 13651 function parseUniform(activeInfo, addr, container) { 13652 const path = activeInfo.name, 13653 pathLength = path.length; // reset RegExp object, because of the early exit of a previous run 13654 13655 RePathPart.lastIndex = 0; 13656 13657 while (true) { 13658 const match = RePathPart.exec(path), 13659 matchEnd = RePathPart.lastIndex; 13660 let id = match[1]; 13661 const idIsIndex = match[2] === ']', 13662 subscript = match[3]; 13663 if (idIsIndex) id = id | 0; // convert to integer 13664 13665 if (subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength) { 13666 // bare name or "pure" bottom-level array "[0]" suffix 13667 addUniform(container, subscript === undefined ? new SingleUniform(id, activeInfo, addr) : new PureArrayUniform(id, activeInfo, addr)); 13668 break; 13669 } else { 13670 // step into inner node / create it in case it doesn't exist 13671 const map = container.map; 13672 let next = map[id]; 13673 13674 if (next === undefined) { 13675 next = new StructuredUniform(id); 13676 addUniform(container, next); 13677 } 13678 13679 container = next; 13680 } 13681 } 13682 } // Root Container 13683 13684 13685 function WebGLUniforms(gl, program) { 13686 this.seq = []; 13687 this.map = {}; 13688 const n = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); 13689 13690 for (let i = 0; i < n; ++i) { 13691 const info = gl.getActiveUniform(program, i), 13692 addr = gl.getUniformLocation(program, info.name); 13693 parseUniform(info, addr, this); 13694 } 13695 } 13696 13697 WebGLUniforms.prototype.setValue = function (gl, name, value, textures) { 13698 const u = this.map[name]; 13699 if (u !== undefined) u.setValue(gl, value, textures); 13700 }; 13701 13702 WebGLUniforms.prototype.setOptional = function (gl, object, name) { 13703 const v = object[name]; 13704 if (v !== undefined) this.setValue(gl, name, v); 13705 }; // Static interface 13706 13707 13708 WebGLUniforms.upload = function (gl, seq, values, textures) { 13709 for (let i = 0, n = seq.length; i !== n; ++i) { 13710 const u = seq[i], 13711 v = values[u.id]; 13712 13713 if (v.needsUpdate !== false) { 13714 // note: always updating when .needsUpdate is undefined 13715 u.setValue(gl, v.value, textures); 13716 } 13717 } 13718 }; 13719 13720 WebGLUniforms.seqWithValue = function (seq, values) { 13721 const r = []; 13722 13723 for (let i = 0, n = seq.length; i !== n; ++i) { 13724 const u = seq[i]; 13725 if (u.id in values) r.push(u); 13726 } 13727 13728 return r; 13729 }; 13730 13731 function WebGLShader(gl, type, string) { 13732 const shader = gl.createShader(type); 13733 gl.shaderSource(shader, string); 13734 gl.compileShader(shader); 13735 return shader; 13736 } 13737 13738 let programIdCount = 0; 13739 13740 function addLineNumbers(string) { 13741 const lines = string.split('\n'); 13742 13743 for (let i = 0; i < lines.length; i++) { 13744 lines[i] = i + 1 + ': ' + lines[i]; 13745 } 13746 13747 return lines.join('\n'); 13748 } 13749 13750 function getEncodingComponents(encoding) { 13751 switch (encoding) { 13752 case LinearEncoding: 13753 return ['Linear', '( value )']; 13754 13755 case sRGBEncoding: 13756 return ['sRGB', '( value )']; 13757 13758 default: 13759 console.warn('THREE.WebGLProgram: Unsupported encoding:', encoding); 13760 return ['Linear', '( value )']; 13761 } 13762 } 13763 13764 function getShaderErrors(gl, shader, type) { 13765 const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS); 13766 const errors = gl.getShaderInfoLog(shader).trim(); 13767 if (status && errors === '') return ''; // --enable-privileged-webgl-extension 13768 // console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); 13769 13770 return type.toUpperCase() + '\n\n' + errors + '\n\n' + addLineNumbers(gl.getShaderSource(shader)); 13771 } 13772 13773 function getTexelDecodingFunction(functionName, encoding) { 13774 const components = getEncodingComponents(encoding); 13775 return 'vec4 ' + functionName + '( vec4 value ) { return ' + components[0] + 'ToLinear' + components[1] + '; }'; 13776 } 13777 13778 function getTexelEncodingFunction(functionName, encoding) { 13779 const components = getEncodingComponents(encoding); 13780 return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[0] + components[1] + '; }'; 13781 } 13782 13783 function getToneMappingFunction(functionName, toneMapping) { 13784 let toneMappingName; 13785 13786 switch (toneMapping) { 13787 case LinearToneMapping: 13788 toneMappingName = 'Linear'; 13789 break; 13790 13791 case ReinhardToneMapping: 13792 toneMappingName = 'Reinhard'; 13793 break; 13794 13795 case CineonToneMapping: 13796 toneMappingName = 'OptimizedCineon'; 13797 break; 13798 13799 case ACESFilmicToneMapping: 13800 toneMappingName = 'ACESFilmic'; 13801 break; 13802 13803 case CustomToneMapping: 13804 toneMappingName = 'Custom'; 13805 break; 13806 13807 default: 13808 console.warn('THREE.WebGLProgram: Unsupported toneMapping:', toneMapping); 13809 toneMappingName = 'Linear'; 13810 } 13811 13812 return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }'; 13813 } 13814 13815 function generateExtensions(parameters) { 13816 const chunks = [parameters.extensionDerivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.tangentSpaceNormalMap || parameters.clearcoatNormalMap || parameters.flatShading || parameters.shaderID === 'physical' ? '#extension GL_OES_standard_derivatives : enable' : '', (parameters.extensionFragDepth || parameters.logarithmicDepthBuffer) && parameters.rendererExtensionFragDepth ? '#extension GL_EXT_frag_depth : enable' : '', parameters.extensionDrawBuffers && parameters.rendererExtensionDrawBuffers ? '#extension GL_EXT_draw_buffers : require' : '', (parameters.extensionShaderTextureLOD || parameters.envMap || parameters.transmission) && parameters.rendererExtensionShaderTextureLod ? '#extension GL_EXT_shader_texture_lod : enable' : '']; 13817 return chunks.filter(filterEmptyLine).join('\n'); 13818 } 13819 13820 function generateDefines(defines) { 13821 const chunks = []; 13822 13823 for (const name in defines) { 13824 const value = defines[name]; 13825 if (value === false) continue; 13826 chunks.push('#define ' + name + ' ' + value); 13827 } 13828 13829 return chunks.join('\n'); 13830 } 13831 13832 function fetchAttributeLocations(gl, program) { 13833 const attributes = {}; 13834 const n = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); 13835 13836 for (let i = 0; i < n; i++) { 13837 const info = gl.getActiveAttrib(program, i); 13838 const name = info.name; 13839 let locationSize = 1; 13840 if (info.type === gl.FLOAT_MAT2) locationSize = 2; 13841 if (info.type === gl.FLOAT_MAT3) locationSize = 3; 13842 if (info.type === gl.FLOAT_MAT4) locationSize = 4; // console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i ); 13843 13844 attributes[name] = { 13845 type: info.type, 13846 location: gl.getAttribLocation(program, name), 13847 locationSize: locationSize 13848 }; 13849 } 13850 13851 return attributes; 13852 } 13853 13854 function filterEmptyLine(string) { 13855 return string !== ''; 13856 } 13857 13858 function replaceLightNums(string, parameters) { 13859 return string.replace(/NUM_DIR_LIGHTS/g, parameters.numDirLights).replace(/NUM_SPOT_LIGHTS/g, parameters.numSpotLights).replace(/NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g, parameters.numPointLights).replace(/NUM_HEMI_LIGHTS/g, parameters.numHemiLights).replace(/NUM_DIR_LIGHT_SHADOWS/g, parameters.numDirLightShadows).replace(/NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows); 13860 } 13861 13862 function replaceClippingPlaneNums(string, parameters) { 13863 return string.replace(/NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g, parameters.numClippingPlanes - parameters.numClipIntersection); 13864 } // Resolve Includes 13865 13866 13867 const includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm; 13868 13869 function resolveIncludes(string) { 13870 return string.replace(includePattern, includeReplacer); 13871 } 13872 13873 function includeReplacer(match, include) { 13874 const string = ShaderChunk[include]; 13875 13876 if (string === undefined) { 13877 throw new Error('Can not resolve #include <' + include + '>'); 13878 } 13879 13880 return resolveIncludes(string); 13881 } // Unroll Loops 13882 13883 13884 const deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; 13885 const unrollLoopPattern = /#pragma unroll_loop_start\s+for\s*\(\s*int\s+i\s*=\s*(\d+)\s*;\s*i\s*<\s*(\d+)\s*;\s*i\s*\+\+\s*\)\s*{([\s\S]+?)}\s+#pragma unroll_loop_end/g; 13886 13887 function unrollLoops(string) { 13888 return string.replace(unrollLoopPattern, loopReplacer).replace(deprecatedUnrollLoopPattern, deprecatedLoopReplacer); 13889 } 13890 13891 function deprecatedLoopReplacer(match, start, end, snippet) { 13892 console.warn('WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead.'); 13893 return loopReplacer(match, start, end, snippet); 13894 } 13895 13896 function loopReplacer(match, start, end, snippet) { 13897 let string = ''; 13898 13899 for (let i = parseInt(start); i < parseInt(end); i++) { 13900 string += snippet.replace(/\[\s*i\s*\]/g, '[ ' + i + ' ]').replace(/UNROLLED_LOOP_INDEX/g, i); 13901 } 13902 13903 return string; 13904 } // 13905 13906 13907 function generatePrecision(parameters) { 13908 let precisionstring = 'precision ' + parameters.precision + ' float;\nprecision ' + parameters.precision + ' int;'; 13909 13910 if (parameters.precision === 'highp') { 13911 precisionstring += '\n#define HIGH_PRECISION'; 13912 } else if (parameters.precision === 'mediump') { 13913 precisionstring += '\n#define MEDIUM_PRECISION'; 13914 } else if (parameters.precision === 'lowp') { 13915 precisionstring += '\n#define LOW_PRECISION'; 13916 } 13917 13918 return precisionstring; 13919 } 13920 13921 function generateShadowMapTypeDefine(parameters) { 13922 let shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; 13923 13924 if (parameters.shadowMapType === PCFShadowMap) { 13925 shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF'; 13926 } else if (parameters.shadowMapType === PCFSoftShadowMap) { 13927 shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT'; 13928 } else if (parameters.shadowMapType === VSMShadowMap) { 13929 shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM'; 13930 } 13931 13932 return shadowMapTypeDefine; 13933 } 13934 13935 function generateEnvMapTypeDefine(parameters) { 13936 let envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; 13937 13938 if (parameters.envMap) { 13939 switch (parameters.envMapMode) { 13940 case CubeReflectionMapping: 13941 case CubeRefractionMapping: 13942 envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; 13943 break; 13944 13945 case CubeUVReflectionMapping:
13946 case CubeUVRefractionMapping: 13947 envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV'; 13948 break; 13949 } 13950 } 13951 13952 return envMapTypeDefine; 13953 } 13954 13955 function generateEnvMapModeDefine(parameters) { 13956 let envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; 13957 13958 if (parameters.envMap) { 13959 switch (parameters.envMapMode) { 13960 case CubeRefractionMapping: 13961 case CubeUVRefractionMapping: 13962 envMapModeDefine = 'ENVMAP_MODE_REFRACTION'; 13963 break; 13964 } 13965 } 13966 13967 return envMapModeDefine; 13968 } 13969 13970 function generateEnvMapBlendingDefine(parameters) { 13971 let envMapBlendingDefine = 'ENVMAP_BLENDING_NONE'; 13972 13973 if (parameters.envMap) { 13974 switch (parameters.combine) { 13975 case MultiplyOperation: 13976 envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; 13977 break; 13978 13979 case MixOperation: 13980 envMapBlendingDefine = 'ENVMAP_BLENDING_MIX'; 13981 break; 13982 13983 case AddOperation: 13984 envMapBlendingDefine = 'ENVMAP_BLENDING_ADD'; 13985 break; 13986 } 13987 } 13988 13989 return envMapBlendingDefine; 13990 } 13991 13992 function WebGLProgram(renderer, cacheKey, parameters, bindingStates) { 13993 // TODO Send this event to Three.js DevTools
vendor: 12,392 bytes, lines 13994-14048
13994 // console.log( 'WebGLProgram', cacheKey ); 13995 const gl = renderer.getContext(); 13996 const defines = parameters.defines; 13997 let vertexShader = parameters.vertexShader; 13998 let fragmentShader = parameters.fragmentShader; 13999 const shadowMapTypeDefine = generateShadowMapTypeDefine(parameters); 14000 const envMapTypeDefine = generateEnvMapTypeDefine(parameters); 14001 const envMapModeDefine = generateEnvMapModeDefine(parameters); 14002 const envMapBlendingDefine = generateEnvMapBlendingDefine(parameters); 14003 const customExtensions = parameters.isWebGL2 ? '' : generateExtensions(parameters); 14004 const customDefines = generateDefines(defines); 14005 const program = gl.createProgram(); 14006 let prefixVertex, prefixFragment; 14007 let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + '\n' : ''; 14008 14009 if (parameters.isRawShaderMaterial) { 14010 prefixVertex = [customDefines].filter(filterEmptyLine).join('\n'); 14011 14012 if (prefixVertex.length > 0) { 14013 prefixVertex += '\n'; 14014 } 14015 14016 prefixFragment = [customExtensions, customDefines].filter(filterEmptyLine).join('\n'); 14017 14018 if (prefixFragment.length > 0) { 14019 prefixFragment += '\n'; 14020 } 14021 } else { 14022 prefixVertex = [generatePrecision(parameters), '#define SHADER_NAME ' + parameters.shaderName, customDefines, parameters.instancing ? '#define USE_INSTANCING' : '', parameters.instancingColor ? '#define USE_INSTANCING_COLOR' : '', parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '', '#define MAX_BONES ' + parameters.maxBones, parameters.useFog && parameters.fog ? '#define USE_FOG' : '', parameters.useFog && parameters.fogExp2 ? '#define FOG_EXP2' : '', parameters.map ? '#define USE_MAP' : '', parameters.envMap ? '#define USE_ENVMAP' : '', parameters.envMap ? '#define ' + envMapModeDefine : '', parameters.lightMap ? '#define USE_LIGHTMAP' : '', parameters.aoMap ? '#define USE_AOMAP' : '', parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', parameters.bumpMap ? '#define USE_BUMPMAP' : '', parameters.normalMap ? '#define USE_NORMALMAP' : '', parameters.normalMap && parameters.objectSpaceNormalMap ? '#define OBJECTSPACE_NORMALMAP' : '', parameters.normalMap && parameters.tangentSpaceNormalMap ? '#define TANGENTSPACE_NORMALMAP' : '', parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '', parameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.transmission ? '#define USE_TRANSMISSION' : '', parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', parameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '', parameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '', parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors ? '#define USE_COLOR' : '', parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '', parameters.vertexUvs ? '#define USE_UV' : '', parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', parameters.flatShading ? '#define FLAT_SHADED' : '', parameters.skinning ? '#define USE_SKINNING' : '', parameters.useVertexTexture ? '#define BONE_TEXTURE' : '', parameters.morphTargets ? '#define USE_MORPHTARGETS' : '', parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '', parameters.morphTargets && parameters.isWebGL2 ? '#define MORPHTARGETS_TEXTURE' : '', parameters.morphTargets && parameters.isWebGL2 ? '#define MORPHTARGETS_COUNT ' + parameters.morphTargetsCount : '', parameters.doubleSided ? '#define DOUBLE_SIDED' : '', parameters.flipSided ? '#define FLIP_SIDED' : '', parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '', parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ? '#define USE_LOGDEPTHBUF_EXT' : '', 'uniform mat4 modelMatrix;', 'uniform mat4 modelViewMatrix;', 'uniform mat4 projectionMatrix;', 'uniform mat4 viewMatrix;', 'uniform mat3 normalMatrix;', 'uniform vec3 cameraPosition;', 'uniform bool isOrthographic;', '#ifdef USE_INSTANCING', ' attribute mat4 instanceMatrix;', '#endif', '#ifdef USE_INSTANCING_COLOR', ' attribute vec3 instanceColor;', '#endif', 'attribute vec3 position;', 'attribute vec3 normal;', 'attribute vec2 uv;', '#ifdef USE_TANGENT', ' attribute vec4 tangent;', '#endif', '#if defined( USE_COLOR_ALPHA )', ' attribute vec4 color;', '#elif defined( USE_COLOR )', ' attribute vec3 color;', '#endif', '#if ( defined( USE_MORPHTARGETS ) && ! defined( MORPHTARGETS_TEXTURE ) )', ' attribute vec3 morphTarget0;', ' attribute vec3 morphTarget1;', ' attribute vec3 morphTarget2;', ' attribute vec3 morphTarget3;', ' #ifdef USE_MORPHNORMALS', ' attribute vec3 morphNormal0;', ' attribute vec3 morphNormal1;', ' attribute vec3 morphNormal2;', ' attribute vec3 morphNormal3;', ' #else', ' attribute vec3 morphTarget4;', ' attribute vec3 morphTarget5;', ' attribute vec3 morphTarget6;', ' attribute vec3 morphTarget7;', ' #endif', '#endif', '#ifdef USE_SKINNING', ' attribute vec4 skinIndex;', ' attribute vec4 skinWeight;', '#endif', '\n'].filter(filterEmptyLine).join('\n'); 14023 prefixFragment = [customExtensions, generatePrecision(parameters), '#define SHADER_NAME ' + parameters.shaderName, customDefines, parameters.useFog && parameters.fog ? '#define USE_FOG' : '', parameters.useFog && parameters.fogExp2 ? '#define FOG_EXP2' : '', parameters.map ? '#define USE_MAP' : '', parameters.matcap ? '#define USE_MATCAP' : '', parameters.envMap ? '#define USE_ENVMAP' : '', parameters.envMap ? '#define ' + envMapTypeDefine : '', parameters.envMap ? '#define ' + envMapModeDefine : '', parameters.envMap ? '#define ' + envMapBlendingDefine : '', parameters.lightMap ? '#define USE_LIGHTMAP' : '', parameters.aoMap ? '#define USE_AOMAP' : '', parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', parameters.bumpMap ? '#define USE_BUMPMAP' : '', parameters.normalMap ? '#define USE_NORMALMAP' : '', parameters.normalMap && parameters.objectSpaceNormalMap ? '#define OBJECTSPACE_NORMALMAP' : '', parameters.normalMap && parameters.tangentSpaceNormalMap ? '#define TANGENTSPACE_NORMALMAP' : '', parameters.clearcoat ? '#define USE_CLEARCOAT' : '', parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '', parameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.alphaTest ? '#define USE_ALPHATEST' : '', parameters.sheen ? '#define USE_SHEEN' : '', parameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '', parameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '', parameters.transmission ? '#define USE_TRANSMISSION' : '', parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '', parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '', parameters.vertexUvs ? '#define USE_UV' : '', parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', parameters.gradientMap ? '#define USE_GRADIENTMAP' : '', parameters.flatShading ? '#define FLAT_SHADED' : '', parameters.doubleSided ? '#define DOUBLE_SIDED' : '', parameters.flipSided ? '#define FLIP_SIDED' : '', parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '', parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '', parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ? '#define USE_LOGDEPTHBUF_EXT' : '', (parameters.extensionShaderTextureLOD || parameters.envMap) && parameters.rendererExtensionShaderTextureLod ? '#define TEXTURE_LOD_EXT' : '', 'uniform mat4 viewMatrix;', 'uniform vec3 cameraPosition;', 'uniform bool isOrthographic;', parameters.toneMapping !== NoToneMapping ? '#define TONE_MAPPING' : '', parameters.toneMapping !== NoToneMapping ? ShaderChunk['tonemapping_pars_fragment'] : '', // this code is required here because it is used by the toneMapping() function defined below 14024 parameters.toneMapping !== NoToneMapping ? getToneMappingFunction('toneMapping', parameters.toneMapping) : '', parameters.dithering ? '#define DITHERING' : '', parameters.format === RGBFormat ? '#define OPAQUE' : '', ShaderChunk['encodings_pars_fragment'], // this code is required here because it is used by the various encoding/decoding function defined below 14025 parameters.map ? getTexelDecodingFunction('mapTexelToLinear', parameters.mapEncoding) : '', parameters.matcap ? getTexelDecodingFunction('matcapTexelToLinear', parameters.matcapEncoding) : '', parameters.envMap ? getTexelDecodingFunction('envMapTexelToLinear', parameters.envMapEncoding) : '', parameters.emissiveMap ? getTexelDecodingFunction('emissiveMapTexelToLinear', parameters.emissiveMapEncoding) : '', parameters.specularColorMap ? getTexelDecodingFunction('specularColorMapTexelToLinear', parameters.specularColorMapEncoding) : '', parameters.sheenColorMap ? getTexelDecodingFunction('sheenColorMapTexelToLinear', parameters.sheenColorMapEncoding) : '', parameters.lightMap ? getTexelDecodingFunction('lightMapTexelToLinear', parameters.lightMapEncoding) : '', getTexelEncodingFunction('linearToOutputTexel', parameters.outputEncoding), parameters.depthPacking ? '#define DEPTH_PACKING ' + parameters.depthPacking : '', '\n'].filter(filterEmptyLine).join('\n'); 14026 } 14027 14028 vertexShader = resolveIncludes(vertexShader); 14029 vertexShader = replaceLightNums(vertexShader, parameters); 14030 vertexShader = replaceClippingPlaneNums(vertexShader, parameters); 14031 fragmentShader = resolveIncludes(fragmentShader); 14032 fragmentShader = replaceLightNums(fragmentShader, parameters); 14033 fragmentShader = replaceClippingPlaneNums(fragmentShader, parameters); 14034 vertexShader = unrollLoops(vertexShader); 14035 fragmentShader = unrollLoops(fragmentShader); 14036 14037 if (parameters.isWebGL2 && parameters.isRawShaderMaterial !== true) { 14038 // GLSL 3.0 conversion for built-in materials and ShaderMaterial 14039 versionString = '#version 300 es\n'; 14040 prefixVertex = ['precision mediump sampler2DArray;', '#define attribute in', '#define varying out', '#define texture2D texture'].join('\n') + '\n' + prefixVertex; 14041 prefixFragment = ['#define varying in', parameters.glslVersion === GLSL3 ? '' : 'layout(location = 0) out highp vec4 pc_fragColor;', parameters.glslVersion === GLSL3 ? '' : '#define gl_FragColor pc_fragColor', '#define gl_FragDepthEXT gl_FragDepth', '#define texture2D texture', '#define textureCube texture', '#define texture2DProj textureProj', '#define texture2DLodEXT textureLod', '#define texture2DProjLodEXT textureProjLod', '#define textureCubeLodEXT textureLod', '#define texture2DGradEXT textureGrad', '#define texture2DProjGradEXT textureProjGrad', '#define textureCubeGradEXT textureGrad'].join('\n') + '\n' + prefixFragment; 14042 } 14043 14044 const vertexGlsl = versionString + prefixVertex + vertexShader; 14045 const fragmentGlsl = versionString + prefixFragment + fragmentShader; // console.log( '*VERTEX*', vertexGlsl ); 14046 // console.log( '*FRAGMENT*', fragmentGlsl ); 14047 14048 const glVertexShader = WebGLShader(gl, gl.VERTEX_SHADER, vertexGlsl);
vendor: 4,356 bytes, lines 14049-14199
14049 const glFragmentShader = WebGLShader(gl, gl.FRAGMENT_SHADER, fragmentGlsl); 14050 gl.attachShader(program, glVertexShader); 14051 gl.attachShader(program, glFragmentShader); // Force a particular attribute to index 0. 14052 14053 if (parameters.index0AttributeName !== undefined) { 14054 gl.bindAttribLocation(program, 0, parameters.index0AttributeName); 14055 } else if (parameters.morphTargets === true) { 14056 // programs with morphTargets displace position out of attribute 0 14057 gl.bindAttribLocation(program, 0, 'position'); 14058 } 14059 14060 gl.linkProgram(program); // check for link errors 14061 14062 if (renderer.debug.checkShaderErrors) { 14063 const programLog = gl.getProgramInfoLog(program).trim(); 14064 const vertexLog = gl.getShaderInfoLog(glVertexShader).trim(); 14065 const fragmentLog = gl.getShaderInfoLog(glFragmentShader).trim(); 14066 let runnable = true; 14067 let haveDiagnostics = true; 14068 14069 if (gl.getProgramParameter(program, gl.LINK_STATUS) === false) { 14070 runnable = false; 14071 const vertexErrors = getShaderErrors(gl, glVertexShader, 'vertex'); 14072 const fragmentErrors = getShaderErrors(gl, glFragmentShader, 'fragment'); 14073 console.error('THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' + 'VALIDATE_STATUS ' + gl.getProgramParameter(program, gl.VALIDATE_STATUS) + '\n\n' + 'Program Info Log: ' + programLog + '\n' + vertexErrors + '\n' + fragmentErrors); 14074 } else if (programLog !== '') { 14075 console.warn('THREE.WebGLProgram: Program Info Log:', programLog); 14076 } else if (vertexLog === '' || fragmentLog === '') { 14077 haveDiagnostics = false; 14078 } 14079 14080 if (haveDiagnostics) { 14081 this.diagnostics = { 14082 runnable: runnable, 14083 programLog: programLog, 14084 vertexShader: { 14085 log: vertexLog, 14086 prefix: prefixVertex 14087 }, 14088 fragmentShader: { 14089 log: fragmentLog, 14090 prefix: prefixFragment 14091 } 14092 }; 14093 } 14094 } // Clean up 14095 // Crashes in iOS9 and iOS10. #18402 14096 // gl.detachShader( program, glVertexShader ); 14097 // gl.detachShader( program, glFragmentShader ); 14098 14099 14100 gl.deleteShader(glVertexShader); 14101 gl.deleteShader(glFragmentShader); // set up caching for uniform locations 14102 14103 let cachedUniforms; 14104 14105 this.getUniforms = function () { 14106 if (cachedUniforms === undefined) { 14107 cachedUniforms = new WebGLUniforms(gl, program); 14108 } 14109 14110 return cachedUniforms; 14111 }; // set up caching for attribute locations 14112 14113 14114 let cachedAttributes; 14115 14116 this.getAttributes = function () { 14117 if (cachedAttributes === undefined) { 14118 cachedAttributes = fetchAttributeLocations(gl, program); 14119 } 14120 14121 return cachedAttributes; 14122 }; // free resource 14123 14124 14125 this.destroy = function () { 14126 bindingStates.releaseStatesOfProgram(this); 14127 gl.deleteProgram(program); 14128 this.program = undefined; 14129 }; // 14130 14131 14132 this.name = parameters.shaderName; 14133 this.id = programIdCount++; 14134 this.cacheKey = cacheKey; 14135 this.usedTimes = 1; 14136 this.program = program; 14137 this.vertexShader = glVertexShader; 14138 this.fragmentShader = glFragmentShader; 14139 return this; 14140 } 14141 14142 let _id = 0; 14143 14144 class WebGLShaderCache { 14145 constructor() { 14146 this.shaderCache = new Map(); 14147 this.materialCache = new Map(); 14148 } 14149 14150 update(material) { 14151 const vertexShader = material.vertexShader; 14152 const fragmentShader = material.fragmentShader; 14153 14154 const vertexShaderStage = this._getShaderStage(vertexShader); 14155 14156 const fragmentShaderStage = this._getShaderStage(fragmentShader); 14157 14158 const materialShaders = this._getShaderCacheForMaterial(material); 14159 14160 if (materialShaders.has(vertexShaderStage) === false) { 14161 materialShaders.add(vertexShaderStage); 14162 vertexShaderStage.usedTimes++; 14163 } 14164 14165 if (materialShaders.has(fragmentShaderStage) === false) { 14166 materialShaders.add(fragmentShaderStage); 14167 fragmentShaderStage.usedTimes++; 14168 } 14169 14170 return this; 14171 } 14172 14173 remove(material) { 14174 const materialShaders = this.materialCache.get(material); 14175 14176 for (const shaderStage of materialShaders) { 14177 shaderStage.usedTimes--; 14178 if (shaderStage.usedTimes === 0) this.shaderCache.delete(shaderStage); 14179 } 14180 14181 this.materialCache.delete(material); 14182 return this; 14183 } 14184 14185 getVertexShaderID(material) { 14186 return this._getShaderStage(material.vertexShader).id; 14187 } 14188 14189 getFragmentShaderID(material) { 14190 return this._getShaderStage(material.fragmentShader).id; 14191 } 14192 14193 dispose() { 14194 this.shaderCache.clear(); 14195 this.materialCache.clear(); 14196 } 14197 14198 _getShaderCacheForMaterial(material) { 14199 const cache = this.materialCache;
14200 14201 if (cache.has(material) === false) { 14202 cache.set(material, new Set()); 14203 } 14204 14205 return cache.get(material); 14206 } 14207 14208 _getShaderStage(code) { 14209 const cache = this.shaderCache; 14210 14211 if (cache.has(code) === false) { 14212 const stage = new WebGLShaderStage(); 14213 cache.set(code, stage); 14214 } 14215 14216 return cache.get(code); 14217 } 14218 14219 } 14220 14221 class WebGLShaderStage { 14222 constructor() { 14223 this.id = _id++; 14224 this.usedTimes = 0; 14225 } 14226 14227 } 14228 14229 function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping) { 14230 const _programLayers = new Layers(); 14231 14232 const _customShaders = new WebGLShaderCache(); 14233 14234 const programs = []; 14235 const isWebGL2 = capabilities.isWebGL2; 14236 const logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer; 14237 const floatVertexTextures = capabilities.floatVertexTextures; 14238 const maxVertexUniforms = capabilities.maxVertexUniforms; 14239 const vertexTextures = capabilities.vertexTextures; 14240 let precision = capabilities.precision; 14241 const shaderIDs = { 14242 MeshDepthMaterial: 'depth', 14243 MeshDistanceMaterial: 'distanceRGBA', 14244 MeshNormalMaterial: 'normal', 14245 MeshBasicMaterial: 'basic', 14246 MeshLambertMaterial: 'lambert', 14247 MeshPhongMaterial: 'phong', 14248 MeshToonMaterial: 'toon', 14249 MeshStandardMaterial: 'physical', 14250 MeshPhysicalMaterial: 'physical', 14251 MeshMatcapMaterial: 'matcap', 14252 LineBasicMaterial: 'basic', 14253 LineDashedMaterial: 'dashed', 14254 PointsMaterial: 'points', 14255 ShadowMaterial: 'shadow', 14256 SpriteMaterial: 'sprite' 14257 }; 14258 14259 function getMaxBones(object) { 14260 const skeleton = object.skeleton; 14261 const bones = skeleton.bones; 14262 14263 if (floatVertexTextures) { 14264 return 1024; 14265 } else { 14266 // default for when object is not specified 14267 // ( for example when prebuilding shader to be used with multiple objects ) 14268 // 14269 // - leave some extra space for other uniforms 14270 // - limit here is ANGLE's 254 max uniform vectors 14271 // (up to 54 should be safe) 14272 const nVertexUniforms = maxVertexUniforms; 14273 const nVertexMatrices = Math.floor((nVertexUniforms - 20) / 4); 14274 const maxBones = Math.min(nVertexMatrices, bones.length); 14275 14276 if (maxBones < bones.length) { 14277 console.warn('THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.'); 14278 return 0; 14279 } 14280 14281 return maxBones; 14282 } 14283 } 14284 14285 function getTextureEncodingFromMap(map) { 14286 let encoding; 14287 14288 if (map && map.isTexture) { 14289 encoding = map.encoding; 14290 } else if (map && map.isWebGLRenderTarget) { 14291 console.warn('THREE.WebGLPrograms.getTextureEncodingFromMap: don\'t use render targets as textures. Use their .texture property instead.'); 14292 encoding = map.texture.encoding; 14293 } else { 14294 encoding = LinearEncoding; 14295 } 14296 14297 if (isWebGL2 && map && map.isTexture && map.format === RGBAFormat && map.type === UnsignedByteType && map.encoding === sRGBEncoding) { 14298 encoding = LinearEncoding; // disable inline decode for sRGB textures in WebGL 2 14299 } 14300 14301 return encoding; 14302 } 14303 14304 function getParameters(material, lights, shadows, scene, object) { 14305 const fog = scene.fog; 14306 const environment = material.isMeshStandardMaterial ? scene.environment : null; 14307 const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment); 14308 const shaderID = shaderIDs[material.type]; // heuristics to create shader parameters according to lights in the scene 14309 // (not to blow over maxLights budget) 14310 14311 const maxBones = object.isSkinnedMesh ? getMaxBones(object) : 0; 14312 14313 if (material.precision !== null) { 14314 precision = capabilities.getMaxPrecision(material.precision); 14315 14316 if (precision !== material.precision) { 14317 console.warn('THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.'); 14318 } 14319 } 14320 14321 let vertexShader, fragmentShader; 14322 let customVertexShaderID, customFragmentShaderID; 14323 14324 if (shaderID) { 14325 const shader = ShaderLib[shaderID]; 14326 vertexShader = shader.vertexShader; 14327 fragmentShader = shader.fragmentShader; 14328 } else { 14329 vertexShader = material.vertexShader; 14330 fragmentShader = material.fragmentShader; 14331 14332 _customShaders.update(material); 14333 14334 customVertexShaderID = _customShaders.getVertexShaderID(material); 14335 customFragmentShaderID = _customShaders.getFragmentShaderID(material); 14336 } 14337 14338 const currentRenderTarget = renderer.getRenderTarget(); 14339 const useAlphaTest = material.alphaTest > 0; 14340 const useClearcoat = material.clearcoat > 0; 14341 const parameters = { 14342 isWebGL2: isWebGL2, 14343 shaderID: shaderID, 14344 shaderName: material.type, 14345 vertexShader: vertexShader, 14346 fragmentShader: fragmentShader, 14347 defines: material.defines, 14348 customVertexShaderID: customVertexShaderID, 14349 customFragmentShaderID: customFragmentShaderID, 14350 isRawShaderMaterial: material.isRawShaderMaterial === true, 14351 glslVersion: material.glslVersion, 14352 precision: precision,
14353 instancing: object.isInstancedMesh === true, 14354 instancingColor: object.isInstancedMesh === true && object.instanceColor !== null, 14355 supportsVertexTextures: vertexTextures, 14356 outputEncoding: currentRenderTarget !== null ? getTextureEncodingFromMap(currentRenderTarget.texture) : renderer.outputEncoding, 14357 map: !!material.map, 14358 mapEncoding: getTextureEncodingFromMap(material.map), 14359 matcap: !!material.matcap, 14360 matcapEncoding: getTextureEncodingFromMap(material.matcap), 14361 envMap: !!envMap, 14362 envMapMode: envMap && envMap.mapping, 14363 envMapEncoding: getTextureEncodingFromMap(envMap), 14364 envMapCubeUV: !!envMap && (envMap.mapping === CubeUVReflectionMapping || envMap.mapping === CubeUVRefractionMapping), 14365 lightMap: !!material.lightMap, 14366 lightMapEncoding: getTextureEncodingFromMap(material.lightMap), 14367 aoMap: !!material.aoMap, 14368 emissiveMap: !!material.emissiveMap, 14369 emissiveMapEncoding: getTextureEncodingFromMap(material.emissiveMap), 14370 bumpMap: !!material.bumpMap, 14371 normalMap: !!material.normalMap, 14372 objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap, 14373 tangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap, 14374 clearcoat: useClearcoat, 14375 clearcoatMap: useClearcoat && !!material.clearcoatMap, 14376 clearcoatRoughnessMap: useClearcoat && !!material.clearcoatRoughnessMap, 14377 clearcoatNormalMap: useClearcoat && !!material.clearcoatNormalMap, 14378 displacementMap: !!material.displacementMap, 14379 roughnessMap: !!material.roughnessMap, 14380 metalnessMap: !!material.metalnessMap, 14381 specularMap: !!material.specularMap, 14382 specularIntensityMap: !!material.specularIntensityMap, 14383 specularColorMap: !!material.specularColorMap, 14384 specularColorMapEncoding: getTextureEncodingFromMap(material.specularColorMap), 14385 alphaMap: !!material.alphaMap, 14386 alphaTest: useAlphaTest, 14387 gradientMap: !!material.gradientMap, 14388 sheen: material.sheen > 0, 14389 sheenColorMap: !!material.sheenColorMap, 14390 sheenColorMapEncoding: getTextureEncodingFromMap(material.sheenColorMap), 14391 sheenRoughnessMap: !!material.sheenRoughnessMap, 14392 transmission: material.transmission > 0, 14393 transmissionMap: !!material.transmissionMap, 14394 thicknessMap: !!material.thicknessMap, 14395 combine: material.combine, 14396 vertexTangents: !!material.normalMap && !!object.geometry && !!object.geometry.attributes.tangent, 14397 vertexColors: material.vertexColors, 14398 vertexAlphas: material.vertexColors === true && !!object.geometry && !!object.geometry.attributes.color && object.geometry.attributes.color.itemSize === 4, 14399 vertexUvs: !!material.map || !!material.bumpMap || !!material.normalMap || !!material.specularMap || !!material.alphaMap || !!material.emissiveMap || !!material.roughnessMap || !!material.metalnessMap || !!material.clearcoatMap || !!material.clearcoatRoughnessMap || !!material.clearcoatNormalMap || !!material.displacementMap || !!material.transmissionMap || !!material.thicknessMap || !!material.specularIntensityMap || !!material.specularColorMap || !!material.sheenColorMap || !!material.sheenRoughnessMap, 14400 uvsVertexOnly: !(!!material.map || !!material.bumpMap || !!material.normalMap || !!material.specularMap || !!material.alphaMap || !!material.emissiveMap || !!material.roughnessMap || !!material.metalnessMap || !!material.clearcoatNormalMap || material.transmission > 0 || !!material.transmissionMap || !!material.thicknessMap || !!material.specularIntensityMap || !!material.specularColorMap || material.sheen > 0 || !!material.sheenColorMap || !!material.sheenRoughnessMap) && !!material.displacementMap, 14401 fog: !!fog, 14402 useFog: material.fog, 14403 fogExp2: fog && fog.isFogExp2, 14404 flatShading: !!material.flatShading, 14405 sizeAttenuation: material.sizeAttenuation, 14406 logarithmicDepthBuffer: logarithmicDepthBuffer, 14407 skinning: object.isSkinnedMesh === true && maxBones > 0, 14408 maxBones: maxBones, 14409 useVertexTexture: floatVertexTextures, 14410 morphTargets: !!object.geometry && !!object.geometry.morphAttributes.position, 14411 morphNormals: !!object.geometry && !!object.geometry.morphAttributes.normal, 14412 morphTargetsCount: !!object.geometry && !!object.geometry.morphAttributes.position ? object.geometry.morphAttributes.position.length : 0, 14413 numDirLights: lights.directional.length, 14414 numPointLights: lights.point.length, 14415 numSpotLights: lights.spot.length, 14416 numRectAreaLights: lights.rectArea.length, 14417 numHemiLights: lights.hemi.length, 14418 numDirLightShadows: lights.directionalShadowMap.length, 14419 numPointLightShadows: lights.pointShadowMap.length, 14420 numSpotLightShadows: lights.spotShadowMap.length, 14421 numClippingPlanes: clipping.numPlanes, 14422 numClipIntersection: clipping.numIntersection, 14423 format: material.format, 14424 dithering: material.dithering, 14425 shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0, 14426 shadowMapType: renderer.shadowMap.type, 14427 toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping, 14428 physicallyCorrectLights: renderer.physicallyCorrectLights, 14429 premultipliedAlpha: material.premultipliedAlpha, 14430 doubleSided: material.side === DoubleSide, 14431 flipSided: material.side === BackSide, 14432 depthPacking: material.depthPacking !== undefined ? material.depthPacking : false, 14433 index0AttributeName: material.index0AttributeName, 14434 extensionDerivatives: material.extensions && material.extensions.derivatives, 14435 extensionFragDepth: material.extensions && material.extensions.fragDepth, 14436 extensionDrawBuffers: material.extensions && material.extensions.drawBuffers, 14437 extensionShaderTextureLOD: material.extensions && material.extensions.shaderTextureLOD, 14438 rendererExtensionFragDepth: isWebGL2 || extensions.has('EXT_frag_depth'), 14439 rendererExtensionDrawBuffers: isWebGL2 || extensions.has('WEBGL_draw_buffers'), 14440 rendererExtensionShaderTextureLod: isWebGL2 || extensions.has('EXT_shader_texture_lod'), 14441 customProgramCacheKey: material.customProgramCacheKey() 14442 }; 14443 return parameters; 14444 } 14445 14446 function getProgramCacheKey(parameters) { 14447 const array = []; 14448 14449 if (parameters.shaderID) { 14450 array.push(parameters.shaderID); 14451 } else { 14452 array.push(parameters.customVertexShaderID); 14453 array.push(parameters.customFragmentShaderID); 14454 } 14455 14456 if (parameters.defines !== undefined) { 14457 for (const name in parameters.defines) { 14458 array.push(name); 14459 array.push(parameters.defines[name]); 14460 } 14461 } 14462 14463 if (parameters.isRawShaderMaterial === false) { 14464 getProgramCacheKeyParameters(array, parameters); 14465 getProgramCacheKeyBooleans(array, parameters); 14466 array.push(renderer.outputEncoding); 14467 } 14468 14469 array.push(parameters.customProgramCacheKey); 14470 return array.join(); 14471 } 14472 14473 function getProgramCacheKeyParameters(array, parameters) { 14474 array.push(parameters.precision); 14475 array.push(parameters.outputEncoding); 14476 array.push(parameters.mapEncoding);
14477 array.push(parameters.matcapEncoding); 14478 array.push(parameters.envMapMode); 14479 array.push(parameters.envMapEncoding); 14480 array.push(parameters.lightMapEncoding); 14481 array.push(parameters.emissiveMapEncoding); 14482 array.push(parameters.combine); 14483 array.push(parameters.vertexUvs); 14484 array.push(parameters.fogExp2); 14485 array.push(parameters.sizeAttenuation); 14486 array.push(parameters.maxBones); 14487 array.push(parameters.morphTargetsCount); 14488 array.push(parameters.numDirLights); 14489 array.push(parameters.numPointLights); 14490 array.push(parameters.numSpotLights); 14491 array.push(parameters.numHemiLights); 14492 array.push(parameters.numRectAreaLights); 14493 array.push(parameters.numDirLightShadows); 14494 array.push(parameters.numPointLightShadows); 14495 array.push(parameters.numSpotLightShadows); 14496 array.push(parameters.shadowMapType); 14497 array.push(parameters.toneMapping); 14498 array.push(parameters.numClippingPlanes); 14499 array.push(parameters.numClipIntersection); 14500 array.push(parameters.format); 14501 array.push(parameters.specularColorMapEncoding); 14502 array.push(parameters.sheenColorMapEncoding); 14503 } 14504 14505 function getProgramCacheKeyBooleans(array, parameters) { 14506 _programLayers.disableAll(); 14507 14508 if (parameters.isWebGL2) _programLayers.enable(0); 14509 if (parameters.supportsVertexTextures) _programLayers.enable(1); 14510 if (parameters.instancing) _programLayers.enable(2); 14511 if (parameters.instancingColor) _programLayers.enable(3); 14512 if (parameters.map) _programLayers.enable(4); 14513 if (parameters.matcap) _programLayers.enable(5); 14514 if (parameters.envMap) _programLayers.enable(6); 14515 if (parameters.envMapCubeUV) _programLayers.enable(7); 14516 if (parameters.lightMap) _programLayers.enable(8); 14517 if (parameters.aoMap) _programLayers.enable(9); 14518 if (parameters.emissiveMap) _programLayers.enable(10); 14519 if (parameters.bumpMap) _programLayers.enable(11); 14520 if (parameters.normalMap) _programLayers.enable(12); 14521 if (parameters.objectSpaceNormalMap) _programLayers.enable(13); 14522 if (parameters.tangentSpaceNormalMap) _programLayers.enable(14); 14523 if (parameters.clearcoat) _programLayers.enable(15); 14524 if (parameters.clearcoatMap) _programLayers.enable(16); 14525 if (parameters.clearcoatRoughnessMap) _programLayers.enable(17); 14526 if (parameters.clearcoatNormalMap) _programLayers.enable(18); 14527 if (parameters.displacementMap) _programLayers.enable(19); 14528 if (parameters.specularMap) _programLayers.enable(20); 14529 if (parameters.roughnessMap) _programLayers.enable(21); 14530 if (parameters.metalnessMap) _programLayers.enable(22); 14531 if (parameters.gradientMap) _programLayers.enable(23); 14532 if (parameters.alphaMap) _programLayers.enable(24); 14533 if (parameters.alphaTest) _programLayers.enable(25); 14534 if (parameters.vertexColors) _programLayers.enable(26); 14535 if (parameters.vertexAlphas) _programLayers.enable(27); 14536 if (parameters.vertexUvs) _programLayers.enable(28); 14537 if (parameters.vertexTangents) _programLayers.enable(29); 14538 if (parameters.uvsVertexOnly) _programLayers.enable(30); 14539 if (parameters.fog) _programLayers.enable(31); 14540 array.push(_programLayers.mask); 14541 14542 _programLayers.disableAll(); 14543 14544 if (parameters.useFog) _programLayers.enable(0); 14545 if (parameters.flatShading) _programLayers.enable(1); 14546 if (parameters.logarithmicDepthBuffer) _programLayers.enable(2); 14547 if (parameters.skinning) _programLayers.enable(3); 14548 if (parameters.useVertexTexture) _programLayers.enable(4); 14549 if (parameters.morphTargets) _programLayers.enable(5); 14550 if (parameters.morphNormals) _programLayers.enable(6); 14551 if (parameters.premultipliedAlpha) _programLayers.enable(7); 14552 if (parameters.shadowMapEnabled) _programLayers.enable(8); 14553 if (parameters.physicallyCorrectLights) _programLayers.enable(9); 14554 if (parameters.doubleSided) _programLayers.enable(10); 14555 if (parameters.flipSided) _programLayers.enable(11); 14556 if (parameters.depthPacking) _programLayers.enable(12); 14557 if (parameters.dithering) _programLayers.enable(13); 14558 if (parameters.specularIntensityMap) _programLayers.enable(14); 14559 if (parameters.specularColorMap) _programLayers.enable(15); 14560 if (parameters.transmission) _programLayers.enable(16); 14561 if (parameters.transmissionMap) _programLayers.enable(17); 14562 if (parameters.thicknessMap) _programLayers.enable(18); 14563 if (parameters.sheen) _programLayers.enable(19); 14564 if (parameters.sheenColorMap) _programLayers.enable(20); 14565 if (parameters.sheenRoughnessMap) _programLayers.enable(21); 14566 array.push(_programLayers.mask); 14567 } 14568 14569 function getUniforms(material) { 14570 const shaderID = shaderIDs[material.type]; 14571 let uniforms; 14572 14573 if (shaderID) { 14574 const shader = ShaderLib[shaderID]; 14575 uniforms = UniformsUtils.clone(shader.uniforms); 14576 } else { 14577 uniforms = material.uniforms; 14578 } 14579 14580 return uniforms; 14581 } 14582 14583 function acquireProgram(parameters, cacheKey) { 14584 let program; // Check if code has been already compiled 14585 14586 for (let p = 0, pl = programs.length; p < pl; p++) {
vendor: 17,332 bytes, lines 14587-15190
14587 const preexistingProgram = programs[p]; 14588 14589 if (preexistingProgram.cacheKey === cacheKey) { 14590 program = preexistingProgram; 14591 ++program.usedTimes; 14592 break; 14593 } 14594 } 14595 14596 if (program === undefined) { 14597 program = new WebGLProgram(renderer, cacheKey, parameters, bindingStates); 14598 programs.push(program); 14599 } 14600 14601 return program; 14602 } 14603 14604 function releaseProgram(program) { 14605 if (--program.usedTimes === 0) { 14606 // Remove from unordered set 14607 const i = programs.indexOf(program); 14608 programs[i] = programs[programs.length - 1]; 14609 programs.pop(); // Free WebGL resources 14610 14611 program.destroy(); 14612 } 14613 } 14614 14615 function releaseShaderCache(material) { 14616 _customShaders.remove(material); 14617 } 14618 14619 function dispose() { 14620 _customShaders.dispose(); 14621 } 14622 14623 return { 14624 getParameters: getParameters, 14625 getProgramCacheKey: getProgramCacheKey, 14626 getUniforms: getUniforms, 14627 acquireProgram: acquireProgram, 14628 releaseProgram: releaseProgram, 14629 releaseShaderCache: releaseShaderCache, 14630 // Exposed for resource monitoring & error feedback via renderer.info: 14631 programs: programs, 14632 dispose: dispose 14633 }; 14634 } 14635 14636 function WebGLProperties() { 14637 let properties = new WeakMap(); 14638 14639 function get(object) { 14640 let map = properties.get(object); 14641 14642 if (map === undefined) { 14643 map = {}; 14644 properties.set(object, map); 14645 } 14646 14647 return map; 14648 } 14649 14650 function remove(object) { 14651 properties.delete(object); 14652 } 14653 14654 function update(object, key, value) { 14655 properties.get(object)[key] = value; 14656 } 14657 14658 function dispose() { 14659 properties = new WeakMap(); 14660 } 14661 14662 return { 14663 get: get, 14664 remove: remove, 14665 update: update, 14666 dispose: dispose 14667 }; 14668 } 14669 14670 function painterSortStable(a, b) { 14671 if (a.groupOrder !== b.groupOrder) { 14672 return a.groupOrder - b.groupOrder; 14673 } else if (a.renderOrder !== b.renderOrder) { 14674 return a.renderOrder - b.renderOrder; 14675 } else if (a.material.id !== b.material.id) { 14676 return a.material.id - b.material.id; 14677 } else if (a.z !== b.z) { 14678 return a.z - b.z; 14679 } else { 14680 return a.id - b.id; 14681 } 14682 } 14683 14684 function reversePainterSortStable(a, b) { 14685 if (a.groupOrder !== b.groupOrder) { 14686 return a.groupOrder - b.groupOrder; 14687 } else if (a.renderOrder !== b.renderOrder) { 14688 return a.renderOrder - b.renderOrder; 14689 } else if (a.z !== b.z) { 14690 return b.z - a.z; 14691 } else { 14692 return a.id - b.id; 14693 } 14694 } 14695 14696 function WebGLRenderList() { 14697 const renderItems = []; 14698 let renderItemsIndex = 0; 14699 const opaque = []; 14700 const transmissive = []; 14701 const transparent = []; 14702 14703 function init() { 14704 renderItemsIndex = 0; 14705 opaque.length = 0; 14706 transmissive.length = 0; 14707 transparent.length = 0; 14708 } 14709 14710 function getNextRenderItem(object, geometry, material, groupOrder, z, group) { 14711 let renderItem = renderItems[renderItemsIndex]; 14712 14713 if (renderItem === undefined) { 14714 renderItem = { 14715 id: object.id, 14716 object: object, 14717 geometry: geometry, 14718 material: material, 14719 groupOrder: groupOrder, 14720 renderOrder: object.renderOrder, 14721 z: z, 14722 group: group 14723 }; 14724 renderItems[renderItemsIndex] = renderItem; 14725 } else { 14726 renderItem.id = object.id; 14727 renderItem.object = object; 14728 renderItem.geometry = geometry; 14729 renderItem.material = material; 14730 renderItem.groupOrder = groupOrder; 14731 renderItem.renderOrder = object.renderOrder; 14732 renderItem.z = z; 14733 renderItem.group = group; 14734 } 14735 14736 renderItemsIndex++; 14737 return renderItem; 14738 } 14739 14740 function push(object, geometry, material, groupOrder, z, group) { 14741 const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); 14742 14743 if (material.transmission > 0.0) { 14744 transmissive.push(renderItem); 14745 } else if (material.transparent === true) { 14746 transparent.push(renderItem); 14747 } else { 14748 opaque.push(renderItem); 14749 } 14750 } 14751 14752 function unshift(object, geometry, material, groupOrder, z, group) { 14753 const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); 14754 14755 if (material.transmission > 0.0) { 14756 transmissive.unshift(renderItem); 14757 } else if (material.transparent === true) { 14758 transparent.unshift(renderItem); 14759 } else { 14760 opaque.unshift(renderItem); 14761 } 14762 } 14763 14764 function sort(customOpaqueSort, customTransparentSort) { 14765 if (opaque.length > 1) opaque.sort(customOpaqueSort || painterSortStable); 14766 if (transmissive.length > 1) transmissive.sort(customTransparentSort || reversePainterSortStable); 14767 if (transparent.length > 1) transparent.sort(customTransparentSort || reversePainterSortStable); 14768 } 14769 14770 function finish() { 14771 // Clear references from inactive renderItems in the list 14772 for (let i = renderItemsIndex, il = renderItems.length; i < il; i++) { 14773 const renderItem = renderItems[i]; 14774 if (renderItem.id === null) break; 14775 renderItem.id = null; 14776 renderItem.object = null; 14777 renderItem.geometry = null; 14778 renderItem.material = null; 14779 renderItem.group = null; 14780 } 14781 } 14782 14783 return { 14784 opaque: opaque, 14785 transmissive: transmissive, 14786 transparent: transparent, 14787 init: init, 14788 push: push, 14789 unshift: unshift, 14790 finish: finish, 14791 sort: sort 14792 }; 14793 } 14794 14795 function WebGLRenderLists() { 14796 let lists = new WeakMap(); 14797 14798 function get(scene, renderCallDepth) { 14799 let list; 14800 14801 if (lists.has(scene) === false) { 14802 list = new WebGLRenderList(); 14803 lists.set(scene, [list]); 14804 } else { 14805 if (renderCallDepth >= lists.get(scene).length) { 14806 list = new WebGLRenderList(); 14807 lists.get(scene).push(list); 14808 } else { 14809 list = lists.get(scene)[renderCallDepth]; 14810 } 14811 } 14812 14813 return list; 14814 } 14815 14816 function dispose() { 14817 lists = new WeakMap(); 14818 } 14819 14820 return { 14821 get: get, 14822 dispose: dispose 14823 }; 14824 } 14825 14826 function UniformsCache() { 14827 const lights = {}; 14828 return { 14829 get: function (light) { 14830 if (lights[light.id] !== undefined) { 14831 return lights[light.id]; 14832 } 14833 14834 let uniforms; 14835 14836 switch (light.type) { 14837 case 'DirectionalLight': 14838 uniforms = { 14839 direction: new Vector3(), 14840 color: new Color() 14841 }; 14842 break; 14843 14844 case 'SpotLight': 14845 uniforms = { 14846 position: new Vector3(), 14847 direction: new Vector3(), 14848 color: new Color(), 14849 distance: 0, 14850 coneCos: 0, 14851 penumbraCos: 0, 14852 decay: 0 14853 }; 14854 break; 14855 14856 case 'PointLight': 14857 uniforms = { 14858 position: new Vector3(), 14859 color: new Color(), 14860 distance: 0, 14861 decay: 0 14862 }; 14863 break; 14864 14865 case 'HemisphereLight': 14866 uniforms = { 14867 direction: new Vector3(), 14868 skyColor: new Color(), 14869 groundColor: new Color() 14870 }; 14871 break; 14872 14873 case 'RectAreaLight': 14874 uniforms = { 14875 color: new Color(), 14876 position: new Vector3(), 14877 halfWidth: new Vector3(), 14878 halfHeight: new Vector3() 14879 }; 14880 break; 14881 } 14882 14883 lights[light.id] = uniforms; 14884 return uniforms; 14885 } 14886 }; 14887 } 14888 14889 function ShadowUniformsCache() { 14890 const lights = {}; 14891 return { 14892 get: function (light) { 14893 if (lights[light.id] !== undefined) { 14894 return lights[light.id]; 14895 } 14896 14897 let uniforms; 14898 14899 switch (light.type) { 14900 case 'DirectionalLight': 14901 uniforms = { 14902 shadowBias: 0, 14903 shadowNormalBias: 0, 14904 shadowRadius: 1, 14905 shadowMapSize: new Vector2() 14906 }; 14907 break; 14908 14909 case 'SpotLight': 14910 uniforms = { 14911 shadowBias: 0, 14912 shadowNormalBias: 0, 14913 shadowRadius: 1, 14914 shadowMapSize: new Vector2() 14915 }; 14916 break; 14917 14918 case 'PointLight': 14919 uniforms = { 14920 shadowBias: 0, 14921 shadowNormalBias: 0, 14922 shadowRadius: 1, 14923 shadowMapSize: new Vector2(), 14924 shadowCameraNear: 1, 14925 shadowCameraFar: 1000 14926 }; 14927 break; 14928 // TODO (abelnation): set RectAreaLight shadow uniforms 14929 } 14930 14931 lights[light.id] = uniforms; 14932 return uniforms; 14933 } 14934 }; 14935 } 14936 14937 let nextVersion = 0; 14938 14939 function shadowCastingLightsFirst(lightA, lightB) { 14940 return (lightB.castShadow ? 1 : 0) - (lightA.castShadow ? 1 : 0); 14941 } 14942 14943 function WebGLLights(extensions, capabilities) { 14944 const cache = new UniformsCache(); 14945 const shadowCache = ShadowUniformsCache(); 14946 const state = { 14947 version: 0, 14948 hash: { 14949 directionalLength: -1, 14950 pointLength: -1, 14951 spotLength: -1, 14952 rectAreaLength: -1, 14953 hemiLength: -1, 14954 numDirectionalShadows: -1, 14955 numPointShadows: -1, 14956 numSpotShadows: -1 14957 }, 14958 ambient: [0, 0, 0], 14959 probe: [], 14960 directional: [], 14961 directionalShadow: [], 14962 directionalShadowMap: [], 14963 directionalShadowMatrix: [], 14964 spot: [], 14965 spotShadow: [], 14966 spotShadowMap: [], 14967 spotShadowMatrix: [], 14968 rectArea: [], 14969 rectAreaLTC1: null, 14970 rectAreaLTC2: null, 14971 point: [], 14972 pointShadow: [], 14973 pointShadowMap: [], 14974 pointShadowMatrix: [], 14975 hemi: [] 14976 }; 14977 14978 for (let i = 0; i < 9; i++) state.probe.push(new Vector3()); 14979 14980 const vector3 = new Vector3(); 14981 const matrix4 = new Matrix4(); 14982 const matrix42 = new Matrix4(); 14983 14984 function setup(lights, physicallyCorrectLights) { 14985 let r = 0, 14986 g = 0, 14987 b = 0; 14988 14989 for (let i = 0; i < 9; i++) state.probe[i].set(0, 0, 0); 14990 14991 let directionalLength = 0; 14992 let pointLength = 0; 14993 let spotLength = 0; 14994 let rectAreaLength = 0; 14995 let hemiLength = 0; 14996 let numDirectionalShadows = 0; 14997 let numPointShadows = 0; 14998 let numSpotShadows = 0; 14999 lights.sort(shadowCastingLightsFirst); // artist-friendly light intensity scaling factor 15000 15001 const scaleFactor = physicallyCorrectLights !== true ? Math.PI : 1; 15002 15003 for (let i = 0, l = lights.length; i < l; i++) { 15004 const light = lights[i]; 15005 const color = light.color; 15006 const intensity = light.intensity; 15007 const distance = light.distance; 15008 const shadowMap = light.shadow && light.shadow.map ? light.shadow.map.texture : null; 15009 15010 if (light.isAmbientLight) { 15011 r += color.r * intensity * scaleFactor; 15012 g += color.g * intensity * scaleFactor; 15013 b += color.b * intensity * scaleFactor; 15014 } else if (light.isLightProbe) { 15015 for (let j = 0; j < 9; j++) { 15016 state.probe[j].addScaledVector(light.sh.coefficients[j], intensity); 15017 } 15018 } else if (light.isDirectionalLight) { 15019 const uniforms = cache.get(light); 15020 uniforms.color.copy(light.color).multiplyScalar(light.intensity * scaleFactor); 15021 15022 if (light.castShadow) { 15023 const shadow = light.shadow; 15024 const shadowUniforms = shadowCache.get(light); 15025 shadowUniforms.shadowBias = shadow.bias; 15026 shadowUniforms.shadowNormalBias = shadow.normalBias; 15027 shadowUniforms.shadowRadius = shadow.radius; 15028 shadowUniforms.shadowMapSize = shadow.mapSize; 15029 state.directionalShadow[directionalLength] = shadowUniforms; 15030 state.directionalShadowMap[directionalLength] = shadowMap; 15031 state.directionalShadowMatrix[directionalLength] = light.shadow.matrix; 15032 numDirectionalShadows++; 15033 } 15034 15035 state.directional[directionalLength] = uniforms; 15036 directionalLength++; 15037 } else if (light.isSpotLight) { 15038 const uniforms = cache.get(light); 15039 uniforms.position.setFromMatrixPosition(light.matrixWorld); 15040 uniforms.color.copy(color).multiplyScalar(intensity * scaleFactor); 15041 uniforms.distance = distance; 15042 uniforms.coneCos = Math.cos(light.angle); 15043 uniforms.penumbraCos = Math.cos(light.angle * (1 - light.penumbra)); 15044 uniforms.decay = light.decay; 15045 15046 if (light.castShadow) { 15047 const shadow = light.shadow; 15048 const shadowUniforms = shadowCache.get(light); 15049 shadowUniforms.shadowBias = shadow.bias; 15050 shadowUniforms.shadowNormalBias = shadow.normalBias; 15051 shadowUniforms.shadowRadius = shadow.radius; 15052 shadowUniforms.shadowMapSize = shadow.mapSize; 15053 state.spotShadow[spotLength] = shadowUniforms; 15054 state.spotShadowMap[spotLength] = shadowMap; 15055 state.spotShadowMatrix[spotLength] = light.shadow.matrix; 15056 numSpotShadows++; 15057 } 15058 15059 state.spot[spotLength] = uniforms; 15060 spotLength++; 15061 } else if (light.isRectAreaLight) { 15062 const uniforms = cache.get(light); // (a) intensity is the total visible light emitted 15063 //uniforms.color.copy( color ).multiplyScalar( intensity / ( light.width * light.height * Math.PI ) ); 15064 // (b) intensity is the brightness of the light 15065 15066 uniforms.color.copy(color).multiplyScalar(intensity); 15067 uniforms.halfWidth.set(light.width * 0.5, 0.0, 0.0); 15068 uniforms.halfHeight.set(0.0, light.height * 0.5, 0.0); 15069 state.rectArea[rectAreaLength] = uniforms; 15070 rectAreaLength++; 15071 } else if (light.isPointLight) { 15072 const uniforms = cache.get(light); 15073 uniforms.color.copy(light.color).multiplyScalar(light.intensity * scaleFactor); 15074 uniforms.distance = light.distance; 15075 uniforms.decay = light.decay; 15076 15077 if (light.castShadow) { 15078 const shadow = light.shadow; 15079 const shadowUniforms = shadowCache.get(light); 15080 shadowUniforms.shadowBias = shadow.bias; 15081 shadowUniforms.shadowNormalBias = shadow.normalBias; 15082 shadowUniforms.shadowRadius = shadow.radius; 15083 shadowUniforms.shadowMapSize = shadow.mapSize; 15084 shadowUniforms.shadowCameraNear = shadow.camera.near; 15085 shadowUniforms.shadowCameraFar = shadow.camera.far; 15086 state.pointShadow[pointLength] = shadowUniforms; 15087 state.pointShadowMap[pointLength] = shadowMap; 15088 state.pointShadowMatrix[pointLength] = light.shadow.matrix; 15089 numPointShadows++; 15090 } 15091 15092 state.point[pointLength] = uniforms; 15093 pointLength++; 15094 } else if (light.isHemisphereLight) { 15095 const uniforms = cache.get(light); 15096 uniforms.skyColor.copy(light.color).multiplyScalar(intensity * scaleFactor); 15097 uniforms.groundColor.copy(light.groundColor).multiplyScalar(intensity * scaleFactor); 15098 state.hemi[hemiLength] = uniforms; 15099 hemiLength++; 15100 } 15101 } 15102 15103 if (rectAreaLength > 0) { 15104 if (capabilities.isWebGL2) { 15105 // WebGL 2 15106 state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1; 15107 state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2; 15108 } else { 15109 // WebGL 1 15110 if (extensions.has('OES_texture_float_linear') === true) { 15111 state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1; 15112 state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2; 15113 } else if (extensions.has('OES_texture_half_float_linear') === true) { 15114 state.rectAreaLTC1 = UniformsLib.LTC_HALF_1; 15115 state.rectAreaLTC2 = UniformsLib.LTC_HALF_2; 15116 } else { 15117 console.error('THREE.WebGLRenderer: Unable to use RectAreaLight. Missing WebGL extensions.'); 15118 } 15119 } 15120 } 15121 15122 state.ambient[0] = r; 15123 state.ambient[1] = g; 15124 state.ambient[2] = b; 15125 const hash = state.hash; 15126 15127 if (hash.directionalLength !== directionalLength || hash.pointLength !== pointLength || hash.spotLength !== spotLength || hash.rectAreaLength !== rectAreaLength || hash.hemiLength !== hemiLength || hash.numDirectionalShadows !== numDirectionalShadows || hash.numPointShadows !== numPointShadows || hash.numSpotShadows !== numSpotShadows) { 15128 state.directional.length = directionalLength; 15129 state.spot.length = spotLength; 15130 state.rectArea.length = rectAreaLength; 15131 state.point.length = pointLength; 15132 state.hemi.length = hemiLength; 15133 state.directionalShadow.length = numDirectionalShadows; 15134 state.directionalShadowMap.length = numDirectionalShadows; 15135 state.pointShadow.length = numPointShadows; 15136 state.pointShadowMap.length = numPointShadows; 15137 state.spotShadow.length = numSpotShadows; 15138 state.spotShadowMap.length = numSpotShadows; 15139 state.directionalShadowMatrix.length = numDirectionalShadows; 15140 state.pointShadowMatrix.length = numPointShadows; 15141 state.spotShadowMatrix.length = numSpotShadows; 15142 hash.directionalLength = directionalLength; 15143 hash.pointLength = pointLength; 15144 hash.spotLength = spotLength; 15145 hash.rectAreaLength = rectAreaLength; 15146 hash.hemiLength = hemiLength; 15147 hash.numDirectionalShadows = numDirectionalShadows; 15148 hash.numPointShadows = numPointShadows; 15149 hash.numSpotShadows = numSpotShadows; 15150 state.version = nextVersion++; 15151 } 15152 } 15153 15154 function setupView(lights, camera) { 15155 let directionalLength = 0; 15156 let pointLength = 0; 15157 let spotLength = 0; 15158 let rectAreaLength = 0; 15159 let hemiLength = 0; 15160 const viewMatrix = camera.matrixWorldInverse; 15161 15162 for (let i = 0, l = lights.length; i < l; i++) { 15163 const light = lights[i]; 15164 15165 if (light.isDirectionalLight) { 15166 const uniforms = state.directional[directionalLength]; 15167 uniforms.direction.setFromMatrixPosition(light.matrixWorld); 15168 vector3.setFromMatrixPosition(light.target.matrixWorld); 15169 uniforms.direction.sub(vector3); 15170 uniforms.direction.transformDirection(viewMatrix); 15171 directionalLength++; 15172 } else if (light.isSpotLight) { 15173 const uniforms = state.spot[spotLength]; 15174 uniforms.position.setFromMatrixPosition(light.matrixWorld); 15175 uniforms.position.applyMatrix4(viewMatrix); 15176 uniforms.direction.setFromMatrixPosition(light.matrixWorld); 15177 vector3.setFromMatrixPosition(light.target.matrixWorld); 15178 uniforms.direction.sub(vector3); 15179 uniforms.direction.transformDirection(viewMatrix); 15180 spotLength++; 15181 } else if (light.isRectAreaLight) { 15182 const uniforms = state.rectArea[rectAreaLength]; 15183 uniforms.position.setFromMatrixPosition(light.matrixWorld); 15184 uniforms.position.applyMatrix4(viewMatrix); // extract local rotation of light to derive width/height half vectors 15185 15186 matrix42.identity(); 15187 matrix4.copy(light.matrixWorld); 15188 matrix4.premultiply(viewMatrix); 15189 matrix42.extractRotation(matrix4); 15190 uniforms.halfWidth.set(light.width * 0.5, 0.0, 0.0);
vendor: 4,288 bytes, lines 15191-15370
15191 uniforms.halfHeight.set(0.0, light.height * 0.5, 0.0); 15192 uniforms.halfWidth.applyMatrix4(matrix42); 15193 uniforms.halfHeight.applyMatrix4(matrix42); 15194 rectAreaLength++; 15195 } else if (light.isPointLight) { 15196 const uniforms = state.point[pointLength]; 15197 uniforms.position.setFromMatrixPosition(light.matrixWorld); 15198 uniforms.position.applyMatrix4(viewMatrix); 15199 pointLength++; 15200 } else if (light.isHemisphereLight) { 15201 const uniforms = state.hemi[hemiLength]; 15202 uniforms.direction.setFromMatrixPosition(light.matrixWorld); 15203 uniforms.direction.transformDirection(viewMatrix); 15204 uniforms.direction.normalize(); 15205 hemiLength++; 15206 } 15207 } 15208 } 15209 15210 return { 15211 setup: setup, 15212 setupView: setupView, 15213 state: state 15214 }; 15215 } 15216 15217 function WebGLRenderState(extensions, capabilities) { 15218 const lights = new WebGLLights(extensions, capabilities); 15219 const lightsArray = []; 15220 const shadowsArray = []; 15221 15222 function init() { 15223 lightsArray.length = 0; 15224 shadowsArray.length = 0; 15225 } 15226 15227 function pushLight(light) { 15228 lightsArray.push(light); 15229 } 15230 15231 function pushShadow(shadowLight) { 15232 shadowsArray.push(shadowLight); 15233 } 15234 15235 function setupLights(physicallyCorrectLights) { 15236 lights.setup(lightsArray, physicallyCorrectLights); 15237 } 15238 15239 function setupLightsView(camera) { 15240 lights.setupView(lightsArray, camera); 15241 } 15242 15243 const state = { 15244 lightsArray: lightsArray, 15245 shadowsArray: shadowsArray, 15246 lights: lights 15247 }; 15248 return { 15249 init: init, 15250 state: state, 15251 setupLights: setupLights, 15252 setupLightsView: setupLightsView, 15253 pushLight: pushLight, 15254 pushShadow: pushShadow 15255 }; 15256 } 15257 15258 function WebGLRenderStates(extensions, capabilities) { 15259 let renderStates = new WeakMap(); 15260 15261 function get(scene, renderCallDepth = 0) { 15262 let renderState; 15263 15264 if (renderStates.has(scene) === false) { 15265 renderState = new WebGLRenderState(extensions, capabilities); 15266 renderStates.set(scene, [renderState]); 15267 } else { 15268 if (renderCallDepth >= renderStates.get(scene).length) { 15269 renderState = new WebGLRenderState(extensions, capabilities); 15270 renderStates.get(scene).push(renderState); 15271 } else { 15272 renderState = renderStates.get(scene)[renderCallDepth]; 15273 } 15274 } 15275 15276 return renderState; 15277 } 15278 15279 function dispose() { 15280 renderStates = new WeakMap(); 15281 } 15282 15283 return { 15284 get: get, 15285 dispose: dispose 15286 }; 15287 } 15288 15289 /** 15290 * parameters = { 15291 * 15292 * opacity: <float>, 15293 * 15294 * map: new THREE.Texture( <Image> ), 15295 * 15296 * alphaMap: new THREE.Texture( <Image> ), 15297 * 15298 * displacementMap: new THREE.Texture( <Image> ), 15299 * displacementScale: <float>, 15300 * displacementBias: <float>, 15301 * 15302 * wireframe: <boolean>, 15303 * wireframeLinewidth: <float> 15304 * } 15305 */ 15306 15307 class MeshDepthMaterial extends Material { 15308 constructor(parameters) { 15309 super(); 15310 this.type = 'MeshDepthMaterial'; 15311 this.depthPacking = BasicDepthPacking; 15312 this.map = null; 15313 this.alphaMap = null; 15314 this.displacementMap = null; 15315 this.displacementScale = 1; 15316 this.displacementBias = 0; 15317 this.wireframe = false; 15318 this.wireframeLinewidth = 1; 15319 this.fog = false; 15320 this.setValues(parameters); 15321 } 15322 15323 copy(source) { 15324 super.copy(source); 15325 this.depthPacking = source.depthPacking; 15326 this.map = source.map; 15327 this.alphaMap = source.alphaMap; 15328 this.displacementMap = source.displacementMap; 15329 this.displacementScale = source.displacementScale; 15330 this.displacementBias = source.displacementBias; 15331 this.wireframe = source.wireframe; 15332 this.wireframeLinewidth = source.wireframeLinewidth; 15333 return this; 15334 } 15335 15336 } 15337 15338 MeshDepthMaterial.prototype.isMeshDepthMaterial = true; 15339 15340 /** 15341 * parameters = { 15342 * 15343 * referencePosition: <float>, 15344 * nearDistance: <float>, 15345 * farDistance: <float>, 15346 * 15347 * map: new THREE.Texture( <Image> ), 15348 * 15349 * alphaMap: new THREE.Texture( <Image> ), 15350 * 15351 * displacementMap: new THREE.Texture( <Image> ), 15352 * displacementScale: <float>, 15353 * displacementBias: <float> 15354 * 15355 * } 15356 */ 15357 15358 class MeshDistanceMaterial extends Material { 15359 constructor(parameters) { 15360 super(); 15361 this.type = 'MeshDistanceMaterial'; 15362 this.referencePosition = new Vector3(); 15363 this.nearDistance = 1; 15364 this.farDistance = 1000; 15365 this.map = null; 15366 this.alphaMap = null; 15367 this.displacementMap = null; 15368 this.displacementScale = 1; 15369 this.displacementBias = 0; 15370 this.fog = false;
vendor: 4,751 bytes, lines 15371-15495
15371 this.setValues(parameters); 15372 } 15373 15374 copy(source) { 15375 super.copy(source); 15376 this.referencePosition.copy(source.referencePosition); 15377 this.nearDistance = source.nearDistance; 15378 this.farDistance = source.farDistance; 15379 this.map = source.map; 15380 this.alphaMap = source.alphaMap; 15381 this.displacementMap = source.displacementMap; 15382 this.displacementScale = source.displacementScale; 15383 this.displacementBias = source.displacementBias; 15384 return this; 15385 } 15386 15387 } 15388 15389 MeshDistanceMaterial.prototype.isMeshDistanceMaterial = true; 15390 15391 const vertex = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}"; 15392 const fragment = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include <packing>\nvoid main() {\n\tconst float samples = float( VSM_SAMPLES );\n\tfloat mean = 0.0;\n\tfloat squared_mean = 0.0;\n\tfloat uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 );\n\tfloat uvStart = samples <= 1.0 ? 0.0 : - 1.0;\n\tfor ( float i = 0.0; i < samples; i ++ ) {\n\t\tfloat uvOffset = uvStart + i * uvStride;\n\t\t#ifdef HORIZONTAL_PASS\n\t\t\tvec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 0.0 ) * radius ) / resolution ) );\n\t\t\tmean += distribution.x;\n\t\t\tsquared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n\t\t#else\n\t\t\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, uvOffset ) * radius ) / resolution ) );\n\t\t\tmean += depth;\n\t\t\tsquared_mean += depth * depth;\n\t\t#endif\n\t}\n\tmean = mean / samples;\n\tsquared_mean = squared_mean / samples;\n\tfloat std_dev = sqrt( squared_mean - mean * mean );\n\tgl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}"; 15393 15394 function WebGLShadowMap(_renderer, _objects, _capabilities) { 15395 let _frustum = new Frustum(); 15396 15397 const _shadowMapSize = new Vector2(), 15398 _viewportSize = new Vector2(), 15399 _viewport = new Vector4(), 15400 _depthMaterial = new MeshDepthMaterial({ 15401 depthPacking: RGBADepthPacking 15402 }), 15403 _distanceMaterial = new MeshDistanceMaterial(), 15404 _materialCache = {}, 15405 _maxTextureSize = _capabilities.maxTextureSize; 15406 15407 const shadowSide = { 15408 0: BackSide, 15409 1: FrontSide, 15410 2: DoubleSide 15411 }; 15412 const shadowMaterialVertical = new ShaderMaterial({ 15413 defines: { 15414 VSM_SAMPLES: 8 15415 }, 15416 uniforms: { 15417 shadow_pass: { 15418 value: null 15419 }, 15420 resolution: { 15421 value: new Vector2() 15422 }, 15423 radius: { 15424 value: 4.0 15425 } 15426 }, 15427 vertexShader: vertex, 15428 fragmentShader: fragment 15429 }); 15430 const shadowMaterialHorizontal = shadowMaterialVertical.clone(); 15431 shadowMaterialHorizontal.defines.HORIZONTAL_PASS = 1; 15432 const fullScreenTri = new BufferGeometry(); 15433 fullScreenTri.setAttribute('position', new BufferAttribute(new Float32Array([-1, -1, 0.5, 3, -1, 0.5, -1, 3, 0.5]), 3)); 15434 const fullScreenMesh = new Mesh(fullScreenTri, shadowMaterialVertical); 15435 const scope = this; 15436 this.enabled = false; 15437 this.autoUpdate = true; 15438 this.needsUpdate = false; 15439 this.type = PCFShadowMap; 15440 15441 this.render = function (lights, scene, camera) { 15442 if (scope.enabled === false) return; 15443 if (scope.autoUpdate === false && scope.needsUpdate === false) return; 15444 if (lights.length === 0) return; 15445 15446 const currentRenderTarget = _renderer.getRenderTarget(); 15447 15448 const activeCubeFace = _renderer.getActiveCubeFace(); 15449 15450 const activeMipmapLevel = _renderer.getActiveMipmapLevel(); 15451 15452 const _state = _renderer.state; // Set GL state for depth map. 15453 15454 _state.setBlending(NoBlending); 15455 15456 _state.buffers.color.setClear(1, 1, 1, 1); 15457 15458 _state.buffers.depth.setTest(true); 15459 15460 _state.setScissorTest(false); // render depth map 15461 15462 15463 for (let i = 0, il = lights.length; i < il; i++) { 15464 const light = lights[i]; 15465 const shadow = light.shadow; 15466 15467 if (shadow === undefined) { 15468 console.warn('THREE.WebGLShadowMap:', light, 'has no shadow.'); 15469 continue; 15470 } 15471 15472 if (shadow.autoUpdate === false && shadow.needsUpdate === false) continue; 15473 15474 _shadowMapSize.copy(shadow.mapSize); 15475 15476 const shadowFrameExtents = shadow.getFrameExtents(); 15477 15478 _shadowMapSize.multiply(shadowFrameExtents); 15479 15480 _viewportSize.copy(shadow.mapSize); 15481 15482 if (_shadowMapSize.x > _maxTextureSize || _shadowMapSize.y > _maxTextureSize) { 15483 if (_shadowMapSize.x > _maxTextureSize) { 15484 _viewportSize.x = Math.floor(_maxTextureSize / shadowFrameExtents.x); 15485 _shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x; 15486 shadow.mapSize.x = _viewportSize.x; 15487 } 15488 15489 if (_shadowMapSize.y > _maxTextureSize) { 15490 _viewportSize.y = Math.floor(_maxTextureSize / shadowFrameExtents.y); 15491 _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y; 15492 shadow.mapSize.y = _viewportSize.y; 15493 } 15494 } 15495
15496 if (shadow.map === null && !shadow.isPointLightShadow && this.type === VSMShadowMap) { 15497 const pars = { 15498 minFilter: LinearFilter, 15499 magFilter: LinearFilter, 15500 format: RGBAFormat 15501 }; 15502 shadow.map = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, pars); 15503 shadow.map.texture.name = light.name + '.shadowMap'; 15504 shadow.mapPass = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, pars); 15505 shadow.camera.updateProjectionMatrix(); 15506 } 15507 15508 if (shadow.map === null) { 15509 const pars = { 15510 minFilter: NearestFilter, 15511 magFilter: NearestFilter, 15512 format: RGBAFormat 15513 }; 15514 shadow.map = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, pars); 15515 shadow.map.texture.name = light.name + '.shadowMap'; 15516 shadow.camera.updateProjectionMatrix(); 15517 } 15518 15519 _renderer.setRenderTarget(shadow.map); 15520 15521 _renderer.clear(); 15522 15523 const viewportCount = shadow.getViewportCount(); 15524 15525 for (let vp = 0; vp < viewportCount; vp++) { 15526 const viewport = shadow.getViewport(vp); 15527 15528 _viewport.set(_viewportSize.x * viewport.x, _viewportSize.y * viewport.y, _viewportSize.x * viewport.z, _viewportSize.y * viewport.w); 15529 15530 _state.viewport(_viewport); 15531 15532 shadow.updateMatrices(light, vp); 15533 _frustum = shadow.getFrustum(); 15534 renderObject(scene, camera, shadow.camera, light, this.type); 15535 } // do blur pass for VSM 15536 15537 15538 if (!shadow.isPointLightShadow && this.type === VSMShadowMap) { 15539 VSMPass(shadow, camera); 15540 } 15541 15542 shadow.needsUpdate = false; 15543 } 15544 15545 scope.needsUpdate = false; 15546 15547 _renderer.setRenderTarget(currentRenderTarget, activeCubeFace, activeMipmapLevel); 15548 }; 15549 15550 function VSMPass(shadow, camera) { 15551 const geometry = _objects.update(fullScreenMesh); 15552 15553 if (shadowMaterialVertical.defines.VSM_SAMPLES !== shadow.blurSamples) { 15554 shadowMaterialVertical.defines.VSM_SAMPLES = shadow.blurSamples; 15555 shadowMaterialHorizontal.defines.VSM_SAMPLES = shadow.blurSamples; 15556 shadowMaterialVertical.needsUpdate = true; 15557 shadowMaterialHorizontal.needsUpdate = true; 15558 } // vertical pass 15559 15560 15561 shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture; 15562 shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize; 15563 shadowMaterialVertical.uniforms.radius.value = shadow.radius; 15564 15565 _renderer.setRenderTarget(shadow.mapPass); 15566 15567 _renderer.clear(); 15568 15569 _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null); // horizontal pass 15570 15571 15572 shadowMaterialHorizontal.uniforms.shadow_pass.value = shadow.mapPass.texture; 15573 shadowMaterialHorizontal.uniforms.resolution.value = shadow.mapSize; 15574 shadowMaterialHorizontal.uniforms.radius.value = shadow.radius; 15575 15576 _renderer.setRenderTarget(shadow.map); 15577 15578 _renderer.clear(); 15579 15580 _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialHorizontal, fullScreenMesh, null); 15581 } 15582 15583 function getDepthMaterial(object, geometry, material, light, shadowCameraNear, shadowCameraFar, type) { 15584 let result = null; 15585 const customMaterial = light.isPointLight === true ? object.customDistanceMaterial : object.customDepthMaterial; 15586 15587 if (customMaterial !== undefined) { 15588 result = customMaterial; 15589 } else { 15590 result = light.isPointLight === true ? _distanceMaterial : _depthMaterial; 15591 } 15592
15593 if (_renderer.localClippingEnabled && material.clipShadows === true && material.clippingPlanes.length !== 0 || material.displacementMap && material.displacementScale !== 0 || material.alphaMap && material.alphaTest > 0) { 15594 // in this case we need a unique material instance reflecting the 15595 // appropriate state 15596 const keyA = result.uuid, 15597 keyB = material.uuid; 15598 let materialsForVariant = _materialCache[keyA]; 15599 15600 if (materialsForVariant === undefined) { 15601 materialsForVariant = {}; 15602 _materialCache[keyA] = materialsForVariant; 15603 } 15604 15605 let cachedMaterial = materialsForVariant[keyB]; 15606 15607 if (cachedMaterial === undefined) { 15608 cachedMaterial = result.clone(); 15609 materialsForVariant[keyB] = cachedMaterial; 15610 } 15611 15612 result = cachedMaterial; 15613 } 15614 15615 result.visible = material.visible; 15616 result.wireframe = material.wireframe; 15617 15618 if (type === VSMShadowMap) { 15619 result.side = material.shadowSide !== null ? material.shadowSide : material.side; 15620 } else { 15621 result.side = material.shadowSide !== null ? material.shadowSide : shadowSide[material.side]; 15622 } 15623 15624 result.alphaMap = material.alphaMap; 15625 result.alphaTest = material.alphaTest;
vendor: 9,779 bytes, lines 15626-15953
15626 result.clipShadows = material.clipShadows; 15627 result.clippingPlanes = material.clippingPlanes; 15628 result.clipIntersection = material.clipIntersection; 15629 result.displacementMap = material.displacementMap; 15630 result.displacementScale = material.displacementScale; 15631 result.displacementBias = material.displacementBias; 15632 result.wireframeLinewidth = material.wireframeLinewidth; 15633 result.linewidth = material.linewidth; 15634 15635 if (light.isPointLight === true && result.isMeshDistanceMaterial === true) { 15636 result.referencePosition.setFromMatrixPosition(light.matrixWorld); 15637 result.nearDistance = shadowCameraNear; 15638 result.farDistance = shadowCameraFar; 15639 } 15640 15641 return result; 15642 } 15643 15644 function renderObject(object, camera, shadowCamera, light, type) { 15645 if (object.visible === false) return; 15646 const visible = object.layers.test(camera.layers); 15647 15648 if (visible && (object.isMesh || object.isLine || object.isPoints)) { 15649 if ((object.castShadow || object.receiveShadow && type === VSMShadowMap) && (!object.frustumCulled || _frustum.intersectsObject(object))) { 15650 object.modelViewMatrix.multiplyMatrices(shadowCamera.matrixWorldInverse, object.matrixWorld); 15651 15652 const geometry = _objects.update(object); 15653 15654 const material = object.material; 15655 15656 if (Array.isArray(material)) { 15657 const groups = geometry.groups; 15658 15659 for (let k = 0, kl = groups.length; k < kl; k++) { 15660 const group = groups[k]; 15661 const groupMaterial = material[group.materialIndex]; 15662 15663 if (groupMaterial && groupMaterial.visible) { 15664 const depthMaterial = getDepthMaterial(object, geometry, groupMaterial, light, shadowCamera.near, shadowCamera.far, type); 15665 15666 _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, group); 15667 } 15668 } 15669 } else if (material.visible) { 15670 const depthMaterial = getDepthMaterial(object, geometry, material, light, shadowCamera.near, shadowCamera.far, type); 15671 15672 _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, null); 15673 } 15674 } 15675 } 15676 15677 const children = object.children; 15678 15679 for (let i = 0, l = children.length; i < l; i++) { 15680 renderObject(children[i], camera, shadowCamera, light, type); 15681 } 15682 } 15683 } 15684 15685 function WebGLState(gl, extensions, capabilities) { 15686 const isWebGL2 = capabilities.isWebGL2; 15687 15688 function ColorBuffer() { 15689 let locked = false; 15690 const color = new Vector4(); 15691 let currentColorMask = null; 15692 const currentColorClear = new Vector4(0, 0, 0, 0); 15693 return { 15694 setMask: function (colorMask) { 15695 if (currentColorMask !== colorMask && !locked) { 15696 gl.colorMask(colorMask, colorMask, colorMask, colorMask); 15697 currentColorMask = colorMask; 15698 } 15699 }, 15700 setLocked: function (lock) { 15701 locked = lock; 15702 }, 15703 setClear: function (r, g, b, a, premultipliedAlpha) { 15704 if (premultipliedAlpha === true) { 15705 r *= a; 15706 g *= a; 15707 b *= a; 15708 } 15709 15710 color.set(r, g, b, a); 15711 15712 if (currentColorClear.equals(color) === false) { 15713 gl.clearColor(r, g, b, a); 15714 currentColorClear.copy(color); 15715 } 15716 }, 15717 reset: function () { 15718 locked = false; 15719 currentColorMask = null; 15720 currentColorClear.set(-1, 0, 0, 0); // set to invalid state 15721 } 15722 }; 15723 } 15724 15725 function DepthBuffer() { 15726 let locked = false; 15727 let currentDepthMask = null; 15728 let currentDepthFunc = null; 15729 let currentDepthClear = null; 15730 return { 15731 setTest: function (depthTest) { 15732 if (depthTest) { 15733 enable(gl.DEPTH_TEST); 15734 } else { 15735 disable(gl.DEPTH_TEST); 15736 } 15737 }, 15738 setMask: function (depthMask) { 15739 if (currentDepthMask !== depthMask && !locked) { 15740 gl.depthMask(depthMask); 15741 currentDepthMask = depthMask; 15742 } 15743 }, 15744 setFunc: function (depthFunc) { 15745 if (currentDepthFunc !== depthFunc) { 15746 if (depthFunc) { 15747 switch (depthFunc) { 15748 case NeverDepth: 15749 gl.depthFunc(gl.NEVER); 15750 break; 15751 15752 case AlwaysDepth: 15753 gl.depthFunc(gl.ALWAYS); 15754 break; 15755 15756 case LessDepth: 15757 gl.depthFunc(gl.LESS); 15758 break; 15759 15760 case LessEqualDepth: 15761 gl.depthFunc(gl.LEQUAL); 15762 break; 15763 15764 case EqualDepth: 15765 gl.depthFunc(gl.EQUAL); 15766 break; 15767 15768 case GreaterEqualDepth: 15769 gl.depthFunc(gl.GEQUAL); 15770 break; 15771 15772 case GreaterDepth: 15773 gl.depthFunc(gl.GREATER); 15774 break; 15775 15776 case NotEqualDepth: 15777 gl.depthFunc(gl.NOTEQUAL); 15778 break; 15779 15780 default: 15781 gl.depthFunc(gl.LEQUAL); 15782 } 15783 } else { 15784 gl.depthFunc(gl.LEQUAL); 15785 } 15786 15787 currentDepthFunc = depthFunc; 15788 } 15789 }, 15790 setLocked: function (lock) { 15791 locked = lock; 15792 }, 15793 setClear: function (depth) { 15794 if (currentDepthClear !== depth) { 15795 gl.clearDepth(depth); 15796 currentDepthClear = depth; 15797 } 15798 }, 15799 reset: function () { 15800 locked = false; 15801 currentDepthMask = null; 15802 currentDepthFunc = null; 15803 currentDepthClear = null; 15804 } 15805 }; 15806 } 15807 15808 function StencilBuffer() { 15809 let locked = false; 15810 let currentStencilMask = null; 15811 let currentStencilFunc = null; 15812 let currentStencilRef = null; 15813 let currentStencilFuncMask = null; 15814 let currentStencilFail = null; 15815 let currentStencilZFail = null; 15816 let currentStencilZPass = null; 15817 let currentStencilClear = null; 15818 return { 15819 setTest: function (stencilTest) { 15820 if (!locked) { 15821 if (stencilTest) { 15822 enable(gl.STENCIL_TEST); 15823 } else { 15824 disable(gl.STENCIL_TEST); 15825 } 15826 } 15827 }, 15828 setMask: function (stencilMask) { 15829 if (currentStencilMask !== stencilMask && !locked) { 15830 gl.stencilMask(stencilMask); 15831 currentStencilMask = stencilMask; 15832 } 15833 }, 15834 setFunc: function (stencilFunc, stencilRef, stencilMask) { 15835 if (currentStencilFunc !== stencilFunc || currentStencilRef !== stencilRef || currentStencilFuncMask !== stencilMask) { 15836 gl.stencilFunc(stencilFunc, stencilRef, stencilMask); 15837 currentStencilFunc = stencilFunc; 15838 currentStencilRef = stencilRef; 15839 currentStencilFuncMask = stencilMask; 15840 } 15841 }, 15842 setOp: function (stencilFail, stencilZFail, stencilZPass) { 15843 if (currentStencilFail !== stencilFail || currentStencilZFail !== stencilZFail || currentStencilZPass !== stencilZPass) { 15844 gl.stencilOp(stencilFail, stencilZFail, stencilZPass); 15845 currentStencilFail = stencilFail; 15846 currentStencilZFail = stencilZFail; 15847 currentStencilZPass = stencilZPass; 15848 } 15849 }, 15850 setLocked: function (lock) { 15851 locked = lock; 15852 }, 15853 setClear: function (stencil) { 15854 if (currentStencilClear !== stencil) { 15855 gl.clearStencil(stencil); 15856 currentStencilClear = stencil; 15857 } 15858 }, 15859 reset: function () { 15860 locked = false; 15861 currentStencilMask = null; 15862 currentStencilFunc = null; 15863 currentStencilRef = null; 15864 currentStencilFuncMask = null; 15865 currentStencilFail = null; 15866 currentStencilZFail = null; 15867 currentStencilZPass = null; 15868 currentStencilClear = null; 15869 } 15870 }; 15871 } // 15872 15873 15874 const colorBuffer = new ColorBuffer(); 15875 const depthBuffer = new DepthBuffer(); 15876 const stencilBuffer = new StencilBuffer(); 15877 let enabledCapabilities = {}; 15878 let currentBoundFramebuffers = {}; 15879 let currentProgram = null; 15880 let currentBlendingEnabled = false; 15881 let currentBlending = null; 15882 let currentBlendEquation = null; 15883 let currentBlendSrc = null; 15884 let currentBlendDst = null; 15885 let currentBlendEquationAlpha = null; 15886 let currentBlendSrcAlpha = null; 15887 let currentBlendDstAlpha = null; 15888 let currentPremultipledAlpha = false; 15889 let currentFlipSided = null; 15890 let currentCullFace = null; 15891 let currentLineWidth = null; 15892 let currentPolygonOffsetFactor = null; 15893 let currentPolygonOffsetUnits = null; 15894 const maxTextures = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS); 15895 let lineWidthAvailable = false; 15896 let version = 0; 15897 const glVersion = gl.getParameter(gl.VERSION); 15898 15899 if (glVersion.indexOf('WebGL') !== -1) { 15900 version = parseFloat(/^WebGL (\d)/.exec(glVersion)[1]); 15901 lineWidthAvailable = version >= 1.0; 15902 } else if (glVersion.indexOf('OpenGL ES') !== -1) { 15903 version = parseFloat(/^OpenGL ES (\d)/.exec(glVersion)[1]); 15904 lineWidthAvailable = version >= 2.0; 15905 } 15906 15907 let currentTextureSlot = null; 15908 let currentBoundTextures = {}; 15909 const scissorParam = gl.getParameter(gl.SCISSOR_BOX); 15910 const viewportParam = gl.getParameter(gl.VIEWPORT); 15911 const currentScissor = new Vector4().fromArray(scissorParam); 15912 const currentViewport = new Vector4().fromArray(viewportParam); 15913 15914 function createTexture(type, target, count) { 15915 const data = new Uint8Array(4); // 4 is required to match default unpack alignment of 4. 15916 15917 const texture = gl.createTexture(); 15918 gl.bindTexture(type, texture); 15919 gl.texParameteri(type, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 15920 gl.texParameteri(type, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 15921 15922 for (let i = 0; i < count; i++) { 15923 gl.texImage2D(target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data); 15924 } 15925 15926 return texture; 15927 } 15928 15929 const emptyTextures = {}; 15930 emptyTextures[gl.TEXTURE_2D] = createTexture(gl.TEXTURE_2D, gl.TEXTURE_2D, 1); 15931 emptyTextures[gl.TEXTURE_CUBE_MAP] = createTexture(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6); // init 15932 15933 colorBuffer.setClear(0, 0, 0, 1); 15934 depthBuffer.setClear(1); 15935 stencilBuffer.setClear(0); 15936 enable(gl.DEPTH_TEST); 15937 depthBuffer.setFunc(LessEqualDepth); 15938 setFlipSided(false); 15939 setCullFace(CullFaceBack); 15940 enable(gl.CULL_FACE); 15941 setBlending(NoBlending); // 15942 15943 function enable(id) { 15944 if (enabledCapabilities[id] !== true) { 15945 gl.enable(id); 15946 enabledCapabilities[id] = true; 15947 } 15948 } 15949 15950 function disable(id) { 15951 if (enabledCapabilities[id] !== false) { 15952 gl.disable(id); 15953 enabledCapabilities[id] = false;
vendor: 11,726 bytes, lines 15954-16373
15954 } 15955 } 15956 15957 function bindFramebuffer(target, framebuffer) { 15958 if (currentBoundFramebuffers[target] !== framebuffer) { 15959 gl.bindFramebuffer(target, framebuffer); 15960 currentBoundFramebuffers[target] = framebuffer; 15961 15962 if (isWebGL2) { 15963 // gl.DRAW_FRAMEBUFFER is equivalent to gl.FRAMEBUFFER 15964 if (target === gl.DRAW_FRAMEBUFFER) { 15965 currentBoundFramebuffers[gl.FRAMEBUFFER] = framebuffer; 15966 } 15967 15968 if (target === gl.FRAMEBUFFER) { 15969 currentBoundFramebuffers[gl.DRAW_FRAMEBUFFER] = framebuffer; 15970 } 15971 } 15972 15973 return true; 15974 } 15975 15976 return false; 15977 } 15978 15979 function useProgram(program) { 15980 if (currentProgram !== program) { 15981 gl.useProgram(program); 15982 currentProgram = program; 15983 return true; 15984 } 15985 15986 return false; 15987 } 15988 15989 const equationToGL = { 15990 [AddEquation]: gl.FUNC_ADD, 15991 [SubtractEquation]: gl.FUNC_SUBTRACT, 15992 [ReverseSubtractEquation]: gl.FUNC_REVERSE_SUBTRACT 15993 }; 15994 15995 if (isWebGL2) { 15996 equationToGL[MinEquation] = gl.MIN; 15997 equationToGL[MaxEquation] = gl.MAX; 15998 } else { 15999 const extension = extensions.get('EXT_blend_minmax'); 16000 16001 if (extension !== null) { 16002 equationToGL[MinEquation] = extension.MIN_EXT; 16003 equationToGL[MaxEquation] = extension.MAX_EXT; 16004 } 16005 } 16006 16007 const factorToGL = { 16008 [ZeroFactor]: gl.ZERO, 16009 [OneFactor]: gl.ONE, 16010 [SrcColorFactor]: gl.SRC_COLOR, 16011 [SrcAlphaFactor]: gl.SRC_ALPHA, 16012 [SrcAlphaSaturateFactor]: gl.SRC_ALPHA_SATURATE, 16013 [DstColorFactor]: gl.DST_COLOR, 16014 [DstAlphaFactor]: gl.DST_ALPHA, 16015 [OneMinusSrcColorFactor]: gl.ONE_MINUS_SRC_COLOR, 16016 [OneMinusSrcAlphaFactor]: gl.ONE_MINUS_SRC_ALPHA, 16017 [OneMinusDstColorFactor]: gl.ONE_MINUS_DST_COLOR, 16018 [OneMinusDstAlphaFactor]: gl.ONE_MINUS_DST_ALPHA 16019 }; 16020 16021 function setBlending(blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha) { 16022 if (blending === NoBlending) { 16023 if (currentBlendingEnabled === true) { 16024 disable(gl.BLEND); 16025 currentBlendingEnabled = false; 16026 } 16027 16028 return; 16029 } 16030 16031 if (currentBlendingEnabled === false) { 16032 enable(gl.BLEND); 16033 currentBlendingEnabled = true; 16034 } 16035 16036 if (blending !== CustomBlending) { 16037 if (blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha) { 16038 if (currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation) { 16039 gl.blendEquation(gl.FUNC_ADD); 16040 currentBlendEquation = AddEquation; 16041 currentBlendEquationAlpha = AddEquation; 16042 } 16043 16044 if (premultipliedAlpha) { 16045 switch (blending) { 16046 case NormalBlending: 16047 gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); 16048 break; 16049 16050 case AdditiveBlending: 16051 gl.blendFunc(gl.ONE, gl.ONE); 16052 break; 16053 16054 case SubtractiveBlending: 16055 gl.blendFuncSeparate(gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA); 16056 break; 16057 16058 case MultiplyBlending: 16059 gl.blendFuncSeparate(gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA); 16060 break; 16061 16062 default: 16063 console.error('THREE.WebGLState: Invalid blending: ', blending); 16064 break; 16065 } 16066 } else { 16067 switch (blending) { 16068 case NormalBlending: 16069 gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); 16070 break; 16071 16072 case AdditiveBlending: 16073 gl.blendFunc(gl.SRC_ALPHA, gl.ONE); 16074 break; 16075 16076 case SubtractiveBlending: 16077 gl.blendFunc(gl.ZERO, gl.ONE_MINUS_SRC_COLOR); 16078 break; 16079 16080 case MultiplyBlending: 16081 gl.blendFunc(gl.ZERO, gl.SRC_COLOR); 16082 break; 16083 16084 default: 16085 console.error('THREE.WebGLState: Invalid blending: ', blending); 16086 break; 16087 } 16088 } 16089 16090 currentBlendSrc = null; 16091 currentBlendDst = null; 16092 currentBlendSrcAlpha = null; 16093 currentBlendDstAlpha = null; 16094 currentBlending = blending; 16095 currentPremultipledAlpha = premultipliedAlpha; 16096 } 16097 16098 return; 16099 } // custom blending 16100 16101 16102 blendEquationAlpha = blendEquationAlpha || blendEquation; 16103 blendSrcAlpha = blendSrcAlpha || blendSrc; 16104 blendDstAlpha = blendDstAlpha || blendDst; 16105 16106 if (blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha) { 16107 gl.blendEquationSeparate(equationToGL[blendEquation], equationToGL[blendEquationAlpha]); 16108 currentBlendEquation = blendEquation; 16109 currentBlendEquationAlpha = blendEquationAlpha; 16110 } 16111 16112 if (blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha) { 16113 gl.blendFuncSeparate(factorToGL[blendSrc], factorToGL[blendDst], factorToGL[blendSrcAlpha], factorToGL[blendDstAlpha]); 16114 currentBlendSrc = blendSrc; 16115 currentBlendDst = blendDst; 16116 currentBlendSrcAlpha = blendSrcAlpha; 16117 currentBlendDstAlpha = blendDstAlpha; 16118 } 16119 16120 currentBlending = blending; 16121 currentPremultipledAlpha = null; 16122 } 16123 16124 function setMaterial(material, frontFaceCW) { 16125 material.side === DoubleSide ? disable(gl.CULL_FACE) : enable(gl.CULL_FACE); 16126 let flipSided = material.side === BackSide; 16127 if (frontFaceCW) flipSided = !flipSided; 16128 setFlipSided(flipSided); 16129 material.blending === NormalBlending && material.transparent === false ? setBlending(NoBlending) : setBlending(material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha); 16130 depthBuffer.setFunc(material.depthFunc); 16131 depthBuffer.setTest(material.depthTest); 16132 depthBuffer.setMask(material.depthWrite); 16133 colorBuffer.setMask(material.colorWrite); 16134 const stencilWrite = material.stencilWrite; 16135 stencilBuffer.setTest(stencilWrite); 16136 16137 if (stencilWrite) { 16138 stencilBuffer.setMask(material.stencilWriteMask); 16139 stencilBuffer.setFunc(material.stencilFunc, material.stencilRef, material.stencilFuncMask); 16140 stencilBuffer.setOp(material.stencilFail, material.stencilZFail, material.stencilZPass); 16141 } 16142 16143 setPolygonOffset(material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits); 16144 material.alphaToCoverage === true ? enable(gl.SAMPLE_ALPHA_TO_COVERAGE) : disable(gl.SAMPLE_ALPHA_TO_COVERAGE); 16145 } // 16146 16147 16148 function setFlipSided(flipSided) { 16149 if (currentFlipSided !== flipSided) { 16150 if (flipSided) { 16151 gl.frontFace(gl.CW); 16152 } else { 16153 gl.frontFace(gl.CCW); 16154 } 16155 16156 currentFlipSided = flipSided; 16157 } 16158 } 16159 16160 function setCullFace(cullFace) { 16161 if (cullFace !== CullFaceNone) { 16162 enable(gl.CULL_FACE); 16163 16164 if (cullFace !== currentCullFace) { 16165 if (cullFace === CullFaceBack) { 16166 gl.cullFace(gl.BACK); 16167 } else if (cullFace === CullFaceFront) { 16168 gl.cullFace(gl.FRONT); 16169 } else { 16170 gl.cullFace(gl.FRONT_AND_BACK); 16171 } 16172 } 16173 } else { 16174 disable(gl.CULL_FACE); 16175 } 16176 16177 currentCullFace = cullFace; 16178 } 16179 16180 function setLineWidth(width) { 16181 if (width !== currentLineWidth) { 16182 if (lineWidthAvailable) gl.lineWidth(width); 16183 currentLineWidth = width; 16184 } 16185 } 16186 16187 function setPolygonOffset(polygonOffset, factor, units) { 16188 if (polygonOffset) { 16189 enable(gl.POLYGON_OFFSET_FILL); 16190 16191 if (currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units) { 16192 gl.polygonOffset(factor, units); 16193 currentPolygonOffsetFactor = factor; 16194 currentPolygonOffsetUnits = units; 16195 } 16196 } else { 16197 disable(gl.POLYGON_OFFSET_FILL); 16198 } 16199 } 16200 16201 function setScissorTest(scissorTest) { 16202 if (scissorTest) { 16203 enable(gl.SCISSOR_TEST); 16204 } else { 16205 disable(gl.SCISSOR_TEST); 16206 } 16207 } // texture 16208 16209 16210 function activeTexture(webglSlot) { 16211 if (webglSlot === undefined) webglSlot = gl.TEXTURE0 + maxTextures - 1; 16212 16213 if (currentTextureSlot !== webglSlot) { 16214 gl.activeTexture(webglSlot); 16215 currentTextureSlot = webglSlot; 16216 } 16217 } 16218 16219 function bindTexture(webglType, webglTexture) { 16220 if (currentTextureSlot === null) { 16221 activeTexture(); 16222 } 16223 16224 let boundTexture = currentBoundTextures[currentTextureSlot]; 16225 16226 if (boundTexture === undefined) { 16227 boundTexture = { 16228 type: undefined, 16229 texture: undefined 16230 }; 16231 currentBoundTextures[currentTextureSlot] = boundTexture; 16232 } 16233 16234 if (boundTexture.type !== webglType || boundTexture.texture !== webglTexture) { 16235 gl.bindTexture(webglType, webglTexture || emptyTextures[webglType]); 16236 boundTexture.type = webglType; 16237 boundTexture.texture = webglTexture; 16238 } 16239 } 16240 16241 function unbindTexture() { 16242 const boundTexture = currentBoundTextures[currentTextureSlot]; 16243 16244 if (boundTexture !== undefined && boundTexture.type !== undefined) { 16245 gl.bindTexture(boundTexture.type, null); 16246 boundTexture.type = undefined; 16247 boundTexture.texture = undefined; 16248 } 16249 } 16250 16251 function compressedTexImage2D() { 16252 try { 16253 gl.compressedTexImage2D.apply(gl, arguments); 16254 } catch (error) { 16255 console.error('THREE.WebGLState:', error); 16256 } 16257 } 16258 16259 function texSubImage2D() { 16260 try { 16261 gl.texSubImage2D.apply(gl, arguments); 16262 } catch (error) { 16263 console.error('THREE.WebGLState:', error); 16264 } 16265 } 16266 16267 function texSubImage3D() { 16268 try { 16269 gl.texSubImage3D.apply(gl, arguments); 16270 } catch (error) { 16271 console.error('THREE.WebGLState:', error); 16272 } 16273 } 16274 16275 function compressedTexSubImage2D() { 16276 try { 16277 gl.compressedTexSubImage2D.apply(gl, arguments); 16278 } catch (error) { 16279 console.error('THREE.WebGLState:', error); 16280 } 16281 } 16282 16283 function texStorage2D() { 16284 try { 16285 gl.texStorage2D.apply(gl, arguments); 16286 } catch (error) { 16287 console.error('THREE.WebGLState:', error); 16288 } 16289 } 16290 16291 function texStorage3D() { 16292 try { 16293 gl.texStorage3D.apply(gl, arguments); 16294 } catch (error) { 16295 console.error('THREE.WebGLState:', error); 16296 } 16297 } 16298 16299 function texImage2D() { 16300 try { 16301 gl.texImage2D.apply(gl, arguments); 16302 } catch (error) { 16303 console.error('THREE.WebGLState:', error); 16304 } 16305 } 16306 16307 function texImage3D() { 16308 try { 16309 gl.texImage3D.apply(gl, arguments); 16310 } catch (error) { 16311 console.error('THREE.WebGLState:', error); 16312 } 16313 } // 16314 16315 16316 function scissor(scissor) { 16317 if (currentScissor.equals(scissor) === false) { 16318 gl.scissor(scissor.x, scissor.y, scissor.z, scissor.w); 16319 currentScissor.copy(scissor); 16320 } 16321 } 16322 16323 function viewport(viewport) { 16324 if (currentViewport.equals(viewport) === false) { 16325 gl.viewport(viewport.x, viewport.y, viewport.z, viewport.w); 16326 currentViewport.copy(viewport); 16327 } 16328 } // 16329 16330 16331 function reset() { 16332 // reset state 16333 gl.disable(gl.BLEND); 16334 gl.disable(gl.CULL_FACE); 16335 gl.disable(gl.DEPTH_TEST); 16336 gl.disable(gl.POLYGON_OFFSET_FILL); 16337 gl.disable(gl.SCISSOR_TEST); 16338 gl.disable(gl.STENCIL_TEST); 16339 gl.disable(gl.SAMPLE_ALPHA_TO_COVERAGE); 16340 gl.blendEquation(gl.FUNC_ADD); 16341 gl.blendFunc(gl.ONE, gl.ZERO); 16342 gl.blendFuncSeparate(gl.ONE, gl.ZERO, gl.ONE, gl.ZERO); 16343 gl.colorMask(true, true, true, true); 16344 gl.clearColor(0, 0, 0, 0); 16345 gl.depthMask(true); 16346 gl.depthFunc(gl.LESS); 16347 gl.clearDepth(1); 16348 gl.stencilMask(0xffffffff); 16349 gl.stencilFunc(gl.ALWAYS, 0, 0xffffffff); 16350 gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); 16351 gl.clearStencil(0); 16352 gl.cullFace(gl.BACK); 16353 gl.frontFace(gl.CCW); 16354 gl.polygonOffset(0, 0); 16355 gl.activeTexture(gl.TEXTURE0); 16356 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 16357 16358 if (isWebGL2 === true) { 16359 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null); 16360 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null); 16361 } 16362 16363 gl.useProgram(null); 16364 gl.lineWidth(1); 16365 gl.scissor(0, 0, gl.canvas.width, gl.canvas.height); 16366 gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); // reset internals 16367 16368 enabledCapabilities = {}; 16369 currentTextureSlot = null; 16370 currentBoundTextures = {}; 16371 currentBoundFramebuffers = {}; 16372 currentProgram = null; 16373 currentBlendingEnabled = false;
vendor: 4,534 bytes, lines 16374-16496
16374 currentBlending = null; 16375 currentBlendEquation = null; 16376 currentBlendSrc = null; 16377 currentBlendDst = null; 16378 currentBlendEquationAlpha = null; 16379 currentBlendSrcAlpha = null; 16380 currentBlendDstAlpha = null; 16381 currentPremultipledAlpha = false; 16382 currentFlipSided = null; 16383 currentCullFace = null; 16384 currentLineWidth = null; 16385 currentPolygonOffsetFactor = null; 16386 currentPolygonOffsetUnits = null; 16387 currentScissor.set(0, 0, gl.canvas.width, gl.canvas.height); 16388 currentViewport.set(0, 0, gl.canvas.width, gl.canvas.height); 16389 colorBuffer.reset(); 16390 depthBuffer.reset(); 16391 stencilBuffer.reset(); 16392 } 16393 16394 return { 16395 buffers: { 16396 color: colorBuffer, 16397 depth: depthBuffer, 16398 stencil: stencilBuffer 16399 }, 16400 enable: enable, 16401 disable: disable, 16402 bindFramebuffer: bindFramebuffer, 16403 useProgram: useProgram, 16404 setBlending: setBlending, 16405 setMaterial: setMaterial, 16406 setFlipSided: setFlipSided, 16407 setCullFace: setCullFace, 16408 setLineWidth: setLineWidth, 16409 setPolygonOffset: setPolygonOffset, 16410 setScissorTest: setScissorTest, 16411 activeTexture: activeTexture, 16412 bindTexture: bindTexture, 16413 unbindTexture: unbindTexture, 16414 compressedTexImage2D: compressedTexImage2D, 16415 texImage2D: texImage2D, 16416 texImage3D: texImage3D, 16417 texStorage2D: texStorage2D, 16418 texStorage3D: texStorage3D, 16419 texSubImage2D: texSubImage2D, 16420 texSubImage3D: texSubImage3D, 16421 compressedTexSubImage2D: compressedTexSubImage2D, 16422 scissor: scissor, 16423 viewport: viewport, 16424 reset: reset 16425 }; 16426 } 16427 16428 function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info) { 16429 const isWebGL2 = capabilities.isWebGL2; 16430 const maxTextures = capabilities.maxTextures; 16431 const maxCubemapSize = capabilities.maxCubemapSize; 16432 const maxTextureSize = capabilities.maxTextureSize; 16433 const maxSamples = capabilities.maxSamples; 16434 const hasMultisampledRenderToTexture = extensions.has('WEBGL_multisampled_render_to_texture'); 16435 const MultisampledRenderToTextureExtension = hasMultisampledRenderToTexture ? extensions.get('WEBGL_multisampled_render_to_texture') : undefined; 16436 16437 const _videoTextures = new WeakMap(); 16438 16439 let _canvas; // cordova iOS (as of 5.0) still uses UIWebView, which provides OffscreenCanvas, 16440 // also OffscreenCanvas.getContext("webgl"), but not OffscreenCanvas.getContext("2d")! 16441 // Some implementations may only implement OffscreenCanvas partially (e.g. lacking 2d). 16442 16443 16444 let useOffscreenCanvas = false; 16445 16446 try { 16447 useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' && new OffscreenCanvas(1, 1).getContext('2d') !== null; 16448 } catch (err) {// Ignore any errors 16449 } 16450 16451 function createCanvas(width, height) { 16452 // Use OffscreenCanvas when available. Specially needed in web workers 16453 return useOffscreenCanvas ? new OffscreenCanvas(width, height) : createElementNS('canvas'); 16454 } 16455 16456 function resizeImage(image, needsPowerOfTwo, needsNewCanvas, maxSize) { 16457 let scale = 1; // handle case if texture exceeds max size 16458 16459 if (image.width > maxSize || image.height > maxSize) { 16460 scale = maxSize / Math.max(image.width, image.height); 16461 } // only perform resize if necessary 16462 16463 16464 if (scale < 1 || needsPowerOfTwo === true) { 16465 // only perform resize for certain image types 16466 if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) { 16467 const floor = needsPowerOfTwo ? floorPowerOfTwo : Math.floor; 16468 const width = floor(scale * image.width); 16469 const height = floor(scale * image.height); 16470 if (_canvas === undefined) _canvas = createCanvas(width, height); // cube textures can't reuse the same canvas 16471 16472 const canvas = needsNewCanvas ? createCanvas(width, height) : _canvas; 16473 canvas.width = width; 16474 canvas.height = height; 16475 const context = canvas.getContext('2d'); 16476 context.drawImage(image, 0, 0, width, height); 16477 console.warn('THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').'); 16478 return canvas; 16479 } else { 16480 if ('data' in image) { 16481 console.warn('THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').'); 16482 } 16483 16484 return image; 16485 } 16486 } 16487 16488 return image; 16489 } 16490 16491 function isPowerOfTwo$1(image) { 16492 return isPowerOfTwo(image.width) && isPowerOfTwo(image.height); 16493 } 16494 16495 function textureNeedsPowerOfTwo(texture) { 16496 if (isWebGL2) return false;
16497 return texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping || texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; 16498 } 16499 16500 function textureNeedsGenerateMipmaps(texture, supportsMips) { 16501 return texture.generateMipmaps && supportsMips && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; 16502 } 16503 16504 function generateMipmap(target) { 16505 _gl.generateMipmap(target); 16506 } 16507 16508 function getInternalFormat(internalFormatName, glFormat, glType, encoding) { 16509 if (isWebGL2 === false) return glFormat; 16510 16511 if (internalFormatName !== null) { 16512 if (_gl[internalFormatName] !== undefined) return _gl[internalFormatName]; 16513 console.warn('THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\''); 16514 } 16515 16516 let internalFormat = glFormat; 16517 16518 if (glFormat === _gl.RED) { 16519 if (glType === _gl.FLOAT) internalFormat = _gl.R32F; 16520 if (glType === _gl.HALF_FLOAT) internalFormat = _gl.R16F; 16521 if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.R8; 16522 } 16523 16524 if (glFormat === _gl.RGB) { 16525 if (glType === _gl.FLOAT) internalFormat = _gl.RGB32F; 16526 if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RGB16F; 16527 if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RGB8; 16528 } 16529 16530 if (glFormat === _gl.RGBA) { 16531 if (glType === _gl.FLOAT) internalFormat = _gl.RGBA32F; 16532 if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RGBA16F; 16533 if (glType === _gl.UNSIGNED_BYTE) internalFormat = encoding === sRGBEncoding ? _gl.SRGB8_ALPHA8 : _gl.RGBA8; 16534 } 16535 16536 if (internalFormat === _gl.R16F || internalFormat === _gl.R32F || internalFormat === _gl.RGBA16F || internalFormat === _gl.RGBA32F) { 16537 extensions.get('EXT_color_buffer_float'); 16538 } 16539 16540 return internalFormat; 16541 } 16542 16543 function getMipLevels(texture, image, supportsMips) { 16544 if (textureNeedsGenerateMipmaps(texture, supportsMips) === true || texture.isFramebufferTexture && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter) { 16545 return Math.log2(Math.max(image.width, image.height)) + 1; 16546 } else if (texture.mipmaps !== undefined && texture.mipmaps.length > 0) { 16547 // user-defined mipmaps 16548 return texture.mipmaps.length; 16549 } else if (texture.isCompressedTexture && Array.isArray(texture.image)) { 16550 return image.mipmaps.length; 16551 } else { 16552 // texture without mipmaps (only base level) 16553 return 1; 16554 } 16555 } // Fallback filters for non-power-of-2 textures 16556 16557 16558 function filterFallback(f) { 16559 if (f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter) { 16560 return _gl.NEAREST; 16561 } 16562 16563 return _gl.LINEAR; 16564 } // 16565 16566 16567 function onTextureDispose(event) { 16568 const texture = event.target; 16569 texture.removeEventListener('dispose', onTextureDispose); 16570 deallocateTexture(texture); 16571 16572 if (texture.isVideoTexture) { 16573 _videoTextures.delete(texture); 16574 } 16575 16576 info.memory.textures--; 16577 } 16578 16579 function onRenderTargetDispose(event) { 16580 const renderTarget = event.target; 16581 renderTarget.removeEventListener('dispose', onRenderTargetDispose); 16582 deallocateRenderTarget(renderTarget); 16583 } // 16584 16585 16586 function deallocateTexture(texture) { 16587 const textureProperties = properties.get(texture); 16588 if (textureProperties.__webglInit === undefined) return; 16589 16590 _gl.deleteTexture(textureProperties.__webglTexture); 16591 16592 properties.remove(texture); 16593 } 16594 16595 function deallocateRenderTarget(renderTarget) { 16596 const texture = renderTarget.texture; 16597 const renderTargetProperties = properties.get(renderTarget); 16598 const textureProperties = properties.get(texture); 16599 if (!renderTarget) return; 16600 16601 if (textureProperties.__webglTexture !== undefined) { 16602 _gl.deleteTexture(textureProperties.__webglTexture); 16603 16604 info.memory.textures--; 16605 } 16606 16607 if (renderTarget.depthTexture) { 16608 renderTarget.depthTexture.dispose(); 16609 } 16610 16611 if (renderTarget.isWebGLCubeRenderTarget) { 16612 for (let i = 0; i < 6; i++) { 16613 _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[i]); 16614 16615 if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer[i]); 16616 } 16617 } else { 16618 _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer); 16619 16620 if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer); 16621 if (renderTargetProperties.__webglMultisampledFramebuffer) _gl.deleteFramebuffer(renderTargetProperties.__webglMultisampledFramebuffer);
vendor: 10,835 bytes, lines 16622-16892
16622 if (renderTargetProperties.__webglColorRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglColorRenderbuffer); 16623 if (renderTargetProperties.__webglDepthRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthRenderbuffer); 16624 } 16625 16626 if (renderTarget.isWebGLMultipleRenderTargets) { 16627 for (let i = 0, il = texture.length; i < il; i++) { 16628 const attachmentProperties = properties.get(texture[i]); 16629 16630 if (attachmentProperties.__webglTexture) { 16631 _gl.deleteTexture(attachmentProperties.__webglTexture); 16632 16633 info.memory.textures--; 16634 } 16635 16636 properties.remove(texture[i]); 16637 } 16638 } 16639 16640 properties.remove(texture); 16641 properties.remove(renderTarget); 16642 } // 16643 16644 16645 let textureUnits = 0; 16646 16647 function resetTextureUnits() { 16648 textureUnits = 0; 16649 } 16650 16651 function allocateTextureUnit() { 16652 const textureUnit = textureUnits; 16653 16654 if (textureUnit >= maxTextures) { 16655 console.warn('THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures); 16656 } 16657 16658 textureUnits += 1; 16659 return textureUnit; 16660 } // 16661 16662 16663 function setTexture2D(texture, slot) { 16664 const textureProperties = properties.get(texture); 16665 if (texture.isVideoTexture) updateVideoTexture(texture); 16666 16667 if (texture.version > 0 && textureProperties.__version !== texture.version) { 16668 const image = texture.image; 16669 16670 if (image === undefined) { 16671 console.warn('THREE.WebGLRenderer: Texture marked for update but image is undefined'); 16672 } else if (image.complete === false) { 16673 console.warn('THREE.WebGLRenderer: Texture marked for update but image is incomplete'); 16674 } else { 16675 uploadTexture(textureProperties, texture, slot); 16676 return; 16677 } 16678 } 16679 16680 state.activeTexture(_gl.TEXTURE0 + slot); 16681 state.bindTexture(_gl.TEXTURE_2D, textureProperties.__webglTexture); 16682 } 16683 16684 function setTexture2DArray(texture, slot) { 16685 const textureProperties = properties.get(texture); 16686 16687 if (texture.version > 0 && textureProperties.__version !== texture.version) { 16688 uploadTexture(textureProperties, texture, slot); 16689 return; 16690 } 16691 16692 state.activeTexture(_gl.TEXTURE0 + slot); 16693 state.bindTexture(_gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture); 16694 } 16695 16696 function setTexture3D(texture, slot) { 16697 const textureProperties = properties.get(texture); 16698 16699 if (texture.version > 0 && textureProperties.__version !== texture.version) { 16700 uploadTexture(textureProperties, texture, slot); 16701 return; 16702 } 16703 16704 state.activeTexture(_gl.TEXTURE0 + slot); 16705 state.bindTexture(_gl.TEXTURE_3D, textureProperties.__webglTexture); 16706 } 16707 16708 function setTextureCube(texture, slot) { 16709 const textureProperties = properties.get(texture); 16710 16711 if (texture.version > 0 && textureProperties.__version !== texture.version) { 16712 uploadCubeTexture(textureProperties, texture, slot); 16713 return; 16714 } 16715 16716 state.activeTexture(_gl.TEXTURE0 + slot); 16717 state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture); 16718 } 16719 16720 const wrappingToGL = { 16721 [RepeatWrapping]: _gl.REPEAT, 16722 [ClampToEdgeWrapping]: _gl.CLAMP_TO_EDGE, 16723 [MirroredRepeatWrapping]: _gl.MIRRORED_REPEAT 16724 }; 16725 const filterToGL = { 16726 [NearestFilter]: _gl.NEAREST, 16727 [NearestMipmapNearestFilter]: _gl.NEAREST_MIPMAP_NEAREST, 16728 [NearestMipmapLinearFilter]: _gl.NEAREST_MIPMAP_LINEAR, 16729 [LinearFilter]: _gl.LINEAR, 16730 [LinearMipmapNearestFilter]: _gl.LINEAR_MIPMAP_NEAREST, 16731 [LinearMipmapLinearFilter]: _gl.LINEAR_MIPMAP_LINEAR 16732 }; 16733 16734 function setTextureParameters(textureType, texture, supportsMips) { 16735 if (supportsMips) { 16736 _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_S, wrappingToGL[texture.wrapS]); 16737 16738 _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_T, wrappingToGL[texture.wrapT]); 16739 16740 if (textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY) { 16741 _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_R, wrappingToGL[texture.wrapR]); 16742 } 16743 16744 _gl.texParameteri(textureType, _gl.TEXTURE_MAG_FILTER, filterToGL[texture.magFilter]); 16745 16746 _gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterToGL[texture.minFilter]); 16747 } else { 16748 _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE); 16749 16750 _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE); 16751 16752 if (textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY) { 16753 _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_R, _gl.CLAMP_TO_EDGE); 16754 } 16755 16756 if (texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping) { 16757 console.warn('THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.'); 16758 } 16759 16760 _gl.texParameteri(textureType, _gl.TEXTURE_MAG_FILTER, filterFallback(texture.magFilter)); 16761 16762 _gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterFallback(texture.minFilter)); 16763 16764 if (texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter) { 16765 console.warn('THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.'); 16766 } 16767 } 16768 16769 if (extensions.has('EXT_texture_filter_anisotropic') === true) { 16770 const extension = extensions.get('EXT_texture_filter_anisotropic'); 16771 if (texture.type === FloatType && extensions.has('OES_texture_float_linear') === false) return; // verify extension for WebGL 1 and WebGL 2 16772 16773 if (isWebGL2 === false && texture.type === HalfFloatType && extensions.has('OES_texture_half_float_linear') === false) return; // verify extension for WebGL 1 only 16774 16775 if (texture.anisotropy > 1 || properties.get(texture).__currentAnisotropy) { 16776 _gl.texParameterf(textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(texture.anisotropy, capabilities.getMaxAnisotropy())); 16777 16778 properties.get(texture).__currentAnisotropy = texture.anisotropy; 16779 } 16780 } 16781 } 16782 16783 function initTexture(textureProperties, texture) { 16784 if (textureProperties.__webglInit === undefined) { 16785 textureProperties.__webglInit = true; 16786 texture.addEventListener('dispose', onTextureDispose); 16787 textureProperties.__webglTexture = _gl.createTexture(); 16788 info.memory.textures++; 16789 } 16790 } 16791 16792 function uploadTexture(textureProperties, texture, slot) { 16793 let textureType = _gl.TEXTURE_2D; 16794 if (texture.isDataTexture2DArray) textureType = _gl.TEXTURE_2D_ARRAY; 16795 if (texture.isDataTexture3D) textureType = _gl.TEXTURE_3D; 16796 initTexture(textureProperties, texture); 16797 state.activeTexture(_gl.TEXTURE0 + slot); 16798 state.bindTexture(textureType, textureProperties.__webglTexture); 16799 16800 _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); 16801 16802 _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha); 16803 16804 _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, texture.unpackAlignment); 16805 16806 _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE); 16807 16808 const needsPowerOfTwo = textureNeedsPowerOfTwo(texture) && isPowerOfTwo$1(texture.image) === false; 16809 const image = resizeImage(texture.image, needsPowerOfTwo, false, maxTextureSize); 16810 const supportsMips = isPowerOfTwo$1(image) || isWebGL2, 16811 glFormat = utils.convert(texture.format); 16812 let glType = utils.convert(texture.type), 16813 glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding); 16814 setTextureParameters(textureType, texture, supportsMips); 16815 let mipmap; 16816 const mipmaps = texture.mipmaps; 16817 const useTexStorage = isWebGL2 && texture.isVideoTexture !== true; 16818 const allocateMemory = textureProperties.__version === undefined; 16819 const levels = getMipLevels(texture, image, supportsMips); 16820 16821 if (texture.isDepthTexture) { 16822 // populate depth texture with dummy data 16823 glInternalFormat = _gl.DEPTH_COMPONENT; 16824 16825 if (isWebGL2) { 16826 if (texture.type === FloatType) { 16827 glInternalFormat = _gl.DEPTH_COMPONENT32F; 16828 } else if (texture.type === UnsignedIntType) { 16829 glInternalFormat = _gl.DEPTH_COMPONENT24; 16830 } else if (texture.type === UnsignedInt248Type) { 16831 glInternalFormat = _gl.DEPTH24_STENCIL8; 16832 } else { 16833 glInternalFormat = _gl.DEPTH_COMPONENT16; // WebGL2 requires sized internalformat for glTexImage2D 16834 } 16835 } else { 16836 if (texture.type === FloatType) { 16837 console.error('WebGLRenderer: Floating point depth texture requires WebGL2.'); 16838 } 16839 } // validation checks for WebGL 1 16840 16841 16842 if (texture.format === DepthFormat && glInternalFormat === _gl.DEPTH_COMPONENT) { 16843 // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are 16844 // DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT 16845 // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) 16846 if (texture.type !== UnsignedShortType && texture.type !== UnsignedIntType) { 16847 console.warn('THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.'); 16848 texture.type = UnsignedShortType; 16849 glType = utils.convert(texture.type); 16850 } 16851 } 16852 16853 if (texture.format === DepthStencilFormat && glInternalFormat === _gl.DEPTH_COMPONENT) { 16854 // Depth stencil textures need the DEPTH_STENCIL internal format 16855 // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) 16856 glInternalFormat = _gl.DEPTH_STENCIL; // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are 16857 // DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL. 16858 // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) 16859 16860 if (texture.type !== UnsignedInt248Type) { 16861 console.warn('THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.'); 16862 texture.type = UnsignedInt248Type; 16863 glType = utils.convert(texture.type); 16864 } 16865 } // 16866 16867 16868 if (useTexStorage && allocateMemory) { 16869 state.texStorage2D(_gl.TEXTURE_2D, 1, glInternalFormat, image.width, image.height); 16870 } else { 16871 state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null); 16872 } 16873 } else if (texture.isDataTexture) { 16874 // use manually created mipmaps if available 16875 // if there are no manual mipmaps 16876 // set 0 level mipmap and then use GL to generate other mipmap levels 16877 if (mipmaps.length > 0 && supportsMips) { 16878 if (useTexStorage && allocateMemory) { 16879 state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); 16880 } 16881 16882 for (let i = 0, il = mipmaps.length; i < il; i++) { 16883 mipmap = mipmaps[i]; 16884 16885 if (useTexStorage) { 16886 state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); 16887 } else { 16888 state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); 16889 } 16890 } 16891 16892 texture.generateMipmaps = false;
16893 } else { 16894 if (useTexStorage) { 16895 if (allocateMemory) { 16896 state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); 16897 } 16898 16899 state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data); 16900 } else { 16901 state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data); 16902 } 16903 } 16904 } else if (texture.isCompressedTexture) { 16905 if (useTexStorage && allocateMemory) { 16906 state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); 16907 } 16908 16909 for (let i = 0, il = mipmaps.length; i < il; i++) { 16910 mipmap = mipmaps[i]; 16911 16912 if (texture.format !== RGBAFormat && texture.format !== RGBFormat) { 16913 if (glFormat !== null) { 16914 if (useTexStorage) { 16915 state.compressedTexSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data); 16916 } else { 16917 state.compressedTexImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data); 16918 } 16919 } else { 16920 console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()'); 16921 } 16922 } else { 16923 if (useTexStorage) { 16924 state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); 16925 } else { 16926 state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); 16927 } 16928 } 16929 } 16930 } else if (texture.isDataTexture2DArray) { 16931 if (useTexStorage) { 16932 if (allocateMemory) { 16933 state.texStorage3D(_gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, image.width, image.height, image.depth); 16934 } 16935 16936 state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data); 16937 } else { 16938 state.texImage3D(_gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data); 16939 } 16940 } else if (texture.isDataTexture3D) { 16941 if (useTexStorage) { 16942 if (allocateMemory) { 16943 state.texStorage3D(_gl.TEXTURE_3D, levels, glInternalFormat, image.width, image.height, image.depth); 16944 } 16945 16946 state.texSubImage3D(_gl.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data); 16947 } else { 16948 state.texImage3D(_gl.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data); 16949 } 16950 } else if (texture.isFramebufferTexture) { 16951 if (useTexStorage && allocateMemory) { 16952 state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); 16953 } else { 16954 state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null); 16955 } 16956 } else { 16957 // regular Texture (image, video, canvas) 16958 // use manually created mipmaps if available 16959 // if there are no manual mipmaps 16960 // set 0 level mipmap and then use GL to generate other mipmap levels 16961 if (mipmaps.length > 0 && supportsMips) { 16962 if (useTexStorage && allocateMemory) { 16963 state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); 16964 } 16965 16966 for (let i = 0, il = mipmaps.length; i < il; i++) { 16967 mipmap = mipmaps[i]; 16968 16969 if (useTexStorage) { 16970 state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap); 16971 } else { 16972 state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap); 16973 } 16974 } 16975 16976 texture.generateMipmaps = false; 16977 } else { 16978 if (useTexStorage) { 16979 if (allocateMemory) { 16980 state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); 16981 } 16982 16983 state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, glFormat, glType, image); 16984 } else { 16985 state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image); 16986 } 16987 } 16988 } 16989 16990 if (textureNeedsGenerateMipmaps(texture, supportsMips)) { 16991 generateMipmap(textureType); 16992 } 16993 16994 textureProperties.__version = texture.version; 16995 if (texture.onUpdate) texture.onUpdate(texture); 16996 } 16997 16998 function uploadCubeTexture(textureProperties, texture, slot) { 16999 if (texture.image.length !== 6) return; 17000 initTexture(textureProperties, texture); 17001 state.activeTexture(_gl.TEXTURE0 + slot); 17002 state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture); 17003 17004 _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); 17005 17006 _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha); 17007 17008 _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, texture.unpackAlignment); 17009 17010 _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE); 17011 17012 const isCompressed = texture && (texture.isCompressedTexture || texture.image[0].isCompressedTexture); 17013 const isDataTexture = texture.image[0] && texture.image[0].isDataTexture; 17014 const cubeImage = []; 17015 17016 for (let i = 0; i < 6; i++) { 17017 if (!isCompressed && !isDataTexture) { 17018 cubeImage[i] = resizeImage(texture.image[i], false, true, maxCubemapSize); 17019 } else { 17020 cubeImage[i] = isDataTexture ? texture.image[i].image : texture.image[i]; 17021 } 17022 } 17023 17024 const image = cubeImage[0], 17025 supportsMips = isPowerOfTwo$1(image) || isWebGL2, 17026 glFormat = utils.convert(texture.format), 17027 glType = utils.convert(texture.type), 17028 glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding); 17029 const useTexStorage = isWebGL2 && texture.isVideoTexture !== true; 17030 const allocateMemory = textureProperties.__version === undefined; 17031 let levels = getMipLevels(texture, image, supportsMips); 17032 setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture, supportsMips); 17033 let mipmaps; 17034 17035 if (isCompressed) { 17036 if (useTexStorage && allocateMemory) { 17037 state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, image.width, image.height); 17038 } 17039 17040 for (let i = 0; i < 6; i++) { 17041 mipmaps = cubeImage[i].mipmaps; 17042 17043 for (let j = 0; j < mipmaps.length; j++) { 17044 const mipmap = mipmaps[j]; 17045 17046 if (texture.format !== RGBAFormat && texture.format !== RGBFormat) { 17047 if (glFormat !== null) { 17048 if (useTexStorage) { 17049 state.compressedTexSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data); 17050 } else { 17051 state.compressedTexImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data); 17052 } 17053 } else { 17054 console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()'); 17055 } 17056 } else { 17057 if (useTexStorage) { 17058 state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); 17059 } else { 17060 state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); 17061 } 17062 } 17063 } 17064 } 17065 } else { 17066 mipmaps = texture.mipmaps; 17067 17068 if (useTexStorage && allocateMemory) { 17069 // TODO: Uniformly handle mipmap definitions 17070 // Normal textures and compressed cube textures define base level + mips with their mipmap array 17071 // Uncompressed cube textures use their mipmap array only for mips (no base level) 17072 if (mipmaps.length > 0) levels++; 17073 state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, cubeImage[0].width, cubeImage[0].height); 17074 } 17075 17076 for (let i = 0; i < 6; i++) { 17077 if (isDataTexture) { 17078 if (useTexStorage) { 17079 state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, cubeImage[i].width, cubeImage[i].height, glFormat, glType, cubeImage[i].data); 17080 } else { 17081 state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[i].width, cubeImage[i].height, 0, glFormat, glType, cubeImage[i].data); 17082 } 17083 17084 for (let j = 0; j < mipmaps.length; j++) { 17085 const mipmap = mipmaps[j]; 17086 const mipmapImage = mipmap.image[i].image; 17087 17088 if (useTexStorage) { 17089 state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width, mipmapImage.height, glFormat, glType, mipmapImage.data); 17090 } else { 17091 state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data); 17092 } 17093 } 17094 } else { 17095 if (useTexStorage) { 17096 state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[i]); 17097 } else { 17098 state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i]); 17099 } 17100 17101 for (let j = 0; j < mipmaps.length; j++) { 17102 const mipmap = mipmaps[j]; 17103 17104 if (useTexStorage) { 17105 state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[i]); 17106 } else { 17107 state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[i]); 17108 } 17109 } 17110 } 17111 } 17112 } 17113 17114 if (textureNeedsGenerateMipmaps(texture, supportsMips)) { 17115 // We assume images for cube map have the same size. 17116 generateMipmap(_gl.TEXTURE_CUBE_MAP); 17117 } 17118 17119 textureProperties.__version = texture.version; 17120 if (texture.onUpdate) texture.onUpdate(texture); 17121 } // Render targets 17122 // Setup storage for target texture and bind it to correct framebuffer 17123 17124 17125 function setupFrameBufferTexture(framebuffer, renderTarget, texture, attachment, textureTarget) { 17126 const glFormat = utils.convert(texture.format); 17127 const glType = utils.convert(texture.type); 17128 const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding); 17129 const renderTargetProperties = properties.get(renderTarget); 17130 17131 if (!renderTargetProperties.__hasExternalTextures) { 17132 if (textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY) { 17133 state.texImage3D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, renderTarget.depth, 0, glFormat, glType, null); 17134 } else { 17135 state.texImage2D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null); 17136 } 17137 } 17138 17139 state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); 17140 17141 if (renderTarget.useRenderToTexture) { 17142 MultisampledRenderToTextureExtension.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, attachment, textureTarget, properties.get(texture).__webglTexture, 0, getRenderTargetSamples(renderTarget)); 17143 } else { 17144 _gl.framebufferTexture2D(_gl.FRAMEBUFFER, attachment, textureTarget, properties.get(texture).__webglTexture, 0); 17145 } 17146 17147 state.bindFramebuffer(_gl.FRAMEBUFFER, null); 17148 } // Setup storage for internal depth/stencil buffers and bind to correct framebuffer 17149 17150 17151 function setupRenderBufferStorage(renderbuffer, renderTarget, isMultisample) { 17152 _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer); 17153 17154 if (renderTarget.depthBuffer && !renderTarget.stencilBuffer) { 17155 let glInternalFormat = _gl.DEPTH_COMPONENT16; 17156 17157 if (isMultisample || renderTarget.useRenderToTexture) { 17158 const depthTexture = renderTarget.depthTexture; 17159 17160 if (depthTexture && depthTexture.isDepthTexture) { 17161 if (depthTexture.type === FloatType) { 17162 glInternalFormat = _gl.DEPTH_COMPONENT32F; 17163 } else if (depthTexture.type === UnsignedIntType) { 17164 glInternalFormat = _gl.DEPTH_COMPONENT24; 17165 } 17166 } 17167 17168 const samples = getRenderTargetSamples(renderTarget); 17169 17170 if (renderTarget.useRenderToTexture) { 17171 MultisampledRenderToTextureExtension.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); 17172 } else { 17173 _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); 17174 } 17175 } else { 17176 _gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height); 17177 } 17178 17179 _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer); 17180 } else if (renderTarget.depthBuffer && renderTarget.stencilBuffer) { 17181 const samples = getRenderTargetSamples(renderTarget); 17182 17183 if (isMultisample && renderTarget.useRenderbuffer) { 17184 _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height); 17185 } else if (renderTarget.useRenderToTexture) { 17186 MultisampledRenderToTextureExtension.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height); 17187 } else { 17188 _gl.renderbufferStorage(_gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height); 17189 } 17190 17191 _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer); 17192 } else { 17193 // Use the first texture for MRT so far 17194 const texture = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture[0] : renderTarget.texture; 17195 const glFormat = utils.convert(texture.format); 17196 const glType = utils.convert(texture.type); 17197 const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding); 17198 const samples = getRenderTargetSamples(renderTarget); 17199 17200 if (isMultisample && renderTarget.useRenderbuffer) { 17201 _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); 17202 } else if (renderTarget.useRenderToTexture) { 17203 MultisampledRenderToTextureExtension.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); 17204 } else { 17205 _gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height); 17206 } 17207 } 17208 17209 _gl.bindRenderbuffer(_gl.RENDERBUFFER, null); 17210 } // Setup resources for a Depth Texture for a FBO (needs an extension) 17211 17212 17213 function setupDepthTexture(framebuffer, renderTarget) {
vendor: 4,205 bytes, lines 17214-17307
17214 const isCube = renderTarget && renderTarget.isWebGLCubeRenderTarget; 17215 if (isCube) throw new Error('Depth Texture with cube render targets is not supported'); 17216 state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); 17217 17218 if (!(renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture)) { 17219 throw new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture'); 17220 } // upload an empty depth texture with framebuffer size 17221 17222 17223 if (!properties.get(renderTarget.depthTexture).__webglTexture || renderTarget.depthTexture.image.width !== renderTarget.width || renderTarget.depthTexture.image.height !== renderTarget.height) { 17224 renderTarget.depthTexture.image.width = renderTarget.width; 17225 renderTarget.depthTexture.image.height = renderTarget.height; 17226 renderTarget.depthTexture.needsUpdate = true; 17227 } 17228 17229 setTexture2D(renderTarget.depthTexture, 0); 17230 17231 const webglDepthTexture = properties.get(renderTarget.depthTexture).__webglTexture; 17232 17233 const samples = getRenderTargetSamples(renderTarget); 17234 17235 if (renderTarget.depthTexture.format === DepthFormat) { 17236 if (renderTarget.useRenderToTexture) { 17237 MultisampledRenderToTextureExtension.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples); 17238 } else { 17239 _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0); 17240 } 17241 } else if (renderTarget.depthTexture.format === DepthStencilFormat) { 17242 if (renderTarget.useRenderToTexture) { 17243 MultisampledRenderToTextureExtension.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples); 17244 } else { 17245 _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0); 17246 } 17247 } else { 17248 throw new Error('Unknown depthTexture format'); 17249 } 17250 } // Setup GL resources for a non-texture depth buffer 17251 17252 17253 function setupDepthRenderbuffer(renderTarget) { 17254 const renderTargetProperties = properties.get(renderTarget); 17255 const isCube = renderTarget.isWebGLCubeRenderTarget === true; 17256 17257 if (renderTarget.depthTexture && !renderTargetProperties.__autoAllocateDepthBuffer) { 17258 if (isCube) throw new Error('target.depthTexture not supported in Cube render targets'); 17259 setupDepthTexture(renderTargetProperties.__webglFramebuffer, renderTarget); 17260 } else { 17261 if (isCube) { 17262 renderTargetProperties.__webglDepthbuffer = []; 17263 17264 for (let i = 0; i < 6; i++) { 17265 state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[i]); 17266 renderTargetProperties.__webglDepthbuffer[i] = _gl.createRenderbuffer(); 17267 setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer[i], renderTarget, false); 17268 } 17269 } else { 17270 state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); 17271 renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); 17272 setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer, renderTarget, false); 17273 } 17274 } 17275 17276 state.bindFramebuffer(_gl.FRAMEBUFFER, null); 17277 } // rebind framebuffer with external textures 17278 17279 17280 function rebindTextures(renderTarget, colorTexture, depthTexture) { 17281 const renderTargetProperties = properties.get(renderTarget); 17282 17283 if (colorTexture !== undefined) { 17284 setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, renderTarget.texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D); 17285 } 17286 17287 if (depthTexture !== undefined) { 17288 setupDepthRenderbuffer(renderTarget); 17289 } 17290 } // Set up GL resources for the render target 17291 17292 17293 function setupRenderTarget(renderTarget) { 17294 const texture = renderTarget.texture; 17295 const renderTargetProperties = properties.get(renderTarget); 17296 const textureProperties = properties.get(texture); 17297 renderTarget.addEventListener('dispose', onRenderTargetDispose); 17298 17299 if (renderTarget.isWebGLMultipleRenderTargets !== true) { 17300 if (textureProperties.__webglTexture === undefined) { 17301 textureProperties.__webglTexture = _gl.createTexture(); 17302 } 17303 17304 textureProperties.__version = texture.version; 17305 info.memory.textures++; 17306 } 17307
17308 const isCube = renderTarget.isWebGLCubeRenderTarget === true; 17309 const isMultipleRenderTargets = renderTarget.isWebGLMultipleRenderTargets === true; 17310 const isRenderTarget3D = texture.isDataTexture3D || texture.isDataTexture2DArray; 17311 const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; // Handles WebGL2 RGBFormat fallback - #18858 17312 17313 if (isWebGL2 && texture.format === RGBFormat && (texture.type === FloatType || texture.type === HalfFloatType)) { 17314 texture.format = RGBAFormat; 17315 console.warn('THREE.WebGLRenderer: Rendering to textures with RGB format is not supported. Using RGBA format instead.'); 17316 } // Setup framebuffer 17317 17318 17319 if (isCube) { 17320 renderTargetProperties.__webglFramebuffer = []; 17321 17322 for (let i = 0; i < 6; i++) { 17323 renderTargetProperties.__webglFramebuffer[i] = _gl.createFramebuffer(); 17324 } 17325 } else { 17326 renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer(); 17327 17328 if (isMultipleRenderTargets) { 17329 if (capabilities.drawBuffers) { 17330 const textures = renderTarget.texture; 17331 17332 for (let i = 0, il = textures.length; i < il; i++) { 17333 const attachmentProperties = properties.get(textures[i]); 17334 17335 if (attachmentProperties.__webglTexture === undefined) { 17336 attachmentProperties.__webglTexture = _gl.createTexture(); 17337 info.memory.textures++; 17338 } 17339 } 17340 } else { 17341 console.warn('THREE.WebGLRenderer: WebGLMultipleRenderTargets can only be used with WebGL2 or WEBGL_draw_buffers extension.'); 17342 } 17343 } else if (renderTarget.useRenderbuffer) { 17344 if (isWebGL2) { 17345 renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer(); 17346 renderTargetProperties.__webglColorRenderbuffer = _gl.createRenderbuffer(); 17347 17348 _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer); 17349 17350 const glFormat = utils.convert(texture.format); 17351 const glType = utils.convert(texture.type); 17352 const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding); 17353 const samples = getRenderTargetSamples(renderTarget); 17354 17355 _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); 17356 17357 state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); 17358 17359 _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer); 17360 17361 _gl.bindRenderbuffer(_gl.RENDERBUFFER, null); 17362 17363 if (renderTarget.depthBuffer) { 17364 renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer(); 17365 setupRenderBufferStorage(renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true); 17366 } 17367 17368 state.bindFramebuffer(_gl.FRAMEBUFFER, null); 17369 } else { 17370 console.warn('THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.'); 17371 } 17372 } 17373 } // Setup color buffer 17374 17375 17376 if (isCube) { 17377 state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture); 17378 setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture, supportsMips); 17379 17380 for (let i = 0; i < 6; i++) { 17381 setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[i], renderTarget, texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i); 17382 } 17383 17384 if (textureNeedsGenerateMipmaps(texture, supportsMips)) { 17385 generateMipmap(_gl.TEXTURE_CUBE_MAP); 17386 } 17387 17388 state.unbindTexture(); 17389 } else if (isMultipleRenderTargets) { 17390 const textures = renderTarget.texture; 17391 17392 for (let i = 0, il = textures.length; i < il; i++) { 17393 const attachment = textures[i]; 17394 const attachmentProperties = properties.get(attachment); 17395 state.bindTexture(_gl.TEXTURE_2D, attachmentProperties.__webglTexture); 17396 setTextureParameters(_gl.TEXTURE_2D, attachment, supportsMips); 17397 setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, attachment, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D); 17398 17399 if (textureNeedsGenerateMipmaps(attachment, supportsMips)) { 17400 generateMipmap(_gl.TEXTURE_2D); 17401 } 17402 } 17403 17404 state.unbindTexture(); 17405 } else { 17406 let glTextureType = _gl.TEXTURE_2D; 17407 17408 if (isRenderTarget3D) { 17409 // Render targets containing layers, i.e: Texture 3D and 2d arrays 17410 if (isWebGL2) { 17411 const isTexture3D = texture.isDataTexture3D; 17412 glTextureType = isTexture3D ? _gl.TEXTURE_3D : _gl.TEXTURE_2D_ARRAY; 17413 } else { 17414 console.warn('THREE.DataTexture3D and THREE.DataTexture2DArray only supported with WebGL2.'); 17415 } 17416 } 17417 17418 state.bindTexture(glTextureType, textureProperties.__webglTexture); 17419 setTextureParameters(glTextureType, texture, supportsMips); 17420 setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, texture, _gl.COLOR_ATTACHMENT0, glTextureType); 17421 17422 if (textureNeedsGenerateMipmaps(texture, supportsMips)) { 17423 generateMipmap(glTextureType); 17424 } 17425 17426 state.unbindTexture(); 17427 } // Setup depth and stencil buffers 17428 17429 17430 if (renderTarget.depthBuffer) { 17431 setupDepthRenderbuffer(renderTarget); 17432 } 17433 } 17434 17435 function updateRenderTargetMipmap(renderTarget) { 17436 const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; 17437 const textures = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture : [renderTarget.texture]; 17438 17439 for (let i = 0, il = textures.length; i < il; i++) { 17440 const texture = textures[i]; 17441 17442 if (textureNeedsGenerateMipmaps(texture, supportsMips)) {
17443 const target = renderTarget.isWebGLCubeRenderTarget ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D; 17444 17445 const webglTexture = properties.get(texture).__webglTexture; 17446 17447 state.bindTexture(target, webglTexture); 17448 generateMipmap(target); 17449 state.unbindTexture(); 17450 } 17451 } 17452 } 17453 17454 function updateMultisampleRenderTarget(renderTarget) { 17455 if (renderTarget.useRenderbuffer) { 17456 if (isWebGL2) { 17457 const width = renderTarget.width; 17458 const height = renderTarget.height; 17459 let mask = _gl.COLOR_BUFFER_BIT; 17460 const invalidationArray = [_gl.COLOR_ATTACHMENT0]; 17461 const depthStyle = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; 17462 17463 if (renderTarget.depthBuffer) { 17464 invalidationArray.push(depthStyle); 17465 } 17466 17467 if (!renderTarget.ignoreDepthForMultisampleCopy) { 17468 if (renderTarget.depthBuffer) mask |= _gl.DEPTH_BUFFER_BIT; 17469 if (renderTarget.stencilBuffer) mask |= _gl.STENCIL_BUFFER_BIT; 17470 } 17471 17472 const renderTargetProperties = properties.get(renderTarget); 17473 state.bindFramebuffer(_gl.READ_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); 17474 state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); 17475 17476 if (renderTarget.ignoreDepthForMultisampleCopy) { 17477 _gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, [depthStyle]); 17478 17479 _gl.invalidateFramebuffer(_gl.DRAW_FRAMEBUFFER, [depthStyle]); 17480 } 17481 17482 _gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, mask, _gl.NEAREST); 17483 17484 _gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, invalidationArray); 17485 17486 state.bindFramebuffer(_gl.READ_FRAMEBUFFER, null); 17487 state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); 17488 } else { 17489 console.warn('THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.'); 17490 } 17491 } 17492 } 17493 17494 function getRenderTargetSamples(renderTarget) { 17495 return isWebGL2 && (renderTarget.useRenderbuffer || renderTarget.useRenderToTexture) ? Math.min(maxSamples, renderTarget.samples) : 0; 17496 } 17497 17498 function updateVideoTexture(texture) { 17499 const frame = info.render.frame; // Check the last frame we updated the VideoTexture 17500 17501 if (_videoTextures.get(texture) !== frame) { 17502 _videoTextures.set(texture, frame); 17503 17504 texture.update(); 17505 } 17506 } // backwards compatibility 17507 17508 17509 let warnedTexture2D = false; 17510 let warnedTextureCube = false; 17511 17512 function safeSetTexture2D(texture, slot) { 17513 if (texture && texture.isWebGLRenderTarget) { 17514 if (warnedTexture2D === false) { 17515 console.warn('THREE.WebGLTextures.safeSetTexture2D: don\'t use render targets as textures. Use their .texture property instead.'); 17516 warnedTexture2D = true; 17517 } 17518 17519 texture = texture.texture; 17520 } 17521 17522 setTexture2D(texture, slot); 17523 } 17524 17525 function safeSetTextureCube(texture, slot) { 17526 if (texture && texture.isWebGLCubeRenderTarget) { 17527 if (warnedTextureCube === false) { 17528 console.warn('THREE.WebGLTextures.safeSetTextureCube: don\'t use cube render targets as textures. Use their .texture property instead.'); 17529 warnedTextureCube = true; 17530 } 17531 17532 texture = texture.texture; 17533 } 17534 17535 setTextureCube(texture, slot); 17536 } // 17537 17538 17539 this.allocateTextureUnit = allocateTextureUnit; 17540 this.resetTextureUnits = resetTextureUnits; 17541 this.setTexture2D = setTexture2D; 17542 this.setTexture2DArray = setTexture2DArray; 17543 this.setTexture3D = setTexture3D; 17544 this.setTextureCube = setTextureCube; 17545 this.rebindTextures = rebindTextures; 17546 this.setupRenderTarget = setupRenderTarget; 17547 this.updateRenderTargetMipmap = updateRenderTargetMipmap; 17548 this.updateMultisampleRenderTarget = updateMultisampleRenderTarget; 17549 this.setupDepthRenderbuffer = setupDepthRenderbuffer; 17550 this.setupFrameBufferTexture = setupFrameBufferTexture; 17551 this.safeSetTexture2D = safeSetTexture2D; 17552 this.safeSetTextureCube = safeSetTextureCube; 17553 } 17554 17555 function WebGLUtils(gl, extensions, capabilities) { 17556 const isWebGL2 = capabilities.isWebGL2; 17557 17558 function convert(p) { 17559 let extension; 17560 if (p === UnsignedByteType) return gl.UNSIGNED_BYTE; 17561 if (p === UnsignedShort4444Type) return gl.UNSIGNED_SHORT_4_4_4_4; 17562 if (p === UnsignedShort5551Type) return gl.UNSIGNED_SHORT_5_5_5_1; 17563 if (p === UnsignedShort565Type) return gl.UNSIGNED_SHORT_5_6_5; 17564 if (p === ByteType) return gl.BYTE; 17565 if (p === ShortType) return gl.SHORT; 17566 if (p === UnsignedShortType) return gl.UNSIGNED_SHORT; 17567 if (p === IntType) return gl.INT; 17568 if (p === UnsignedIntType) return gl.UNSIGNED_INT; 17569 if (p === FloatType) return gl.FLOAT; 17570 17571 if (p === HalfFloatType) { 17572 if (isWebGL2) return gl.HALF_FLOAT; 17573 extension = extensions.get('OES_texture_half_float'); 17574 17575 if (extension !== null) { 17576 return extension.HALF_FLOAT_OES; 17577 } else { 17578 return null; 17579 } 17580 } 17581 17582 if (p === AlphaFormat) return gl.ALPHA; 17583 if (p === RGBFormat) return gl.RGB; 17584 if (p === RGBAFormat) return gl.RGBA; 17585 if (p === LuminanceFormat) return gl.LUMINANCE; 17586 if (p === LuminanceAlphaFormat) return gl.LUMINANCE_ALPHA; 17587 if (p === DepthFormat) return gl.DEPTH_COMPONENT; 17588 if (p === DepthStencilFormat) return gl.DEPTH_STENCIL; 17589 if (p === RedFormat) return gl.RED; // WebGL2 formats. 17590 17591 if (p === RedIntegerFormat) return gl.RED_INTEGER; 17592 if (p === RGFormat) return gl.RG; 17593 if (p === RGIntegerFormat) return gl.RG_INTEGER; 17594 if (p === RGBIntegerFormat) return gl.RGB_INTEGER; 17595 if (p === RGBAIntegerFormat) return gl.RGBA_INTEGER; 17596 17597 if (p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format) { 17598 extension = extensions.get('WEBGL_compressed_texture_s3tc'); 17599 17600 if (extension !== null) { 17601 if (p === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT; 17602 if (p === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT; 17603 if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; 17604 if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; 17605 } else { 17606 return null; 17607 } 17608 } 17609 17610 if (p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format) { 17611 extension = extensions.get('WEBGL_compressed_texture_pvrtc'); 17612 17613 if (extension !== null) { 17614 if (p === RGB_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; 17615 if (p === RGB_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; 17616 if (p === RGBA_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; 17617 if (p === RGBA_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; 17618 } else { 17619 return null; 17620 } 17621 } 17622 17623 if (p === RGB_ETC1_Format) { 17624 extension = extensions.get('WEBGL_compressed_texture_etc1'); 17625 17626 if (extension !== null) { 17627 return extension.COMPRESSED_RGB_ETC1_WEBGL; 17628 } else { 17629 return null; 17630 } 17631 } 17632 17633 if (p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format) { 17634 extension = extensions.get('WEBGL_compressed_texture_etc'); 17635 17636 if (extension !== null) { 17637 if (p === RGB_ETC2_Format) return extension.COMPRESSED_RGB8_ETC2; 17638 if (p === RGBA_ETC2_EAC_Format) return extension.COMPRESSED_RGBA8_ETC2_EAC; 17639 } 17640 } 17641 17642 if (p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format || p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format || p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format || p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format || p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format || p === SRGB8_ALPHA8_ASTC_4x4_Format || p === SRGB8_ALPHA8_ASTC_5x4_Format || p === SRGB8_ALPHA8_ASTC_5x5_Format || p === SRGB8_ALPHA8_ASTC_6x5_Format || p === SRGB8_ALPHA8_ASTC_6x6_Format || p === SRGB8_ALPHA8_ASTC_8x5_Format || p === SRGB8_ALPHA8_ASTC_8x6_Format || p === SRGB8_ALPHA8_ASTC_8x8_Format || p === SRGB8_ALPHA8_ASTC_10x5_Format || p === SRGB8_ALPHA8_ASTC_10x6_Format || p === SRGB8_ALPHA8_ASTC_10x8_Format || p === SRGB8_ALPHA8_ASTC_10x10_Format || p === SRGB8_ALPHA8_ASTC_12x10_Format || p === SRGB8_ALPHA8_ASTC_12x12_Format) { 17643 extension = extensions.get('WEBGL_compressed_texture_astc'); 17644 17645 if (extension !== null) { 17646 // TODO Complete? 17647 return p; 17648 } else { 17649 return null; 17650 } 17651 } 17652 17653 if (p === RGBA_BPTC_Format) { 17654 extension = extensions.get('EXT_texture_compression_bptc'); 17655 17656 if (extension !== null) { 17657 // TODO Complete? 17658 return p; 17659 } else { 17660 return null; 17661 } 17662 } 17663 17664 if (p === UnsignedInt248Type) { 17665 if (isWebGL2) return gl.UNSIGNED_INT_24_8; 17666 extension = extensions.get('WEBGL_depth_texture'); 17667 17668 if (extension !== null) { 17669 return extension.UNSIGNED_INT_24_8_WEBGL; 17670 } else { 17671 return null; 17672 } 17673 } 17674 } 17675 17676 return { 17677 convert: convert 17678 }; 17679 } 17680 17681 class ArrayCamera extends PerspectiveCamera { 17682 constructor(array = []) { 17683 super(); 17684 this.cameras = array; 17685 } 17686 17687 } 17688 17689 ArrayCamera.prototype.isArrayCamera = true; 17690 17691 class Group extends Object3D { 17692 constructor() { 17693 super(); 17694 this.type = 'Group'; 17695 } 17696 17697 } 17698 17699 Group.prototype.isGroup = true; 17700 17701 const _moveEvent = { 17702 type: 'move' 17703 }; 17704 17705 class WebXRController { 17706 constructor() { 17707 this._targetRay = null; 17708 this._grip = null; 17709 this._hand = null; 17710 } 17711 17712 getHandSpace() { 17713 if (this._hand === null) { 17714 this._hand = new Group(); 17715 this._hand.matrixAutoUpdate = false;
vendor: 4,806 bytes, lines 17716-17888
17716 this._hand.visible = false; 17717 this._hand.joints = {}; 17718 this._hand.inputState = { 17719 pinching: false 17720 }; 17721 } 17722 17723 return this._hand; 17724 } 17725 17726 getTargetRaySpace() { 17727 if (this._targetRay === null) { 17728 this._targetRay = new Group(); 17729 this._targetRay.matrixAutoUpdate = false; 17730 this._targetRay.visible = false; 17731 this._targetRay.hasLinearVelocity = false; 17732 this._targetRay.linearVelocity = new Vector3(); 17733 this._targetRay.hasAngularVelocity = false; 17734 this._targetRay.angularVelocity = new Vector3(); 17735 } 17736 17737 return this._targetRay; 17738 } 17739 17740 getGripSpace() { 17741 if (this._grip === null) { 17742 this._grip = new Group(); 17743 this._grip.matrixAutoUpdate = false; 17744 this._grip.visible = false; 17745 this._grip.hasLinearVelocity = false; 17746 this._grip.linearVelocity = new Vector3(); 17747 this._grip.hasAngularVelocity = false; 17748 this._grip.angularVelocity = new Vector3(); 17749 } 17750 17751 return this._grip; 17752 } 17753 17754 dispatchEvent(event) { 17755 if (this._targetRay !== null) { 17756 this._targetRay.dispatchEvent(event); 17757 } 17758 17759 if (this._grip !== null) { 17760 this._grip.dispatchEvent(event); 17761 } 17762 17763 if (this._hand !== null) { 17764 this._hand.dispatchEvent(event); 17765 } 17766 17767 return this; 17768 } 17769 17770 disconnect(inputSource) { 17771 this.dispatchEvent({ 17772 type: 'disconnected', 17773 data: inputSource 17774 }); 17775 17776 if (this._targetRay !== null) { 17777 this._targetRay.visible = false; 17778 } 17779 17780 if (this._grip !== null) { 17781 this._grip.visible = false; 17782 } 17783 17784 if (this._hand !== null) { 17785 this._hand.visible = false; 17786 } 17787 17788 return this; 17789 } 17790 17791 update(inputSource, frame, referenceSpace) { 17792 let inputPose = null; 17793 let gripPose = null; 17794 let handPose = null; 17795 const targetRay = this._targetRay; 17796 const grip = this._grip; 17797 const hand = this._hand; 17798 17799 if (inputSource && frame.session.visibilityState !== 'visible-blurred') { 17800 if (targetRay !== null) { 17801 inputPose = frame.getPose(inputSource.targetRaySpace, referenceSpace); 17802 17803 if (inputPose !== null) { 17804 targetRay.matrix.fromArray(inputPose.transform.matrix); 17805 targetRay.matrix.decompose(targetRay.position, targetRay.rotation, targetRay.scale); 17806 17807 if (inputPose.linearVelocity) { 17808 targetRay.hasLinearVelocity = true; 17809 targetRay.linearVelocity.copy(inputPose.linearVelocity); 17810 } else { 17811 targetRay.hasLinearVelocity = false; 17812 } 17813 17814 if (inputPose.angularVelocity) { 17815 targetRay.hasAngularVelocity = true; 17816 targetRay.angularVelocity.copy(inputPose.angularVelocity); 17817 } else { 17818 targetRay.hasAngularVelocity = false; 17819 } 17820 17821 this.dispatchEvent(_moveEvent); 17822 } 17823 } 17824 17825 if (hand && inputSource.hand) { 17826 handPose = true; 17827 17828 for (const inputjoint of inputSource.hand.values()) { 17829 // Update the joints groups with the XRJoint poses 17830 const jointPose = frame.getJointPose(inputjoint, referenceSpace); 17831 17832 if (hand.joints[inputjoint.jointName] === undefined) { 17833 // The transform of this joint will be updated with the joint pose on each frame 17834 const joint = new Group(); 17835 joint.matrixAutoUpdate = false; 17836 joint.visible = false; 17837 hand.joints[inputjoint.jointName] = joint; // ?? 17838 17839 hand.add(joint); 17840 } 17841 17842 const joint = hand.joints[inputjoint.jointName]; 17843 17844 if (jointPose !== null) { 17845 joint.matrix.fromArray(jointPose.transform.matrix); 17846 joint.matrix.decompose(joint.position, joint.rotation, joint.scale); 17847 joint.jointRadius = jointPose.radius; 17848 } 17849 17850 joint.visible = jointPose !== null; 17851 } // Custom events 17852 // Check pinchz 17853 17854 17855 const indexTip = hand.joints['index-finger-tip']; 17856 const thumbTip = hand.joints['thumb-tip']; 17857 const distance = indexTip.position.distanceTo(thumbTip.position); 17858 const distanceToPinch = 0.02; 17859 const threshold = 0.005; 17860 17861 if (hand.inputState.pinching && distance > distanceToPinch + threshold) { 17862 hand.inputState.pinching = false; 17863 this.dispatchEvent({ 17864 type: 'pinchend', 17865 handedness: inputSource.handedness, 17866 target: this 17867 }); 17868 } else if (!hand.inputState.pinching && distance <= distanceToPinch - threshold) { 17869 hand.inputState.pinching = true; 17870 this.dispatchEvent({ 17871 type: 'pinchstart', 17872 handedness: inputSource.handedness, 17873 target: this 17874 }); 17875 } 17876 } else { 17877 if (grip !== null && inputSource.gripSpace) { 17878 gripPose = frame.getPose(inputSource.gripSpace, referenceSpace); 17879 17880 if (gripPose !== null) { 17881 grip.matrix.fromArray(gripPose.transform.matrix); 17882 grip.matrix.decompose(grip.position, grip.rotation, grip.scale); 17883 17884 if (gripPose.linearVelocity) { 17885 grip.hasLinearVelocity = true; 17886 grip.linearVelocity.copy(gripPose.linearVelocity); 17887 } else { 17888 grip.hasLinearVelocity = false;
17889 } 17890 17891 if (gripPose.angularVelocity) { 17892 grip.hasAngularVelocity = true; 17893 grip.angularVelocity.copy(gripPose.angularVelocity); 17894 } else { 17895 grip.hasAngularVelocity = false; 17896 } 17897 } 17898 } 17899 } 17900 } 17901 17902 if (targetRay !== null) { 17903 targetRay.visible = inputPose !== null; 17904 } 17905 17906 if (grip !== null) { 17907 grip.visible = gripPose !== null; 17908 } 17909 17910 if (hand !== null) { 17911 hand.visible = handPose !== null; 17912 } 17913 17914 return this; 17915 } 17916 17917 } 17918 17919 class DepthTexture extends Texture { 17920 constructor(width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format) { 17921 format = format !== undefined ? format : DepthFormat; 17922 17923 if (format !== DepthFormat && format !== DepthStencilFormat) { 17924 throw new Error('DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat'); 17925 } 17926 17927 if (type === undefined && format === DepthFormat) type = UnsignedShortType; 17928 if (type === undefined && format === DepthStencilFormat) type = UnsignedInt248Type; 17929 super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); 17930 this.image = { 17931 width: width, 17932 height: height 17933 }; 17934 this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; 17935 this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; 17936 this.flipY = false; 17937 this.generateMipmaps = false; 17938 } 17939 17940 } 17941 17942 DepthTexture.prototype.isDepthTexture = true; 17943 17944 class WebXRManager extends EventDispatcher { 17945 constructor(renderer, gl) { 17946 super(); 17947 const scope = this; 17948 let session = null; 17949 let framebufferScaleFactor = 1.0; 17950 let referenceSpace = null; 17951 let referenceSpaceType = 'local-floor'; 17952 const hasMultisampledRenderToTexture = renderer.extensions.has('WEBGL_multisampled_render_to_texture'); 17953 let pose = null; 17954 let glBinding = null; 17955 let glProjLayer = null; 17956 let glBaseLayer = null; 17957 let isMultisample = false; 17958 let xrFrame = null; 17959 const attributes = gl.getContextAttributes(); 17960 let initialRenderTarget = null; 17961 let newRenderTarget = null; 17962 const controllers = []; 17963 const inputSourcesMap = new Map(); // 17964 17965 const cameraL = new PerspectiveCamera(); 17966 cameraL.layers.enable(1); 17967 cameraL.viewport = new Vector4(); 17968 const cameraR = new PerspectiveCamera(); 17969 cameraR.layers.enable(2); 17970 cameraR.viewport = new Vector4(); 17971 const cameras = [cameraL, cameraR]; 17972 const cameraVR = new ArrayCamera(); 17973 cameraVR.layers.enable(1); 17974 cameraVR.layers.enable(2); 17975 let _currentDepthNear = null; 17976 let _currentDepthFar = null; // 17977 17978 this.cameraAutoUpdate = true; 17979 this.enabled = false; 17980 this.isPresenting = false; 17981 17982 this.getController = function (index) { 17983 let controller = controllers[index]; 17984 17985 if (controller === undefined) { 17986 controller = new WebXRController(); 17987 controllers[index] = controller; 17988 } 17989 17990 return controller.getTargetRaySpace(); 17991 }; 17992 17993 this.getControllerGrip = function (index) { 17994 let controller = controllers[index]; 17995 17996 if (controller === undefined) { 17997 controller = new WebXRController(); 17998 controllers[index] = controller; 17999 } 18000 18001 return controller.getGripSpace(); 18002 }; 18003 18004 this.getHand = function (index) { 18005 let controller = controllers[index]; 18006 18007 if (controller === undefined) { 18008 controller = new WebXRController(); 18009 controllers[index] = controller; 18010 } 18011 18012 return controller.getHandSpace(); 18013 }; // 18014 18015 18016 function onSessionEvent(event) { 18017 const controller = inputSourcesMap.get(event.inputSource); 18018 18019 if (controller) { 18020 controller.dispatchEvent({ 18021 type: event.type, 18022 data: event.inputSource 18023 }); 18024 } 18025 } 18026 18027 function onSessionEnd() { 18028 inputSourcesMap.forEach(function (controller, inputSource) { 18029 controller.disconnect(inputSource); 18030 }); 18031 inputSourcesMap.clear(); 18032 _currentDepthNear = null; 18033 _currentDepthFar = null; // restore framebuffer/rendering state 18034 18035 renderer.setRenderTarget(initialRenderTarget); 18036 glBaseLayer = null; 18037 glProjLayer = null; 18038 glBinding = null; 18039 session = null; 18040 newRenderTarget = null; // 18041 18042 animation.stop(); 18043 scope.isPresenting = false;
18044 scope.dispatchEvent({ 18045 type: 'sessionend' 18046 }); 18047 } 18048 18049 this.setFramebufferScaleFactor = function (value) { 18050 framebufferScaleFactor = value; 18051 18052 if (scope.isPresenting === true) { 18053 console.warn('THREE.WebXRManager: Cannot change framebuffer scale while presenting.'); 18054 } 18055 }; 18056 18057 this.setReferenceSpaceType = function (value) { 18058 referenceSpaceType = value; 18059 18060 if (scope.isPresenting === true) { 18061 console.warn('THREE.WebXRManager: Cannot change reference space type while presenting.'); 18062 } 18063 }; 18064 18065 this.getReferenceSpace = function () { 18066 return referenceSpace; 18067 }; 18068 18069 this.getBaseLayer = function () { 18070 return glProjLayer !== null ? glProjLayer : glBaseLayer; 18071 }; 18072 18073 this.getBinding = function () { 18074 return glBinding; 18075 }; 18076 18077 this.getFrame = function () { 18078 return xrFrame; 18079 }; 18080 18081 this.getSession = function () { 18082 return session; 18083 }; 18084 18085 this.setSession = async function (value) { 18086 session = value; 18087 18088 if (session !== null) { 18089 initialRenderTarget = renderer.getRenderTarget(); 18090 session.addEventListener('select', onSessionEvent); 18091 session.addEventListener('selectstart', onSessionEvent); 18092 session.addEventListener('selectend', onSessionEvent); 18093 session.addEventListener('squeeze', onSessionEvent); 18094 session.addEventListener('squeezestart', onSessionEvent); 18095 session.addEventListener('squeezeend', onSessionEvent); 18096 session.addEventListener('end', onSessionEnd); 18097 session.addEventListener('inputsourceschange', onInputSourcesChange); 18098 18099 if (attributes.xrCompatible !== true) { 18100 await gl.makeXRCompatible(); 18101 } 18102 18103 if (session.renderState.layers === undefined || renderer.capabilities.isWebGL2 === false) { 18104 const layerInit = { 18105 antialias: session.renderState.layers === undefined ? attributes.antialias : true, 18106 alpha: attributes.alpha, 18107 depth: attributes.depth, 18108 stencil: attributes.stencil, 18109 framebufferScaleFactor: framebufferScaleFactor 18110 }; 18111 glBaseLayer = new XRWebGLLayer(session, gl, layerInit); 18112 session.updateRenderState({ 18113 baseLayer: glBaseLayer 18114 }); 18115 newRenderTarget = new WebGLRenderTarget(glBaseLayer.framebufferWidth, glBaseLayer.framebufferHeight, { 18116 format: RGBAFormat, 18117 type: UnsignedByteType, 18118 encoding: renderer.outputEncoding 18119 }); 18120 } else { 18121 isMultisample = attributes.antialias; 18122 let depthFormat = null; 18123 let depthType = null; 18124 let glDepthFormat = null; 18125 18126 if (attributes.depth) { 18127 glDepthFormat = attributes.stencil ? gl.DEPTH24_STENCIL8 : gl.DEPTH_COMPONENT24; 18128 depthFormat = attributes.stencil ? DepthStencilFormat : DepthFormat; 18129 depthType = attributes.stencil ? UnsignedInt248Type : UnsignedShortType; 18130 } 18131 18132 const projectionlayerInit = { 18133 colorFormat: attributes.alpha || isMultisample ? gl.RGBA8 : gl.RGB8, 18134 depthFormat: glDepthFormat, 18135 scaleFactor: framebufferScaleFactor 18136 }; 18137 glBinding = new XRWebGLBinding(session, gl); 18138 glProjLayer = glBinding.createProjectionLayer(projectionlayerInit); 18139 session.updateRenderState({ 18140 layers: [glProjLayer] 18141 }); 18142 18143 if (isMultisample) { 18144 newRenderTarget = new WebGLMultisampleRenderTarget(glProjLayer.textureWidth, glProjLayer.textureHeight, { 18145 format: RGBAFormat, 18146 type: UnsignedByteType, 18147 depthTexture: new DepthTexture(glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat), 18148 stencilBuffer: attributes.stencil, 18149 ignoreDepth: glProjLayer.ignoreDepthValues, 18150 useRenderToTexture: hasMultisampledRenderToTexture, 18151 encoding: renderer.outputEncoding 18152 }); 18153 } else { 18154 newRenderTarget = new WebGLRenderTarget(glProjLayer.textureWidth, glProjLayer.textureHeight, { 18155 format: attributes.alpha ? RGBAFormat : RGBFormat, 18156 type: UnsignedByteType, 18157 depthTexture: new DepthTexture(glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat), 18158 stencilBuffer: attributes.stencil, 18159 ignoreDepth: glProjLayer.ignoreDepthValues, 18160 encoding: renderer.outputEncoding 18161 }); 18162 } 18163 } // Set foveation to maximum. 18164 18165 18166 this.setFoveation(1.0); 18167 referenceSpace = await session.requestReferenceSpace(referenceSpaceType); 18168 animation.setContext(session); 18169 animation.start(); 18170 scope.isPresenting = true; 18171 scope.dispatchEvent({ 18172 type: 'sessionstart' 18173 }); 18174 } 18175 }; 18176 18177 function onInputSourcesChange(event) { 18178 const inputSources = session.inputSources; // Assign inputSources to available controllers 18179 18180 for (let i = 0; i < controllers.length; i++) { 18181 inputSourcesMap.set(inputSources[i], controllers[i]); 18182 } // Notify disconnected 18183 18184 18185 for (let i = 0; i < event.removed.length; i++) { 18186 const inputSource = event.removed[i]; 18187 const controller = inputSourcesMap.get(inputSource); 18188 18189 if (controller) { 18190 controller.dispatchEvent({ 18191 type: 'disconnected', 18192 data: inputSource 18193 }); 18194 inputSourcesMap.delete(inputSource); 18195 } 18196 } // Notify connected 18197 18198 18199 for (let i = 0; i < event.added.length; i++) { 18200 const inputSource = event.added[i]; 18201 const controller = inputSourcesMap.get(inputSource); 18202 18203 if (controller) { 18204 controller.dispatchEvent({ 18205 type: 'connected', 18206 data: inputSource 18207 }); 18208 } 18209 } 18210 } // 18211 18212 18213 const cameraLPos = new Vector3(); 18214 const cameraRPos = new Vector3(); 18215 /** 18216 * Assumes 2 cameras that are parallel and share an X-axis, and that 18217 * the cameras' projection and world matrices have already been set. 18218 * And that near and far planes are identical for both cameras. 18219 * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765 18220 */ 18221 18222 function setProjectionFromUnion(camera, cameraL, cameraR) { 18223 cameraLPos.setFromMatrixPosition(cameraL.matrixWorld); 18224 cameraRPos.setFromMatrixPosition(cameraR.matrixWorld); 18225 const ipd = cameraLPos.distanceTo(cameraRPos); 18226 const projL = cameraL.projectionMatrix.elements; 18227 const projR = cameraR.projectionMatrix.elements; // VR systems will have identical far and near planes, and 18228 // most likely identical top and bottom frustum extents. 18229 // Use the left camera for these values. 18230 18231 const near = projL[14] / (projL[10] - 1); 18232 const far = projL[14] / (projL[10] + 1);
18233 const topFov = (projL[9] + 1) / projL[5]; 18234 const bottomFov = (projL[9] - 1) / projL[5]; 18235 const leftFov = (projL[8] - 1) / projL[0]; 18236 const rightFov = (projR[8] + 1) / projR[0]; 18237 const left = near * leftFov; 18238 const right = near * rightFov; // Calculate the new camera's position offset from the 18239 // left camera. xOffset should be roughly half `ipd`. 18240 18241 const zOffset = ipd / (-leftFov + rightFov); 18242 const xOffset = zOffset * -leftFov; // TODO: Better way to apply this offset? 18243 18244 cameraL.matrixWorld.decompose(camera.position, camera.quaternion, camera.scale); 18245 camera.translateX(xOffset); 18246 camera.translateZ(zOffset); 18247 camera.matrixWorld.compose(camera.position, camera.quaternion, camera.scale); 18248 camera.matrixWorldInverse.copy(camera.matrixWorld).invert(); // Find the union of the frustum values of the cameras and scale 18249 // the values so that the near plane's position does not change in world space, 18250 // although must now be relative to the new union camera. 18251 18252 const near2 = near + zOffset; 18253 const far2 = far + zOffset; 18254 const left2 = left - xOffset; 18255 const right2 = right + (ipd - xOffset); 18256 const top2 = topFov * far / far2 * near2; 18257 const bottom2 = bottomFov * far / far2 * near2; 18258 camera.projectionMatrix.makePerspective(left2, right2, top2, bottom2, near2, far2); 18259 } 18260 18261 function updateCamera(camera, parent) { 18262 if (parent === null) { 18263 camera.matrixWorld.copy(camera.matrix); 18264 } else { 18265 camera.matrixWorld.multiplyMatrices(parent.matrixWorld, camera.matrix); 18266 } 18267 18268 camera.matrixWorldInverse.copy(camera.matrixWorld).invert(); 18269 } 18270 18271 this.updateCamera = function (camera) { 18272 if (session === null) return; 18273 cameraVR.near = cameraR.near = cameraL.near = camera.near; 18274 cameraVR.far = cameraR.far = cameraL.far = camera.far; 18275 18276 if (_currentDepthNear !== cameraVR.near || _currentDepthFar !== cameraVR.far) { 18277 // Note that the new renderState won't apply until the next frame. See #18320 18278 session.updateRenderState({ 18279 depthNear: cameraVR.near, 18280 depthFar: cameraVR.far 18281 }); 18282 _currentDepthNear = cameraVR.near; 18283 _currentDepthFar = cameraVR.far; 18284 } 18285 18286 const parent = camera.parent; 18287 const cameras = cameraVR.cameras; 18288 updateCamera(cameraVR, parent); 18289 18290 for (let i = 0; i < cameras.length; i++) { 18291 updateCamera(cameras[i], parent); 18292 } 18293 18294 cameraVR.matrixWorld.decompose(cameraVR.position, cameraVR.quaternion, cameraVR.scale); // update user camera and its children 18295 18296 camera.position.copy(cameraVR.position); 18297 camera.quaternion.copy(cameraVR.quaternion); 18298 camera.scale.copy(cameraVR.scale); 18299 camera.matrix.copy(cameraVR.matrix); 18300 camera.matrixWorld.copy(cameraVR.matrixWorld); 18301 const children = camera.children; 18302 18303 for (let i = 0, l = children.length; i < l; i++) { 18304 children[i].updateMatrixWorld(true); 18305 } // update projection matrix for proper view frustum culling 18306 18307 18308 if (cameras.length === 2) { 18309 setProjectionFromUnion(cameraVR, cameraL, cameraR); 18310 } else { 18311 // assume single camera setup (AR) 18312 cameraVR.projectionMatrix.copy(cameraL.projectionMatrix); 18313 } 18314 }; 18315 18316 this.getCamera = function () { 18317 return cameraVR; 18318 }; 18319 18320 this.getFoveation = function () { 18321 if (glProjLayer !== null) { 18322 return glProjLayer.fixedFoveation; 18323 } 18324 18325 if (glBaseLayer !== null) { 18326 return glBaseLayer.fixedFoveation; 18327 } 18328 18329 return undefined; 18330 }; 18331 18332 this.setFoveation = function (foveation) { 18333 // 0 = no foveation = full resolution 18334 // 1 = maximum foveation = the edges render at lower resolution 18335 if (glProjLayer !== null) { 18336 glProjLayer.fixedFoveation = foveation; 18337 } 18338 18339 if (glBaseLayer !== null && glBaseLayer.fixedFoveation !== undefined) { 18340 glBaseLayer.fixedFoveation = foveation; 18341 } 18342 }; // Animation Loop 18343 18344 18345 let onAnimationFrameCallback = null; 18346 18347 function onAnimationFrame(time, frame) { 18348 pose = frame.getViewerPose(referenceSpace); 18349 xrFrame = frame; 18350 18351 if (pose !== null) { 18352 const views = pose.views; 18353 18354 if (glBaseLayer !== null) { 18355 renderer.setRenderTargetFramebuffer(newRenderTarget, glBaseLayer.framebuffer); 18356 renderer.setRenderTarget(newRenderTarget); 18357 } 18358
vendor: 16,384 bytes, lines 18359-18892
18359 let cameraVRNeedsUpdate = false; // check if it's necessary to rebuild cameraVR's camera list 18360 18361 if (views.length !== cameraVR.cameras.length) { 18362 cameraVR.cameras.length = 0; 18363 cameraVRNeedsUpdate = true; 18364 } 18365 18366 for (let i = 0; i < views.length; i++) { 18367 const view = views[i]; 18368 let viewport = null; 18369 18370 if (glBaseLayer !== null) { 18371 viewport = glBaseLayer.getViewport(view); 18372 } else { 18373 const glSubImage = glBinding.getViewSubImage(glProjLayer, view); 18374 viewport = glSubImage.viewport; // For side-by-side projection, we only produce a single texture for both eyes. 18375 18376 if (i === 0) { 18377 renderer.setRenderTargetTextures(newRenderTarget, glSubImage.colorTexture, glProjLayer.ignoreDepthValues ? undefined : glSubImage.depthStencilTexture); 18378 renderer.setRenderTarget(newRenderTarget); 18379 } 18380 } 18381 18382 const camera = cameras[i]; 18383 camera.matrix.fromArray(view.transform.matrix); 18384 camera.projectionMatrix.fromArray(view.projectionMatrix); 18385 camera.viewport.set(viewport.x, viewport.y, viewport.width, viewport.height); 18386 18387 if (i === 0) { 18388 cameraVR.matrix.copy(camera.matrix); 18389 } 18390 18391 if (cameraVRNeedsUpdate === true) { 18392 cameraVR.cameras.push(camera); 18393 } 18394 } 18395 } // 18396 18397 18398 const inputSources = session.inputSources; 18399 18400 for (let i = 0; i < controllers.length; i++) { 18401 const controller = controllers[i]; 18402 const inputSource = inputSources[i]; 18403 controller.update(inputSource, frame, referenceSpace); 18404 } 18405 18406 if (onAnimationFrameCallback) onAnimationFrameCallback(time, frame); 18407 xrFrame = null; 18408 } 18409 18410 const animation = new WebGLAnimation(); 18411 animation.setAnimationLoop(onAnimationFrame); 18412 18413 this.setAnimationLoop = function (callback) { 18414 onAnimationFrameCallback = callback; 18415 }; 18416 18417 this.dispose = function () {}; 18418 } 18419 18420 } 18421 18422 function WebGLMaterials(properties) { 18423 function refreshFogUniforms(uniforms, fog) { 18424 uniforms.fogColor.value.copy(fog.color); 18425 18426 if (fog.isFog) { 18427 uniforms.fogNear.value = fog.near; 18428 uniforms.fogFar.value = fog.far; 18429 } else if (fog.isFogExp2) { 18430 uniforms.fogDensity.value = fog.density; 18431 } 18432 } 18433 18434 function refreshMaterialUniforms(uniforms, material, pixelRatio, height, transmissionRenderTarget) { 18435 if (material.isMeshBasicMaterial) { 18436 refreshUniformsCommon(uniforms, material); 18437 } else if (material.isMeshLambertMaterial) { 18438 refreshUniformsCommon(uniforms, material); 18439 refreshUniformsLambert(uniforms, material); 18440 } else if (material.isMeshToonMaterial) { 18441 refreshUniformsCommon(uniforms, material); 18442 refreshUniformsToon(uniforms, material); 18443 } else if (material.isMeshPhongMaterial) { 18444 refreshUniformsCommon(uniforms, material); 18445 refreshUniformsPhong(uniforms, material); 18446 } else if (material.isMeshStandardMaterial) { 18447 refreshUniformsCommon(uniforms, material); 18448 18449 if (material.isMeshPhysicalMaterial) { 18450 refreshUniformsPhysical(uniforms, material, transmissionRenderTarget); 18451 } else { 18452 refreshUniformsStandard(uniforms, material); 18453 } 18454 } else if (material.isMeshMatcapMaterial) { 18455 refreshUniformsCommon(uniforms, material); 18456 refreshUniformsMatcap(uniforms, material); 18457 } else if (material.isMeshDepthMaterial) { 18458 refreshUniformsCommon(uniforms, material); 18459 refreshUniformsDepth(uniforms, material); 18460 } else if (material.isMeshDistanceMaterial) { 18461 refreshUniformsCommon(uniforms, material); 18462 refreshUniformsDistance(uniforms, material); 18463 } else if (material.isMeshNormalMaterial) { 18464 refreshUniformsCommon(uniforms, material); 18465 refreshUniformsNormal(uniforms, material); 18466 } else if (material.isLineBasicMaterial) { 18467 refreshUniformsLine(uniforms, material); 18468 18469 if (material.isLineDashedMaterial) { 18470 refreshUniformsDash(uniforms, material); 18471 } 18472 } else if (material.isPointsMaterial) { 18473 refreshUniformsPoints(uniforms, material, pixelRatio, height); 18474 } else if (material.isSpriteMaterial) { 18475 refreshUniformsSprites(uniforms, material); 18476 } else if (material.isShadowMaterial) { 18477 uniforms.color.value.copy(material.color); 18478 uniforms.opacity.value = material.opacity; 18479 } else if (material.isShaderMaterial) { 18480 material.uniformsNeedUpdate = false; // #15581 18481 } 18482 } 18483 18484 function refreshUniformsCommon(uniforms, material) { 18485 uniforms.opacity.value = material.opacity; 18486 18487 if (material.color) { 18488 uniforms.diffuse.value.copy(material.color); 18489 } 18490 18491 if (material.emissive) { 18492 uniforms.emissive.value.copy(material.emissive).multiplyScalar(material.emissiveIntensity); 18493 } 18494 18495 if (material.map) { 18496 uniforms.map.value = material.map; 18497 } 18498 18499 if (material.alphaMap) { 18500 uniforms.alphaMap.value = material.alphaMap; 18501 } 18502 18503 if (material.specularMap) { 18504 uniforms.specularMap.value = material.specularMap; 18505 } 18506 18507 if (material.alphaTest > 0) { 18508 uniforms.alphaTest.value = material.alphaTest; 18509 } 18510 18511 const envMap = properties.get(material).envMap; 18512 18513 if (envMap) { 18514 uniforms.envMap.value = envMap; 18515 uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap.isRenderTargetTexture === false ? -1 : 1; 18516 uniforms.reflectivity.value = material.reflectivity; 18517 uniforms.ior.value = material.ior; 18518 uniforms.refractionRatio.value = material.refractionRatio; 18519 } 18520 18521 if (material.lightMap) { 18522 uniforms.lightMap.value = material.lightMap; 18523 uniforms.lightMapIntensity.value = material.lightMapIntensity; 18524 } 18525 18526 if (material.aoMap) { 18527 uniforms.aoMap.value = material.aoMap; 18528 uniforms.aoMapIntensity.value = material.aoMapIntensity; 18529 } // uv repeat and offset setting priorities 18530 // 1. color map 18531 // 2. specular map 18532 // 3. displacementMap map 18533 // 4. normal map 18534 // 5. bump map 18535 // 6. roughnessMap map 18536 // 7. metalnessMap map 18537 // 8. alphaMap map 18538 // 9. emissiveMap map 18539 // 10. clearcoat map 18540 // 11. clearcoat normal map 18541 // 12. clearcoat roughnessMap map 18542 // 13. specular intensity map 18543 // 14. specular tint map 18544 // 15. transmission map 18545 // 16. thickness map 18546 18547 18548 let uvScaleMap; 18549 18550 if (material.map) { 18551 uvScaleMap = material.map; 18552 } else if (material.specularMap) { 18553 uvScaleMap = material.specularMap; 18554 } else if (material.displacementMap) { 18555 uvScaleMap = material.displacementMap; 18556 } else if (material.normalMap) { 18557 uvScaleMap = material.normalMap; 18558 } else if (material.bumpMap) { 18559 uvScaleMap = material.bumpMap; 18560 } else if (material.roughnessMap) { 18561 uvScaleMap = material.roughnessMap; 18562 } else if (material.metalnessMap) { 18563 uvScaleMap = material.metalnessMap; 18564 } else if (material.alphaMap) { 18565 uvScaleMap = material.alphaMap; 18566 } else if (material.emissiveMap) { 18567 uvScaleMap = material.emissiveMap; 18568 } else if (material.clearcoatMap) { 18569 uvScaleMap = material.clearcoatMap; 18570 } else if (material.clearcoatNormalMap) { 18571 uvScaleMap = material.clearcoatNormalMap; 18572 } else if (material.clearcoatRoughnessMap) { 18573 uvScaleMap = material.clearcoatRoughnessMap; 18574 } else if (material.specularIntensityMap) { 18575 uvScaleMap = material.specularIntensityMap; 18576 } else if (material.specularColorMap) { 18577 uvScaleMap = material.specularColorMap; 18578 } else if (material.transmissionMap) { 18579 uvScaleMap = material.transmissionMap; 18580 } else if (material.thicknessMap) { 18581 uvScaleMap = material.thicknessMap; 18582 } else if (material.sheenColorMap) { 18583 uvScaleMap = material.sheenColorMap; 18584 } else if (material.sheenRoughnessMap) { 18585 uvScaleMap = material.sheenRoughnessMap; 18586 } 18587 18588 if (uvScaleMap !== undefined) { 18589 // backwards compatibility 18590 if (uvScaleMap.isWebGLRenderTarget) { 18591 uvScaleMap = uvScaleMap.texture; 18592 } 18593 18594 if (uvScaleMap.matrixAutoUpdate === true) { 18595 uvScaleMap.updateMatrix(); 18596 } 18597 18598 uniforms.uvTransform.value.copy(uvScaleMap.matrix); 18599 } // uv repeat and offset setting priorities for uv2 18600 // 1. ao map 18601 // 2. light map 18602 18603 18604 let uv2ScaleMap; 18605 18606 if (material.aoMap) { 18607 uv2ScaleMap = material.aoMap; 18608 } else if (material.lightMap) { 18609 uv2ScaleMap = material.lightMap; 18610 } 18611 18612 if (uv2ScaleMap !== undefined) { 18613 // backwards compatibility 18614 if (uv2ScaleMap.isWebGLRenderTarget) { 18615 uv2ScaleMap = uv2ScaleMap.texture; 18616 } 18617 18618 if (uv2ScaleMap.matrixAutoUpdate === true) { 18619 uv2ScaleMap.updateMatrix(); 18620 } 18621 18622 uniforms.uv2Transform.value.copy(uv2ScaleMap.matrix); 18623 } 18624 } 18625 18626 function refreshUniformsLine(uniforms, material) { 18627 uniforms.diffuse.value.copy(material.color); 18628 uniforms.opacity.value = material.opacity; 18629 } 18630 18631 function refreshUniformsDash(uniforms, material) { 18632 uniforms.dashSize.value = material.dashSize; 18633 uniforms.totalSize.value = material.dashSize + material.gapSize; 18634 uniforms.scale.value = material.scale; 18635 } 18636 18637 function refreshUniformsPoints(uniforms, material, pixelRatio, height) { 18638 uniforms.diffuse.value.copy(material.color); 18639 uniforms.opacity.value = material.opacity; 18640 uniforms.size.value = material.size * pixelRatio; 18641 uniforms.scale.value = height * 0.5; 18642 18643 if (material.map) { 18644 uniforms.map.value = material.map; 18645 } 18646 18647 if (material.alphaMap) { 18648 uniforms.alphaMap.value = material.alphaMap; 18649 } 18650 18651 if (material.alphaTest > 0) { 18652 uniforms.alphaTest.value = material.alphaTest; 18653 } // uv repeat and offset setting priorities 18654 // 1. color map 18655 // 2. alpha map 18656 18657 18658 let uvScaleMap; 18659 18660 if (material.map) { 18661 uvScaleMap = material.map; 18662 } else if (material.alphaMap) { 18663 uvScaleMap = material.alphaMap; 18664 } 18665 18666 if (uvScaleMap !== undefined) { 18667 if (uvScaleMap.matrixAutoUpdate === true) { 18668 uvScaleMap.updateMatrix(); 18669 } 18670 18671 uniforms.uvTransform.value.copy(uvScaleMap.matrix); 18672 } 18673 } 18674 18675 function refreshUniformsSprites(uniforms, material) { 18676 uniforms.diffuse.value.copy(material.color); 18677 uniforms.opacity.value = material.opacity; 18678 uniforms.rotation.value = material.rotation; 18679 18680 if (material.map) { 18681 uniforms.map.value = material.map; 18682 } 18683 18684 if (material.alphaMap) { 18685 uniforms.alphaMap.value = material.alphaMap; 18686 } 18687 18688 if (material.alphaTest > 0) { 18689 uniforms.alphaTest.value = material.alphaTest; 18690 } // uv repeat and offset setting priorities 18691 // 1. color map 18692 // 2. alpha map 18693 18694 18695 let uvScaleMap; 18696 18697 if (material.map) { 18698 uvScaleMap = material.map; 18699 } else if (material.alphaMap) { 18700 uvScaleMap = material.alphaMap; 18701 } 18702 18703 if (uvScaleMap !== undefined) { 18704 if (uvScaleMap.matrixAutoUpdate === true) { 18705 uvScaleMap.updateMatrix(); 18706 } 18707 18708 uniforms.uvTransform.value.copy(uvScaleMap.matrix); 18709 } 18710 } 18711 18712 function refreshUniformsLambert(uniforms, material) { 18713 if (material.emissiveMap) { 18714 uniforms.emissiveMap.value = material.emissiveMap; 18715 } 18716 } 18717 18718 function refreshUniformsPhong(uniforms, material) { 18719 uniforms.specular.value.copy(material.specular); 18720 uniforms.shininess.value = Math.max(material.shininess, 1e-4); // to prevent pow( 0.0, 0.0 ) 18721 18722 if (material.emissiveMap) { 18723 uniforms.emissiveMap.value = material.emissiveMap; 18724 } 18725 18726 if (material.bumpMap) { 18727 uniforms.bumpMap.value = material.bumpMap; 18728 uniforms.bumpScale.value = material.bumpScale; 18729 if (material.side === BackSide) uniforms.bumpScale.value *= -1; 18730 } 18731 18732 if (material.normalMap) { 18733 uniforms.normalMap.value = material.normalMap; 18734 uniforms.normalScale.value.copy(material.normalScale); 18735 if (material.side === BackSide) uniforms.normalScale.value.negate(); 18736 } 18737 18738 if (material.displacementMap) { 18739 uniforms.displacementMap.value = material.displacementMap; 18740 uniforms.displacementScale.value = material.displacementScale; 18741 uniforms.displacementBias.value = material.displacementBias; 18742 } 18743 } 18744 18745 function refreshUniformsToon(uniforms, material) { 18746 if (material.gradientMap) { 18747 uniforms.gradientMap.value = material.gradientMap; 18748 } 18749 18750 if (material.emissiveMap) { 18751 uniforms.emissiveMap.value = material.emissiveMap; 18752 } 18753 18754 if (material.bumpMap) { 18755 uniforms.bumpMap.value = material.bumpMap; 18756 uniforms.bumpScale.value = material.bumpScale; 18757 if (material.side === BackSide) uniforms.bumpScale.value *= -1; 18758 } 18759 18760 if (material.normalMap) { 18761 uniforms.normalMap.value = material.normalMap; 18762 uniforms.normalScale.value.copy(material.normalScale); 18763 if (material.side === BackSide) uniforms.normalScale.value.negate(); 18764 } 18765 18766 if (material.displacementMap) { 18767 uniforms.displacementMap.value = material.displacementMap; 18768 uniforms.displacementScale.value = material.displacementScale; 18769 uniforms.displacementBias.value = material.displacementBias; 18770 } 18771 } 18772 18773 function refreshUniformsStandard(uniforms, material) { 18774 uniforms.roughness.value = material.roughness; 18775 uniforms.metalness.value = material.metalness; 18776 18777 if (material.roughnessMap) { 18778 uniforms.roughnessMap.value = material.roughnessMap; 18779 } 18780 18781 if (material.metalnessMap) { 18782 uniforms.metalnessMap.value = material.metalnessMap; 18783 } 18784 18785 if (material.emissiveMap) { 18786 uniforms.emissiveMap.value = material.emissiveMap; 18787 } 18788 18789 if (material.bumpMap) { 18790 uniforms.bumpMap.value = material.bumpMap; 18791 uniforms.bumpScale.value = material.bumpScale; 18792 if (material.side === BackSide) uniforms.bumpScale.value *= -1; 18793 } 18794 18795 if (material.normalMap) { 18796 uniforms.normalMap.value = material.normalMap; 18797 uniforms.normalScale.value.copy(material.normalScale); 18798 if (material.side === BackSide) uniforms.normalScale.value.negate(); 18799 } 18800 18801 if (material.displacementMap) { 18802 uniforms.displacementMap.value = material.displacementMap; 18803 uniforms.displacementScale.value = material.displacementScale; 18804 uniforms.displacementBias.value = material.displacementBias; 18805 } 18806 18807 const envMap = properties.get(material).envMap; 18808 18809 if (envMap) { 18810 //uniforms.envMap.value = material.envMap; // part of uniforms common 18811 uniforms.envMapIntensity.value = material.envMapIntensity; 18812 } 18813 } 18814 18815 function refreshUniformsPhysical(uniforms, material, transmissionRenderTarget) { 18816 refreshUniformsStandard(uniforms, material); 18817 uniforms.ior.value = material.ior; // also part of uniforms common 18818 18819 if (material.sheen > 0) { 18820 uniforms.sheenColor.value.copy(material.sheenColor).multiplyScalar(material.sheen); 18821 uniforms.sheenRoughness.value = material.sheenRoughness; 18822 18823 if (material.sheenColorMap) { 18824 uniforms.sheenColorMap.value = material.sheenColorMap; 18825 } 18826 18827 if (material.sheenRoughnessMap) { 18828 uniforms.sheenRoughnessMap.value = material.sheenRoughnessMap; 18829 } 18830 } 18831 18832 if (material.clearcoat > 0) { 18833 uniforms.clearcoat.value = material.clearcoat; 18834 uniforms.clearcoatRoughness.value = material.clearcoatRoughness; 18835 18836 if (material.clearcoatMap) { 18837 uniforms.clearcoatMap.value = material.clearcoatMap; 18838 } 18839 18840 if (material.clearcoatRoughnessMap) { 18841 uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap; 18842 } 18843 18844 if (material.clearcoatNormalMap) { 18845 uniforms.clearcoatNormalScale.value.copy(material.clearcoatNormalScale); 18846 uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap; 18847 18848 if (material.side === BackSide) { 18849 uniforms.clearcoatNormalScale.value.negate(); 18850 } 18851 } 18852 } 18853 18854 if (material.transmission > 0) { 18855 uniforms.transmission.value = material.transmission; 18856 uniforms.transmissionSamplerMap.value = transmissionRenderTarget.texture; 18857 uniforms.transmissionSamplerSize.value.set(transmissionRenderTarget.width, transmissionRenderTarget.height); 18858 18859 if (material.transmissionMap) { 18860 uniforms.transmissionMap.value = material.transmissionMap; 18861 } 18862 18863 uniforms.thickness.value = material.thickness; 18864 18865 if (material.thicknessMap) { 18866 uniforms.thicknessMap.value = material.thicknessMap; 18867 } 18868 18869 uniforms.attenuationDistance.value = material.attenuationDistance; 18870 uniforms.attenuationColor.value.copy(material.attenuationColor); 18871 } 18872 18873 uniforms.specularIntensity.value = material.specularIntensity; 18874 uniforms.specularColor.value.copy(material.specularColor); 18875 18876 if (material.specularIntensityMap) { 18877 uniforms.specularIntensityMap.value = material.specularIntensityMap; 18878 } 18879 18880 if (material.specularColorMap) { 18881 uniforms.specularColorMap.value = material.specularColorMap; 18882 } 18883 } 18884 18885 function refreshUniformsMatcap(uniforms, material) { 18886 if (material.matcap) { 18887 uniforms.matcap.value = material.matcap; 18888 } 18889 18890 if (material.bumpMap) { 18891 uniforms.bumpMap.value = material.bumpMap; 18892 uniforms.bumpScale.value = m
vendor: 10,377 bytes, lines 18892-19203
18892aterial.bumpScale; 18893 if (material.side === BackSide) uniforms.bumpScale.value *= -1; 18894 } 18895 18896 if (material.normalMap) { 18897 uniforms.normalMap.value = material.normalMap; 18898 uniforms.normalScale.value.copy(material.normalScale); 18899 if (material.side === BackSide) uniforms.normalScale.value.negate(); 18900 } 18901 18902 if (material.displacementMap) { 18903 uniforms.displacementMap.value = material.displacementMap; 18904 uniforms.displacementScale.value = material.displacementScale; 18905 uniforms.displacementBias.value = material.displacementBias; 18906 } 18907 } 18908 18909 function refreshUniformsDepth(uniforms, material) { 18910 if (material.displacementMap) { 18911 uniforms.displacementMap.value = material.displacementMap; 18912 uniforms.displacementScale.value = material.displacementScale; 18913 uniforms.displacementBias.value = material.displacementBias; 18914 } 18915 } 18916 18917 function refreshUniformsDistance(uniforms, material) { 18918 if (material.displacementMap) { 18919 uniforms.displacementMap.value = material.displacementMap; 18920 uniforms.displacementScale.value = material.displacementScale; 18921 uniforms.displacementBias.value = material.displacementBias; 18922 } 18923 18924 uniforms.referencePosition.value.copy(material.referencePosition); 18925 uniforms.nearDistance.value = material.nearDistance; 18926 uniforms.farDistance.value = material.farDistance; 18927 } 18928 18929 function refreshUniformsNormal(uniforms, material) { 18930 if (material.bumpMap) { 18931 uniforms.bumpMap.value = material.bumpMap; 18932 uniforms.bumpScale.value = material.bumpScale; 18933 if (material.side === BackSide) uniforms.bumpScale.value *= -1; 18934 } 18935 18936 if (material.normalMap) { 18937 uniforms.normalMap.value = material.normalMap; 18938 uniforms.normalScale.value.copy(material.normalScale); 18939 if (material.side === BackSide) uniforms.normalScale.value.negate(); 18940 } 18941 18942 if (material.displacementMap) { 18943 uniforms.displacementMap.value = material.displacementMap; 18944 uniforms.displacementScale.value = material.displacementScale; 18945 uniforms.displacementBias.value = material.displacementBias; 18946 } 18947 } 18948 18949 return { 18950 refreshFogUniforms: refreshFogUniforms, 18951 refreshMaterialUniforms: refreshMaterialUniforms 18952 }; 18953 } 18954 18955 function createCanvasElement() { 18956 const canvas = createElementNS('canvas'); 18957 canvas.style.display = 'block'; 18958 return canvas; 18959 } 18960 18961 function WebGLRenderer(parameters = {}) { 18962 const _canvas = parameters.canvas !== undefined ? parameters.canvas : createCanvasElement(), 18963 _context = parameters.context !== undefined ? parameters.context : null, 18964 _alpha = parameters.alpha !== undefined ? parameters.alpha : false, 18965 _depth = parameters.depth !== undefined ? parameters.depth : true, 18966 _stencil = parameters.stencil !== undefined ? parameters.stencil : true, 18967 _antialias = parameters.antialias !== undefined ? parameters.antialias : false, 18968 _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true, 18969 _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false, 18970 _powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default', 18971 _failIfMajorPerformanceCaveat = parameters.failIfMajorPerformanceCaveat !== undefined ? parameters.failIfMajorPerformanceCaveat : false; 18972 18973 let currentRenderList = null; 18974 let currentRenderState = null; // render() can be called from within a callback triggered by another render. 18975 // We track this so that the nested render call gets its list and state isolated from the parent render call. 18976 18977 const renderListStack = []; 18978 const renderStateStack = []; // public properties 18979 18980 this.domElement = _canvas; // Debug configuration container 18981 18982 this.debug = { 18983 /** 18984 * Enables error checking and reporting when shader programs are being compiled 18985 * @type {boolean} 18986 */ 18987 checkShaderErrors: true 18988 }; // clearing 18989 18990 this.autoClear = true; 18991 this.autoClearColor = true; 18992 this.autoClearDepth = true; 18993 this.autoClearStencil = true; // scene graph 18994 18995 this.sortObjects = true; // user-defined clipping 18996 18997 this.clippingPlanes = []; 18998 this.localClippingEnabled = false; // physically based shading 18999 19000 this.outputEncoding = LinearEncoding; // physical lights 19001 19002 this.physicallyCorrectLights = false; // tone mapping 19003 19004 this.toneMapping = NoToneMapping; 19005 this.toneMappingExposure = 1.0; // internal properties 19006 19007 const _this = this; 19008 19009 let _isContextLost = false; // internal state cache 19010 19011 let _currentActiveCubeFace = 0; 19012 let _currentActiveMipmapLevel = 0; 19013 let _currentRenderTarget = null; 19014 19015 let _currentMaterialId = -1; 19016 19017 let _currentCamera = null; 19018 19019 const _currentViewport = new Vector4(); 19020 19021 const _currentScissor = new Vector4(); 19022 19023 let _currentScissorTest = null; // 19024 19025 let _width = _canvas.width; 19026 let _height = _canvas.height; 19027 let _pixelRatio = 1; 19028 let _opaqueSort = null; 19029 let _transparentSort = null; 19030 19031 const _viewport = new Vector4(0, 0, _width, _height); 19032 19033 const _scissor = new Vector4(0, 0, _width, _height); 19034 19035 let _scissorTest = false; // 19036 19037 const _currentDrawBuffers = []; // frustum 19038 19039 const _frustum = new Frustum(); // clipping 19040 19041 19042 let _clippingEnabled = false; 19043 let _localClippingEnabled = false; // transmission 19044 19045 let _transmissionRenderTarget = null; // camera matrices cache 19046 19047 const _projScreenMatrix = new Matrix4(); 19048 19049 const _vector3 = new Vector3(); 19050 19051 const _emptyScene = { 19052 background: null, 19053 fog: null, 19054 environment: null, 19055 overrideMaterial: null, 19056 isScene: true 19057 }; 19058 19059 function getTargetPixelRatio() { 19060 return _currentRenderTarget === null ? _pixelRatio : 1; 19061 } // initialize 19062 19063 19064 let _gl = _context; 19065 19066 function getContext(contextNames, contextAttributes) { 19067 for (let i = 0; i < contextNames.length; i++) { 19068 const contextName = contextNames[i]; 19069 19070 const context = _canvas.getContext(contextName, contextAttributes); 19071 19072 if (context !== null) return context; 19073 } 19074 19075 return null; 19076 } 19077 19078 try { 19079 const contextAttributes = { 19080 alpha: _alpha, 19081 depth: _depth, 19082 stencil: _stencil, 19083 antialias: _antialias, 19084 premultipliedAlpha: _premultipliedAlpha, 19085 preserveDrawingBuffer: _preserveDrawingBuffer, 19086 powerPreference: _powerPreference, 19087 failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat 19088 }; // OffscreenCanvas does not have setAttribute, see #22811 19089 19090 if ('setAttribute' in _canvas) _canvas.setAttribute('data-engine', `three.js r${REVISION}`); // event listeners must be registered before WebGL context is created, see #12753 19091 19092 _canvas.addEventListener('webglcontextlost', onContextLost, false); 19093 19094 _canvas.addEventListener('webglcontextrestored', onContextRestore, false); 19095 19096 if (_gl === null) { 19097 const contextNames = ['webgl2', 'webgl', 'experimental-webgl']; 19098 19099 if (_this.isWebGL1Renderer === true) { 19100 contextNames.shift(); 19101 } 19102 19103 _gl = getContext(contextNames, contextAttributes); 19104 19105 if (_gl === null) { 19106 if (getContext(contextNames)) { 19107 throw new Error('Error creating WebGL context with your selected attributes.'); 19108 } else { 19109 throw new Error('Error creating WebGL context.'); 19110 } 19111 } 19112 } // Some experimental-webgl implementations do not have getShaderPrecisionFormat 19113 19114 19115 if (_gl.getShaderPrecisionFormat === undefined) { 19116 _gl.getShaderPrecisionFormat = function () { 19117 return { 19118 'rangeMin': 1, 19119 'rangeMax': 1, 19120 'precision': 1 19121 }; 19122 }; 19123 } 19124 } catch (error) { 19125 console.error('THREE.WebGLRenderer: ' + error.message); 19126 throw error; 19127 } 19128 19129 let extensions, capabilities, state, info; 19130 let properties, textures, cubemaps, cubeuvmaps, attributes, geometries, objects; 19131 let programCache, materials, renderLists, renderStates, clipping, shadowMap; 19132 let background, morphtargets, bufferRenderer, indexedBufferRenderer; 19133 let utils, bindingStates; 19134 19135 function initGLContext() { 19136 extensions = new WebGLExtensions(_gl); 19137 capabilities = new WebGLCapabilities(_gl, extensions, parameters); 19138 extensions.init(capabilities); 19139 utils = new WebGLUtils(_gl, extensions, capabilities); 19140 state = new WebGLState(_gl, extensions, capabilities); 19141 _currentDrawBuffers[0] = _gl.BACK; 19142 info = new WebGLInfo(_gl); 19143 properties = new WebGLProperties(); 19144 textures = new WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info); 19145 cubemaps = new WebGLCubeMaps(_this); 19146 cubeuvmaps = new WebGLCubeUVMaps(_this); 19147 attributes = new WebGLAttributes(_gl, capabilities); 19148 bindingStates = new WebGLBindingStates(_gl, extensions, attributes, capabilities); 19149 geometries = new WebGLGeometries(_gl, attributes, info, bindingStates); 19150 objects = new WebGLObjects(_gl, geometries, attributes, info); 19151 morphtargets = new WebGLMorphtargets(_gl, capabilities, textures); 19152 clipping = new WebGLClipping(properties); 19153 programCache = new WebGLPrograms(_this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping); 19154 materials = new WebGLMaterials(properties); 19155 renderLists = new WebGLRenderLists(); 19156 renderStates = new WebGLRenderStates(extensions, capabilities); 19157 background = new WebGLBackground(_this, cubemaps, state, objects, _premultipliedAlpha); 19158 shadowMap = new WebGLShadowMap(_this, objects, capabilities); 19159 bufferRenderer = new WebGLBufferRenderer(_gl, extensions, info, capabilities); 19160 indexedBufferRenderer = new WebGLIndexedBufferRenderer(_gl, extensions, info, capabilities); 19161 info.programs = programCache.programs; 19162 _this.capabilities = capabilities; 19163 _this.extensions = extensions; 19164 _this.properties = properties; 19165 _this.renderLists = renderLists; 19166 _this.shadowMap = shadowMap; 19167 _this.state = state; 19168 _this.info = info; 19169 } 19170 19171 initGLContext(); // xr 19172 19173 const xr = new WebXRManager(_this, _gl); 19174 this.xr = xr; // API 19175 19176 this.getContext = function () { 19177 return _gl; 19178 }; 19179 19180 this.getContextAttributes = function () { 19181 return _gl.getContextAttributes(); 19182 }; 19183 19184 this.forceContextLoss = function () { 19185 const extension = extensions.get('WEBGL_lose_context'); 19186 if (extension) extension.loseContext(); 19187 }; 19188 19189 this.forceContextRestore = function () { 19190 const extension = extensions.get('WEBGL_lose_context'); 19191 if (extension) extension.restoreContext(); 19192 }; 19193 19194 this.getPixelRatio = function () { 19195 return _pixelRatio; 19196 }; 19197 19198 this.setPixelRatio = function (value) { 19199 if (value === undefined) return; 19200 _pixelRatio = value; 19201 this.setSize(_width, _height, false); 19202 }; 19203
vendor: 4,937 bytes, lines 19204-19391
19204 this.getSize = function (target) { 19205 return target.set(_width, _height); 19206 }; 19207 19208 this.setSize = function (width, height, updateStyle) { 19209 if (xr.isPresenting) { 19210 console.warn('THREE.WebGLRenderer: Can\'t change size while VR device is presenting.'); 19211 return; 19212 } 19213 19214 _width = width; 19215 _height = height; 19216 _canvas.width = Math.floor(width * _pixelRatio); 19217 _canvas.height = Math.floor(height * _pixelRatio); 19218 19219 if (updateStyle !== false) { 19220 _canvas.style.width = width + 'px'; 19221 _canvas.style.height = height + 'px'; 19222 } 19223 19224 this.setViewport(0, 0, width, height); 19225 }; 19226 19227 this.getDrawingBufferSize = function (target) { 19228 return target.set(_width * _pixelRatio, _height * _pixelRatio).floor(); 19229 }; 19230 19231 this.setDrawingBufferSize = function (width, height, pixelRatio) { 19232 _width = width; 19233 _height = height; 19234 _pixelRatio = pixelRatio; 19235 _canvas.width = Math.floor(width * pixelRatio); 19236 _canvas.height = Math.floor(height * pixelRatio); 19237 this.setViewport(0, 0, width, height); 19238 }; 19239 19240 this.getCurrentViewport = function (target) { 19241 return target.copy(_currentViewport); 19242 }; 19243 19244 this.getViewport = function (target) { 19245 return target.copy(_viewport); 19246 }; 19247 19248 this.setViewport = function (x, y, width, height) { 19249 if (x.isVector4) { 19250 _viewport.set(x.x, x.y, x.z, x.w); 19251 } else { 19252 _viewport.set(x, y, width, height); 19253 } 19254 19255 state.viewport(_currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor()); 19256 }; 19257 19258 this.getScissor = function (target) { 19259 return target.copy(_scissor); 19260 }; 19261 19262 this.setScissor = function (x, y, width, height) { 19263 if (x.isVector4) { 19264 _scissor.set(x.x, x.y, x.z, x.w); 19265 } else { 19266 _scissor.set(x, y, width, height); 19267 } 19268 19269 state.scissor(_currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor()); 19270 }; 19271 19272 this.getScissorTest = function () { 19273 return _scissorTest; 19274 }; 19275 19276 this.setScissorTest = function (boolean) { 19277 state.setScissorTest(_scissorTest = boolean); 19278 }; 19279 19280 this.setOpaqueSort = function (method) { 19281 _opaqueSort = method; 19282 }; 19283 19284 this.setTransparentSort = function (method) { 19285 _transparentSort = method; 19286 }; // Clearing 19287 19288 19289 this.getClearColor = function (target) { 19290 return target.copy(background.getClearColor()); 19291 }; 19292 19293 this.setClearColor = function () { 19294 background.setClearColor.apply(background, arguments); 19295 }; 19296 19297 this.getClearAlpha = function () { 19298 return background.getClearAlpha(); 19299 }; 19300 19301 this.setClearAlpha = function () { 19302 background.setClearAlpha.apply(background, arguments); 19303 }; 19304 19305 this.clear = function (color, depth, stencil) { 19306 let bits = 0; 19307 if (color === undefined || color) bits |= _gl.COLOR_BUFFER_BIT; 19308 if (depth === undefined || depth) bits |= _gl.DEPTH_BUFFER_BIT; 19309 if (stencil === undefined || stencil) bits |= _gl.STENCIL_BUFFER_BIT; 19310 19311 _gl.clear(bits); 19312 }; 19313 19314 this.clearColor = function () { 19315 this.clear(true, false, false); 19316 }; 19317 19318 this.clearDepth = function () { 19319 this.clear(false, true, false); 19320 }; 19321 19322 this.clearStencil = function () { 19323 this.clear(false, false, true); 19324 }; // 19325 19326 19327 this.dispose = function () { 19328 _canvas.removeEventListener('webglcontextlost', onContextLost, false); 19329 19330 _canvas.removeEventListener('webglcontextrestored', onContextRestore, false); 19331 19332 renderLists.dispose(); 19333 renderStates.dispose(); 19334 properties.dispose(); 19335 cubemaps.dispose(); 19336 cubeuvmaps.dispose(); 19337 objects.dispose(); 19338 bindingStates.dispose(); 19339 programCache.dispose(); 19340 xr.dispose(); 19341 xr.removeEventListener('sessionstart', onXRSessionStart); 19342 xr.removeEventListener('sessionend', onXRSessionEnd); 19343 19344 if (_transmissionRenderTarget) { 19345 _transmissionRenderTarget.dispose(); 19346 19347 _transmissionRenderTarget = null; 19348 } 19349 19350 animation.stop(); 19351 }; // Events 19352 19353 19354 function onContextLost(event) { 19355 event.preventDefault(); 19356 console.log('THREE.WebGLRenderer: Context Lost.'); 19357 _isContextLost = true; 19358 } 19359 19360 function onContextRestore() { 19361 console.log('THREE.WebGLRenderer: Context Restored.'); 19362 _isContextLost = false; 19363 const infoAutoReset = info.autoReset; 19364 const shadowMapEnabled = shadowMap.enabled; 19365 const shadowMapAutoUpdate = shadowMap.autoUpdate; 19366 const shadowMapNeedsUpdate = shadowMap.needsUpdate; 19367 const shadowMapType = shadowMap.type; 19368 initGLContext(); 19369 info.autoReset = infoAutoReset; 19370 shadowMap.enabled = shadowMapEnabled; 19371 shadowMap.autoUpdate = shadowMapAutoUpdate; 19372 shadowMap.needsUpdate = shadowMapNeedsUpdate; 19373 shadowMap.type = shadowMapType; 19374 } 19375 19376 function onMaterialDispose(event) { 19377 const material = event.target; 19378 material.removeEventListener('dispose', onMaterialDispose); 19379 deallocateMaterial(material); 19380 } // Buffer deallocation 19381 19382 19383 function deallocateMaterial(material) { 19384 releaseMaterialProgramReferences(material); 19385 properties.remove(material); 19386 } 19387 19388 function releaseMaterialProgramReferences(material) { 19389 const programs = properties.get(material).programs; 19390 19391 if (programs !== undefined) {
19392 programs.forEach(function (program) { 19393 programCache.releaseProgram(program); 19394 }); 19395 19396 if (material.isShaderMaterial) { 19397 programCache.releaseShaderCache(material); 19398 } 19399 } 19400 } // Buffer rendering 19401 19402 19403 this.renderBufferDirect = function (camera, scene, geometry, material, object, group) { 19404 if (scene === null) scene = _emptyScene; // renderBufferDirect second parameter used to be fog (could be null) 19405 19406 const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0; 19407 const program = setProgram(camera, scene, geometry, material, object); 19408 state.setMaterial(material, frontFaceCW); // 19409 19410 let index = geometry.index; 19411 const position = geometry.attributes.position; // 19412 19413 if (index === null) { 19414 if (position === undefined || position.count === 0) return; 19415 } else if (index.count === 0) { 19416 return; 19417 } // 19418 19419 19420 let rangeFactor = 1; 19421 19422 if (material.wireframe === true) { 19423 index = geometries.getWireframeAttribute(geometry); 19424 rangeFactor = 2; 19425 } 19426 19427 bindingStates.setup(object, material, program, geometry, index); 19428 let attribute; 19429 let renderer = bufferRenderer; 19430 19431 if (index !== null) { 19432 attribute = attributes.get(index); 19433 renderer = indexedBufferRenderer; 19434 renderer.setIndex(attribute); 19435 } // 19436 19437 19438 const dataCount = index !== null ? index.count : position.count; 19439 const rangeStart = geometry.drawRange.start * rangeFactor; 19440 const rangeCount = geometry.drawRange.count * rangeFactor; 19441 const groupStart = group !== null ? group.start * rangeFactor : 0; 19442 const groupCount = group !== null ? group.count * rangeFactor : Infinity; 19443 const drawStart = Math.max(rangeStart, groupStart); 19444 const drawEnd = Math.min(dataCount, rangeStart + rangeCount, groupStart + groupCount) - 1; 19445 const drawCount = Math.max(0, drawEnd - drawStart + 1); 19446 if (drawCount === 0) return; // 19447 19448 if (object.isMesh) { 19449 if (material.wireframe === true) { 19450 state.setLineWidth(material.wireframeLinewidth * getTargetPixelRatio()); 19451 renderer.setMode(_gl.LINES); 19452 } else { 19453 renderer.setMode(_gl.TRIANGLES); 19454 } 19455 } else if (object.isLine) { 19456 let lineWidth = material.linewidth; 19457 if (lineWidth === undefined) lineWidth = 1; // Not using Line*Material 19458 19459 state.setLineWidth(lineWidth * getTargetPixelRatio()); 19460 19461 if (object.isLineSegments) { 19462 renderer.setMode(_gl.LINES); 19463 } else if (object.isLineLoop) { 19464 renderer.setMode(_gl.LINE_LOOP); 19465 } else { 19466 renderer.setMode(_gl.LINE_STRIP); 19467 } 19468 } else if (object.isPoints) { 19469 renderer.setMode(_gl.POINTS); 19470 } else if (object.isSprite) { 19471 renderer.setMode(_gl.TRIANGLES); 19472 } 19473 19474 if (object.isInstancedMesh) { 19475 renderer.renderInstances(drawStart, drawCount, object.count); 19476 } else if (geometry.isInstancedBufferGeometry) { 19477 const instanceCount = Math.min(geometry.instanceCount, geometry._maxInstanceCount); 19478 renderer.renderInstances(drawStart, drawCount, instanceCount); 19479 } else { 19480 renderer.render(drawStart, drawCount); 19481 } 19482 }; // Compile 19483 19484 19485 this.compile = function (scene, camera) { 19486 currentRenderState = renderStates.get(scene); 19487 currentRenderState.init(); 19488 renderStateStack.push(currentRenderState); 19489 scene.traverseVisible(function (object) { 19490 if (object.isLight && object.layers.test(camera.layers)) { 19491 currentRenderState.pushLight(object); 19492 19493 if (object.castShadow) { 19494 currentRenderState.pushShadow(object); 19495 } 19496 } 19497 }); 19498 currentRenderState.setupLights(_this.physicallyCorrectLights); 19499 scene.traverse(function (object) { 19500 const material = object.material; 19501 19502 if (material) { 19503 if (Array.isArray(material)) { 19504 for (let i = 0; i < material.length; i++) { 19505 const material2 = material[i]; 19506 getProgram(material2, scene, object); 19507 } 19508 } else { 19509 getProgram(material, scene, object); 19510 } 19511 } 19512 }); 19513 renderStateStack.pop(); 19514 currentRenderState = null; 19515 }; // Animation Loop 19516 19517 19518 let onAnimationFrameCallback = null; 19519 19520 function onAnimationFrame(time) { 19521 if (onAnimationFrameCallback) onAnimationFrameCallback(time); 19522 } 19523 19524 function onXRSessionStart() { 19525 animation.stop(); 19526 } 19527 19528 function onXRSessionEnd() { 19529 animation.start(); 19530 } 19531 19532 const animation = new WebGLAnimation(); 19533 animation.setAnimationLoop(onAnimationFrame); 19534 if (typeof window !== 'undefined') animation.setContext(window); 19535 19536 this.setAnimationLoop = function (callback) { 19537 onAnimationFrameCallback = callback; 19538 xr.setAnimationLoop(callback); 19539 callback === null ? animation.stop() : animation.start(); 19540 }; 19541 19542 xr.addEventListener('sessionstart', onXRSessionStart); 19543 xr.addEventListener('sessionend', onXRSessionEnd); // Rendering 19544 19545 this.render = function (scene, camera) { 19546 if (camera !== undefined && camera.isCamera !== true) { 19547 console.error('THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.'); 19548 return; 19549 } 19550 19551 if (_isContextLost === true) return; // update scene graph 19552 19553 if (scene.autoUpdate === true) scene.updateMatrixWorld(); // update camera matrices and frustum 19554 19555 if (camera.parent === null) camera.updateMatrixWorld(); 19556 19557 if (xr.enabled === true && xr.isPresenting === true) { 19558 if (xr.cameraAutoUpdate === true) xr.updateCamera(camera); 19559 camera = xr.getCamera(); // use XR camera for rendering 19560 } // 19561 19562 19563 if (scene.isScene === true) scene.onBeforeRender(_this, scene, camera, _currentRenderTarget); 19564 currentRenderState = renderStates.get(scene, renderStateStack.length);
vendor: 4,795 bytes, lines 19565-19712
19565 currentRenderState.init(); 19566 renderStateStack.push(currentRenderState); 19567 19568 _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); 19569 19570 _frustum.setFromProjectionMatrix(_projScreenMatrix); 19571 19572 _localClippingEnabled = this.localClippingEnabled; 19573 _clippingEnabled = clipping.init(this.clippingPlanes, _localClippingEnabled, camera); 19574 currentRenderList = renderLists.get(scene, renderListStack.length); 19575 currentRenderList.init(); 19576 renderListStack.push(currentRenderList); 19577 projectObject(scene, camera, 0, _this.sortObjects); 19578 currentRenderList.finish(); 19579 19580 if (_this.sortObjects === true) { 19581 currentRenderList.sort(_opaqueSort, _transparentSort); 19582 } // 19583 19584 19585 if (_clippingEnabled === true) clipping.beginShadows(); 19586 const shadowsArray = currentRenderState.state.shadowsArray; 19587 shadowMap.render(shadowsArray, scene, camera); 19588 if (_clippingEnabled === true) clipping.endShadows(); // 19589 19590 if (this.info.autoReset === true) this.info.reset(); // 19591 19592 background.render(currentRenderList, scene); // render scene 19593 19594 currentRenderState.setupLights(_this.physicallyCorrectLights); 19595 19596 if (camera.isArrayCamera) { 19597 const cameras = camera.cameras; 19598 19599 for (let i = 0, l = cameras.length; i < l; i++) { 19600 const camera2 = cameras[i]; 19601 renderScene(currentRenderList, scene, camera2, camera2.viewport); 19602 } 19603 } else { 19604 renderScene(currentRenderList, scene, camera); 19605 } // 19606 19607 19608 if (_currentRenderTarget !== null) { 19609 // resolve multisample renderbuffers to a single-sample texture if necessary 19610 textures.updateMultisampleRenderTarget(_currentRenderTarget); // Generate mipmap if we're using any kind of mipmap filtering 19611 19612 textures.updateRenderTargetMipmap(_currentRenderTarget); 19613 } // 19614 19615 19616 if (scene.isScene === true) scene.onAfterRender(_this, scene, camera); // Ensure depth buffer writing is enabled so it can be cleared on next render 19617 19618 state.buffers.depth.setTest(true); 19619 state.buffers.depth.setMask(true); 19620 state.buffers.color.setMask(true); 19621 state.setPolygonOffset(false); // _gl.finish(); 19622 19623 bindingStates.resetDefaultState(); 19624 _currentMaterialId = -1; 19625 _currentCamera = null; 19626 renderStateStack.pop(); 19627 19628 if (renderStateStack.length > 0) { 19629 currentRenderState = renderStateStack[renderStateStack.length - 1]; 19630 } else { 19631 currentRenderState = null; 19632 } 19633 19634 renderListStack.pop(); 19635 19636 if (renderListStack.length > 0) { 19637 currentRenderList = renderListStack[renderListStack.length - 1]; 19638 } else { 19639 currentRenderList = null; 19640 } 19641 }; 19642 19643 function projectObject(object, camera, groupOrder, sortObjects) { 19644 if (object.visible === false) return; 19645 const visible = object.layers.test(camera.layers); 19646 19647 if (visible) { 19648 if (object.isGroup) { 19649 groupOrder = object.renderOrder; 19650 } else if (object.isLOD) { 19651 if (object.autoUpdate === true) object.update(camera); 19652 } else if (object.isLight) { 19653 currentRenderState.pushLight(object); 19654 19655 if (object.castShadow) { 19656 currentRenderState.pushShadow(object); 19657 } 19658 } else if (object.isSprite) { 19659 if (!object.frustumCulled || _frustum.intersectsSprite(object)) { 19660 if (sortObjects) { 19661 _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); 19662 } 19663 19664 const geometry = objects.update(object); 19665 const material = object.material; 19666 19667 if (material.visible) { 19668 currentRenderList.push(object, geometry, material, groupOrder, _vector3.z, null); 19669 } 19670 } 19671 } else if (object.isMesh || object.isLine || object.isPoints) { 19672 if (object.isSkinnedMesh) { 19673 // update skeleton only once in a frame 19674 if (object.skeleton.frame !== info.render.frame) { 19675 object.skeleton.update(); 19676 object.skeleton.frame = info.render.frame; 19677 } 19678 } 19679 19680 if (!object.frustumCulled || _frustum.intersectsObject(object)) { 19681 if (sortObjects) { 19682 _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); 19683 } 19684 19685 const geometry = objects.update(object); 19686 const material = object.material; 19687 19688 if (Array.isArray(material)) { 19689 const groups = geometry.groups; 19690 19691 for (let i = 0, l = groups.length; i < l; i++) { 19692 const group = groups[i]; 19693 const groupMaterial = material[group.materialIndex]; 19694 19695 if (groupMaterial && groupMaterial.visible) { 19696 currentRenderList.push(object, geometry, groupMaterial, groupOrder, _vector3.z, group); 19697 } 19698 } 19699 } else if (material.visible) { 19700 currentRenderList.push(object, geometry, material, groupOrder, _vector3.z, null); 19701 } 19702 } 19703 } 19704 } 19705 19706 const children = object.children; 19707 19708 for (let i = 0, l = children.length; i < l; i++) { 19709 projectObject(children[i], camera, groupOrder, sortObjects); 19710 } 19711 } 19712
19713 function renderScene(currentRenderList, scene, camera, viewport) { 19714 const opaqueObjects = currentRenderList.opaque; 19715 const transmissiveObjects = currentRenderList.transmissive; 19716 const transparentObjects = currentRenderList.transparent; 19717 currentRenderState.setupLightsView(camera); 19718 if (transmissiveObjects.length > 0) renderTransmissionPass(opaqueObjects, scene, camera); 19719 if (viewport) state.viewport(_currentViewport.copy(viewport)); 19720 if (opaqueObjects.length > 0) renderObjects(opaqueObjects, scene, camera); 19721 if (transmissiveObjects.length > 0) renderObjects(transmissiveObjects, scene, camera); 19722 if (transparentObjects.length > 0) renderObjects(transparentObjects, scene, camera); 19723 } 19724 19725 function renderTransmissionPass(opaqueObjects, scene, camera) { 19726 if (_transmissionRenderTarget === null) { 19727 const needsAntialias = _antialias === true && capabilities.isWebGL2 === true; 19728 const renderTargetType = needsAntialias ? WebGLMultisampleRenderTarget : WebGLRenderTarget; 19729 _transmissionRenderTarget = new renderTargetType(1024, 1024, { 19730 generateMipmaps: true, 19731 type: utils.convert(HalfFloatType) !== null ? HalfFloatType : UnsignedByteType, 19732 minFilter: LinearMipmapLinearFilter, 19733 magFilter: NearestFilter, 19734 wrapS: ClampToEdgeWrapping, 19735 wrapT: ClampToEdgeWrapping, 19736 useRenderToTexture: extensions.has('WEBGL_multisampled_render_to_texture') 19737 }); 19738 } 19739 19740 const currentRenderTarget = _this.getRenderTarget(); 19741 19742 _this.setRenderTarget(_transmissionRenderTarget); 19743 19744 _this.clear(); // Turn off the features which can affect the frag color for opaque objects pass. 19745 // Otherwise they are applied twice in opaque objects pass and transmission objects pass. 19746 19747 19748 const currentToneMapping = _this.toneMapping; 19749 _this.toneMapping = NoToneMapping; 19750 renderObjects(opaqueObjects, scene, camera); 19751 _this.toneMapping = currentToneMapping; 19752 textures.updateMultisampleRenderTarget(_transmissionRenderTarget); 19753 textures.updateRenderTargetMipmap(_transmissionRenderTarget); 19754 19755 _this.setRenderTarget(currentRenderTarget); 19756 } 19757 19758 function renderObjects(renderList, scene, camera) { 19759 const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null; 19760 19761 for (let i = 0, l = renderList.length; i < l; i++) { 19762 const renderItem = renderList[i]; 19763 const object = renderItem.object; 19764 const geometry = renderItem.geometry; 19765 const material = overrideMaterial === null ? renderItem.material : overrideMaterial; 19766 const group = renderItem.group; 19767 19768 if (object.layers.test(camera.layers)) { 19769 renderObject(object, scene, camera, geometry, material, group); 19770 } 19771 } 19772 } 19773 19774 function renderObject(object, scene, camera, geometry, material, group) { 19775 object.onBeforeRender(_this, scene, camera, geometry, material, group); 19776 object.modelViewMatrix.multiplyMatrices(camera.matrixWorldInverse, object.matrixWorld); 19777 object.normalMatrix.getNormalMatrix(object.modelViewMatrix); 19778 material.onBeforeRender(_this, scene, camera, geometry, object, group); 19779 19780 if (material.transparent === true && material.side === DoubleSide) { 19781 material.side = BackSide; 19782 material.needsUpdate = true; 19783 19784 _this.renderBufferDirect(camera, scene, geometry, material, object, group); 19785 19786 material.side = FrontSide; 19787 material.needsUpdate = true; 19788 19789 _this.renderBufferDirect(camera, scene, geometry, material, object, group); 19790 19791 material.side = DoubleSide; 19792 } else { 19793 _this.renderBufferDirect(camera, scene, geometry, material, object, group); 19794 } 19795 19796 object.onAfterRender(_this, scene, camera, geometry, material, group); 19797 } 19798 19799 function getProgram(material, scene, object) { 19800 if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ... 19801 19802 const materialProperties = properties.get(material); 19803 const lights = currentRenderState.state.lights; 19804 const shadowsArray = currentRenderState.state.shadowsArray; 19805 const lightsStateVersion = lights.state.version; 19806 const parameters = programCache.getParameters(material, lights.state, shadowsArray, scene, object); 19807 const programCacheKey = programCache.getProgramCacheKey(parameters); 19808 let programs = materialProperties.programs; // always update environment and fog - changing these trigger an getProgram call, but it's possible that the program doesn't change 19809 19810 materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null; 19811 materialProperties.fog = scene.fog; 19812 materialProperties.envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || materialProperties.environment); 19813 19814 if (programs === undefined) { 19815 // new material 19816 material.addEventListener('dispose', onMaterialDispose); 19817 programs = new Map(); 19818 materialProperties.programs = programs; 19819 } 19820 19821 let program = programs.get(programCacheKey); 19822 19823 if (program !== undefined) { 19824 // early out if program and light state is identical 19825 if (materialProperties.currentProgram === program && materialProperties.lightsStateVersion === lightsStateVersion) { 19826 updateCommonMaterialProperties(material, parameters); 19827 return program; 19828 } 19829 } else { 19830 parameters.uniforms = programCache.getUniforms(material); 19831 material.onBuild(object, parameters, _this); 19832 material.onBeforeCompile(parameters, _this); 19833 program = programCache.acquireProgram(parameters, programCacheKey); 19834 programs.set(programCacheKey, program); 19835 materialProperties.uniforms = parameters.uniforms; 19836 } 19837 19838 const uniforms = materialProperties.uniforms; 19839 19840 if (!material.isShaderMaterial && !material.isRawShaderMaterial || material.clipping === true) { 19841 uniforms.clippingPlanes = clipping.uniform; 19842 } 19843 19844 updateCommonMaterialProperties(material, parameters); // store the light setup it was created for 19845 19846 materialProperties.needsLights = materialNeedsLights(material); 19847 materialProperties.lightsStateVersion = lightsStateVersion; 19848 19849 if (materialProperties.needsLights) { 19850 // wire up the material to this renderer's lighting state 19851 uniforms.ambientLightColor.value = lights.state.ambient; 19852 uniforms.lightProbe.value = lights.state.probe; 19853 uniforms.directionalLights.value = lights.state.directional; 19854 uniforms.directionalLightShadows.value = lights.state.directionalShadow; 19855 uniforms.spotLights.value = lights.state.spot; 19856 uniforms.spotLightShadows.value = lights.state.spotShadow; 19857 uniforms.rectAreaLights.value = lights.state.rectArea; 19858 uniforms.ltc_1.value = lights.state.rectAreaLTC1; 19859 uniforms.ltc_2.value = lights.state.rectAreaLTC2; 19860 uniforms.pointLights.value = lights.state.point; 19861 uniforms.pointLightShadows.value = lights.state.pointShadow; 19862 uniforms.hemisphereLights.value = lights.state.hemi; 19863 uniforms.directionalShadowMap.value = lights.state.directionalShadowMap; 19864 uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix; 19865 uniforms.spotShadowMap.value = lights.state.spotShadowMap; 19866 uniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix; 19867 uniforms.pointShadowMap.value = lights.state.pointShadowMap; 19868 uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; // TODO (abelnation): add area lights shadow info to uniforms 19869 } 19870 19871 const progUniforms = program.getUniforms(); 19872 const uniformsList = WebGLUniforms.seqWithValue(progUniforms.seq, uniforms); 19873 materialProperties.currentProgram = program; 19874 materialProperties.uniformsList = uniformsList; 19875 return program; 19876 } 19877 19878 function updateCommonMaterialProperties(material, parameters) { 19879 const materialProperties = properties.get(material); 19880 materialProperties.outputEncoding = parameters.outputEncoding; 19881 materialProperties.instancing = parameters.instancing; 19882 materialProperties.skinning = parameters.skinning; 19883 materialProperties.morphTargets = parameters.morphTargets; 19884 materialProperties.morphNormals = parameters.morphNormals; 19885 materialProperties.morphTargetsCount = parameters.morphTargetsCount; 19886 materialProperties.numClippingPlanes = parameters.numClippingPlanes; 19887 materialProperties.numIntersection = parameters.numClipIntersection; 19888 materialProperties.vertexAlphas = parameters.vertexAlphas; 19889 materialProperties.vertexTangents = parameters.vertexTangents; 19890 materialProperties.toneMapping = parameters.toneMapping; 19891 } 19892 19893 function setProgram(camera, scene, geometry, material, object) { 19894 if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ... 19895 19896 textures.resetTextureUnits(); 19897 const fog = scene.fog; 19898 const environment = material.isMeshStandardMaterial ? scene.environment : null; 19899 const encoding = _currentRenderTarget === null ? _this.outputEncoding : _currentRenderTarget.texture.encoding; 19900 const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment); 19901 const vertexAlphas = material.vertexColors === true && !!geometry.attributes.color && geometry.attributes.color.itemSize === 4; 19902 const vertexTangents = !!material.normalMap && !!geometry.attributes.tangent; 19903 const morphTargets = !!geometry.morphAttributes.position; 19904 const morphNormals = !!geometry.morphAttributes.normal;
vendor: 5,161 bytes, lines 19905-20019
19905 const morphTargetsCount = !!geometry.morphAttributes.position ? geometry.morphAttributes.position.length : 0; 19906 const toneMapping = material.toneMapped ? _this.toneMapping : NoToneMapping; 19907 const materialProperties = properties.get(material); 19908 const lights = currentRenderState.state.lights; 19909 19910 if (_clippingEnabled === true) { 19911 if (_localClippingEnabled === true || camera !== _currentCamera) { 19912 const useCache = camera === _currentCamera && material.id === _currentMaterialId; // we might want to call this function with some ClippingGroup 19913 // object instead of the material, once it becomes feasible 19914 // (#8465, #8379) 19915 19916 clipping.setState(material, camera, useCache); 19917 } 19918 } // 19919 19920 19921 let needsProgramChange = false; 19922 19923 if (material.version === materialProperties.__version) { 19924 if (materialProperties.needsLights && materialProperties.lightsStateVersion !== lights.state.version) { 19925 needsProgramChange = true; 19926 } else if (materialProperties.outputEncoding !== encoding) { 19927 needsProgramChange = true; 19928 } else if (object.isInstancedMesh && materialProperties.instancing === false) { 19929 needsProgramChange = true; 19930 } else if (!object.isInstancedMesh && materialProperties.instancing === true) { 19931 needsProgramChange = true; 19932 } else if (object.isSkinnedMesh && materialProperties.skinning === false) { 19933 needsProgramChange = true; 19934 } else if (!object.isSkinnedMesh && materialProperties.skinning === true) { 19935 needsProgramChange = true; 19936 } else if (materialProperties.envMap !== envMap) { 19937 needsProgramChange = true; 19938 } else if (material.fog && materialProperties.fog !== fog) { 19939 needsProgramChange = true; 19940 } else if (materialProperties.numClippingPlanes !== undefined && (materialProperties.numClippingPlanes !== clipping.numPlanes || materialProperties.numIntersection !== clipping.numIntersection)) { 19941 needsProgramChange = true; 19942 } else if (materialProperties.vertexAlphas !== vertexAlphas) { 19943 needsProgramChange = true; 19944 } else if (materialProperties.vertexTangents !== vertexTangents) { 19945 needsProgramChange = true; 19946 } else if (materialProperties.morphTargets !== morphTargets) { 19947 needsProgramChange = true; 19948 } else if (materialProperties.morphNormals !== morphNormals) { 19949 needsProgramChange = true; 19950 } else if (materialProperties.toneMapping !== toneMapping) { 19951 needsProgramChange = true; 19952 } else if (capabilities.isWebGL2 === true && materialProperties.morphTargetsCount !== morphTargetsCount) { 19953 needsProgramChange = true; 19954 } 19955 } else { 19956 needsProgramChange = true; 19957 materialProperties.__version = material.version; 19958 } // 19959 19960 19961 let program = materialProperties.currentProgram; 19962 19963 if (needsProgramChange === true) { 19964 program = getProgram(material, scene, object); 19965 } 19966 19967 let refreshProgram = false; 19968 let refreshMaterial = false; 19969 let refreshLights = false; 19970 const p_uniforms = program.getUniforms(), 19971 m_uniforms = materialProperties.uniforms; 19972 19973 if (state.useProgram(program.program)) { 19974 refreshProgram = true; 19975 refreshMaterial = true; 19976 refreshLights = true; 19977 } 19978 19979 if (material.id !== _currentMaterialId) { 19980 _currentMaterialId = material.id; 19981 refreshMaterial = true; 19982 } 19983 19984 if (refreshProgram || _currentCamera !== camera) { 19985 p_uniforms.setValue(_gl, 'projectionMatrix', camera.projectionMatrix); 19986 19987 if (capabilities.logarithmicDepthBuffer) { 19988 p_uniforms.setValue(_gl, 'logDepthBufFC', 2.0 / (Math.log(camera.far + 1.0) / Math.LN2)); 19989 } 19990 19991 if (_currentCamera !== camera) { 19992 _currentCamera = camera; // lighting uniforms depend on the camera so enforce an update 19993 // now, in case this material supports lights - or later, when 19994 // the next material that does gets activated: 19995 19996 refreshMaterial = true; // set to true on material change 19997 19998 refreshLights = true; // remains set until update done 19999 } // load material specific uniforms 20000 // (shader material also gets them for the sake of genericity) 20001 20002 20003 if (material.isShaderMaterial || material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshStandardMaterial || material.envMap) { 20004 const uCamPos = p_uniforms.map.cameraPosition; 20005 20006 if (uCamPos !== undefined) { 20007 uCamPos.setValue(_gl, _vector3.setFromMatrixPosition(camera.matrixWorld)); 20008 } 20009 } 20010 20011 if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial) { 20012 p_uniforms.setValue(_gl, 'isOrthographic', camera.isOrthographicCamera === true); 20013 } 20014 20015 if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial || material.isShadowMaterial || object.isSkinnedMesh) { 20016 p_uniforms.setValue(_gl, 'viewMatrix', camera.matrixWorldInverse); 20017 } 20018 } // skinning and morph target uniforms must be set even if material didn't change 20019 // auto-setting of texture unit for bone and morph texture must go before other textures
20020 // otherwise textures used for skinning and morphing can take over texture units reserved for other material textures 20021 20022 20023 if (object.isSkinnedMesh) { 20024 p_uniforms.setOptional(_gl, object, 'bindMatrix'); 20025 p_uniforms.setOptional(_gl, object, 'bindMatrixInverse'); 20026 const skeleton = object.skeleton; 20027 20028 if (skeleton) { 20029 if (capabilities.floatVertexTextures) { 20030 if (skeleton.boneTexture === null) skeleton.computeBoneTexture(); 20031 p_uniforms.setValue(_gl, 'boneTexture', skeleton.boneTexture, textures); 20032 p_uniforms.setValue(_gl, 'boneTextureSize', skeleton.boneTextureSize); 20033 } else { 20034 p_uniforms.setOptional(_gl, skeleton, 'boneMatrices'); 20035 } 20036 } 20037 } 20038 20039 if (!!geometry && (geometry.morphAttributes.position !== undefined || geometry.morphAttributes.normal !== undefined)) { 20040 morphtargets.update(object, geometry, material, program); 20041 } 20042 20043 if (refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow) { 20044 materialProperties.receiveShadow = object.receiveShadow; 20045 p_uniforms.setValue(_gl, 'receiveShadow', object.receiveShadow); 20046 } 20047 20048 if (refreshMaterial) { 20049 p_uniforms.setValue(_gl, 'toneMappingExposure', _this.toneMappingExposure); 20050 20051 if (materialProperties.needsLights) { 20052 // the current material requires lighting info 20053 // note: all lighting uniforms are always set correctly 20054 // they simply reference the renderer's state for their 20055 // values 20056 // 20057 // use the current material's .needsUpdate flags to set 20058 // the GL state when required 20059 markUniformsLightsNeedsUpdate(m_uniforms, refreshLights); 20060 } // refresh uniforms common to several materials 20061 20062 20063 if (fog && material.fog) { 20064 materials.refreshFogUniforms(m_uniforms, fog); 20065 } 20066 20067 materials.refreshMaterialUniforms(m_uniforms, material, _pixelRatio, _height, _transmissionRenderTarget); 20068 WebGLUniforms.upload(_gl, materialProperties.uniformsList, m_uniforms, textures); 20069 } 20070 20071 if (material.isShaderMaterial && material.uniformsNeedUpdate === true) { 20072 WebGLUniforms.upload(_gl, materialProperties.uniformsList, m_uniforms, textures); 20073 material.uniformsNeedUpdate = false; 20074 } 20075 20076 if (material.isSpriteMaterial) { 20077 p_uniforms.setValue(_gl, 'center', object.center); 20078 } // common matrices 20079 20080 20081 p_uniforms.setValue(_gl, 'modelViewMatrix', object.modelViewMatrix); 20082 p_uniforms.setValue(_gl, 'normalMatrix', object.normalMatrix); 20083 p_uniforms.setValue(_gl, 'modelMatrix', object.matrixWorld); 20084 return program; 20085 } // If uniforms are marked as clean, they don't need to be loaded to the GPU. 20086 20087 20088 function markUniformsLightsNeedsUpdate(uniforms, value) { 20089 uniforms.ambientLightColor.needsUpdate = value; 20090 uniforms.lightProbe.needsUpdate = value; 20091 uniforms.directionalLights.needsUpdate = value; 20092 uniforms.directionalLightShadows.needsUpdate = value; 20093 uniforms.pointLights.needsUpdate = value; 20094 uniforms.pointLightShadows.needsUpdate = value; 20095 uniforms.spotLights.needsUpdate = value; 20096 uniforms.spotLightShadows.needsUpdate = value; 20097 uniforms.rectAreaLights.needsUpdate = value; 20098 uniforms.hemisphereLights.needsUpdate = value; 20099 } 20100 20101 function materialNeedsLights(material) { 20102 return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial || material.isShadowMaterial || material.isShaderMaterial && material.lights === true; 20103 } 20104 20105 this.getActiveCubeFace = function () { 20106 return _currentActiveCubeFace; 20107 }; 20108 20109 this.getActiveMipmapLevel = function () { 20110 return _currentActiveMipmapLevel; 20111 }; 20112 20113 this.getRenderTarget = function () { 20114 return _currentRenderTarget; 20115 }; 20116 20117 this.setRenderTargetTextures = function (renderTarget, colorTexture, depthTexture) { 20118 properties.get(renderTarget.texture).__webglTexture = colorTexture; 20119 properties.get(renderTarget.depthTexture).__webglTexture = depthTexture; 20120 const renderTargetProperties = properties.get(renderTarget); 20121 renderTargetProperties.__hasExternalTextures = true; 20122 20123 if (renderTargetProperties.__hasExternalTextures) { 20124 renderTargetProperties.__autoAllocateDepthBuffer = depthTexture === undefined; 20125 20126 if (!renderTargetProperties.__autoAllocateDepthBuffer) { 20127 // The multisample_render_to_texture extension doesn't work properly if there 20128 // are midframe flushes and an external depth buffer. Disable use of the extension. 20129 if (renderTarget.useRenderToTexture) { 20130 console.warn('render-to-texture extension was disabled because an external texture was provided'); 20131 renderTarget.useRenderToTexture = false;
20132 renderTarget.useRenderbuffer = true; 20133 } 20134 } 20135 } 20136 }; 20137 20138 this.setRenderTargetFramebuffer = function (renderTarget, defaultFramebuffer) { 20139 const renderTargetProperties = properties.get(renderTarget); 20140 renderTargetProperties.__webglFramebuffer = defaultFramebuffer; 20141 renderTargetProperties.__useDefaultFramebuffer = defaultFramebuffer === undefined; 20142 }; 20143 20144 this.setRenderTarget = function (renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) { 20145 _currentRenderTarget = renderTarget; 20146 _currentActiveCubeFace = activeCubeFace; 20147 _currentActiveMipmapLevel = activeMipmapLevel; 20148 let useDefaultFramebuffer = true; 20149 20150 if (renderTarget) { 20151 const renderTargetProperties = properties.get(renderTarget); 20152 20153 if (renderTargetProperties.__useDefaultFramebuffer !== undefined) { 20154 // We need to make sure to rebind the framebuffer. 20155 state.bindFramebuffer(_gl.FRAMEBUFFER, null); 20156 useDefaultFramebuffer = false; 20157 } else if (renderTargetProperties.__webglFramebuffer === undefined) { 20158 textures.setupRenderTarget(renderTarget); 20159 } else if (renderTargetProperties.__hasExternalTextures) { 20160 // Color and depth texture must be rebound in order for the swapchain to update. 20161 textures.rebindTextures(renderTarget, properties.get(renderTarget.texture).__webglTexture, properties.get(renderTarget.depthTexture).__webglTexture); 20162 } 20163 } 20164 20165 let framebuffer = null; 20166 let isCube = false; 20167 let isRenderTarget3D = false; 20168 20169 if (renderTarget) { 20170 const texture = renderTarget.texture; 20171 20172 if (texture.isDataTexture3D || texture.isDataTexture2DArray) { 20173 isRenderTarget3D = true; 20174 } 20175 20176 const __webglFramebuffer = properties.get(renderTarget).__webglFramebuffer; 20177 20178 if (renderTarget.isWebGLCubeRenderTarget) { 20179 framebuffer = __webglFramebuffer[activeCubeFace]; 20180 isCube = true; 20181 } else if (renderTarget.useRenderbuffer) { 20182 framebuffer = properties.get(renderTarget).__webglMultisampledFramebuffer; 20183 } else { 20184 framebuffer = __webglFramebuffer; 20185 } 20186 20187 _currentViewport.copy(renderTarget.viewport); 20188 20189 _currentScissor.copy(renderTarget.scissor); 20190 20191 _currentScissorTest = renderTarget.scissorTest; 20192 } else { 20193 _currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor(); 20194 20195 _currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor(); 20196 20197 _currentScissorTest = _scissorTest; 20198 } 20199 20200 const framebufferBound = state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); 20201 20202 if (framebufferBound && capabilities.drawBuffers && useDefaultFramebuffer) { 20203 let needsUpdate = false; 20204 20205 if (renderTarget) { 20206 if (renderTarget.isWebGLMultipleRenderTargets) { 20207 const textures = renderTarget.texture; 20208 20209 if (_currentDrawBuffers.length !== textures.length || _currentDrawBuffers[0] !== _gl.COLOR_ATTACHMENT0) { 20210 for (let i = 0, il = textures.length; i < il; i++) { 20211 _currentDrawBuffers[i] = _gl.COLOR_ATTACHMENT0 + i; 20212 } 20213 20214 _currentDrawBuffers.length = textures.length; 20215 needsUpdate = true; 20216 } 20217 } else { 20218 if (_currentDrawBuffers.length !== 1 || _currentDrawBuffers[0] !== _gl.COLOR_ATTACHMENT0) { 20219 _currentDrawBuffers[0] = _gl.COLOR_ATTACHMENT0; 20220 _currentDrawBuffers.length = 1; 20221 needsUpdate = true; 20222 } 20223 } 20224 } else { 20225 if (_currentDrawBuffers.length !== 1 || _currentDrawBuffers[0] !== _gl.BACK) { 20226 _currentDrawBuffers[0] = _gl.BACK; 20227 _currentDrawBuffers.length = 1; 20228 needsUpdate = true; 20229 } 20230 } 20231 20232 if (needsUpdate) { 20233 if (capabilities.isWebGL2) { 20234 _gl.drawBuffers(_currentDrawBuffers); 20235 } else { 20236 extensions.get('WEBGL_draw_buffers').drawBuffersWEBGL(_currentDrawBuffers); 20237 } 20238 } 20239 } 20240 20241 state.viewport(_currentViewport); 20242 state.scissor(_currentScissor); 20243 state.setScissorTest(_currentScissorTest); 20244 20245 if (isCube) { 20246 const textureProperties = properties.get(renderTarget.texture); 20247 20248 _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + activeCubeFace, textureProperties.__webglTexture, activeMipmapLevel); 20249 } else if (isRenderTarget3D) { 20250 const textureProperties = properties.get(renderTarget.texture); 20251 const layer = activeCubeFace || 0; 20252 20253 _gl.framebufferTextureLayer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureProperties.__webglTexture, activeMipmapLevel || 0, layer); 20254 } 20255 20256 _currentMaterialId = -1; // reset current material to ensure correct uniform bindings 20257 }; 20258 20259 this.readRenderTargetPixels = function (renderTarget, x, y, width, height, buffer, activeCubeFaceIndex) { 20260 if (!(renderTarget && renderTarget.isWebGLRenderTarget)) { 20261 console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.'); 20262 return; 20263 } 20264 20265 let framebuffer = properties.get(renderTarget).__webglFramebuffer; 20266
20267 if (renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined) { 20268 framebuffer = framebuffer[activeCubeFaceIndex]; 20269 } 20270 20271 if (framebuffer) { 20272 state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); 20273 20274 try { 20275 const texture = renderTarget.texture; 20276 const textureFormat = texture.format; 20277 const textureType = texture.type; 20278 20279 if (textureFormat !== RGBAFormat && utils.convert(textureFormat) !== _gl.getParameter(_gl.IMPLEMENTATION_COLOR_READ_FORMAT)) { 20280 console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.'); 20281 return; 20282 } 20283 20284 const halfFloatSupportedByExt = textureType === HalfFloatType && (extensions.has('EXT_color_buffer_half_float') || capabilities.isWebGL2 && extensions.has('EXT_color_buffer_float')); 20285 20286 if (textureType !== UnsignedByteType && utils.convert(textureType) !== _gl.getParameter(_gl.IMPLEMENTATION_COLOR_READ_TYPE) && // Edge and Chrome Mac < 52 (#9513) 20287 !(textureType === FloatType && (capabilities.isWebGL2 || extensions.has('OES_texture_float') || extensions.has('WEBGL_color_buffer_float'))) && // Chrome Mac >= 52 and Firefox 20288 !halfFloatSupportedByExt) { 20289 console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.'); 20290 return; 20291 } 20292 20293 if (_gl.checkFramebufferStatus(_gl.FRAMEBUFFER) === _gl.FRAMEBUFFER_COMPLETE) { 20294 // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604) 20295 if (x >= 0 && x <= renderTarget.width - width && y >= 0 && y <= renderTarget.height - height) { 20296 _gl.readPixels(x, y, width, height, utils.convert(textureFormat), utils.convert(textureType), buffer); 20297 } 20298 } else { 20299 console.error('THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.'); 20300 } 20301 } finally { 20302 // restore framebuffer of current render target if necessary 20303 const framebuffer = _currentRenderTarget !== null ? properties.get(_currentRenderTarget).__webglFramebuffer : null; 20304 state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); 20305 } 20306 } 20307 }; 20308 20309 this.copyFramebufferToTexture = function (position, texture, level = 0) { 20310 if (texture.isFramebufferTexture !== true) { 20311 console.error('THREE.WebGLRenderer: copyFramebufferToTexture() can only be used with FramebufferTexture.'); 20312 return; 20313 } 20314 20315 const levelScale = Math.pow(2, -level); 20316 const width = Math.floor(texture.image.width * levelScale); 20317 const height = Math.floor(texture.image.height * levelScale); 20318 textures.setTexture2D(texture, 0); 20319 20320 _gl.copyTexSubImage2D(_gl.TEXTURE_2D, level, 0, 0, position.x, position.y, width, height); 20321 20322 state.unbindTexture(); 20323 }; 20324 20325 this.copyTextureToTexture = function (position, srcTexture, dstTexture, level = 0) { 20326 const width = srcTexture.image.width; 20327 const height = srcTexture.image.height; 20328 const glFormat = utils.convert(dstTexture.format); 20329 const glType = utils.convert(dstTexture.type); 20330 textures.setTexture2D(dstTexture, 0); // As another texture upload may have changed pixelStorei 20331 // parameters, make sure they are correct for the dstTexture 20332 20333 _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY); 20334 20335 _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha); 20336 20337 _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment); 20338 20339 if (srcTexture.isDataTexture) { 20340 _gl.texSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data); 20341 } else { 20342 if (srcTexture.isCompressedTexture) { 20343 _gl.compressedTexSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, srcTexture.mipmaps[0].width, srcTexture.mipmaps[0].height, glFormat, srcTexture.mipmaps[0].data); 20344 } else { 20345 _gl.texSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, glFormat, glType, srcTexture.image); 20346 } 20347 } // Generate mipmaps only when copying level 0 20348 20349 20350 if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(_gl.TEXTURE_2D); 20351 state.unbindTexture(); 20352 }; 20353 20354 this.copyTextureToTexture3D = function (sourceBox, position, srcTexture, dstTexture, level = 0) {
20355 if (_this.isWebGL1Renderer) { 20356 console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: can only be used with WebGL2.'); 20357 return; 20358 } 20359 20360 const width = sourceBox.max.x - sourceBox.min.x + 1; 20361 const height = sourceBox.max.y - sourceBox.min.y + 1; 20362 const depth = sourceBox.max.z - sourceBox.min.z + 1; 20363 const glFormat = utils.convert(dstTexture.format); 20364 const glType = utils.convert(dstTexture.type); 20365 let glTarget; 20366 20367 if (dstTexture.isDataTexture3D) { 20368 textures.setTexture3D(dstTexture, 0); 20369 glTarget = _gl.TEXTURE_3D; 20370 } else if (dstTexture.isDataTexture2DArray) { 20371 textures.setTexture2DArray(dstTexture, 0); 20372 glTarget = _gl.TEXTURE_2D_ARRAY; 20373 } else { 20374 console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: only supports THREE.DataTexture3D and THREE.DataTexture2DArray.'); 20375 return; 20376 } 20377 20378 _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY); 20379 20380 _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha); 20381 20382 _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment); 20383 20384 const unpackRowLen = _gl.getParameter(_gl.UNPACK_ROW_LENGTH); 20385 20386 const unpackImageHeight = _gl.getParameter(_gl.UNPACK_IMAGE_HEIGHT); 20387 20388 const unpackSkipPixels = _gl.getParameter(_gl.UNPACK_SKIP_PIXELS); 20389 20390 const unpackSkipRows = _gl.getParameter(_gl.UNPACK_SKIP_ROWS); 20391 20392 const unpackSkipImages = _gl.getParameter(_gl.UNPACK_SKIP_IMAGES); 20393 20394 const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[0] : srcTexture.image; 20395 20396 _gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, image.width); 20397 20398 _gl.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, image.height); 20399 20400 _gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, sourceBox.min.x); 20401 20402 _gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, sourceBox.min.y); 20403 20404 _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, sourceBox.min.z); 20405 20406 if (srcTexture.isDataTexture || srcTexture.isDataTexture3D) { 20407 _gl.texSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, glType, image.data); 20408 } else { 20409 if (srcTexture.isCompressedTexture) { 20410 console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: untested support for compressed srcTexture.'); 20411 20412 _gl.compressedTexSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, image.data); 20413 } else { 20414 _gl.texSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, glType, image); 20415 } 20416 } 20417 20418 _gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, unpackRowLen); 20419 20420 _gl.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, unpackImageHeight); 20421 20422 _gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, unpackSkipPixels); 20423 20424 _gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, unpackSkipRows); 20425 20426 _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, unpackSkipImages); // Generate mipmaps only when copying level 0 20427 20428 20429 if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(glTarget); 20430 state.unbindTexture(); 20431 }; 20432 20433 this.initTexture = function (texture) { 20434 textures.setTexture2D(texture, 0); 20435 state.unbindTexture(); 20436 }; 20437 20438 this.resetState = function () { 20439 _currentActiveCubeFace = 0; 20440 _currentActiveMipmapLevel = 0; 20441 _currentRenderTarget = null; 20442 state.reset(); 20443 bindingStates.reset(); 20444 }; 20445 20446 if (typeof __THREE_DEVTOOLS__ !== 'undefined') { 20447 __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', { 20448 detail: this 20449 })); 20450 } 20451 } 20452 20453 WebGLRenderer.prototype.isWebGLRenderer = true; 20454 20455 class WebGL1Renderer extends WebGLRenderer {} 20456 20457 WebGL1Renderer.prototype.isWebGL1Renderer = true; 20458 20459 class FogExp2 { 20460 constructor(color, density = 0.00025) { 20461 this.name = ''; 20462 this.color = new Color(color); 20463 this.density = density; 20464 } 20465 20466 clone() { 20467 return new FogExp2(this.color, this.density); 20468 } 20469 20470 toJSON() { 20471 return { 20472 type: 'FogExp2', 20473 color: this.color.getHex(), 20474 density: this.density 20475 }; 20476 } 20477 20478 } 20479 20480 FogExp2.prototype.isFogExp2 = true; 20481 20482 class Fog { 20483 constructor(color, near = 1, far = 1000) { 20484 this.name = ''; 20485 this.color = new Color(color); 20486 this.near = near; 20487 this.far = far; 20488 } 20489 20490 clone() { 20491 return new Fog(this.color, this.near, this.far); 20492 } 20493 20494 toJSON() { 20495 return { 20496 type: 'Fog', 20497 color: this.color.getHex(), 20498 near: this.near, 20499 far: this.far 20500 }; 20501 } 20502 20503 } 20504 20505 Fog.prototype.isFog = true; 20506 20507 class Scene extends Object3D { 20508 constructor() { 20509 super(); 20510 this.type = 'Scene'; 20511 this.background = null; 20512 this.environment = null; 20513 this.fog = null; 20514 this.overrideMaterial = null; 20515 this.autoUpdate = true; // checked by the renderer 20516 20517 if (typeof __THREE_DEVTOOLS__ !== 'undefined') { 20518 __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', { 20519 detail: this 20520 })); 20521 } 20522 } 20523 20524 copy(source, recursive) { 20525 super.copy(source, recursive); 20526 if (source.background !== null) this.background = source.background.clone(); 20527 if (source.environment !== null) this.environment = source.environment.clone();
vendor: 18,633 bytes, lines 20528-21290
20528 if (source.fog !== null) this.fog = source.fog.clone(); 20529 if (source.overrideMaterial !== null) this.overrideMaterial = source.overrideMaterial.clone(); 20530 this.autoUpdate = source.autoUpdate; 20531 this.matrixAutoUpdate = source.matrixAutoUpdate; 20532 return this; 20533 } 20534 20535 toJSON(meta) { 20536 const data = super.toJSON(meta); 20537 if (this.fog !== null) data.object.fog = this.fog.toJSON(); 20538 return data; 20539 } 20540 20541 } 20542 20543 Scene.prototype.isScene = true; 20544 20545 class InterleavedBuffer { 20546 constructor(array, stride) { 20547 this.array = array; 20548 this.stride = stride; 20549 this.count = array !== undefined ? array.length / stride : 0; 20550 this.usage = StaticDrawUsage; 20551 this.updateRange = { 20552 offset: 0, 20553 count: -1 20554 }; 20555 this.version = 0; 20556 this.uuid = generateUUID(); 20557 } 20558 20559 onUploadCallback() {} 20560 20561 set needsUpdate(value) { 20562 if (value === true) this.version++; 20563 } 20564 20565 setUsage(value) { 20566 this.usage = value; 20567 return this; 20568 } 20569 20570 copy(source) { 20571 this.array = new source.array.constructor(source.array); 20572 this.count = source.count; 20573 this.stride = source.stride; 20574 this.usage = source.usage; 20575 return this; 20576 } 20577 20578 copyAt(index1, attribute, index2) { 20579 index1 *= this.stride; 20580 index2 *= attribute.stride; 20581 20582 for (let i = 0, l = this.stride; i < l; i++) { 20583 this.array[index1 + i] = attribute.array[index2 + i]; 20584 } 20585 20586 return this; 20587 } 20588 20589 set(value, offset = 0) { 20590 this.array.set(value, offset); 20591 return this; 20592 } 20593 20594 clone(data) { 20595 if (data.arrayBuffers === undefined) { 20596 data.arrayBuffers = {}; 20597 } 20598 20599 if (this.array.buffer._uuid === undefined) { 20600 this.array.buffer._uuid = generateUUID(); 20601 } 20602 20603 if (data.arrayBuffers[this.array.buffer._uuid] === undefined) { 20604 data.arrayBuffers[this.array.buffer._uuid] = this.array.slice(0).buffer; 20605 } 20606 20607 const array = new this.array.constructor(data.arrayBuffers[this.array.buffer._uuid]); 20608 const ib = new this.constructor(array, this.stride); 20609 ib.setUsage(this.usage); 20610 return ib; 20611 } 20612 20613 onUpload(callback) { 20614 this.onUploadCallback = callback; 20615 return this; 20616 } 20617 20618 toJSON(data) { 20619 if (data.arrayBuffers === undefined) { 20620 data.arrayBuffers = {}; 20621 } // generate UUID for array buffer if necessary 20622 20623 20624 if (this.array.buffer._uuid === undefined) { 20625 this.array.buffer._uuid = generateUUID(); 20626 } 20627 20628 if (data.arrayBuffers[this.array.buffer._uuid] === undefined) { 20629 data.arrayBuffers[this.array.buffer._uuid] = Array.prototype.slice.call(new Uint32Array(this.array.buffer)); 20630 } // 20631 20632 20633 return { 20634 uuid: this.uuid, 20635 buffer: this.array.buffer._uuid, 20636 type: this.array.constructor.name, 20637 stride: this.stride 20638 }; 20639 } 20640 20641 } 20642 20643 InterleavedBuffer.prototype.isInterleavedBuffer = true; 20644 20645 const _vector$6 = /*@__PURE__*/new Vector3(); 20646 20647 class InterleavedBufferAttribute { 20648 constructor(interleavedBuffer, itemSize, offset, normalized = false) { 20649 this.name = ''; 20650 this.data = interleavedBuffer; 20651 this.itemSize = itemSize; 20652 this.offset = offset; 20653 this.normalized = normalized === true; 20654 } 20655 20656 get count() { 20657 return this.data.count; 20658 } 20659 20660 get array() { 20661 return this.data.array; 20662 } 20663 20664 set needsUpdate(value) { 20665 this.data.needsUpdate = value; 20666 } 20667 20668 applyMatrix4(m) { 20669 for (let i = 0, l = this.data.count; i < l; i++) { 20670 _vector$6.x = this.getX(i); 20671 _vector$6.y = this.getY(i); 20672 _vector$6.z = this.getZ(i); 20673 20674 _vector$6.applyMatrix4(m); 20675 20676 this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); 20677 } 20678 20679 return this; 20680 } 20681 20682 applyNormalMatrix(m) { 20683 for (let i = 0, l = this.count; i < l; i++) { 20684 _vector$6.x = this.getX(i); 20685 _vector$6.y = this.getY(i); 20686 _vector$6.z = this.getZ(i); 20687 20688 _vector$6.applyNormalMatrix(m); 20689 20690 this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); 20691 } 20692 20693 return this; 20694 } 20695 20696 transformDirection(m) { 20697 for (let i = 0, l = this.count; i < l; i++) { 20698 _vector$6.x = this.getX(i); 20699 _vector$6.y = this.getY(i); 20700 _vector$6.z = this.getZ(i); 20701 20702 _vector$6.transformDirection(m); 20703 20704 this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); 20705 } 20706 20707 return this; 20708 } 20709 20710 setX(index, x) { 20711 this.data.array[index * this.data.stride + this.offset] = x; 20712 return this; 20713 } 20714 20715 setY(index, y) { 20716 this.data.array[index * this.data.stride + this.offset + 1] = y; 20717 return this; 20718 } 20719 20720 setZ(index, z) { 20721 this.data.array[index * this.data.stride + this.offset + 2] = z; 20722 return this; 20723 } 20724 20725 setW(index, w) { 20726 this.data.array[index * this.data.stride + this.offset + 3] = w; 20727 return this; 20728 } 20729 20730 getX(index) { 20731 return this.data.array[index * this.data.stride + this.offset]; 20732 } 20733 20734 getY(index) { 20735 return this.data.array[index * this.data.stride + this.offset + 1]; 20736 } 20737 20738 getZ(index) { 20739 return this.data.array[index * this.data.stride + this.offset + 2]; 20740 } 20741 20742 getW(index) { 20743 return this.data.array[index * this.data.stride + this.offset + 3]; 20744 } 20745 20746 setXY(index, x, y) { 20747 index = index * this.data.stride + this.offset; 20748 this.data.array[index + 0] = x; 20749 this.data.array[index + 1] = y; 20750 return this; 20751 } 20752 20753 setXYZ(index, x, y, z) { 20754 index = index * this.data.stride + this.offset; 20755 this.data.array[index + 0] = x; 20756 this.data.array[index + 1] = y; 20757 this.data.array[index + 2] = z; 20758 return this; 20759 } 20760 20761 setXYZW(index, x, y, z, w) { 20762 index = index * this.data.stride + this.offset; 20763 this.data.array[index + 0] = x; 20764 this.data.array[index + 1] = y; 20765 this.data.array[index + 2] = z; 20766 this.data.array[index + 3] = w; 20767 return this; 20768 } 20769 20770 clone(data) { 20771 if (data === undefined) { 20772 console.log('THREE.InterleavedBufferAttribute.clone(): Cloning an interlaved buffer attribute will deinterleave buffer data.'); 20773 const array = []; 20774 20775 for (let i = 0; i < this.count; i++) { 20776 const index = i * this.data.stride + this.offset; 20777 20778 for (let j = 0; j < this.itemSize; j++) { 20779 array.push(this.data.array[index + j]); 20780 } 20781 } 20782 20783 return new BufferAttribute(new this.array.constructor(array), this.itemSize, this.normalized); 20784 } else { 20785 if (data.interleavedBuffers === undefined) { 20786 data.interleavedBuffers = {}; 20787 } 20788 20789 if (data.interleavedBuffers[this.data.uuid] === undefined) { 20790 data.interleavedBuffers[this.data.uuid] = this.data.clone(data); 20791 } 20792 20793 return new InterleavedBufferAttribute(data.interleavedBuffers[this.data.uuid], this.itemSize, this.offset, this.normalized); 20794 } 20795 } 20796 20797 toJSON(data) { 20798 if (data === undefined) { 20799 console.log('THREE.InterleavedBufferAttribute.toJSON(): Serializing an interlaved buffer attribute will deinterleave buffer data.'); 20800 const array = []; 20801 20802 for (let i = 0; i < this.count; i++) { 20803 const index = i * this.data.stride + this.offset; 20804 20805 for (let j = 0; j < this.itemSize; j++) { 20806 array.push(this.data.array[index + j]); 20807 } 20808 } // deinterleave data and save it as an ordinary buffer attribute for now 20809 20810 20811 return { 20812 itemSize: this.itemSize, 20813 type: this.array.constructor.name, 20814 array: array, 20815 normalized: this.normalized 20816 }; 20817 } else { 20818 // save as true interlaved attribtue 20819 if (data.interleavedBuffers === undefined) { 20820 data.interleavedBuffers = {}; 20821 } 20822 20823 if (data.interleavedBuffers[this.data.uuid] === undefined) { 20824 data.interleavedBuffers[this.data.uuid] = this.data.toJSON(data); 20825 } 20826 20827 return { 20828 isInterleavedBufferAttribute: true, 20829 itemSize: this.itemSize, 20830 data: this.data.uuid, 20831 offset: this.offset, 20832 normalized: this.normalized 20833 }; 20834 } 20835 } 20836 20837 } 20838 20839 InterleavedBufferAttribute.prototype.isInterleavedBufferAttribute = true; 20840 20841 /** 20842 * parameters = { 20843 * color: <hex>, 20844 * map: new THREE.Texture( <Image> ), 20845 * alphaMap: new THREE.Texture( <Image> ), 20846 * rotation: <float>, 20847 * sizeAttenuation: <bool> 20848 * } 20849 */ 20850 20851 class SpriteMaterial extends Material { 20852 constructor(parameters) { 20853 super(); 20854 this.type = 'SpriteMaterial'; 20855 this.color = new Color(0xffffff); 20856 this.map = null; 20857 this.alphaMap = null; 20858 this.rotation = 0; 20859 this.sizeAttenuation = true; 20860 this.transparent = true; 20861 this.setValues(parameters); 20862 } 20863 20864 copy(source) { 20865 super.copy(source); 20866 this.color.copy(source.color); 20867 this.map = source.map; 20868 this.alphaMap = source.alphaMap; 20869 this.rotation = source.rotation; 20870 this.sizeAttenuation = source.sizeAttenuation; 20871 return this; 20872 } 20873 20874 } 20875 20876 SpriteMaterial.prototype.isSpriteMaterial = true; 20877 20878 let _geometry; 20879 20880 const _intersectPoint = /*@__PURE__*/new Vector3(); 20881 20882 const _worldScale = /*@__PURE__*/new Vector3(); 20883 20884 const _mvPosition = /*@__PURE__*/new Vector3(); 20885 20886 const _alignedPosition = /*@__PURE__*/new Vector2(); 20887 20888 const _rotatedPosition = /*@__PURE__*/new Vector2(); 20889 20890 const _viewWorldMatrix = /*@__PURE__*/new Matrix4(); 20891 20892 const _vA = /*@__PURE__*/new Vector3(); 20893 20894 const _vB = /*@__PURE__*/new Vector3(); 20895 20896 const _vC = /*@__PURE__*/new Vector3(); 20897 20898 const _uvA = /*@__PURE__*/new Vector2(); 20899 20900 const _uvB = /*@__PURE__*/new Vector2(); 20901 20902 const _uvC = /*@__PURE__*/new Vector2(); 20903 20904 class Sprite extends Object3D { 20905 constructor(material) { 20906 super(); 20907 this.type = 'Sprite'; 20908 20909 if (_geometry === undefined) { 20910 _geometry = new BufferGeometry(); 20911 const float32Array = new Float32Array([-0.5, -0.5, 0, 0, 0, 0.5, -0.5, 0, 1, 0, 0.5, 0.5, 0, 1, 1, -0.5, 0.5, 0, 0, 1]); 20912 const interleavedBuffer = new InterleavedBuffer(float32Array, 5); 20913 20914 _geometry.setIndex([0, 1, 2, 0, 2, 3]); 20915 20916 _geometry.setAttribute('position', new InterleavedBufferAttribute(interleavedBuffer, 3, 0, false)); 20917 20918 _geometry.setAttribute('uv', new InterleavedBufferAttribute(interleavedBuffer, 2, 3, false)); 20919 } 20920 20921 this.geometry = _geometry; 20922 this.material = material !== undefined ? material : new SpriteMaterial(); 20923 this.center = new Vector2(0.5, 0.5); 20924 } 20925 20926 raycast(raycaster, intersects) { 20927 if (raycaster.camera === null) { 20928 console.error('THREE.Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.'); 20929 } 20930 20931 _worldScale.setFromMatrixScale(this.matrixWorld); 20932 20933 _viewWorldMatrix.copy(raycaster.camera.matrixWorld); 20934 20935 this.modelViewMatrix.multiplyMatrices(raycaster.camera.matrixWorldInverse, this.matrixWorld); 20936 20937 _mvPosition.setFromMatrixPosition(this.modelViewMatrix); 20938 20939 if (raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false) { 20940 _worldScale.multiplyScalar(-_mvPosition.z); 20941 } 20942 20943 const rotation = this.material.rotation; 20944 let sin, cos; 20945 20946 if (rotation !== 0) { 20947 cos = Math.cos(rotation); 20948 sin = Math.sin(rotation); 20949 } 20950 20951 const center = this.center; 20952 transformVertex(_vA.set(-0.5, -0.5, 0), _mvPosition, center, _worldScale, sin, cos); 20953 transformVertex(_vB.set(0.5, -0.5, 0), _mvPosition, center, _worldScale, sin, cos); 20954 transformVertex(_vC.set(0.5, 0.5, 0), _mvPosition, center, _worldScale, sin, cos); 20955 20956 _uvA.set(0, 0); 20957 20958 _uvB.set(1, 0); 20959 20960 _uvC.set(1, 1); // check first triangle 20961 20962 20963 let intersect = raycaster.ray.intersectTriangle(_vA, _vB, _vC, false, _intersectPoint); 20964 20965 if (intersect === null) { 20966 // check second triangle 20967 transformVertex(_vB.set(-0.5, 0.5, 0), _mvPosition, center, _worldScale, sin, cos); 20968 20969 _uvB.set(0, 1); 20970 20971 intersect = raycaster.ray.intersectTriangle(_vA, _vC, _vB, false, _intersectPoint); 20972 20973 if (intersect === null) { 20974 return; 20975 } 20976 } 20977 20978 const distance = raycaster.ray.origin.distanceTo(_intersectPoint); 20979 if (distance < raycaster.near || distance > raycaster.far) return; 20980 intersects.push({ 20981 distance: distance, 20982 point: _intersectPoint.clone(), 20983 uv: Triangle.getUV(_intersectPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2()), 20984 face: null, 20985 object: this 20986 }); 20987 } 20988 20989 copy(source) { 20990 super.copy(source); 20991 if (source.center !== undefined) this.center.copy(source.center); 20992 this.material = source.material; 20993 return this; 20994 } 20995 20996 } 20997 20998 Sprite.prototype.isSprite = true; 20999 21000 function transformVertex(vertexPosition, mvPosition, center, scale, sin, cos) { 21001 // compute position in camera space 21002 _alignedPosition.subVectors(vertexPosition, center).addScalar(0.5).multiply(scale); // to check if rotation is not zero 21003 21004 21005 if (sin !== undefined) { 21006 _rotatedPosition.x = cos * _alignedPosition.x - sin * _alignedPosition.y; 21007 _rotatedPosition.y = sin * _alignedPosition.x + cos * _alignedPosition.y; 21008 } else { 21009 _rotatedPosition.copy(_alignedPosition); 21010 } 21011 21012 vertexPosition.copy(mvPosition); 21013 vertexPosition.x += _rotatedPosition.x; 21014 vertexPosition.y += _rotatedPosition.y; // transform to world space 21015 21016 vertexPosition.applyMatrix4(_viewWorldMatrix); 21017 } 21018 21019 const _v1$2 = /*@__PURE__*/new Vector3(); 21020 21021 const _v2$1 = /*@__PURE__*/new Vector3(); 21022 21023 class LOD extends Object3D { 21024 constructor() { 21025 super(); 21026 this._currentLevel = 0; 21027 this.type = 'LOD'; 21028 Object.defineProperties(this, { 21029 levels: { 21030 enumerable: true, 21031 value: [] 21032 }, 21033 isLOD: { 21034 value: true 21035 } 21036 }); 21037 this.autoUpdate = true; 21038 } 21039 21040 copy(source) { 21041 super.copy(source, false); 21042 const levels = source.levels; 21043 21044 for (let i = 0, l = levels.length; i < l; i++) { 21045 const level = levels[i]; 21046 this.addLevel(level.object.clone(), level.distance); 21047 } 21048 21049 this.autoUpdate = source.autoUpdate; 21050 return this; 21051 } 21052 21053 addLevel(object, distance = 0) { 21054 distance = Math.abs(distance); 21055 const levels = this.levels; 21056 let l; 21057 21058 for (l = 0; l < levels.length; l++) { 21059 if (distance < levels[l].distance) { 21060 break; 21061 } 21062 } 21063 21064 levels.splice(l, 0, { 21065 distance: distance, 21066 object: object 21067 }); 21068 this.add(object); 21069 return this; 21070 } 21071 21072 getCurrentLevel() { 21073 return this._currentLevel; 21074 } 21075 21076 getObjectForDistance(distance) { 21077 const levels = this.levels; 21078 21079 if (levels.length > 0) { 21080 let i, l; 21081 21082 for (i = 1, l = levels.length; i < l; i++) { 21083 if (distance < levels[i].distance) { 21084 break; 21085 } 21086 } 21087 21088 return levels[i - 1].object; 21089 } 21090 21091 return null; 21092 } 21093 21094 raycast(raycaster, intersects) { 21095 const levels = this.levels; 21096 21097 if (levels.length > 0) { 21098 _v1$2.setFromMatrixPosition(this.matrixWorld); 21099 21100 const distance = raycaster.ray.origin.distanceTo(_v1$2); 21101 this.getObjectForDistance(distance).raycast(raycaster, intersects); 21102 } 21103 } 21104 21105 update(camera) { 21106 const levels = this.levels; 21107 21108 if (levels.length > 1) { 21109 _v1$2.setFromMatrixPosition(camera.matrixWorld); 21110 21111 _v2$1.setFromMatrixPosition(this.matrixWorld); 21112 21113 const distance = _v1$2.distanceTo(_v2$1) / camera.zoom; 21114 levels[0].object.visible = true; 21115 let i, l; 21116 21117 for (i = 1, l = levels.length; i < l; i++) { 21118 if (distance >= levels[i].distance) { 21119 levels[i - 1].object.visible = false; 21120 levels[i].object.visible = true; 21121 } else { 21122 break; 21123 } 21124 } 21125 21126 this._currentLevel = i - 1; 21127 21128 for (; i < l; i++) { 21129 levels[i].object.visible = false; 21130 } 21131 } 21132 } 21133 21134 toJSON(meta) { 21135 const data = super.toJSON(meta); 21136 if (this.autoUpdate === false) data.object.autoUpdate = false; 21137 data.object.levels = []; 21138 const levels = this.levels; 21139 21140 for (let i = 0, l = levels.length; i < l; i++) { 21141 const level = levels[i]; 21142 data.object.levels.push({ 21143 object: level.object.uuid, 21144 distance: level.distance 21145 }); 21146 } 21147 21148 return data; 21149 } 21150 21151 } 21152 21153 const _basePosition = /*@__PURE__*/new Vector3(); 21154 21155 const _skinIndex = /*@__PURE__*/new Vector4(); 21156 21157 const _skinWeight = /*@__PURE__*/new Vector4(); 21158 21159 const _vector$5 = /*@__PURE__*/new Vector3(); 21160 21161 const _matrix = /*@__PURE__*/new Matrix4(); 21162 21163 class SkinnedMesh extends Mesh { 21164 constructor(geometry, material) { 21165 super(geometry, material); 21166 this.type = 'SkinnedMesh'; 21167 this.bindMode = 'attached'; 21168 this.bindMatrix = new Matrix4(); 21169 this.bindMatrixInverse = new Matrix4(); 21170 } 21171 21172 copy(source) { 21173 super.copy(source); 21174 this.bindMode = source.bindMode; 21175 this.bindMatrix.copy(source.bindMatrix); 21176 this.bindMatrixInverse.copy(source.bindMatrixInverse); 21177 this.skeleton = source.skeleton; 21178 return this; 21179 } 21180 21181 bind(skeleton, bindMatrix) { 21182 this.skeleton = skeleton; 21183 21184 if (bindMatrix === undefined) { 21185 this.updateMatrixWorld(true); 21186 this.skeleton.calculateInverses(); 21187 bindMatrix = this.matrixWorld; 21188 } 21189 21190 this.bindMatrix.copy(bindMatrix); 21191 this.bindMatrixInverse.copy(bindMatrix).invert(); 21192 } 21193 21194 pose() { 21195 this.skeleton.pose(); 21196 } 21197 21198 normalizeSkinWeights() { 21199 const vector = new Vector4(); 21200 const skinWeight = this.geometry.attributes.skinWeight; 21201 21202 for (let i = 0, l = skinWeight.count; i < l; i++) { 21203 vector.x = skinWeight.getX(i); 21204 vector.y = skinWeight.getY(i); 21205 vector.z = skinWeight.getZ(i); 21206 vector.w = skinWeight.getW(i); 21207 const scale = 1.0 / vector.manhattanLength(); 21208 21209 if (scale !== Infinity) { 21210 vector.multiplyScalar(scale); 21211 } else { 21212 vector.set(1, 0, 0, 0); // do something reasonable 21213 } 21214 21215 skinWeight.setXYZW(i, vector.x, vector.y, vector.z, vector.w); 21216 } 21217 } 21218 21219 updateMatrixWorld(force) { 21220 super.updateMatrixWorld(force); 21221 21222 if (this.bindMode === 'attached') { 21223 this.bindMatrixInverse.copy(this.matrixWorld).invert(); 21224 } else if (this.bindMode === 'detached') { 21225 this.bindMatrixInverse.copy(this.bindMatrix).invert(); 21226 } else { 21227 console.warn('THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode); 21228 } 21229 } 21230 21231 boneTransform(index, target) { 21232 const skeleton = this.skeleton; 21233 const geometry = this.geometry; 21234 21235 _skinIndex.fromBufferAttribute(geometry.attributes.skinIndex, index); 21236 21237 _skinWeight.fromBufferAttribute(geometry.attributes.skinWeight, index); 21238 21239 _basePosition.copy(target).applyMatrix4(this.bindMatrix); 21240 21241 target.set(0, 0, 0); 21242 21243 for (let i = 0; i < 4; i++) { 21244 const weight = _skinWeight.getComponent(i); 21245 21246 if (weight !== 0) { 21247 const boneIndex = _skinIndex.getComponent(i); 21248 21249 _matrix.multiplyMatrices(skeleton.bones[boneIndex].matrixWorld, skeleton.boneInverses[boneIndex]); 21250 21251 target.addScaledVector(_vector$5.copy(_basePosition).applyMatrix4(_matrix), weight); 21252 } 21253 } 21254 21255 return target.applyMatrix4(this.bindMatrixInverse); 21256 } 21257 21258 } 21259 21260 SkinnedMesh.prototype.isSkinnedMesh = true; 21261 21262 class Bone extends Object3D { 21263 constructor() { 21264 super(); 21265 this.type = 'Bone'; 21266 } 21267 21268 } 21269 21270 Bone.prototype.isBone = true; 21271 21272 class DataTexture extends Texture { 21273 constructor(data = null, width = 1, height = 1, format, type, mapping, wrapS, wrapT, magFilter = NearestFilter, minFilter = NearestFilter, anisotropy, encoding) { 21274 super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding); 21275 this.image = { 21276 data: data, 21277 width: width, 21278 height: height 21279 }; 21280 this.magFilter = magFilter; 21281 this.minFilter = minFilter; 21282 this.generateMipmaps = false; 21283 this.flipY = false; 21284 this.unpackAlignment = 1; 21285 } 21286 21287 } 21288 21289 DataTexture.prototype.isDataTexture = true; 21290
vendor: 4,315 bytes, lines 21291-21447
21291 const _offsetMatrix = /*@__PURE__*/new Matrix4(); 21292 21293 const _identityMatrix = /*@__PURE__*/new Matrix4(); 21294 21295 class Skeleton { 21296 constructor(bones = [], boneInverses = []) { 21297 this.uuid = generateUUID(); 21298 this.bones = bones.slice(0); 21299 this.boneInverses = boneInverses; 21300 this.boneMatrices = null; 21301 this.boneTexture = null; 21302 this.boneTextureSize = 0; 21303 this.frame = -1; 21304 this.init(); 21305 } 21306 21307 init() { 21308 const bones = this.bones; 21309 const boneInverses = this.boneInverses; 21310 this.boneMatrices = new Float32Array(bones.length * 16); // calculate inverse bone matrices if necessary 21311 21312 if (boneInverses.length === 0) { 21313 this.calculateInverses(); 21314 } else { 21315 // handle special case 21316 if (bones.length !== boneInverses.length) { 21317 console.warn('THREE.Skeleton: Number of inverse bone matrices does not match amount of bones.'); 21318 this.boneInverses = []; 21319 21320 for (let i = 0, il = this.bones.length; i < il; i++) { 21321 this.boneInverses.push(new Matrix4()); 21322 } 21323 } 21324 } 21325 } 21326 21327 calculateInverses() { 21328 this.boneInverses.length = 0; 21329 21330 for (let i = 0, il = this.bones.length; i < il; i++) { 21331 const inverse = new Matrix4(); 21332 21333 if (this.bones[i]) { 21334 inverse.copy(this.bones[i].matrixWorld).invert(); 21335 } 21336 21337 this.boneInverses.push(inverse); 21338 } 21339 } 21340 21341 pose() { 21342 // recover the bind-time world matrices 21343 for (let i = 0, il = this.bones.length; i < il; i++) { 21344 const bone = this.bones[i]; 21345 21346 if (bone) { 21347 bone.matrixWorld.copy(this.boneInverses[i]).invert(); 21348 } 21349 } // compute the local matrices, positions, rotations and scales 21350 21351 21352 for (let i = 0, il = this.bones.length; i < il; i++) { 21353 const bone = this.bones[i]; 21354 21355 if (bone) { 21356 if (bone.parent && bone.parent.isBone) { 21357 bone.matrix.copy(bone.parent.matrixWorld).invert(); 21358 bone.matrix.multiply(bone.matrixWorld); 21359 } else { 21360 bone.matrix.copy(bone.matrixWorld); 21361 } 21362 21363 bone.matrix.decompose(bone.position, bone.quaternion, bone.scale); 21364 } 21365 } 21366 } 21367 21368 update() { 21369 const bones = this.bones; 21370 const boneInverses = this.boneInverses; 21371 const boneMatrices = this.boneMatrices; 21372 const boneTexture = this.boneTexture; // flatten bone matrices to array 21373 21374 for (let i = 0, il = bones.length; i < il; i++) { 21375 // compute the offset between the current and the original transform 21376 const matrix = bones[i] ? bones[i].matrixWorld : _identityMatrix; 21377 21378 _offsetMatrix.multiplyMatrices(matrix, boneInverses[i]); 21379 21380 _offsetMatrix.toArray(boneMatrices, i * 16); 21381 } 21382 21383 if (boneTexture !== null) { 21384 boneTexture.needsUpdate = true; 21385 } 21386 } 21387 21388 clone() { 21389 return new Skeleton(this.bones, this.boneInverses); 21390 } 21391 21392 computeBoneTexture() { 21393 // layout (1 matrix = 4 pixels) 21394 // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4) 21395 // with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8) 21396 // 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16) 21397 // 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32) 21398 // 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64) 21399 let size = Math.sqrt(this.bones.length * 4); // 4 pixels needed for 1 matrix 21400 21401 size = ceilPowerOfTwo(size); 21402 size = Math.max(size, 4); 21403 const boneMatrices = new Float32Array(size * size * 4); // 4 floats per RGBA pixel 21404 21405 boneMatrices.set(this.boneMatrices); // copy current values 21406 21407 const boneTexture = new DataTexture(boneMatrices, size, size, RGBAFormat, FloatType); 21408 boneTexture.needsUpdate = true; 21409 this.boneMatrices = boneMatrices; 21410 this.boneTexture = boneTexture; 21411 this.boneTextureSize = size; 21412 return this; 21413 } 21414 21415 getBoneByName(name) { 21416 for (let i = 0, il = this.bones.length; i < il; i++) { 21417 const bone = this.bones[i]; 21418 21419 if (bone.name === name) { 21420 return bone; 21421 } 21422 } 21423 21424 return undefined; 21425 } 21426 21427 dispose() { 21428 if (this.boneTexture !== null) { 21429 this.boneTexture.dispose(); 21430 this.boneTexture = null; 21431 } 21432 } 21433 21434 fromJSON(json, bones) { 21435 this.uuid = json.uuid; 21436 21437 for (let i = 0, l = json.bones.length; i < l; i++) { 21438 const uuid = json.bones[i]; 21439 let bone = bones[uuid]; 21440 21441 if (bone === undefined) { 21442 console.warn('THREE.Skeleton: No bone found with UUID:', uuid); 21443 bone = new Bone(); 21444 } 21445 21446 this.bones.push(bone); 21447 this.boneInverses.push(new Matrix4().fromArray(json.boneInverses[i])
21447); 21448 } 21449 21450 this.init(); 21451 return this; 21452 } 21453 21454 toJSON() { 21455 const data = { 21456 metadata: { 21457 version: 4.5, 21458 type: 'Skeleton', 21459 generator: 'Skeleton.toJSON' 21460 }, 21461 bones: [], 21462 boneInverses: [] 21463 }; 21464 data.uuid = this.uuid; 21465 const bones = this.bones; 21466 const boneInverses = this.boneInverses; 21467 21468 for (let i = 0, l = bones.length; i < l; i++) { 21469 const bone = bones[i]; 21470 data.bones.push(bone.uuid); 21471 const boneInverse = boneInverses[i]; 21472 data.boneInverses.push(boneInverse.toArray()); 21473 } 21474 21475 return data; 21476 } 21477 21478 } 21479 21480 class InstancedBufferAttribute extends BufferAttribute { 21481 constructor(array, itemSize, normalized, meshPerAttribute = 1) { 21482 if (typeof normalized === 'number') { 21483 meshPerAttribute = normalized; 21484 normalized = false; 21485 console.error('THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.'); 21486 } 21487 21488 super(array, itemSize, normalized); 21489 this.meshPerAttribute = meshPerAttribute; 21490 } 21491 21492 copy(source) { 21493 super.copy(source); 21494 this.meshPerAttribute = source.meshPerAttribute; 21495 return this; 21496 } 21497 21498 toJSON() { 21499 const data = super.toJSON(); 21500 data.meshPerAttribute = this.meshPerAttribute; 21501 data.isInstancedBufferAttribute = true; 21502 return data; 21503 } 21504 21505 } 21506 21507 InstancedBufferAttribute.prototype.isInstancedBufferAttribute = true; 21508 21509 const _instanceLocalMatrix = /*@__PURE__*/new Matrix4(); 21510 21511 const _instanceWorldMatrix = /*@__PURE__*/new Matrix4(); 21512 21513 const _instanceIntersects = []; 21514 21515 const _mesh = /*@__PURE__*/new Mesh(); 21516 21517 class InstancedMesh extends Mesh { 21518 constructor(geometry, material, count) { 21519 super(geometry, material); 21520 this.instanceMatrix = new InstancedBufferAttribute(new Float32Array(count * 16), 16); 21521 this.instanceColor = null; 21522 this.count = count; 21523 this.frustumCulled = false; 21524 } 21525 21526 copy(source) { 21527 super.copy(source); 21528 this.instanceMatrix.copy(source.instanceMatrix); 21529 if (source.instanceColor !== null) this.instanceColor = source.instanceColor.clone(); 21530 this.count = source.count; 21531 return this; 21532 } 21533 21534 getColorAt(index, color) { 21535 color.fromArray(this.instanceColor.array, index * 3); 21536 } 21537 21538 getMatrixAt(index, matrix) { 21539 matrix.fromArray(this.instanceMatrix.array, index * 16); 21540 } 21541 21542 raycast(raycaster, intersects) { 21543 const matrixWorld = this.matrixWorld; 21544 const raycastTimes = this.count; 21545 _mesh.geometry = this.geometry; 21546 _mesh.material = this.material; 21547 if (_mesh.material === undefined) return; 21548 21549 for (let instanceId = 0; instanceId < raycastTimes; instanceId++) { 21550 // calculate the world matrix for each instance 21551 this.getMatrixAt(instanceId, _instanceLocalMatrix); 21552 21553 _instanceWorldMatrix.multiplyMatrices(matrixWorld, _instanceLocalMatrix); // the mesh represents this single instance 21554 21555 21556 _mesh.matrixWorld = _instanceWorldMatrix; 21557 21558 _mesh.raycast(raycaster, _instanceIntersects); // process the result of raycast 21559 21560 21561 for (let i = 0, l = _instanceIntersects.length; i < l; i++) { 21562 const intersect = _instanceIntersects[i]; 21563 intersect.instanceId = instanceId; 21564 intersect.object = this; 21565 intersects.push(intersect); 21566 } 21567 21568 _instanceIntersects.length = 0; 21569 } 21570 } 21571 21572 setColorAt(index, color) { 21573 if (this.instanceColor === null) { 21574 this.instanceColor = new InstancedBufferAttribute(new Float32Array(this.instanceMatrix.count * 3), 3); 21575 } 21576 21577 color.toArray(this.instanceColor.array, index * 3); 21578 } 21579 21580 setMatrixAt(index, matrix) { 21581 matrix.toArray(this.instanceMatrix.array, index * 16); 21582 } 21583 21584 updateMorphTargets() {} 21585 21586 dispose() { 21587 this.dispatchEvent({ 21588 type: 'dispose' 21589 }); 21590 } 21591 21592 } 21593 21594 InstancedMesh.prototype.isInstancedMesh = true; 21595 21596 /** 21597 * parameters = { 21598 * color: <hex>, 21599 * opacity: <float>, 21600 * 21601 * linewidth: <float>, 21602 * linecap: "round", 21603 * linejoin: "round" 21604 * } 21605 */ 21606 21607 class LineBasicMaterial extends Material { 21608 constructor(parameters) { 21609 super(); 21610 this.type = 'LineBasicMaterial'; 21611 this.color = new Color(0xffffff); 21612 this.linewidth = 1; 21613 this.linecap = 'round'; 21614 this.linejoin = 'round'; 21615 this.setValues(parameters); 21616 } 21617 21618 copy(source) { 21619 super.copy(source); 21620 this.color.copy(source.color); 21621 this.linewidth = source.linewidth; 21622 this.linecap = source.linecap; 21623 this.linejoin = source.linejoin; 21624 return this; 21625 } 21626 21627 } 21628 21629 LineBasicMaterial.prototype.isLineBasicMaterial = true; 21630 21631 const _start$1 = /*@__PURE__*/new Vector3(); 21632 21633 const _end$1 = /*@__PURE__*/new Vector3(); 21634 21635 const _inverseMatrix$1 = /*@__PURE__*/new Matrix4(); 21636 21637 const _ray$1 = /*@__PURE__*/new Ray(); 21638 21639 const _sphere$1 = /*@__PURE__*/new Sphere(); 21640 21641 class Line extends Object3D { 21642 constructor(geometry = new BufferGeometry(), material = new LineBasicMaterial()) { 21643 super(); 21644 this.type = 'Line'; 21645 this.geometry = geometry; 21646 this.material = material; 21647 this.updateMorphTargets(); 21648 } 21649 21650 copy(source) { 21651 super.copy(source); 21652 this.material = source.material; 21653 this.geometry = source.geometry; 21654 return this; 21655 } 21656 21657 computeLineDistances() { 21658 const geometry = this.geometry; 21659 21660 if (geometry.isBufferGeometry) { 21661 // we assume non-indexed geometry 21662 if (geometry.index === null) { 21663 const positionAttribute = geometry.attributes.position; 21664 const lineDistances = [0]; 21665 21666 for (let i = 1, l = positionAttribute.count; i < l; i++) { 21667 _start$1.fromBufferAttribute(positionAttribute, i - 1); 21668 21669 _end$1.fromBufferAttribute(positionAttribute, i); 21670 21671 lineDistances[i] = lineDistances[i - 1]; 21672 lineDistances[i] += _start$1.distanceTo(_end$1); 21673 } 21674 21675 geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1)); 21676 } else { 21677 console.warn('THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.'); 21678 } 21679 } else if (geometry.isGeometry) {
vendor: 5,604 bytes, lines 21680-21844
21680 console.error('THREE.Line.computeLineDistances() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.'); 21681 } 21682 21683 return this; 21684 } 21685 21686 raycast(raycaster, intersects) { 21687 const geometry = this.geometry; 21688 const matrixWorld = this.matrixWorld; 21689 const threshold = raycaster.params.Line.threshold; 21690 const drawRange = geometry.drawRange; // Checking boundingSphere distance to ray 21691 21692 if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); 21693 21694 _sphere$1.copy(geometry.boundingSphere); 21695 21696 _sphere$1.applyMatrix4(matrixWorld); 21697 21698 _sphere$1.radius += threshold; 21699 if (raycaster.ray.intersectsSphere(_sphere$1) === false) return; // 21700 21701 _inverseMatrix$1.copy(matrixWorld).invert(); 21702 21703 _ray$1.copy(raycaster.ray).applyMatrix4(_inverseMatrix$1); 21704 21705 const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3); 21706 const localThresholdSq = localThreshold * localThreshold; 21707 const vStart = new Vector3(); 21708 const vEnd = new Vector3(); 21709 const interSegment = new Vector3(); 21710 const interRay = new Vector3(); 21711 const step = this.isLineSegments ? 2 : 1; 21712 21713 if (geometry.isBufferGeometry) { 21714 const index = geometry.index; 21715 const attributes = geometry.attributes; 21716 const positionAttribute = attributes.position; 21717 21718 if (index !== null) { 21719 const start = Math.max(0, drawRange.start); 21720 const end = Math.min(index.count, drawRange.start + drawRange.count); 21721 21722 for (let i = start, l = end - 1; i < l; i += step) { 21723 const a = index.getX(i); 21724 const b = index.getX(i + 1); 21725 vStart.fromBufferAttribute(positionAttribute, a); 21726 vEnd.fromBufferAttribute(positionAttribute, b); 21727 21728 const distSq = _ray$1.distanceSqToSegment(vStart, vEnd, interRay, interSegment); 21729 21730 if (distSq > localThresholdSq) continue; 21731 interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation 21732 21733 const distance = raycaster.ray.origin.distanceTo(interRay); 21734 if (distance < raycaster.near || distance > raycaster.far) continue; 21735 intersects.push({ 21736 distance: distance, 21737 // What do we want? intersection point on the ray or on the segment?? 21738 // point: raycaster.ray.at( distance ), 21739 point: interSegment.clone().applyMatrix4(this.matrixWorld), 21740 index: i, 21741 face: null, 21742 faceIndex: null, 21743 object: this 21744 }); 21745 } 21746 } else { 21747 const start = Math.max(0, drawRange.start); 21748 const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count); 21749 21750 for (let i = start, l = end - 1; i < l; i += step) { 21751 vStart.fromBufferAttribute(positionAttribute, i); 21752 vEnd.fromBufferAttribute(positionAttribute, i + 1); 21753 21754 const distSq = _ray$1.distanceSqToSegment(vStart, vEnd, interRay, interSegment); 21755 21756 if (distSq > localThresholdSq) continue; 21757 interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation 21758 21759 const distance = raycaster.ray.origin.distanceTo(interRay); 21760 if (distance < raycaster.near || distance > raycaster.far) continue; 21761 intersects.push({ 21762 distance: distance, 21763 // What do we want? intersection point on the ray or on the segment?? 21764 // point: raycaster.ray.at( distance ), 21765 point: interSegment.clone().applyMatrix4(this.matrixWorld), 21766 index: i, 21767 face: null, 21768 faceIndex: null, 21769 object: this 21770 }); 21771 } 21772 } 21773 } else if (geometry.isGeometry) { 21774 console.error('THREE.Line.raycast() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.'); 21775 } 21776 } 21777 21778 updateMorphTargets() { 21779 const geometry = this.geometry; 21780 21781 if (geometry.isBufferGeometry) { 21782 const morphAttributes = geometry.morphAttributes; 21783 const keys = Object.keys(morphAttributes); 21784 21785 if (keys.length > 0) { 21786 const morphAttribute = morphAttributes[keys[0]]; 21787 21788 if (morphAttribute !== undefined) { 21789 this.morphTargetInfluences = []; 21790 this.morphTargetDictionary = {}; 21791 21792 for (let m = 0, ml = morphAttribute.length; m < ml; m++) { 21793 const name = morphAttribute[m].name || String(m); 21794 this.morphTargetInfluences.push(0); 21795 this.morphTargetDictionary[name] = m; 21796 } 21797 } 21798 } 21799 } else { 21800 const morphTargets = geometry.morphTargets; 21801 21802 if (morphTargets !== undefined && morphTargets.length > 0) { 21803 console.error('THREE.Line.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.'); 21804 } 21805 } 21806 } 21807 21808 } 21809 21810 Line.prototype.isLine = true; 21811 21812 const _start = /*@__PURE__*/new Vector3(); 21813 21814 const _end = /*@__PURE__*/new Vector3(); 21815 21816 class LineSegments extends Line { 21817 constructor(geometry, material) { 21818 super(geometry, material); 21819 this.type = 'LineSegments'; 21820 } 21821 21822 computeLineDistances() { 21823 const geometry = this.geometry; 21824 21825 if (geometry.isBufferGeometry) { 21826 // we assume non-indexed geometry 21827 if (geometry.index === null) { 21828 const positionAttribute = geometry.attributes.position; 21829 const lineDistances = []; 21830 21831 for (let i = 0, l = positionAttribute.count; i < l; i += 2) { 21832 _start.fromBufferAttribute(positionAttribute, i); 21833 21834 _end.fromBufferAttribute(positionAttribute, i + 1); 21835 21836 lineDistances[i] = i === 0 ? 0 : lineDistances[i - 1]; 21837 lineDistances[i + 1] = lineDistances[i] + _start.distanceTo(_end); 21838 } 21839 21840 geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1)); 21841 } else { 21842 console.warn('THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.'); 21843 } 21844 } else if (geometry.isGeometry) {
21845 console.error('THREE.LineSegments.computeLineDistances() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.'); 21846 } 21847 21848 return this; 21849 } 21850 21851 } 21852 21853 LineSegments.prototype.isLineSegments = true; 21854 21855 class LineLoop extends Line { 21856 constructor(geometry, material) { 21857 super(geometry, material); 21858 this.type = 'LineLoop'; 21859 } 21860 21861 } 21862 21863 LineLoop.prototype.isLineLoop = true; 21864 21865 /** 21866 * parameters = { 21867 * color: <hex>, 21868 * opacity: <float>, 21869 * map: new THREE.Texture( <Image> ), 21870 * alphaMap: new THREE.Texture( <Image> ), 21871 * 21872 * size: <float>, 21873 * sizeAttenuation: <bool> 21874 * 21875 * } 21876 */ 21877 21878 class PointsMaterial extends Material { 21879 constructor(parameters) { 21880 super(); 21881 this.type = 'PointsMaterial'; 21882 this.color = new Color(0xffffff); 21883 this.map = null; 21884 this.alphaMap = null; 21885 this.size = 1; 21886 this.sizeAttenuation = true; 21887 this.setValues(parameters); 21888 } 21889 21890 copy(source) { 21891 super.copy(source); 21892 this.color.copy(source.color); 21893 this.map = source.map; 21894 this.alphaMap = source.alphaMap; 21895 this.size = source.size; 21896 this.sizeAttenuation = source.sizeAttenuation; 21897 return this; 21898 } 21899 21900 } 21901 21902 PointsMaterial.prototype.isPointsMaterial = true; 21903 21904 const _inverseMatrix = /*@__PURE__*/new Matrix4(); 21905 21906 const _ray = /*@__PURE__*/new Ray(); 21907 21908 const _sphere = /*@__PURE__*/new Sphere(); 21909 21910 const _position$2 = /*@__PURE__*/new Vector3(); 21911 21912 class Points extends Object3D { 21913 constructor(geometry = new BufferGeometry(), material = new PointsMaterial()) { 21914 super(); 21915 this.type = 'Points'; 21916 this.geometry = geometry; 21917 this.material = material; 21918 this.updateMorphTargets(); 21919 } 21920 21921 copy(source) { 21922 super.copy(source); 21923 this.material = source.material; 21924 this.geometry = source.geometry; 21925 return this; 21926 } 21927 21928 raycast(raycaster, intersects) { 21929 const geometry = this.geometry; 21930 const matrixWorld = this.matrixWorld; 21931 const threshold = raycaster.params.Points.threshold; 21932 const drawRange = geometry.drawRange; // Checking boundingSphere distance to ray 21933 21934 if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); 21935 21936 _sphere.copy(geometry.boundingSphere); 21937 21938 _sphere.applyMatrix4(matrixWorld); 21939 21940 _sphere.radius += threshold; 21941 if (raycaster.ray.intersectsSphere(_sphere) === false) return; // 21942 21943 _inverseMatrix.copy(matrixWorld).invert(); 21944 21945 _ray.copy(raycaster.ray).applyMatrix4(_inverseMatrix); 21946 21947 const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3); 21948 const localThresholdSq = localThreshold * localThreshold; 21949 21950 if (geometry.isBufferGeometry) { 21951 const index = geometry.index; 21952 const attributes = geometry.attributes; 21953 const positionAttribute = attributes.position; 21954 21955 if (index !== null) { 21956 const start = Math.max(0, drawRange.start); 21957 const end = Math.min(index.count, drawRange.start + drawRange.count); 21958 21959 for (let i = start, il = end; i < il; i++) { 21960 const a = index.getX(i); 21961 21962 _position$2.fromBufferAttribute(positionAttribute, a); 21963 21964 testPoint(_position$2, a, localThresholdSq, matrixWorld, raycaster, intersects, this); 21965 } 21966 } else { 21967 const start = Math.max(0, drawRange.start); 21968 const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count); 21969 21970 for (let i = start, l = end; i < l; i++) { 21971 _position$2.fromBufferAttribute(positionAttribute, i); 21972 21973 testPoint(_position$2, i, localThresholdSq, matrixWorld, raycaster, intersects, this); 21974 } 21975 } 21976 } else { 21977 console.error('THREE.Points.raycast() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.'); 21978 } 21979 } 21980 21981 updateMorphTargets() { 21982 const geometry = this.geometry; 21983 21984 if (geometry.isBufferGeometry) { 21985 const morphAttributes = geometry.morphAttributes; 21986 const keys = Object.keys(morphAttributes); 21987 21988 if (keys.length > 0) { 21989 const morphAttribute = morphAttributes[keys[0]]; 21990 21991 if (morphAttribute !== undefined) { 21992 this.morphTargetInfluences = []; 21993 this.morphTargetDictionary = {}; 21994 21995 for (let m = 0, ml = morphAttribute.length; m < ml; m++) { 21996 const name = morphAttribute[m].name || String(m); 21997 this.morphTargetInfluences.push(0); 21998 this.morphTargetDictionary[name] = m; 21999 } 22000 } 22001 } 22002 } else { 22003 const morphTargets = geometry.morphTargets; 22004 22005 if (morphTargets !== undefined && morphTargets.length > 0) { 22006 console.error('THREE.Points.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.'); 22007 } 22008 } 22009 } 22010 22011 } 22012 22013 Points.prototype.isPoints = true; 22014 22015 function testPoint(point, index, localThresholdSq, matrixWorld, raycaster, intersects, object) { 22016 const rayPointDistanceSq = _ray.distanceSqToPoint(point); 22017 22018 if (rayPointDistanceSq < localThresholdSq) { 22019 const intersectPoint = new Vector3(); 22020 22021 _ray.closestPointToPoint(point, intersectPoint); 22022 22023 intersectPoint.applyMatrix4(matrixWorld); 22024 const distance = raycaster.ray.origin.distanceTo(intersectPoint); 22025 if (distance < raycaster.near || distance > raycaster.far) return; 22026 intersects.push({ 22027 distance: distance, 22028 distanceToRay: Math.sqrt(rayPointDistanceSq), 22029 point: intersectPoint, 22030 index: index, 22031 face: null, 22032 object: object 22033 }); 22034 } 22035 } 22036 22037 class VideoTexture extends Texture { 22038 constructor(video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) { 22039 super(video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); 22040 this.format = format !== undefined ? format : RGBFormat; 22041 this.minFilter = minFilter !== undefined ? minFilter : LinearFilter;
22042 this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; 22043 this.generateMipmaps = false; 22044 const scope = this; 22045 22046 function updateVideo() { 22047 scope.needsUpdate = true; 22048 video.requestVideoFrameCallback(updateVideo); 22049 } 22050 22051 if ('requestVideoFrameCallback' in video) { 22052 video.requestVideoFrameCallback(updateVideo); 22053 } 22054 } 22055 22056 clone() { 22057 return new this.constructor(this.image).copy(this); 22058 } 22059 22060 update() { 22061 const video = this.image; 22062 const hasVideoFrameCallback = ('requestVideoFrameCallback' in video); 22063 22064 if (hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA) { 22065 this.needsUpdate = true; 22066 } 22067 } 22068 22069 } 22070 22071 VideoTexture.prototype.isVideoTexture = true; 22072 22073 class FramebufferTexture extends Texture { 22074 constructor(width, height, format) { 22075 super({ 22076 width, 22077 height 22078 }); 22079 this.format = format; 22080 this.magFilter = NearestFilter; 22081 this.minFilter = NearestFilter; 22082 this.generateMipmaps = false; 22083 this.needsUpdate = true; 22084 } 22085 22086 } 22087 22088 FramebufferTexture.prototype.isFramebufferTexture = true; 22089 22090 class CompressedTexture extends Texture { 22091 constructor(mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding) { 22092 super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding); 22093 this.image = { 22094 width: width, 22095 height: height 22096 }; 22097 this.mipmaps = mipmaps; // no flipping for cube textures 22098 // (also flipping doesn't work for compressed textures ) 22099 22100 this.flipY = false; // can't generate mipmaps for compressed textures 22101 // mips must be embedded in DDS files 22102 22103 this.generateMipmaps = false; 22104 } 22105 22106 } 22107 22108 CompressedTexture.prototype.isCompressedTexture = true; 22109 22110 class CanvasTexture extends Texture { 22111 constructor(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) { 22112 super(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); 22113 this.needsUpdate = true; 22114 } 22115 22116 } 22117 22118 CanvasTexture.prototype.isCanvasTexture = true; 22119 22120 class CircleGeometry extends BufferGeometry { 22121 constructor(radius = 1, segments = 8, thetaStart = 0, thetaLength = Math.PI * 2) { 22122 super(); 22123 this.type = 'CircleGeometry'; 22124 this.parameters = { 22125 radius: radius, 22126 segments: segments, 22127 thetaStart: thetaStart, 22128 thetaLength: thetaLength 22129 }; 22130 segments = Math.max(3, segments); // buffers 22131 22132 const indices = []; 22133 const vertices = []; 22134 const normals = []; 22135 const uvs = []; // helper variables 22136 22137 const vertex = new Vector3(); 22138 const uv = new Vector2(); // center point 22139 22140 vertices.push(0, 0, 0); 22141 normals.push(0, 0, 1); 22142 uvs.push(0.5, 0.5); 22143 22144 for (let s = 0, i = 3; s <= segments; s++, i += 3) { 22145 const segment = thetaStart + s / segments * thetaLength; // vertex 22146 22147 vertex.x = radius * Math.cos(segment); 22148 vertex.y = radius * Math.sin(segment); 22149 vertices.push(vertex.x, vertex.y, vertex.z); // normal 22150 22151 normals.push(0, 0, 1); // uvs 22152 22153 uv.x = (vertices[i] / radius + 1) / 2; 22154 uv.y = (vertices[i + 1] / radius + 1) / 2; 22155 uvs.push(uv.x, uv.y); 22156 } // indices 22157 22158 22159 for (let i = 1; i <= segments; i++) { 22160 indices.push(i, i + 1, 0); 22161 } // build geometry 22162 22163 22164 this.setIndex(indices); 22165 this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 22166 this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); 22167 this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); 22168 } 22169 22170 static fromJSON(data) { 22171 return new CircleGeometry(data.radius, data.segments, data.thetaStart, data.thetaLength); 22172 } 22173 22174 } 22175 22176 class CylinderGeometry extends BufferGeometry { 22177 constructor(radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) { 22178 super(); 22179 this.type = 'CylinderGeometry'; 22180 this.parameters = { 22181 radiusTop: radiusTop, 22182 radiusBottom: radiusBottom, 22183 height: height, 22184 radialSegments: radialSegments, 22185 heightSegments: heightSegments, 22186 openEnded: openEnded, 22187 thetaStart: thetaStart, 22188 thetaLength: thetaLength 22189 }; 22190 const scope = this; 22191 radialSegments = Math.floor(radialSegments); 22192 heightSegments = Math.floor(heightSegments); // buffers 22193 22194 const indices = []; 22195 const vertices = []; 22196 const normals = []; 22197 const uvs = []; // helper variables 22198 22199 let index = 0; 22200 const indexArray = []; 22201 const halfHeight = height / 2; 22202 let groupStart = 0; // generate geometry 22203 22204 generateTorso(); 22205 22206 if (openEnded === false) { 22207 if (radiusTop > 0) generateCap(true); 22208 if (radiusBottom > 0) generateCap(false); 22209 } // build geometry 22210 22211 22212 this.setIndex(indices); 22213 this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 22214 this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); 22215 this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); 22216 22217 function generateTorso() { 22218 const normal = new Vector3(); 22219 const vertex = new Vector3(); 22220 let groupCount = 0; // this will be used to calculate the normal 22221 22222 const slope = (radiusBottom - radiusTop) / height; // generate vertices, normals and uvs 22223 22224 for (let y = 0; y <= heightSegments; y++) { 22225 const indexRow = []; 22226 const v = y / heightSegments; // calculate the radius of the current row 22227 22228 const radius = v * (radiusBottom - radiusTop) + radiusTop; 22229 22230 for (let x = 0; x <= radialSegments; x++) { 22231 const u = x / radialSegments; 22232 const theta = u * thetaLength + thetaStart; 22233 const sinTheta = Math.sin(theta); 22234 const cosTheta = Math.cos(theta); // vertex 22235
vendor: 14,486 bytes, lines 22236-22702
22236 vertex.x = radius * sinTheta; 22237 vertex.y = -v * height + halfHeight; 22238 vertex.z = radius * cosTheta; 22239 vertices.push(vertex.x, vertex.y, vertex.z); // normal 22240 22241 normal.set(sinTheta, slope, cosTheta).normalize(); 22242 normals.push(normal.x, normal.y, normal.z); // uv 22243 22244 uvs.push(u, 1 - v); // save index of vertex in respective row 22245 22246 indexRow.push(index++); 22247 } // now save vertices of the row in our index array 22248 22249 22250 indexArray.push(indexRow); 22251 } // generate indices 22252 22253 22254 for (let x = 0; x < radialSegments; x++) { 22255 for (let y = 0; y < heightSegments; y++) { 22256 // we use the index array to access the correct indices 22257 const a = indexArray[y][x]; 22258 const b = indexArray[y + 1][x]; 22259 const c = indexArray[y + 1][x + 1]; 22260 const d = indexArray[y][x + 1]; // faces 22261 22262 indices.push(a, b, d); 22263 indices.push(b, c, d); // update group counter 22264 22265 groupCount += 6; 22266 } 22267 } // add a group to the geometry. this will ensure multi material support 22268 22269 22270 scope.addGroup(groupStart, groupCount, 0); // calculate new start value for groups 22271 22272 groupStart += groupCount; 22273 } 22274 22275 function generateCap(top) { 22276 // save the index of the first center vertex 22277 const centerIndexStart = index; 22278 const uv = new Vector2(); 22279 const vertex = new Vector3(); 22280 let groupCount = 0; 22281 const radius = top === true ? radiusTop : radiusBottom; 22282 const sign = top === true ? 1 : -1; // first we generate the center vertex data of the cap. 22283 // because the geometry needs one set of uvs per face, 22284 // we must generate a center vertex per face/segment 22285 22286 for (let x = 1; x <= radialSegments; x++) { 22287 // vertex 22288 vertices.push(0, halfHeight * sign, 0); // normal 22289 22290 normals.push(0, sign, 0); // uv 22291 22292 uvs.push(0.5, 0.5); // increase index 22293 22294 index++; 22295 } // save the index of the last center vertex 22296 22297 22298 const centerIndexEnd = index; // now we generate the surrounding vertices, normals and uvs 22299 22300 for (let x = 0; x <= radialSegments; x++) { 22301 const u = x / radialSegments; 22302 const theta = u * thetaLength + thetaStart; 22303 const cosTheta = Math.cos(theta); 22304 const sinTheta = Math.sin(theta); // vertex 22305 22306 vertex.x = radius * sinTheta; 22307 vertex.y = halfHeight * sign; 22308 vertex.z = radius * cosTheta; 22309 vertices.push(vertex.x, vertex.y, vertex.z); // normal 22310 22311 normals.push(0, sign, 0); // uv 22312 22313 uv.x = cosTheta * 0.5 + 0.5; 22314 uv.y = sinTheta * 0.5 * sign + 0.5; 22315 uvs.push(uv.x, uv.y); // increase index 22316 22317 index++; 22318 } // generate indices 22319 22320 22321 for (let x = 0; x < radialSegments; x++) { 22322 const c = centerIndexStart + x; 22323 const i = centerIndexEnd + x; 22324 22325 if (top === true) { 22326 // face top 22327 indices.push(i, i + 1, c); 22328 } else { 22329 // face bottom 22330 indices.push(i + 1, i, c); 22331 } 22332 22333 groupCount += 3; 22334 } // add a group to the geometry. this will ensure multi material support 22335 22336 22337 scope.addGroup(groupStart, groupCount, top === true ? 1 : 2); // calculate new start value for groups 22338 22339 groupStart += groupCount; 22340 } 22341 } 22342 22343 static fromJSON(data) { 22344 return new CylinderGeometry(data.radiusTop, data.radiusBottom, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); 22345 } 22346 22347 } 22348 22349 class ConeGeometry extends CylinderGeometry { 22350 constructor(radius = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) { 22351 super(0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength); 22352 this.type = 'ConeGeometry'; 22353 this.parameters = { 22354 radius: radius, 22355 height: height, 22356 radialSegments: radialSegments, 22357 heightSegments: heightSegments, 22358 openEnded: openEnded, 22359 thetaStart: thetaStart, 22360 thetaLength: thetaLength 22361 }; 22362 } 22363 22364 static fromJSON(data) { 22365 return new ConeGeometry(data.radius, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); 22366 } 22367 22368 } 22369 22370 class PolyhedronGeometry extends BufferGeometry { 22371 constructor(vertices = [], indices = [], radius = 1, detail = 0) { 22372 super(); 22373 this.type = 'PolyhedronGeometry'; 22374 this.parameters = { 22375 vertices: vertices, 22376 indices: indices, 22377 radius: radius, 22378 detail: detail 22379 }; // default buffer data 22380 22381 const vertexBuffer = []; 22382 const uvBuffer = []; // the subdivision creates the vertex buffer data 22383 22384 subdivide(detail); // all vertices should lie on a conceptual sphere with a given radius 22385 22386 applyRadius(radius); // finally, create the uv data 22387 22388 generateUVs(); // build non-indexed geometry 22389 22390 this.setAttribute('position', new Float32BufferAttribute(vertexBuffer, 3)); 22391 this.setAttribute('normal', new Float32BufferAttribute(vertexBuffer.slice(), 3)); 22392 this.setAttribute('uv', new Float32BufferAttribute(uvBuffer, 2)); 22393 22394 if (detail === 0) { 22395 this.computeVertexNormals(); // flat normals 22396 } else { 22397 this.normalizeNormals(); // smooth normals 22398 } // helper functions 22399 22400 22401 function subdivide(detail) { 22402 const a = new Vector3(); 22403 const b = new Vector3(); 22404 const c = new Vector3(); // iterate over all faces and apply a subdivison with the given detail value 22405 22406 for (let i = 0; i < indices.length; i += 3) { 22407 // get the vertices of the face 22408 getVertexByIndex(indices[i + 0], a); 22409 getVertexByIndex(indices[i + 1], b); 22410 getVertexByIndex(indices[i + 2], c); // perform subdivision 22411 22412 subdivideFace(a, b, c, detail); 22413 } 22414 } 22415 22416 function subdivideFace(a, b, c, detail) { 22417 const cols = detail + 1; // we use this multidimensional array as a data structure for creating the subdivision 22418 22419 const v = []; // construct all of the vertices for this subdivision 22420 22421 for (let i = 0; i <= cols; i++) { 22422 v[i] = []; 22423 const aj = a.clone().lerp(c, i / cols); 22424 const bj = b.clone().lerp(c, i / cols); 22425 const rows = cols - i; 22426 22427 for (let j = 0; j <= rows; j++) { 22428 if (j === 0 && i === cols) { 22429 v[i][j] = aj; 22430 } else { 22431 v[i][j] = aj.clone().lerp(bj, j / rows); 22432 } 22433 } 22434 } // construct all of the faces 22435 22436 22437 for (let i = 0; i < cols; i++) { 22438 for (let j = 0; j < 2 * (cols - i) - 1; j++) { 22439 const k = Math.floor(j / 2); 22440 22441 if (j % 2 === 0) { 22442 pushVertex(v[i][k + 1]); 22443 pushVertex(v[i + 1][k]); 22444 pushVertex(v[i][k]); 22445 } else { 22446 pushVertex(v[i][k + 1]); 22447 pushVertex(v[i + 1][k + 1]); 22448 pushVertex(v[i + 1][k]); 22449 } 22450 } 22451 } 22452 } 22453 22454 function applyRadius(radius) { 22455 const vertex = new Vector3(); // iterate over the entire buffer and apply the radius to each vertex 22456 22457 for (let i = 0; i < vertexBuffer.length; i += 3) { 22458 vertex.x = vertexBuffer[i + 0]; 22459 vertex.y = vertexBuffer[i + 1]; 22460 vertex.z = vertexBuffer[i + 2]; 22461 vertex.normalize().multiplyScalar(radius); 22462 vertexBuffer[i + 0] = vertex.x; 22463 vertexBuffer[i + 1] = vertex.y; 22464 vertexBuffer[i + 2] = vertex.z; 22465 } 22466 } 22467 22468 function generateUVs() { 22469 const vertex = new Vector3(); 22470 22471 for (let i = 0; i < vertexBuffer.length; i += 3) { 22472 vertex.x = vertexBuffer[i + 0]; 22473 vertex.y = vertexBuffer[i + 1]; 22474 vertex.z = vertexBuffer[i + 2]; 22475 const u = azimuth(vertex) / 2 / Math.PI + 0.5; 22476 const v = inclination(vertex) / Math.PI + 0.5; 22477 uvBuffer.push(u, 1 - v); 22478 } 22479 22480 correctUVs(); 22481 correctSeam(); 22482 } 22483 22484 function correctSeam() { 22485 // handle case when face straddles the seam, see #3269 22486 for (let i = 0; i < uvBuffer.length; i += 6) { 22487 // uv data of a single face 22488 const x0 = uvBuffer[i + 0]; 22489 const x1 = uvBuffer[i + 2]; 22490 const x2 = uvBuffer[i + 4]; 22491 const max = Math.max(x0, x1, x2); 22492 const min = Math.min(x0, x1, x2); // 0.9 is somewhat arbitrary 22493 22494 if (max > 0.9 && min < 0.1) { 22495 if (x0 < 0.2) uvBuffer[i + 0] += 1; 22496 if (x1 < 0.2) uvBuffer[i + 2] += 1; 22497 if (x2 < 0.2) uvBuffer[i + 4] += 1; 22498 } 22499 } 22500 } 22501 22502 function pushVertex(vertex) { 22503 vertexBuffer.push(vertex.x, vertex.y, vertex.z); 22504 } 22505 22506 function getVertexByIndex(index, vertex) { 22507 const stride = index * 3; 22508 vertex.x = vertices[stride + 0]; 22509 vertex.y = vertices[stride + 1]; 22510 vertex.z = vertices[stride + 2]; 22511 } 22512 22513 function correctUVs() { 22514 const a = new Vector3(); 22515 const b = new Vector3(); 22516 const c = new Vector3(); 22517 const centroid = new Vector3(); 22518 const uvA = new Vector2(); 22519 const uvB = new Vector2(); 22520 const uvC = new Vector2(); 22521 22522 for (let i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6) { 22523 a.set(vertexBuffer[i + 0], vertexBuffer[i + 1], vertexBuffer[i + 2]); 22524 b.set(vertexBuffer[i + 3], vertexBuffer[i + 4], vertexBuffer[i + 5]); 22525 c.set(vertexBuffer[i + 6], vertexBuffer[i + 7], vertexBuffer[i + 8]); 22526 uvA.set(uvBuffer[j + 0], uvBuffer[j + 1]); 22527 uvB.set(uvBuffer[j + 2], uvBuffer[j + 3]); 22528 uvC.set(uvBuffer[j + 4], uvBuffer[j + 5]); 22529 centroid.copy(a).add(b).add(c).divideScalar(3); 22530 const azi = azimuth(centroid); 22531 correctUV(uvA, j + 0, a, azi); 22532 correctUV(uvB, j + 2, b, azi); 22533 correctUV(uvC, j + 4, c, azi); 22534 } 22535 } 22536 22537 function correctUV(uv, stride, vector, azimuth) { 22538 if (azimuth < 0 && uv.x === 1) { 22539 uvBuffer[stride] = uv.x - 1; 22540 } 22541 22542 if (vector.x === 0 && vector.z === 0) { 22543 uvBuffer[stride] = azimuth / 2 / Math.PI + 0.5; 22544 } 22545 } // Angle around the Y axis, counter-clockwise when looking from above. 22546 22547 22548 function azimuth(vector) { 22549 return Math.atan2(vector.z, -vector.x); 22550 } // Angle above the XZ plane. 22551 22552 22553 function inclination(vector) { 22554 return Math.atan2(-vector.y, Math.sqrt(vector.x * vector.x + vector.z * vector.z)); 22555 } 22556 } 22557 22558 static fromJSON(data) { 22559 return new PolyhedronGeometry(data.vertices, data.indices, data.radius, data.details); 22560 } 22561 22562 } 22563 22564 class DodecahedronGeometry extends PolyhedronGeometry { 22565 constructor(radius = 1, detail = 0) { 22566 const t = (1 + Math.sqrt(5)) / 2; 22567 const r = 1 / t; 22568 const vertices = [// (±1, ±1, ±1) 22569 -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, // (0, ±1/Ï, ±Ï) 22570 0, -r, -t, 0, -r, t, 0, r, -t, 0, r, t, // (±1/Ï, ±Ï, 0) 22571 -r, -t, 0, -r, t, 0, r, -t, 0, r, t, 0, // (±Ï, 0, ±1/Ï) 22572 -t, 0, -r, t, 0, -r, -t, 0, r, t, 0, r]; 22573 const indices = [3, 11, 7, 3, 7, 15, 3, 15, 13, 7, 19, 17, 7, 17, 6, 7, 6, 15, 17, 4, 8, 17, 8, 10, 17, 10, 6, 8, 0, 16, 8, 16, 2, 8, 2, 10, 0, 12, 1, 0, 1, 18, 0, 18, 16, 6, 10, 2, 6, 2, 13, 6, 13, 15, 2, 16, 18, 2, 18, 3, 2, 3, 13, 18, 1, 9, 18, 9, 11, 18, 11, 3, 4, 14, 12, 4, 12, 0, 4, 0, 8, 11, 9, 5, 11, 5, 19, 11, 19, 7, 19, 5, 14, 19, 14, 4, 19, 4, 17, 1, 12, 14, 1, 14, 5, 1, 5, 9]; 22574 super(vertices, indices, radius, detail); 22575 this.type = 'DodecahedronGeometry'; 22576 this.parameters = { 22577 radius: radius, 22578 detail: detail 22579 }; 22580 } 22581 22582 static fromJSON(data) { 22583 return new DodecahedronGeometry(data.radius, data.detail); 22584 } 22585 22586 } 22587 22588 const _v0 = new Vector3(); 22589 22590 const _v1$1 = new Vector3(); 22591 22592 const _normal = new Vector3(); 22593 22594 const _triangle = new Triangle(); 22595 22596 class EdgesGeometry extends BufferGeometry { 22597 constructor(geometry = null, thresholdAngle = 1) { 22598 super(); 22599 this.type = 'EdgesGeometry'; 22600 this.parameters = { 22601 geometry: geometry, 22602 thresholdAngle: thresholdAngle 22603 }; 22604 22605 if (geometry !== null) { 22606 const precisionPoints = 4; 22607 const precision = Math.pow(10, precisionPoints); 22608 const thresholdDot = Math.cos(DEG2RAD * thresholdAngle); 22609 const indexAttr = geometry.getIndex(); 22610 const positionAttr = geometry.getAttribute('position'); 22611 const indexCount = indexAttr ? indexAttr.count : positionAttr.count; 22612 const indexArr = [0, 0, 0]; 22613 const vertKeys = ['a', 'b', 'c']; 22614 const hashes = new Array(3); 22615 const edgeData = {}; 22616 const vertices = []; 22617 22618 for (let i = 0; i < indexCount; i += 3) { 22619 if (indexAttr) { 22620 indexArr[0] = indexAttr.getX(i); 22621 indexArr[1] = indexAttr.getX(i + 1); 22622 indexArr[2] = indexAttr.getX(i + 2); 22623 } else { 22624 indexArr[0] = i; 22625 indexArr[1] = i + 1; 22626 indexArr[2] = i + 2; 22627 } 22628 22629 const { 22630 a, 22631 b, 22632 c 22633 } = _triangle; 22634 a.fromBufferAttribute(positionAttr, indexArr[0]); 22635 b.fromBufferAttribute(positionAttr, indexArr[1]); 22636 c.fromBufferAttribute(positionAttr, indexArr[2]); 22637 22638 _triangle.getNormal(_normal); // create hashes for the edge from the vertices 22639 22640 22641 hashes[0] = `${Math.round(a.x * precision)},${Math.round(a.y * precision)},${Math.round(a.z * precision)}`; 22642 hashes[1] = `${Math.round(b.x * precision)},${Math.round(b.y * precision)},${Math.round(b.z * precision)}`; 22643 hashes[2] = `${Math.round(c.x * precision)},${Math.round(c.y * precision)},${Math.round(c.z * precision)}`; // skip degenerate triangles 22644 22645 if (hashes[0] === hashes[1] || hashes[1] === hashes[2] || hashes[2] === hashes[0]) { 22646 continue; 22647 } // iterate over every edge 22648 22649 22650 for (let j = 0; j < 3; j++) { 22651 // get the first and next vertex making up the edge 22652 const jNext = (j + 1) % 3; 22653 const vecHash0 = hashes[j]; 22654 const vecHash1 = hashes[jNext]; 22655 const v0 = _triangle[vertKeys[j]]; 22656 const v1 = _triangle[vertKeys[jNext]]; 22657 const hash = `${vecHash0}_${vecHash1}`; 22658 const reverseHash = `${vecHash1}_${vecHash0}`; 22659 22660 if (reverseHash in edgeData && edgeData[reverseHash]) { 22661 // if we found a sibling edge add it into the vertex array if 22662 // it meets the angle threshold and delete the edge from the map. 22663 if (_normal.dot(edgeData[reverseHash].normal) <= thresholdDot) { 22664 vertices.push(v0.x, v0.y, v0.z); 22665 vertices.push(v1.x, v1.y, v1.z); 22666 } 22667 22668 edgeData[reverseHash] = null; 22669 } else if (!(hash in edgeData)) { 22670 // if we've already got an edge here then skip adding a new one 22671 edgeData[hash] = { 22672 index0: indexArr[j], 22673 index1: indexArr[jNext], 22674 normal: _normal.clone() 22675 }; 22676 } 22677 } 22678 } // iterate over all remaining, unmatched edges and add them to the vertex array 22679 22680 22681 for (const key in edgeData) { 22682 if (edgeData[key]) { 22683 const { 22684 index0, 22685 index1 22686 } = edgeData[key]; 22687 22688 _v0.fromBufferAttribute(positionAttr, index0); 22689 22690 _v1$1.fromBufferAttribute(positionAttr, index1); 22691 22692 vertices.push(_v0.x, _v0.y, _v0.z); 22693 vertices.push(_v1$1.x, _v1$1.y, _v1$1.z); 22694 } 22695 } 22696 22697 this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 22698 } 22699 } 22700 22701 } 22702
vendor: 4,783 bytes, lines 22703-22883
22703 /** 22704 * Extensible curve object. 22705 * 22706 * Some common of curve methods: 22707 * .getPoint( t, optionalTarget ), .getTangent( t, optionalTarget ) 22708 * .getPointAt( u, optionalTarget ), .getTangentAt( u, optionalTarget ) 22709 * .getPoints(), .getSpacedPoints() 22710 * .getLength() 22711 * .updateArcLengths() 22712 * 22713 * This following curves inherit from THREE.Curve: 22714 * 22715 * -- 2D curves -- 22716 * THREE.ArcCurve 22717 * THREE.CubicBezierCurve 22718 * THREE.EllipseCurve 22719 * THREE.LineCurve 22720 * THREE.QuadraticBezierCurve 22721 * THREE.SplineCurve 22722 * 22723 * -- 3D curves -- 22724 * THREE.CatmullRomCurve3 22725 * THREE.CubicBezierCurve3 22726 * THREE.LineCurve3 22727 * THREE.QuadraticBezierCurve3 22728 * 22729 * A series of curves can be represented as a THREE.CurvePath. 22730 * 22731 **/ 22732 22733 class Curve { 22734 constructor() { 22735 this.type = 'Curve'; 22736 this.arcLengthDivisions = 200; 22737 } // Virtual base class method to overwrite and implement in subclasses 22738 // - t [0 .. 1] 22739 22740 22741 getPoint() { 22742 console.warn('THREE.Curve: .getPoint() not implemented.'); 22743 return null; 22744 } // Get point at relative position in curve according to arc length 22745 // - u [0 .. 1] 22746 22747 22748 getPointAt(u, optionalTarget) { 22749 const t = this.getUtoTmapping(u); 22750 return this.getPoint(t, optionalTarget); 22751 } // Get sequence of points using getPoint( t ) 22752 22753 22754 getPoints(divisions = 5) { 22755 const points = []; 22756 22757 for (let d = 0; d <= divisions; d++) { 22758 points.push(this.getPoint(d / divisions)); 22759 } 22760 22761 return points; 22762 } // Get sequence of points using getPointAt( u ) 22763 22764 22765 getSpacedPoints(divisions = 5) { 22766 const points = []; 22767 22768 for (let d = 0; d <= divisions; d++) { 22769 points.push(this.getPointAt(d / divisions)); 22770 } 22771 22772 return points; 22773 } // Get total curve arc length 22774 22775 22776 getLength() { 22777 const lengths = this.getLengths(); 22778 return lengths[lengths.length - 1]; 22779 } // Get list of cumulative segment lengths 22780 22781 22782 getLengths(divisions = this.arcLengthDivisions) { 22783 if (this.cacheArcLengths && this.cacheArcLengths.length === divisions + 1 && !this.needsUpdate) { 22784 return this.cacheArcLengths; 22785 } 22786 22787 this.needsUpdate = false; 22788 const cache = []; 22789 let current, 22790 last = this.getPoint(0); 22791 let sum = 0; 22792 cache.push(0); 22793 22794 for (let p = 1; p <= divisions; p++) { 22795 current = this.getPoint(p / divisions); 22796 sum += current.distanceTo(last); 22797 cache.push(sum); 22798 last = current; 22799 } 22800 22801 this.cacheArcLengths = cache; 22802 return cache; // { sums: cache, sum: sum }; Sum is in the last element. 22803 } 22804 22805 updateArcLengths() { 22806 this.needsUpdate = true; 22807 this.getLengths(); 22808 } // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant 22809 22810 22811 getUtoTmapping(u, distance) { 22812 const arcLengths = this.getLengths(); 22813 let i = 0; 22814 const il = arcLengths.length; 22815 let targetArcLength; // The targeted u distance value to get 22816 22817 if (distance) { 22818 targetArcLength = distance; 22819 } else { 22820 targetArcLength = u * arcLengths[il - 1]; 22821 } // binary search for the index with largest value smaller than target u distance 22822 22823 22824 let low = 0, 22825 high = il - 1, 22826 comparison; 22827 22828 while (low <= high) { 22829 i = Math.floor(low + (high - low) / 2); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats 22830 22831 comparison = arcLengths[i] - targetArcLength; 22832 22833 if (comparison < 0) { 22834 low = i + 1; 22835 } else if (comparison > 0) { 22836 high = i - 1; 22837 } else { 22838 high = i; 22839 break; // DONE 22840 } 22841 } 22842 22843 i = high; 22844 22845 if (arcLengths[i] === targetArcLength) { 22846 return i / (il - 1); 22847 } // we could get finer grain at lengths, or use simple interpolation between two points 22848 22849 22850 const lengthBefore = arcLengths[i]; 22851 const lengthAfter = arcLengths[i + 1]; 22852 const segmentLength = lengthAfter - lengthBefore; // determine where we are between the 'before' and 'after' points 22853 22854 const segmentFraction = (targetArcLength - lengthBefore) / segmentLength; // add that fractional amount to t 22855 22856 const t = (i + segmentFraction) / (il - 1); 22857 return t; 22858 } // Returns a unit vector tangent at t 22859 // In case any sub curve does not implement its tangent derivation, 22860 // 2 points a small delta apart will be used to find its gradient 22861 // which seems to give a reasonable approximation 22862 22863 22864 getTangent(t, optionalTarget) { 22865 const delta = 0.0001; 22866 let t1 = t - delta; 22867 let t2 = t + delta; // Capping in case of danger 22868 22869 if (t1 < 0) t1 = 0; 22870 if (t2 > 1) t2 = 1; 22871 const pt1 = this.getPoint(t1); 22872 const pt2 = this.getPoint(t2); 22873 const tangent = optionalTarget || (pt1.isVector2 ? new Vector2() : new Vector3()); 22874 tangent.copy(pt2).sub(pt1).normalize(); 22875 return tangent; 22876 } 22877 22878 getTangentAt(u, optionalTarget) { 22879 const t = this.getUtoTmapping(u); 22880 return this.getTangent(t, optionalTarget); 22881 } 22882 22883 computeFrenetFrames(segments, closed) {
vendor: 4,578 bytes, lines 22884-23053
22884 // see http://www.cs.indiana.edu/pub/techreports/TR425.pdf 22885 const normal = new Vector3(); 22886 const tangents = []; 22887 const normals = []; 22888 const binormals = []; 22889 const vec = new Vector3(); 22890 const mat = new Matrix4(); // compute the tangent vectors for each segment on the curve 22891 22892 for (let i = 0; i <= segments; i++) { 22893 const u = i / segments; 22894 tangents[i] = this.getTangentAt(u, new Vector3()); 22895 } // select an initial normal vector perpendicular to the first tangent vector, 22896 // and in the direction of the minimum tangent xyz component 22897 22898 22899 normals[0] = new Vector3(); 22900 binormals[0] = new Vector3(); 22901 let min = Number.MAX_VALUE; 22902 const tx = Math.abs(tangents[0].x); 22903 const ty = Math.abs(tangents[0].y); 22904 const tz = Math.abs(tangents[0].z); 22905 22906 if (tx <= min) { 22907 min = tx; 22908 normal.set(1, 0, 0); 22909 } 22910 22911 if (ty <= min) { 22912 min = ty; 22913 normal.set(0, 1, 0); 22914 } 22915 22916 if (tz <= min) { 22917 normal.set(0, 0, 1); 22918 } 22919 22920 vec.crossVectors(tangents[0], normal).normalize(); 22921 normals[0].crossVectors(tangents[0], vec); 22922 binormals[0].crossVectors(tangents[0], normals[0]); // compute the slowly-varying normal and binormal vectors for each segment on the curve 22923 22924 for (let i = 1; i <= segments; i++) { 22925 normals[i] = normals[i - 1].clone(); 22926 binormals[i] = binormals[i - 1].clone(); 22927 vec.crossVectors(tangents[i - 1], tangents[i]); 22928 22929 if (vec.length() > Number.EPSILON) { 22930 vec.normalize(); 22931 const theta = Math.acos(clamp(tangents[i - 1].dot(tangents[i]), -1, 1)); // clamp for floating pt errors 22932 22933 normals[i].applyMatrix4(mat.makeRotationAxis(vec, theta)); 22934 } 22935 22936 binormals[i].crossVectors(tangents[i], normals[i]); 22937 } // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same 22938 22939 22940 if (closed === true) { 22941 let theta = Math.acos(clamp(normals[0].dot(normals[segments]), -1, 1)); 22942 theta /= segments; 22943 22944 if (tangents[0].dot(vec.crossVectors(normals[0], normals[segments])) > 0) { 22945 theta = -theta; 22946 } 22947 22948 for (let i = 1; i <= segments; i++) { 22949 // twist a little... 22950 normals[i].applyMatrix4(mat.makeRotationAxis(tangents[i], theta * i)); 22951 binormals[i].crossVectors(tangents[i], normals[i]); 22952 } 22953 } 22954 22955 return { 22956 tangents: tangents, 22957 normals: normals, 22958 binormals: binormals 22959 }; 22960 } 22961 22962 clone() { 22963 return new this.constructor().copy(this); 22964 } 22965 22966 copy(source) { 22967 this.arcLengthDivisions = source.arcLengthDivisions; 22968 return this; 22969 } 22970 22971 toJSON() { 22972 const data = { 22973 metadata: { 22974 version: 4.5, 22975 type: 'Curve', 22976 generator: 'Curve.toJSON' 22977 } 22978 }; 22979 data.arcLengthDivisions = this.arcLengthDivisions; 22980 data.type = this.type; 22981 return data; 22982 } 22983 22984 fromJSON(json) { 22985 this.arcLengthDivisions = json.arcLengthDivisions; 22986 return this; 22987 } 22988 22989 } 22990 22991 class EllipseCurve extends Curve { 22992 constructor(aX = 0, aY = 0, xRadius = 1, yRadius = 1, aStartAngle = 0, aEndAngle = Math.PI * 2, aClockwise = false, aRotation = 0) { 22993 super(); 22994 this.type = 'EllipseCurve'; 22995 this.aX = aX; 22996 this.aY = aY; 22997 this.xRadius = xRadius; 22998 this.yRadius = yRadius; 22999 this.aStartAngle = aStartAngle; 23000 this.aEndAngle = aEndAngle; 23001 this.aClockwise = aClockwise; 23002 this.aRotation = aRotation; 23003 } 23004 23005 getPoint(t, optionalTarget) { 23006 const point = optionalTarget || new Vector2(); 23007 const twoPi = Math.PI * 2; 23008 let deltaAngle = this.aEndAngle - this.aStartAngle; 23009 const samePoints = Math.abs(deltaAngle) < Number.EPSILON; // ensures that deltaAngle is 0 .. 2 PI 23010 23011 while (deltaAngle < 0) deltaAngle += twoPi; 23012 23013 while (deltaAngle > twoPi) deltaAngle -= twoPi; 23014 23015 if (deltaAngle < Number.EPSILON) { 23016 if (samePoints) { 23017 deltaAngle = 0; 23018 } else { 23019 deltaAngle = twoPi; 23020 } 23021 } 23022 23023 if (this.aClockwise === true && !samePoints) { 23024 if (deltaAngle === twoPi) { 23025 deltaAngle = -twoPi; 23026 } else { 23027 deltaAngle = deltaAngle - twoPi; 23028 } 23029 } 23030 23031 const angle = this.aStartAngle + t * deltaAngle; 23032 let x = this.aX + this.xRadius * Math.cos(angle); 23033 let y = this.aY + this.yRadius * Math.sin(angle); 23034 23035 if (this.aRotation !== 0) { 23036 const cos = Math.cos(this.aRotation); 23037 const sin = Math.sin(this.aRotation); 23038 const tx = x - this.aX; 23039 const ty = y - this.aY; // Rotate the point about the center of the ellipse. 23040 23041 x = tx * cos - ty * sin + this.aX; 23042 y = tx * sin + ty * cos + this.aY; 23043 } 23044 23045 return point.set(x, y); 23046 } 23047 23048 copy(source) { 23049 super.copy(source); 23050 this.aX = source.aX; 23051 this.aY = source.aY; 23052 this.xRadius = source.xRadius; 23053 this.yRadius = source.yRadius;
vendor: 7,926 bytes, lines 23054-23354
23054 this.aStartAngle = source.aStartAngle; 23055 this.aEndAngle = source.aEndAngle; 23056 this.aClockwise = source.aClockwise; 23057 this.aRotation = source.aRotation; 23058 return this; 23059 } 23060 23061 toJSON() { 23062 const data = super.toJSON(); 23063 data.aX = this.aX; 23064 data.aY = this.aY; 23065 data.xRadius = this.xRadius; 23066 data.yRadius = this.yRadius; 23067 data.aStartAngle = this.aStartAngle; 23068 data.aEndAngle = this.aEndAngle; 23069 data.aClockwise = this.aClockwise; 23070 data.aRotation = this.aRotation; 23071 return data; 23072 } 23073 23074 fromJSON(json) { 23075 super.fromJSON(json); 23076 this.aX = json.aX; 23077 this.aY = json.aY; 23078 this.xRadius = json.xRadius; 23079 this.yRadius = json.yRadius; 23080 this.aStartAngle = json.aStartAngle; 23081 this.aEndAngle = json.aEndAngle; 23082 this.aClockwise = json.aClockwise; 23083 this.aRotation = json.aRotation; 23084 return this; 23085 } 23086 23087 } 23088 23089 EllipseCurve.prototype.isEllipseCurve = true; 23090 23091 class ArcCurve extends EllipseCurve { 23092 constructor(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { 23093 super(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise); 23094 this.type = 'ArcCurve'; 23095 } 23096 23097 } 23098 23099 ArcCurve.prototype.isArcCurve = true; 23100 23101 /** 23102 * Centripetal CatmullRom Curve - which is useful for avoiding 23103 * cusps and self-intersections in non-uniform catmull rom curves. 23104 * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf 23105 * 23106 * curve.type accepts centripetal(default), chordal and catmullrom 23107 * curve.tension is used for catmullrom which defaults to 0.5 23108 */ 23109 23110 /* 23111 Based on an optimized c++ solution in 23112 - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/ 23113 - http://ideone.com/NoEbVM 23114 23115 This CubicPoly class could be used for reusing some variables and calculations, 23116 but for three.js curve use, it could be possible inlined and flatten into a single function call 23117 which can be placed in CurveUtils. 23118 */ 23119 23120 function CubicPoly() { 23121 let c0 = 0, 23122 c1 = 0, 23123 c2 = 0, 23124 c3 = 0; 23125 /* 23126 * Compute coefficients for a cubic polynomial 23127 * p(s) = c0 + c1*s + c2*s^2 + c3*s^3 23128 * such that 23129 * p(0) = x0, p(1) = x1 23130 * and 23131 * p'(0) = t0, p'(1) = t1. 23132 */ 23133 23134 function init(x0, x1, t0, t1) { 23135 c0 = x0; 23136 c1 = t0; 23137 c2 = -3 * x0 + 3 * x1 - 2 * t0 - t1; 23138 c3 = 2 * x0 - 2 * x1 + t0 + t1; 23139 } 23140 23141 return { 23142 initCatmullRom: function (x0, x1, x2, x3, tension) { 23143 init(x1, x2, tension * (x2 - x0), tension * (x3 - x1)); 23144 }, 23145 initNonuniformCatmullRom: function (x0, x1, x2, x3, dt0, dt1, dt2) { 23146 // compute tangents when parameterized in [t1,t2] 23147 let t1 = (x1 - x0) / dt0 - (x2 - x0) / (dt0 + dt1) + (x2 - x1) / dt1; 23148 let t2 = (x2 - x1) / dt1 - (x3 - x1) / (dt1 + dt2) + (x3 - x2) / dt2; // rescale tangents for parametrization in [0,1] 23149 23150 t1 *= dt1; 23151 t2 *= dt1; 23152 init(x1, x2, t1, t2); 23153 }, 23154 calc: function (t) { 23155 const t2 = t * t; 23156 const t3 = t2 * t; 23157 return c0 + c1 * t + c2 * t2 + c3 * t3; 23158 } 23159 }; 23160 } // 23161 23162 23163 const tmp = new Vector3(); 23164 const px = new CubicPoly(), 23165 py = new CubicPoly(), 23166 pz = new CubicPoly(); 23167 23168 class CatmullRomCurve3 extends Curve { 23169 constructor(points = [], closed = false, curveType = 'centripetal', tension = 0.5) { 23170 super(); 23171 this.type = 'CatmullRomCurve3'; 23172 this.points = points; 23173 this.closed = closed; 23174 this.curveType = curveType; 23175 this.tension = tension; 23176 } 23177 23178 getPoint(t, optionalTarget = new Vector3()) { 23179 const point = optionalTarget; 23180 const points = this.points; 23181 const l = points.length; 23182 const p = (l - (this.closed ? 0 : 1)) * t; 23183 let intPoint = Math.floor(p); 23184 let weight = p - intPoint; 23185 23186 if (this.closed) { 23187 intPoint += intPoint > 0 ? 0 : (Math.floor(Math.abs(intPoint) / l) + 1) * l; 23188 } else if (weight === 0 && intPoint === l - 1) { 23189 intPoint = l - 2; 23190 weight = 1; 23191 } 23192 23193 let p0, p3; // 4 points (p1 & p2 defined below) 23194 23195 if (this.closed || intPoint > 0) { 23196 p0 = points[(intPoint - 1) % l]; 23197 } else { 23198 // extrapolate first point 23199 tmp.subVectors(points[0], points[1]).add(points[0]); 23200 p0 = tmp; 23201 } 23202 23203 const p1 = points[intPoint % l]; 23204 const p2 = points[(intPoint + 1) % l]; 23205 23206 if (this.closed || intPoint + 2 < l) { 23207 p3 = points[(intPoint + 2) % l]; 23208 } else { 23209 // extrapolate last point 23210 tmp.subVectors(points[l - 1], points[l - 2]).add(points[l - 1]); 23211 p3 = tmp; 23212 } 23213 23214 if (this.curveType === 'centripetal' || this.curveType === 'chordal') { 23215 // init Centripetal / Chordal Catmull-Rom 23216 const pow = this.curveType === 'chordal' ? 0.5 : 0.25; 23217 let dt0 = Math.pow(p0.distanceToSquared(p1), pow); 23218 let dt1 = Math.pow(p1.distanceToSquared(p2), pow); 23219 let dt2 = Math.pow(p2.distanceToSquared(p3), pow); // safety check for repeated points 23220 23221 if (dt1 < 1e-4) dt1 = 1.0; 23222 if (dt0 < 1e-4) dt0 = dt1; 23223 if (dt2 < 1e-4) dt2 = dt1; 23224 px.initNonuniformCatmullRom(p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2); 23225 py.initNonuniformCatmullRom(p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2); 23226 pz.initNonuniformCatmullRom(p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2); 23227 } else if (this.curveType === 'catmullrom') { 23228 px.initCatmullRom(p0.x, p1.x, p2.x, p3.x, this.tension); 23229 py.initCatmullRom(p0.y, p1.y, p2.y, p3.y, this.tension); 23230 pz.initCatmullRom(p0.z, p1.z, p2.z, p3.z, this.tension); 23231 } 23232 23233 point.set(px.calc(weight), py.calc(weight), pz.calc(weight)); 23234 return point; 23235 } 23236 23237 copy(source) { 23238 super.copy(source); 23239 this.points = []; 23240 23241 for (let i = 0, l = source.points.length; i < l; i++) { 23242 const point = source.points[i]; 23243 this.points.push(point.clone()); 23244 } 23245 23246 this.closed = source.closed; 23247 this.curveType = source.curveType; 23248 this.tension = source.tension; 23249 return this; 23250 } 23251 23252 toJSON() { 23253 const data = super.toJSON(); 23254 data.points = []; 23255 23256 for (let i = 0, l = this.points.length; i < l; i++) { 23257 const point = this.points[i]; 23258 data.points.push(point.toArray()); 23259 } 23260 23261 data.closed = this.closed; 23262 data.curveType = this.curveType; 23263 data.tension = this.tension; 23264 return data; 23265 } 23266 23267 fromJSON(json) { 23268 super.fromJSON(json); 23269 this.points = []; 23270 23271 for (let i = 0, l = json.points.length; i < l; i++) { 23272 const point = json.points[i]; 23273 this.points.push(new Vector3().fromArray(point)); 23274 } 23275 23276 this.closed = json.closed; 23277 this.curveType = json.curveType; 23278 this.tension = json.tension; 23279 return this; 23280 } 23281 23282 } 23283 23284 CatmullRomCurve3.prototype.isCatmullRomCurve3 = true; 23285 23286 /** 23287 * Bezier Curves formulas obtained from 23288 * https://en.wikipedia.org/wiki/B%C3%A9zier_curve 23289 */ 23290 function CatmullRom(t, p0, p1, p2, p3) { 23291 const v0 = (p2 - p0) * 0.5; 23292 const v1 = (p3 - p1) * 0.5; 23293 const t2 = t * t; 23294 const t3 = t * t2; 23295 return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; 23296 } // 23297 23298 23299 function QuadraticBezierP0(t, p) { 23300 const k = 1 - t; 23301 return k * k * p; 23302 } 23303 23304 function QuadraticBezierP1(t, p) { 23305 return 2 * (1 - t) * t * p; 23306 } 23307 23308 function QuadraticBezierP2(t, p) { 23309 return t * t * p; 23310 } 23311 23312 function QuadraticBezier(t, p0, p1, p2) { 23313 return QuadraticBezierP0(t, p0) + QuadraticBezierP1(t, p1) + QuadraticBezierP2(t, p2); 23314 } // 23315 23316 23317 function CubicBezierP0(t, p) { 23318 const k = 1 - t; 23319 return k * k * k * p; 23320 } 23321 23322 function CubicBezierP1(t, p) { 23323 const k = 1 - t; 23324 return 3 * k * k * t * p; 23325 } 23326 23327 function CubicBezierP2(t, p) { 23328 return 3 * (1 - t) * t * t * p; 23329 } 23330 23331 function CubicBezierP3(t, p) { 23332 return t * t * t * p; 23333 } 23334 23335 function CubicBezier(t, p0, p1, p2, p3) { 23336 return CubicBezierP0(t, p0) + CubicBezierP1(t, p1) + CubicBezierP2(t, p2) + CubicBezierP3(t, p3); 23337 } 23338 23339 class CubicBezierCurve extends Curve { 23340 constructor(v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2(), v3 = new Vector2()) { 23341 super(); 23342 this.type = 'CubicBezierCurve'; 23343 this.v0 = v0; 23344 this.v1 = v1; 23345 this.v2 = v2; 23346 this.v3 = v3; 23347 } 23348 23349 getPoint(t, optionalTarget = new Vector2()) { 23350 const point = optionalTarget; 23351 const v0 = this.v0, 23352 v1 = this.v1, 23353 v2 = this.v2, 23354 v3 = this.v3;
vendor: 6,400 bytes, lines 23355-23650
23355 point.set(CubicBezier(t, v0.x, v1.x, v2.x, v3.x), CubicBezier(t, v0.y, v1.y, v2.y, v3.y)); 23356 return point; 23357 } 23358 23359 copy(source) { 23360 super.copy(source); 23361 this.v0.copy(source.v0); 23362 this.v1.copy(source.v1); 23363 this.v2.copy(source.v2); 23364 this.v3.copy(source.v3); 23365 return this; 23366 } 23367 23368 toJSON() { 23369 const data = super.toJSON(); 23370 data.v0 = this.v0.toArray(); 23371 data.v1 = this.v1.toArray(); 23372 data.v2 = this.v2.toArray(); 23373 data.v3 = this.v3.toArray(); 23374 return data; 23375 } 23376 23377 fromJSON(json) { 23378 super.fromJSON(json); 23379 this.v0.fromArray(json.v0); 23380 this.v1.fromArray(json.v1); 23381 this.v2.fromArray(json.v2); 23382 this.v3.fromArray(json.v3); 23383 return this; 23384 } 23385 23386 } 23387 23388 CubicBezierCurve.prototype.isCubicBezierCurve = true; 23389 23390 class CubicBezierCurve3 extends Curve { 23391 constructor(v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3(), v3 = new Vector3()) { 23392 super(); 23393 this.type = 'CubicBezierCurve3'; 23394 this.v0 = v0; 23395 this.v1 = v1; 23396 this.v2 = v2; 23397 this.v3 = v3; 23398 } 23399 23400 getPoint(t, optionalTarget = new Vector3()) { 23401 const point = optionalTarget; 23402 const v0 = this.v0, 23403 v1 = this.v1, 23404 v2 = this.v2, 23405 v3 = this.v3; 23406 point.set(CubicBezier(t, v0.x, v1.x, v2.x, v3.x), CubicBezier(t, v0.y, v1.y, v2.y, v3.y), CubicBezier(t, v0.z, v1.z, v2.z, v3.z)); 23407 return point; 23408 } 23409 23410 copy(source) { 23411 super.copy(source); 23412 this.v0.copy(source.v0); 23413 this.v1.copy(source.v1); 23414 this.v2.copy(source.v2); 23415 this.v3.copy(source.v3); 23416 return this; 23417 } 23418 23419 toJSON() { 23420 const data = super.toJSON(); 23421 data.v0 = this.v0.toArray(); 23422 data.v1 = this.v1.toArray(); 23423 data.v2 = this.v2.toArray(); 23424 data.v3 = this.v3.toArray(); 23425 return data; 23426 } 23427 23428 fromJSON(json) { 23429 super.fromJSON(json); 23430 this.v0.fromArray(json.v0); 23431 this.v1.fromArray(json.v1); 23432 this.v2.fromArray(json.v2); 23433 this.v3.fromArray(json.v3); 23434 return this; 23435 } 23436 23437 } 23438 23439 CubicBezierCurve3.prototype.isCubicBezierCurve3 = true; 23440 23441 class LineCurve extends Curve { 23442 constructor(v1 = new Vector2(), v2 = new Vector2()) { 23443 super(); 23444 this.type = 'LineCurve'; 23445 this.v1 = v1; 23446 this.v2 = v2; 23447 } 23448 23449 getPoint(t, optionalTarget = new Vector2()) { 23450 const point = optionalTarget; 23451 23452 if (t === 1) { 23453 point.copy(this.v2); 23454 } else { 23455 point.copy(this.v2).sub(this.v1); 23456 point.multiplyScalar(t).add(this.v1); 23457 } 23458 23459 return point; 23460 } // Line curve is linear, so we can overwrite default getPointAt 23461 23462 23463 getPointAt(u, optionalTarget) { 23464 return this.getPoint(u, optionalTarget); 23465 } 23466 23467 getTangent(t, optionalTarget) { 23468 const tangent = optionalTarget || new Vector2(); 23469 tangent.copy(this.v2).sub(this.v1).normalize(); 23470 return tangent; 23471 } 23472 23473 copy(source) { 23474 super.copy(source); 23475 this.v1.copy(source.v1); 23476 this.v2.copy(source.v2); 23477 return this; 23478 } 23479 23480 toJSON() { 23481 const data = super.toJSON(); 23482 data.v1 = this.v1.toArray(); 23483 data.v2 = this.v2.toArray(); 23484 return data; 23485 } 23486 23487 fromJSON(json) { 23488 super.fromJSON(json); 23489 this.v1.fromArray(json.v1); 23490 this.v2.fromArray(json.v2); 23491 return this; 23492 } 23493 23494 } 23495 23496 LineCurve.prototype.isLineCurve = true; 23497 23498 class LineCurve3 extends Curve { 23499 constructor(v1 = new Vector3(), v2 = new Vector3()) { 23500 super(); 23501 this.type = 'LineCurve3'; 23502 this.isLineCurve3 = true; 23503 this.v1 = v1; 23504 this.v2 = v2; 23505 } 23506 23507 getPoint(t, optionalTarget = new Vector3()) { 23508 const point = optionalTarget; 23509 23510 if (t === 1) { 23511 point.copy(this.v2); 23512 } else { 23513 point.copy(this.v2).sub(this.v1); 23514 point.multiplyScalar(t).add(this.v1); 23515 } 23516 23517 return point; 23518 } // Line curve is linear, so we can overwrite default getPointAt 23519 23520 23521 getPointAt(u, optionalTarget) { 23522 return this.getPoint(u, optionalTarget); 23523 } 23524 23525 copy(source) { 23526 super.copy(source); 23527 this.v1.copy(source.v1); 23528 this.v2.copy(source.v2); 23529 return this; 23530 } 23531 23532 toJSON() { 23533 const data = super.toJSON(); 23534 data.v1 = this.v1.toArray(); 23535 data.v2 = this.v2.toArray(); 23536 return data; 23537 } 23538 23539 fromJSON(json) { 23540 super.fromJSON(json); 23541 this.v1.fromArray(json.v1); 23542 this.v2.fromArray(json.v2); 23543 return this; 23544 } 23545 23546 } 23547 23548 class QuadraticBezierCurve extends Curve { 23549 constructor(v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2()) { 23550 super(); 23551 this.type = 'QuadraticBezierCurve'; 23552 this.v0 = v0; 23553 this.v1 = v1; 23554 this.v2 = v2; 23555 } 23556 23557 getPoint(t, optionalTarget = new Vector2()) { 23558 const point = optionalTarget; 23559 const v0 = this.v0, 23560 v1 = this.v1, 23561 v2 = this.v2; 23562 point.set(QuadraticBezier(t, v0.x, v1.x, v2.x), QuadraticBezier(t, v0.y, v1.y, v2.y)); 23563 return point; 23564 } 23565 23566 copy(source) { 23567 super.copy(source); 23568 this.v0.copy(source.v0); 23569 this.v1.copy(source.v1); 23570 this.v2.copy(source.v2); 23571 return this; 23572 } 23573 23574 toJSON() { 23575 const data = super.toJSON(); 23576 data.v0 = this.v0.toArray(); 23577 data.v1 = this.v1.toArray(); 23578 data.v2 = this.v2.toArray(); 23579 return data; 23580 } 23581 23582 fromJSON(json) { 23583 super.fromJSON(json); 23584 this.v0.fromArray(json.v0); 23585 this.v1.fromArray(json.v1); 23586 this.v2.fromArray(json.v2); 23587 return this; 23588 } 23589 23590 } 23591 23592 QuadraticBezierCurve.prototype.isQuadraticBezierCurve = true; 23593 23594 class QuadraticBezierCurve3 extends Curve { 23595 constructor(v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3()) { 23596 super(); 23597 this.type = 'QuadraticBezierCurve3'; 23598 this.v0 = v0; 23599 this.v1 = v1; 23600 this.v2 = v2; 23601 } 23602 23603 getPoint(t, optionalTarget = new Vector3()) { 23604 const point = optionalTarget; 23605 const v0 = this.v0, 23606 v1 = this.v1, 23607 v2 = this.v2; 23608 point.set(QuadraticBezier(t, v0.x, v1.x, v2.x), QuadraticBezier(t, v0.y, v1.y, v2.y), QuadraticBezier(t, v0.z, v1.z, v2.z)); 23609 return point; 23610 } 23611 23612 copy(source) { 23613 super.copy(source); 23614 this.v0.copy(source.v0); 23615 this.v1.copy(source.v1); 23616 this.v2.copy(source.v2); 23617 return this; 23618 } 23619 23620 toJSON() { 23621 const data = super.toJSON(); 23622 data.v0 = this.v0.toArray(); 23623 data.v1 = this.v1.toArray(); 23624 data.v2 = this.v2.toArray(); 23625 return data; 23626 } 23627 23628 fromJSON(json) { 23629 super.fromJSON(json); 23630 this.v0.fromArray(json.v0); 23631 this.v1.fromArray(json.v1); 23632 this.v2.fromArray(json.v2); 23633 return this; 23634 } 23635 23636 } 23637 23638 QuadraticBezierCurve3.prototype.isQuadraticBezierCurve3 = true; 23639 23640 class SplineCurve extends Curve { 23641 constructor(points = []) { 23642 super(); 23643 this.type = 'SplineCurve'; 23644 this.points = points; 23645 } 23646 23647 getPoint(t, optionalTarget = new Vector2()) { 23648 const point = optionalTarget; 23649 const points = this.points; 23650 const p = (points.length - 1) * t;
vendor: 10,353 bytes, lines 23651-24066
23651 const intPoint = Math.floor(p); 23652 const weight = p - intPoint; 23653 const p0 = points[intPoint === 0 ? intPoint : intPoint - 1]; 23654 const p1 = points[intPoint]; 23655 const p2 = points[intPoint > points.length - 2 ? points.length - 1 : intPoint + 1]; 23656 const p3 = points[intPoint > points.length - 3 ? points.length - 1 : intPoint + 2]; 23657 point.set(CatmullRom(weight, p0.x, p1.x, p2.x, p3.x), CatmullRom(weight, p0.y, p1.y, p2.y, p3.y)); 23658 return point; 23659 } 23660 23661 copy(source) { 23662 super.copy(source); 23663 this.points = []; 23664 23665 for (let i = 0, l = source.points.length; i < l; i++) { 23666 const point = source.points[i]; 23667 this.points.push(point.clone()); 23668 } 23669 23670 return this; 23671 } 23672 23673 toJSON() { 23674 const data = super.toJSON(); 23675 data.points = []; 23676 23677 for (let i = 0, l = this.points.length; i < l; i++) { 23678 const point = this.points[i]; 23679 data.points.push(point.toArray()); 23680 } 23681 23682 return data; 23683 } 23684 23685 fromJSON(json) { 23686 super.fromJSON(json); 23687 this.points = []; 23688 23689 for (let i = 0, l = json.points.length; i < l; i++) { 23690 const point = json.points[i]; 23691 this.points.push(new Vector2().fromArray(point)); 23692 } 23693 23694 return this; 23695 } 23696 23697 } 23698 23699 SplineCurve.prototype.isSplineCurve = true; 23700 23701 var Curves = /*#__PURE__*/Object.freeze({ 23702 __proto__: null, 23703 ArcCurve: ArcCurve, 23704 CatmullRomCurve3: CatmullRomCurve3, 23705 CubicBezierCurve: CubicBezierCurve, 23706 CubicBezierCurve3: CubicBezierCurve3, 23707 EllipseCurve: EllipseCurve, 23708 LineCurve: LineCurve, 23709 LineCurve3: LineCurve3, 23710 QuadraticBezierCurve: QuadraticBezierCurve, 23711 QuadraticBezierCurve3: QuadraticBezierCurve3, 23712 SplineCurve: SplineCurve 23713 }); 23714 23715 /************************************************************** 23716 * Curved Path - a curve path is simply a array of connected 23717 * curves, but retains the api of a curve 23718 **************************************************************/ 23719 23720 class CurvePath extends Curve { 23721 constructor() { 23722 super(); 23723 this.type = 'CurvePath'; 23724 this.curves = []; 23725 this.autoClose = false; // Automatically closes the path 23726 } 23727 23728 add(curve) { 23729 this.curves.push(curve); 23730 } 23731 23732 closePath() { 23733 // Add a line curve if start and end of lines are not connected 23734 const startPoint = this.curves[0].getPoint(0); 23735 const endPoint = this.curves[this.curves.length - 1].getPoint(1); 23736 23737 if (!startPoint.equals(endPoint)) { 23738 this.curves.push(new LineCurve(endPoint, startPoint)); 23739 } 23740 } // To get accurate point with reference to 23741 // entire path distance at time t, 23742 // following has to be done: 23743 // 1. Length of each sub path have to be known 23744 // 2. Locate and identify type of curve 23745 // 3. Get t for the curve 23746 // 4. Return curve.getPointAt(t') 23747 23748 23749 getPoint(t, optionalTarget) { 23750 const d = t * this.getLength(); 23751 const curveLengths = this.getCurveLengths(); 23752 let i = 0; // To think about boundaries points. 23753 23754 while (i < curveLengths.length) { 23755 if (curveLengths[i] >= d) { 23756 const diff = curveLengths[i] - d; 23757 const curve = this.curves[i]; 23758 const segmentLength = curve.getLength(); 23759 const u = segmentLength === 0 ? 0 : 1 - diff / segmentLength; 23760 return curve.getPointAt(u, optionalTarget); 23761 } 23762 23763 i++; 23764 } 23765 23766 return null; // loop where sum != 0, sum > d , sum+1 <d 23767 } // We cannot use the default THREE.Curve getPoint() with getLength() because in 23768 // THREE.Curve, getLength() depends on getPoint() but in THREE.CurvePath 23769 // getPoint() depends on getLength 23770 23771 23772 getLength() { 23773 const lens = this.getCurveLengths(); 23774 return lens[lens.length - 1]; 23775 } // cacheLengths must be recalculated. 23776 23777 23778 updateArcLengths() { 23779 this.needsUpdate = true; 23780 this.cacheLengths = null; 23781 this.getCurveLengths(); 23782 } // Compute lengths and cache them 23783 // We cannot overwrite getLengths() because UtoT mapping uses it. 23784 23785 23786 getCurveLengths() { 23787 // We use cache values if curves and cache array are same length 23788 if (this.cacheLengths && this.cacheLengths.length === this.curves.length) { 23789 return this.cacheLengths; 23790 } // Get length of sub-curve 23791 // Push sums into cached array 23792 23793 23794 const lengths = []; 23795 let sums = 0; 23796 23797 for (let i = 0, l = this.curves.length; i < l; i++) { 23798 sums += this.curves[i].getLength(); 23799 lengths.push(sums); 23800 } 23801 23802 this.cacheLengths = lengths; 23803 return lengths; 23804 } 23805 23806 getSpacedPoints(divisions = 40) { 23807 const points = []; 23808 23809 for (let i = 0; i <= divisions; i++) { 23810 points.push(this.getPoint(i / divisions)); 23811 } 23812 23813 if (this.autoClose) { 23814 points.push(points[0]); 23815 } 23816 23817 return points; 23818 } 23819 23820 getPoints(divisions = 12) { 23821 const points = []; 23822 let last; 23823 23824 for (let i = 0, curves = this.curves; i < curves.length; i++) { 23825 const curve = curves[i]; 23826 const resolution = curve && curve.isEllipseCurve ? divisions * 2 : curve && (curve.isLineCurve || curve.isLineCurve3) ? 1 : curve && curve.isSplineCurve ? divisions * curve.points.length : divisions; 23827 const pts = curve.getPoints(resolution); 23828 23829 for (let j = 0; j < pts.length; j++) { 23830 const point = pts[j]; 23831 if (last && last.equals(point)) continue; // ensures no consecutive points are duplicates 23832 23833 points.push(point); 23834 last = point; 23835 } 23836 } 23837 23838 if (this.autoClose && points.length > 1 && !points[points.length - 1].equals(points[0])) { 23839 points.push(points[0]); 23840 } 23841 23842 return points; 23843 } 23844 23845 copy(source) { 23846 super.copy(source); 23847 this.curves = []; 23848 23849 for (let i = 0, l = source.curves.length; i < l; i++) { 23850 const curve = source.curves[i]; 23851 this.curves.push(curve.clone()); 23852 } 23853 23854 this.autoClose = source.autoClose; 23855 return this; 23856 } 23857 23858 toJSON() { 23859 const data = super.toJSON(); 23860 data.autoClose = this.autoClose; 23861 data.curves = []; 23862 23863 for (let i = 0, l = this.curves.length; i < l; i++) { 23864 const curve = this.curves[i]; 23865 data.curves.push(curve.toJSON()); 23866 } 23867 23868 return data; 23869 } 23870 23871 fromJSON(json) { 23872 super.fromJSON(json); 23873 this.autoClose = json.autoClose; 23874 this.curves = []; 23875 23876 for (let i = 0, l = json.curves.length; i < l; i++) { 23877 const curve = json.curves[i]; 23878 this.curves.push(new Curves[curve.type]().fromJSON(curve)); 23879 } 23880 23881 return this; 23882 } 23883 23884 } 23885 23886 class Path extends CurvePath { 23887 constructor(points) { 23888 super(); 23889 this.type = 'Path'; 23890 this.currentPoint = new Vector2(); 23891 23892 if (points) { 23893 this.setFromPoints(points); 23894 } 23895 } 23896 23897 setFromPoints(points) { 23898 this.moveTo(points[0].x, points[0].y); 23899 23900 for (let i = 1, l = points.length; i < l; i++) { 23901 this.lineTo(points[i].x, points[i].y); 23902 } 23903 23904 return this; 23905 } 23906 23907 moveTo(x, y) { 23908 this.currentPoint.set(x, y); // TODO consider referencing vectors instead of copying? 23909 23910 return this; 23911 } 23912 23913 lineTo(x, y) { 23914 const curve = new LineCurve(this.currentPoint.clone(), new Vector2(x, y)); 23915 this.curves.push(curve); 23916 this.currentPoint.set(x, y); 23917 return this; 23918 } 23919 23920 quadraticCurveTo(aCPx, aCPy, aX, aY) { 23921 const curve = new QuadraticBezierCurve(this.currentPoint.clone(), new Vector2(aCPx, aCPy), new Vector2(aX, aY)); 23922 this.curves.push(curve); 23923 this.currentPoint.set(aX, aY); 23924 return this; 23925 } 23926 23927 bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) { 23928 const curve = new CubicBezierCurve(this.currentPoint.clone(), new Vector2(aCP1x, aCP1y), new Vector2(aCP2x, aCP2y), new Vector2(aX, aY)); 23929 this.curves.push(curve); 23930 this.currentPoint.set(aX, aY); 23931 return this; 23932 } 23933 23934 splineThru(pts 23935 /*Array of Vector*/ 23936 ) { 23937 const npts = [this.currentPoint.clone()].concat(pts); 23938 const curve = new SplineCurve(npts); 23939 this.curves.push(curve); 23940 this.currentPoint.copy(pts[pts.length - 1]); 23941 return this; 23942 } 23943 23944 arc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { 23945 const x0 = this.currentPoint.x; 23946 const y0 = this.currentPoint.y; 23947 this.absarc(aX + x0, aY + y0, aRadius, aStartAngle, aEndAngle, aClockwise); 23948 return this; 23949 } 23950 23951 absarc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { 23952 this.absellipse(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise); 23953 return this; 23954 } 23955 23956 ellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) { 23957 const x0 = this.currentPoint.x; 23958 const y0 = this.currentPoint.y; 23959 this.absellipse(aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation); 23960 return this; 23961 } 23962 23963 absellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) { 23964 const curve = new EllipseCurve(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation); 23965 23966 if (this.curves.length > 0) { 23967 // if a previous curve is present, attempt to join 23968 const firstPoint = curve.getPoint(0); 23969 23970 if (!firstPoint.equals(this.currentPoint)) { 23971 this.lineTo(firstPoint.x, firstPoint.y); 23972 } 23973 } 23974 23975 this.curves.push(curve); 23976 const lastPoint = curve.getPoint(1); 23977 this.currentPoint.copy(lastPoint); 23978 return this; 23979 } 23980 23981 copy(source) { 23982 super.copy(source); 23983 this.currentPoint.copy(source.currentPoint); 23984 return this; 23985 } 23986 23987 toJSON() { 23988 const data = super.toJSON(); 23989 data.currentPoint = this.currentPoint.toArray(); 23990 return data; 23991 } 23992 23993 fromJSON(json) { 23994 super.fromJSON(json); 23995 this.currentPoint.fromArray(json.currentPoint); 23996 return this; 23997 } 23998 23999 } 24000 24001 class Shape extends Path { 24002 constructor(points) { 24003 super(points); 24004 this.uuid = generateUUID(); 24005 this.type = 'Shape'; 24006 this.holes = []; 24007 } 24008 24009 getPointsHoles(divisions) { 24010 const holesPts = []; 24011 24012 for (let i = 0, l = this.holes.length; i < l; i++) { 24013 holesPts[i] = this.holes[i].getPoints(divisions); 24014 } 24015 24016 return holesPts; 24017 } // get points of shape and holes (keypoints based on segments parameter) 24018 24019 24020 extractPoints(divisions) { 24021 return { 24022 shape: this.getPoints(divisions), 24023 holes: this.getPointsHoles(divisions) 24024 }; 24025 } 24026 24027 copy(source) { 24028 super.copy(source); 24029 this.holes = []; 24030 24031 for (let i = 0, l = source.holes.length; i < l; i++) { 24032 const hole = source.holes[i]; 24033 this.holes.push(hole.clone()); 24034 } 24035 24036 return this; 24037 } 24038 24039 toJSON() { 24040 const data = super.toJSON(); 24041 data.uuid = this.uuid; 24042 data.holes = []; 24043 24044 for (let i = 0, l = this.holes.length; i < l; i++) { 24045 const hole = this.holes[i]; 24046 data.holes.push(hole.toJSON()); 24047 } 24048 24049 return data; 24050 } 24051 24052 fromJSON(json) { 24053 super.fromJSON(json); 24054 this.uuid = json.uuid; 24055 this.holes = []; 24056 24057 for (let i = 0, l = json.holes.length; i < l; i++) { 24058 const hole = json.holes[i]; 24059 this.holes.push(new Path().fromJSON(hole)); 24060 } 24061 24062 return this; 24063 } 24064 24065 } 24066
vendor: 14,892 bytes, lines 24067-24570
24067 /** 24068 * Port from https://github.com/mapbox/earcut (v2.2.2) 24069 */ 24070 const Earcut = { 24071 triangulate: function (data, holeIndices, dim = 2) { 24072 const hasHoles = holeIndices && holeIndices.length; 24073 const outerLen = hasHoles ? holeIndices[0] * dim : data.length; 24074 let outerNode = linkedList(data, 0, outerLen, dim, true); 24075 const triangles = []; 24076 if (!outerNode || outerNode.next === outerNode.prev) return triangles; 24077 let minX, minY, maxX, maxY, x, y, invSize; 24078 if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox 24079 24080 if (data.length > 80 * dim) { 24081 minX = maxX = data[0]; 24082 minY = maxY = data[1]; 24083 24084 for (let i = dim; i < outerLen; i += dim) { 24085 x = data[i]; 24086 y = data[i + 1]; 24087 if (x < minX) minX = x; 24088 if (y < minY) minY = y; 24089 if (x > maxX) maxX = x; 24090 if (y > maxY) maxY = y; 24091 } // minX, minY and invSize are later used to transform coords into integers for z-order calculation 24092 24093 24094 invSize = Math.max(maxX - minX, maxY - minY); 24095 invSize = invSize !== 0 ? 1 / invSize : 0; 24096 } 24097 24098 earcutLinked(outerNode, triangles, dim, minX, minY, invSize); 24099 return triangles; 24100 } 24101 }; // create a circular doubly linked list from polygon points in the specified winding order 24102 24103 function linkedList(data, start, end, dim, clockwise) { 24104 let i, last; 24105 24106 if (clockwise === signedArea(data, start, end, dim) > 0) { 24107 for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last); 24108 } else { 24109 for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last); 24110 } 24111 24112 if (last && equals(last, last.next)) { 24113 removeNode(last); 24114 last = last.next; 24115 } 24116 24117 return last; 24118 } // eliminate colinear or duplicate points 24119 24120 24121 function filterPoints(start, end) { 24122 if (!start) return start; 24123 if (!end) end = start; 24124 let p = start, 24125 again; 24126 24127 do { 24128 again = false; 24129 24130 if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { 24131 removeNode(p); 24132 p = end = p.prev; 24133 if (p === p.next) break; 24134 again = true; 24135 } else { 24136 p = p.next; 24137 } 24138 } while (again || p !== end); 24139 24140 return end; 24141 } // main ear slicing loop which triangulates a polygon (given as a linked list) 24142 24143 24144 function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { 24145 if (!ear) return; // interlink polygon nodes in z-order 24146 24147 if (!pass && invSize) indexCurve(ear, minX, minY, invSize); 24148 let stop = ear, 24149 prev, 24150 next; // iterate through ears, slicing them one by one 24151 24152 while (ear.prev !== ear.next) { 24153 prev = ear.prev; 24154 next = ear.next; 24155 24156 if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) { 24157 // cut off the triangle 24158 triangles.push(prev.i / dim); 24159 triangles.push(ear.i / dim); 24160 triangles.push(next.i / dim); 24161 removeNode(ear); // skipping the next vertex leads to less sliver triangles 24162 24163 ear = next.next; 24164 stop = next.next; 24165 continue; 24166 } 24167 24168 ear = next; // if we looped through the whole remaining polygon and can't find any more ears 24169 24170 if (ear === stop) { 24171 // try filtering points and slicing again 24172 if (!pass) { 24173 earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); // if this didn't work, try curing all small self-intersections locally 24174 } else if (pass === 1) { 24175 ear = cureLocalIntersections(filterPoints(ear), triangles, dim); 24176 earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); // as a last resort, try splitting the remaining polygon into two 24177 } else if (pass === 2) { 24178 splitEarcut(ear, triangles, dim, minX, minY, invSize); 24179 } 24180 24181 break; 24182 } 24183 } 24184 } // check whether a polygon node forms a valid ear with adjacent nodes 24185 24186 24187 function isEar(ear) { 24188 const a = ear.prev, 24189 b = ear, 24190 c = ear.next; 24191 if (area(a, b, c) >= 0) return false; // reflex, can't be an ear 24192 // now make sure we don't have other points inside the potential ear 24193 24194 let p = ear.next.next; 24195 24196 while (p !== ear.prev) { 24197 if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; 24198 p = p.next; 24199 } 24200 24201 return true; 24202 } 24203 24204 function isEarHashed(ear, minX, minY, invSize) { 24205 const a = ear.prev, 24206 b = ear, 24207 c = ear.next; 24208 if (area(a, b, c) >= 0) return false; // reflex, can't be an ear 24209 // triangle bbox; min & max are calculated like this for speed 24210 24211 const minTX = a.x < b.x ? a.x < c.x ? a.x : c.x : b.x < c.x ? b.x : c.x, 24212 minTY = a.y < b.y ? a.y < c.y ? a.y : c.y : b.y < c.y ? b.y : c.y, 24213 maxTX = a.x > b.x ? a.x > c.x ? a.x : c.x : b.x > c.x ? b.x : c.x, 24214 maxTY = a.y > b.y ? a.y > c.y ? a.y : c.y : b.y > c.y ? b.y : c.y; // z-order range for the current triangle bbox; 24215 24216 const minZ = zOrder(minTX, minTY, minX, minY, invSize), 24217 maxZ = zOrder(maxTX, maxTY, minX, minY, invSize); 24218 let p = ear.prevZ, 24219 n = ear.nextZ; // look for points inside the triangle in both directions 24220 24221 while (p && p.z >= minZ && n && n.z <= maxZ) { 24222 if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; 24223 p = p.prevZ; 24224 if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; 24225 n = n.nextZ; 24226 } // look for remaining points in decreasing z-order 24227 24228 24229 while (p && p.z >= minZ) { 24230 if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; 24231 p = p.prevZ; 24232 } // look for remaining points in increasing z-order 24233 24234 24235 while (n && n.z <= maxZ) { 24236 if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; 24237 n = n.nextZ; 24238 } 24239 24240 return true; 24241 } // go through all polygon nodes and cure small local self-intersections 24242 24243 24244 function cureLocalIntersections(start, triangles, dim) { 24245 let p = start; 24246 24247 do { 24248 const a = p.prev, 24249 b = p.next.next; 24250 24251 if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { 24252 triangles.push(a.i / dim); 24253 triangles.push(p.i / dim); 24254 triangles.push(b.i / dim); // remove two nodes involved 24255 24256 removeNode(p); 24257 removeNode(p.next); 24258 p = start = b; 24259 } 24260 24261 p = p.next; 24262 } while (p !== start); 24263 24264 return filterPoints(p); 24265 } // try splitting polygon into two and triangulate them independently 24266 24267 24268 function splitEarcut(start, triangles, dim, minX, minY, invSize) { 24269 // look for a valid diagonal that divides the polygon into two 24270 let a = start; 24271 24272 do { 24273 let b = a.next.next; 24274 24275 while (b !== a.prev) { 24276 if (a.i !== b.i && isValidDiagonal(a, b)) { 24277 // split the polygon in two by the diagonal 24278 let c = splitPolygon(a, b); // filter colinear points around the cuts 24279 24280 a = filterPoints(a, a.next); 24281 c = filterPoints(c, c.next); // run earcut on each half 24282 24283 earcutLinked(a, triangles, dim, minX, minY, invSize); 24284 earcutLinked(c, triangles, dim, minX, minY, invSize); 24285 return; 24286 } 24287 24288 b = b.next; 24289 } 24290 24291 a = a.next; 24292 } while (a !== start); 24293 } // link every hole into the outer loop, producing a single-ring polygon without holes 24294 24295 24296 function eliminateHoles(data, holeIndices, outerNode, dim) { 24297 const queue = []; 24298 let i, len, start, end, list; 24299 24300 for (i = 0, len = holeIndices.length; i < len; i++) { 24301 start = holeIndices[i] * dim; 24302 end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; 24303 list = linkedList(data, start, end, dim, false); 24304 if (list === list.next) list.steiner = true; 24305 queue.push(getLeftmost(list)); 24306 } 24307 24308 queue.sort(compareX); // process holes from left to right 24309 24310 for (i = 0; i < queue.length; i++) { 24311 eliminateHole(queue[i], outerNode); 24312 outerNode = filterPoints(outerNode, outerNode.next); 24313 } 24314 24315 return outerNode; 24316 } 24317 24318 function compareX(a, b) { 24319 return a.x - b.x; 24320 } // find a bridge between vertices that connects hole with an outer ring and and link it 24321 24322 24323 function eliminateHole(hole, outerNode) { 24324 outerNode = findHoleBridge(hole, outerNode); 24325 24326 if (outerNode) { 24327 const b = splitPolygon(outerNode, hole); // filter collinear points around the cuts 24328 24329 filterPoints(outerNode, outerNode.next); 24330 filterPoints(b, b.next); 24331 } 24332 } // David Eberly's algorithm for finding a bridge between hole and outer polygon 24333 24334 24335 function findHoleBridge(hole, outerNode) { 24336 let p = outerNode; 24337 const hx = hole.x; 24338 const hy = hole.y; 24339 let qx = -Infinity, 24340 m; // find a segment intersected by a ray from the hole's leftmost point to the left; 24341 // segment's endpoint with lesser x will be potential connection point 24342 24343 do { 24344 if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { 24345 const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); 24346 24347 if (x <= hx && x > qx) { 24348 qx = x; 24349 24350 if (x === hx) { 24351 if (hy === p.y) return p; 24352 if (hy === p.next.y) return p.next; 24353 } 24354 24355 m = p.x < p.next.x ? p : p.next; 24356 } 24357 } 24358 24359 p = p.next; 24360 } while (p !== outerNode); 24361 24362 if (!m) return null; 24363 if (hx === qx) return m; // hole touches outer segment; pick leftmost endpoint 24364 // look for points inside the triangle of hole point, segment intersection and endpoint; 24365 // if there are no points found, we have a valid connection; 24366 // otherwise choose the point of the minimum angle with the ray as connection point 24367 24368 const stop = m, 24369 mx = m.x, 24370 my = m.y; 24371 let tanMin = Infinity, 24372 tan; 24373 p = m; 24374 24375 do { 24376 if (hx >= p.x && p.x >= mx && hx !== p.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { 24377 tan = Math.abs(hy - p.y) / (hx - p.x); // tangential 24378 24379 if (locallyInside(p, hole) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) { 24380 m = p; 24381 tanMin = tan; 24382 } 24383 } 24384 24385 p = p.next; 24386 } while (p !== stop); 24387 24388 return m; 24389 } // whether sector in vertex m contains sector in vertex p in the same coordinates 24390 24391 24392 function sectorContainsSector(m, p) { 24393 return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0; 24394 } // interlink polygon nodes in z-order 24395 24396 24397 function indexCurve(start, minX, minY, invSize) { 24398 let p = start; 24399 24400 do { 24401 if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize); 24402 p.prevZ = p.prev; 24403 p.nextZ = p.next; 24404 p = p.next; 24405 } while (p !== start); 24406 24407 p.prevZ.nextZ = null; 24408 p.prevZ = null; 24409 sortLinked(p); 24410 } // Simon Tatham's linked list merge sort algorithm 24411 // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html 24412 24413 24414 function sortLinked(list) { 24415 let i, 24416 p, 24417 q, 24418 e, 24419 tail, 24420 numMerges, 24421 pSize, 24422 qSize, 24423 inSize = 1; 24424 24425 do { 24426 p = list; 24427 list = null; 24428 tail = null; 24429 numMerges = 0; 24430 24431 while (p) { 24432 numMerges++; 24433 q = p; 24434 pSize = 0; 24435 24436 for (i = 0; i < inSize; i++) { 24437 pSize++; 24438 q = q.nextZ; 24439 if (!q) break; 24440 } 24441 24442 qSize = inSize; 24443 24444 while (pSize > 0 || qSize > 0 && q) { 24445 if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { 24446 e = p; 24447 p = p.nextZ; 24448 pSize--; 24449 } else { 24450 e = q; 24451 q = q.nextZ; 24452 qSize--; 24453 } 24454 24455 if (tail) tail.nextZ = e;else list = e; 24456 e.prevZ = tail; 24457 tail = e; 24458 } 24459 24460 p = q; 24461 } 24462 24463 tail.nextZ = null; 24464 inSize *= 2; 24465 } while (numMerges > 1); 24466 24467 return list; 24468 } // z-order of a point given coords and inverse of the longer side of data bbox 24469 24470 24471 function zOrder(x, y, minX, minY, invSize) { 24472 // coords are transformed into non-negative 15-bit integer range 24473 x = 32767 * (x - minX) * invSize; 24474 y = 32767 * (y - minY) * invSize; 24475 x = (x | x << 8) & 0x00FF00FF; 24476 x = (x | x << 4) & 0x0F0F0F0F; 24477 x = (x | x << 2) & 0x33333333; 24478 x = (x | x << 1) & 0x55555555; 24479 y = (y | y << 8) & 0x00FF00FF; 24480 y = (y | y << 4) & 0x0F0F0F0F; 24481 y = (y | y << 2) & 0x33333333; 24482 y = (y | y << 1) & 0x55555555; 24483 return x | y << 1; 24484 } // find the leftmost node of a polygon ring 24485 24486 24487 function getLeftmost(start) { 24488 let p = start, 24489 leftmost = start; 24490 24491 do { 24492 if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y) leftmost = p; 24493 p = p.next; 24494 } while (p !== start); 24495 24496 return leftmost; 24497 } // check if a point lies within a convex triangle 24498 24499 24500 function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { 24501 return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0; 24502 } // check if a diagonal between two polygon nodes is valid (lies in polygon interior) 24503 24504 24505 function isValidDiagonal(a, b) { 24506 return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && ( // dones't intersect other edges 24507 locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && ( // locally visible 24508 area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors 24509 equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case 24510 } // signed area of a triangle 24511 24512 24513 function area(p, q, r) { 24514 return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); 24515 } // check if two points are equal 24516 24517 24518 function equals(p1, p2) { 24519 return p1.x === p2.x && p1.y === p2.y; 24520 } // check if two segments intersect 24521 24522 24523 function intersects(p1, q1, p2, q2) { 24524 const o1 = sign(area(p1, q1, p2)); 24525 const o2 = sign(area(p1, q1, q2)); 24526 const o3 = sign(area(p2, q2, p1)); 24527 const o4 = sign(area(p2, q2, q1)); 24528 if (o1 !== o2 && o3 !== o4) return true; // general case 24529 24530 if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1 24531 24532 if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1 24533 24534 if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2 24535 24536 if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2 24537 24538 return false; 24539 } // for collinear points p, q, r, check if point q lies on segment pr 24540 24541 24542 function onSegment(p, q, r) { 24543 return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y); 24544 } 24545 24546 function sign(num) { 24547 return num > 0 ? 1 : num < 0 ? -1 : 0; 24548 } // check if a polygon diagonal intersects any polygon segments 24549 24550 24551 function intersectsPolygon(a, b) { 24552 let p = a; 24553 24554 do { 24555 if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b)) return true; 24556 p = p.next; 24557 } while (p !== a); 24558 24559 return false; 24560 } // check if a polygon diagonal is locally inside the polygon 24561 24562 24563 function locallyInside(a, b) { 24564 return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0; 24565 } // check if the middle point of a polygon diagonal is inside the polygon 24566 24567 24568 function middleInside(a, b) { 24569 let p = a, 24570 inside = false;
vendor: 5,948 bytes, lines 24571-24782
24571 const px = (a.x + b.x) / 2, 24572 py = (a.y + b.y) / 2; 24573 24574 do { 24575 if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x) inside = !inside; 24576 p = p.next; 24577 } while (p !== a); 24578 24579 return inside; 24580 } // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; 24581 // if one belongs to the outer ring and another to a hole, it merges it into a single ring 24582 24583 24584 function splitPolygon(a, b) { 24585 const a2 = new Node(a.i, a.x, a.y), 24586 b2 = new Node(b.i, b.x, b.y), 24587 an = a.next, 24588 bp = b.prev; 24589 a.next = b; 24590 b.prev = a; 24591 a2.next = an; 24592 an.prev = a2; 24593 b2.next = a2; 24594 a2.prev = b2; 24595 bp.next = b2; 24596 b2.prev = bp; 24597 return b2; 24598 } // create a node and optionally link it with previous one (in a circular doubly linked list) 24599 24600 24601 function insertNode(i, x, y, last) { 24602 const p = new Node(i, x, y); 24603 24604 if (!last) { 24605 p.prev = p; 24606 p.next = p; 24607 } else { 24608 p.next = last.next; 24609 p.prev = last; 24610 last.next.prev = p; 24611 last.next = p; 24612 } 24613 24614 return p; 24615 } 24616 24617 function removeNode(p) { 24618 p.next.prev = p.prev; 24619 p.prev.next = p.next; 24620 if (p.prevZ) p.prevZ.nextZ = p.nextZ; 24621 if (p.nextZ) p.nextZ.prevZ = p.prevZ; 24622 } 24623 24624 function Node(i, x, y) { 24625 // vertex index in coordinates array 24626 this.i = i; // vertex coordinates 24627 24628 this.x = x; 24629 this.y = y; // previous and next vertex nodes in a polygon ring 24630 24631 this.prev = null; 24632 this.next = null; // z-order curve value 24633 24634 this.z = null; // previous and next nodes in z-order 24635 24636 this.prevZ = null; 24637 this.nextZ = null; // indicates whether this is a steiner point 24638 24639 this.steiner = false; 24640 } 24641 24642 function signedArea(data, start, end, dim) { 24643 let sum = 0; 24644 24645 for (let i = start, j = end - dim; i < end; i += dim) { 24646 sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); 24647 j = i; 24648 } 24649 24650 return sum; 24651 } 24652 24653 class ShapeUtils { 24654 // calculate area of the contour polygon 24655 static area(contour) { 24656 const n = contour.length; 24657 let a = 0.0; 24658 24659 for (let p = n - 1, q = 0; q < n; p = q++) { 24660 a += contour[p].x * contour[q].y - contour[q].x * contour[p].y; 24661 } 24662 24663 return a * 0.5; 24664 } 24665 24666 static isClockWise(pts) { 24667 return ShapeUtils.area(pts) < 0; 24668 } 24669 24670 static triangulateShape(contour, holes) { 24671 const vertices = []; // flat array of vertices like [ x0,y0, x1,y1, x2,y2, ... ] 24672 24673 const holeIndices = []; // array of hole indices 24674 24675 const faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ] 24676 24677 removeDupEndPts(contour); 24678 addContour(vertices, contour); // 24679 24680 let holeIndex = contour.length; 24681 holes.forEach(removeDupEndPts); 24682 24683 for (let i = 0; i < holes.length; i++) { 24684 holeIndices.push(holeIndex); 24685 holeIndex += holes[i].length; 24686 addContour(vertices, holes[i]); 24687 } // 24688 24689 24690 const triangles = Earcut.triangulate(vertices, holeIndices); // 24691 24692 for (let i = 0; i < triangles.length; i += 3) { 24693 faces.push(triangles.slice(i, i + 3)); 24694 } 24695 24696 return faces; 24697 } 24698 24699 } 24700 24701 function removeDupEndPts(points) { 24702 const l = points.length; 24703 24704 if (l > 2 && points[l - 1].equals(points[0])) { 24705 points.pop(); 24706 } 24707 } 24708 24709 function addContour(vertices, contour) { 24710 for (let i = 0; i < contour.length; i++) { 24711 vertices.push(contour[i].x); 24712 vertices.push(contour[i].y); 24713 } 24714 } 24715 24716 /** 24717 * Creates extruded geometry from a path shape. 24718 * 24719 * parameters = { 24720 * 24721 * curveSegments: <int>, // number of points on the curves 24722 * steps: <int>, // number of points for z-side extrusions / used for subdividing segments of extrude spline too 24723 * depth: <float>, // Depth to extrude the shape 24724 * 24725 * bevelEnabled: <bool>, // turn on bevel 24726 * bevelThickness: <float>, // how deep into the original shape bevel goes 24727 * bevelSize: <float>, // how far from shape outline (including bevelOffset) is bevel 24728 * bevelOffset: <float>, // how far from shape outline does bevel start 24729 * bevelSegments: <int>, // number of bevel layers 24730 * 24731 * extrudePath: <THREE.Curve> // curve to extrude shape along 24732 * 24733 * UVGenerator: <Object> // object that provides UV generator functions 24734 * 24735 * } 24736 */ 24737 24738 class ExtrudeGeometry extends BufferGeometry { 24739 constructor(shapes = new Shape([new Vector2(0.5, 0.5), new Vector2(-0.5, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)]), options = {}) { 24740 super(); 24741 this.type = 'ExtrudeGeometry'; 24742 this.parameters = { 24743 shapes: shapes, 24744 options: options 24745 }; 24746 shapes = Array.isArray(shapes) ? shapes : [shapes]; 24747 const scope = this; 24748 const verticesArray = []; 24749 const uvArray = []; 24750 24751 for (let i = 0, l = shapes.length; i < l; i++) { 24752 const shape = shapes[i]; 24753 addShape(shape); 24754 } // build geometry 24755 24756 24757 this.setAttribute('position', new Float32BufferAttribute(verticesArray, 3)); 24758 this.setAttribute('uv', new Float32BufferAttribute(uvArray, 2)); 24759 this.computeVertexNormals(); // functions 24760 24761 function addShape(shape) { 24762 const placeholder = []; // options 24763 24764 const curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; 24765 const steps = options.steps !== undefined ? options.steps : 1; 24766 let depth = options.depth !== undefined ? options.depth : 1; 24767 let bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; 24768 let bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 0.2; 24769 let bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 0.1; 24770 let bevelOffset = options.bevelOffset !== undefined ? options.bevelOffset : 0; 24771 let bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3; 24772 const extrudePath = options.extrudePath; 24773 const uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator; // deprecated options 24774 24775 if (options.amount !== undefined) { 24776 console.warn('THREE.ExtrudeBufferGeometry: amount has been renamed to depth.'); 24777 depth = options.amount; 24778 } // 24779 24780 24781 let extrudePts, 24782 extrudeByPath = false;
vendor: 8,050 bytes, lines 24783-25007
24783 let splineTube, binormal, normal, position2; 24784 24785 if (extrudePath) { 24786 extrudePts = extrudePath.getSpacedPoints(steps); 24787 extrudeByPath = true; 24788 bevelEnabled = false; // bevels not supported for path extrusion 24789 // SETUP TNB variables 24790 // TODO1 - have a .isClosed in spline? 24791 24792 splineTube = extrudePath.computeFrenetFrames(steps, false); // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length); 24793 24794 binormal = new Vector3(); 24795 normal = new Vector3(); 24796 position2 = new Vector3(); 24797 } // Safeguards if bevels are not enabled 24798 24799 24800 if (!bevelEnabled) { 24801 bevelSegments = 0; 24802 bevelThickness = 0; 24803 bevelSize = 0; 24804 bevelOffset = 0; 24805 } // Variables initialization 24806 24807 24808 const shapePoints = shape.extractPoints(curveSegments); 24809 let vertices = shapePoints.shape; 24810 const holes = shapePoints.holes; 24811 const reverse = !ShapeUtils.isClockWise(vertices); 24812 24813 if (reverse) { 24814 vertices = vertices.reverse(); // Maybe we should also check if holes are in the opposite direction, just to be safe ... 24815 24816 for (let h = 0, hl = holes.length; h < hl; h++) { 24817 const ahole = holes[h]; 24818 24819 if (ShapeUtils.isClockWise(ahole)) { 24820 holes[h] = ahole.reverse(); 24821 } 24822 } 24823 } 24824 24825 const faces = ShapeUtils.triangulateShape(vertices, holes); 24826 /* Vertices */ 24827 24828 const contour = vertices; // vertices has all points but contour has only points of circumference 24829 24830 for (let h = 0, hl = holes.length; h < hl; h++) { 24831 const ahole = holes[h]; 24832 vertices = vertices.concat(ahole); 24833 } 24834 24835 function scalePt2(pt, vec, size) { 24836 if (!vec) console.error('THREE.ExtrudeGeometry: vec does not exist'); 24837 return vec.clone().multiplyScalar(size).add(pt); 24838 } 24839 24840 const vlen = vertices.length, 24841 flen = faces.length; // Find directions for point movement 24842 24843 function getBevelVec(inPt, inPrev, inNext) { 24844 // computes for inPt the corresponding point inPt' on a new contour 24845 // shifted by 1 unit (length of normalized vector) to the left 24846 // if we walk along contour clockwise, this new contour is outside the old one 24847 // 24848 // inPt' is the intersection of the two lines parallel to the two 24849 // adjacent edges of inPt at a distance of 1 unit on the left side. 24850 let v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt 24851 // good reading for geometry algorithms (here: line-line intersection) 24852 // http://geomalgorithms.com/a05-_intersect-1.html 24853 24854 const v_prev_x = inPt.x - inPrev.x, 24855 v_prev_y = inPt.y - inPrev.y; 24856 const v_next_x = inNext.x - inPt.x, 24857 v_next_y = inNext.y - inPt.y; 24858 const v_prev_lensq = v_prev_x * v_prev_x + v_prev_y * v_prev_y; // check for collinear edges 24859 24860 const collinear0 = v_prev_x * v_next_y - v_prev_y * v_next_x; 24861 24862 if (Math.abs(collinear0) > Number.EPSILON) { 24863 // not collinear 24864 // length of vectors for normalizing 24865 const v_prev_len = Math.sqrt(v_prev_lensq); 24866 const v_next_len = Math.sqrt(v_next_x * v_next_x + v_next_y * v_next_y); // shift adjacent points by unit vectors to the left 24867 24868 const ptPrevShift_x = inPrev.x - v_prev_y / v_prev_len; 24869 const ptPrevShift_y = inPrev.y + v_prev_x / v_prev_len; 24870 const ptNextShift_x = inNext.x - v_next_y / v_next_len; 24871 const ptNextShift_y = inNext.y + v_next_x / v_next_len; // scaling factor for v_prev to intersection point 24872 24873 const sf = ((ptNextShift_x - ptPrevShift_x) * v_next_y - (ptNextShift_y - ptPrevShift_y) * v_next_x) / (v_prev_x * v_next_y - v_prev_y * v_next_x); // vector from inPt to intersection point 24874 24875 v_trans_x = ptPrevShift_x + v_prev_x * sf - inPt.x; 24876 v_trans_y = ptPrevShift_y + v_prev_y * sf - inPt.y; // Don't normalize!, otherwise sharp corners become ugly 24877 // but prevent crazy spikes 24878 24879 const v_trans_lensq = v_trans_x * v_trans_x + v_trans_y * v_trans_y; 24880 24881 if (v_trans_lensq <= 2) { 24882 return new Vector2(v_trans_x, v_trans_y); 24883 } else { 24884 shrink_by = Math.sqrt(v_trans_lensq / 2); 24885 } 24886 } else { 24887 // handle special case of collinear edges 24888 let direction_eq = false; // assumes: opposite 24889 24890 if (v_prev_x > Number.EPSILON) { 24891 if (v_next_x > Number.EPSILON) { 24892 direction_eq = true; 24893 } 24894 } else { 24895 if (v_prev_x < -Number.EPSILON) { 24896 if (v_next_x < -Number.EPSILON) { 24897 direction_eq = true; 24898 } 24899 } else { 24900 if (Math.sign(v_prev_y) === Math.sign(v_next_y)) { 24901 direction_eq = true; 24902 } 24903 } 24904 } 24905 24906 if (direction_eq) { 24907 // console.log("Warning: lines are a straight sequence"); 24908 v_trans_x = -v_prev_y; 24909 v_trans_y = v_prev_x; 24910 shrink_by = Math.sqrt(v_prev_lensq); 24911 } else { 24912 // console.log("Warning: lines are a straight spike"); 24913 v_trans_x = v_prev_x; 24914 v_trans_y = v_prev_y; 24915 shrink_by = Math.sqrt(v_prev_lensq / 2); 24916 } 24917 } 24918 24919 return new Vector2(v_trans_x / shrink_by, v_trans_y / shrink_by); 24920 } 24921 24922 const contourMovements = []; 24923 24924 for (let i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i++, j++, k++) { 24925 if (j === il) j = 0; 24926 if (k === il) k = 0; // (j)---(i)---(k) 24927 // console.log('i,j,k', i, j , k) 24928 24929 contourMovements[i] = getBevelVec(contour[i], contour[j], contour[k]); 24930 } 24931 24932 const holesMovements = []; 24933 let oneHoleMovements, 24934 verticesMovements = contourMovements.concat(); 24935 24936 for (let h = 0, hl = holes.length; h < hl; h++) { 24937 const ahole = holes[h]; 24938 oneHoleMovements = []; 24939 24940 for (let i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i++, j++, k++) { 24941 if (j === il) j = 0; 24942 if (k === il) k = 0; // (j)---(i)---(k) 24943 24944 oneHoleMovements[i] = getBevelVec(ahole[i], ahole[j], ahole[k]); 24945 } 24946 24947 holesMovements.push(oneHoleMovements); 24948 verticesMovements = verticesMovements.concat(oneHoleMovements); 24949 } // Loop bevelSegments, 1 for the front, 1 for the back 24950 24951 24952 for (let b = 0; b < bevelSegments; b++) { 24953 //for ( b = bevelSegments; b > 0; b -- ) { 24954 const t = b / bevelSegments; 24955 const z = bevelThickness * Math.cos(t * Math.PI / 2); 24956 const bs = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; // contract shape 24957 24958 for (let i = 0, il = contour.length; i < il; i++) { 24959 const vert = scalePt2(contour[i], contourMovements[i], bs); 24960 v(vert.x, vert.y, -z); 24961 } // expand holes 24962 24963 24964 for (let h = 0, hl = holes.length; h < hl; h++) { 24965 const ahole = holes[h]; 24966 oneHoleMovements = holesMovements[h]; 24967 24968 for (let i = 0, il = ahole.length; i < il; i++) { 24969 const vert = scalePt2(ahole[i], oneHoleMovements[i], bs); 24970 v(vert.x, vert.y, -z); 24971 } 24972 } 24973 } 24974 24975 const bs = bevelSize + bevelOffset; // Back facing vertices 24976 24977 for (let i = 0; i < vlen; i++) { 24978 const vert = bevelEnabled ? scalePt2(vertices[i], verticesMovements[i], bs) : vertices[i]; 24979 24980 if (!extrudeByPath) { 24981 v(vert.x, vert.y, 0); 24982 } else { 24983 // v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x ); 24984 normal.copy(splineTube.normals[0]).multiplyScalar(vert.x); 24985 binormal.copy(splineTube.binormals[0]).multiplyScalar(vert.y); 24986 position2.copy(extrudePts[0]).add(normal).add(binormal); 24987 v(position2.x, position2.y, position2.z); 24988 } 24989 } // Add stepped vertices... 24990 // Including front facing vertices 24991 24992 24993 for (let s = 1; s <= steps; s++) { 24994 for (let i = 0; i < vlen; i++) { 24995 const vert = bevelEnabled ? scalePt2(vertices[i], verticesMovements[i], bs) : vertices[i]; 24996 24997 if (!extrudeByPath) { 24998 v(vert.x, vert.y, depth / steps * s); 24999 } else { 25000 // v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x ); 25001 normal.copy(splineTube.normals[s]).multiplyScalar(vert.x); 25002 binormal.copy(splineTube.binormals[s]).multiplyScalar(vert.y); 25003 position2.copy(extrudePts[s]).add(normal).add(binormal); 25004 v(position2.x, position2.y, position2.z); 25005 } 25006 } 25007 }
vendor: 32,102 bytes, lines 25007-26047
25007 // Add bevel segments planes 25008 //for ( b = 1; b <= bevelSegments; b ++ ) { 25009 25010 25011 for (let b = bevelSegments - 1; b >= 0; b--) { 25012 const t = b / bevelSegments; 25013 const z = bevelThickness * Math.cos(t * Math.PI / 2); 25014 const bs = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; // contract shape 25015 25016 for (let i = 0, il = contour.length; i < il; i++) { 25017 const vert = scalePt2(contour[i], contourMovements[i], bs); 25018 v(vert.x, vert.y, depth + z); 25019 } // expand holes 25020 25021 25022 for (let h = 0, hl = holes.length; h < hl; h++) { 25023 const ahole = holes[h]; 25024 oneHoleMovements = holesMovements[h]; 25025 25026 for (let i = 0, il = ahole.length; i < il; i++) { 25027 const vert = scalePt2(ahole[i], oneHoleMovements[i], bs); 25028 25029 if (!extrudeByPath) { 25030 v(vert.x, vert.y, depth + z); 25031 } else { 25032 v(vert.x, vert.y + extrudePts[steps - 1].y, extrudePts[steps - 1].x + z); 25033 } 25034 } 25035 } 25036 } 25037 /* Faces */ 25038 // Top and bottom faces 25039 25040 25041 buildLidFaces(); // Sides faces 25042 25043 buildSideFaces(); ///// Internal functions 25044 25045 function buildLidFaces() { 25046 const start = verticesArray.length / 3; 25047 25048 if (bevelEnabled) { 25049 let layer = 0; // steps + 1 25050 25051 let offset = vlen * layer; // Bottom faces 25052 25053 for (let i = 0; i < flen; i++) { 25054 const face = faces[i]; 25055 f3(face[2] + offset, face[1] + offset, face[0] + offset); 25056 } 25057 25058 layer = steps + bevelSegments * 2; 25059 offset = vlen * layer; // Top faces 25060 25061 for (let i = 0; i < flen; i++) { 25062 const face = faces[i]; 25063 f3(face[0] + offset, face[1] + offset, face[2] + offset); 25064 } 25065 } else { 25066 // Bottom faces 25067 for (let i = 0; i < flen; i++) { 25068 const face = faces[i]; 25069 f3(face[2], face[1], face[0]); 25070 } // Top faces 25071 25072 25073 for (let i = 0; i < flen; i++) { 25074 const face = faces[i]; 25075 f3(face[0] + vlen * steps, face[1] + vlen * steps, face[2] + vlen * steps); 25076 } 25077 } 25078 25079 scope.addGroup(start, verticesArray.length / 3 - start, 0); 25080 } // Create faces for the z-sides of the shape 25081 25082 25083 function buildSideFaces() { 25084 const start = verticesArray.length / 3; 25085 let layeroffset = 0; 25086 sidewalls(contour, layeroffset); 25087 layeroffset += contour.length; 25088 25089 for (let h = 0, hl = holes.length; h < hl; h++) { 25090 const ahole = holes[h]; 25091 sidewalls(ahole, layeroffset); //, true 25092 25093 layeroffset += ahole.length; 25094 } 25095 25096 scope.addGroup(start, verticesArray.length / 3 - start, 1); 25097 } 25098 25099 function sidewalls(contour, layeroffset) { 25100 let i = contour.length; 25101 25102 while (--i >= 0) { 25103 const j = i; 25104 let k = i - 1; 25105 if (k < 0) k = contour.length - 1; //console.log('b', i,j, i-1, k,vertices.length); 25106 25107 for (let s = 0, sl = steps + bevelSegments * 2; s < sl; s++) { 25108 const slen1 = vlen * s; 25109 const slen2 = vlen * (s + 1); 25110 const a = layeroffset + j + slen1, 25111 b = layeroffset + k + slen1, 25112 c = layeroffset + k + slen2, 25113 d = layeroffset + j + slen2; 25114 f4(a, b, c, d); 25115 } 25116 } 25117 } 25118 25119 function v(x, y, z) { 25120 placeholder.push(x); 25121 placeholder.push(y); 25122 placeholder.push(z); 25123 } 25124 25125 function f3(a, b, c) { 25126 addVertex(a); 25127 addVertex(b); 25128 addVertex(c); 25129 const nextIndex = verticesArray.length / 3; 25130 const uvs = uvgen.generateTopUV(scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1); 25131 addUV(uvs[0]); 25132 addUV(uvs[1]); 25133 addUV(uvs[2]); 25134 } 25135 25136 function f4(a, b, c, d) { 25137 addVertex(a); 25138 addVertex(b); 25139 addVertex(d); 25140 addVertex(b); 25141 addVertex(c); 25142 addVertex(d); 25143 const nextIndex = verticesArray.length / 3; 25144 const uvs = uvgen.generateSideWallUV(scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1); 25145 addUV(uvs[0]); 25146 addUV(uvs[1]); 25147 addUV(uvs[3]); 25148 addUV(uvs[1]); 25149 addUV(uvs[2]); 25150 addUV(uvs[3]); 25151 } 25152 25153 function addVertex(index) { 25154 verticesArray.push(placeholder[index * 3 + 0]); 25155 verticesArray.push(placeholder[index * 3 + 1]); 25156 verticesArray.push(placeholder[index * 3 + 2]); 25157 } 25158 25159 function addUV(vector2) { 25160 uvArray.push(vector2.x); 25161 uvArray.push(vector2.y); 25162 } 25163 } 25164 } 25165 25166 toJSON() { 25167 const data = super.toJSON(); 25168 const shapes = this.parameters.shapes; 25169 const options = this.parameters.options; 25170 return toJSON$1(shapes, options, data); 25171 } 25172 25173 static fromJSON(data, shapes) { 25174 const geometryShapes = []; 25175 25176 for (let j = 0, jl = data.shapes.length; j < jl; j++) { 25177 const shape = shapes[data.shapes[j]]; 25178 geometryShapes.push(shape); 25179 } 25180 25181 const extrudePath = data.options.extrudePath; 25182 25183 if (extrudePath !== undefined) { 25184 data.options.extrudePath = new Curves[extrudePath.type]().fromJSON(extrudePath); 25185 } 25186 25187 return new ExtrudeGeometry(geometryShapes, data.options); 25188 } 25189 25190 } 25191 25192 const WorldUVGenerator = { 25193 generateTopUV: function (geometry, vertices, indexA, indexB, indexC) { 25194 const a_x = vertices[indexA * 3]; 25195 const a_y = vertices[indexA * 3 + 1]; 25196 const b_x = vertices[indexB * 3]; 25197 const b_y = vertices[indexB * 3 + 1]; 25198 const c_x = vertices[indexC * 3]; 25199 const c_y = vertices[indexC * 3 + 1]; 25200 return [new Vector2(a_x, a_y), new Vector2(b_x, b_y), new Vector2(c_x, c_y)]; 25201 }, 25202 generateSideWallUV: function (geometry, vertices, indexA, indexB, indexC, indexD) { 25203 const a_x = vertices[indexA * 3]; 25204 const a_y = vertices[indexA * 3 + 1]; 25205 const a_z = vertices[indexA * 3 + 2]; 25206 const b_x = vertices[indexB * 3]; 25207 const b_y = vertices[indexB * 3 + 1]; 25208 const b_z = vertices[indexB * 3 + 2]; 25209 const c_x = vertices[indexC * 3]; 25210 const c_y = vertices[indexC * 3 + 1]; 25211 const c_z = vertices[indexC * 3 + 2]; 25212 const d_x = vertices[indexD * 3]; 25213 const d_y = vertices[indexD * 3 + 1]; 25214 const d_z = vertices[indexD * 3 + 2]; 25215 25216 if (Math.abs(a_y - b_y) < Math.abs(a_x - b_x)) { 25217 return [new Vector2(a_x, 1 - a_z), new Vector2(b_x, 1 - b_z), new Vector2(c_x, 1 - c_z), new Vector2(d_x, 1 - d_z)]; 25218 } else { 25219 return [new Vector2(a_y, 1 - a_z), new Vector2(b_y, 1 - b_z), new Vector2(c_y, 1 - c_z), new Vector2(d_y, 1 - d_z)]; 25220 } 25221 } 25222 }; 25223 25224 function toJSON$1(shapes, options, data) { 25225 data.shapes = []; 25226 25227 if (Array.isArray(shapes)) { 25228 for (let i = 0, l = shapes.length; i < l; i++) { 25229 const shape = shapes[i]; 25230 data.shapes.push(shape.uuid); 25231 } 25232 } else { 25233 data.shapes.push(shapes.uuid); 25234 } 25235 25236 if (options.extrudePath !== undefined) data.options.extrudePath = options.extrudePath.toJSON(); 25237 return data; 25238 } 25239 25240 class IcosahedronGeometry extends PolyhedronGeometry { 25241 constructor(radius = 1, detail = 0) { 25242 const t = (1 + Math.sqrt(5)) / 2; 25243 const vertices = [-1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, 0, 0, -1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, t, 0, -1, t, 0, 1, -t, 0, -1, -t, 0, 1]; 25244 const indices = [0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1]; 25245 super(vertices, indices, radius, detail); 25246 this.type = 'IcosahedronGeometry'; 25247 this.parameters = { 25248 radius: radius, 25249 detail: detail 25250 }; 25251 } 25252 25253 static fromJSON(data) { 25254 return new IcosahedronGeometry(data.radius, data.detail); 25255 } 25256 25257 } 25258 25259 class LatheGeometry extends BufferGeometry { 25260 constructor(points = [new Vector2(0, 0.5), new Vector2(0.5, 0), new Vector2(0, -0.5)], segments = 12, phiStart = 0, phiLength = Math.PI * 2) { 25261 super(); 25262 this.type = 'LatheGeometry'; 25263 this.parameters = { 25264 points: points, 25265 segments: segments, 25266 phiStart: phiStart, 25267 phiLength: phiLength 25268 }; 25269 segments = Math.floor(segments); // clamp phiLength so it's in range of [ 0, 2PI ] 25270 25271 phiLength = clamp(phiLength, 0, Math.PI * 2); // buffers 25272 25273 const indices = []; 25274 const vertices = []; 25275 const uvs = []; 25276 const initNormals = []; 25277 const normals = []; // helper variables 25278 25279 const inverseSegments = 1.0 / segments; 25280 const vertex = new Vector3(); 25281 const uv = new Vector2(); 25282 const normal = new Vector3(); 25283 const curNormal = new Vector3(); 25284 const prevNormal = new Vector3(); 25285 let dx = 0; 25286 let dy = 0; // pre-compute normals for initial "meridian" 25287 25288 for (let j = 0; j <= points.length - 1; j++) { 25289 switch (j) { 25290 case 0: 25291 // special handling for 1st vertex on path 25292 dx = points[j + 1].x - points[j].x; 25293 dy = points[j + 1].y - points[j].y; 25294 normal.x = dy * 1.0; 25295 normal.y = -dx; 25296 normal.z = dy * 0.0; 25297 prevNormal.copy(normal); 25298 normal.normalize(); 25299 initNormals.push(normal.x, normal.y, normal.z); 25300 break; 25301 25302 case points.length - 1: 25303 // special handling for last Vertex on path 25304 initNormals.push(prevNormal.x, prevNormal.y, prevNormal.z); 25305 break; 25306 25307 default: 25308 // default handling for all vertices in between 25309 dx = points[j + 1].x - points[j].x; 25310 dy = points[j + 1].y - points[j].y; 25311 normal.x = dy * 1.0; 25312 normal.y = -dx; 25313 normal.z = dy * 0.0; 25314 curNormal.copy(normal); 25315 normal.x += prevNormal.x; 25316 normal.y += prevNormal.y; 25317 normal.z += prevNormal.z; 25318 normal.normalize(); 25319 initNormals.push(normal.x, normal.y, normal.z); 25320 prevNormal.copy(curNormal); 25321 } 25322 } // generate vertices, uvs and normals 25323 25324 25325 for (let i = 0; i <= segments; i++) { 25326 const phi = phiStart + i * inverseSegments * phiLength; 25327 const sin = Math.sin(phi); 25328 const cos = Math.cos(phi); 25329 25330 for (let j = 0; j <= points.length - 1; j++) { 25331 // vertex 25332 vertex.x = points[j].x * sin; 25333 vertex.y = points[j].y; 25334 vertex.z = points[j].x * cos; 25335 vertices.push(vertex.x, vertex.y, vertex.z); // uv 25336 25337 uv.x = i / segments; 25338 uv.y = j / (points.length - 1); 25339 uvs.push(uv.x, uv.y); // normal 25340 25341 const x = initNormals[3 * j + 0] * sin; 25342 const y = initNormals[3 * j + 1]; 25343 const z = initNormals[3 * j + 0] * cos; 25344 normals.push(x, y, z); 25345 } 25346 } // indices 25347 25348 25349 for (let i = 0; i < segments; i++) { 25350 for (let j = 0; j < points.length - 1; j++) { 25351 const base = j + i * points.length; 25352 const a = base; 25353 const b = base + points.length; 25354 const c = base + points.length + 1; 25355 const d = base + 1; // faces 25356 25357 indices.push(a, b, d); 25358 indices.push(b, c, d); 25359 } 25360 } // build geometry 25361 25362 25363 this.setIndex(indices); 25364 this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 25365 this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); 25366 this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); 25367 } 25368 25369 static fromJSON(data) { 25370 return new LatheGeometry(data.points, data.segments, data.phiStart, data.phiLength); 25371 } 25372 25373 } 25374 25375 class OctahedronGeometry extends PolyhedronGeometry { 25376 constructor(radius = 1, detail = 0) { 25377 const vertices = [1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1]; 25378 const indices = [0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2]; 25379 super(vertices, indices, radius, detail); 25380 this.type = 'OctahedronGeometry'; 25381 this.parameters = { 25382 radius: radius, 25383 detail: detail 25384 }; 25385 } 25386 25387 static fromJSON(data) { 25388 return new OctahedronGeometry(data.radius, data.detail); 25389 } 25390 25391 } 25392 25393 class RingGeometry extends BufferGeometry { 25394 constructor(innerRadius = 0.5, outerRadius = 1, thetaSegments = 8, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2) { 25395 super(); 25396 this.type = 'RingGeometry'; 25397 this.parameters = { 25398 innerRadius: innerRadius, 25399 outerRadius: outerRadius, 25400 thetaSegments: thetaSegments, 25401 phiSegments: phiSegments, 25402 thetaStart: thetaStart, 25403 thetaLength: thetaLength 25404 }; 25405 thetaSegments = Math.max(3, thetaSegments); 25406 phiSegments = Math.max(1, phiSegments); // buffers 25407 25408 const indices = []; 25409 const vertices = []; 25410 const normals = []; 25411 const uvs = []; // some helper variables 25412 25413 let radius = innerRadius; 25414 const radiusStep = (outerRadius - innerRadius) / phiSegments; 25415 const vertex = new Vector3(); 25416 const uv = new Vector2(); // generate vertices, normals and uvs 25417 25418 for (let j = 0; j <= phiSegments; j++) { 25419 for (let i = 0; i <= thetaSegments; i++) { 25420 // values are generate from the inside of the ring to the outside 25421 const segment = thetaStart + i / thetaSegments * thetaLength; // vertex 25422 25423 vertex.x = radius * Math.cos(segment); 25424 vertex.y = radius * Math.sin(segment); 25425 vertices.push(vertex.x, vertex.y, vertex.z); // normal 25426 25427 normals.push(0, 0, 1); // uv 25428 25429 uv.x = (vertex.x / outerRadius + 1) / 2; 25430 uv.y = (vertex.y / outerRadius + 1) / 2; 25431 uvs.push(uv.x, uv.y); 25432 } // increase the radius for next row of vertices 25433 25434 25435 radius += radiusStep; 25436 } // indices 25437 25438 25439 for (let j = 0; j < phiSegments; j++) { 25440 const thetaSegmentLevel = j * (thetaSegments + 1); 25441 25442 for (let i = 0; i < thetaSegments; i++) { 25443 const segment = i + thetaSegmentLevel; 25444 const a = segment; 25445 const b = segment + thetaSegments + 1; 25446 const c = segment + thetaSegments + 2; 25447 const d = segment + 1; // faces 25448 25449 indices.push(a, b, d); 25450 indices.push(b, c, d); 25451 } 25452 } // build geometry 25453 25454 25455 this.setIndex(indices); 25456 this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 25457 this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); 25458 this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); 25459 } 25460 25461 static fromJSON(data) { 25462 return new RingGeometry(data.innerRadius, data.outerRadius, data.thetaSegments, data.phiSegments, data.thetaStart, data.thetaLength); 25463 } 25464 25465 } 25466 25467 class ShapeGeometry extends BufferGeometry { 25468 constructor(shapes = new Shape([new Vector2(0, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)]), curveSegments = 12) { 25469 super(); 25470 this.type = 'ShapeGeometry'; 25471 this.parameters = { 25472 shapes: shapes, 25473 curveSegments: curveSegments 25474 }; // buffers 25475 25476 const indices = []; 25477 const vertices = []; 25478 const normals = []; 25479 const uvs = []; // helper variables 25480 25481 let groupStart = 0; 25482 let groupCount = 0; // allow single and array values for "shapes" parameter 25483 25484 if (Array.isArray(shapes) === false) { 25485 addShape(shapes); 25486 } else { 25487 for (let i = 0; i < shapes.length; i++) { 25488 addShape(shapes[i]); 25489 this.addGroup(groupStart, groupCount, i); // enables MultiMaterial support 25490 25491 groupStart += groupCount; 25492 groupCount = 0; 25493 } 25494 } // build geometry 25495 25496 25497 this.setIndex(indices); 25498 this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 25499 this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); 25500 this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // helper functions 25501 25502 function addShape(shape) { 25503 const indexOffset = vertices.length / 3; 25504 const points = shape.extractPoints(curveSegments); 25505 let shapeVertices = points.shape; 25506 const shapeHoles = points.holes; // check direction of vertices 25507 25508 if (ShapeUtils.isClockWise(shapeVertices) === false) { 25509 shapeVertices = shapeVertices.reverse(); 25510 } 25511 25512 for (let i = 0, l = shapeHoles.length; i < l; i++) { 25513 const shapeHole = shapeHoles[i]; 25514 25515 if (ShapeUtils.isClockWise(shapeHole) === true) { 25516 shapeHoles[i] = shapeHole.reverse(); 25517 } 25518 } 25519 25520 const faces = ShapeUtils.triangulateShape(shapeVertices, shapeHoles); // join vertices of inner and outer paths to a single array 25521 25522 for (let i = 0, l = shapeHoles.length; i < l; i++) { 25523 const shapeHole = shapeHoles[i]; 25524 shapeVertices = shapeVertices.concat(shapeHole); 25525 } // vertices, normals, uvs 25526 25527 25528 for (let i = 0, l = shapeVertices.length; i < l; i++) { 25529 const vertex = shapeVertices[i]; 25530 vertices.push(vertex.x, vertex.y, 0); 25531 normals.push(0, 0, 1); 25532 uvs.push(vertex.x, vertex.y); // world uvs 25533 } // incides 25534 25535 25536 for (let i = 0, l = faces.length; i < l; i++) { 25537 const face = faces[i]; 25538 const a = face[0] + indexOffset; 25539 const b = face[1] + indexOffset; 25540 const c = face[2] + indexOffset; 25541 indices.push(a, b, c); 25542 groupCount += 3; 25543 } 25544 } 25545 } 25546 25547 toJSON() { 25548 const data = super.toJSON(); 25549 const shapes = this.parameters.shapes; 25550 return toJSON(shapes, data); 25551 } 25552 25553 static fromJSON(data, shapes) { 25554 const geometryShapes = []; 25555 25556 for (let j = 0, jl = data.shapes.length; j < jl; j++) { 25557 const shape = shapes[data.shapes[j]]; 25558 geometryShapes.push(shape); 25559 } 25560 25561 return new ShapeGeometry(geometryShapes, data.curveSegments); 25562 } 25563 25564 } 25565 25566 function toJSON(shapes, data) { 25567 data.shapes = []; 25568 25569 if (Array.isArray(shapes)) { 25570 for (let i = 0, l = shapes.length; i < l; i++) { 25571 const shape = shapes[i]; 25572 data.shapes.push(shape.uuid); 25573 } 25574 } else { 25575 data.shapes.push(shapes.uuid); 25576 } 25577 25578 return data; 25579 } 25580 25581 class SphereGeometry extends BufferGeometry { 25582 constructor(radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI) { 25583 super(); 25584 this.type = 'SphereGeometry'; 25585 this.parameters = { 25586 radius: radius, 25587 widthSegments: widthSegments, 25588 heightSegments: heightSegments, 25589 phiStart: phiStart, 25590 phiLength: phiLength, 25591 thetaStart: thetaStart, 25592 thetaLength: thetaLength 25593 }; 25594 widthSegments = Math.max(3, Math.floor(widthSegments)); 25595 heightSegments = Math.max(2, Math.floor(heightSegments)); 25596 const thetaEnd = Math.min(thetaStart + thetaLength, Math.PI); 25597 let index = 0; 25598 const grid = []; 25599 const vertex = new Vector3(); 25600 const normal = new Vector3(); // buffers 25601 25602 const indices = []; 25603 const vertices = []; 25604 const normals = []; 25605 const uvs = []; // generate vertices, normals and uvs 25606 25607 for (let iy = 0; iy <= heightSegments; iy++) { 25608 const verticesRow = []; 25609 const v = iy / heightSegments; // special case for the poles 25610 25611 let uOffset = 0; 25612 25613 if (iy == 0 && thetaStart == 0) { 25614 uOffset = 0.5 / widthSegments; 25615 } else if (iy == heightSegments && thetaEnd == Math.PI) { 25616 uOffset = -0.5 / widthSegments; 25617 } 25618 25619 for (let ix = 0; ix <= widthSegments; ix++) { 25620 const u = ix / widthSegments; // vertex 25621 25622 vertex.x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength); 25623 vertex.y = radius * Math.cos(thetaStart + v * thetaLength); 25624 vertex.z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength); 25625 vertices.push(vertex.x, vertex.y, vertex.z); // normal 25626 25627 normal.copy(vertex).normalize(); 25628 normals.push(normal.x, normal.y, normal.z); // uv 25629 25630 uvs.push(u + uOffset, 1 - v); 25631 verticesRow.push(index++); 25632 } 25633 25634 grid.push(verticesRow); 25635 } // indices 25636 25637 25638 for (let iy = 0; iy < heightSegments; iy++) { 25639 for (let ix = 0; ix < widthSegments; ix++) { 25640 const a = grid[iy][ix + 1]; 25641 const b = grid[iy][ix]; 25642 const c = grid[iy + 1][ix]; 25643 const d = grid[iy + 1][ix + 1]; 25644 if (iy !== 0 || thetaStart > 0) indices.push(a, b, d); 25645 if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c, d); 25646 } 25647 } // build geometry 25648 25649 25650 this.setIndex(indices); 25651 this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 25652 this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); 25653 this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); 25654 } 25655 25656 static fromJSON(data) { 25657 return new SphereGeometry(data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength); 25658 } 25659 25660 } 25661 25662 class TetrahedronGeometry extends PolyhedronGeometry { 25663 constructor(radius = 1, detail = 0) { 25664 const vertices = [1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1]; 25665 const indices = [2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1]; 25666 super(vertices, indices, radius, detail); 25667 this.type = 'TetrahedronGeometry'; 25668 this.parameters = { 25669 radius: radius, 25670 detail: detail 25671 }; 25672 } 25673 25674 static fromJSON(data) { 25675 return new TetrahedronGeometry(data.radius, data.detail); 25676 } 25677 25678 } 25679 25680 class TorusGeometry extends BufferGeometry { 25681 constructor(radius = 1, tube = 0.4, radialSegments = 8, tubularSegments = 6, arc = Math.PI * 2) { 25682 super(); 25683 this.type = 'TorusGeometry'; 25684 this.parameters = { 25685 radius: radius, 25686 tube: tube, 25687 radialSegments: radialSegments, 25688 tubularSegments: tubularSegments, 25689 arc: arc 25690 }; 25691 radialSegments = Math.floor(radialSegments); 25692 tubularSegments = Math.floor(tubularSegments); // buffers 25693 25694 const indices = []; 25695 const vertices = []; 25696 const normals = []; 25697 const uvs = []; // helper variables 25698 25699 const center = new Vector3(); 25700 const vertex = new Vector3(); 25701 const normal = new Vector3(); // generate vertices, normals and uvs 25702 25703 for (let j = 0; j <= radialSegments; j++) { 25704 for (let i = 0; i <= tubularSegments; i++) { 25705 const u = i / tubularSegments * arc; 25706 const v = j / radialSegments * Math.PI * 2; // vertex 25707 25708 vertex.x = (radius + tube * Math.cos(v)) * Math.cos(u); 25709 vertex.y = (radius + tube * Math.cos(v)) * Math.sin(u); 25710 vertex.z = tube * Math.sin(v); 25711 vertices.push(vertex.x, vertex.y, vertex.z); // normal 25712 25713 center.x = radius * Math.cos(u); 25714 center.y = radius * Math.sin(u); 25715 normal.subVectors(vertex, center).normalize(); 25716 normals.push(normal.x, normal.y, normal.z); // uv 25717 25718 uvs.push(i / tubularSegments); 25719 uvs.push(j / radialSegments); 25720 } 25721 } // generate indices 25722 25723 25724 for (let j = 1; j <= radialSegments; j++) { 25725 for (let i = 1; i <= tubularSegments; i++) { 25726 // indices 25727 const a = (tubularSegments + 1) * j + i - 1; 25728 const b = (tubularSegments + 1) * (j - 1) + i - 1; 25729 const c = (tubularSegments + 1) * (j - 1) + i; 25730 const d = (tubularSegments + 1) * j + i; // faces 25731 25732 indices.push(a, b, d); 25733 indices.push(b, c, d); 25734 } 25735 } // build geometry 25736 25737 25738 this.setIndex(indices); 25739 this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 25740 this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); 25741 this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); 25742 } 25743 25744 static fromJSON(data) { 25745 return new TorusGeometry(data.radius, data.tube, data.radialSegments, data.tubularSegments, data.arc); 25746 } 25747 25748 } 25749 25750 class TorusKnotGeometry extends BufferGeometry { 25751 constructor(radius = 1, tube = 0.4, tubularSegments = 64, radialSegments = 8, p = 2, q = 3) { 25752 super(); 25753 this.type = 'TorusKnotGeometry'; 25754 this.parameters = { 25755 radius: radius, 25756 tube: tube, 25757 tubularSegments: tubularSegments, 25758 radialSegments: radialSegments, 25759 p: p, 25760 q: q 25761 }; 25762 tubularSegments = Math.floor(tubularSegments); 25763 radialSegments = Math.floor(radialSegments); // buffers 25764 25765 const indices = []; 25766 const vertices = []; 25767 const normals = []; 25768 const uvs = []; // helper variables 25769 25770 const vertex = new Vector3(); 25771 const normal = new Vector3(); 25772 const P1 = new Vector3(); 25773 const P2 = new Vector3(); 25774 const B = new Vector3(); 25775 const T = new Vector3(); 25776 const N = new Vector3(); // generate vertices, normals and uvs 25777 25778 for (let i = 0; i <= tubularSegments; ++i) { 25779 // the radian "u" is used to calculate the position on the torus curve of the current tubular segement 25780 const u = i / tubularSegments * p * Math.PI * 2; // now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead. 25781 // these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions 25782 25783 calculatePositionOnCurve(u, p, q, radius, P1); 25784 calculatePositionOnCurve(u + 0.01, p, q, radius, P2); // calculate orthonormal basis 25785 25786 T.subVectors(P2, P1); 25787 N.addVectors(P2, P1); 25788 B.crossVectors(T, N); 25789 N.crossVectors(B, T); // normalize B, N. T can be ignored, we don't use it 25790 25791 B.normalize(); 25792 N.normalize(); 25793 25794 for (let j = 0; j <= radialSegments; ++j) { 25795 // now calculate the vertices. they are nothing more than an extrusion of the torus curve. 25796 // because we extrude a shape in the xy-plane, there is no need to calculate a z-value. 25797 const v = j / radialSegments * Math.PI * 2; 25798 const cx = -tube * Math.cos(v); 25799 const cy = tube * Math.sin(v); // now calculate the final vertex position. 25800 // first we orient the extrusion with our basis vectos, then we add it to the current position on the curve 25801 25802 vertex.x = P1.x + (cx * N.x + cy * B.x); 25803 vertex.y = P1.y + (cx * N.y + cy * B.y); 25804 vertex.z = P1.z + (cx * N.z + cy * B.z); 25805 vertices.push(vertex.x, vertex.y, vertex.z); // normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal) 25806 25807 normal.subVectors(vertex, P1).normalize(); 25808 normals.push(normal.x, normal.y, normal.z); // uv 25809 25810 uvs.push(i / tubularSegments); 25811 uvs.push(j / radialSegments); 25812 } 25813 } // generate indices 25814 25815 25816 for (let j = 1; j <= tubularSegments; j++) { 25817 for (let i = 1; i <= radialSegments; i++) { 25818 // indices 25819 const a = (radialSegments + 1) * (j - 1) + (i - 1); 25820 const b = (radialSegments + 1) * j + (i - 1); 25821 const c = (radialSegments + 1) * j + i; 25822 const d = (radialSegments + 1) * (j - 1) + i; // faces 25823 25824 indices.push(a, b, d); 25825 indices.push(b, c, d); 25826 } 25827 } // build geometry 25828 25829 25830 this.setIndex(indices); 25831 this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 25832 this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); 25833 this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // this function calculates the current position on the torus curve 25834 25835 function calculatePositionOnCurve(u, p, q, radius, position) { 25836 const cu = Math.cos(u); 25837 const su = Math.sin(u); 25838 const quOverP = q / p * u; 25839 const cs = Math.cos(quOverP); 25840 position.x = radius * (2 + cs) * 0.5 * cu; 25841 position.y = radius * (2 + cs) * su * 0.5; 25842 position.z = radius * Math.sin(quOverP) * 0.5; 25843 } 25844 } 25845 25846 static fromJSON(data) { 25847 return new TorusKnotGeometry(data.radius, data.tube, data.tubularSegments, data.radialSegments, data.p, data.q); 25848 } 25849 25850 } 25851 25852 class TubeGeometry extends BufferGeometry { 25853 constructor(path = new QuadraticBezierCurve3(new Vector3(-1, -1, 0), new Vector3(-1, 1, 0), new Vector3(1, 1, 0)), tubularSegments = 64, radius = 1, radialSegments = 8, closed = false) { 25854 super(); 25855 this.type = 'TubeGeometry'; 25856 this.parameters = { 25857 path: path, 25858 tubularSegments: tubularSegments, 25859 radius: radius, 25860 radialSegments: radialSegments, 25861 closed: closed 25862 }; 25863 const frames = path.computeFrenetFrames(tubularSegments, closed); // expose internals 25864 25865 this.tangents = frames.tangents; 25866 this.normals = frames.normals; 25867 this.binormals = frames.binormals; // helper variables 25868 25869 const vertex = new Vector3(); 25870 const normal = new Vector3(); 25871 const uv = new Vector2(); 25872 let P = new Vector3(); // buffer 25873 25874 const vertices = []; 25875 const normals = []; 25876 const uvs = []; 25877 const indices = []; // create buffer data 25878 25879 generateBufferData(); // build geometry 25880 25881 this.setIndex(indices); 25882 this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 25883 this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); 25884 this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // functions 25885 25886 function generateBufferData() { 25887 for (let i = 0; i < tubularSegments; i++) { 25888 generateSegment(i); 25889 } // if the geometry is not closed, generate the last row of vertices and normals 25890 // at the regular position on the given path 25891 // 25892 // if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ) 25893 25894 25895 generateSegment(closed === false ? tubularSegments : 0); // uvs are generated in a separate function. 25896 // this makes it easy compute correct values for closed geometries 25897 25898 generateUVs(); // finally create faces 25899 25900 generateIndices(); 25901 } 25902 25903 function generateSegment(i) { 25904 // we use getPointAt to sample evenly distributed points from the given path 25905 P = path.getPointAt(i / tubularSegments, P); // retrieve corresponding normal and binormal 25906 25907 const N = frames.normals[i]; 25908 const B = frames.binormals[i]; // generate normals and vertices for the current segment 25909 25910 for (let j = 0; j <= radialSegments; j++) { 25911 const v = j / radialSegments * Math.PI * 2; 25912 const sin = Math.sin(v); 25913 const cos = -Math.cos(v); // normal 25914 25915 normal.x = cos * N.x + sin * B.x; 25916 normal.y = cos * N.y + sin * B.y; 25917 normal.z = cos * N.z + sin * B.z; 25918 normal.normalize(); 25919 normals.push(normal.x, normal.y, normal.z); // vertex 25920 25921 vertex.x = P.x + radius * normal.x; 25922 vertex.y = P.y + radius * normal.y; 25923 vertex.z = P.z + radius * normal.z; 25924 vertices.push(vertex.x, vertex.y, vertex.z); 25925 } 25926 } 25927 25928 function generateIndices() { 25929 for (let j = 1; j <= tubularSegments; j++) { 25930 for (let i = 1; i <= radialSegments; i++) { 25931 const a = (radialSegments + 1) * (j - 1) + (i - 1); 25932 const b = (radialSegments + 1) * j + (i - 1); 25933 const c = (radialSegments + 1) * j + i; 25934 const d = (radialSegments + 1) * (j - 1) + i; // faces 25935 25936 indices.push(a, b, d); 25937 indices.push(b, c, d); 25938 } 25939 } 25940 } 25941 25942 function generateUVs() { 25943 for (let i = 0; i <= tubularSegments; i++) { 25944 for (let j = 0; j <= radialSegments; j++) { 25945 uv.x = i / tubularSegments; 25946 uv.y = j / radialSegments; 25947 uvs.push(uv.x, uv.y); 25948 } 25949 } 25950 } 25951 } 25952 25953 toJSON() { 25954 const data = super.toJSON(); 25955 data.path = this.parameters.path.toJSON(); 25956 return data; 25957 } 25958 25959 static fromJSON(data) { 25960 // This only works for built-in curves (e.g. CatmullRomCurve3). 25961 // User defined curves or instances of CurvePath will not be deserialized. 25962 return new TubeGeometry(new Curves[data.path.type]().fromJSON(data.path), data.tubularSegments, data.radius, data.radialSegments, data.closed); 25963 } 25964 25965 } 25966 25967 class WireframeGeometry extends BufferGeometry { 25968 constructor(geometry = null) { 25969 super(); 25970 this.type = 'WireframeGeometry'; 25971 this.parameters = { 25972 geometry: geometry 25973 }; 25974 25975 if (geometry !== null) { 25976 // buffer 25977 const vertices = []; 25978 const edges = new Set(); // helper variables 25979 25980 const start = new Vector3(); 25981 const end = new Vector3(); 25982 25983 if (geometry.index !== null) { 25984 // indexed BufferGeometry 25985 const position = geometry.attributes.position; 25986 const indices = geometry.index; 25987 let groups = geometry.groups; 25988 25989 if (groups.length === 0) { 25990 groups = [{ 25991 start: 0, 25992 count: indices.count, 25993 materialIndex: 0 25994 }]; 25995 } // create a data structure that contains all eges without duplicates 25996 25997 25998 for (let o = 0, ol = groups.length; o < ol; ++o) { 25999 const group = groups[o]; 26000 const groupStart = group.start; 26001 const groupCount = group.count; 26002 26003 for (let i = groupStart, l = groupStart + groupCount; i < l; i += 3) { 26004 for (let j = 0; j < 3; j++) { 26005 const index1 = indices.getX(i + j); 26006 const index2 = indices.getX(i + (j + 1) % 3); 26007 start.fromBufferAttribute(position, index1); 26008 end.fromBufferAttribute(position, index2); 26009 26010 if (isUniqueEdge(start, end, edges) === true) { 26011 vertices.push(start.x, start.y, start.z); 26012 vertices.push(end.x, end.y, end.z); 26013 } 26014 } 26015 } 26016 } 26017 } else { 26018 // non-indexed BufferGeometry 26019 const position = geometry.attributes.position; 26020 26021 for (let i = 0, l = position.count / 3; i < l; i++) { 26022 for (let j = 0; j < 3; j++) { 26023 // three edges per triangle, an edge is represented as (index1, index2) 26024 // e.g. the first triangle has the following edges: (0,1),(1,2),(2,0) 26025 const index1 = 3 * i + j; 26026 const index2 = 3 * i + (j + 1) % 3; 26027 start.fromBufferAttribute(position, index1); 26028 end.fromBufferAttribute(position, index2); 26029 26030 if (isUniqueEdge(start, end, edges) === true) { 26031 vertices.push(start.x, start.y, start.z); 26032 vertices.push(end.x, end.y, end.z); 26033 } 26034 } 26035 } 26036 } // build geometry 26037 26038 26039 this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 26040 } 26041 } 26042 26043 } 26044 26045 function isUniqueEdge(start, end, edges) { 26046 const hash1 = `${start.x},${start.y},${start.z}-${end.x},${end.y},${end.z}`; 26047 const hash2 = `${end.x}
26047,${end.y},${end.z}-${start.x},${start.y},${start.z}`; // coincident edge 26048 26049 if (edges.has(hash1) === true || edges.has(hash2) === true) { 26050 return false; 26051 } else { 26052 edges.add(hash1, hash2); 26053 return true; 26054 } 26055 } 26056 26057 var Geometries = /*#__PURE__*/Object.freeze({ 26058 __proto__: null, 26059 BoxGeometry: BoxGeometry, 26060 BoxBufferGeometry: BoxGeometry, 26061 CircleGeometry: CircleGeometry, 26062 CircleBufferGeometry: CircleGeometry, 26063 ConeGeometry: ConeGeometry, 26064 ConeBufferGeometry: ConeGeometry, 26065 CylinderGeometry: CylinderGeometry, 26066 CylinderBufferGeometry: CylinderGeometry, 26067 DodecahedronGeometry: DodecahedronGeometry, 26068 DodecahedronBufferGeometry: DodecahedronGeometry, 26069 EdgesGeometry: EdgesGeometry, 26070 ExtrudeGeometry: ExtrudeGeometry, 26071 ExtrudeBufferGeometry: ExtrudeGeometry, 26072 IcosahedronGeometry: IcosahedronGeometry, 26073 IcosahedronBufferGeometry: IcosahedronGeometry, 26074 LatheGeometry: LatheGeometry, 26075 LatheBufferGeometry: LatheGeometry, 26076 OctahedronGeometry: OctahedronGeometry, 26077 OctahedronBufferGeometry: OctahedronGeometry, 26078 PlaneGeometry: PlaneGeometry, 26079 PlaneBufferGeometry: PlaneGeometry, 26080 PolyhedronGeometry: PolyhedronGeometry, 26081 PolyhedronBufferGeometry: PolyhedronGeometry, 26082 RingGeometry: RingGeometry, 26083 RingBufferGeometry: RingGeometry, 26084 ShapeGeometry: ShapeGeometry, 26085 ShapeBufferGeometry: ShapeGeometry, 26086 SphereGeometry: SphereGeometry, 26087 SphereBufferGeometry: SphereGeometry, 26088 TetrahedronGeometry: TetrahedronGeometry, 26089 TetrahedronBufferGeometry: TetrahedronGeometry, 26090 TorusGeometry: TorusGeometry, 26091 TorusBufferGeometry: TorusGeometry, 26092 TorusKnotGeometry: TorusKnotGeometry, 26093 TorusKnotBufferGeometry: TorusKnotGeometry, 26094 TubeGeometry: TubeGeometry, 26095 TubeBufferGeometry: TubeGeometry, 26096 WireframeGeometry: WireframeGeometry 26097 }); 26098 26099 /** 26100 * parameters = { 26101 * color: <THREE.Color> 26102 * } 26103 */ 26104 26105 class ShadowMaterial extends Material { 26106 constructor(parameters) { 26107 super(); 26108 this.type = 'ShadowMaterial'; 26109 this.color = new Color(0x000000); 26110 this.transparent = true; 26111 this.setValues(parameters); 26112 } 26113 26114 copy(source) { 26115 super.copy(source); 26116 this.color.copy(source.color); 26117 return this; 26118 } 26119 26120 } 26121 26122 ShadowMaterial.prototype.isShadowMaterial = true; 26123 26124 /** 26125 * parameters = { 26126 * color: <hex>, 26127 * roughness: <float>, 26128 * metalness: <float>, 26129 * opacity: <float>, 26130 * 26131 * map: new THREE.Texture( <Image> ), 26132 * 26133 * lightMap: new THREE.Texture( <Image> ), 26134 * lightMapIntensity: <float> 26135 * 26136 * aoMap: new THREE.Texture( <Image> ), 26137 * aoMapIntensity: <float> 26138 * 26139 * emissive: <hex>, 26140 * emissiveIntensity: <float> 26141 * emissiveMap: new THREE.Texture( <Image> ), 26142 * 26143 * bumpMap: new THREE.Texture( <Image> ), 26144 * bumpScale: <float>, 26145 * 26146 * normalMap: new THREE.Texture( <Image> ), 26147 * normalMapType: THREE.TangentSpaceNormalMap, 26148 * normalScale: <Vector2>, 26149 * 26150 * displacementMap: new THREE.Texture( <Image> ), 26151 * displacementScale: <float>, 26152 * displacementBias: <float>, 26153 * 26154 * roughnessMap: new THREE.Texture( <Image> ), 26155 * 26156 * metalnessMap: new THREE.Texture( <Image> ), 26157 * 26158 * alphaMap: new THREE.Texture( <Image> ), 26159 * 26160 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), 26161 * envMapIntensity: <float> 26162 * 26163 * refractionRatio: <float>, 26164 * 26165 * wireframe: <boolean>, 26166 * wireframeLinewidth: <float>, 26167 * 26168 * flatShading: <bool> 26169 * } 26170 */ 26171 26172 class MeshStandardMaterial extends Material { 26173 constructor(parameters) { 26174 super(); 26175 this.defines = { 26176 'STANDARD': '' 26177 }; 26178 this.type = 'MeshStandardMaterial'; 26179 this.color = new Color(0xffffff); // diffuse 26180 26181 this.roughness = 1.0; 26182 this.metalness = 0.0; 26183 this.map = null; 26184 this.lightMap = null; 26185 this.lightMapIntensity = 1.0; 26186 this.aoMap = null; 26187 this.aoMapIntensity = 1.0; 26188 this.emissive = new Color(0x000000); 26189 this.emissiveIntensity = 1.0; 26190 this.emissiveMap = null; 26191 this.bumpMap = null; 26192 this.bumpScale = 1; 26193 this.normalMap = null; 26194 this.normalMapType = TangentSpaceNormalMap; 26195 this.normalScale = new Vector2(1, 1); 26196 this.displacementMap = null; 26197 this.displacementScale = 1; 26198 this.displacementBias = 0; 26199 this.roughnessMap = null; 26200 this.metalnessMap = null; 26201 this.alphaMap = null; 26202 this.envMap = null; 26203 this.envMapIntensity = 1.0; 26204 this.refractionRatio = 0.98; 26205 this.wireframe = false;
vendor: 6,184 bytes, lines 26206-26424
26206 this.wireframeLinewidth = 1; 26207 this.wireframeLinecap = 'round'; 26208 this.wireframeLinejoin = 'round'; 26209 this.flatShading = false; 26210 this.setValues(parameters); 26211 } 26212 26213 copy(source) { 26214 super.copy(source); 26215 this.defines = { 26216 'STANDARD': '' 26217 }; 26218 this.color.copy(source.color); 26219 this.roughness = source.roughness; 26220 this.metalness = source.metalness; 26221 this.map = source.map; 26222 this.lightMap = source.lightMap; 26223 this.lightMapIntensity = source.lightMapIntensity; 26224 this.aoMap = source.aoMap; 26225 this.aoMapIntensity = source.aoMapIntensity; 26226 this.emissive.copy(source.emissive); 26227 this.emissiveMap = source.emissiveMap; 26228 this.emissiveIntensity = source.emissiveIntensity; 26229 this.bumpMap = source.bumpMap; 26230 this.bumpScale = source.bumpScale; 26231 this.normalMap = source.normalMap; 26232 this.normalMapType = source.normalMapType; 26233 this.normalScale.copy(source.normalScale); 26234 this.displacementMap = source.displacementMap; 26235 this.displacementScale = source.displacementScale; 26236 this.displacementBias = source.displacementBias; 26237 this.roughnessMap = source.roughnessMap; 26238 this.metalnessMap = source.metalnessMap; 26239 this.alphaMap = source.alphaMap; 26240 this.envMap = source.envMap; 26241 this.envMapIntensity = source.envMapIntensity; 26242 this.refractionRatio = source.refractionRatio; 26243 this.wireframe = source.wireframe; 26244 this.wireframeLinewidth = source.wireframeLinewidth; 26245 this.wireframeLinecap = source.wireframeLinecap; 26246 this.wireframeLinejoin = source.wireframeLinejoin; 26247 this.flatShading = source.flatShading; 26248 return this; 26249 } 26250 26251 } 26252 26253 MeshStandardMaterial.prototype.isMeshStandardMaterial = true; 26254 26255 /** 26256 * parameters = { 26257 * clearcoat: <float>, 26258 * clearcoatMap: new THREE.Texture( <Image> ), 26259 * clearcoatRoughness: <float>, 26260 * clearcoatRoughnessMap: new THREE.Texture( <Image> ), 26261 * clearcoatNormalScale: <Vector2>, 26262 * clearcoatNormalMap: new THREE.Texture( <Image> ), 26263 * 26264 * ior: <float>, 26265 * reflectivity: <float>, 26266 * 26267 * sheen: <float>, 26268 * sheenColor: <Color>, 26269 * sheenColorMap: new THREE.Texture( <Image> ), 26270 * sheenRoughness: <float>, 26271 * sheenRoughnessMap: new THREE.Texture( <Image> ), 26272 * 26273 * transmission: <float>, 26274 * transmissionMap: new THREE.Texture( <Image> ), 26275 * 26276 * thickness: <float>, 26277 * thicknessMap: new THREE.Texture( <Image> ), 26278 * attenuationDistance: <float>, 26279 * attenuationColor: <Color>, 26280 * 26281 * specularIntensity: <float>, 26282 * specularIntensityMap: new THREE.Texture( <Image> ), 26283 * specularColor: <Color>, 26284 * specularColorMap: new THREE.Texture( <Image> ) 26285 * } 26286 */ 26287 26288 class MeshPhysicalMaterial extends MeshStandardMaterial { 26289 constructor(parameters) { 26290 super(); 26291 this.defines = { 26292 'STANDARD': '', 26293 'PHYSICAL': '' 26294 }; 26295 this.type = 'MeshPhysicalMaterial'; 26296 this.clearcoatMap = null; 26297 this.clearcoatRoughness = 0.0; 26298 this.clearcoatRoughnessMap = null; 26299 this.clearcoatNormalScale = new Vector2(1, 1); 26300 this.clearcoatNormalMap = null; 26301 this.ior = 1.5; 26302 Object.defineProperty(this, 'reflectivity', { 26303 get: function () { 26304 return clamp(2.5 * (this.ior - 1) / (this.ior + 1), 0, 1); 26305 }, 26306 set: function (reflectivity) { 26307 this.ior = (1 + 0.4 * reflectivity) / (1 - 0.4 * reflectivity); 26308 } 26309 }); 26310 this.sheenColor = new Color(0x000000); 26311 this.sheenColorMap = null; 26312 this.sheenRoughness = 1.0; 26313 this.sheenRoughnessMap = null; 26314 this.transmissionMap = null; 26315 this.thickness = 0; 26316 this.thicknessMap = null; 26317 this.attenuationDistance = 0.0; 26318 this.attenuationColor = new Color(1, 1, 1); 26319 this.specularIntensity = 1.0; 26320 this.specularIntensityMap = null; 26321 this.specularColor = new Color(1, 1, 1); 26322 this.specularColorMap = null; 26323 this._sheen = 0.0; 26324 this._clearcoat = 0; 26325 this._transmission = 0; 26326 this.setValues(parameters); 26327 } 26328 26329 get sheen() { 26330 return this._sheen; 26331 } 26332 26333 set sheen(value) { 26334 if (this._sheen > 0 !== value > 0) { 26335 this.version++; 26336 } 26337 26338 this._sheen = value; 26339 } 26340 26341 get clearcoat() { 26342 return this._clearcoat; 26343 } 26344 26345 set clearcoat(value) { 26346 if (this._clearcoat > 0 !== value > 0) { 26347 this.version++; 26348 } 26349 26350 this._clearcoat = value; 26351 } 26352 26353 get transmission() { 26354 return this._transmission; 26355 } 26356 26357 set transmission(value) { 26358 if (this._transmission > 0 !== value > 0) { 26359 this.version++; 26360 } 26361 26362 this._transmission = value; 26363 } 26364 26365 copy(source) { 26366 super.copy(source); 26367 this.defines = { 26368 'STANDARD': '', 26369 'PHYSICAL': '' 26370 }; 26371 this.clearcoat = source.clearcoat; 26372 this.clearcoatMap = source.clearcoatMap; 26373 this.clearcoatRoughness = source.clearcoatRoughness; 26374 this.clearcoatRoughnessMap = source.clearcoatRoughnessMap; 26375 this.clearcoatNormalMap = source.clearcoatNormalMap; 26376 this.clearcoatNormalScale.copy(source.clearcoatNormalScale); 26377 this.ior = source.ior; 26378 this.sheen = source.sheen; 26379 this.sheenColor.copy(source.sheenColor); 26380 this.sheenColorMap = source.sheenColorMap; 26381 this.sheenRoughness = source.sheenRoughness; 26382 this.sheenRoughnessMap = source.sheenRoughnessMap; 26383 this.transmission = source.transmission; 26384 this.transmissionMap = source.transmissionMap; 26385 this.thickness = source.thickness; 26386 this.thicknessMap = source.thicknessMap; 26387 this.attenuationDistance = source.attenuationDistance; 26388 this.attenuationColor.copy(source.attenuationColor); 26389 this.specularIntensity = source.specularIntensity; 26390 this.specularIntensityMap = source.specularIntensityMap; 26391 this.specularColor.copy(source.specularColor); 26392 this.specularColorMap = source.specularColorMap; 26393 return this; 26394 } 26395 26396 } 26397 26398 MeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true; 26399 26400 /** 26401 * parameters = { 26402 * color: <hex>, 26403 * specular: <hex>, 26404 * shininess: <float>, 26405 * opacity: <float>, 26406 * 26407 * map: new THREE.Texture( <Image> ), 26408 * 26409 * lightMap: new THREE.Texture( <Image> ), 26410 * lightMapIntensity: <float> 26411 * 26412 * aoMap: new THREE.Texture( <Image> ), 26413 * aoMapIntensity: <float> 26414 * 26415 * emissive: <hex>, 26416 * emissiveIntensity: <float> 26417 * emissiveMap: new THREE.Texture( <Image> ), 26418 * 26419 * bumpMap: new THREE.Texture( <Image> ), 26420 * bumpScale: <float>, 26421 * 26422 * normalMap: new THREE.Texture( <Image> ), 26423 * normalMapType: THREE.TangentSpaceNormalMap, 26424 * normalScale: <Vector2>,
26425 * 26426 * displacementMap: new THREE.Texture( <Image> ), 26427 * displacementScale: <float>, 26428 * displacementBias: <float>, 26429 * 26430 * specularMap: new THREE.Texture( <Image> ), 26431 * 26432 * alphaMap: new THREE.Texture( <Image> ), 26433 * 26434 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), 26435 * combine: THREE.MultiplyOperation, 26436 * reflectivity: <float>, 26437 * refractionRatio: <float>, 26438 * 26439 * wireframe: <boolean>, 26440 * wireframeLinewidth: <float>, 26441 * 26442 * flatShading: <bool> 26443 * } 26444 */ 26445 26446 class MeshPhongMaterial extends Material { 26447 constructor(parameters) { 26448 super(); 26449 this.type = 'MeshPhongMaterial'; 26450 this.color = new Color(0xffffff); // diffuse 26451 26452 this.specular = new Color(0x111111); 26453 this.shininess = 30; 26454 this.map = null; 26455 this.lightMap = null; 26456 this.lightMapIntensity = 1.0; 26457 this.aoMap = null; 26458 this.aoMapIntensity = 1.0; 26459 this.emissive = new Color(0x000000); 26460 this.emissiveIntensity = 1.0; 26461 this.emissiveMap = null; 26462 this.bumpMap = null; 26463 this.bumpScale = 1; 26464 this.normalMap = null; 26465 this.normalMapType = TangentSpaceNormalMap; 26466 this.normalScale = new Vector2(1, 1); 26467 this.displacementMap = null; 26468 this.displacementScale = 1; 26469 this.displacementBias = 0; 26470 this.specularMap = null; 26471 this.alphaMap = null; 26472 this.envMap = null; 26473 this.combine = MultiplyOperation; 26474 this.reflectivity = 1; 26475 this.refractionRatio = 0.98; 26476 this.wireframe = false; 26477 this.wireframeLinewidth = 1; 26478 this.wireframeLinecap = 'round'; 26479 this.wireframeLinejoin = 'round'; 26480 this.flatShading = false; 26481 this.setValues(parameters); 26482 } 26483 26484 copy(source) { 26485 super.copy(source); 26486 this.color.copy(source.color); 26487 this.specular.copy(source.specular); 26488 this.shininess = source.shininess; 26489 this.map = source.map; 26490 this.lightMap = source.lightMap; 26491 this.lightMapIntensity = source.lightMapIntensity; 26492 this.aoMap = source.aoMap; 26493 this.aoMapIntensity = source.aoMapIntensity; 26494 this.emissive.copy(source.emissive); 26495 this.emissiveMap = source.emissiveMap; 26496 this.emissiveIntensity = source.emissiveIntensity; 26497 this.bumpMap = source.bumpMap; 26498 this.bumpScale = source.bumpScale; 26499 this.normalMap = source.normalMap; 26500 this.normalMapType = source.normalMapType; 26501 this.normalScale.copy(source.normalScale); 26502 this.displacementMap = source.displacementMap; 26503 this.displacementScale = source.displacementScale; 26504 this.displacementBias = source.displacementBias; 26505 this.specularMap = source.specularMap; 26506 this.alphaMap = source.alphaMap; 26507 this.envMap = source.envMap; 26508 this.combine = source.combine; 26509 this.reflectivity = source.reflectivity; 26510 this.refractionRatio = source.refractionRatio; 26511 this.wireframe = source.wireframe; 26512 this.wireframeLinewidth = source.wireframeLinewidth; 26513 this.wireframeLinecap = source.wireframeLinecap; 26514 this.wireframeLinejoin = source.wireframeLinejoin; 26515 this.flatShading = source.flatShading; 26516 return this; 26517 } 26518 26519 } 26520 26521 MeshPhongMaterial.prototype.isMeshPhongMaterial = true; 26522 26523 /** 26524 * parameters = { 26525 * color: <hex>, 26526 * 26527 * map: new THREE.Texture( <Image> ), 26528 * gradientMap: new THREE.Texture( <Image> ), 26529 * 26530 * lightMap: new THREE.Texture( <Image> ), 26531 * lightMapIntensity: <float> 26532 * 26533 * aoMap: new THREE.Texture( <Image> ), 26534 * aoMapIntensity: <float> 26535 * 26536 * emissive: <hex>, 26537 * emissiveIntensity: <float> 26538 * emissiveMap: new THREE.Texture( <Image> ), 26539 * 26540 * bumpMap: new THREE.Texture( <Image> ), 26541 * bumpScale: <float>, 26542 * 26543 * normalMap: new THREE.Texture( <Image> ), 26544 * normalMapType: THREE.TangentSpaceNormalMap, 26545 * normalScale: <Vector2>, 26546 * 26547 * displacementMap: new THREE.Texture( <Image> ), 26548 * displacementScale: <float>, 26549 * displacementBias: <float>, 26550 * 26551 * alphaMap: new THREE.Texture( <Image> ), 26552 * 26553 * wireframe: <boolean>, 26554 * wireframeLinewidth: <float>, 26555 * 26556 * } 26557 */ 26558 26559 class MeshToonMaterial extends Material { 26560 constructor(parameters) { 26561 super(); 26562 this.defines = { 26563 'TOON': '' 26564 }; 26565 this.type = 'MeshToonMaterial'; 26566 this.color = new Color(0xffffff); 26567 this.map = null; 26568 this.gradientMap = null; 26569 this.lightMap = null; 26570 this.lightMapIntensity = 1.0; 26571 this.aoMap = null; 26572 this.aoMapIntensity = 1.0; 26573 this.emissive = new Color(0x000000); 26574 this.emissiveIntensity = 1.0; 26575 this.emissiveMap = null; 26576 this.bumpMap = null; 26577 this.bumpScale = 1; 26578 this.normalMap = null; 26579 this.normalMapType = TangentSpaceNormalMap; 26580 this.normalScale = new Vector2(1, 1); 26581 this.displacementMap = null; 26582 this.displacementScale = 1; 26583 this.displacementBias = 0; 26584 this.alphaMap = null; 26585 this.wireframe = false;
26586 this.wireframeLinewidth = 1; 26587 this.wireframeLinecap = 'round'; 26588 this.wireframeLinejoin = 'round'; 26589 this.setValues(parameters); 26590 } 26591 26592 copy(source) { 26593 super.copy(source); 26594 this.color.copy(source.color); 26595 this.map = source.map; 26596 this.gradientMap = source.gradientMap; 26597 this.lightMap = source.lightMap; 26598 this.lightMapIntensity = source.lightMapIntensity; 26599 this.aoMap = source.aoMap; 26600 this.aoMapIntensity = source.aoMapIntensity; 26601 this.emissive.copy(source.emissive); 26602 this.emissiveMap = source.emissiveMap; 26603 this.emissiveIntensity = source.emissiveIntensity; 26604 this.bumpMap = source.bumpMap; 26605 this.bumpScale = source.bumpScale; 26606 this.normalMap = source.normalMap; 26607 this.normalMapType = source.normalMapType; 26608 this.normalScale.copy(source.normalScale); 26609 this.displacementMap = source.displacementMap; 26610 this.displacementScale = source.displacementScale; 26611 this.displacementBias = source.displacementBias; 26612 this.alphaMap = source.alphaMap; 26613 this.wireframe = source.wireframe; 26614 this.wireframeLinewidth = source.wireframeLinewidth; 26615 this.wireframeLinecap = source.wireframeLinecap; 26616 this.wireframeLinejoin = source.wireframeLinejoin; 26617 return this; 26618 } 26619 26620 } 26621 26622 MeshToonMaterial.prototype.isMeshToonMaterial = true; 26623 26624 /** 26625 * parameters = { 26626 * opacity: <float>, 26627 * 26628 * bumpMap: new THREE.Texture( <Image> ), 26629 * bumpScale: <float>, 26630 * 26631 * normalMap: new THREE.Texture( <Image> ), 26632 * normalMapType: THREE.TangentSpaceNormalMap, 26633 * normalScale: <Vector2>, 26634 * 26635 * displacementMap: new THREE.Texture( <Image> ), 26636 * displacementScale: <float>, 26637 * displacementBias: <float>, 26638 * 26639 * wireframe: <boolean>, 26640 * wireframeLinewidth: <float> 26641 * 26642 * flatShading: <bool> 26643 * } 26644 */ 26645 26646 class MeshNormalMaterial extends Material { 26647 constructor(parameters) { 26648 super(); 26649 this.type = 'MeshNormalMaterial'; 26650 this.bumpMap = null; 26651 this.bumpScale = 1; 26652 this.normalMap = null; 26653 this.normalMapType = TangentSpaceNormalMap; 26654 this.normalScale = new Vector2(1, 1); 26655 this.displacementMap = null; 26656 this.displacementScale = 1; 26657 this.displacementBias = 0; 26658 this.wireframe = false; 26659 this.wireframeLinewidth = 1; 26660 this.fog = false; 26661 this.flatShading = false; 26662 this.setValues(parameters); 26663 } 26664 26665 copy(source) { 26666 super.copy(source); 26667 this.bumpMap = source.bumpMap; 26668 this.bumpScale = source.bumpScale; 26669 this.normalMap = source.normalMap; 26670 this.normalMapType = source.normalMapType; 26671 this.normalScale.copy(source.normalScale); 26672 this.displacementMap = source.displacementMap; 26673 this.displacementScale = source.displacementScale; 26674 this.displacementBias = source.displacementBias; 26675 this.wireframe = source.wireframe; 26676 this.wireframeLinewidth = source.wireframeLinewidth; 26677 this.flatShading = source.flatShading; 26678 return this; 26679 } 26680 26681 } 26682 26683 MeshNormalMaterial.prototype.isMeshNormalMaterial = true; 26684 26685 /** 26686 * parameters = { 26687 * color: <hex>, 26688 * opacity: <float>, 26689 * 26690 * map: new THREE.Texture( <Image> ), 26691 * 26692 * lightMap: new THREE.Texture( <Image> ), 26693 * lightMapIntensity: <float> 26694 * 26695 * aoMap: new THREE.Texture( <Image> ), 26696 * aoMapIntensity: <float> 26697 * 26698 * emissive: <hex>, 26699 * emissiveIntensity: <float> 26700 * emissiveMap: new THREE.Texture( <Image> ), 26701 * 26702 * specularMap: new THREE.Texture( <Image> ), 26703 * 26704 * alphaMap: new THREE.Texture( <Image> ), 26705 * 26706 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), 26707 * combine: THREE.Multiply, 26708 * reflectivity: <float>, 26709 * refractionRatio: <float>, 26710 * 26711 * wireframe: <boolean>, 26712 * wireframeLinewidth: <float>, 26713 * 26714 * } 26715 */ 26716 26717 class MeshLambertMaterial extends Material { 26718 constructor(parameters) { 26719 super(); 26720 this.type = 'MeshLambertMaterial'; 26721 this.color = new Color(0xffffff); // diffuse 26722 26723 this.map = null; 26724 this.lightMap = null; 26725 this.lightMapIntensity = 1.0; 26726 this.aoMap = null; 26727 this.aoMapIntensity = 1.0; 26728 this.emissive = new Color(0x000000); 26729 this.emissiveIntensity = 1.0; 26730 this.emissiveMap = null; 26731 this.specularMap = null; 26732 this.alphaMap = null; 26733 this.envMap = null; 26734 this.combine = MultiplyOperation; 26735 this.reflectivity = 1; 26736 this.refractionRatio = 0.98; 26737 this.wireframe = false;
26738 this.wireframeLinewidth = 1; 26739 this.wireframeLinecap = 'round'; 26740 this.wireframeLinejoin = 'round'; 26741 this.setValues(parameters); 26742 } 26743 26744 copy(source) { 26745 super.copy(source); 26746 this.color.copy(source.color); 26747 this.map = source.map; 26748 this.lightMap = source.lightMap; 26749 this.lightMapIntensity = source.lightMapIntensity; 26750 this.aoMap = source.aoMap; 26751 this.aoMapIntensity = source.aoMapIntensity; 26752 this.emissive.copy(source.emissive); 26753 this.emissiveMap = source.emissiveMap; 26754 this.emissiveIntensity = source.emissiveIntensity; 26755 this.specularMap = source.specularMap; 26756 this.alphaMap = source.alphaMap; 26757 this.envMap = source.envMap; 26758 this.combine = source.combine; 26759 this.reflectivity = source.reflectivity; 26760 this.refractionRatio = source.refractionRatio; 26761 this.wireframe = source.wireframe; 26762 this.wireframeLinewidth = source.wireframeLinewidth; 26763 this.wireframeLinecap = source.wireframeLinecap; 26764 this.wireframeLinejoin = source.wireframeLinejoin; 26765 return this; 26766 } 26767 26768 } 26769 26770 MeshLambertMaterial.prototype.isMeshLambertMaterial = true; 26771 26772 /** 26773 * parameters = { 26774 * color: <hex>, 26775 * opacity: <float>, 26776 * 26777 * matcap: new THREE.Texture( <Image> ), 26778 * 26779 * map: new THREE.Texture( <Image> ), 26780 * 26781 * bumpMap: new THREE.Texture( <Image> ), 26782 * bumpScale: <float>, 26783 * 26784 * normalMap: new THREE.Texture( <Image> ), 26785 * normalMapType: THREE.TangentSpaceNormalMap, 26786 * normalScale: <Vector2>, 26787 * 26788 * displacementMap: new THREE.Texture( <Image> ), 26789 * displacementScale: <float>, 26790 * displacementBias: <float>, 26791 * 26792 * alphaMap: new THREE.Texture( <Image> ), 26793 * 26794 * flatShading: <bool> 26795 * } 26796 */ 26797 26798 class MeshMatcapMaterial extends Material { 26799 constructor(parameters) { 26800 super(); 26801 this.defines = { 26802 'MATCAP': '' 26803 }; 26804 this.type = 'MeshMatcapMaterial'; 26805 this.color = new Color(0xffffff); // diffuse 26806 26807 this.matcap = null; 26808 this.map = null; 26809 this.bumpMap = null; 26810 this.bumpScale = 1; 26811 this.normalMap = null; 26812 this.normalMapType = TangentSpaceNormalMap; 26813 this.normalScale = new Vector2(1, 1); 26814 this.displacementMap = null; 26815 this.displacementScale = 1; 26816 this.displacementBias = 0; 26817 this.alphaMap = null; 26818 this.flatShading = false; 26819 this.setValues(parameters); 26820 } 26821 26822 copy(source) { 26823 super.copy(source); 26824 this.defines = { 26825 'MATCAP': '' 26826 }; 26827 this.color.copy(source.color); 26828 this.matcap = source.matcap; 26829 this.map = source.map; 26830 this.bumpMap = source.bumpMap; 26831 this.bumpScale = source.bumpScale; 26832 this.normalMap = source.normalMap; 26833 this.normalMapType = source.normalMapType; 26834 this.normalScale.copy(source.normalScale); 26835 this.displacementMap = source.displacementMap; 26836 this.displacementScale = source.displacementScale; 26837 this.displacementBias = source.displacementBias; 26838 this.alphaMap = source.alphaMap; 26839 this.flatShading = source.flatShading; 26840 return this; 26841 } 26842 26843 } 26844 26845 MeshMatcapMaterial.prototype.isMeshMatcapMaterial = true; 26846 26847 /** 26848 * parameters = { 26849 * color: <hex>, 26850 * opacity: <float>, 26851 * 26852 * linewidth: <float>, 26853 * 26854 * scale: <float>, 26855 * dashSize: <float>, 26856 * gapSize: <float> 26857 * } 26858 */ 26859 26860 class LineDashedMaterial extends LineBasicMaterial { 26861 constructor(parameters) { 26862 super(); 26863 this.type = 'LineDashedMaterial'; 26864 this.scale = 1; 26865 this.dashSize = 3; 26866 this.gapSize = 1; 26867 this.setValues(parameters); 26868 } 26869 26870 copy(source) { 26871 super.copy(source); 26872 this.scale = source.scale; 26873 this.dashSize = source.dashSize; 26874 this.gapSize = source.gapSize; 26875 return this; 26876 } 26877 26878 } 26879 26880 LineDashedMaterial.prototype.isLineDashedMaterial = true; 26881 26882 var Materials = /*#__PURE__*/Object.freeze({ 26883 __proto__: null, 26884 ShadowMaterial: ShadowMaterial, 26885 SpriteMaterial: SpriteMaterial, 26886 RawShaderMaterial: RawShaderMaterial, 26887 ShaderMaterial: ShaderMaterial, 26888 PointsMaterial: PointsMaterial, 26889 MeshPhysicalMaterial: MeshPhysicalMaterial, 26890 MeshStandardMaterial: MeshStandardMaterial, 26891 MeshPhongMaterial: MeshPhongMaterial, 26892 MeshToonMaterial: MeshToonMaterial, 26893 MeshNormalMaterial: MeshNormalMaterial, 26894 MeshLambertMaterial: MeshLambertMaterial, 26895 MeshDepthMaterial: MeshDepthMaterial, 26896 MeshDistanceMaterial: MeshDistanceMaterial, 26897 MeshBasicMaterial: MeshBasicMaterial, 26898 MeshMatcapMaterial: MeshMatcapMaterial, 26899 LineDashedMaterial: LineDashedMaterial, 26900 LineBasicMaterial: LineBasicMaterial, 26901 Material: Material 26902 }); 26903 26904 const AnimationUtils = { 26905 // same as Array.prototype.slice, but also works on typed arrays 26906 arraySlice: function (array, from, to) { 26907 if (AnimationUtils.isTypedArray(array)) { 26908 // in ios9 array.subarray(from, undefined) will return empty array 26909 // but array.subarray(from) or array.subarray(from, len) is correct 26910 return new array.constructor(array.subarray(from, to !== undefined ? to : array.length)); 26911 } 26912 26913 return array.slice(from, to); 26914 }, 26915 // converts an array to a specific type 26916 convertArray: function (array, type, forceClone) { 26917 if (!array || // let 'undefined' and 'null' pass
vendor: 8,141 bytes, lines 26918-27159
26918 !forceClone && array.constructor === type) return array; 26919 26920 if (typeof type.BYTES_PER_ELEMENT === 'number') { 26921 return new type(array); // create typed array 26922 } 26923 26924 return Array.prototype.slice.call(array); // create Array 26925 }, 26926 isTypedArray: function (object) { 26927 return ArrayBuffer.isView(object) && !(object instanceof DataView); 26928 }, 26929 // returns an array by which times and values can be sorted 26930 getKeyframeOrder: function (times) { 26931 function compareTime(i, j) { 26932 return times[i] - times[j]; 26933 } 26934 26935 const n = times.length; 26936 const result = new Array(n); 26937 26938 for (let i = 0; i !== n; ++i) result[i] = i; 26939 26940 result.sort(compareTime); 26941 return result; 26942 }, 26943 // uses the array previously returned by 'getKeyframeOrder' to sort data 26944 sortedArray: function (values, stride, order) { 26945 const nValues = values.length; 26946 const result = new values.constructor(nValues); 26947 26948 for (let i = 0, dstOffset = 0; dstOffset !== nValues; ++i) { 26949 const srcOffset = order[i] * stride; 26950 26951 for (let j = 0; j !== stride; ++j) { 26952 result[dstOffset++] = values[srcOffset + j]; 26953 } 26954 } 26955 26956 return result; 26957 }, 26958 // function for parsing AOS keyframe formats 26959 flattenJSON: function (jsonKeys, times, values, valuePropertyName) { 26960 let i = 1, 26961 key = jsonKeys[0]; 26962 26963 while (key !== undefined && key[valuePropertyName] === undefined) { 26964 key = jsonKeys[i++]; 26965 } 26966 26967 if (key === undefined) return; // no data 26968 26969 let value = key[valuePropertyName]; 26970 if (value === undefined) return; // no data 26971 26972 if (Array.isArray(value)) { 26973 do { 26974 value = key[valuePropertyName]; 26975 26976 if (value !== undefined) { 26977 times.push(key.time); 26978 values.push.apply(values, value); // push all elements 26979 } 26980 26981 key = jsonKeys[i++]; 26982 } while (key !== undefined); 26983 } else if (value.toArray !== undefined) { 26984 // ...assume THREE.Math-ish 26985 do { 26986 value = key[valuePropertyName]; 26987 26988 if (value !== undefined) { 26989 times.push(key.time); 26990 value.toArray(values, values.length); 26991 } 26992 26993 key = jsonKeys[i++]; 26994 } while (key !== undefined); 26995 } else { 26996 // otherwise push as-is 26997 do { 26998 value = key[valuePropertyName]; 26999 27000 if (value !== undefined) { 27001 times.push(key.time); 27002 values.push(value); 27003 } 27004 27005 key = jsonKeys[i++]; 27006 } while (key !== undefined); 27007 } 27008 }, 27009 subclip: function (sourceClip, name, startFrame, endFrame, fps = 30) { 27010 const clip = sourceClip.clone(); 27011 clip.name = name; 27012 const tracks = []; 27013 27014 for (let i = 0; i < clip.tracks.length; ++i) { 27015 const track = clip.tracks[i]; 27016 const valueSize = track.getValueSize(); 27017 const times = []; 27018 const values = []; 27019 27020 for (let j = 0; j < track.times.length; ++j) { 27021 const frame = track.times[j] * fps; 27022 if (frame < startFrame || frame >= endFrame) continue; 27023 times.push(track.times[j]); 27024 27025 for (let k = 0; k < valueSize; ++k) { 27026 values.push(track.values[j * valueSize + k]); 27027 } 27028 } 27029 27030 if (times.length === 0) continue; 27031 track.times = AnimationUtils.convertArray(times, track.times.constructor); 27032 track.values = AnimationUtils.convertArray(values, track.values.constructor); 27033 tracks.push(track); 27034 } 27035 27036 clip.tracks = tracks; // find minimum .times value across all tracks in the trimmed clip 27037 27038 let minStartTime = Infinity; 27039 27040 for (let i = 0; i < clip.tracks.length; ++i) { 27041 if (minStartTime > clip.tracks[i].times[0]) { 27042 minStartTime = clip.tracks[i].times[0]; 27043 } 27044 } // shift all tracks such that clip begins at t=0 27045 27046 27047 for (let i = 0; i < clip.tracks.length; ++i) { 27048 clip.tracks[i].shift(-1 * minStartTime); 27049 } 27050 27051 clip.resetDuration(); 27052 return clip; 27053 }, 27054 makeClipAdditive: function (targetClip, referenceFrame = 0, referenceClip = targetClip, fps = 30) { 27055 if (fps <= 0) fps = 30; 27056 const numTracks = referenceClip.tracks.length; 27057 const referenceTime = referenceFrame / fps; // Make each track's values relative to the values at the reference frame 27058 27059 for (let i = 0; i < numTracks; ++i) { 27060 const referenceTrack = referenceClip.tracks[i]; 27061 const referenceTrackType = referenceTrack.ValueTypeName; // Skip this track if it's non-numeric 27062 27063 if (referenceTrackType === 'bool' || referenceTrackType === 'string') continue; // Find the track in the target clip whose name and type matches the reference track 27064 27065 const targetTrack = targetClip.tracks.find(function (track) { 27066 return track.name === referenceTrack.name && track.ValueTypeName === referenceTrackType; 27067 }); 27068 if (targetTrack === undefined) continue; 27069 let referenceOffset = 0; 27070 const referenceValueSize = referenceTrack.getValueSize(); 27071 27072 if (referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) { 27073 referenceOffset = referenceValueSize / 3; 27074 } 27075 27076 let targetOffset = 0; 27077 const targetValueSize = targetTrack.getValueSize(); 27078 27079 if (targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) { 27080 targetOffset = targetValueSize / 3; 27081 } 27082 27083 const lastIndex = referenceTrack.times.length - 1; 27084 let referenceValue; // Find the value to subtract out of the track 27085 27086 if (referenceTime <= referenceTrack.times[0]) { 27087 // Reference frame is earlier than the first keyframe, so just use the first keyframe 27088 const startIndex = referenceOffset; 27089 const endIndex = referenceValueSize - referenceOffset; 27090 referenceValue = AnimationUtils.arraySlice(referenceTrack.values, startIndex, endIndex); 27091 } else if (referenceTime >= referenceTrack.times[lastIndex]) { 27092 // Reference frame is after the last keyframe, so just use the last keyframe 27093 const startIndex = lastIndex * referenceValueSize + referenceOffset; 27094 const endIndex = startIndex + referenceValueSize - referenceOffset; 27095 referenceValue = AnimationUtils.arraySlice(referenceTrack.values, startIndex, endIndex); 27096 } else { 27097 // Interpolate to the reference value 27098 const interpolant = referenceTrack.createInterpolant(); 27099 const startIndex = referenceOffset; 27100 const endIndex = referenceValueSize - referenceOffset; 27101 interpolant.evaluate(referenceTime); 27102 referenceValue = AnimationUtils.arraySlice(interpolant.resultBuffer, startIndex, endIndex); 27103 } // Conjugate the quaternion 27104 27105 27106 if (referenceTrackType === 'quaternion') { 27107 const referenceQuat = new Quaternion().fromArray(referenceValue).normalize().conjugate(); 27108 referenceQuat.toArray(referenceValue); 27109 } // Subtract the reference value from all of the track values 27110 27111 27112 const numTimes = targetTrack.times.length; 27113 27114 for (let j = 0; j < numTimes; ++j) { 27115 const valueStart = j * targetValueSize + targetOffset; 27116 27117 if (referenceTrackType === 'quaternion') { 27118 // Multiply the conjugate for quaternion track types 27119 Quaternion.multiplyQuaternionsFlat(targetTrack.values, valueStart, referenceValue, 0, targetTrack.values, valueStart); 27120 } else { 27121 const valueEnd = targetValueSize - targetOffset * 2; // Subtract each value for all other numeric track types 27122 27123 for (let k = 0; k < valueEnd; ++k) { 27124 targetTrack.values[valueStart + k] -= referenceValue[k]; 27125 } 27126 } 27127 } 27128 } 27129 27130 targetClip.blendMode = AdditiveAnimationBlendMode; 27131 return targetClip; 27132 } 27133 }; 27134 27135 /** 27136 * Abstract base class of interpolants over parametric samples. 27137 * 27138 * The parameter domain is one dimensional, typically the time or a path 27139 * along a curve defined by the data. 27140 * 27141 * The sample values can have any dimensionality and derived classes may 27142 * apply special interpretations to the data. 27143 * 27144 * This class provides the interval seek in a Template Method, deferring 27145 * the actual interpolation to derived classes. 27146 * 27147 * Time complexity is O(1) for linear access crossing at most two points 27148 * and O(log N) for random access, where N is the number of positions. 27149 * 27150 * References: 27151 * 27152 * http://www.oodesign.com/template-method-pattern.html 27153 * 27154 */ 27155 class Interpolant { 27156 constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { 27157 this.parameterPositions = parameterPositions; 27158 this._cachedIndex = 0; 27159 this.resultBuffer = resultBuffer !== undefined ? resultBuffer : new s
vendor: 6,015 bytes, lines 27159-27413
27159ampleValues.constructor(sampleSize); 27160 this.sampleValues = sampleValues; 27161 this.valueSize = sampleSize; 27162 this.settings = null; 27163 this.DefaultSettings_ = {}; 27164 } 27165 27166 evaluate(t) { 27167 const pp = this.parameterPositions; 27168 let i1 = this._cachedIndex, 27169 t1 = pp[i1], 27170 t0 = pp[i1 - 1]; 27171 27172 validate_interval: { 27173 seek: { 27174 let right; 27175 27176 linear_scan: { 27177 //- See http://jsperf.com/comparison-to-undefined/3 27178 //- slower code: 27179 //- 27180 //- if ( t >= t1 || t1 === undefined ) { 27181 forward_scan: if (!(t < t1)) { 27182 for (let giveUpAt = i1 + 2;;) { 27183 if (t1 === undefined) { 27184 if (t < t0) break forward_scan; // after end 27185 27186 i1 = pp.length; 27187 this._cachedIndex = i1; 27188 return this.afterEnd_(i1 - 1, t, t0); 27189 } 27190 27191 if (i1 === giveUpAt) break; // this loop 27192 27193 t0 = t1; 27194 t1 = pp[++i1]; 27195 27196 if (t < t1) { 27197 // we have arrived at the sought interval 27198 break seek; 27199 } 27200 } // prepare binary search on the right side of the index 27201 27202 27203 right = pp.length; 27204 break linear_scan; 27205 } //- slower code: 27206 //- if ( t < t0 || t0 === undefined ) { 27207 27208 27209 if (!(t >= t0)) { 27210 // looping? 27211 const t1global = pp[1]; 27212 27213 if (t < t1global) { 27214 i1 = 2; // + 1, using the scan for the details 27215 27216 t0 = t1global; 27217 } // linear reverse scan 27218 27219 27220 for (let giveUpAt = i1 - 2;;) { 27221 if (t0 === undefined) { 27222 // before start 27223 this._cachedIndex = 0; 27224 return this.beforeStart_(0, t, t1); 27225 } 27226 27227 if (i1 === giveUpAt) break; // this loop 27228 27229 t1 = t0; 27230 t0 = pp[--i1 - 1]; 27231 27232 if (t >= t0) { 27233 // we have arrived at the sought interval 27234 break seek; 27235 } 27236 } // prepare binary search on the left side of the index 27237 27238 27239 right = i1; 27240 i1 = 0; 27241 break linear_scan; 27242 } // the interval is valid 27243 27244 27245 break validate_interval; 27246 } // linear scan 27247 // binary search 27248 27249 27250 while (i1 < right) { 27251 const mid = i1 + right >>> 1; 27252 27253 if (t < pp[mid]) { 27254 right = mid; 27255 } else { 27256 i1 = mid + 1; 27257 } 27258 } 27259 27260 t1 = pp[i1]; 27261 t0 = pp[i1 - 1]; // check boundary cases, again 27262 27263 if (t0 === undefined) { 27264 this._cachedIndex = 0; 27265 return this.beforeStart_(0, t, t1); 27266 } 27267 27268 if (t1 === undefined) { 27269 i1 = pp.length; 27270 this._cachedIndex = i1; 27271 return this.afterEnd_(i1 - 1, t0, t); 27272 } 27273 } // seek 27274 27275 27276 this._cachedIndex = i1; 27277 this.intervalChanged_(i1, t0, t1); 27278 } // validate_interval 27279 27280 27281 return this.interpolate_(i1, t0, t, t1); 27282 } 27283 27284 getSettings_() { 27285 return this.settings || this.DefaultSettings_; 27286 } 27287 27288 copySampleValue_(index) { 27289 // copies a sample value to the result buffer 27290 const result = this.resultBuffer, 27291 values = this.sampleValues, 27292 stride = this.valueSize, 27293 offset = index * stride; 27294 27295 for (let i = 0; i !== stride; ++i) { 27296 result[i] = values[offset + i]; 27297 } 27298 27299 return result; 27300 } // Template methods for derived classes: 27301 27302 27303 interpolate_() { 27304 throw new Error('call to abstract method'); // implementations shall return this.resultBuffer 27305 } 27306 27307 intervalChanged_() {// empty 27308 } 27309 27310 } // ALIAS DEFINITIONS 27311 27312 27313 Interpolant.prototype.beforeStart_ = Interpolant.prototype.copySampleValue_; 27314 Interpolant.prototype.afterEnd_ = Interpolant.prototype.copySampleValue_; 27315 27316 /** 27317 * Fast and simple cubic spline interpolant. 27318 * 27319 * It was derived from a Hermitian construction setting the first derivative 27320 * at each sample position to the linear slope between neighboring positions 27321 * over their parameter interval. 27322 */ 27323 27324 class CubicInterpolant extends Interpolant { 27325 constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { 27326 super(parameterPositions, sampleValues, sampleSize, resultBuffer); 27327 this._weightPrev = -0; 27328 this._offsetPrev = -0; 27329 this._weightNext = -0; 27330 this._offsetNext = -0; 27331 this.DefaultSettings_ = { 27332 endingStart: ZeroCurvatureEnding, 27333 endingEnd: ZeroCurvatureEnding 27334 }; 27335 } 27336 27337 intervalChanged_(i1, t0, t1) { 27338 const pp = this.parameterPositions; 27339 let iPrev = i1 - 2, 27340 iNext = i1 + 1, 27341 tPrev = pp[iPrev], 27342 tNext = pp[iNext]; 27343 27344 if (tPrev === undefined) { 27345 switch (this.getSettings_().endingStart) { 27346 case ZeroSlopeEnding: 27347 // f'(t0) = 0 27348 iPrev = i1; 27349 tPrev = 2 * t0 - t1; 27350 break; 27351 27352 case WrapAroundEnding: 27353 // use the other end of the curve 27354 iPrev = pp.length - 2; 27355 tPrev = t0 + pp[iPrev] - pp[iPrev + 1]; 27356 break; 27357 27358 default: 27359 // ZeroCurvatureEnding 27360 // f''(t0) = 0 a.k.a. Natural Spline 27361 iPrev = i1; 27362 tPrev = t1; 27363 } 27364 } 27365 27366 if (tNext === undefined) { 27367 switch (this.getSettings_().endingEnd) { 27368 case ZeroSlopeEnding: 27369 // f'(tN) = 0 27370 iNext = i1; 27371 tNext = 2 * t1 - t0; 27372 break; 27373 27374 case WrapAroundEnding: 27375 // use the other end of the curve 27376 iNext = 1; 27377 tNext = t1 + pp[1] - pp[0]; 27378 break; 27379 27380 default: 27381 // ZeroCurvatureEnding 27382 // f''(tN) = 0, a.k.a. Natural Spline 27383 iNext = i1 - 1; 27384 tNext = t0; 27385 } 27386 } 27387 27388 const halfDt = (t1 - t0) * 0.5, 27389 stride = this.valueSize; 27390 this._weightPrev = halfDt / (t0 - tPrev); 27391 this._weightNext = halfDt / (tNext - t1); 27392 this._offsetPrev = iPrev * stride; 27393 this._offsetNext = iNext * stride; 27394 } 27395 27396 interpolate_(i1, t0, t, t1) { 27397 const result = this.resultBuffer, 27398 values = this.sampleValues, 27399 stride = this.valueSize, 27400 o1 = i1 * stride, 27401 o0 = o1 - stride, 27402 oP = this._offsetPrev, 27403 oN = this._offsetNext, 27404 wP = this._weightPrev, 27405 wN = this._weightNext, 27406 p = (t - t0) / (t1 - t0), 27407 pp = p * p, 27408 ppp = pp * p; // evaluate polynomials 27409 27410 const sP = -wP * ppp + 2 * wP * pp - wP * p; 27411 const s0 = (1 + wP) * ppp + (-1.5 - 2 * wP) * pp + (-0.5 + wP) * p + 1; 27412 const s1 = (-1 - wN) * ppp + (1.5 + wN) * pp + 0.5 * p; 27413 const sN = wN * ppp - wN * pp;
vendor: 1,511 bytes, lines 27413-27469
27413 // combine data linearly 27414 27415 for (let i = 0; i !== stride; ++i) { 27416 result[i] = sP * values[oP + i] + s0 * values[o0 + i] + s1 * values[o1 + i] + sN * values[oN + i]; 27417 } 27418 27419 return result; 27420 } 27421 27422 } 27423 27424 class LinearInterpolant extends Interpolant { 27425 constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { 27426 super(parameterPositions, sampleValues, sampleSize, resultBuffer); 27427 } 27428 27429 interpolate_(i1, t0, t, t1) { 27430 const result = this.resultBuffer, 27431 values = this.sampleValues, 27432 stride = this.valueSize, 27433 offset1 = i1 * stride, 27434 offset0 = offset1 - stride, 27435 weight1 = (t - t0) / (t1 - t0), 27436 weight0 = 1 - weight1; 27437 27438 for (let i = 0; i !== stride; ++i) { 27439 result[i] = values[offset0 + i] * weight0 + values[offset1 + i] * weight1; 27440 } 27441 27442 return result; 27443 } 27444 27445 } 27446 27447 /** 27448 * 27449 * Interpolant that evaluates to the sample value at the position preceeding 27450 * the parameter. 27451 */ 27452 27453 class DiscreteInterpolant extends Interpolant { 27454 constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { 27455 super(parameterPositions, sampleValues, sampleSize, resultBuffer); 27456 } 27457 27458 interpolate_(i1 27459 /*, t0, t, t1 */ 27460 ) { 27461 return this.copySampleValue_(i1 - 1); 27462 } 27463 27464 } 27465 27466 class KeyframeTrack { 27467 constructor(name, times, values, interpolation) { 27468 if (name === undefined) throw new Error('THREE.KeyframeTrack: track name is undefined'); 27469 if (times === undefined || times.length === 0) throw new Error('THREE.KeyframeTrack: no keyframes in track named ' + n
vendor: 4,655 bytes, lines 27469-27635
27469ame); 27470 this.name = name; 27471 this.times = AnimationUtils.convertArray(times, this.TimeBufferType); 27472 this.values = AnimationUtils.convertArray(values, this.ValueBufferType); 27473 this.setInterpolation(interpolation || this.DefaultInterpolation); 27474 } // Serialization (in static context, because of constructor invocation 27475 // and automatic invocation of .toJSON): 27476 27477 27478 static toJSON(track) { 27479 const trackType = track.constructor; 27480 let json; // derived classes can define a static toJSON method 27481 27482 if (trackType.toJSON !== this.toJSON) { 27483 json = trackType.toJSON(track); 27484 } else { 27485 // by default, we assume the data can be serialized as-is 27486 json = { 27487 'name': track.name, 27488 'times': AnimationUtils.convertArray(track.times, Array), 27489 'values': AnimationUtils.convertArray(track.values, Array) 27490 }; 27491 const interpolation = track.getInterpolation(); 27492 27493 if (interpolation !== track.DefaultInterpolation) { 27494 json.interpolation = interpolation; 27495 } 27496 } 27497 27498 json.type = track.ValueTypeName; // mandatory 27499 27500 return json; 27501 } 27502 27503 InterpolantFactoryMethodDiscrete(result) { 27504 return new DiscreteInterpolant(this.times, this.values, this.getValueSize(), result); 27505 } 27506 27507 InterpolantFactoryMethodLinear(result) { 27508 return new LinearInterpolant(this.times, this.values, this.getValueSize(), result); 27509 } 27510 27511 InterpolantFactoryMethodSmooth(result) { 27512 return new CubicInterpolant(this.times, this.values, this.getValueSize(), result); 27513 } 27514 27515 setInterpolation(interpolation) { 27516 let factoryMethod; 27517 27518 switch (interpolation) { 27519 case InterpolateDiscrete: 27520 factoryMethod = this.InterpolantFactoryMethodDiscrete; 27521 break; 27522 27523 case InterpolateLinear: 27524 factoryMethod = this.InterpolantFactoryMethodLinear; 27525 break; 27526 27527 case InterpolateSmooth: 27528 factoryMethod = this.InterpolantFactoryMethodSmooth; 27529 break; 27530 } 27531 27532 if (factoryMethod === undefined) { 27533 const message = 'unsupported interpolation for ' + this.ValueTypeName + ' keyframe track named ' + this.name; 27534 27535 if (this.createInterpolant === undefined) { 27536 // fall back to default, unless the default itself is messed up 27537 if (interpolation !== this.DefaultInterpolation) { 27538 this.setInterpolation(this.DefaultInterpolation); 27539 } else { 27540 throw new Error(message); // fatal, in this case 27541 } 27542 } 27543 27544 console.warn('THREE.KeyframeTrack:', message); 27545 return this; 27546 } 27547 27548 this.createInterpolant = factoryMethod; 27549 return this; 27550 } 27551 27552 getInterpolation() { 27553 switch (this.createInterpolant) { 27554 case this.InterpolantFactoryMethodDiscrete: 27555 return InterpolateDiscrete; 27556 27557 case this.InterpolantFactoryMethodLinear: 27558 return InterpolateLinear; 27559 27560 case this.InterpolantFactoryMethodSmooth: 27561 return InterpolateSmooth; 27562 } 27563 } 27564 27565 getValueSize() { 27566 return this.values.length / this.times.length; 27567 } // move all keyframes either forwards or backwards in time 27568 27569 27570 shift(timeOffset) { 27571 if (timeOffset !== 0.0) { 27572 const times = this.times; 27573 27574 for (let i = 0, n = times.length; i !== n; ++i) { 27575 times[i] += timeOffset; 27576 } 27577 } 27578 27579 return this; 27580 } // scale all keyframe times by a factor (useful for frame <-> seconds conversions) 27581 27582 27583 scale(timeScale) { 27584 if (timeScale !== 1.0) { 27585 const times = this.times; 27586 27587 for (let i = 0, n = times.length; i !== n; ++i) { 27588 times[i] *= timeScale; 27589 } 27590 } 27591 27592 return this; 27593 } // removes keyframes before and after animation without changing any values within the range [startTime, endTime]. 27594 // IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values 27595 27596 27597 trim(startTime, endTime) { 27598 const times = this.times, 27599 nKeys = times.length; 27600 let from = 0, 27601 to = nKeys - 1; 27602 27603 while (from !== nKeys && times[from] < startTime) { 27604 ++from; 27605 } 27606 27607 while (to !== -1 && times[to] > endTime) { 27608 --to; 27609 } 27610 27611 ++to; // inclusive -> exclusive bound 27612 27613 if (from !== 0 || to !== nKeys) { 27614 // empty tracks are forbidden, so keep at least one keyframe 27615 if (from >= to) { 27616 to = Math.max(to, 1); 27617 from = to - 1; 27618 } 27619 27620 const stride = this.getValueSize(); 27621 this.times = AnimationUtils.arraySlice(times, from, to); 27622 this.values = AnimationUtils.arraySlice(this.values, from * stride, to * stride); 27623 } 27624 27625 return this; 27626 } // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable 27627 27628 27629 validate() { 27630 let valid = true; 27631 const valueSize = this.getValueSize(); 27632 27633 if (valueSize - Math.floor(valueSize) !== 0) { 27634 console.error('THREE.KeyframeTrack: Invalid value size in track.', this); 27635 valid = false;
vendor: 4,479 bytes, lines 27636-27792
27636 } 27637 27638 const times = this.times, 27639 values = this.values, 27640 nKeys = times.length; 27641 27642 if (nKeys === 0) { 27643 console.error('THREE.KeyframeTrack: Track is empty.', this); 27644 valid = false; 27645 } 27646 27647 let prevTime = null; 27648 27649 for (let i = 0; i !== nKeys; i++) { 27650 const currTime = times[i]; 27651 27652 if (typeof currTime === 'number' && isNaN(currTime)) { 27653 console.error('THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime); 27654 valid = false; 27655 break; 27656 } 27657 27658 if (prevTime !== null && prevTime > currTime) { 27659 console.error('THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime); 27660 valid = false; 27661 break; 27662 } 27663 27664 prevTime = currTime; 27665 } 27666 27667 if (values !== undefined) { 27668 if (AnimationUtils.isTypedArray(values)) { 27669 for (let i = 0, n = values.length; i !== n; ++i) { 27670 const value = values[i]; 27671 27672 if (isNaN(value)) { 27673 console.error('THREE.KeyframeTrack: Value is not a valid number.', this, i, value); 27674 valid = false; 27675 break; 27676 } 27677 } 27678 } 27679 } 27680 27681 return valid; 27682 } // removes equivalent sequential keys as common in morph target sequences 27683 // (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0) 27684 27685 27686 optimize() { 27687 // times or values may be shared with other tracks, so overwriting is unsafe 27688 const times = AnimationUtils.arraySlice(this.times), 27689 values = AnimationUtils.arraySlice(this.values), 27690 stride = this.getValueSize(), 27691 smoothInterpolation = this.getInterpolation() === InterpolateSmooth, 27692 lastIndex = times.length - 1; 27693 let writeIndex = 1; 27694 27695 for (let i = 1; i < lastIndex; ++i) { 27696 let keep = false; 27697 const time = times[i]; 27698 const timeNext = times[i + 1]; // remove adjacent keyframes scheduled at the same time 27699 27700 if (time !== timeNext && (i !== 1 || time !== times[0])) { 27701 if (!smoothInterpolation) { 27702 // remove unnecessary keyframes same as their neighbors 27703 const offset = i * stride, 27704 offsetP = offset - stride, 27705 offsetN = offset + stride; 27706 27707 for (let j = 0; j !== stride; ++j) { 27708 const value = values[offset + j]; 27709 27710 if (value !== values[offsetP + j] || value !== values[offsetN + j]) { 27711 keep = true; 27712 break; 27713 } 27714 } 27715 } else { 27716 keep = true; 27717 } 27718 } // in-place compaction 27719 27720 27721 if (keep) { 27722 if (i !== writeIndex) { 27723 times[writeIndex] = times[i]; 27724 const readOffset = i * stride, 27725 writeOffset = writeIndex * stride; 27726 27727 for (let j = 0; j !== stride; ++j) { 27728 values[writeOffset + j] = values[readOffset + j]; 27729 } 27730 } 27731 27732 ++writeIndex; 27733 } 27734 } // flush last keyframe (compaction looks ahead) 27735 27736 27737 if (lastIndex > 0) { 27738 times[writeIndex] = times[lastIndex]; 27739 27740 for (let readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++j) { 27741 values[writeOffset + j] = values[readOffset + j]; 27742 } 27743 27744 ++writeIndex; 27745 } 27746 27747 if (writeIndex !== times.length) { 27748 this.times = AnimationUtils.arraySlice(times, 0, writeIndex); 27749 this.values = AnimationUtils.arraySlice(values, 0, writeIndex * stride); 27750 } else { 27751 this.times = times; 27752 this.values = values; 27753 } 27754 27755 return this; 27756 } 27757 27758 clone() { 27759 const times = AnimationUtils.arraySlice(this.times, 0); 27760 const values = AnimationUtils.arraySlice(this.values, 0); 27761 const TypedKeyframeTrack = this.constructor; 27762 const track = new TypedKeyframeTrack(this.name, times, values); // Interpolant argument to constructor is not saved, so copy the factory method directly. 27763 27764 track.createInterpolant = this.createInterpolant; 27765 return track; 27766 } 27767 27768 } 27769 27770 KeyframeTrack.prototype.TimeBufferType = Float32Array; 27771 KeyframeTrack.prototype.ValueBufferType = Float32Array; 27772 KeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear; 27773 27774 /** 27775 * A Track of Boolean keyframe values. 27776 */ 27777 27778 class BooleanKeyframeTrack extends KeyframeTrack {} 27779 27780 BooleanKeyframeTrack.prototype.ValueTypeName = 'bool'; 27781 BooleanKeyframeTrack.prototype.ValueBufferType = Array; 27782 BooleanKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete; 27783 BooleanKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined; 27784 BooleanKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; // Note: Actually this track could have a optimized / compressed 27785 27786 /** 27787 * A Track of keyframe values that represent color. 27788 */ 27789 27790 class ColorKeyframeTrack extends KeyframeTrack {} 27791 27792 ColorKeyframeTrack.prototype.ValueTypeName = 'color';
vendor: 6,272 bytes, lines 27792-28003
27792 // ValueBufferType is inherited 27793 27794 /** 27795 * A Track of numeric keyframe values. 27796 */ 27797 27798 class NumberKeyframeTrack extends KeyframeTrack {} 27799 27800 NumberKeyframeTrack.prototype.ValueTypeName = 'number'; // ValueBufferType is inherited 27801 27802 /** 27803 * Spherical linear unit quaternion interpolant. 27804 */ 27805 27806 class QuaternionLinearInterpolant extends Interpolant { 27807 constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { 27808 super(parameterPositions, sampleValues, sampleSize, resultBuffer); 27809 } 27810 27811 interpolate_(i1, t0, t, t1) { 27812 const result = this.resultBuffer, 27813 values = this.sampleValues, 27814 stride = this.valueSize, 27815 alpha = (t - t0) / (t1 - t0); 27816 let offset = i1 * stride; 27817 27818 for (let end = offset + stride; offset !== end; offset += 4) { 27819 Quaternion.slerpFlat(result, 0, values, offset - stride, values, offset, alpha); 27820 } 27821 27822 return result; 27823 } 27824 27825 } 27826 27827 /** 27828 * A Track of quaternion keyframe values. 27829 */ 27830 27831 class QuaternionKeyframeTrack extends KeyframeTrack { 27832 InterpolantFactoryMethodLinear(result) { 27833 return new QuaternionLinearInterpolant(this.times, this.values, this.getValueSize(), result); 27834 } 27835 27836 } 27837 27838 QuaternionKeyframeTrack.prototype.ValueTypeName = 'quaternion'; // ValueBufferType is inherited 27839 27840 QuaternionKeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear; 27841 QuaternionKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; 27842 27843 /** 27844 * A Track that interpolates Strings 27845 */ 27846 27847 class StringKeyframeTrack extends KeyframeTrack {} 27848 27849 StringKeyframeTrack.prototype.ValueTypeName = 'string'; 27850 StringKeyframeTrack.prototype.ValueBufferType = Array; 27851 StringKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete; 27852 StringKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined; 27853 StringKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; 27854 27855 /** 27856 * A Track of vectored keyframe values. 27857 */ 27858 27859 class VectorKeyframeTrack extends KeyframeTrack {} 27860 27861 VectorKeyframeTrack.prototype.ValueTypeName = 'vector'; // ValueBufferType is inherited 27862 27863 class AnimationClip { 27864 constructor(name, duration = -1, tracks, blendMode = NormalAnimationBlendMode) { 27865 this.name = name; 27866 this.tracks = tracks; 27867 this.duration = duration; 27868 this.blendMode = blendMode; 27869 this.uuid = generateUUID(); // this means it should figure out its duration by scanning the tracks 27870 27871 if (this.duration < 0) { 27872 this.resetDuration(); 27873 } 27874 } 27875 27876 static parse(json) { 27877 const tracks = [], 27878 jsonTracks = json.tracks, 27879 frameTime = 1.0 / (json.fps || 1.0); 27880 27881 for (let i = 0, n = jsonTracks.length; i !== n; ++i) { 27882 tracks.push(parseKeyframeTrack(jsonTracks[i]).scale(frameTime)); 27883 } 27884 27885 const clip = new this(json.name, json.duration, tracks, json.blendMode); 27886 clip.uuid = json.uuid; 27887 return clip; 27888 } 27889 27890 static toJSON(clip) { 27891 const tracks = [], 27892 clipTracks = clip.tracks; 27893 const json = { 27894 'name': clip.name, 27895 'duration': clip.duration, 27896 'tracks': tracks, 27897 'uuid': clip.uuid, 27898 'blendMode': clip.blendMode 27899 }; 27900 27901 for (let i = 0, n = clipTracks.length; i !== n; ++i) { 27902 tracks.push(KeyframeTrack.toJSON(clipTracks[i])); 27903 } 27904 27905 return json; 27906 } 27907 27908 static CreateFromMorphTargetSequence(name, morphTargetSequence, fps, noLoop) { 27909 const numMorphTargets = morphTargetSequence.length; 27910 const tracks = []; 27911 27912 for (let i = 0; i < numMorphTargets; i++) { 27913 let times = []; 27914 let values = []; 27915 times.push((i + numMorphTargets - 1) % numMorphTargets, i, (i + 1) % numMorphTargets); 27916 values.push(0, 1, 0); 27917 const order = AnimationUtils.getKeyframeOrder(times); 27918 times = AnimationUtils.sortedArray(times, 1, order); 27919 values = AnimationUtils.sortedArray(values, 1, order); // if there is a key at the first frame, duplicate it as the 27920 // last frame as well for perfect loop. 27921 27922 if (!noLoop && times[0] === 0) { 27923 times.push(numMorphTargets); 27924 values.push(values[0]); 27925 } 27926 27927 tracks.push(new NumberKeyframeTrack('.morphTargetInfluences[' + morphTargetSequence[i].name + ']', times, values).scale(1.0 / fps)); 27928 } 27929 27930 return new this(name, -1, tracks); 27931 } 27932 27933 static findByName(objectOrClipArray, name) { 27934 let clipArray = objectOrClipArray; 27935 27936 if (!Array.isArray(objectOrClipArray)) { 27937 const o = objectOrClipArray; 27938 clipArray = o.geometry && o.geometry.animations || o.animations; 27939 } 27940 27941 for (let i = 0; i < clipArray.length; i++) { 27942 if (clipArray[i].name === name) { 27943 return clipArray[i]; 27944 } 27945 } 27946 27947 return null; 27948 } 27949 27950 static CreateClipsFromMorphTargetSequences(morphTargets, fps, noLoop) { 27951 const animationToMorphTargets = {}; // tested with https://regex101.com/ on trick sequences 27952 // such flamingo_flyA_003, flamingo_run1_003, crdeath0059 27953 27954 const pattern = /^([\w-]*?)([\d]+)$/; // sort morph target names into animation groups based 27955 // patterns like Walk_001, Walk_002, Run_001, Run_002 27956 27957 for (let i = 0, il = morphTargets.length; i < il; i++) { 27958 const morphTarget = morphTargets[i]; 27959 const parts = morphTarget.name.match(pattern); 27960 27961 if (parts && parts.length > 1) { 27962 const name = parts[1]; 27963 let animationMorphTargets = animationToMorphTargets[name]; 27964 27965 if (!animationMorphTargets) { 27966 animationToMorphTargets[name] = animationMorphTargets = []; 27967 } 27968 27969 animationMorphTargets.push(morphTarget); 27970 } 27971 } 27972 27973 const clips = []; 27974 27975 for (const name in animationToMorphTargets) { 27976 clips.push(this.CreateFromMorphTargetSequence(name, animationToMorphTargets[name], fps, noLoop)); 27977 } 27978 27979 return clips; 27980 } // parse the animation.hierarchy format 27981 27982 27983 static parseAnimation(animation, bones) { 27984 if (!animation) { 27985 console.error('THREE.AnimationClip: No animation in JSONLoader data.'); 27986 return null; 27987 } 27988 27989 const addNonemptyTrack = function (trackType, trackName, animationKeys, propertyName, destTracks) { 27990 // only return track if there are actually keys. 27991 if (animationKeys.length !== 0) { 27992 const times = []; 27993 const values = []; 27994 AnimationUtils.flattenJSON(animationKeys, times, values, propertyName); // empty keys are filtered out, so check again 27995 27996 if (times.length !== 0) { 27997 destTracks.push(new trackType(trackName, times, values)); 27998 } 27999 } 28000 }; 28001 28002 const tracks = []; 28003 const clipName = animation.name || 'default';
vendor: 12,829 bytes, lines 28004-28544
28004 const fps = animation.fps || 30; 28005 const blendMode = animation.blendMode; // automatic length determination in AnimationClip. 28006 28007 let duration = animation.length || -1; 28008 const hierarchyTracks = animation.hierarchy || []; 28009 28010 for (let h = 0; h < hierarchyTracks.length; h++) { 28011 const animationKeys = hierarchyTracks[h].keys; // skip empty tracks 28012 28013 if (!animationKeys || animationKeys.length === 0) continue; // process morph targets 28014 28015 if (animationKeys[0].morphTargets) { 28016 // figure out all morph targets used in this track 28017 const morphTargetNames = {}; 28018 let k; 28019 28020 for (k = 0; k < animationKeys.length; k++) { 28021 if (animationKeys[k].morphTargets) { 28022 for (let m = 0; m < animationKeys[k].morphTargets.length; m++) { 28023 morphTargetNames[animationKeys[k].morphTargets[m]] = -1; 28024 } 28025 } 28026 } // create a track for each morph target with all zero 28027 // morphTargetInfluences except for the keys in which 28028 // the morphTarget is named. 28029 28030 28031 for (const morphTargetName in morphTargetNames) { 28032 const times = []; 28033 const values = []; 28034 28035 for (let m = 0; m !== animationKeys[k].morphTargets.length; ++m) { 28036 const animationKey = animationKeys[k]; 28037 times.push(animationKey.time); 28038 values.push(animationKey.morphTarget === morphTargetName ? 1 : 0); 28039 } 28040 28041 tracks.push(new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values)); 28042 } 28043 28044 duration = morphTargetNames.length * (fps || 1.0); 28045 } else { 28046 // ...assume skeletal animation 28047 const boneName = '.bones[' + bones[h].name + ']'; 28048 addNonemptyTrack(VectorKeyframeTrack, boneName + '.position', animationKeys, 'pos', tracks); 28049 addNonemptyTrack(QuaternionKeyframeTrack, boneName + '.quaternion', animationKeys, 'rot', tracks); 28050 addNonemptyTrack(VectorKeyframeTrack, boneName + '.scale', animationKeys, 'scl', tracks); 28051 } 28052 } 28053 28054 if (tracks.length === 0) { 28055 return null; 28056 } 28057 28058 const clip = new this(clipName, duration, tracks, blendMode); 28059 return clip; 28060 } 28061 28062 resetDuration() { 28063 const tracks = this.tracks; 28064 let duration = 0; 28065 28066 for (let i = 0, n = tracks.length; i !== n; ++i) { 28067 const track = this.tracks[i]; 28068 duration = Math.max(duration, track.times[track.times.length - 1]); 28069 } 28070 28071 this.duration = duration; 28072 return this; 28073 } 28074 28075 trim() { 28076 for (let i = 0; i < this.tracks.length; i++) { 28077 this.tracks[i].trim(0, this.duration); 28078 } 28079 28080 return this; 28081 } 28082 28083 validate() { 28084 let valid = true; 28085 28086 for (let i = 0; i < this.tracks.length; i++) { 28087 valid = valid && this.tracks[i].validate(); 28088 } 28089 28090 return valid; 28091 } 28092 28093 optimize() { 28094 for (let i = 0; i < this.tracks.length; i++) { 28095 this.tracks[i].optimize(); 28096 } 28097 28098 return this; 28099 } 28100 28101 clone() { 28102 const tracks = []; 28103 28104 for (let i = 0; i < this.tracks.length; i++) { 28105 tracks.push(this.tracks[i].clone()); 28106 } 28107 28108 return new this.constructor(this.name, this.duration, tracks, this.blendMode); 28109 } 28110 28111 toJSON() { 28112 return this.constructor.toJSON(this); 28113 } 28114 28115 } 28116 28117 function getTrackTypeForValueTypeName(typeName) { 28118 switch (typeName.toLowerCase()) { 28119 case 'scalar': 28120 case 'double': 28121 case 'float': 28122 case 'number': 28123 case 'integer': 28124 return NumberKeyframeTrack; 28125 28126 case 'vector': 28127 case 'vector2': 28128 case 'vector3': 28129 case 'vector4': 28130 return VectorKeyframeTrack; 28131 28132 case 'color': 28133 return ColorKeyframeTrack; 28134 28135 case 'quaternion': 28136 return QuaternionKeyframeTrack; 28137 28138 case 'bool': 28139 case 'boolean': 28140 return BooleanKeyframeTrack; 28141 28142 case 'string': 28143 return StringKeyframeTrack; 28144 } 28145 28146 throw new Error('THREE.KeyframeTrack: Unsupported typeName: ' + typeName); 28147 } 28148 28149 function parseKeyframeTrack(json) { 28150 if (json.type === undefined) { 28151 throw new Error('THREE.KeyframeTrack: track type undefined, can not parse'); 28152 } 28153 28154 const trackType = getTrackTypeForValueTypeName(json.type); 28155 28156 if (json.times === undefined) { 28157 const times = [], 28158 values = []; 28159 AnimationUtils.flattenJSON(json.keys, times, values, 'value'); 28160 json.times = times; 28161 json.values = values; 28162 } // derived classes can define a static parse method 28163 28164 28165 if (trackType.parse !== undefined) { 28166 return trackType.parse(json); 28167 } else { 28168 // by default, we assume a constructor compatible with the base 28169 return new trackType(json.name, json.times, json.values, json.interpolation); 28170 } 28171 } 28172 28173 const Cache = { 28174 enabled: false, 28175 files: {}, 28176 add: function (key, file) { 28177 if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Adding key:', key ); 28178 28179 this.files[key] = file; 28180 }, 28181 get: function (key) { 28182 if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Checking key:', key ); 28183 28184 return this.files[key]; 28185 }, 28186 remove: function (key) { 28187 delete this.files[key]; 28188 }, 28189 clear: function () { 28190 this.files = {}; 28191 } 28192 }; 28193 28194 class LoadingManager { 28195 constructor(onLoad, onProgress, onError) { 28196 const scope = this; 28197 let isLoading = false; 28198 let itemsLoaded = 0; 28199 let itemsTotal = 0; 28200 let urlModifier = undefined; 28201 const handlers = []; // Refer to #5689 for the reason why we don't set .onStart 28202 // in the constructor 28203 28204 this.onStart = undefined; 28205 this.onLoad = onLoad; 28206 this.onProgress = onProgress; 28207 this.onError = onError; 28208 28209 this.itemStart = function (url) { 28210 itemsTotal++; 28211 28212 if (isLoading === false) { 28213 if (scope.onStart !== undefined) { 28214 scope.onStart(url, itemsLoaded, itemsTotal); 28215 } 28216 } 28217 28218 isLoading = true; 28219 }; 28220 28221 this.itemEnd = function (url) { 28222 itemsLoaded++; 28223 28224 if (scope.onProgress !== undefined) { 28225 scope.onProgress(url, itemsLoaded, itemsTotal); 28226 } 28227 28228 if (itemsLoaded === itemsTotal) { 28229 isLoading = false; 28230 28231 if (scope.onLoad !== undefined) { 28232 scope.onLoad(); 28233 } 28234 } 28235 }; 28236 28237 this.itemError = function (url) { 28238 if (scope.onError !== undefined) { 28239 scope.onError(url); 28240 } 28241 }; 28242 28243 this.resolveURL = function (url) { 28244 if (urlModifier) { 28245 return urlModifier(url); 28246 } 28247 28248 return url; 28249 }; 28250 28251 this.setURLModifier = function (transform) { 28252 urlModifier = transform; 28253 return this; 28254 }; 28255 28256 this.addHandler = function (regex, loader) { 28257 handlers.push(regex, loader); 28258 return this; 28259 }; 28260 28261 this.removeHandler = function (regex) { 28262 const index = handlers.indexOf(regex); 28263 28264 if (index !== -1) { 28265 handlers.splice(index, 2); 28266 } 28267 28268 return this; 28269 }; 28270 28271 this.getHandler = function (file) { 28272 for (let i = 0, l = handlers.length; i < l; i += 2) { 28273 const regex = handlers[i]; 28274 const loader = handlers[i + 1]; 28275 if (regex.global) regex.lastIndex = 0; // see #17920 28276 28277 if (regex.test(file)) { 28278 return loader; 28279 } 28280 } 28281 28282 return null; 28283 }; 28284 } 28285 28286 } 28287 28288 const DefaultLoadingManager = new LoadingManager(); 28289 28290 class Loader { 28291 constructor(manager) { 28292 this.manager = manager !== undefined ? manager : DefaultLoadingManager; 28293 this.crossOrigin = 'anonymous'; 28294 this.withCredentials = false; 28295 this.path = ''; 28296 this.resourcePath = ''; 28297 this.requestHeader = {}; 28298 } 28299 28300 load() {} 28301 28302 loadAsync(url, onProgress) { 28303 const scope = this; 28304 return new Promise(function (resolve, reject) { 28305 scope.load(url, resolve, onProgress, reject); 28306 }); 28307 } 28308 28309 parse() {} 28310 28311 setCrossOrigin(crossOrigin) { 28312 this.crossOrigin = crossOrigin; 28313 return this; 28314 } 28315 28316 setWithCredentials(value) { 28317 this.withCredentials = value; 28318 return this; 28319 } 28320 28321 setPath(path) { 28322 this.path = path; 28323 return this; 28324 } 28325 28326 setResourcePath(resourcePath) { 28327 this.resourcePath = resourcePath; 28328 return this; 28329 } 28330 28331 setRequestHeader(requestHeader) { 28332 this.requestHeader = requestHeader; 28333 return this; 28334 } 28335 28336 } 28337 28338 const loading = {}; 28339 28340 class FileLoader extends Loader { 28341 constructor(manager) { 28342 super(manager); 28343 } 28344 28345 load(url, onLoad, onProgress, onError) { 28346 if (url === undefined) url = ''; 28347 if (this.path !== undefined) url = this.path + url; 28348 url = this.manager.resolveURL(url); 28349 const cached = Cache.get(url); 28350 28351 if (cached !== undefined) { 28352 this.manager.itemStart(url); 28353 setTimeout(() => { 28354 if (onLoad) onLoad(cached); 28355 this.manager.itemEnd(url); 28356 }, 0); 28357 return cached; 28358 } // Check if request is duplicate 28359 28360 28361 if (loading[url] !== undefined) { 28362 loading[url].push({ 28363 onLoad: onLoad, 28364 onProgress: onProgress, 28365 onError: onError 28366 }); 28367 return; 28368 } // Initialise array for duplicate requests 28369 28370 28371 loading[url] = []; 28372 loading[url].push({ 28373 onLoad: onLoad, 28374 onProgress: onProgress, 28375 onError: onError 28376 }); // create request 28377 28378 const req = new Request(url, { 28379 headers: new Headers(this.requestHeader), 28380 credentials: this.withCredentials ? 'include' : 'same-origin' // An abort controller could be added within a future PR 28381 28382 }); // start the fetch 28383 28384 fetch(req).then(response => { 28385 if (response.status === 200 || response.status === 0) { 28386 // Some browsers return HTTP Status 0 when using non-http protocol 28387 // e.g. 'file://' or 'data://'. Handle as success. 28388 if (response.status === 0) { 28389 console.warn('THREE.FileLoader: HTTP Status 0 received.'); 28390 } 28391 28392 if (typeof ReadableStream === 'undefined' || response.body.getReader === undefined) { 28393 return response; 28394 } 28395 28396 const callbacks = loading[url]; 28397 const reader = response.body.getReader(); 28398 const contentLength = response.headers.get('Content-Length'); 28399 const total = contentLength ? parseInt(contentLength) : 0; 28400 const lengthComputable = total !== 0; 28401 let loaded = 0; // periodically read data into the new stream tracking while download progress 28402 28403 const stream = new ReadableStream({ 28404 start(controller) { 28405 readData(); 28406 28407 function readData() { 28408 reader.read().then(({ 28409 done, 28410 value 28411 }) => { 28412 if (done) { 28413 controller.close(); 28414 } else { 28415 loaded += value.byteLength; 28416 const event = new ProgressEvent('progress', { 28417 lengthComputable, 28418 loaded, 28419 total 28420 }); 28421 28422 for (let i = 0, il = callbacks.length; i < il; i++) { 28423 const callback = callbacks[i]; 28424 if (callback.onProgress) callback.onProgress(event); 28425 } 28426 28427 controller.enqueue(value); 28428 readData(); 28429 } 28430 }); 28431 } 28432 } 28433 28434 }); 28435 return new Response(stream); 28436 } else { 28437 throw Error(`fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`); 28438 } 28439 }).then(response => { 28440 switch (this.responseType) { 28441 case 'arraybuffer': 28442 return response.arrayBuffer(); 28443 28444 case 'blob': 28445 return response.blob(); 28446 28447 case 'document': 28448 return response.text().then(text => { 28449 const parser = new DOMParser(); 28450 return parser.parseFromString(text, this.mimeType); 28451 }); 28452 28453 case 'json': 28454 return response.json(); 28455 28456 default: 28457 return response.text(); 28458 } 28459 }).then(data => { 28460 // Add to cache only on HTTP success, so that we do not cache 28461 // error response bodies as proper responses to requests. 28462 Cache.add(url, data); 28463 const callbacks = loading[url]; 28464 delete loading[url]; 28465 28466 for (let i = 0, il = callbacks.length; i < il; i++) { 28467 const callback = callbacks[i]; 28468 if (callback.onLoad) callback.onLoad(data); 28469 } 28470 }).catch(err => { 28471 // Abort errors and other errors are handled the same 28472 const callbacks = loading[url]; 28473 28474 if (callbacks === undefined) { 28475 // When onLoad was called and url was deleted in `loading` 28476 this.manager.itemError(url); 28477 throw err; 28478 } 28479 28480 delete loading[url]; 28481 28482 for (let i = 0, il = callbacks.length; i < il; i++) { 28483 const callback = callbacks[i]; 28484 if (callback.onError) callback.onError(err); 28485 } 28486 28487 this.manager.itemError(url); 28488 }).finally(() => { 28489 this.manager.itemEnd(url); 28490 }); 28491 this.manager.itemStart(url); 28492 } 28493 28494 setResponseType(value) { 28495 this.responseType = value; 28496 return this; 28497 } 28498 28499 setMimeType(value) { 28500 this.mimeType = value; 28501 return this; 28502 } 28503 28504 } 28505 28506 class AnimationLoader extends Loader { 28507 constructor(manager) { 28508 super(manager); 28509 } 28510 28511 load(url, onLoad, onProgress, onError) { 28512 const scope = this; 28513 const loader = new FileLoader(this.manager); 28514 loader.setPath(this.path); 28515 loader.setRequestHeader(this.requestHeader); 28516 loader.setWithCredentials(this.withCredentials); 28517 loader.load(url, function (text) { 28518 try { 28519 onLoad(scope.parse(JSON.parse(text))); 28520 } catch (e) { 28521 if (onError) { 28522 onError(e); 28523 } else { 28524 console.error(e); 28525 } 28526 28527 scope.manager.itemError(url); 28528 } 28529 }, onProgress, onError); 28530 } 28531 28532 parse(json) { 28533 const animations = []; 28534 28535 for (let i = 0; i < json.length; i++) { 28536 const clip = AnimationClip.parse(json[i]); 28537 animations.push(clip); 28538 } 28539 28540 return animations; 28541 } 28542 28543 } 28544
vendor: 4,379 bytes, lines 28545-28722
28545 /** 28546 * Abstract Base class to block based textures loader (dds, pvr, ...) 28547 * 28548 * Sub classes have to implement the parse() method which will be used in load(). 28549 */ 28550 28551 class CompressedTextureLoader extends Loader { 28552 constructor(manager) { 28553 super(manager); 28554 } 28555 28556 load(url, onLoad, onProgress, onError) { 28557 const scope = this; 28558 const images = []; 28559 const texture = new CompressedTexture(); 28560 const loader = new FileLoader(this.manager); 28561 loader.setPath(this.path); 28562 loader.setResponseType('arraybuffer'); 28563 loader.setRequestHeader(this.requestHeader); 28564 loader.setWithCredentials(scope.withCredentials); 28565 let loaded = 0; 28566 28567 function loadTexture(i) { 28568 loader.load(url[i], function (buffer) { 28569 const texDatas = scope.parse(buffer, true); 28570 images[i] = { 28571 width: texDatas.width, 28572 height: texDatas.height, 28573 format: texDatas.format, 28574 mipmaps: texDatas.mipmaps 28575 }; 28576 loaded += 1; 28577 28578 if (loaded === 6) { 28579 if (texDatas.mipmapCount === 1) texture.minFilter = LinearFilter; 28580 texture.image = images; 28581 texture.format = texDatas.format; 28582 texture.needsUpdate = true; 28583 if (onLoad) onLoad(texture); 28584 } 28585 }, onProgress, onError); 28586 } 28587 28588 if (Array.isArray(url)) { 28589 for (let i = 0, il = url.length; i < il; ++i) { 28590 loadTexture(i); 28591 } 28592 } else { 28593 // compressed cubemap texture stored in a single DDS file 28594 loader.load(url, function (buffer) { 28595 const texDatas = scope.parse(buffer, true); 28596 28597 if (texDatas.isCubemap) { 28598 const faces = texDatas.mipmaps.length / texDatas.mipmapCount; 28599 28600 for (let f = 0; f < faces; f++) { 28601 images[f] = { 28602 mipmaps: [] 28603 }; 28604 28605 for (let i = 0; i < texDatas.mipmapCount; i++) { 28606 images[f].mipmaps.push(texDatas.mipmaps[f * texDatas.mipmapCount + i]); 28607 images[f].format = texDatas.format; 28608 images[f].width = texDatas.width; 28609 images[f].height = texDatas.height; 28610 } 28611 } 28612 28613 texture.image = images; 28614 } else { 28615 texture.image.width = texDatas.width; 28616 texture.image.height = texDatas.height; 28617 texture.mipmaps = texDatas.mipmaps; 28618 } 28619 28620 if (texDatas.mipmapCount === 1) { 28621 texture.minFilter = LinearFilter; 28622 } 28623 28624 texture.format = texDatas.format; 28625 texture.needsUpdate = true; 28626 if (onLoad) onLoad(texture); 28627 }, onProgress, onError); 28628 } 28629 28630 return texture; 28631 } 28632 28633 } 28634 28635 class ImageLoader extends Loader { 28636 constructor(manager) { 28637 super(manager); 28638 } 28639 28640 load(url, onLoad, onProgress, onError) { 28641 if (this.path !== undefined) url = this.path + url; 28642 url = this.manager.resolveURL(url); 28643 const scope = this; 28644 const cached = Cache.get(url); 28645 28646 if (cached !== undefined) { 28647 scope.manager.itemStart(url); 28648 setTimeout(function () { 28649 if (onLoad) onLoad(cached); 28650 scope.manager.itemEnd(url); 28651 }, 0); 28652 return cached; 28653 } 28654 28655 const image = createElementNS('img'); 28656 28657 function onImageLoad() { 28658 removeEventListeners(); 28659 Cache.add(url, this); 28660 if (onLoad) onLoad(this); 28661 scope.manager.itemEnd(url); 28662 } 28663 28664 function onImageError(event) { 28665 removeEventListeners(); 28666 if (onError) onError(event); 28667 scope.manager.itemError(url); 28668 scope.manager.itemEnd(url); 28669 } 28670 28671 function removeEventListeners() { 28672 image.removeEventListener('load', onImageLoad, false); 28673 image.removeEventListener('error', onImageError, false); 28674 } 28675 28676 image.addEventListener('load', onImageLoad, false); 28677 image.addEventListener('error', onImageError, false); 28678 28679 if (url.substr(0, 5) !== 'data:') { 28680 if (this.crossOrigin !== undefined) image.crossOrigin = this.crossOrigin; 28681 } 28682 28683 scope.manager.itemStart(url); 28684 image.src = url; 28685 return image; 28686 } 28687 28688 } 28689 28690 class CubeTextureLoader extends Loader { 28691 constructor(manager) { 28692 super(manager); 28693 } 28694 28695 load(urls, onLoad, onProgress, onError) { 28696 const texture = new CubeTexture(); 28697 const loader = new ImageLoader(this.manager); 28698 loader.setCrossOrigin(this.crossOrigin); 28699 loader.setPath(this.path); 28700 let loaded = 0; 28701 28702 function loadTexture(i) { 28703 loader.load(urls[i], function (image) { 28704 texture.images[i] = image; 28705 loaded++; 28706 28707 if (loaded === 6) { 28708 texture.needsUpdate = true; 28709 if (onLoad) onLoad(texture); 28710 } 28711 }, undefined, onError); 28712 } 28713 28714 for (let i = 0; i < urls.length; ++i) { 28715 loadTexture(i); 28716 } 28717 28718 return texture; 28719 } 28720 28721 } 28722
28723 /** 28724 * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...) 28725 * 28726 * Sub classes have to implement the parse() method which will be used in load(). 28727 */ 28728 28729 class DataTextureLoader extends Loader { 28730 constructor(manager) { 28731 super(manager); 28732 } 28733 28734 load(url, onLoad, onProgress, onError) { 28735 const scope = this; 28736 const texture = new DataTexture(); 28737 const loader = new FileLoader(this.manager); 28738 loader.setResponseType('arraybuffer'); 28739 loader.setRequestHeader(this.requestHeader); 28740 loader.setPath(this.path); 28741 loader.setWithCredentials(scope.withCredentials); 28742 loader.load(url, function (buffer) { 28743 const texData = scope.parse(buffer); 28744 if (!texData) return; 28745 28746 if (texData.image !== undefined) { 28747 texture.image = texData.image; 28748 } else if (texData.data !== undefined) { 28749 texture.image.width = texData.width; 28750 texture.image.height = texData.height; 28751 texture.image.data = texData.data; 28752 } 28753 28754 texture.wrapS = texData.wrapS !== undefined ? texData.wrapS : ClampToEdgeWrapping; 28755 texture.wrapT = texData.wrapT !== undefined ? texData.wrapT : ClampToEdgeWrapping; 28756 texture.magFilter = texData.magFilter !== undefined ? texData.magFilter : LinearFilter; 28757 texture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearFilter; 28758 texture.anisotropy = texData.anisotropy !== undefined ? texData.anisotropy : 1; 28759 28760 if (texData.encoding !== undefined) { 28761 texture.encoding = texData.encoding; 28762 } 28763 28764 if (texData.flipY !== undefined) { 28765 texture.flipY = texData.flipY; 28766 } 28767 28768 if (texData.format !== undefined) { 28769 texture.format = texData.format; 28770 } 28771 28772 if (texData.type !== undefined) { 28773 texture.type = texData.type; 28774 } 28775 28776 if (texData.mipmaps !== undefined) { 28777 texture.mipmaps = texData.mipmaps; 28778 texture.minFilter = LinearMipmapLinearFilter; // presumably... 28779 } 28780 28781 if (texData.mipmapCount === 1) { 28782 texture.minFilter = LinearFilter; 28783 } 28784 28785 if (texData.generateMipmaps !== undefined) { 28786 texture.generateMipmaps = texData.generateMipmaps; 28787 } 28788 28789 texture.needsUpdate = true; 28790 if (onLoad) onLoad(texture, texData); 28791 }, onProgress, onError); 28792 return texture; 28793 } 28794 28795 } 28796 28797 class TextureLoader extends Loader { 28798 constructor(manager) { 28799 super(manager); 28800 } 28801 28802 load(url, onLoad, onProgress, onError) { 28803 const texture = new Texture(); 28804 const loader = new ImageLoader(this.manager); 28805 loader.setCrossOrigin(this.crossOrigin); 28806 loader.setPath(this.path); 28807 loader.load(url, function (image) { 28808 texture.image = image; 28809 texture.needsUpdate = true; 28810 28811 if (onLoad !== undefined) { 28812 onLoad(texture); 28813 } 28814 }, onProgress, onError); 28815 return texture; 28816 } 28817 28818 } 28819 28820 class Light extends Object3D { 28821 constructor(color, intensity = 1) { 28822 super(); 28823 this.type = 'Light'; 28824 this.color = new Color(color); 28825 this.intensity = intensity; 28826 } 28827 28828 dispose() {// Empty here in base class; some subclasses override. 28829 } 28830 28831 copy(source) { 28832 super.copy(source); 28833 this.color.copy(source.color); 28834 this.intensity = source.intensity; 28835 return this; 28836 } 28837 28838 toJSON(meta) { 28839 const data = super.toJSON(meta); 28840 data.object.color = this.color.getHex(); 28841 data.object.intensity = this.intensity; 28842 if (this.groundColor !== undefined) data.object.groundColor = this.groundColor.getHex(); 28843 if (this.distance !== undefined) data.object.distance = this.distance; 28844 if (this.angle !== undefined) data.object.angle = this.angle; 28845 if (this.decay !== undefined) data.object.decay = this.decay; 28846 if (this.penumbra !== undefined) data.object.penumbra = this.penumbra; 28847 if (this.shadow !== undefined) data.object.shadow = this.shadow.toJSON(); 28848 return data; 28849 } 28850 28851 } 28852 28853 Light.prototype.isLight = true; 28854 28855 class HemisphereLight extends Light { 28856 constructor(skyColor, groundColor, intensity) { 28857 super(skyColor, intensity); 28858 this.type = 'HemisphereLight'; 28859 this.position.copy(Object3D.DefaultUp); 28860 this.updateMatrix(); 28861 this.groundColor = new Color(groundColor); 28862 } 28863 28864 copy(source) { 28865 Light.prototype.copy.call(this, source); 28866 this.groundColor.copy(source.groundColor); 28867 return this; 28868 } 28869 28870 } 28871 28872 HemisphereLight.prototype.isHemisphereLight = true; 28873 28874 const _projScreenMatrix$1 = /*@__PURE__*/new Matrix4(); 28875 28876 const _lightPositionWorld$1 = /*@__PURE__*/new Vector3(); 28877 28878 const _lookTarget$1 = /*@__PURE__*/new Vector3(); 28879 28880 class LightShadow { 28881 constructor(camera) { 28882 this.camera = camera; 28883 this.bias = 0; 28884 this.normalBias = 0; 28885 this.radius = 1; 28886 this.blurSamples = 8; 28887 this.mapSize = new Vector2(512, 512); 28888 this.map = null; 28889 this.mapPass = null; 28890 this.matrix = new Matrix4(); 28891 this.autoUpdate = true; 28892 this.needsUpdate = false;
vendor: 7,073 bytes, lines 28893-29153
28893 this._frustum = new Frustum(); 28894 this._frameExtents = new Vector2(1, 1); 28895 this._viewportCount = 1; 28896 this._viewports = [new Vector4(0, 0, 1, 1)]; 28897 } 28898 28899 getViewportCount() { 28900 return this._viewportCount; 28901 } 28902 28903 getFrustum() { 28904 return this._frustum; 28905 } 28906 28907 updateMatrices(light) { 28908 const shadowCamera = this.camera; 28909 const shadowMatrix = this.matrix; 28910 28911 _lightPositionWorld$1.setFromMatrixPosition(light.matrixWorld); 28912 28913 shadowCamera.position.copy(_lightPositionWorld$1); 28914 28915 _lookTarget$1.setFromMatrixPosition(light.target.matrixWorld); 28916 28917 shadowCamera.lookAt(_lookTarget$1); 28918 shadowCamera.updateMatrixWorld(); 28919 28920 _projScreenMatrix$1.multiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse); 28921 28922 this._frustum.setFromProjectionMatrix(_projScreenMatrix$1); 28923 28924 shadowMatrix.set(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0); 28925 shadowMatrix.multiply(shadowCamera.projectionMatrix); 28926 shadowMatrix.multiply(shadowCamera.matrixWorldInverse); 28927 } 28928 28929 getViewport(viewportIndex) { 28930 return this._viewports[viewportIndex]; 28931 } 28932 28933 getFrameExtents() { 28934 return this._frameExtents; 28935 } 28936 28937 dispose() { 28938 if (this.map) { 28939 this.map.dispose(); 28940 } 28941 28942 if (this.mapPass) { 28943 this.mapPass.dispose(); 28944 } 28945 } 28946 28947 copy(source) { 28948 this.camera = source.camera.clone(); 28949 this.bias = source.bias; 28950 this.radius = source.radius; 28951 this.mapSize.copy(source.mapSize); 28952 return this; 28953 } 28954 28955 clone() { 28956 return new this.constructor().copy(this); 28957 } 28958 28959 toJSON() { 28960 const object = {}; 28961 if (this.bias !== 0) object.bias = this.bias; 28962 if (this.normalBias !== 0) object.normalBias = this.normalBias; 28963 if (this.radius !== 1) object.radius = this.radius; 28964 if (this.mapSize.x !== 512 || this.mapSize.y !== 512) object.mapSize = this.mapSize.toArray(); 28965 object.camera = this.camera.toJSON(false).object; 28966 delete object.camera.matrix; 28967 return object; 28968 } 28969 28970 } 28971 28972 class SpotLightShadow extends LightShadow { 28973 constructor() { 28974 super(new PerspectiveCamera(50, 1, 0.5, 500)); 28975 this.focus = 1; 28976 } 28977 28978 updateMatrices(light) { 28979 const camera = this.camera; 28980 const fov = RAD2DEG * 2 * light.angle * this.focus; 28981 const aspect = this.mapSize.width / this.mapSize.height; 28982 const far = light.distance || camera.far; 28983 28984 if (fov !== camera.fov || aspect !== camera.aspect || far !== camera.far) { 28985 camera.fov = fov; 28986 camera.aspect = aspect; 28987 camera.far = far; 28988 camera.updateProjectionMatrix(); 28989 } 28990 28991 super.updateMatrices(light); 28992 } 28993 28994 copy(source) { 28995 super.copy(source); 28996 this.focus = source.focus; 28997 return this; 28998 } 28999 29000 } 29001 29002 SpotLightShadow.prototype.isSpotLightShadow = true; 29003 29004 class SpotLight extends Light { 29005 constructor(color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 1) { 29006 super(color, intensity); 29007 this.type = 'SpotLight'; 29008 this.position.copy(Object3D.DefaultUp); 29009 this.updateMatrix(); 29010 this.target = new Object3D(); 29011 this.distance = distance; 29012 this.angle = angle; 29013 this.penumbra = penumbra; 29014 this.decay = decay; // for physically correct lights, should be 2. 29015 29016 this.shadow = new SpotLightShadow(); 29017 } 29018 29019 get power() { 29020 // compute the light's luminous power (in lumens) from its intensity (in candela) 29021 // by convention for a spotlight, luminous power (lm) = Ï * luminous intensity (cd) 29022 return this.intensity * Math.PI; 29023 } 29024 29025 set power(power) { 29026 // set the light's intensity (in candela) from the desired luminous power (in lumens) 29027 this.intensity = power / Math.PI; 29028 } 29029 29030 dispose() { 29031 this.shadow.dispose(); 29032 } 29033 29034 copy(source) { 29035 super.copy(source); 29036 this.distance = source.distance; 29037 this.angle = source.angle; 29038 this.penumbra = source.penumbra; 29039 this.decay = source.decay; 29040 this.target = source.target.clone(); 29041 this.shadow = source.shadow.clone(); 29042 return this; 29043 } 29044 29045 } 29046 29047 SpotLight.prototype.isSpotLight = true; 29048 29049 const _projScreenMatrix = /*@__PURE__*/new Matrix4(); 29050 29051 const _lightPositionWorld = /*@__PURE__*/new Vector3(); 29052 29053 const _lookTarget = /*@__PURE__*/new Vector3(); 29054 29055 class PointLightShadow extends LightShadow { 29056 constructor() { 29057 super(new PerspectiveCamera(90, 1, 0.5, 500)); 29058 this._frameExtents = new Vector2(4, 2); 29059 this._viewportCount = 6; 29060 this._viewports = [// These viewports map a cube-map onto a 2D texture with the 29061 // following orientation: 29062 // 29063 // xzXZ 29064 // y Y 29065 // 29066 // X - Positive x direction 29067 // x - Negative x direction 29068 // Y - Positive y direction 29069 // y - Negative y direction 29070 // Z - Positive z direction 29071 // z - Negative z direction 29072 // positive X 29073 new Vector4(2, 1, 1, 1), // negative X 29074 new Vector4(0, 1, 1, 1), // positive Z 29075 new Vector4(3, 1, 1, 1), // negative Z 29076 new Vector4(1, 1, 1, 1), // positive Y 29077 new Vector4(3, 0, 1, 1), // negative Y 29078 new Vector4(1, 0, 1, 1)]; 29079 this._cubeDirections = [new Vector3(1, 0, 0), new Vector3(-1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1), new Vector3(0, 1, 0), new Vector3(0, -1, 0)]; 29080 this._cubeUps = [new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1)]; 29081 } 29082 29083 updateMatrices(light, viewportIndex = 0) { 29084 const camera = this.camera; 29085 const shadowMatrix = this.matrix; 29086 const far = light.distance || camera.far; 29087 29088 if (far !== camera.far) { 29089 camera.far = far; 29090 camera.updateProjectionMatrix(); 29091 } 29092 29093 _lightPositionWorld.setFromMatrixPosition(light.matrixWorld); 29094 29095 camera.position.copy(_lightPositionWorld); 29096 29097 _lookTarget.copy(camera.position); 29098 29099 _lookTarget.add(this._cubeDirections[viewportIndex]); 29100 29101 camera.up.copy(this._cubeUps[viewportIndex]); 29102 camera.lookAt(_lookTarget); 29103 camera.updateMatrixWorld(); 29104 shadowMatrix.makeTranslation(-_lightPositionWorld.x, -_lightPositionWorld.y, -_lightPositionWorld.z); 29105 29106 _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); 29107 29108 this._frustum.setFromProjectionMatrix(_projScreenMatrix); 29109 } 29110 29111 } 29112 29113 PointLightShadow.prototype.isPointLightShadow = true; 29114 29115 class PointLight extends Light { 29116 constructor(color, intensity, distance = 0, decay = 1) { 29117 super(color, intensity); 29118 this.type = 'PointLight'; 29119 this.distance = distance; 29120 this.decay = decay; // for physically correct lights, should be 2. 29121 29122 this.shadow = new PointLightShadow(); 29123 } 29124 29125 get power() { 29126 // compute the light's luminous power (in lumens) from its intensity (in candela) 29127 // for an isotropic light source, luminous power (lm) = 4 Ï luminous intensity (cd) 29128 return this.intensity * 4 * Math.PI; 29129 } 29130 29131 set power(power) { 29132 // set the light's intensity (in candela) from the desired luminous power (in lumens) 29133 this.intensity = power / (4 * Math.PI); 29134 } 29135 29136 dispose() { 29137 this.shadow.dispose(); 29138 } 29139 29140 copy(source) { 29141 super.copy(source); 29142 this.distance = source.distance; 29143 this.decay = source.decay; 29144 this.shadow = source.shadow.clone(); 29145 return this; 29146 } 29147 29148 } 29149 29150 PointLight.prototype.isPointLight = true; 29151 29152 class DirectionalLightShadow extends LightShadow { 29153 constructor() {
vendor: 26,967 bytes, lines 29154-29954
29154 super(new OrthographicCamera(-5, 5, 5, -5, 0.5, 500)); 29155 } 29156 29157 } 29158 29159 DirectionalLightShadow.prototype.isDirectionalLightShadow = true; 29160 29161 class DirectionalLight extends Light { 29162 constructor(color, intensity) { 29163 super(color, intensity); 29164 this.type = 'DirectionalLight'; 29165 this.position.copy(Object3D.DefaultUp); 29166 this.updateMatrix(); 29167 this.target = new Object3D(); 29168 this.shadow = new DirectionalLightShadow(); 29169 } 29170 29171 dispose() { 29172 this.shadow.dispose(); 29173 } 29174 29175 copy(source) { 29176 super.copy(source); 29177 this.target = source.target.clone(); 29178 this.shadow = source.shadow.clone(); 29179 return this; 29180 } 29181 29182 } 29183 29184 DirectionalLight.prototype.isDirectionalLight = true; 29185 29186 class AmbientLight extends Light { 29187 constructor(color, intensity) { 29188 super(color, intensity); 29189 this.type = 'AmbientLight'; 29190 } 29191 29192 } 29193 29194 AmbientLight.prototype.isAmbientLight = true; 29195 29196 class RectAreaLight extends Light { 29197 constructor(color, intensity, width = 10, height = 10) { 29198 super(color, intensity); 29199 this.type = 'RectAreaLight'; 29200 this.width = width; 29201 this.height = height; 29202 } 29203 29204 get power() { 29205 // compute the light's luminous power (in lumens) from its intensity (in nits) 29206 return this.intensity * this.width * this.height * Math.PI; 29207 } 29208 29209 set power(power) { 29210 // set the light's intensity (in nits) from the desired luminous power (in lumens) 29211 this.intensity = power / (this.width * this.height * Math.PI); 29212 } 29213 29214 copy(source) { 29215 super.copy(source); 29216 this.width = source.width; 29217 this.height = source.height; 29218 return this; 29219 } 29220 29221 toJSON(meta) { 29222 const data = super.toJSON(meta); 29223 data.object.width = this.width; 29224 data.object.height = this.height; 29225 return data; 29226 } 29227 29228 } 29229 29230 RectAreaLight.prototype.isRectAreaLight = true; 29231 29232 /** 29233 * Primary reference: 29234 * https://graphics.stanford.edu/papers/envmap/envmap.pdf 29235 * 29236 * Secondary reference: 29237 * https://www.ppsloan.org/publications/StupidSH36.pdf 29238 */ 29239 // 3-band SH defined by 9 coefficients 29240 29241 class SphericalHarmonics3 { 29242 constructor() { 29243 this.coefficients = []; 29244 29245 for (let i = 0; i < 9; i++) { 29246 this.coefficients.push(new Vector3()); 29247 } 29248 } 29249 29250 set(coefficients) { 29251 for (let i = 0; i < 9; i++) { 29252 this.coefficients[i].copy(coefficients[i]); 29253 } 29254 29255 return this; 29256 } 29257 29258 zero() { 29259 for (let i = 0; i < 9; i++) { 29260 this.coefficients[i].set(0, 0, 0); 29261 } 29262 29263 return this; 29264 } // get the radiance in the direction of the normal 29265 // target is a Vector3 29266 29267 29268 getAt(normal, target) { 29269 // normal is assumed to be unit length 29270 const x = normal.x, 29271 y = normal.y, 29272 z = normal.z; 29273 const coeff = this.coefficients; // band 0 29274 29275 target.copy(coeff[0]).multiplyScalar(0.282095); // band 1 29276 29277 target.addScaledVector(coeff[1], 0.488603 * y); 29278 target.addScaledVector(coeff[2], 0.488603 * z); 29279 target.addScaledVector(coeff[3], 0.488603 * x); // band 2 29280 29281 target.addScaledVector(coeff[4], 1.092548 * (x * y)); 29282 target.addScaledVector(coeff[5], 1.092548 * (y * z)); 29283 target.addScaledVector(coeff[6], 0.315392 * (3.0 * z * z - 1.0)); 29284 target.addScaledVector(coeff[7], 1.092548 * (x * z)); 29285 target.addScaledVector(coeff[8], 0.546274 * (x * x - y * y)); 29286 return target; 29287 } // get the irradiance (radiance convolved with cosine lobe) in the direction of the normal 29288 // target is a Vector3 29289 // https://graphics.stanford.edu/papers/envmap/envmap.pdf 29290 29291 29292 getIrradianceAt(normal, target) { 29293 // normal is assumed to be unit length 29294 const x = normal.x, 29295 y = normal.y, 29296 z = normal.z; 29297 const coeff = this.coefficients; // band 0 29298 29299 target.copy(coeff[0]).multiplyScalar(0.886227); // Ï * 0.282095 29300 // band 1 29301 29302 target.addScaledVector(coeff[1], 2.0 * 0.511664 * y); // ( 2 * Ï / 3 ) * 0.488603 29303 29304 target.addScaledVector(coeff[2], 2.0 * 0.511664 * z); 29305 target.addScaledVector(coeff[3], 2.0 * 0.511664 * x); // band 2 29306 29307 target.addScaledVector(coeff[4], 2.0 * 0.429043 * x * y); // ( Ï / 4 ) * 1.092548 29308 29309 target.addScaledVector(coeff[5], 2.0 * 0.429043 * y * z); 29310 target.addScaledVector(coeff[6], 0.743125 * z * z - 0.247708); // ( Ï / 4 ) * 0.315392 * 3 29311 29312 target.addScaledVector(coeff[7], 2.0 * 0.429043 * x * z); 29313 target.addScaledVector(coeff[8], 0.429043 * (x * x - y * y)); // ( Ï / 4 ) * 0.546274 29314 29315 return target; 29316 } 29317 29318 add(sh) { 29319 for (let i = 0; i < 9; i++) { 29320 this.coefficients[i].add(sh.coefficients[i]); 29321 } 29322 29323 return this; 29324 } 29325 29326 addScaledSH(sh, s) { 29327 for (let i = 0; i < 9; i++) { 29328 this.coefficients[i].addScaledVector(sh.coefficients[i], s); 29329 } 29330 29331 return this; 29332 } 29333 29334 scale(s) { 29335 for (let i = 0; i < 9; i++) { 29336 this.coefficients[i].multiplyScalar(s); 29337 } 29338 29339 return this; 29340 } 29341 29342 lerp(sh, alpha) { 29343 for (let i = 0; i < 9; i++) { 29344 this.coefficients[i].lerp(sh.coefficients[i], alpha); 29345 } 29346 29347 return this; 29348 } 29349 29350 equals(sh) { 29351 for (let i = 0; i < 9; i++) { 29352 if (!this.coefficients[i].equals(sh.coefficients[i])) { 29353 return false; 29354 } 29355 } 29356 29357 return true; 29358 } 29359 29360 copy(sh) { 29361 return this.set(sh.coefficients); 29362 } 29363 29364 clone() { 29365 return new this.constructor().copy(this); 29366 } 29367 29368 fromArray(array, offset = 0) { 29369 const coefficients = this.coefficients; 29370 29371 for (let i = 0; i < 9; i++) { 29372 coefficients[i].fromArray(array, offset + i * 3); 29373 } 29374 29375 return this; 29376 } 29377 29378 toArray(array = [], offset = 0) { 29379 const coefficients = this.coefficients; 29380 29381 for (let i = 0; i < 9; i++) { 29382 coefficients[i].toArray(array, offset + i * 3); 29383 } 29384 29385 return array; 29386 } // evaluate the basis functions 29387 // shBasis is an Array[ 9 ] 29388 29389 29390 static getBasisAt(normal, shBasis) { 29391 // normal is assumed to be unit length 29392 const x = normal.x, 29393 y = normal.y, 29394 z = normal.z; // band 0 29395 29396 shBasis[0] = 0.282095; // band 1 29397 29398 shBasis[1] = 0.488603 * y; 29399 shBasis[2] = 0.488603 * z; 29400 shBasis[3] = 0.488603 * x; // band 2 29401 29402 shBasis[4] = 1.092548 * x * y; 29403 shBasis[5] = 1.092548 * y * z; 29404 shBasis[6] = 0.315392 * (3 * z * z - 1); 29405 shBasis[7] = 1.092548 * x * z; 29406 shBasis[8] = 0.546274 * (x * x - y * y); 29407 } 29408 29409 } 29410 29411 SphericalHarmonics3.prototype.isSphericalHarmonics3 = true; 29412 29413 class LightProbe extends Light { 29414 constructor(sh = new SphericalHarmonics3(), intensity = 1) { 29415 super(undefined, intensity); 29416 this.sh = sh; 29417 } 29418 29419 copy(source) { 29420 super.copy(source); 29421 this.sh.copy(source.sh); 29422 return this; 29423 } 29424 29425 fromJSON(json) { 29426 this.intensity = json.intensity; // TODO: Move this bit to Light.fromJSON(); 29427 29428 this.sh.fromArray(json.sh); 29429 return this; 29430 } 29431 29432 toJSON(meta) { 29433 const data = super.toJSON(meta); 29434 data.object.sh = this.sh.toArray(); 29435 return data; 29436 } 29437 29438 } 29439 29440 LightProbe.prototype.isLightProbe = true; 29441 29442 class MaterialLoader extends Loader { 29443 constructor(manager) { 29444 super(manager); 29445 this.textures = {}; 29446 } 29447 29448 load(url, onLoad, onProgress, onError) { 29449 const scope = this; 29450 const loader = new FileLoader(scope.manager); 29451 loader.setPath(scope.path); 29452 loader.setRequestHeader(scope.requestHeader); 29453 loader.setWithCredentials(scope.withCredentials); 29454 loader.load(url, function (text) { 29455 try { 29456 onLoad(scope.parse(JSON.parse(text))); 29457 } catch (e) { 29458 if (onError) { 29459 onError(e); 29460 } else { 29461 console.error(e); 29462 } 29463 29464 scope.manager.itemError(url); 29465 } 29466 }, onProgress, onError); 29467 } 29468 29469 parse(json) { 29470 const textures = this.textures; 29471 29472 function getTexture(name) { 29473 if (textures[name] === undefined) { 29474 console.warn('THREE.MaterialLoader: Undefined texture', name); 29475 } 29476 29477 return textures[name]; 29478 } 29479 29480 const material = new Materials[json.type](); 29481 if (json.uuid !== undefined) material.uuid = json.uuid; 29482 if (json.name !== undefined) material.name = json.name; 29483 if (json.color !== undefined && material.color !== undefined) material.color.setHex(json.color); 29484 if (json.roughness !== undefined) material.roughness = json.roughness; 29485 if (json.metalness !== undefined) material.metalness = json.metalness; 29486 if (json.sheen !== undefined) material.sheen = json.sheen; 29487 if (json.sheenColor !== undefined) material.sheenColor = new Color().setHex(json.sheenColor); 29488 if (json.sheenRoughness !== undefined) material.sheenRoughness = json.sheenRoughness; 29489 if (json.emissive !== undefined && material.emissive !== undefined) material.emissive.setHex(json.emissive); 29490 if (json.specular !== undefined && material.specular !== undefined) material.specular.setHex(json.specular); 29491 if (json.specularIntensity !== undefined) material.specularIntensity = json.specularIntensity; 29492 if (json.specularColor !== undefined && material.specularColor !== undefined) material.specularColor.setHex(json.specularColor); 29493 if (json.shininess !== undefined) material.shininess = json.shininess; 29494 if (json.clearcoat !== undefined) material.clearcoat = json.clearcoat; 29495 if (json.clearcoatRoughness !== undefined) material.clearcoatRoughness = json.clearcoatRoughness; 29496 if (json.transmission !== undefined) material.transmission = json.transmission; 29497 if (json.thickness !== undefined) material.thickness = json.thickness; 29498 if (json.attenuationDistance !== undefined) material.attenuationDistance = json.attenuationDistance; 29499 if (json.attenuationColor !== undefined && material.attenuationColor !== undefined) material.attenuationColor.setHex(json.attenuationColor); 29500 if (json.fog !== undefined) material.fog = json.fog; 29501 if (json.flatShading !== undefined) material.flatShading = json.flatShading; 29502 if (json.blending !== undefined) material.blending = json.blending; 29503 if (json.combine !== undefined) material.combine = json.combine; 29504 if (json.side !== undefined) material.side = json.side; 29505 if (json.shadowSide !== undefined) material.shadowSide = json.shadowSide; 29506 if (json.opacity !== undefined) material.opacity = json.opacity; 29507 if (json.format !== undefined) material.format = json.format; 29508 if (json.transparent !== undefined) material.transparent = json.transparent; 29509 if (json.alphaTest !== undefined) material.alphaTest = json.alphaTest; 29510 if (json.depthTest !== undefined) material.depthTest = json.depthTest; 29511 if (json.depthWrite !== undefined) material.depthWrite = json.depthWrite; 29512 if (json.colorWrite !== undefined) material.colorWrite = json.colorWrite; 29513 if (json.stencilWrite !== undefined) material.stencilWrite = json.stencilWrite; 29514 if (json.stencilWriteMask !== undefined) material.stencilWriteMask = json.stencilWriteMask; 29515 if (json.stencilFunc !== undefined) material.stencilFunc = json.stencilFunc; 29516 if (json.stencilRef !== undefined) material.stencilRef = json.stencilRef; 29517 if (json.stencilFuncMask !== undefined) material.stencilFuncMask = json.stencilFuncMask; 29518 if (json.stencilFail !== undefined) material.stencilFail = json.stencilFail; 29519 if (json.stencilZFail !== undefined) material.stencilZFail = json.stencilZFail; 29520 if (json.stencilZPass !== undefined) material.stencilZPass = json.stencilZPass; 29521 if (json.wireframe !== undefined) material.wireframe = json.wireframe; 29522 if (json.wireframeLinewidth !== undefined) material.wireframeLinewidth = json.wireframeLinewidth; 29523 if (json.wireframeLinecap !== undefined) material.wireframeLinecap = json.wireframeLinecap; 29524 if (json.wireframeLinejoin !== undefined) material.wireframeLinejoin = json.wireframeLinejoin; 29525 if (json.rotation !== undefined) material.rotation = json.rotation; 29526 if (json.linewidth !== 1) material.linewidth = json.linewidth; 29527 if (json.dashSize !== undefined) material.dashSize = json.dashSize; 29528 if (json.gapSize !== undefined) material.gapSize = json.gapSize; 29529 if (json.scale !== undefined) material.scale = json.scale; 29530 if (json.polygonOffset !== undefined) material.polygonOffset = json.polygonOffset; 29531 if (json.polygonOffsetFactor !== undefined) material.polygonOffsetFactor = json.polygonOffsetFactor; 29532 if (json.polygonOffsetUnits !== undefined) material.polygonOffsetUnits = json.polygonOffsetUnits; 29533 if (json.dithering !== undefined) material.dithering = json.dithering; 29534 if (json.alphaToCoverage !== undefined) material.alphaToCoverage = json.alphaToCoverage; 29535 if (json.premultipliedAlpha !== undefined) material.premultipliedAlpha = json.premultipliedAlpha; 29536 if (json.visible !== undefined) material.visible = json.visible; 29537 if (json.toneMapped !== undefined) material.toneMapped = json.toneMapped; 29538 if (json.userData !== undefined) material.userData = json.userData; 29539 29540 if (json.vertexColors !== undefined) { 29541 if (typeof json.vertexColors === 'number') { 29542 material.vertexColors = json.vertexColors > 0 ? true : false; 29543 } else { 29544 material.vertexColors = json.vertexColors; 29545 } 29546 } // Shader Material 29547 29548 29549 if (json.uniforms !== undefined) { 29550 for (const name in json.uniforms) { 29551 const uniform = json.uniforms[name]; 29552 material.uniforms[name] = {}; 29553 29554 switch (uniform.type) { 29555 case 't': 29556 material.uniforms[name].value = getTexture(uniform.value); 29557 break; 29558 29559 case 'c': 29560 material.uniforms[name].value = new Color().setHex(uniform.value); 29561 break; 29562 29563 case 'v2': 29564 material.uniforms[name].value = new Vector2().fromArray(uniform.value); 29565 break; 29566 29567 case 'v3': 29568 material.uniforms[name].value = new Vector3().fromArray(uniform.value); 29569 break; 29570 29571 case 'v4': 29572 material.uniforms[name].value = new Vector4().fromArray(uniform.value); 29573 break; 29574 29575 case 'm3': 29576 material.uniforms[name].value = new Matrix3().fromArray(uniform.value); 29577 break; 29578 29579 case 'm4': 29580 material.uniforms[name].value = new Matrix4().fromArray(uniform.value); 29581 break; 29582 29583 default: 29584 material.uniforms[name].value = uniform.value; 29585 } 29586 } 29587 } 29588 29589 if (json.defines !== undefined) material.defines = json.defines; 29590 if (json.vertexShader !== undefined) material.vertexShader = json.vertexShader; 29591 if (json.fragmentShader !== undefined) material.fragmentShader = json.fragmentShader; 29592 29593 if (json.extensions !== undefined) { 29594 for (const key in json.extensions) { 29595 material.extensions[key] = json.extensions[key]; 29596 } 29597 } // Deprecated 29598 29599 29600 if (json.shading !== undefined) material.flatShading = json.shading === 1; // THREE.FlatShading 29601 // for PointsMaterial 29602 29603 if (json.size !== undefined) material.size = json.size; 29604 if (json.sizeAttenuation !== undefined) material.sizeAttenuation = json.sizeAttenuation; // maps 29605 29606 if (json.map !== undefined) material.map = getTexture(json.map); 29607 if (json.matcap !== undefined) material.matcap = getTexture(json.matcap); 29608 if (json.alphaMap !== undefined) material.alphaMap = getTexture(json.alphaMap); 29609 if (json.bumpMap !== undefined) material.bumpMap = getTexture(json.bumpMap); 29610 if (json.bumpScale !== undefined) material.bumpScale = json.bumpScale; 29611 if (json.normalMap !== undefined) material.normalMap = getTexture(json.normalMap); 29612 if (json.normalMapType !== undefined) material.normalMapType = json.normalMapType; 29613 29614 if (json.normalScale !== undefined) { 29615 let normalScale = json.normalScale; 29616 29617 if (Array.isArray(normalScale) === false) { 29618 // Blender exporter used to export a scalar. See #7459 29619 normalScale = [normalScale, normalScale]; 29620 } 29621 29622 material.normalScale = new Vector2().fromArray(normalScale); 29623 } 29624 29625 if (json.displacementMap !== undefined) material.displacementMap = getTexture(json.displacementMap); 29626 if (json.displacementScale !== undefined) material.displacementScale = json.displacementScale; 29627 if (json.displacementBias !== undefined) material.displacementBias = json.displacementBias; 29628 if (json.roughnessMap !== undefined) material.roughnessMap = getTexture(json.roughnessMap); 29629 if (json.metalnessMap !== undefined) material.metalnessMap = getTexture(json.metalnessMap); 29630 if (json.emissiveMap !== undefined) material.emissiveMap = getTexture(json.emissiveMap); 29631 if (json.emissiveIntensity !== undefined) material.emissiveIntensity = json.emissiveIntensity; 29632 if (json.specularMap !== undefined) material.specularMap = getTexture(json.specularMap); 29633 if (json.specularIntensityMap !== undefined) material.specularIntensityMap = getTexture(json.specularIntensityMap); 29634 if (json.specularColorMap !== undefined) material.specularColorMap = getTexture(json.specularColorMap); 29635 if (json.envMap !== undefined) material.envMap = getTexture(json.envMap); 29636 if (json.envMapIntensity !== undefined) material.envMapIntensity = json.envMapIntensity; 29637 if (json.reflectivity !== undefined) material.reflectivity = json.reflectivity; 29638 if (json.refractionRatio !== undefined) material.refractionRatio = json.refractionRatio; 29639 if (json.lightMap !== undefined) material.lightMap = getTexture(json.lightMap); 29640 if (json.lightMapIntensity !== undefined) material.lightMapIntensity = json.lightMapIntensity; 29641 if (json.aoMap !== undefined) material.aoMap = getTexture(json.aoMap); 29642 if (json.aoMapIntensity !== undefined) material.aoMapIntensity = json.aoMapIntensity; 29643 if (json.gradientMap !== undefined) material.gradientMap = getTexture(json.gradientMap); 29644 if (json.clearcoatMap !== undefined) material.clearcoatMap = getTexture(json.clearcoatMap); 29645 if (json.clearcoatRoughnessMap !== undefined) material.clearcoatRoughnessMap = getTexture(json.clearcoatRoughnessMap); 29646 if (json.clearcoatNormalMap !== undefined) material.clearcoatNormalMap = getTexture(json.clearcoatNormalMap); 29647 if (json.clearcoatNormalScale !== undefined) material.clearcoatNormalScale = new Vector2().fromArray(json.clearcoatNormalScale); 29648 if (json.transmissionMap !== undefined) material.transmissionMap = getTexture(json.transmissionMap); 29649 if (json.thicknessMap !== undefined) material.thicknessMap = getTexture(json.thicknessMap); 29650 if (json.sheenColorMap !== undefined) material.sheenColorMap = getTexture(json.sheenColorMap); 29651 if (json.sheenRoughnessMap !== undefined) material.sheenRoughnessMap = getTexture(json.sheenRoughnessMap); 29652 return material; 29653 } 29654 29655 setTextures(value) { 29656 this.textures = value; 29657 return this; 29658 } 29659 29660 } 29661 29662 class LoaderUtils { 29663 static decodeText(array) { 29664 if (typeof TextDecoder !== 'undefined') { 29665 return new TextDecoder().decode(array); 29666 } // Avoid the String.fromCharCode.apply(null, array) shortcut, which 29667 // throws a "maximum call stack size exceeded" error for large arrays. 29668 29669 29670 let s = ''; 29671 29672 for (let i = 0, il = array.length; i < il; i++) { 29673 // Implicitly assumes little-endian. 29674 s += String.fromCharCode(array[i]); 29675 } 29676 29677 try { 29678 // merges multi-byte utf-8 characters. 29679 return decodeURIComponent(escape(s)); 29680 } catch (e) { 29681 // see #16358 29682 return s; 29683 } 29684 } 29685 29686 static extractUrlBase(url) { 29687 const index = url.lastIndexOf('/'); 29688 if (index === -1) return './'; 29689 return url.substr(0, index + 1); 29690 } 29691 29692 static resolveURL(url, path) { 29693 // Invalid URL 29694 if (typeof url !== 'string' || url === '') return ''; // Host Relative URL 29695 29696 if (/^https?:\/\//i.test(path) && /^\//.test(url)) { 29697 path = path.replace(/(^https?:\/\/[^\/]+).*/i, '$1'); 29698 } // Absolute URL http://,https://,// 29699 29700 29701 if (/^(https?:)?\/\//i.test(url)) return url; // Data URI 29702 29703 if (/^data:.*,.*$/i.test(url)) return url; // Blob URL 29704 29705 if (/^blob:.*$/i.test(url)) return url; // Relative URL 29706 29707 return path + url; 29708 } 29709 29710 } 29711 29712 class InstancedBufferGeometry extends BufferGeometry { 29713 constructor() { 29714 super(); 29715 this.type = 'InstancedBufferGeometry'; 29716 this.instanceCount = Infinity; 29717 } 29718 29719 copy(source) { 29720 super.copy(source); 29721 this.instanceCount = source.instanceCount; 29722 return this; 29723 } 29724 29725 clone() { 29726 return new this.constructor().copy(this); 29727 } 29728 29729 toJSON() { 29730 const data = super.toJSON(this); 29731 data.instanceCount = this.instanceCount; 29732 data.isInstancedBufferGeometry = true; 29733 return data; 29734 } 29735 29736 } 29737 29738 InstancedBufferGeometry.prototype.isInstancedBufferGeometry = true; 29739 29740 class BufferGeometryLoader extends Loader { 29741 constructor(manager) { 29742 super(manager); 29743 } 29744 29745 load(url, onLoad, onProgress, onError) { 29746 const scope = this; 29747 const loader = new FileLoader(scope.manager); 29748 loader.setPath(scope.path); 29749 loader.setRequestHeader(scope.requestHeader); 29750 loader.setWithCredentials(scope.withCredentials); 29751 loader.load(url, function (text) { 29752 try { 29753 onLoad(scope.parse(JSON.parse(text))); 29754 } catch (e) { 29755 if (onError) { 29756 onError(e); 29757 } else { 29758 console.error(e); 29759 } 29760 29761 scope.manager.itemError(url); 29762 } 29763 }, onProgress, onError); 29764 } 29765 29766 parse(json) { 29767 const interleavedBufferMap = {}; 29768 const arrayBufferMap = {}; 29769 29770 function getInterleavedBuffer(json, uuid) { 29771 if (interleavedBufferMap[uuid] !== undefined) return interleavedBufferMap[uuid]; 29772 const interleavedBuffers = json.interleavedBuffers; 29773 const interleavedBuffer = interleavedBuffers[uuid]; 29774 const buffer = getArrayBuffer(json, interleavedBuffer.buffer); 29775 const array = getTypedArray(interleavedBuffer.type, buffer); 29776 const ib = new InterleavedBuffer(array, interleavedBuffer.stride); 29777 ib.uuid = interleavedBuffer.uuid; 29778 interleavedBufferMap[uuid] = ib; 29779 return ib; 29780 } 29781 29782 function getArrayBuffer(json, uuid) { 29783 if (arrayBufferMap[uuid] !== undefined) return arrayBufferMap[uuid]; 29784 const arrayBuffers = json.arrayBuffers; 29785 const arrayBuffer = arrayBuffers[uuid]; 29786 const ab = new Uint32Array(arrayBuffer).buffer; 29787 arrayBufferMap[uuid] = ab; 29788 return ab; 29789 } 29790 29791 const geometry = json.isInstancedBufferGeometry ? new InstancedBufferGeometry() : new BufferGeometry(); 29792 const index = json.data.index; 29793 29794 if (index !== undefined) { 29795 const typedArray = getTypedArray(index.type, index.array); 29796 geometry.setIndex(new BufferAttribute(typedArray, 1)); 29797 } 29798 29799 const attributes = json.data.attributes; 29800 29801 for (const key in attributes) { 29802 const attribute = attributes[key]; 29803 let bufferAttribute; 29804 29805 if (attribute.isInterleavedBufferAttribute) { 29806 const interleavedBuffer = getInterleavedBuffer(json.data, attribute.data); 29807 bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized); 29808 } else { 29809 const typedArray = getTypedArray(attribute.type, attribute.array); 29810 const bufferAttributeConstr = attribute.isInstancedBufferAttribute ? InstancedBufferAttribute : BufferAttribute; 29811 bufferAttribute = new bufferAttributeConstr(typedArray, attribute.itemSize, attribute.normalized); 29812 } 29813 29814 if (attribute.name !== undefined) bufferAttribute.name = attribute.name; 29815 if (attribute.usage !== undefined) bufferAttribute.setUsage(attribute.usage); 29816 29817 if (attribute.updateRange !== undefined) { 29818 bufferAttribute.updateRange.offset = attribute.updateRange.offset; 29819 bufferAttribute.updateRange.count = attribute.updateRange.count; 29820 } 29821 29822 geometry.setAttribute(key, bufferAttribute); 29823 } 29824 29825 const morphAttributes = json.data.morphAttributes; 29826 29827 if (morphAttributes) { 29828 for (const key in morphAttributes) { 29829 const attributeArray = morphAttributes[key]; 29830 const array = []; 29831 29832 for (let i = 0, il = attributeArray.length; i < il; i++) { 29833 const attribute = attributeArray[i]; 29834 let bufferAttribute; 29835 29836 if (attribute.isInterleavedBufferAttribute) { 29837 const interleavedBuffer = getInterleavedBuffer(json.data, attribute.data); 29838 bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized); 29839 } else { 29840 const typedArray = getTypedArray(attribute.type, attribute.array); 29841 bufferAttribute = new BufferAttribute(typedArray, attribute.itemSize, attribute.normalized); 29842 } 29843 29844 if (attribute.name !== undefined) bufferAttribute.name = attribute.name; 29845 array.push(bufferAttribute); 29846 } 29847 29848 geometry.morphAttributes[key] = array; 29849 } 29850 } 29851 29852 const morphTargetsRelative = json.data.morphTargetsRelative; 29853 29854 if (morphTargetsRelative) { 29855 geometry.morphTargetsRelative = true; 29856 } 29857 29858 const groups = json.data.groups || json.data.drawcalls || json.data.offsets; 29859 29860 if (groups !== undefined) { 29861 for (let i = 0, n = groups.length; i !== n; ++i) { 29862 const group = groups[i]; 29863 geometry.addGroup(group.start, group.count, group.materialIndex); 29864 } 29865 } 29866 29867 const boundingSphere = json.data.boundingSphere; 29868 29869 if (boundingSphere !== undefined) { 29870 const center = new Vector3(); 29871 29872 if (boundingSphere.center !== undefined) { 29873 center.fromArray(boundingSphere.center); 29874 } 29875 29876 geometry.boundingSphere = new Sphere(center, boundingSphere.radius); 29877 } 29878 29879 if (json.name) geometry.name = json.name; 29880 if (json.userData) geometry.userData = json.userData; 29881 return geometry; 29882 } 29883 29884 } 29885 29886 class ObjectLoader extends Loader { 29887 constructor(manager) { 29888 super(manager); 29889 } 29890 29891 load(url, onLoad, onProgress, onError) { 29892 const scope = this; 29893 const path = this.path === '' ? LoaderUtils.extractUrlBase(url) : this.path; 29894 this.resourcePath = this.resourcePath || path; 29895 const loader = new FileLoader(this.manager); 29896 loader.setPath(this.path); 29897 loader.setRequestHeader(this.requestHeader); 29898 loader.setWithCredentials(this.withCredentials); 29899 loader.load(url, function (text) { 29900 let json = null; 29901 29902 try { 29903 json = JSON.parse(text); 29904 } catch (error) { 29905 if (onError !== undefined) onError(error); 29906 console.error('THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message); 29907 return; 29908 } 29909 29910 const metadata = json.metadata; 29911 29912 if (metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry') { 29913 console.error('THREE.ObjectLoader: Can\'t load ' + url); 29914 return; 29915 } 29916 29917 scope.parse(json, onLoad); 29918 }, onProgress, onError); 29919 } 29920 29921 async loadAsync(url, onProgress) { 29922 const scope = this; 29923 const path = this.path === '' ? LoaderUtils.extractUrlBase(url) : this.path; 29924 this.resourcePath = this.resourcePath || path; 29925 const loader = new FileLoader(this.manager); 29926 loader.setPath(this.path); 29927 loader.setRequestHeader(this.requestHeader); 29928 loader.setWithCredentials(this.withCredentials); 29929 const text = await loader.loadAsync(url, onProgress); 29930 const json = JSON.parse(text); 29931 const metadata = json.metadata; 29932 29933 if (metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry') { 29934 throw new Error('THREE.ObjectLoader: Can\'t load ' + url); 29935 } 29936 29937 return await scope.parseAsync(json); 29938 } 29939 29940 parse(json, onLoad) { 29941 const animations = this.parseAnimations(json.animations); 29942 const shapes = this.parseShapes(json.shapes); 29943 const geometries = this.parseGeometries(json.geometries, shapes); 29944 const images = this.parseImages(json.images, function () { 29945 if (onLoad !== undefined) onLoad(object); 29946 }); 29947 const textures = this.parseTextures(json.textures, images); 29948 const materials = this.parseMaterials(json.materials, textures); 29949 const object = this.parseObject(json.object, geometries, materials, textures, animations); 29950 const skeletons = this.parseSkeletons(json.skeletons, object); 29951 this.bindSkeletons(object, skeletons); // 29952 29953 if (onLoad !== undefined) { 29954 let hasImages = false;
29955 29956 for (const uuid in images) { 29957 if (images[uuid] instanceof HTMLImageElement) { 29958 hasImages = true; 29959 break; 29960 } 29961 } 29962 29963 if (hasImages === false) onLoad(object); 29964 } 29965 29966 return object; 29967 } 29968 29969 async parseAsync(json) { 29970 const animations = this.parseAnimations(json.animations); 29971 const shapes = this.parseShapes(json.shapes); 29972 const geometries = this.parseGeometries(json.geometries, shapes); 29973 const images = await this.parseImagesAsync(json.images); 29974 const textures = this.parseTextures(json.textures, images); 29975 const materials = this.parseMaterials(json.materials, textures); 29976 const object = this.parseObject(json.object, geometries, materials, textures, animations); 29977 const skeletons = this.parseSkeletons(json.skeletons, object); 29978 this.bindSkeletons(object, skeletons); 29979 return object; 29980 } 29981 29982 parseShapes(json) { 29983 const shapes = {}; 29984 29985 if (json !== undefined) { 29986 for (let i = 0, l = json.length; i < l; i++) { 29987 const shape = new Shape().fromJSON(json[i]); 29988 shapes[shape.uuid] = shape; 29989 } 29990 } 29991 29992 return shapes; 29993 } 29994 29995 parseSkeletons(json, object) { 29996 const skeletons = {}; 29997 const bones = {}; // generate bone lookup table 29998 29999 object.traverse(function (child) { 30000 if (child.isBone) bones[child.uuid] = child; 30001 }); // create skeletons 30002 30003 if (json !== undefined) { 30004 for (let i = 0, l = json.length; i < l; i++) { 30005 const skeleton = new Skeleton().fromJSON(json[i], bones); 30006 skeletons[skeleton.uuid] = skeleton; 30007 } 30008 } 30009 30010 return skeletons; 30011 } 30012 30013 parseGeometries(json, shapes) { 30014 const geometries = {}; 30015 30016 if (json !== undefined) { 30017 const bufferGeometryLoader = new BufferGeometryLoader(); 30018 30019 for (let i = 0, l = json.length; i < l; i++) { 30020 let geometry; 30021 const data = json[i]; 30022 30023 switch (data.type) { 30024 case 'BufferGeometry': 30025 case 'InstancedBufferGeometry': 30026 geometry = bufferGeometryLoader.parse(data); 30027 break; 30028 30029 case 'Geometry': 30030 console.error('THREE.ObjectLoader: The legacy Geometry type is no longer supported.'); 30031 break; 30032 30033 default: 30034 if (data.type in Geometries) { 30035 geometry = Geometries[data.type].fromJSON(data, shapes); 30036 } else { 30037 console.warn(`THREE.ObjectLoader: Unsupported geometry type "${data.type}"`); 30038 } 30039 30040 } 30041 30042 geometry.uuid = data.uuid; 30043 if (data.name !== undefined) geometry.name = data.name; 30044 if (geometry.isBufferGeometry === true && data.userData !== undefined) geometry.userData = data.userData; 30045 geometries[data.uuid] = geometry; 30046 } 30047 } 30048 30049 return geometries; 30050 } 30051 30052 parseMaterials(json, textures) { 30053 const cache = {}; // MultiMaterial 30054 30055 const materials = {}; 30056 30057 if (json !== undefined) { 30058 const loader = new MaterialLoader(); 30059 loader.setTextures(textures); 30060 30061 for (let i = 0, l = json.length; i < l; i++) { 30062 const data = json[i]; 30063 30064 if (data.type === 'MultiMaterial') { 30065 // Deprecated 30066 const array = []; 30067 30068 for (let j = 0; j < data.materials.length; j++) { 30069 const material = data.materials[j]; 30070 30071 if (cache[material.uuid] === undefined) { 30072 cache[material.uuid] = loader.parse(material); 30073 } 30074 30075 array.push(cache[material.uuid]); 30076 } 30077 30078 materials[data.uuid] = array; 30079 } else { 30080 if (cache[data.uuid] === undefined) { 30081 cache[data.uuid] = loader.parse(data); 30082 } 30083 30084 materials[data.uuid] = cache[data.uuid]; 30085 } 30086 } 30087 } 30088 30089 return materials; 30090 } 30091 30092 parseAnimations(json) { 30093 const animations = {}; 30094 30095 if (json !== undefined) { 30096 for (let i = 0; i < json.length; i++) { 30097 const data = json[i]; 30098 const clip = AnimationClip.parse(data); 30099 animations[clip.uuid] = clip; 30100 } 30101 } 30102 30103 return animations; 30104 } 30105 30106 parseImages(json, onLoad) { 30107 const scope = this; 30108 const images = {}; 30109 let loader; 30110 30111 function loadImage(url) { 30112 scope.manager.itemStart(url); 30113 return loader.load(url, function () { 30114 scope.manager.itemEnd(url); 30115 }, undefined, function () { 30116 scope.manager.itemError(url); 30117 scope.manager.itemEnd(url); 30118 }); 30119 } 30120 30121 function deserializeImage(image) { 30122 if (typeof image === 'string') { 30123 const url = image; 30124 const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test(url) ? url : scope.resourcePath + url; 30125 return loadImage(path); 30126 } else { 30127 if (image.data) { 30128 return { 30129 data: getTypedArray(image.type, image.data), 30130 width: image.width, 30131 height: image.height 30132 }; 30133 } else { 30134 return null; 30135 } 30136 } 30137 } 30138 30139 if (json !== undefined && json.length > 0) { 30140 const manager = new LoadingManager(onLoad); 30141 loader = new ImageLoader(manager); 30142 loader.setCrossOrigin(this.crossOrigin); 30143 30144 for (let i = 0, il = json.length; i < il; i++) { 30145 const image = json[i]; 30146 const url = image.url; 30147 30148 if (Array.isArray(url)) { 30149 // load array of images e.g CubeTexture 30150 images[image.uuid] = []; 30151 30152 for (let j = 0, jl = url.length; j < jl; j++) { 30153 const currentUrl = url[j]; 30154 const deserializedImage = deserializeImage(currentUrl); 30155 30156 if (deserializedImage !== null) { 30157 if (deserializedImage instanceof HTMLImageElement) { 30158 images[image.uuid].push(deserializedImage); 30159 } else { 30160 // special case: handle array of data textures for cube textures 30161 images[image.uuid].push(new DataTexture(deserializedImage.data, deserializedImage.width, deserializedImage.height)); 30162 } 30163 } 30164 } 30165 } else { 30166 // load single image 30167 const deserializedImage = deserializeImage(image.url); 30168 30169 if (deserializedImage !== null) { 30170 images[image.uuid] = deserializedImage; 30171 } 30172 } 30173 } 30174 } 30175 30176 return images; 30177 } 30178 30179 async parseImagesAsync(json) { 30180 const scope = this; 30181 const images = {}; 30182 let loader; 30183 30184 async function deserializeImage(image) { 30185 if (typeof image === 'string') { 30186 const url = image; 30187 const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test(url) ? url : scope.resourcePath + url; 30188 return await loader.loadAsync(path); 30189 } else { 30190 if (image.data) { 30191 return { 30192 data: getTypedArray(image.type, image.data), 30193 width: image.width, 30194 height: image.height 30195 }; 30196 } else { 30197 return null; 30198 } 30199 } 30200 } 30201 30202 if (json !== undefined && json.length > 0) { 30203 loader = new ImageLoader(this.manager); 30204 loader.setCrossOrigin(this.crossOrigin); 30205 30206 for (let i = 0, il = json.length; i < il; i++) { 30207 const image = json[i]; 30208 const url = image.url; 30209 30210 if (Array.isArray(url)) { 30211 // load array of images e.g CubeTexture 30212 images[image.uuid] = []; 30213 30214 for (let j = 0, jl = url.length; j < jl; j++) { 30215 const currentUrl = url[j]; 30216 const deserializedImage = await deserializeImage(currentUrl); 30217 30218 if (deserializedImage !== null) { 30219 if (deserializedImage instanceof HTMLImageElement) { 30220 images[image.uuid].push(deserializedImage); 30221 } else { 30222 // special case: handle array of data textures for cube textures 30223 images[image.uuid].push(new DataTexture(deserializedImage.data, deserializedImage.width, deserializedImage.height)); 30224 } 30225 } 30226 } 30227 } else { 30228 // load single image 30229 const deserializedImage = await deserializeImage(image.url); 30230 30231 if (deserializedImage !== null) { 30232 images[image.uuid] = deserializedImage; 30233 } 30234 } 30235 } 30236 } 30237 30238 return images; 30239 } 30240 30241 parseTextures(json, images) { 30242 function parseConstant(value, type) { 30243 if (typeof value === 'number') return value; 30244 console.warn('THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value); 30245 return type[value]; 30246 } 30247 30248 const textures = {}; 30249 30250 if (json !== undefined) { 30251 for (let i = 0, l = json.length; i < l; i++) { 30252 const data = json[i]; 30253 30254 if (data.image === undefined) { 30255 console.warn('THREE.ObjectLoader: No "image" specified for', data.uuid); 30256 } 30257 30258 if (images[data.image] === undefined) { 30259 console.warn('THREE.ObjectLoader: Undefined image', data.image); 30260 } 30261 30262 let texture; 30263 const image = images[data.image]; 30264 30265 if (Array.isArray(image)) { 30266 texture = new CubeTexture(image); 30267 if (image.length === 6) texture.needsUpdate = true; 30268 } else { 30269 if (image && image.data) { 30270 texture = new DataTexture(image.data, image.width, image.height); 30271 } else { 30272 texture = new Texture(image); 30273 } 30274 30275 if (image) texture.needsUpdate = true; // textures can have undefined image data 30276 } 30277 30278 texture.uuid = data.uuid; 30279 if (data.name !== undefined) texture.name = data.name; 30280 if (data.mapping !== undefined) texture.mapping = parseConstant(data.mapping, TEXTURE_MAPPING); 30281 if (data.offset !== undefined) texture.offset.fromArray(data.offset); 30282 if (data.repeat !== undefined) texture.repeat.fromArray(data.repeat); 30283 if (data.center !== undefined) texture.center.fromArray(data.center); 30284 if (data.rotation !== undefined) texture.rotation = data.rotation; 30285 30286 if (data.wrap !== undefined) { 30287 texture.wrapS = parseConstant(data.wrap[0], TEXTURE_WRAPPING); 30288 texture.wrapT = parseConstant(data.wrap[1], TEXTURE_WRAPPING); 30289 } 30290 30291 if (data.format !== undefined) texture.format = data.format; 30292 if (data.type !== undefined) texture.type = data.type; 30293 if (data.encoding !== undefined) texture.encoding = data.encoding; 30294 if (data.minFilter !== undefined) texture.minFilter = parseConstant(data.minFilter, TEXTURE_FILTER);
vendor: 4,100 bytes, lines 30295-30428
30295 if (data.magFilter !== undefined) texture.magFilter = parseConstant(data.magFilter, TEXTURE_FILTER); 30296 if (data.anisotropy !== undefined) texture.anisotropy = data.anisotropy; 30297 if (data.flipY !== undefined) texture.flipY = data.flipY; 30298 if (data.premultiplyAlpha !== undefined) texture.premultiplyAlpha = data.premultiplyAlpha; 30299 if (data.unpackAlignment !== undefined) texture.unpackAlignment = data.unpackAlignment; 30300 if (data.userData !== undefined) texture.userData = data.userData; 30301 textures[data.uuid] = texture; 30302 } 30303 } 30304 30305 return textures; 30306 } 30307 30308 parseObject(data, geometries, materials, textures, animations) { 30309 let object; 30310 30311 function getGeometry(name) { 30312 if (geometries[name] === undefined) { 30313 console.warn('THREE.ObjectLoader: Undefined geometry', name); 30314 } 30315 30316 return geometries[name]; 30317 } 30318 30319 function getMaterial(name) { 30320 if (name === undefined) return undefined; 30321 30322 if (Array.isArray(name)) { 30323 const array = []; 30324 30325 for (let i = 0, l = name.length; i < l; i++) { 30326 const uuid = name[i]; 30327 30328 if (materials[uuid] === undefined) { 30329 console.warn('THREE.ObjectLoader: Undefined material', uuid); 30330 } 30331 30332 array.push(materials[uuid]); 30333 } 30334 30335 return array; 30336 } 30337 30338 if (materials[name] === undefined) { 30339 console.warn('THREE.ObjectLoader: Undefined material', name); 30340 } 30341 30342 return materials[name]; 30343 } 30344 30345 function getTexture(uuid) { 30346 if (textures[uuid] === undefined) { 30347 console.warn('THREE.ObjectLoader: Undefined texture', uuid); 30348 } 30349 30350 return textures[uuid]; 30351 } 30352 30353 let geometry, material; 30354 30355 switch (data.type) { 30356 case 'Scene': 30357 object = new Scene(); 30358 30359 if (data.background !== undefined) { 30360 if (Number.isInteger(data.background)) { 30361 object.background = new Color(data.background); 30362 } else { 30363 object.background = getTexture(data.background); 30364 } 30365 } 30366 30367 if (data.environment !== undefined) { 30368 object.environment = getTexture(data.environment); 30369 } 30370 30371 if (data.fog !== undefined) { 30372 if (data.fog.type === 'Fog') { 30373 object.fog = new Fog(data.fog.color, data.fog.near, data.fog.far); 30374 } else if (data.fog.type === 'FogExp2') { 30375 object.fog = new FogExp2(data.fog.color, data.fog.density); 30376 } 30377 } 30378 30379 break; 30380 30381 case 'PerspectiveCamera': 30382 object = new PerspectiveCamera(data.fov, data.aspect, data.near, data.far); 30383 if (data.focus !== undefined) object.focus = data.focus; 30384 if (data.zoom !== undefined) object.zoom = data.zoom; 30385 if (data.filmGauge !== undefined) object.filmGauge = data.filmGauge; 30386 if (data.filmOffset !== undefined) object.filmOffset = data.filmOffset; 30387 if (data.view !== undefined) object.view = Object.assign({}, data.view); 30388 break; 30389 30390 case 'OrthographicCamera': 30391 object = new OrthographicCamera(data.left, data.right, data.top, data.bottom, data.near, data.far); 30392 if (data.zoom !== undefined) object.zoom = data.zoom; 30393 if (data.view !== undefined) object.view = Object.assign({}, data.view); 30394 break; 30395 30396 case 'AmbientLight': 30397 object = new AmbientLight(data.color, data.intensity); 30398 break; 30399 30400 case 'DirectionalLight': 30401 object = new DirectionalLight(data.color, data.intensity); 30402 break; 30403 30404 case 'PointLight': 30405 object = new PointLight(data.color, data.intensity, data.distance, data.decay); 30406 break; 30407 30408 case 'RectAreaLight': 30409 object = new RectAreaLight(data.color, data.intensity, data.width, data.height); 30410 break; 30411 30412 case 'SpotLight': 30413 object = new SpotLight(data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay); 30414 break; 30415 30416 case 'HemisphereLight': 30417 object = new HemisphereLight(data.color, data.groundColor, data.intensity); 30418 break; 30419 30420 case 'LightProbe': 30421 object = new LightProbe().fromJSON(data); 30422 break; 30423 30424 case 'SkinnedMesh': 30425 geometry = getGeometry(data.geometry); 30426 material = getMaterial(data.material); 30427 object = new SkinnedMesh(geometry, material); 30428 if (data.bindMode !== undefined) object.bindMode = data.bindMode;
30429 if (data.bindMatrix !== undefined) object.bindMatrix.fromArray(data.bindMatrix); 30430 if (data.skeleton !== undefined) object.skeleton = data.skeleton; 30431 break; 30432 30433 case 'Mesh': 30434 geometry = getGeometry(data.geometry); 30435 material = getMaterial(data.material); 30436 object = new Mesh(geometry, material); 30437 break; 30438 30439 case 'InstancedMesh': 30440 geometry = getGeometry(data.geometry); 30441 material = getMaterial(data.material); 30442 const count = data.count; 30443 const instanceMatrix = data.instanceMatrix; 30444 const instanceColor = data.instanceColor; 30445 object = new InstancedMesh(geometry, material, count); 30446 object.instanceMatrix = new InstancedBufferAttribute(new Float32Array(instanceMatrix.array), 16); 30447 if (instanceColor !== undefined) object.instanceColor = new InstancedBufferAttribute(new Float32Array(instanceColor.array), instanceColor.itemSize); 30448 break; 30449 30450 case 'LOD': 30451 object = new LOD(); 30452 break; 30453 30454 case 'Line': 30455 object = new Line(getGeometry(data.geometry), getMaterial(data.material)); 30456 break; 30457 30458 case 'LineLoop': 30459 object = new LineLoop(getGeometry(data.geometry), getMaterial(data.material)); 30460 break; 30461 30462 case 'LineSegments': 30463 object = new LineSegments(getGeometry(data.geometry), getMaterial(data.material)); 30464 break; 30465 30466 case 'PointCloud': 30467 case 'Points': 30468 object = new Points(getGeometry(data.geometry), getMaterial(data.material)); 30469 break; 30470 30471 case 'Sprite': 30472 object = new Sprite(getMaterial(data.material)); 30473 break; 30474 30475 case 'Group': 30476 object = new Group(); 30477 break; 30478 30479 case 'Bone': 30480 object = new Bone(); 30481 break; 30482 30483 default: 30484 object = new Object3D(); 30485 } 30486 30487 object.uuid = data.uuid; 30488 if (data.name !== undefined) object.name = data.name; 30489 30490 if (data.matrix !== undefined) { 30491 object.matrix.fromArray(data.matrix); 30492 if (data.matrixAutoUpdate !== undefined) object.matrixAutoUpdate = data.matrixAutoUpdate; 30493 if (object.matrixAutoUpdate) object.matrix.decompose(object.position, object.quaternion, object.scale); 30494 } else { 30495 if (data.position !== undefined) object.position.fromArray(data.position); 30496 if (data.rotation !== undefined) object.rotation.fromArray(data.rotation); 30497 if (data.quaternion !== undefined) object.quaternion.fromArray(data.quaternion); 30498 if (data.scale !== undefined) object.scale.fromArray(data.scale); 30499 } 30500 30501 if (data.castShadow !== undefined) object.castShadow = data.castShadow; 30502 if (data.receiveShadow !== undefined) object.receiveShadow = data.receiveShadow; 30503 30504 if (data.shadow) { 30505 if (data.shadow.bias !== undefined) object.shadow.bias = data.shadow.bias; 30506 if (data.shadow.normalBias !== undefined) object.shadow.normalBias = data.shadow.normalBias; 30507 if (data.shadow.radius !== undefined) object.shadow.radius = data.shadow.radius; 30508 if (data.shadow.mapSize !== undefined) object.shadow.mapSize.fromArray(data.shadow.mapSize); 30509 if (data.shadow.camera !== undefined) object.shadow.camera = this.parseObject(data.shadow.camera); 30510 } 30511 30512 if (data.visible !== undefined) object.visible = data.visible; 30513 if (data.frustumCulled !== undefined) object.frustumCulled = data.frustumCulled; 30514 if (data.renderOrder !== undefined) object.renderOrder = data.renderOrder; 30515 if (data.userData !== undefined) object.userData = data.userData; 30516 if (data.layers !== undefined) object.layers.mask = data.layers; 30517 30518 if (data.children !== undefined) { 30519 const children = data.children; 30520 30521 for (let i = 0; i < children.length; i++) { 30522 object.add(this.parseObject(children[i], geometries, materials, textures, animations)); 30523 } 30524 } 30525 30526 if (data.animations !== undefined) { 30527 const objectAnimations = data.animations; 30528 30529 for (let i = 0; i < objectAnimations.length; i++) { 30530 const uuid = objectAnimations[i]; 30531 object.animations.push(animations[uuid]); 30532 } 30533 } 30534 30535 if (data.type === 'LOD') { 30536 if (data.autoUpdate !== undefined) object.autoUpdate = data.autoUpdate; 30537 const levels = data.levels; 30538 30539 for (let l = 0; l < levels.length; l++) { 30540 const level = levels[l]; 30541 const child = object.getObjectByProperty('uuid', level.object); 30542 30543 if (child !== undefined) { 30544 object.addLevel(child, level.distance); 30545 } 30546 } 30547 } 30548 30549 return object; 30550 } 30551 30552 bindSkeletons(object, skeletons) { 30553 if (Object.keys(skeletons).length === 0) return; 30554 object.traverse(function (child) { 30555 if (child.isSkinnedMesh === true && child.skeleton !== undefined) { 30556 const skeleton = skeletons[child.skeleton]; 30557 30558 if (skeleton === undefined) { 30559 console.warn('THREE.ObjectLoader: No skeleton found with UUID:', child.skeleton); 30560 } else { 30561 child.bind(skeleton, child.bindMatrix); 30562 } 30563 } 30564 }); 30565 } 30566 /* DEPRECATED */ 30567 30568 30569 setTexturePath(value) { 30570 console.warn('THREE.ObjectLoader: .setTexturePath() has been renamed to .setResourcePath().'); 30571 return this.setResourcePath(value); 30572 } 30573 30574 } 30575 30576 const TEXTURE_MAPPING = { 30577 UVMapping: UVMapping, 30578 CubeReflectionMapping: CubeReflectionMapping, 30579 CubeRefractionMapping: CubeRefractionMapping, 30580 EquirectangularReflectionMapping: EquirectangularReflectionMapping, 30581 EquirectangularRefractionMapping: EquirectangularRefractionMapping, 30582 CubeUVReflectionMapping: CubeUVReflectionMapping, 30583 CubeUVRefractionMapping: CubeUVRefractionMapping 30584 }; 30585 const TEXTURE_WRAPPING = { 30586 RepeatWrapping: RepeatWrapping, 30587 ClampToEdgeWrapping: ClampToEdgeWrapping, 30588 MirroredRepeatWrapping: MirroredRepeatWrapping 30589 }; 30590 const TEXTURE_FILTER = { 30591 NearestFilter: NearestFilter, 30592 NearestMipmapNearestFilter: NearestMipmapNearestFilter, 30593 NearestMipmapLinearFilter: NearestMipmapLinearFilter, 30594 LinearFilter: LinearFilter, 30595 LinearMipmapNearestFilter: LinearMipmapNearestFilter, 30596 LinearMipmapLinearFilter: LinearMipmapLinearFilter 30597 }; 30598 30599 class ImageBitmapLoader extends Loader { 30600 constructor(manager) { 30601 super(manager); 30602 30603 if (typeof createImageBitmap === 'undefined') { 30604 console.warn('THREE.ImageBitmapLoader: createImageBitmap() not supported.'); 30605 } 30606 30607 if (typeof fetch === 'undefined') { 30608 console.warn('THREE.ImageBitmapLoader: fetch() not supported.'); 30609 } 30610 30611 this.options = { 30612 premultiplyAlpha: 'none' 30613 }; 30614 } 30615 30616 setOptions(options) { 30617 this.options = options; 30618 return this; 30619 } 30620 30621 load(url, onLoad, onProgress, onError) { 30622 if (url === undefined) url = ''; 30623 if (this.path !== undefined) url = this.path + url; 30624 url = this.manager.resolveURL(url); 30625 const scope = this; 30626 const cached = Cache.get(url); 30627 30628 if (cached !== undefined) { 30629 scope.manager.itemStart(url); 30630 setTimeout(function () { 30631 if (onLoad) onLoad(cached); 30632 scope.manager.itemEnd(url); 30633 }, 0); 30634 return cached; 30635 } 30636 30637 const fetchOptions = {}; 30638 fetchOptions.credentials = this.crossOrigin === 'anonymous' ? 'same-origin' : 'include'; 30639 fetchOptions.headers = this.requestHeader; 30640 fetch(url, fetchOptions).then(function (res) { 30641 return res.blob(); 30642 }).then(function (blob) { 30643 return createImageBitmap(blob, Object.assign(scope.options, { 30644 colorSpaceConversion: 'none' 30645 })); 30646 }).then(function (imageBitmap) { 30647 Cache.add(url, imageBitmap); 30648 if (onLoad) onLoad(imageBitmap); 30649 scope.manager.itemEnd(url); 30650 }).catch(function (e) { 30651 if (onError) onError(e); 30652 scope.manager.itemError(url); 30653 scope.manager.itemEnd(url); 30654 }); 30655 scope.manager.itemStart(url); 30656 } 30657 30658 } 30659 30660 ImageBitmapLoader.prototype.isImageBitmapLoader = true; 30661 30662 let _context; 30663 30664 const AudioContext = { 30665 getContext: function () { 30666 if (_context === undefined) { 30667 _context = new (window.AudioContext || window.webkitAudioContext)(); 30668 } 30669 30670 return _context; 30671 }, 30672 setContext: function (value) { 30673 _context = value; 30674 } 30675 }; 30676 30677 class AudioLoader extends Loader { 30678 constructor(manager) { 30679 super(manager); 30680 } 30681 30682 load(url, onLoad, onProgress, onError) { 30683 const scope = this; 30684 const loader = new FileLoader(this.manager); 30685 loader.setResponseType('arraybuffer'); 30686 loader.setPath(this.path); 30687 loader.setRequestHeader(this.requestHeader); 30688 loader.setWithCredentials(this.withCredentials); 30689 loader.load(url, function (buffer) { 30690 try { 30691 // Create a copy of the buffer. The `decodeAudioData` method 30692 // detaches the buffer when complete, preventing reuse. 30693 const bufferCopy = buffer.slice(0); 30694 const context = AudioContext.getContext(); 30695 context.decodeAudioData(bufferCopy, function (audioBuffer) { 30696 onLoad(audioBuffer); 30697 }); 30698 } catch (e) { 30699 if (onError) { 30700 onError(e); 30701 } else { 30702 console.error(e); 30703 } 30704 30705 scope.manager.itemError(url); 30706 } 30707 }, onProgress, onError); 30708 } 30709 30710 } 30711 30712 class HemisphereLightProbe extends LightProbe { 30713 constructor(skyColor, groundColor, intensity = 1) { 30714 super(undefined, intensity); 30715 const color1 = new Color().set(skyColor); 30716 const color2 = new Color().set(groundColor); 30717 const sky = new Vector3(color1.r, color1.g, color1.b); 30718 const ground = new Vector3(color2.r, color2.g, color2.b); // without extra factor of PI in the shader, should = 1 / Math.sqrt( Math.PI ); 30719 30720 const c0 = Math.sqrt(Math.PI); 30721 const c1 = c0 * Math.sqrt(0.75); 30722 this.sh.coefficients[0].copy(sky).add(ground).multiplyScalar(c0); 30723 this.sh.coefficients[1].copy(sky).sub(ground).multiplyScalar(c1); 30724 } 30725 30726 } 30727 30728 HemisphereLightProbe.prototype.isHemisphereLightProbe = true; 30729 30730 class AmbientLightProbe extends LightProbe { 30731 constructor(color, intensity = 1) { 30732 super(undefined, intensity); 30733 const color1 = new Color().set(color); // without extra factor of PI in the shader, would be 2 / Math.sqrt( Math.PI ); 30734 30735 this.sh.coefficients[0].set(color1.r, color1.g, color1.b).multiplyScalar(2 * Math.sqrt(Math.PI)); 30736 } 30737 30738 } 30739 30740 AmbientLightProbe.prototype.isAmbientLightProbe = true; 30741 30742 const _eyeRight = /*@__PURE__*/new Matrix4(); 30743 30744 const _eyeLeft = /*@__PURE__*/new Matrix4(); 30745 30746 const _projectionMatrix = /*@__PURE__*/new Matrix4(); 30747 30748 class StereoCamera { 30749 constructor() { 30750 this.type = 'StereoCamera'; 30751 this.aspect = 1; 30752 this.eyeSep = 0.064; 30753 this.cameraL = new PerspectiveCamera(); 30754 this.cameraL.layers.enable(1); 30755 this.cameraL.matrixAutoUpdate = false;
vendor: 2,475 bytes, lines 30756-30832
30756 this.cameraR = new PerspectiveCamera(); 30757 this.cameraR.layers.enable(2); 30758 this.cameraR.matrixAutoUpdate = false; 30759 this._cache = { 30760 focus: null, 30761 fov: null, 30762 aspect: null, 30763 near: null, 30764 far: null, 30765 zoom: null, 30766 eyeSep: null 30767 }; 30768 } 30769 30770 update(camera) { 30771 const cache = this._cache; 30772 const needsUpdate = cache.focus !== camera.focus || cache.fov !== camera.fov || cache.aspect !== camera.aspect * this.aspect || cache.near !== camera.near || cache.far !== camera.far || cache.zoom !== camera.zoom || cache.eyeSep !== this.eyeSep; 30773 30774 if (needsUpdate) { 30775 cache.focus = camera.focus; 30776 cache.fov = camera.fov; 30777 cache.aspect = camera.aspect * this.aspect; 30778 cache.near = camera.near; 30779 cache.far = camera.far; 30780 cache.zoom = camera.zoom; 30781 cache.eyeSep = this.eyeSep; // Off-axis stereoscopic effect based on 30782 // http://paulbourke.net/stereographics/stereorender/ 30783 30784 _projectionMatrix.copy(camera.projectionMatrix); 30785 30786 const eyeSepHalf = cache.eyeSep / 2; 30787 const eyeSepOnProjection = eyeSepHalf * cache.near / cache.focus; 30788 const ymax = cache.near * Math.tan(DEG2RAD * cache.fov * 0.5) / cache.zoom; 30789 let xmin, xmax; // translate xOffset 30790 30791 _eyeLeft.elements[12] = -eyeSepHalf; 30792 _eyeRight.elements[12] = eyeSepHalf; // for left eye 30793 30794 xmin = -ymax * cache.aspect + eyeSepOnProjection; 30795 xmax = ymax * cache.aspect + eyeSepOnProjection; 30796 _projectionMatrix.elements[0] = 2 * cache.near / (xmax - xmin); 30797 _projectionMatrix.elements[8] = (xmax + xmin) / (xmax - xmin); 30798 this.cameraL.projectionMatrix.copy(_projectionMatrix); // for right eye 30799 30800 xmin = -ymax * cache.aspect - eyeSepOnProjection; 30801 xmax = ymax * cache.aspect - eyeSepOnProjection; 30802 _projectionMatrix.elements[0] = 2 * cache.near / (xmax - xmin); 30803 _projectionMatrix.elements[8] = (xmax + xmin) / (xmax - xmin); 30804 this.cameraR.projectionMatrix.copy(_projectionMatrix); 30805 } 30806 30807 this.cameraL.matrixWorld.copy(camera.matrixWorld).multiply(_eyeLeft); 30808 this.cameraR.matrixWorld.copy(camera.matrixWorld).multiply(_eyeRight); 30809 } 30810 30811 } 30812 30813 class Clock { 30814 constructor(autoStart = true) { 30815 this.autoStart = autoStart; 30816 this.startTime = 0; 30817 this.oldTime = 0; 30818 this.elapsedTime = 0; 30819 this.running = false; 30820 } 30821 30822 start() { 30823 this.startTime = now(); 30824 this.oldTime = this.startTime; 30825 this.elapsedTime = 0; 30826 this.running = true; 30827 } 30828 30829 stop() { 30830 this.getElapsedTime(); 30831 this.running = false; 30832 this.autoStart = false;
vendor: 4,298 bytes, lines 30833-31004
30833 } 30834 30835 getElapsedTime() { 30836 this.getDelta(); 30837 return this.elapsedTime; 30838 } 30839 30840 getDelta() { 30841 let diff = 0; 30842 30843 if (this.autoStart && !this.running) { 30844 this.start(); 30845 return 0; 30846 } 30847 30848 if (this.running) { 30849 const newTime = now(); 30850 diff = (newTime - this.oldTime) / 1000; 30851 this.oldTime = newTime; 30852 this.elapsedTime += diff; 30853 } 30854 30855 return diff; 30856 } 30857 30858 } 30859 30860 function now() { 30861 return (typeof performance === 'undefined' ? Date : performance).now(); // see #10732 30862 } 30863 30864 const _position$1 = /*@__PURE__*/new Vector3(); 30865 30866 const _quaternion$1 = /*@__PURE__*/new Quaternion(); 30867 30868 const _scale$1 = /*@__PURE__*/new Vector3(); 30869 30870 const _orientation$1 = /*@__PURE__*/new Vector3(); 30871 30872 class AudioListener extends Object3D { 30873 constructor() { 30874 super(); 30875 this.type = 'AudioListener'; 30876 this.context = AudioContext.getContext(); 30877 this.gain = this.context.createGain(); 30878 this.gain.connect(this.context.destination); 30879 this.filter = null; 30880 this.timeDelta = 0; // private 30881 30882 this._clock = new Clock(); 30883 } 30884 30885 getInput() { 30886 return this.gain; 30887 } 30888 30889 removeFilter() { 30890 if (this.filter !== null) { 30891 this.gain.disconnect(this.filter); 30892 this.filter.disconnect(this.context.destination); 30893 this.gain.connect(this.context.destination); 30894 this.filter = null; 30895 } 30896 30897 return this; 30898 } 30899 30900 getFilter() { 30901 return this.filter; 30902 } 30903 30904 setFilter(value) { 30905 if (this.filter !== null) { 30906 this.gain.disconnect(this.filter); 30907 this.filter.disconnect(this.context.destination); 30908 } else { 30909 this.gain.disconnect(this.context.destination); 30910 } 30911 30912 this.filter = value; 30913 this.gain.connect(this.filter); 30914 this.filter.connect(this.context.destination); 30915 return this; 30916 } 30917 30918 getMasterVolume() { 30919 return this.gain.gain.value; 30920 } 30921 30922 setMasterVolume(value) { 30923 this.gain.gain.setTargetAtTime(value, this.context.currentTime, 0.01); 30924 return this; 30925 } 30926 30927 updateMatrixWorld(force) { 30928 super.updateMatrixWorld(force); 30929 const listener = this.context.listener; 30930 const up = this.up; 30931 this.timeDelta = this._clock.getDelta(); 30932 this.matrixWorld.decompose(_position$1, _quaternion$1, _scale$1); 30933 30934 _orientation$1.set(0, 0, -1).applyQuaternion(_quaternion$1); 30935 30936 if (listener.positionX) { 30937 // code path for Chrome (see #14393) 30938 const endTime = this.context.currentTime + this.timeDelta; 30939 listener.positionX.linearRampToValueAtTime(_position$1.x, endTime); 30940 listener.positionY.linearRampToValueAtTime(_position$1.y, endTime); 30941 listener.positionZ.linearRampToValueAtTime(_position$1.z, endTime); 30942 listener.forwardX.linearRampToValueAtTime(_orientation$1.x, endTime); 30943 listener.forwardY.linearRampToValueAtTime(_orientation$1.y, endTime); 30944 listener.forwardZ.linearRampToValueAtTime(_orientation$1.z, endTime); 30945 listener.upX.linearRampToValueAtTime(up.x, endTime); 30946 listener.upY.linearRampToValueAtTime(up.y, endTime); 30947 listener.upZ.linearRampToValueAtTime(up.z, endTime); 30948 } else { 30949 listener.setPosition(_position$1.x, _position$1.y, _position$1.z); 30950 listener.setOrientation(_orientation$1.x, _orientation$1.y, _orientation$1.z, up.x, up.y, up.z); 30951 } 30952 } 30953 30954 } 30955 30956 class Audio extends Object3D { 30957 constructor(listener) { 30958 super(); 30959 this.type = 'Audio'; 30960 this.listener = listener; 30961 this.context = listener.context; 30962 this.gain = this.context.createGain(); 30963 this.gain.connect(listener.getInput()); 30964 this.autoplay = false; 30965 this.buffer = null; 30966 this.detune = 0; 30967 this.loop = false; 30968 this.loopStart = 0; 30969 this.loopEnd = 0; 30970 this.offset = 0; 30971 this.duration = undefined; 30972 this.playbackRate = 1; 30973 this.isPlaying = false; 30974 this.hasPlaybackControl = true; 30975 this.source = null; 30976 this.sourceType = 'empty'; 30977 this._startedAt = 0; 30978 this._progress = 0; 30979 this._connected = false; 30980 this.filters = []; 30981 } 30982 30983 getOutput() { 30984 return this.gain; 30985 } 30986 30987 setNodeSource(audioNode) { 30988 this.hasPlaybackControl = false; 30989 this.sourceType = 'audioNode'; 30990 this.source = audioNode; 30991 this.connect(); 30992 return this; 30993 } 30994 30995 setMediaElementSource(mediaElement) { 30996 this.hasPlaybackControl = false; 30997 this.sourceType = 'mediaNode'; 30998 this.source = this.context.createMediaElementSource(mediaElement); 30999 this.connect(); 31000 return this; 31001 } 31002 31003 setMediaStreamSource(mediaStream) { 31004 this.hasPlaybackControl = false;
vendor: 19,580 bytes, lines 31005-31711
31005 this.sourceType = 'mediaStreamNode'; 31006 this.source = this.context.createMediaStreamSource(mediaStream); 31007 this.connect(); 31008 return this; 31009 } 31010 31011 setBuffer(audioBuffer) { 31012 this.buffer = audioBuffer; 31013 this.sourceType = 'buffer'; 31014 if (this.autoplay) this.play(); 31015 return this; 31016 } 31017 31018 play(delay = 0) { 31019 if (this.isPlaying === true) { 31020 console.warn('THREE.Audio: Audio is already playing.'); 31021 return; 31022 } 31023 31024 if (this.hasPlaybackControl === false) { 31025 console.warn('THREE.Audio: this Audio has no playback control.'); 31026 return; 31027 } 31028 31029 this._startedAt = this.context.currentTime + delay; 31030 const source = this.context.createBufferSource(); 31031 source.buffer = this.buffer; 31032 source.loop = this.loop; 31033 source.loopStart = this.loopStart; 31034 source.loopEnd = this.loopEnd; 31035 source.onended = this.onEnded.bind(this); 31036 source.start(this._startedAt, this._progress + this.offset, this.duration); 31037 this.isPlaying = true; 31038 this.source = source; 31039 this.setDetune(this.detune); 31040 this.setPlaybackRate(this.playbackRate); 31041 return this.connect(); 31042 } 31043 31044 pause() { 31045 if (this.hasPlaybackControl === false) { 31046 console.warn('THREE.Audio: this Audio has no playback control.'); 31047 return; 31048 } 31049 31050 if (this.isPlaying === true) { 31051 // update current progress 31052 this._progress += Math.max(this.context.currentTime - this._startedAt, 0) * this.playbackRate; 31053 31054 if (this.loop === true) { 31055 // ensure _progress does not exceed duration with looped audios 31056 this._progress = this._progress % (this.duration || this.buffer.duration); 31057 } 31058 31059 this.source.stop(); 31060 this.source.onended = null; 31061 this.isPlaying = false; 31062 } 31063 31064 return this; 31065 } 31066 31067 stop() { 31068 if (this.hasPlaybackControl === false) { 31069 console.warn('THREE.Audio: this Audio has no playback control.'); 31070 return; 31071 } 31072 31073 this._progress = 0; 31074 this.source.stop(); 31075 this.source.onended = null; 31076 this.isPlaying = false; 31077 return this; 31078 } 31079 31080 connect() { 31081 if (this.filters.length > 0) { 31082 this.source.connect(this.filters[0]); 31083 31084 for (let i = 1, l = this.filters.length; i < l; i++) { 31085 this.filters[i - 1].connect(this.filters[i]); 31086 } 31087 31088 this.filters[this.filters.length - 1].connect(this.getOutput()); 31089 } else { 31090 this.source.connect(this.getOutput()); 31091 } 31092 31093 this._connected = true; 31094 return this; 31095 } 31096 31097 disconnect() { 31098 if (this.filters.length > 0) { 31099 this.source.disconnect(this.filters[0]); 31100 31101 for (let i = 1, l = this.filters.length; i < l; i++) { 31102 this.filters[i - 1].disconnect(this.filters[i]); 31103 } 31104 31105 this.filters[this.filters.length - 1].disconnect(this.getOutput()); 31106 } else { 31107 this.source.disconnect(this.getOutput()); 31108 } 31109 31110 this._connected = false; 31111 return this; 31112 } 31113 31114 getFilters() { 31115 return this.filters; 31116 } 31117 31118 setFilters(value) { 31119 if (!value) value = []; 31120 31121 if (this._connected === true) { 31122 this.disconnect(); 31123 this.filters = value.slice(); 31124 this.connect(); 31125 } else { 31126 this.filters = value.slice(); 31127 } 31128 31129 return this; 31130 } 31131 31132 setDetune(value) { 31133 this.detune = value; 31134 if (this.source.detune === undefined) return; // only set detune when available 31135 31136 if (this.isPlaying === true) { 31137 this.source.detune.setTargetAtTime(this.detune, this.context.currentTime, 0.01); 31138 } 31139 31140 return this; 31141 } 31142 31143 getDetune() { 31144 return this.detune; 31145 } 31146 31147 getFilter() { 31148 return this.getFilters()[0]; 31149 } 31150 31151 setFilter(filter) { 31152 return this.setFilters(filter ? [filter] : []); 31153 } 31154 31155 setPlaybackRate(value) { 31156 if (this.hasPlaybackControl === false) { 31157 console.warn('THREE.Audio: this Audio has no playback control.'); 31158 return; 31159 } 31160 31161 this.playbackRate = value; 31162 31163 if (this.isPlaying === true) { 31164 this.source.playbackRate.setTargetAtTime(this.playbackRate, this.context.currentTime, 0.01); 31165 } 31166 31167 return this; 31168 } 31169 31170 getPlaybackRate() { 31171 return this.playbackRate; 31172 } 31173 31174 onEnded() { 31175 this.isPlaying = false; 31176 } 31177 31178 getLoop() { 31179 if (this.hasPlaybackControl === false) { 31180 console.warn('THREE.Audio: this Audio has no playback control.'); 31181 return false; 31182 } 31183 31184 return this.loop; 31185 } 31186 31187 setLoop(value) { 31188 if (this.hasPlaybackControl === false) { 31189 console.warn('THREE.Audio: this Audio has no playback control.'); 31190 return; 31191 } 31192 31193 this.loop = value; 31194 31195 if (this.isPlaying === true) { 31196 this.source.loop = this.loop; 31197 } 31198 31199 return this; 31200 } 31201 31202 setLoopStart(value) { 31203 this.loopStart = value; 31204 return this; 31205 } 31206 31207 setLoopEnd(value) { 31208 this.loopEnd = value; 31209 return this; 31210 } 31211 31212 getVolume() { 31213 return this.gain.gain.value; 31214 } 31215 31216 setVolume(value) { 31217 this.gain.gain.setTargetAtTime(value, this.context.currentTime, 0.01); 31218 return this; 31219 } 31220 31221 } 31222 31223 const _position = /*@__PURE__*/new Vector3(); 31224 31225 const _quaternion = /*@__PURE__*/new Quaternion(); 31226 31227 const _scale = /*@__PURE__*/new Vector3(); 31228 31229 const _orientation = /*@__PURE__*/new Vector3(); 31230 31231 class PositionalAudio extends Audio { 31232 constructor(listener) { 31233 super(listener); 31234 this.panner = this.context.createPanner(); 31235 this.panner.panningModel = 'HRTF'; 31236 this.panner.connect(this.gain); 31237 } 31238 31239 getOutput() { 31240 return this.panner; 31241 } 31242 31243 getRefDistance() { 31244 return this.panner.refDistance; 31245 } 31246 31247 setRefDistance(value) { 31248 this.panner.refDistance = value; 31249 return this; 31250 } 31251 31252 getRolloffFactor() { 31253 return this.panner.rolloffFactor; 31254 } 31255 31256 setRolloffFactor(value) { 31257 this.panner.rolloffFactor = value; 31258 return this; 31259 } 31260 31261 getDistanceModel() { 31262 return this.panner.distanceModel; 31263 } 31264 31265 setDistanceModel(value) { 31266 this.panner.distanceModel = value; 31267 return this; 31268 } 31269 31270 getMaxDistance() { 31271 return this.panner.maxDistance; 31272 } 31273 31274 setMaxDistance(value) { 31275 this.panner.maxDistance = value; 31276 return this; 31277 } 31278 31279 setDirectionalCone(coneInnerAngle, coneOuterAngle, coneOuterGain) { 31280 this.panner.coneInnerAngle = coneInnerAngle; 31281 this.panner.coneOuterAngle = coneOuterAngle; 31282 this.panner.coneOuterGain = coneOuterGain; 31283 return this; 31284 } 31285 31286 updateMatrixWorld(force) { 31287 super.updateMatrixWorld(force); 31288 if (this.hasPlaybackControl === true && this.isPlaying === false) return; 31289 this.matrixWorld.decompose(_position, _quaternion, _scale); 31290 31291 _orientation.set(0, 0, 1).applyQuaternion(_quaternion); 31292 31293 const panner = this.panner; 31294 31295 if (panner.positionX) { 31296 // code path for Chrome and Firefox (see #14393) 31297 const endTime = this.context.currentTime + this.listener.timeDelta; 31298 panner.positionX.linearRampToValueAtTime(_position.x, endTime); 31299 panner.positionY.linearRampToValueAtTime(_position.y, endTime); 31300 panner.positionZ.linearRampToValueAtTime(_position.z, endTime); 31301 panner.orientationX.linearRampToValueAtTime(_orientation.x, endTime); 31302 panner.orientationY.linearRampToValueAtTime(_orientation.y, endTime); 31303 panner.orientationZ.linearRampToValueAtTime(_orientation.z, endTime); 31304 } else { 31305 panner.setPosition(_position.x, _position.y, _position.z); 31306 panner.setOrientation(_orientation.x, _orientation.y, _orientation.z); 31307 } 31308 } 31309 31310 } 31311 31312 class AudioAnalyser { 31313 constructor(audio, fftSize = 2048) { 31314 this.analyser = audio.context.createAnalyser(); 31315 this.analyser.fftSize = fftSize; 31316 this.data = new Uint8Array(this.analyser.frequencyBinCount); 31317 audio.getOutput().connect(this.analyser); 31318 } 31319 31320 getFrequencyData() { 31321 this.analyser.getByteFrequencyData(this.data); 31322 return this.data; 31323 } 31324 31325 getAverageFrequency() { 31326 let value = 0; 31327 const data = this.getFrequencyData(); 31328 31329 for (let i = 0; i < data.length; i++) { 31330 value += data[i]; 31331 } 31332 31333 return value / data.length; 31334 } 31335 31336 } 31337 31338 class PropertyMixer { 31339 constructor(binding, typeName, valueSize) { 31340 this.binding = binding; 31341 this.valueSize = valueSize; 31342 let mixFunction, mixFunctionAdditive, setIdentity; // buffer layout: [ incoming | accu0 | accu1 | orig | addAccu | (optional work) ] 31343 // 31344 // interpolators can use .buffer as their .result 31345 // the data then goes to 'incoming' 31346 // 31347 // 'accu0' and 'accu1' are used frame-interleaved for 31348 // the cumulative result and are compared to detect 31349 // changes 31350 // 31351 // 'orig' stores the original state of the property 31352 // 31353 // 'add' is used for additive cumulative results 31354 // 31355 // 'work' is optional and is only present for quaternion types. It is used 31356 // to store intermediate quaternion multiplication results 31357 31358 switch (typeName) { 31359 case 'quaternion': 31360 mixFunction = this._slerp; 31361 mixFunctionAdditive = this._slerpAdditive; 31362 setIdentity = this._setAdditiveIdentityQuaternion; 31363 this.buffer = new Float64Array(valueSize * 6); 31364 this._workIndex = 5; 31365 break; 31366 31367 case 'string': 31368 case 'bool': 31369 mixFunction = this._select; // Use the regular mix function and for additive on these types, 31370 // additive is not relevant for non-numeric types 31371 31372 mixFunctionAdditive = this._select; 31373 setIdentity = this._setAdditiveIdentityOther; 31374 this.buffer = new Array(valueSize * 5); 31375 break; 31376 31377 default: 31378 mixFunction = this._lerp; 31379 mixFunctionAdditive = this._lerpAdditive; 31380 setIdentity = this._setAdditiveIdentityNumeric; 31381 this.buffer = new Float64Array(valueSize * 5); 31382 } 31383 31384 this._mixBufferRegion = mixFunction; 31385 this._mixBufferRegionAdditive = mixFunctionAdditive; 31386 this._setIdentity = setIdentity; 31387 this._origIndex = 3; 31388 this._addIndex = 4; 31389 this.cumulativeWeight = 0; 31390 this.cumulativeWeightAdditive = 0; 31391 this.useCount = 0; 31392 this.referenceCount = 0; 31393 } // accumulate data in the 'incoming' region into 'accu<i>' 31394 31395 31396 accumulate(accuIndex, weight) { 31397 // note: happily accumulating nothing when weight = 0, the caller knows 31398 // the weight and shouldn't have made the call in the first place 31399 const buffer = this.buffer, 31400 stride = this.valueSize, 31401 offset = accuIndex * stride + stride; 31402 let currentWeight = this.cumulativeWeight; 31403 31404 if (currentWeight === 0) { 31405 // accuN := incoming * weight 31406 for (let i = 0; i !== stride; ++i) { 31407 buffer[offset + i] = buffer[i]; 31408 } 31409 31410 currentWeight = weight; 31411 } else { 31412 // accuN := accuN + incoming * weight 31413 currentWeight += weight; 31414 const mix = weight / currentWeight; 31415 31416 this._mixBufferRegion(buffer, offset, 0, mix, stride); 31417 } 31418 31419 this.cumulativeWeight = currentWeight; 31420 } // accumulate data in the 'incoming' region into 'add' 31421 31422 31423 accumulateAdditive(weight) { 31424 const buffer = this.buffer, 31425 stride = this.valueSize, 31426 offset = stride * this._addIndex; 31427 31428 if (this.cumulativeWeightAdditive === 0) { 31429 // add = identity 31430 this._setIdentity(); 31431 } // add := add + incoming * weight 31432 31433 31434 this._mixBufferRegionAdditive(buffer, offset, 0, weight, stride); 31435 31436 this.cumulativeWeightAdditive += weight; 31437 } // apply the state of 'accu<i>' to the binding when accus differ 31438 31439 31440 apply(accuIndex) { 31441 const stride = this.valueSize, 31442 buffer = this.buffer, 31443 offset = accuIndex * stride + stride, 31444 weight = this.cumulativeWeight, 31445 weightAdditive = this.cumulativeWeightAdditive, 31446 binding = this.binding; 31447 this.cumulativeWeight = 0; 31448 this.cumulativeWeightAdditive = 0; 31449 31450 if (weight < 1) { 31451 // accuN := accuN + original * ( 1 - cumulativeWeight ) 31452 const originalValueOffset = stride * this._origIndex; 31453 31454 this._mixBufferRegion(buffer, offset, originalValueOffset, 1 - weight, stride); 31455 } 31456 31457 if (weightAdditive > 0) { 31458 // accuN := accuN + additive accuN 31459 this._mixBufferRegionAdditive(buffer, offset, this._addIndex * stride, 1, stride); 31460 } 31461 31462 for (let i = stride, e = stride + stride; i !== e; ++i) { 31463 if (buffer[i] !== buffer[i + stride]) { 31464 // value has changed -> update scene graph 31465 binding.setValue(buffer, offset); 31466 break; 31467 } 31468 } 31469 } // remember the state of the bound property and copy it to both accus 31470 31471 31472 saveOriginalState() { 31473 const binding = this.binding; 31474 const buffer = this.buffer, 31475 stride = this.valueSize, 31476 originalValueOffset = stride * this._origIndex; 31477 binding.getValue(buffer, originalValueOffset); // accu[0..1] := orig -- initially detect changes against the original 31478 31479 for (let i = stride, e = originalValueOffset; i !== e; ++i) { 31480 buffer[i] = buffer[originalValueOffset + i % stride]; 31481 } // Add to identity for additive 31482 31483 31484 this._setIdentity(); 31485 31486 this.cumulativeWeight = 0; 31487 this.cumulativeWeightAdditive = 0; 31488 } // apply the state previously taken via 'saveOriginalState' to the binding 31489 31490 31491 restoreOriginalState() { 31492 const originalValueOffset = this.valueSize * 3; 31493 this.binding.setValue(this.buffer, originalValueOffset); 31494 } 31495 31496 _setAdditiveIdentityNumeric() { 31497 const startIndex = this._addIndex * this.valueSize; 31498 const endIndex = startIndex + this.valueSize; 31499 31500 for (let i = startIndex; i < endIndex; i++) { 31501 this.buffer[i] = 0; 31502 } 31503 } 31504 31505 _setAdditiveIdentityQuaternion() { 31506 this._setAdditiveIdentityNumeric(); 31507 31508 this.buffer[this._addIndex * this.valueSize + 3] = 1; 31509 } 31510 31511 _setAdditiveIdentityOther() { 31512 const startIndex = this._origIndex * this.valueSize; 31513 const targetIndex = this._addIndex * this.valueSize; 31514 31515 for (let i = 0; i < this.valueSize; i++) { 31516 this.buffer[targetIndex + i] = this.buffer[startIndex + i]; 31517 } 31518 } // mix functions 31519 31520 31521 _select(buffer, dstOffset, srcOffset, t, stride) { 31522 if (t >= 0.5) { 31523 for (let i = 0; i !== stride; ++i) { 31524 buffer[dstOffset + i] = buffer[srcOffset + i]; 31525 } 31526 } 31527 } 31528 31529 _slerp(buffer, dstOffset, srcOffset, t) { 31530 Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t); 31531 } 31532 31533 _slerpAdditive(buffer, dstOffset, srcOffset, t, stride) { 31534 const workOffset = this._workIndex * stride; // Store result in intermediate buffer offset 31535 31536 Quaternion.multiplyQuaternionsFlat(buffer, workOffset, buffer, dstOffset, buffer, srcOffset); // Slerp to the intermediate result 31537 31538 Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t); 31539 } 31540 31541 _lerp(buffer, dstOffset, srcOffset, t, stride) { 31542 const s = 1 - t; 31543 31544 for (let i = 0; i !== stride; ++i) { 31545 const j = dstOffset + i; 31546 buffer[j] = buffer[j] * s + buffer[srcOffset + i] * t; 31547 } 31548 } 31549 31550 _lerpAdditive(buffer, dstOffset, srcOffset, t, stride) { 31551 for (let i = 0; i !== stride; ++i) { 31552 const j = dstOffset + i; 31553 buffer[j] = buffer[j] + buffer[srcOffset + i] * t; 31554 } 31555 } 31556 31557 } 31558 31559 // Characters [].:/ are reserved for track binding syntax. 31560 const _RESERVED_CHARS_RE = '\\[\\]\\.:\\/'; 31561 31562 const _reservedRe = new RegExp('[' + _RESERVED_CHARS_RE + ']', 'g'); // Attempts to allow node names from any language. ES5's `\w` regexp matches 31563 // only latin characters, and the unicode \p{L} is not yet supported. So 31564 // instead, we exclude reserved characters and match everything else. 31565 31566 31567 const _wordChar = '[^' + _RESERVED_CHARS_RE + ']'; 31568 31569 const _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace('\\.', '') + ']'; // Parent directories, delimited by '/' or ':'. Currently unused, but must 31570 // be matched to parse the rest of the track name. 31571 31572 31573 const _directoryRe = /((?:WC+[\/:])*)/.source.replace('WC', _wordChar); // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'. 31574 31575 31576 const _nodeRe = /(WCOD+)?/.source.replace('WCOD', _wordCharOrDot); // Object on target node, and accessor. May not contain reserved 31577 // characters. Accessor may contain any character except closing bracket. 31578 31579 31580 const _objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace('WC', _wordChar); // Property and accessor. May not contain reserved characters. Accessor may 31581 // contain any non-bracket characters. 31582 31583 31584 const _propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace('WC', _wordChar); 31585 31586 const _trackRe = new RegExp('' + '^' + _directoryRe + _nodeRe + _objectRe + _propertyRe + '$'); 31587 31588 const _supportedObjectNames = ['material', 'materials', 'bones']; 31589 31590 class Composite { 31591 constructor(targetGroup, path, optionalParsedPath) { 31592 const parsedPath = optionalParsedPath || PropertyBinding.parseTrackName(path); 31593 this._targetGroup = targetGroup; 31594 this._bindings = targetGroup.subscribe_(path, parsedPath); 31595 } 31596 31597 getValue(array, offset) { 31598 this.bind(); // bind all binding 31599 31600 const firstValidIndex = this._targetGroup.nCachedObjects_, 31601 binding = this._bindings[firstValidIndex]; // and only call .getValue on the first 31602 31603 if (binding !== undefined) binding.getValue(array, offset); 31604 } 31605 31606 setValue(array, offset) { 31607 const bindings = this._bindings; 31608 31609 for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { 31610 bindings[i].setValue(array, offset); 31611 } 31612 } 31613 31614 bind() { 31615 const bindings = this._bindings; 31616 31617 for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { 31618 bindings[i].bind(); 31619 } 31620 } 31621 31622 unbind() { 31623 const bindings = this._bindings; 31624 31625 for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { 31626 bindings[i].unbind(); 31627 } 31628 } 31629 31630 } // Note: This class uses a State pattern on a per-method basis: 31631 // 'bind' sets 'this.getValue' / 'setValue' and shadows the 31632 // prototype version of these methods with one that represents 31633 // the bound state. When the property is not found, the methods 31634 // become no-ops. 31635 31636 31637 class PropertyBinding { 31638 constructor(rootNode, path, parsedPath) { 31639 this.path = path; 31640 this.parsedPath = parsedPath || PropertyBinding.parseTrackName(path); 31641 this.node = PropertyBinding.findNode(rootNode, this.parsedPath.nodeName) || rootNode; 31642 this.rootNode = rootNode; // initial state of these methods that calls 'bind' 31643 31644 this.getValue = this._getValue_unbound; 31645 this.setValue = this._setValue_unbound; 31646 } 31647 31648 static create(root, path, parsedPath) { 31649 if (!(root && root.isAnimationObjectGroup)) { 31650 return new PropertyBinding(root, path, parsedPath); 31651 } else { 31652 return new PropertyBinding.Composite(root, path, parsedPath); 31653 } 31654 } 31655 /** 31656 * Replaces spaces with underscores and removes unsupported characters from 31657 * node names, to ensure compatibility with parseTrackName(). 31658 * 31659 * @param {string} name Node name to be sanitized. 31660 * @return {string} 31661 */ 31662 31663 31664 static sanitizeNodeName(name) { 31665 return name.replace(/\s/g, '_').replace(_reservedRe, ''); 31666 } 31667 31668 static parseTrackName(trackName) { 31669 const matches = _trackRe.exec(trackName); 31670 31671 if (!matches) { 31672 throw new Error('PropertyBinding: Cannot parse trackName: ' + trackName); 31673 } 31674 31675 const results = { 31676 // directoryName: matches[ 1 ], // (tschw) currently unused 31677 nodeName: matches[2], 31678 objectName: matches[3], 31679 objectIndex: matches[4], 31680 propertyName: matches[5], 31681 // required 31682 propertyIndex: matches[6] 31683 }; 31684 const lastDot = results.nodeName && results.nodeName.lastIndexOf('.'); 31685 31686 if (lastDot !== undefined && lastDot !== -1) { 31687 const objectName = results.nodeName.substring(lastDot + 1); // Object names must be checked against an allowlist. Otherwise, there 31688 // is no way to parse 'foo.bar.baz': 'baz' must be a property, but 31689 // 'bar' could be the objectName, or part of a nodeName (which can 31690 // include '.' characters). 31691 31692 if (_supportedObjectNames.indexOf(objectName) !== -1) { 31693 results.nodeName = results.nodeName.substring(0, lastDot); 31694 results.objectName = objectName; 31695 } 31696 } 31697 31698 if (results.propertyName === null || results.propertyName.length === 0) { 31699 throw new Error('PropertyBinding: can not parse propertyName from trackName: ' + trackName); 31700 } 31701 31702 return results; 31703 } 31704 31705 static findNode(root, nodeName) { 31706 if (!nodeName || nodeName === '' || nodeName === '.' || nodeName === -1 || nodeName === root.name || nodeName === root.uuid) { 31707 return root; 31708 } // search into skeleton bones. 31709 31710 31711 if (root.skeleton) {
vendor: 4,641 bytes, lines 31712-31884
31712 const bone = root.skeleton.getBoneByName(nodeName); 31713 31714 if (bone !== undefined) { 31715 return bone; 31716 } 31717 } // search into node subtree. 31718 31719 31720 if (root.children) { 31721 const searchNodeSubtree = function (children) { 31722 for (let i = 0; i < children.length; i++) { 31723 const childNode = children[i]; 31724 31725 if (childNode.name === nodeName || childNode.uuid === nodeName) { 31726 return childNode; 31727 } 31728 31729 const result = searchNodeSubtree(childNode.children); 31730 if (result) return result; 31731 } 31732 31733 return null; 31734 }; 31735 31736 const subTreeNode = searchNodeSubtree(root.children); 31737 31738 if (subTreeNode) { 31739 return subTreeNode; 31740 } 31741 } 31742 31743 return null; 31744 } // these are used to "bind" a nonexistent property 31745 31746 31747 _getValue_unavailable() {} 31748 31749 _setValue_unavailable() {} // Getters 31750 31751 31752 _getValue_direct(buffer, offset) { 31753 buffer[offset] = this.targetObject[this.propertyName]; 31754 } 31755 31756 _getValue_array(buffer, offset) { 31757 const source = this.resolvedProperty; 31758 31759 for (let i = 0, n = source.length; i !== n; ++i) { 31760 buffer[offset++] = source[i]; 31761 } 31762 } 31763 31764 _getValue_arrayElement(buffer, offset) { 31765 buffer[offset] = this.resolvedProperty[this.propertyIndex]; 31766 } 31767 31768 _getValue_toArray(buffer, offset) { 31769 this.resolvedProperty.toArray(buffer, offset); 31770 } // Direct 31771 31772 31773 _setValue_direct(buffer, offset) { 31774 this.targetObject[this.propertyName] = buffer[offset]; 31775 } 31776 31777 _setValue_direct_setNeedsUpdate(buffer, offset) { 31778 this.targetObject[this.propertyName] = buffer[offset]; 31779 this.targetObject.needsUpdate = true; 31780 } 31781 31782 _setValue_direct_setMatrixWorldNeedsUpdate(buffer, offset) { 31783 this.targetObject[this.propertyName] = buffer[offset]; 31784 this.targetObject.matrixWorldNeedsUpdate = true; 31785 } // EntireArray 31786 31787 31788 _setValue_array(buffer, offset) { 31789 const dest = this.resolvedProperty; 31790 31791 for (let i = 0, n = dest.length; i !== n; ++i) { 31792 dest[i] = buffer[offset++]; 31793 } 31794 } 31795 31796 _setValue_array_setNeedsUpdate(buffer, offset) { 31797 const dest = this.resolvedProperty; 31798 31799 for (let i = 0, n = dest.length; i !== n; ++i) { 31800 dest[i] = buffer[offset++]; 31801 } 31802 31803 this.targetObject.needsUpdate = true; 31804 } 31805 31806 _setValue_array_setMatrixWorldNeedsUpdate(buffer, offset) { 31807 const dest = this.resolvedProperty; 31808 31809 for (let i = 0, n = dest.length; i !== n; ++i) { 31810 dest[i] = buffer[offset++]; 31811 } 31812 31813 this.targetObject.matrixWorldNeedsUpdate = true; 31814 } // ArrayElement 31815 31816 31817 _setValue_arrayElement(buffer, offset) { 31818 this.resolvedProperty[this.propertyIndex] = buffer[offset]; 31819 } 31820 31821 _setValue_arrayElement_setNeedsUpdate(buffer, offset) { 31822 this.resolvedProperty[this.propertyIndex] = buffer[offset]; 31823 this.targetObject.needsUpdate = true; 31824 } 31825 31826 _setValue_arrayElement_setMatrixWorldNeedsUpdate(buffer, offset) { 31827 this.resolvedProperty[this.propertyIndex] = buffer[offset]; 31828 this.targetObject.matrixWorldNeedsUpdate = true; 31829 } // HasToFromArray 31830 31831 31832 _setValue_fromArray(buffer, offset) { 31833 this.resolvedProperty.fromArray(buffer, offset); 31834 } 31835 31836 _setValue_fromArray_setNeedsUpdate(buffer, offset) { 31837 this.resolvedProperty.fromArray(buffer, offset); 31838 this.targetObject.needsUpdate = true; 31839 } 31840 31841 _setValue_fromArray_setMatrixWorldNeedsUpdate(buffer, offset) { 31842 this.resolvedProperty.fromArray(buffer, offset); 31843 this.targetObject.matrixWorldNeedsUpdate = true; 31844 } 31845 31846 _getValue_unbound(targetArray, offset) { 31847 this.bind(); 31848 this.getValue(targetArray, offset); 31849 } 31850 31851 _setValue_unbound(sourceArray, offset) { 31852 this.bind(); 31853 this.setValue(sourceArray, offset); 31854 } // create getter / setter pair for a property in the scene graph 31855 31856 31857 bind() { 31858 let targetObject = this.node; 31859 const parsedPath = this.parsedPath; 31860 const objectName = parsedPath.objectName; 31861 const propertyName = parsedPath.propertyName; 31862 let propertyIndex = parsedPath.propertyIndex; 31863 31864 if (!targetObject) { 31865 targetObject = PropertyBinding.findNode(this.rootNode, parsedPath.nodeName) || this.rootNode; 31866 this.node = targetObject; 31867 } // set fail state so we can just 'return' on error 31868 31869 31870 this.getValue = this._getValue_unavailable; 31871 this.setValue = this._setValue_unavailable; // ensure there is a value node 31872 31873 if (!targetObject) { 31874 console.error('THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.'); 31875 return; 31876 } 31877 31878 if (objectName) { 31879 let objectIndex = parsedPath.objectIndex; // special cases were we need to reach deeper into the hierarchy to get the face materials.... 31880 31881 switch (objectName) { 31882 case 'materials': 31883 if (!targetObject.material) { 31884 console.error('THREE.PropertyBinding: Can not bind to material as no
vendor: 5,355 bytes, lines 31884-32027
31884de does not have a material.', this); 31885 return; 31886 } 31887 31888 if (!targetObject.material.materials) { 31889 console.error('THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.', this); 31890 return; 31891 } 31892 31893 targetObject = targetObject.material.materials; 31894 break; 31895 31896 case 'bones': 31897 if (!targetObject.skeleton) { 31898 console.error('THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.', this); 31899 return; 31900 } // potential future optimization: skip this if propertyIndex is already an integer 31901 // and convert the integer string to a true integer. 31902 31903 31904 targetObject = targetObject.skeleton.bones; // support resolving morphTarget names into indices. 31905 31906 for (let i = 0; i < targetObject.length; i++) { 31907 if (targetObject[i].name === objectIndex) { 31908 objectIndex = i; 31909 break; 31910 } 31911 } 31912 31913 break; 31914 31915 default: 31916 if (targetObject[objectName] === undefined) { 31917 console.error('THREE.PropertyBinding: Can not bind to objectName of node undefined.', this); 31918 return; 31919 } 31920 31921 targetObject = targetObject[objectName]; 31922 } 31923 31924 if (objectIndex !== undefined) { 31925 if (targetObject[objectIndex] === undefined) { 31926 console.error('THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject); 31927 return; 31928 } 31929 31930 targetObject = targetObject[objectIndex]; 31931 } 31932 } // resolve property 31933 31934 31935 const nodeProperty = targetObject[propertyName]; 31936 31937 if (nodeProperty === undefined) { 31938 const nodeName = parsedPath.nodeName; 31939 console.error('THREE.PropertyBinding: Trying to update property for track: ' + nodeName + '.' + propertyName + ' but it wasn\'t found.', targetObject); 31940 return; 31941 } // determine versioning scheme 31942 31943 31944 let versioning = this.Versioning.None; 31945 this.targetObject = targetObject; 31946 31947 if (targetObject.needsUpdate !== undefined) { 31948 // material 31949 versioning = this.Versioning.NeedsUpdate; 31950 } else if (targetObject.matrixWorldNeedsUpdate !== undefined) { 31951 // node transform 31952 versioning = this.Versioning.MatrixWorldNeedsUpdate; 31953 } // determine how the property gets bound 31954 31955 31956 let bindingType = this.BindingType.Direct; 31957 31958 if (propertyIndex !== undefined) { 31959 // access a sub element of the property array (only primitives are supported right now) 31960 if (propertyName === 'morphTargetInfluences') { 31961 // potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer. 31962 // support resolving morphTarget names into indices. 31963 if (!targetObject.geometry) { 31964 console.error('THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.', this); 31965 return; 31966 } 31967 31968 if (targetObject.geometry.isBufferGeometry) { 31969 if (!targetObject.geometry.morphAttributes) { 31970 console.error('THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this); 31971 return; 31972 } 31973 31974 if (targetObject.morphTargetDictionary[propertyIndex] !== undefined) { 31975 propertyIndex = targetObject.morphTargetDictionary[propertyIndex]; 31976 } 31977 } else { 31978 console.error('THREE.PropertyBinding: Can not bind to morphTargetInfluences on THREE.Geometry. Use THREE.BufferGeometry instead.', this); 31979 return; 31980 } 31981 } 31982 31983 bindingType = this.BindingType.ArrayElement; 31984 this.resolvedProperty = nodeProperty; 31985 this.propertyIndex = propertyIndex; 31986 } else if (nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined) { 31987 // must use copy for Object3D.Euler/Quaternion 31988 bindingType = this.BindingType.HasFromToArray; 31989 this.resolvedProperty = nodeProperty; 31990 } else if (Array.isArray(nodeProperty)) { 31991 bindingType = this.BindingType.EntireArray; 31992 this.resolvedProperty = nodeProperty; 31993 } else { 31994 this.propertyName = propertyName; 31995 } // select getter / setter 31996 31997 31998 this.getValue = this.GetterByBindingType[bindingType]; 31999 this.setValue = this.SetterByBindingTypeAndVersioning[bindingType][versioning]; 32000 } 32001 32002 unbind() { 32003 this.node = null; // back to the prototype version of getValue / setValue 32004 // note: avoiding to mutate the shape of 'this' via 'delete' 32005 32006 this.getValue = this._getValue_unbound; 32007 this.setValue = this._setValue_unbound; 32008 } 32009 32010 } 32011 32012 PropertyBinding.Composite = Composite; 32013 PropertyBinding.prototype.BindingType = { 32014 Direct: 0, 32015 EntireArray: 1, 32016 ArrayElement: 2, 32017 HasFromToArray: 3 32018 }; 32019 PropertyBinding.prototype.Versioning = { 32020 None: 0, 32021 NeedsUpdate: 1, 32022 MatrixWorldNeedsUpdate: 2 32023 }; 32024 PropertyBinding.prototype.GetterByBindingType = [PropertyBinding.prototype._getValue_direct, PropertyBinding.prototype._getValue_array, PropertyBinding.prototype._getValue_arrayElement, PropertyBinding.prototype._getValue_toArray]; 32025 PropertyBinding.prototype.SetterByBindingTypeAndVersioning = [[// Direct 32026 PropertyBinding.prototype._setValue_direct, PropertyBinding.prototype._setValue_direct_setNeedsUpdate, PropertyBinding.prototype._setValue_direct_setMatrixWorldNeedsUpdate], [// EntireArray 32027 PropertyBinding.prototype._setValue_array, PropertyBinding.prototype._setValue_array_setNeedsUpdate, PropertyBinding.prototype._setValue_array_setMatr
vendor: 4,194 bytes, lines 32027-32154
32027ixWorldNeedsUpdate], [// ArrayElement 32028 PropertyBinding.prototype._setValue_arrayElement, PropertyBinding.prototype._setValue_arrayElement_setNeedsUpdate, PropertyBinding.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate], [// HasToFromArray 32029 PropertyBinding.prototype._setValue_fromArray, PropertyBinding.prototype._setValue_fromArray_setNeedsUpdate, PropertyBinding.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate]]; 32030 32031 /** 32032 * 32033 * A group of objects that receives a shared animation state. 32034 * 32035 * Usage: 32036 * 32037 * - Add objects you would otherwise pass as 'root' to the 32038 * constructor or the .clipAction method of AnimationMixer. 32039 * 32040 * - Instead pass this object as 'root'. 32041 * 32042 * - You can also add and remove objects later when the mixer 32043 * is running. 32044 * 32045 * Note: 32046 * 32047 * Objects of this class appear as one object to the mixer, 32048 * so cache control of the individual objects must be done 32049 * on the group. 32050 * 32051 * Limitation: 32052 * 32053 * - The animated properties must be compatible among the 32054 * all objects in the group. 32055 * 32056 * - A single property can either be controlled through a 32057 * target group or directly, but not both. 32058 */ 32059 32060 class AnimationObjectGroup { 32061 constructor() { 32062 this.uuid = generateUUID(); // cached objects followed by the active ones 32063 32064 this._objects = Array.prototype.slice.call(arguments); 32065 this.nCachedObjects_ = 0; // threshold 32066 // note: read by PropertyBinding.Composite 32067 32068 const indices = {}; 32069 this._indicesByUUID = indices; // for bookkeeping 32070 32071 for (let i = 0, n = arguments.length; i !== n; ++i) { 32072 indices[arguments[i].uuid] = i; 32073 } 32074 32075 this._paths = []; // inside: string 32076 32077 this._parsedPaths = []; // inside: { we don't care, here } 32078 32079 this._bindings = []; // inside: Array< PropertyBinding > 32080 32081 this._bindingsIndicesByPath = {}; // inside: indices in these arrays 32082 32083 const scope = this; 32084 this.stats = { 32085 objects: { 32086 get total() { 32087 return scope._objects.length; 32088 }, 32089 32090 get inUse() { 32091 return this.total - scope.nCachedObjects_; 32092 } 32093 32094 }, 32095 32096 get bindingsPerObject() { 32097 return scope._bindings.length; 32098 } 32099 32100 }; 32101 } 32102 32103 add() { 32104 const objects = this._objects, 32105 indicesByUUID = this._indicesByUUID, 32106 paths = this._paths, 32107 parsedPaths = this._parsedPaths, 32108 bindings = this._bindings, 32109 nBindings = bindings.length; 32110 let knownObject = undefined, 32111 nObjects = objects.length, 32112 nCachedObjects = this.nCachedObjects_; 32113 32114 for (let i = 0, n = arguments.length; i !== n; ++i) { 32115 const object = arguments[i], 32116 uuid = object.uuid; 32117 let index = indicesByUUID[uuid]; 32118 32119 if (index === undefined) { 32120 // unknown object -> add it to the ACTIVE region 32121 index = nObjects++; 32122 indicesByUUID[uuid] = index; 32123 objects.push(object); // accounting is done, now do the same for all bindings 32124 32125 for (let j = 0, m = nBindings; j !== m; ++j) { 32126 bindings[j].push(new PropertyBinding(object, paths[j], parsedPaths[j])); 32127 } 32128 } else if (index < nCachedObjects) { 32129 knownObject = objects[index]; // move existing object to the ACTIVE region 32130 32131 const firstActiveIndex = --nCachedObjects, 32132 lastCachedObject = objects[firstActiveIndex]; 32133 indicesByUUID[lastCachedObject.uuid] = index; 32134 objects[index] = lastCachedObject; 32135 indicesByUUID[uuid] = firstActiveIndex; 32136 objects[firstActiveIndex] = object; // accounting is done, now do the same for all bindings 32137 32138 for (let j = 0, m = nBindings; j !== m; ++j) { 32139 const bindingsForPath = bindings[j], 32140 lastCached = bindingsForPath[firstActiveIndex]; 32141 let binding = bindingsForPath[index]; 32142 bindingsForPath[index] = lastCached; 32143 32144 if (binding === undefined) { 32145 // since we do not bother to create new bindings 32146 // for objects that are cached, the binding may 32147 // or may not exist 32148 binding = new PropertyBinding(object, paths[j], parsedPaths[j]); 32149 } 32150 32151 bindingsForPath[firstActiveIndex] = binding; 32152 } 32153 } else if (objects[index] !== knownObject) { 32154 console.error('THREE.AnimationObjectGroup: Different objects with the same UUID ' + 'detected. Clean the caches or recreate your infrastru
vendor: 7,337 bytes, lines 32154-32389
32154cture when reloading scenes.'); 32155 } // else the object is already where we want it to be 32156 32157 } // for arguments 32158 32159 32160 this.nCachedObjects_ = nCachedObjects; 32161 } 32162 32163 remove() { 32164 const objects = this._objects, 32165 indicesByUUID = this._indicesByUUID, 32166 bindings = this._bindings, 32167 nBindings = bindings.length; 32168 let nCachedObjects = this.nCachedObjects_; 32169 32170 for (let i = 0, n = arguments.length; i !== n; ++i) { 32171 const object = arguments[i], 32172 uuid = object.uuid, 32173 index = indicesByUUID[uuid]; 32174 32175 if (index !== undefined && index >= nCachedObjects) { 32176 // move existing object into the CACHED region 32177 const lastCachedIndex = nCachedObjects++, 32178 firstActiveObject = objects[lastCachedIndex]; 32179 indicesByUUID[firstActiveObject.uuid] = index; 32180 objects[index] = firstActiveObject; 32181 indicesByUUID[uuid] = lastCachedIndex; 32182 objects[lastCachedIndex] = object; // accounting is done, now do the same for all bindings 32183 32184 for (let j = 0, m = nBindings; j !== m; ++j) { 32185 const bindingsForPath = bindings[j], 32186 firstActive = bindingsForPath[lastCachedIndex], 32187 binding = bindingsForPath[index]; 32188 bindingsForPath[index] = firstActive; 32189 bindingsForPath[lastCachedIndex] = binding; 32190 } 32191 } 32192 } // for arguments 32193 32194 32195 this.nCachedObjects_ = nCachedObjects; 32196 } // remove & forget 32197 32198 32199 uncache() { 32200 const objects = this._objects, 32201 indicesByUUID = this._indicesByUUID, 32202 bindings = this._bindings, 32203 nBindings = bindings.length; 32204 let nCachedObjects = this.nCachedObjects_, 32205 nObjects = objects.length; 32206 32207 for (let i = 0, n = arguments.length; i !== n; ++i) { 32208 const object = arguments[i], 32209 uuid = object.uuid, 32210 index = indicesByUUID[uuid]; 32211 32212 if (index !== undefined) { 32213 delete indicesByUUID[uuid]; 32214 32215 if (index < nCachedObjects) { 32216 // object is cached, shrink the CACHED region 32217 const firstActiveIndex = --nCachedObjects, 32218 lastCachedObject = objects[firstActiveIndex], 32219 lastIndex = --nObjects, 32220 lastObject = objects[lastIndex]; // last cached object takes this object's place 32221 32222 indicesByUUID[lastCachedObject.uuid] = index; 32223 objects[index] = lastCachedObject; // last object goes to the activated slot and pop 32224 32225 indicesByUUID[lastObject.uuid] = firstActiveIndex; 32226 objects[firstActiveIndex] = lastObject; 32227 objects.pop(); // accounting is done, now do the same for all bindings 32228 32229 for (let j = 0, m = nBindings; j !== m; ++j) { 32230 const bindingsForPath = bindings[j], 32231 lastCached = bindingsForPath[firstActiveIndex], 32232 last = bindingsForPath[lastIndex]; 32233 bindingsForPath[index] = lastCached; 32234 bindingsForPath[firstActiveIndex] = last; 32235 bindingsForPath.pop(); 32236 } 32237 } else { 32238 // object is active, just swap with the last and pop 32239 const lastIndex = --nObjects, 32240 lastObject = objects[lastIndex]; 32241 32242 if (lastIndex > 0) { 32243 indicesByUUID[lastObject.uuid] = index; 32244 } 32245 32246 objects[index] = lastObject; 32247 objects.pop(); // accounting is done, now do the same for all bindings 32248 32249 for (let j = 0, m = nBindings; j !== m; ++j) { 32250 const bindingsForPath = bindings[j]; 32251 bindingsForPath[index] = bindingsForPath[lastIndex]; 32252 bindingsForPath.pop(); 32253 } 32254 } // cached or active 32255 32256 } // if object is known 32257 32258 } // for arguments 32259 32260 32261 this.nCachedObjects_ = nCachedObjects; 32262 } // Internal interface used by befriended PropertyBinding.Composite: 32263 32264 32265 subscribe_(path, parsedPath) { 32266 // returns an array of bindings for the given path that is changed 32267 // according to the contained objects in the group 32268 const indicesByPath = this._bindingsIndicesByPath; 32269 let index = indicesByPath[path]; 32270 const bindings = this._bindings; 32271 if (index !== undefined) return bindings[index]; 32272 const paths = this._paths, 32273 parsedPaths = this._parsedPaths, 32274 objects = this._objects, 32275 nObjects = objects.length, 32276 nCachedObjects = this.nCachedObjects_, 32277 bindingsForPath = new Array(nObjects); 32278 index = bindings.length; 32279 indicesByPath[path] = index; 32280 paths.push(path); 32281 parsedPaths.push(parsedPath); 32282 bindings.push(bindingsForPath); 32283 32284 for (let i = nCachedObjects, n = objects.length; i !== n; ++i) { 32285 const object = objects[i]; 32286 bindingsForPath[i] = new PropertyBinding(object, path, parsedPath); 32287 } 32288 32289 return bindingsForPath; 32290 } 32291 32292 unsubscribe_(path) { 32293 // tells the group to forget about a property path and no longer 32294 // update the array previously obtained with 'subscribe_' 32295 const indicesByPath = this._bindingsIndicesByPath, 32296 index = indicesByPath[path]; 32297 32298 if (index !== undefined) { 32299 const paths = this._paths, 32300 parsedPaths = this._parsedPaths, 32301 bindings = this._bindings, 32302 lastBindingsIndex = bindings.length - 1, 32303 lastBindings = bindings[lastBindingsIndex], 32304 lastBindingsPath = path[lastBindingsIndex]; 32305 indicesByPath[lastBindingsPath] = index; 32306 bindings[index] = lastBindings; 32307 bindings.pop(); 32308 parsedPaths[index] = parsedPaths[lastBindingsIndex]; 32309 parsedPaths.pop(); 32310 paths[index] = paths[lastBindingsIndex]; 32311 paths.pop(); 32312 } 32313 } 32314 32315 } 32316 32317 AnimationObjectGroup.prototype.isAnimationObjectGroup = true; 32318 32319 class AnimationAction { 32320 constructor(mixer, clip, localRoot = null, blendMode = clip.blendMode) { 32321 this._mixer = mixer; 32322 this._clip = clip; 32323 this._localRoot = localRoot; 32324 this.blendMode = blendMode; 32325 const tracks = clip.tracks, 32326 nTracks = tracks.length, 32327 interpolants = new Array(nTracks); 32328 const interpolantSettings = { 32329 endingStart: ZeroCurvatureEnding, 32330 endingEnd: ZeroCurvatureEnding 32331 }; 32332 32333 for (let i = 0; i !== nTracks; ++i) { 32334 const interpolant = tracks[i].createInterpolant(null); 32335 interpolants[i] = interpolant; 32336 interpolant.settings = interpolantSettings; 32337 } 32338 32339 this._interpolantSettings = interpolantSettings; 32340 this._interpolants = interpolants; // bound by the mixer 32341 // inside: PropertyMixer (managed by the mixer) 32342 32343 this._propertyBindings = new Array(nTracks); 32344 this._cacheIndex = null; // for the memory manager 32345 32346 this._byClipCacheIndex = null; // for the memory manager 32347 32348 this._timeScaleInterpolant = null; 32349 this._weightInterpolant = null; 32350 this.loop = LoopRepeat; 32351 this._loopCount = -1; // global mixer time when the action is to be started 32352 // it's set back to 'null' upon start of the action 32353 32354 this._startTime = null; // scaled local time of the action 32355 // gets clamped or wrapped to 0..clip.duration according to loop 32356 32357 this.time = 0; 32358 this.timeScale = 1; 32359 this._effectiveTimeScale = 1; 32360 this.weight = 1; 32361 this._effectiveWeight = 1; 32362 this.repetitions = Infinity; // no. of repetitions when looping 32363 32364 this.paused = false; // true -> zero effective time scale 32365 32366 this.enabled = true; // false -> zero effective weight 32367 32368 this.clampWhenFinished = false; // keep feeding the last frame? 32369 32370 this.zeroSlopeAtStart = true; // for smooth interpolation w/o separate 32371 32372 this.zeroSlopeAtEnd = true; // clips for start, loop and end 32373 } // State & Scheduling 32374 32375 32376 play() { 32377 this._mixer._activateAction(this); 32378 32379 return this; 32380 } 32381 32382 stop() { 32383 this._mixer._deactivateAction(this); 32384 32385 return this.reset(); 32386 } 32387 32388 reset() { 32389 this.paused = false;
vendor: 10,345 bytes, lines 32390-32814
32390 this.enabled = true; 32391 this.time = 0; // restart clip 32392 32393 this._loopCount = -1; // forget previous loops 32394 32395 this._startTime = null; // forget scheduling 32396 32397 return this.stopFading().stopWarping(); 32398 } 32399 32400 isRunning() { 32401 return this.enabled && !this.paused && this.timeScale !== 0 && this._startTime === null && this._mixer._isActiveAction(this); 32402 } // return true when play has been called 32403 32404 32405 isScheduled() { 32406 return this._mixer._isActiveAction(this); 32407 } 32408 32409 startAt(time) { 32410 this._startTime = time; 32411 return this; 32412 } 32413 32414 setLoop(mode, repetitions) { 32415 this.loop = mode; 32416 this.repetitions = repetitions; 32417 return this; 32418 } // Weight 32419 // set the weight stopping any scheduled fading 32420 // although .enabled = false yields an effective weight of zero, this 32421 // method does *not* change .enabled, because it would be confusing 32422 32423 32424 setEffectiveWeight(weight) { 32425 this.weight = weight; // note: same logic as when updated at runtime 32426 32427 this._effectiveWeight = this.enabled ? weight : 0; 32428 return this.stopFading(); 32429 } // return the weight considering fading and .enabled 32430 32431 32432 getEffectiveWeight() { 32433 return this._effectiveWeight; 32434 } 32435 32436 fadeIn(duration) { 32437 return this._scheduleFading(duration, 0, 1); 32438 } 32439 32440 fadeOut(duration) { 32441 return this._scheduleFading(duration, 1, 0); 32442 } 32443 32444 crossFadeFrom(fadeOutAction, duration, warp) { 32445 fadeOutAction.fadeOut(duration); 32446 this.fadeIn(duration); 32447 32448 if (warp) { 32449 const fadeInDuration = this._clip.duration, 32450 fadeOutDuration = fadeOutAction._clip.duration, 32451 startEndRatio = fadeOutDuration / fadeInDuration, 32452 endStartRatio = fadeInDuration / fadeOutDuration; 32453 fadeOutAction.warp(1.0, startEndRatio, duration); 32454 this.warp(endStartRatio, 1.0, duration); 32455 } 32456 32457 return this; 32458 } 32459 32460 crossFadeTo(fadeInAction, duration, warp) { 32461 return fadeInAction.crossFadeFrom(this, duration, warp); 32462 } 32463 32464 stopFading() { 32465 const weightInterpolant = this._weightInterpolant; 32466 32467 if (weightInterpolant !== null) { 32468 this._weightInterpolant = null; 32469 32470 this._mixer._takeBackControlInterpolant(weightInterpolant); 32471 } 32472 32473 return this; 32474 } // Time Scale Control 32475 // set the time scale stopping any scheduled warping 32476 // although .paused = true yields an effective time scale of zero, this 32477 // method does *not* change .paused, because it would be confusing 32478 32479 32480 setEffectiveTimeScale(timeScale) { 32481 this.timeScale = timeScale; 32482 this._effectiveTimeScale = this.paused ? 0 : timeScale; 32483 return this.stopWarping(); 32484 } // return the time scale considering warping and .paused 32485 32486 32487 getEffectiveTimeScale() { 32488 return this._effectiveTimeScale; 32489 } 32490 32491 setDuration(duration) { 32492 this.timeScale = this._clip.duration / duration; 32493 return this.stopWarping(); 32494 } 32495 32496 syncWith(action) { 32497 this.time = action.time; 32498 this.timeScale = action.timeScale; 32499 return this.stopWarping(); 32500 } 32501 32502 halt(duration) { 32503 return this.warp(this._effectiveTimeScale, 0, duration); 32504 } 32505 32506 warp(startTimeScale, endTimeScale, duration) { 32507 const mixer = this._mixer, 32508 now = mixer.time, 32509 timeScale = this.timeScale; 32510 let interpolant = this._timeScaleInterpolant; 32511 32512 if (interpolant === null) { 32513 interpolant = mixer._lendControlInterpolant(); 32514 this._timeScaleInterpolant = interpolant; 32515 } 32516 32517 const times = interpolant.parameterPositions, 32518 values = interpolant.sampleValues; 32519 times[0] = now; 32520 times[1] = now + duration; 32521 values[0] = startTimeScale / timeScale; 32522 values[1] = endTimeScale / timeScale; 32523 return this; 32524 } 32525 32526 stopWarping() { 32527 const timeScaleInterpolant = this._timeScaleInterpolant; 32528 32529 if (timeScaleInterpolant !== null) { 32530 this._timeScaleInterpolant = null; 32531 32532 this._mixer._takeBackControlInterpolant(timeScaleInterpolant); 32533 } 32534 32535 return this; 32536 } // Object Accessors 32537 32538 32539 getMixer() { 32540 return this._mixer; 32541 } 32542 32543 getClip() { 32544 return this._clip; 32545 } 32546 32547 getRoot() { 32548 return this._localRoot || this._mixer._root; 32549 } // Interna 32550 32551 32552 _update(time, deltaTime, timeDirection, accuIndex) { 32553 // called by the mixer 32554 if (!this.enabled) { 32555 // call ._updateWeight() to update ._effectiveWeight 32556 this._updateWeight(time); 32557 32558 return; 32559 } 32560 32561 const startTime = this._startTime; 32562 32563 if (startTime !== null) { 32564 // check for scheduled start of action 32565 const timeRunning = (time - startTime) * timeDirection; 32566 32567 if (timeRunning < 0 || timeDirection === 0) { 32568 return; // yet to come / don't decide when delta = 0 32569 } // start 32570 32571 32572 this._startTime = null; // unschedule 32573 32574 deltaTime = timeDirection * timeRunning; 32575 } // apply time scale and advance time 32576 32577 32578 deltaTime *= this._updateTimeScale(time); 32579 32580 const clipTime = this._updateTime(deltaTime); // note: _updateTime may disable the action resulting in 32581 // an effective weight of 0 32582 32583 32584 const weight = this._updateWeight(time); 32585 32586 if (weight > 0) { 32587 const interpolants = this._interpolants; 32588 const propertyMixers = this._propertyBindings; 32589 32590 switch (this.blendMode) { 32591 case AdditiveAnimationBlendMode: 32592 for (let j = 0, m = interpolants.length; j !== m; ++j) { 32593 interpolants[j].evaluate(clipTime); 32594 propertyMixers[j].accumulateAdditive(weight); 32595 } 32596 32597 break; 32598 32599 case NormalAnimationBlendMode: 32600 default: 32601 for (let j = 0, m = interpolants.length; j !== m; ++j) { 32602 interpolants[j].evaluate(clipTime); 32603 propertyMixers[j].accumulate(accuIndex, weight); 32604 } 32605 32606 } 32607 } 32608 } 32609 32610 _updateWeight(time) { 32611 let weight = 0; 32612 32613 if (this.enabled) { 32614 weight = this.weight; 32615 const interpolant = this._weightInterpolant; 32616 32617 if (interpolant !== null) { 32618 const interpolantValue = interpolant.evaluate(time)[0]; 32619 weight *= interpolantValue; 32620 32621 if (time > interpolant.parameterPositions[1]) { 32622 this.stopFading(); 32623 32624 if (interpolantValue === 0) { 32625 // faded out, disable 32626 this.enabled = false; 32627 } 32628 } 32629 } 32630 } 32631 32632 this._effectiveWeight = weight; 32633 return weight; 32634 } 32635 32636 _updateTimeScale(time) { 32637 let timeScale = 0; 32638 32639 if (!this.paused) { 32640 timeScale = this.timeScale; 32641 const interpolant = this._timeScaleInterpolant; 32642 32643 if (interpolant !== null) { 32644 const interpolantValue = interpolant.evaluate(time)[0]; 32645 timeScale *= interpolantValue; 32646 32647 if (time > interpolant.parameterPositions[1]) { 32648 this.stopWarping(); 32649 32650 if (timeScale === 0) { 32651 // motion has halted, pause 32652 this.paused = true; 32653 } else { 32654 // warp done - apply final time scale 32655 this.timeScale = timeScale; 32656 } 32657 } 32658 } 32659 } 32660 32661 this._effectiveTimeScale = timeScale; 32662 return timeScale; 32663 } 32664 32665 _updateTime(deltaTime) { 32666 const duration = this._clip.duration; 32667 const loop = this.loop; 32668 let time = this.time + deltaTime; 32669 let loopCount = this._loopCount; 32670 const pingPong = loop === LoopPingPong; 32671 32672 if (deltaTime === 0) { 32673 if (loopCount === -1) return time; 32674 return pingPong && (loopCount & 1) === 1 ? duration - time : time; 32675 } 32676 32677 if (loop === LoopOnce) { 32678 if (loopCount === -1) { 32679 // just started 32680 this._loopCount = 0; 32681 32682 this._setEndings(true, true, false); 32683 } 32684 32685 handle_stop: { 32686 if (time >= duration) { 32687 time = duration; 32688 } else if (time < 0) { 32689 time = 0; 32690 } else { 32691 this.time = time; 32692 break handle_stop; 32693 } 32694 32695 if (this.clampWhenFinished) this.paused = true;else this.enabled = false; 32696 this.time = time; 32697 32698 this._mixer.dispatchEvent({ 32699 type: 'finished', 32700 action: this, 32701 direction: deltaTime < 0 ? -1 : 1 32702 }); 32703 } 32704 } else { 32705 // repetitive Repeat or PingPong 32706 if (loopCount === -1) { 32707 // just started 32708 if (deltaTime >= 0) { 32709 loopCount = 0; 32710 32711 this._setEndings(true, this.repetitions === 0, pingPong); 32712 } else { 32713 // when looping in reverse direction, the initial 32714 // transition through zero counts as a repetition, 32715 // so leave loopCount at -1 32716 this._setEndings(this.repetitions === 0, true, pingPong); 32717 } 32718 } 32719 32720 if (time >= duration || time < 0) { 32721 // wrap around 32722 const loopDelta = Math.floor(time / duration); // signed 32723 32724 time -= duration * loopDelta; 32725 loopCount += Math.abs(loopDelta); 32726 const pending = this.repetitions - loopCount; 32727 32728 if (pending <= 0) { 32729 // have to stop (switch state, clamp time, fire event) 32730 if (this.clampWhenFinished) this.paused = true;else this.enabled = false; 32731 time = deltaTime > 0 ? duration : 0; 32732 this.time = time; 32733 32734 this._mixer.dispatchEvent({ 32735 type: 'finished', 32736 action: this, 32737 direction: deltaTime > 0 ? 1 : -1 32738 }); 32739 } else { 32740 // keep running 32741 if (pending === 1) { 32742 // entering the last round 32743 const atStart = deltaTime < 0; 32744 32745 this._setEndings(atStart, !atStart, pingPong); 32746 } else { 32747 this._setEndings(false, false, pingPong); 32748 } 32749 32750 this._loopCount = loopCount; 32751 this.time = time; 32752 32753 this._mixer.dispatchEvent({ 32754 type: 'loop', 32755 action: this, 32756 loopDelta: loopDelta 32757 }); 32758 } 32759 } else { 32760 this.time = time; 32761 } 32762 32763 if (pingPong && (loopCount & 1) === 1) { 32764 // invert time for the "pong round" 32765 return duration - time; 32766 } 32767 } 32768 32769 return time; 32770 } 32771 32772 _setEndings(atStart, atEnd, pingPong) { 32773 const settings = this._interpolantSettings; 32774 32775 if (pingPong) { 32776 settings.endingStart = ZeroSlopeEnding; 32777 settings.endingEnd = ZeroSlopeEnding; 32778 } else { 32779 // assuming for LoopOnce atStart == atEnd == true 32780 if (atStart) { 32781 settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding; 32782 } else { 32783 settings.endingStart = WrapAroundEnding; 32784 } 32785 32786 if (atEnd) { 32787 settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding; 32788 } else { 32789 settings.endingEnd = WrapAroundEnding; 32790 } 32791 } 32792 } 32793 32794 _scheduleFading(duration, weightNow, weightThen) { 32795 const mixer = this._mixer, 32796 now = mixer.time; 32797 let interpolant = this._weightInterpolant; 32798 32799 if (interpolant === null) { 32800 interpolant = mixer._lendControlInterpolant(); 32801 this._weightInterpolant = interpolant; 32802 } 32803 32804 const times = interpolant.parameterPositions, 32805 values = interpolant.sampleValues; 32806 times[0] = now; 32807 values[0] = weightNow; 32808 times[1] = now + duration; 32809 values[1] = weightThen; 32810 return this; 32811 } 32812 32813 } 32814
vendor: 4,399 bytes, lines 32815-32988
32815 class AnimationMixer extends EventDispatcher { 32816 constructor(root) { 32817 super(); 32818 this._root = root; 32819 32820 this._initMemoryManager(); 32821 32822 this._accuIndex = 0; 32823 this.time = 0; 32824 this.timeScale = 1.0; 32825 } 32826 32827 _bindAction(action, prototypeAction) { 32828 const root = action._localRoot || this._root, 32829 tracks = action._clip.tracks, 32830 nTracks = tracks.length, 32831 bindings = action._propertyBindings, 32832 interpolants = action._interpolants, 32833 rootUuid = root.uuid, 32834 bindingsByRoot = this._bindingsByRootAndName; 32835 let bindingsByName = bindingsByRoot[rootUuid]; 32836 32837 if (bindingsByName === undefined) { 32838 bindingsByName = {}; 32839 bindingsByRoot[rootUuid] = bindingsByName; 32840 } 32841 32842 for (let i = 0; i !== nTracks; ++i) { 32843 const track = tracks[i], 32844 trackName = track.name; 32845 let binding = bindingsByName[trackName]; 32846 32847 if (binding !== undefined) { 32848 bindings[i] = binding; 32849 } else { 32850 binding = bindings[i]; 32851 32852 if (binding !== undefined) { 32853 // existing binding, make sure the cache knows 32854 if (binding._cacheIndex === null) { 32855 ++binding.referenceCount; 32856 32857 this._addInactiveBinding(binding, rootUuid, trackName); 32858 } 32859 32860 continue; 32861 } 32862 32863 const path = prototypeAction && prototypeAction._propertyBindings[i].binding.parsedPath; 32864 binding = new PropertyMixer(PropertyBinding.create(root, trackName, path), track.ValueTypeName, track.getValueSize()); 32865 ++binding.referenceCount; 32866 32867 this._addInactiveBinding(binding, rootUuid, trackName); 32868 32869 bindings[i] = binding; 32870 } 32871 32872 interpolants[i].resultBuffer = binding.buffer; 32873 } 32874 } 32875 32876 _activateAction(action) { 32877 if (!this._isActiveAction(action)) { 32878 if (action._cacheIndex === null) { 32879 // this action has been forgotten by the cache, but the user 32880 // appears to be still using it -> rebind 32881 const rootUuid = (action._localRoot || this._root).uuid, 32882 clipUuid = action._clip.uuid, 32883 actionsForClip = this._actionsByClip[clipUuid]; 32884 32885 this._bindAction(action, actionsForClip && actionsForClip.knownActions[0]); 32886 32887 this._addInactiveAction(action, clipUuid, rootUuid); 32888 } 32889 32890 const bindings = action._propertyBindings; // increment reference counts / sort out state 32891 32892 for (let i = 0, n = bindings.length; i !== n; ++i) { 32893 const binding = bindings[i]; 32894 32895 if (binding.useCount++ === 0) { 32896 this._lendBinding(binding); 32897 32898 binding.saveOriginalState(); 32899 } 32900 } 32901 32902 this._lendAction(action); 32903 } 32904 } 32905 32906 _deactivateAction(action) { 32907 if (this._isActiveAction(action)) { 32908 const bindings = action._propertyBindings; // decrement reference counts / sort out state 32909 32910 for (let i = 0, n = bindings.length; i !== n; ++i) { 32911 const binding = bindings[i]; 32912 32913 if (--binding.useCount === 0) { 32914 binding.restoreOriginalState(); 32915 32916 this._takeBackBinding(binding); 32917 } 32918 } 32919 32920 this._takeBackAction(action); 32921 } 32922 } // Memory manager 32923 32924 32925 _initMemoryManager() { 32926 this._actions = []; // 'nActiveActions' followed by inactive ones 32927 32928 this._nActiveActions = 0; 32929 this._actionsByClip = {}; // inside: 32930 // { 32931 // knownActions: Array< AnimationAction > - used as prototypes 32932 // actionByRoot: AnimationAction - lookup 32933 // } 32934 32935 this._bindings = []; // 'nActiveBindings' followed by inactive ones 32936 32937 this._nActiveBindings = 0; 32938 this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer > 32939 32940 this._controlInterpolants = []; // same game as above 32941 32942 this._nActiveControlInterpolants = 0; 32943 const scope = this; 32944 this.stats = { 32945 actions: { 32946 get total() { 32947 return scope._actions.length; 32948 }, 32949 32950 get inUse() { 32951 return scope._nActiveActions; 32952 } 32953 32954 }, 32955 bindings: { 32956 get total() { 32957 return scope._bindings.length; 32958 }, 32959 32960 get inUse() { 32961 return scope._nActiveBindings; 32962 } 32963 32964 }, 32965 controlInterpolants: { 32966 get total() { 32967 return scope._controlInterpolants.length; 32968 }, 32969 32970 get inUse() { 32971 return scope._nActiveControlInterpolants; 32972 } 32973 32974 } 32975 }; 32976 } // Memory management for AnimationAction objects 32977 32978 32979 _isActiveAction(action) { 32980 const index = action._cacheIndex; 32981 return index !== null && index < this._nActiveActions; 32982 } 32983 32984 _addInactiveAction(action, clipUuid, rootUuid) { 32985 const actions = this._actions, 32986 actionsByClip = this._actionsByClip; 32987 let actionsForClip = actionsByClip[clipUuid]; 32988
vendor: 6,548 bytes, lines 32989-33181
32989 if (actionsForClip === undefined) { 32990 actionsForClip = { 32991 knownActions: [action], 32992 actionByRoot: {} 32993 }; 32994 action._byClipCacheIndex = 0; 32995 actionsByClip[clipUuid] = actionsForClip; 32996 } else { 32997 const knownActions = actionsForClip.knownActions; 32998 action._byClipCacheIndex = knownActions.length; 32999 knownActions.push(action); 33000 } 33001 33002 action._cacheIndex = actions.length; 33003 actions.push(action); 33004 actionsForClip.actionByRoot[rootUuid] = action; 33005 } 33006 33007 _removeInactiveAction(action) { 33008 const actions = this._actions, 33009 lastInactiveAction = actions[actions.length - 1], 33010 cacheIndex = action._cacheIndex; 33011 lastInactiveAction._cacheIndex = cacheIndex; 33012 actions[cacheIndex] = lastInactiveAction; 33013 actions.pop(); 33014 action._cacheIndex = null; 33015 const clipUuid = action._clip.uuid, 33016 actionsByClip = this._actionsByClip, 33017 actionsForClip = actionsByClip[clipUuid], 33018 knownActionsForClip = actionsForClip.knownActions, 33019 lastKnownAction = knownActionsForClip[knownActionsForClip.length - 1], 33020 byClipCacheIndex = action._byClipCacheIndex; 33021 lastKnownAction._byClipCacheIndex = byClipCacheIndex; 33022 knownActionsForClip[byClipCacheIndex] = lastKnownAction; 33023 knownActionsForClip.pop(); 33024 action._byClipCacheIndex = null; 33025 const actionByRoot = actionsForClip.actionByRoot, 33026 rootUuid = (action._localRoot || this._root).uuid; 33027 delete actionByRoot[rootUuid]; 33028 33029 if (knownActionsForClip.length === 0) { 33030 delete actionsByClip[clipUuid]; 33031 } 33032 33033 this._removeInactiveBindingsForAction(action); 33034 } 33035 33036 _removeInactiveBindingsForAction(action) { 33037 const bindings = action._propertyBindings; 33038 33039 for (let i = 0, n = bindings.length; i !== n; ++i) { 33040 const binding = bindings[i]; 33041 33042 if (--binding.referenceCount === 0) { 33043 this._removeInactiveBinding(binding); 33044 } 33045 } 33046 } 33047 33048 _lendAction(action) { 33049 // [ active actions | inactive actions ] 33050 // [ active actions >| inactive actions ] 33051 // s a 33052 // <-swap-> 33053 // a s 33054 const actions = this._actions, 33055 prevIndex = action._cacheIndex, 33056 lastActiveIndex = this._nActiveActions++, 33057 firstInactiveAction = actions[lastActiveIndex]; 33058 action._cacheIndex = lastActiveIndex; 33059 actions[lastActiveIndex] = action; 33060 firstInactiveAction._cacheIndex = prevIndex; 33061 actions[prevIndex] = firstInactiveAction; 33062 } 33063 33064 _takeBackAction(action) { 33065 // [ active actions | inactive actions ] 33066 // [ active actions |< inactive actions ] 33067 // a s 33068 // <-swap-> 33069 // s a 33070 const actions = this._actions, 33071 prevIndex = action._cacheIndex, 33072 firstInactiveIndex = --this._nActiveActions, 33073 lastActiveAction = actions[firstInactiveIndex]; 33074 action._cacheIndex = firstInactiveIndex; 33075 actions[firstInactiveIndex] = action; 33076 lastActiveAction._cacheIndex = prevIndex; 33077 actions[prevIndex] = lastActiveAction; 33078 } // Memory management for PropertyMixer objects 33079 33080 33081 _addInactiveBinding(binding, rootUuid, trackName) { 33082 const bindingsByRoot = this._bindingsByRootAndName, 33083 bindings = this._bindings; 33084 let bindingByName = bindingsByRoot[rootUuid]; 33085 33086 if (bindingByName === undefined) { 33087 bindingByName = {}; 33088 bindingsByRoot[rootUuid] = bindingByName; 33089 } 33090 33091 bindingByName[trackName] = binding; 33092 binding._cacheIndex = bindings.length; 33093 bindings.push(binding); 33094 } 33095 33096 _removeInactiveBinding(binding) { 33097 const bindings = this._bindings, 33098 propBinding = binding.binding, 33099 rootUuid = propBinding.rootNode.uuid, 33100 trackName = propBinding.path, 33101 bindingsByRoot = this._bindingsByRootAndName, 33102 bindingByName = bindingsByRoot[rootUuid], 33103 lastInactiveBinding = bindings[bindings.length - 1], 33104 cacheIndex = binding._cacheIndex; 33105 lastInactiveBinding._cacheIndex = cacheIndex; 33106 bindings[cacheIndex] = lastInactiveBinding; 33107 bindings.pop(); 33108 delete bindingByName[trackName]; 33109 33110 if (Object.keys(bindingByName).length === 0) { 33111 delete bindingsByRoot[rootUuid]; 33112 } 33113 } 33114 33115 _lendBinding(binding) { 33116 const bindings = this._bindings, 33117 prevIndex = binding._cacheIndex, 33118 lastActiveIndex = this._nActiveBindings++, 33119 firstInactiveBinding = bindings[lastActiveIndex]; 33120 binding._cacheIndex = lastActiveIndex; 33121 bindings[lastActiveIndex] = binding; 33122 firstInactiveBinding._cacheIndex = prevIndex; 33123 bindings[prevIndex] = firstInactiveBinding; 33124 } 33125 33126 _takeBackBinding(binding) { 33127 const bindings = this._bindings, 33128 prevIndex = binding._cacheIndex, 33129 firstInactiveIndex = --this._nActiveBindings, 33130 lastActiveBinding = bindings[firstInactiveIndex]; 33131 binding._cacheIndex = firstInactiveIndex; 33132 bindings[firstInactiveIndex] = binding; 33133 lastActiveBinding._cacheIndex = prevIndex; 33134 bindings[prevIndex] = lastActiveBinding; 33135 } // Memory management of Interpolants for weight and time scale 33136 33137 33138 _lendControlInterpolant() { 33139 const interpolants = this._controlInterpolants, 33140 lastActiveIndex = this._nActiveControlInterpolants++; 33141 let interpolant = interpolants[lastActiveIndex]; 33142 33143 if (interpolant === undefined) { 33144 interpolant = new LinearInterpolant(new Float32Array(2), new Float32Array(2), 1, this._controlInterpolantsResultBuffer); 33145 interpolant.__cacheIndex = lastActiveIndex; 33146 interpolants[lastActiveIndex] = interpolant; 33147 } 33148 33149 return interpolant; 33150 } 33151 33152 _takeBackControlInterpolant(interpolant) { 33153 const interpolants = this._controlInterpolants, 33154 prevIndex = interpolant.__cacheIndex, 33155 firstInactiveIndex = --this._nActiveControlInterpolants, 33156 lastActiveInterpolant = interpolants[firstInactiveIndex]; 33157 interpolant.__cacheIndex = firstInactiveIndex; 33158 interpolants[firstInactiveIndex] = interpolant; 33159 lastActiveInterpolant.__cacheIndex = prevIndex; 33160 interpolants[prevIndex] = lastActiveInterpolant; 33161 } // return an action for a clip optionally using a custom root target 33162 // object (this method allocates a lot of dynamic memory in case a 33163 // previously unknown clip/root combination is specified) 33164 33165 33166 clipAction(clip, optionalRoot, blendMode) { 33167 const root = optionalRoot || this._root, 33168 rootUuid = root.uuid; 33169 let clipObject = typeof clip === 'string' ? AnimationClip.findByName(root, clip) : clip; 33170 const clipUuid = clipObject !== null ? clipObject.uuid : clip; 33171 const actionsForClip = this._actionsByClip[clipUuid]; 33172 let prototypeAction = null; 33173 33174 if (blendMode === undefined) { 33175 if (clipObject !== null) { 33176 blendMode = clipObject.blendMode; 33177 } else { 33178 blendMode = NormalAnimationBlendMode; 33179 } 33180 } 33181
vendor: 4,717 bytes, lines 33182-33343
33182 if (actionsForClip !== undefined) { 33183 const existingAction = actionsForClip.actionByRoot[rootUuid]; 33184 33185 if (existingAction !== undefined && existingAction.blendMode === blendMode) { 33186 return existingAction; 33187 } // we know the clip, so we don't have to parse all 33188 // the bindings again but can just copy 33189 33190 33191 prototypeAction = actionsForClip.knownActions[0]; // also, take the clip from the prototype action 33192 33193 if (clipObject === null) clipObject = prototypeAction._clip; 33194 } // clip must be known when specified via string 33195 33196 33197 if (clipObject === null) return null; // allocate all resources required to run it 33198 33199 const newAction = new AnimationAction(this, clipObject, optionalRoot, blendMode); 33200 33201 this._bindAction(newAction, prototypeAction); // and make the action known to the memory manager 33202 33203 33204 this._addInactiveAction(newAction, clipUuid, rootUuid); 33205 33206 return newAction; 33207 } // get an existing action 33208 33209 33210 existingAction(clip, optionalRoot) { 33211 const root = optionalRoot || this._root, 33212 rootUuid = root.uuid, 33213 clipObject = typeof clip === 'string' ? AnimationClip.findByName(root, clip) : clip, 33214 clipUuid = clipObject ? clipObject.uuid : clip, 33215 actionsForClip = this._actionsByClip[clipUuid]; 33216 33217 if (actionsForClip !== undefined) { 33218 return actionsForClip.actionByRoot[rootUuid] || null; 33219 } 33220 33221 return null; 33222 } // deactivates all previously scheduled actions 33223 33224 33225 stopAllAction() { 33226 const actions = this._actions, 33227 nActions = this._nActiveActions; 33228 33229 for (let i = nActions - 1; i >= 0; --i) { 33230 actions[i].stop(); 33231 } 33232 33233 return this; 33234 } // advance the time and update apply the animation 33235 33236 33237 update(deltaTime) { 33238 deltaTime *= this.timeScale; 33239 const actions = this._actions, 33240 nActions = this._nActiveActions, 33241 time = this.time += deltaTime, 33242 timeDirection = Math.sign(deltaTime), 33243 accuIndex = this._accuIndex ^= 1; // run active actions 33244 33245 for (let i = 0; i !== nActions; ++i) { 33246 const action = actions[i]; 33247 33248 action._update(time, deltaTime, timeDirection, accuIndex); 33249 } // update scene graph 33250 33251 33252 const bindings = this._bindings, 33253 nBindings = this._nActiveBindings; 33254 33255 for (let i = 0; i !== nBindings; ++i) { 33256 bindings[i].apply(accuIndex); 33257 } 33258 33259 return this; 33260 } // Allows you to seek to a specific time in an animation. 33261 33262 33263 setTime(timeInSeconds) { 33264 this.time = 0; // Zero out time attribute for AnimationMixer object; 33265 33266 for (let i = 0; i < this._actions.length; i++) { 33267 this._actions[i].time = 0; // Zero out time attribute for all associated AnimationAction objects. 33268 } 33269 33270 return this.update(timeInSeconds); // Update used to set exact time. Returns "this" AnimationMixer object. 33271 } // return this mixer's root target object 33272 33273 33274 getRoot() { 33275 return this._root; 33276 } // free all resources specific to a particular clip 33277 33278 33279 uncacheClip(clip) { 33280 const actions = this._actions, 33281 clipUuid = clip.uuid, 33282 actionsByClip = this._actionsByClip, 33283 actionsForClip = actionsByClip[clipUuid]; 33284 33285 if (actionsForClip !== undefined) { 33286 // note: just calling _removeInactiveAction would mess up the 33287 // iteration state and also require updating the state we can 33288 // just throw away 33289 const actionsToRemove = actionsForClip.knownActions; 33290 33291 for (let i = 0, n = actionsToRemove.length; i !== n; ++i) { 33292 const action = actionsToRemove[i]; 33293 33294 this._deactivateAction(action); 33295 33296 const cacheIndex = action._cacheIndex, 33297 lastInactiveAction = actions[actions.length - 1]; 33298 action._cacheIndex = null; 33299 action._byClipCacheIndex = null; 33300 lastInactiveAction._cacheIndex = cacheIndex; 33301 actions[cacheIndex] = lastInactiveAction; 33302 actions.pop(); 33303 33304 this._removeInactiveBindingsForAction(action); 33305 } 33306 33307 delete actionsByClip[clipUuid]; 33308 } 33309 } // free all resources specific to a particular root target object 33310 33311 33312 uncacheRoot(root) { 33313 const rootUuid = root.uuid, 33314 actionsByClip = this._actionsByClip; 33315 33316 for (const clipUuid in actionsByClip) { 33317 const actionByRoot = actionsByClip[clipUuid].actionByRoot, 33318 action = actionByRoot[rootUuid]; 33319 33320 if (action !== undefined) { 33321 this._deactivateAction(action); 33322 33323 this._removeInactiveAction(action); 33324 } 33325 } 33326 33327 const bindingsByRoot = this._bindingsByRootAndName, 33328 bindingByName = bindingsByRoot[rootUuid]; 33329 33330 if (bindingByName !== undefined) { 33331 for (const trackName in bindingByName) { 33332 const binding = bindingByName[trackName]; 33333 binding.restoreOriginalState(); 33334 33335 this._removeInactiveBinding(binding); 33336 } 33337 } 33338 } // remove a targeted clip from the cache 33339 33340 33341 uncacheAction(clip, optionalRoot) { 33342 const action = this.existingAction(clip, optionalRoot); 33343
vendor: 4,315 bytes, lines 33344-33523
33344 if (action !== null) { 33345 this._deactivateAction(action); 33346 33347 this._removeInactiveAction(action); 33348 } 33349 } 33350 33351 } 33352 33353 AnimationMixer.prototype._controlInterpolantsResultBuffer = new Float32Array(1); 33354 33355 class Uniform { 33356 constructor(value) { 33357 if (typeof value === 'string') { 33358 console.warn('THREE.Uniform: Type parameter is no longer needed.'); 33359 value = arguments[1]; 33360 } 33361 33362 this.value = value; 33363 } 33364 33365 clone() { 33366 return new Uniform(this.value.clone === undefined ? this.value : this.value.clone()); 33367 } 33368 33369 } 33370 33371 class InstancedInterleavedBuffer extends InterleavedBuffer { 33372 constructor(array, stride, meshPerAttribute = 1) { 33373 super(array, stride); 33374 this.meshPerAttribute = meshPerAttribute; 33375 } 33376 33377 copy(source) { 33378 super.copy(source); 33379 this.meshPerAttribute = source.meshPerAttribute; 33380 return this; 33381 } 33382 33383 clone(data) { 33384 const ib = super.clone(data); 33385 ib.meshPerAttribute = this.meshPerAttribute; 33386 return ib; 33387 } 33388 33389 toJSON(data) { 33390 const json = super.toJSON(data); 33391 json.isInstancedInterleavedBuffer = true; 33392 json.meshPerAttribute = this.meshPerAttribute; 33393 return json; 33394 } 33395 33396 } 33397 33398 InstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true; 33399 33400 class GLBufferAttribute { 33401 constructor(buffer, type, itemSize, elementSize, count) { 33402 this.buffer = buffer; 33403 this.type = type; 33404 this.itemSize = itemSize; 33405 this.elementSize = elementSize; 33406 this.count = count; 33407 this.version = 0; 33408 } 33409 33410 set needsUpdate(value) { 33411 if (value === true) this.version++; 33412 } 33413 33414 setBuffer(buffer) { 33415 this.buffer = buffer; 33416 return this; 33417 } 33418 33419 setType(type, elementSize) { 33420 this.type = type; 33421 this.elementSize = elementSize; 33422 return this; 33423 } 33424 33425 setItemSize(itemSize) { 33426 this.itemSize = itemSize; 33427 return this; 33428 } 33429 33430 setCount(count) { 33431 this.count = count; 33432 return this; 33433 } 33434 33435 } 33436 33437 GLBufferAttribute.prototype.isGLBufferAttribute = true; 33438 33439 class Raycaster { 33440 constructor(origin, direction, near = 0, far = Infinity) { 33441 this.ray = new Ray(origin, direction); // direction is assumed to be normalized (for accurate distance calculations) 33442 33443 this.near = near; 33444 this.far = far; 33445 this.camera = null; 33446 this.layers = new Layers(); 33447 this.params = { 33448 Mesh: {}, 33449 Line: { 33450 threshold: 1 33451 }, 33452 LOD: {}, 33453 Points: { 33454 threshold: 1 33455 }, 33456 Sprite: {} 33457 }; 33458 } 33459 33460 set(origin, direction) { 33461 // direction is assumed to be normalized (for accurate distance calculations) 33462 this.ray.set(origin, direction); 33463 } 33464 33465 setFromCamera(coords, camera) { 33466 if (camera && camera.isPerspectiveCamera) { 33467 this.ray.origin.setFromMatrixPosition(camera.matrixWorld); 33468 this.ray.direction.set(coords.x, coords.y, 0.5).unproject(camera).sub(this.ray.origin).normalize(); 33469 this.camera = camera; 33470 } else if (camera && camera.isOrthographicCamera) { 33471 this.ray.origin.set(coords.x, coords.y, (camera.near + camera.far) / (camera.near - camera.far)).unproject(camera); // set origin in plane of camera 33472 33473 this.ray.direction.set(0, 0, -1).transformDirection(camera.matrixWorld); 33474 this.camera = camera; 33475 } else { 33476 console.error('THREE.Raycaster: Unsupported camera type: ' + camera.type); 33477 } 33478 } 33479 33480 intersectObject(object, recursive = true, intersects = []) { 33481 intersectObject(object, this, intersects, recursive); 33482 intersects.sort(ascSort); 33483 return intersects; 33484 } 33485 33486 intersectObjects(objects, recursive = true, intersects = []) { 33487 for (let i = 0, l = objects.length; i < l; i++) { 33488 intersectObject(objects[i], this, intersects, recursive); 33489 } 33490 33491 intersects.sort(ascSort); 33492 return intersects; 33493 } 33494 33495 } 33496 33497 function ascSort(a, b) { 33498 return a.distance - b.distance; 33499 } 33500 33501 function intersectObject(object, raycaster, intersects, recursive) { 33502 if (object.layers.test(raycaster.layers)) { 33503 object.raycast(raycaster, intersects); 33504 } 33505 33506 if (recursive === true) { 33507 const children = object.children; 33508 33509 for (let i = 0, l = children.length; i < l; i++) { 33510 intersectObject(children[i], raycaster, intersects, true); 33511 } 33512 } 33513 } 33514 33515 /** 33516 * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system 33517 * 33518 * The polar angle (phi) is measured from the positive y-axis. The positive y-axis is up. 33519 * The azimuthal angle (theta) is measured from the positive z-axis. 33520 */ 33521 33522 class Spherical { 33523 constructor(radius = 1, phi = 0, theta = 0) {
vendor: 5,067 bytes, lines 33524-33760
33524 this.radius = radius; 33525 this.phi = phi; // polar angle 33526 33527 this.theta = theta; // azimuthal angle 33528 33529 return this; 33530 } 33531 33532 set(radius, phi, theta) { 33533 this.radius = radius; 33534 this.phi = phi; 33535 this.theta = theta; 33536 return this; 33537 } 33538 33539 copy(other) { 33540 this.radius = other.radius; 33541 this.phi = other.phi; 33542 this.theta = other.theta; 33543 return this; 33544 } // restrict phi to be betwee EPS and PI-EPS 33545 33546 33547 makeSafe() { 33548 const EPS = 0.000001; 33549 this.phi = Math.max(EPS, Math.min(Math.PI - EPS, this.phi)); 33550 return this; 33551 } 33552 33553 setFromVector3(v) { 33554 return this.setFromCartesianCoords(v.x, v.y, v.z); 33555 } 33556 33557 setFromCartesianCoords(x, y, z) { 33558 this.radius = Math.sqrt(x * x + y * y + z * z); 33559 33560 if (this.radius === 0) { 33561 this.theta = 0; 33562 this.phi = 0; 33563 } else { 33564 this.theta = Math.atan2(x, z); 33565 this.phi = Math.acos(clamp(y / this.radius, -1, 1)); 33566 } 33567 33568 return this; 33569 } 33570 33571 clone() { 33572 return new this.constructor().copy(this); 33573 } 33574 33575 } 33576 33577 /** 33578 * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system 33579 */ 33580 class Cylindrical { 33581 constructor(radius = 1, theta = 0, y = 0) { 33582 this.radius = radius; // distance from the origin to a point in the x-z plane 33583 33584 this.theta = theta; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis 33585 33586 this.y = y; // height above the x-z plane 33587 33588 return this; 33589 } 33590 33591 set(radius, theta, y) { 33592 this.radius = radius; 33593 this.theta = theta; 33594 this.y = y; 33595 return this; 33596 } 33597 33598 copy(other) { 33599 this.radius = other.radius; 33600 this.theta = other.theta; 33601 this.y = other.y; 33602 return this; 33603 } 33604 33605 setFromVector3(v) { 33606 return this.setFromCartesianCoords(v.x, v.y, v.z); 33607 } 33608 33609 setFromCartesianCoords(x, y, z) { 33610 this.radius = Math.sqrt(x * x + z * z); 33611 this.theta = Math.atan2(x, z); 33612 this.y = y; 33613 return this; 33614 } 33615 33616 clone() { 33617 return new this.constructor().copy(this); 33618 } 33619 33620 } 33621 33622 const _vector$4 = /*@__PURE__*/new Vector2(); 33623 33624 class Box2 { 33625 constructor(min = new Vector2(+Infinity, +Infinity), max = new Vector2(-Infinity, -Infinity)) { 33626 this.min = min; 33627 this.max = max; 33628 } 33629 33630 set(min, max) { 33631 this.min.copy(min); 33632 this.max.copy(max); 33633 return this; 33634 } 33635 33636 setFromPoints(points) { 33637 this.makeEmpty(); 33638 33639 for (let i = 0, il = points.length; i < il; i++) { 33640 this.expandByPoint(points[i]); 33641 } 33642 33643 return this; 33644 } 33645 33646 setFromCenterAndSize(center, size) { 33647 const halfSize = _vector$4.copy(size).multiplyScalar(0.5); 33648 33649 this.min.copy(center).sub(halfSize); 33650 this.max.copy(center).add(halfSize); 33651 return this; 33652 } 33653 33654 clone() { 33655 return new this.constructor().copy(this); 33656 } 33657 33658 copy(box) { 33659 this.min.copy(box.min); 33660 this.max.copy(box.max); 33661 return this; 33662 } 33663 33664 makeEmpty() { 33665 this.min.x = this.min.y = +Infinity; 33666 this.max.x = this.max.y = -Infinity; 33667 return this; 33668 } 33669 33670 isEmpty() { 33671 // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes 33672 return this.max.x < this.min.x || this.max.y < this.min.y; 33673 } 33674 33675 getCenter(target) { 33676 return this.isEmpty() ? target.set(0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5); 33677 } 33678 33679 getSize(target) { 33680 return this.isEmpty() ? target.set(0, 0) : target.subVectors(this.max, this.min); 33681 } 33682 33683 expandByPoint(point) { 33684 this.min.min(point); 33685 this.max.max(point); 33686 return this; 33687 } 33688 33689 expandByVector(vector) { 33690 this.min.sub(vector); 33691 this.max.add(vector); 33692 return this; 33693 } 33694 33695 expandByScalar(scalar) { 33696 this.min.addScalar(-scalar); 33697 this.max.addScalar(scalar); 33698 return this; 33699 } 33700 33701 containsPoint(point) { 33702 return point.x < this.min.x || point.x > this.max.x || point.y < this.min.y || point.y > this.max.y ? false : true; 33703 } 33704 33705 containsBox(box) { 33706 return this.min.x <= box.min.x && box.max.x <= this.max.x && this.min.y <= box.min.y && box.max.y <= this.max.y; 33707 } 33708 33709 getParameter(point, target) { 33710 // This can potentially have a divide by zero if the box 33711 // has a size dimension of 0. 33712 return target.set((point.x - this.min.x) / (this.max.x - this.min.x), (point.y - this.min.y) / (this.max.y - this.min.y)); 33713 } 33714 33715 intersectsBox(box) { 33716 // using 4 splitting planes to rule out intersections 33717 return box.max.x < this.min.x || box.min.x > this.max.x || box.max.y < this.min.y || box.min.y > this.max.y ? false : true; 33718 } 33719 33720 clampPoint(point, target) { 33721 return target.copy(point).clamp(this.min, this.max); 33722 } 33723 33724 distanceToPoint(point) { 33725 const clampedPoint = _vector$4.copy(point).clamp(this.min, this.max); 33726 33727 return clampedPoint.sub(point).length(); 33728 } 33729 33730 intersect(box) { 33731 this.min.max(box.min); 33732 this.max.min(box.max); 33733 return this; 33734 } 33735 33736 union(box) { 33737 this.min.min(box.min); 33738 this.max.max(box.max); 33739 return this; 33740 } 33741 33742 translate(offset) { 33743 this.min.add(offset); 33744 this.max.add(offset); 33745 return this; 33746 } 33747 33748 equals(box) { 33749 return box.min.equals(this.min) && box.max.equals(this.max); 33750 } 33751 33752 } 33753 33754 Box2.prototype.isBox2 = true; 33755 33756 const _startP = /*@__PURE__*/new Vector3(); 33757 33758 const _startEnd = /*@__PURE__*/new Vector3(); 33759 33760 class Line3 {
vendor: 15,418 bytes, lines 33761-34329
33761 constructor(start = new Vector3(), end = new Vector3()) { 33762 this.start = start; 33763 this.end = end; 33764 } 33765 33766 set(start, end) { 33767 this.start.copy(start); 33768 this.end.copy(end); 33769 return this; 33770 } 33771 33772 copy(line) { 33773 this.start.copy(line.start); 33774 this.end.copy(line.end); 33775 return this; 33776 } 33777 33778 getCenter(target) { 33779 return target.addVectors(this.start, this.end).multiplyScalar(0.5); 33780 } 33781 33782 delta(target) { 33783 return target.subVectors(this.end, this.start); 33784 } 33785 33786 distanceSq() { 33787 return this.start.distanceToSquared(this.end); 33788 } 33789 33790 distance() { 33791 return this.start.distanceTo(this.end); 33792 } 33793 33794 at(t, target) { 33795 return this.delta(target).multiplyScalar(t).add(this.start); 33796 } 33797 33798 closestPointToPointParameter(point, clampToLine) { 33799 _startP.subVectors(point, this.start); 33800 33801 _startEnd.subVectors(this.end, this.start); 33802 33803 const startEnd2 = _startEnd.dot(_startEnd); 33804 33805 const startEnd_startP = _startEnd.dot(_startP); 33806 33807 let t = startEnd_startP / startEnd2; 33808 33809 if (clampToLine) { 33810 t = clamp(t, 0, 1); 33811 } 33812 33813 return t; 33814 } 33815 33816 closestPointToPoint(point, clampToLine, target) { 33817 const t = this.closestPointToPointParameter(point, clampToLine); 33818 return this.delta(target).multiplyScalar(t).add(this.start); 33819 } 33820 33821 applyMatrix4(matrix) { 33822 this.start.applyMatrix4(matrix); 33823 this.end.applyMatrix4(matrix); 33824 return this; 33825 } 33826 33827 equals(line) { 33828 return line.start.equals(this.start) && line.end.equals(this.end); 33829 } 33830 33831 clone() { 33832 return new this.constructor().copy(this); 33833 } 33834 33835 } 33836 33837 const _vector$3 = /*@__PURE__*/new Vector3(); 33838 33839 class SpotLightHelper extends Object3D { 33840 constructor(light, color) { 33841 super(); 33842 this.light = light; 33843 this.light.updateMatrixWorld(); 33844 this.matrix = light.matrixWorld; 33845 this.matrixAutoUpdate = false; 33846 this.color = color; 33847 const geometry = new BufferGeometry(); 33848 const positions = [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, -1, 1]; 33849 33850 for (let i = 0, j = 1, l = 32; i < l; i++, j++) { 33851 const p1 = i / l * Math.PI * 2; 33852 const p2 = j / l * Math.PI * 2; 33853 positions.push(Math.cos(p1), Math.sin(p1), 1, Math.cos(p2), Math.sin(p2), 1); 33854 } 33855 33856 geometry.setAttribute('position', new Float32BufferAttribute(positions, 3)); 33857 const material = new LineBasicMaterial({ 33858 fog: false, 33859 toneMapped: false 33860 }); 33861 this.cone = new LineSegments(geometry, material); 33862 this.add(this.cone); 33863 this.update(); 33864 } 33865 33866 dispose() { 33867 this.cone.geometry.dispose(); 33868 this.cone.material.dispose(); 33869 } 33870 33871 update() { 33872 this.light.updateMatrixWorld(); 33873 const coneLength = this.light.distance ? this.light.distance : 1000; 33874 const coneWidth = coneLength * Math.tan(this.light.angle); 33875 this.cone.scale.set(coneWidth, coneWidth, coneLength); 33876 33877 _vector$3.setFromMatrixPosition(this.light.target.matrixWorld); 33878 33879 this.cone.lookAt(_vector$3); 33880 33881 if (this.color !== undefined) { 33882 this.cone.material.color.set(this.color); 33883 } else { 33884 this.cone.material.color.copy(this.light.color); 33885 } 33886 } 33887 33888 } 33889 33890 const _vector$2 = /*@__PURE__*/new Vector3(); 33891 33892 const _boneMatrix = /*@__PURE__*/new Matrix4(); 33893 33894 const _matrixWorldInv = /*@__PURE__*/new Matrix4(); 33895 33896 class SkeletonHelper extends LineSegments { 33897 constructor(object) { 33898 const bones = getBoneList(object); 33899 const geometry = new BufferGeometry(); 33900 const vertices = []; 33901 const colors = []; 33902 const color1 = new Color(0, 0, 1); 33903 const color2 = new Color(0, 1, 0); 33904 33905 for (let i = 0; i < bones.length; i++) { 33906 const bone = bones[i]; 33907 33908 if (bone.parent && bone.parent.isBone) { 33909 vertices.push(0, 0, 0); 33910 vertices.push(0, 0, 0); 33911 colors.push(color1.r, color1.g, color1.b); 33912 colors.push(color2.r, color2.g, color2.b); 33913 } 33914 } 33915 33916 geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 33917 geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); 33918 const material = new LineBasicMaterial({ 33919 vertexColors: true, 33920 depthTest: false, 33921 depthWrite: false, 33922 toneMapped: false, 33923 transparent: true 33924 }); 33925 super(geometry, material); 33926 this.type = 'SkeletonHelper'; 33927 this.isSkeletonHelper = true; 33928 this.root = object; 33929 this.bones = bones; 33930 this.matrix = object.matrixWorld; 33931 this.matrixAutoUpdate = false; 33932 } 33933 33934 updateMatrixWorld(force) { 33935 const bones = this.bones; 33936 const geometry = this.geometry; 33937 const position = geometry.getAttribute('position'); 33938 33939 _matrixWorldInv.copy(this.root.matrixWorld).invert(); 33940 33941 for (let i = 0, j = 0; i < bones.length; i++) { 33942 const bone = bones[i]; 33943 33944 if (bone.parent && bone.parent.isBone) { 33945 _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.matrixWorld); 33946 33947 _vector$2.setFromMatrixPosition(_boneMatrix); 33948 33949 position.setXYZ(j, _vector$2.x, _vector$2.y, _vector$2.z); 33950 33951 _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.parent.matrixWorld); 33952 33953 _vector$2.setFromMatrixPosition(_boneMatrix); 33954 33955 position.setXYZ(j + 1, _vector$2.x, _vector$2.y, _vector$2.z); 33956 j += 2; 33957 } 33958 } 33959 33960 geometry.getAttribute('position').needsUpdate = true; 33961 super.updateMatrixWorld(force); 33962 } 33963 33964 } 33965 33966 function getBoneList(object) { 33967 const boneList = []; 33968 33969 if (object && object.isBone) { 33970 boneList.push(object); 33971 } 33972 33973 for (let i = 0; i < object.children.length; i++) { 33974 boneList.push.apply(boneList, getBoneList(object.children[i])); 33975 } 33976 33977 return boneList; 33978 } 33979 33980 class PointLightHelper extends Mesh { 33981 constructor(light, sphereSize, color) { 33982 const geometry = new SphereGeometry(sphereSize, 4, 2); 33983 const material = new MeshBasicMaterial({ 33984 wireframe: true, 33985 fog: false, 33986 toneMapped: false 33987 }); 33988 super(geometry, material); 33989 this.light = light; 33990 this.light.updateMatrixWorld(); 33991 this.color = color; 33992 this.type = 'PointLightHelper'; 33993 this.matrix = this.light.matrixWorld; 33994 this.matrixAutoUpdate = false; 33995 this.update(); 33996 /* 33997 // TODO: delete this comment? 33998 const distanceGeometry = new THREE.IcosahedronBufferGeometry( 1, 2 ); 33999 const distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } ); 34000 this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial ); 34001 this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial ); 34002 const d = light.distance; 34003 if ( d === 0.0 ) { 34004 this.lightDistance.visible = false; 34005 } else { 34006 this.lightDistance.scale.set( d, d, d ); 34007 } 34008 this.add( this.lightDistance ); 34009 */ 34010 } 34011 34012 dispose() { 34013 this.geometry.dispose(); 34014 this.material.dispose(); 34015 } 34016 34017 update() { 34018 if (this.color !== undefined) { 34019 this.material.color.set(this.color); 34020 } else { 34021 this.material.color.copy(this.light.color); 34022 } 34023 /* 34024 const d = this.light.distance; 34025 if ( d === 0.0 ) { 34026 this.lightDistance.visible = false; 34027 } else { 34028 this.lightDistance.visible = true; 34029 this.lightDistance.scale.set( d, d, d ); 34030 } 34031 */ 34032 34033 } 34034 34035 } 34036 34037 const _vector$1 = /*@__PURE__*/new Vector3(); 34038 34039 const _color1 = /*@__PURE__*/new Color(); 34040 34041 const _color2 = /*@__PURE__*/new Color(); 34042 34043 class HemisphereLightHelper extends Object3D { 34044 constructor(light, size, color) { 34045 super(); 34046 this.light = light; 34047 this.light.updateMatrixWorld(); 34048 this.matrix = light.matrixWorld; 34049 this.matrixAutoUpdate = false; 34050 this.color = color; 34051 const geometry = new OctahedronGeometry(size); 34052 geometry.rotateY(Math.PI * 0.5); 34053 this.material = new MeshBasicMaterial({ 34054 wireframe: true, 34055 fog: false, 34056 toneMapped: false 34057 }); 34058 if (this.color === undefined) this.material.vertexColors = true; 34059 const position = geometry.getAttribute('position'); 34060 const colors = new Float32Array(position.count * 3); 34061 geometry.setAttribute('color', new BufferAttribute(colors, 3)); 34062 this.add(new Mesh(geometry, this.material)); 34063 this.update(); 34064 } 34065 34066 dispose() { 34067 this.children[0].geometry.dispose(); 34068 this.children[0].material.dispose(); 34069 } 34070 34071 update() { 34072 const mesh = this.children[0]; 34073 34074 if (this.color !== undefined) { 34075 this.material.color.set(this.color); 34076 } else { 34077 const colors = mesh.geometry.getAttribute('color'); 34078 34079 _color1.copy(this.light.color); 34080 34081 _color2.copy(this.light.groundColor); 34082 34083 for (let i = 0, l = colors.count; i < l; i++) { 34084 const color = i < l / 2 ? _color1 : _color2; 34085 colors.setXYZ(i, color.r, color.g, color.b); 34086 } 34087 34088 colors.needsUpdate = true; 34089 } 34090 34091 mesh.lookAt(_vector$1.setFromMatrixPosition(this.light.matrixWorld).negate()); 34092 } 34093 34094 } 34095 34096 class GridHelper extends LineSegments { 34097 constructor(size = 10, divisions = 10, color1 = 0x444444, color2 = 0x888888) { 34098 color1 = new Color(color1); 34099 color2 = new Color(color2); 34100 const center = divisions / 2; 34101 const step = size / divisions; 34102 const halfSize = size / 2; 34103 const vertices = [], 34104 colors = []; 34105 34106 for (let i = 0, j = 0, k = -halfSize; i <= divisions; i++, k += step) { 34107 vertices.push(-halfSize, 0, k, halfSize, 0, k); 34108 vertices.push(k, 0, -halfSize, k, 0, halfSize); 34109 const color = i === center ? color1 : color2; 34110 color.toArray(colors, j); 34111 j += 3; 34112 color.toArray(colors, j); 34113 j += 3; 34114 color.toArray(colors, j); 34115 j += 3; 34116 color.toArray(colors, j); 34117 j += 3; 34118 } 34119 34120 const geometry = new BufferGeometry(); 34121 geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 34122 geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); 34123 const material = new LineBasicMaterial({ 34124 vertexColors: true, 34125 toneMapped: false 34126 }); 34127 super(geometry, material); 34128 this.type = 'GridHelper'; 34129 } 34130 34131 } 34132 34133 class PolarGridHelper extends LineSegments { 34134 constructor(radius = 10, radials = 16, circles = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888) { 34135 color1 = new Color(color1); 34136 color2 = new Color(color2); 34137 const vertices = []; 34138 const colors = []; // create the radials 34139 34140 for (let i = 0; i <= radials; i++) { 34141 const v = i / radials * (Math.PI * 2); 34142 const x = Math.sin(v) * radius; 34143 const z = Math.cos(v) * radius; 34144 vertices.push(0, 0, 0); 34145 vertices.push(x, 0, z); 34146 const color = i & 1 ? color1 : color2; 34147 colors.push(color.r, color.g, color.b); 34148 colors.push(color.r, color.g, color.b); 34149 } // create the circles 34150 34151 34152 for (let i = 0; i <= circles; i++) { 34153 const color = i & 1 ? color1 : color2; 34154 const r = radius - radius / circles * i; 34155 34156 for (let j = 0; j < divisions; j++) { 34157 // first vertex 34158 let v = j / divisions * (Math.PI * 2); 34159 let x = Math.sin(v) * r; 34160 let z = Math.cos(v) * r; 34161 vertices.push(x, 0, z); 34162 colors.push(color.r, color.g, color.b); // second vertex 34163 34164 v = (j + 1) / divisions * (Math.PI * 2); 34165 x = Math.sin(v) * r; 34166 z = Math.cos(v) * r; 34167 vertices.push(x, 0, z); 34168 colors.push(color.r, color.g, color.b); 34169 } 34170 } 34171 34172 const geometry = new BufferGeometry(); 34173 geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 34174 geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); 34175 const material = new LineBasicMaterial({ 34176 vertexColors: true, 34177 toneMapped: false 34178 }); 34179 super(geometry, material); 34180 this.type = 'PolarGridHelper'; 34181 } 34182 34183 } 34184 34185 const _v1 = /*@__PURE__*/new Vector3(); 34186 34187 const _v2 = /*@__PURE__*/new Vector3(); 34188 34189 const _v3 = /*@__PURE__*/new Vector3(); 34190 34191 class DirectionalLightHelper extends Object3D { 34192 constructor(light, size, color) { 34193 super(); 34194 this.light = light; 34195 this.light.updateMatrixWorld(); 34196 this.matrix = light.matrixWorld; 34197 this.matrixAutoUpdate = false; 34198 this.color = color; 34199 if (size === undefined) size = 1; 34200 let geometry = new BufferGeometry(); 34201 geometry.setAttribute('position', new Float32BufferAttribute([-size, size, 0, size, size, 0, size, -size, 0, -size, -size, 0, -size, size, 0], 3)); 34202 const material = new LineBasicMaterial({ 34203 fog: false, 34204 toneMapped: false 34205 }); 34206 this.lightPlane = new Line(geometry, material); 34207 this.add(this.lightPlane); 34208 geometry = new BufferGeometry(); 34209 geometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 0, 0, 1], 3)); 34210 this.targetLine = new Line(geometry, material); 34211 this.add(this.targetLine); 34212 this.update(); 34213 } 34214 34215 dispose() { 34216 this.lightPlane.geometry.dispose(); 34217 this.lightPlane.material.dispose(); 34218 this.targetLine.geometry.dispose(); 34219 this.targetLine.material.dispose(); 34220 } 34221 34222 update() { 34223 _v1.setFromMatrixPosition(this.light.matrixWorld); 34224 34225 _v2.setFromMatrixPosition(this.light.target.matrixWorld); 34226 34227 _v3.subVectors(_v2, _v1); 34228 34229 this.lightPlane.lookAt(_v2); 34230 34231 if (this.color !== undefined) { 34232 this.lightPlane.material.color.set(this.color); 34233 this.targetLine.material.color.set(this.color); 34234 } else { 34235 this.lightPlane.material.color.copy(this.light.color); 34236 this.targetLine.material.color.copy(this.light.color); 34237 } 34238 34239 this.targetLine.lookAt(_v2); 34240 this.targetLine.scale.z = _v3.length(); 34241 } 34242 34243 } 34244 34245 const _vector = /*@__PURE__*/new Vector3(); 34246 34247 const _camera = /*@__PURE__*/new Camera(); 34248 /** 34249 * - shows frustum, line of sight and up of the camera 34250 * - suitable for fast updates 34251 * - based on frustum visualization in lightgl.js shadowmap example 34252 * https://github.com/evanw/lightgl.js/blob/master/tests/shadowmap.html 34253 */ 34254 34255 34256 class CameraHelper extends LineSegments { 34257 constructor(camera) { 34258 const geometry = new BufferGeometry(); 34259 const material = new LineBasicMaterial({ 34260 color: 0xffffff, 34261 vertexColors: true, 34262 toneMapped: false 34263 }); 34264 const vertices = []; 34265 const colors = []; 34266 const pointMap = {}; // colors 34267 34268 const colorFrustum = new Color(0xffaa00); 34269 const colorCone = new Color(0xff0000); 34270 const colorUp = new Color(0x00aaff); 34271 const colorTarget = new Color(0xffffff); 34272 const colorCross = new Color(0x333333); // near 34273 34274 addLine('n1', 'n2', colorFrustum); 34275 addLine('n2', 'n4', colorFrustum); 34276 addLine('n4', 'n3', colorFrustum); 34277 addLine('n3', 'n1', colorFrustum); // far 34278 34279 addLine('f1', 'f2', colorFrustum); 34280 addLine('f2', 'f4', colorFrustum); 34281 addLine('f4', 'f3', colorFrustum); 34282 addLine('f3', 'f1', colorFrustum); // sides 34283 34284 addLine('n1', 'f1', colorFrustum); 34285 addLine('n2', 'f2', colorFrustum); 34286 addLine('n3', 'f3', colorFrustum); 34287 addLine('n4', 'f4', colorFrustum); // cone 34288 34289 addLine('p', 'n1', colorCone); 34290 addLine('p', 'n2', colorCone); 34291 addLine('p', 'n3', colorCone); 34292 addLine('p', 'n4', colorCone); // up 34293 34294 addLine('u1', 'u2', colorUp); 34295 addLine('u2', 'u3', colorUp); 34296 addLine('u3', 'u1', colorUp); // target 34297 34298 addLine('c', 't', colorTarget); 34299 addLine('p', 'c', colorCross); // cross 34300 34301 addLine('cn1', 'cn2', colorCross); 34302 addLine('cn3', 'cn4', colorCross); 34303 addLine('cf1', 'cf2', colorCross); 34304 addLine('cf3', 'cf4', colorCross); 34305 34306 function addLine(a, b, color) { 34307 addPoint(a, color); 34308 addPoint(b, color); 34309 } 34310 34311 function addPoint(id, color) { 34312 vertices.push(0, 0, 0); 34313 colors.push(color.r, color.g, color.b); 34314 34315 if (pointMap[id] === undefined) { 34316 pointMap[id] = []; 34317 } 34318 34319 pointMap[id].push(vertices.length / 3 - 1); 34320 } 34321 34322 geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 34323 geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); 34324 super(geometry, material); 34325 this.type = 'CameraHelper'; 34326 this.camera = camera; 34327 if (this.camera.updateProjectionMatrix) this.camera.updateProjectionMatrix(); 34328 this.matrix = camera.matrixWorld; 34329 this.matrixAutoUpdate = false;
34330 this.pointMap = pointMap; 34331 this.update(); 34332 } 34333 34334 update() { 34335 const geometry = this.geometry; 34336 const pointMap = this.pointMap; 34337 const w = 1, 34338 h = 1; // we need just camera projection matrix inverse 34339 // world matrix must be identity 34340 34341 _camera.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse); // center / target 34342 34343 34344 setPoint('c', pointMap, geometry, _camera, 0, 0, -1); 34345 setPoint('t', pointMap, geometry, _camera, 0, 0, 1); // near 34346 34347 setPoint('n1', pointMap, geometry, _camera, -w, -h, -1); 34348 setPoint('n2', pointMap, geometry, _camera, w, -h, -1); 34349 setPoint('n3', pointMap, geometry, _camera, -w, h, -1); 34350 setPoint('n4', pointMap, geometry, _camera, w, h, -1); // far 34351 34352 setPoint('f1', pointMap, geometry, _camera, -w, -h, 1); 34353 setPoint('f2', pointMap, geometry, _camera, w, -h, 1); 34354 setPoint('f3', pointMap, geometry, _camera, -w, h, 1); 34355 setPoint('f4', pointMap, geometry, _camera, w, h, 1); // up 34356 34357 setPoint('u1', pointMap, geometry, _camera, w * 0.7, h * 1.1, -1); 34358 setPoint('u2', pointMap, geometry, _camera, -w * 0.7, h * 1.1, -1); 34359 setPoint('u3', pointMap, geometry, _camera, 0, h * 2, -1); // cross 34360 34361 setPoint('cf1', pointMap, geometry, _camera, -w, 0, 1); 34362 setPoint('cf2', pointMap, geometry, _camera, w, 0, 1); 34363 setPoint('cf3', pointMap, geometry, _camera, 0, -h, 1); 34364 setPoint('cf4', pointMap, geometry, _camera, 0, h, 1); 34365 setPoint('cn1', pointMap, geometry, _camera, -w, 0, -1); 34366 setPoint('cn2', pointMap, geometry, _camera, w, 0, -1); 34367 setPoint('cn3', pointMap, geometry, _camera, 0, -h, -1); 34368 setPoint('cn4', pointMap, geometry, _camera, 0, h, -1); 34369 geometry.getAttribute('position').needsUpdate = true; 34370 } 34371 34372 dispose() { 34373 this.geometry.dispose(); 34374 this.material.dispose(); 34375 } 34376 34377 } 34378 34379 function setPoint(point, pointMap, geometry, camera, x, y, z) { 34380 _vector.set(x, y, z).unproject(camera); 34381 34382 const points = pointMap[point]; 34383 34384 if (points !== undefined) { 34385 const position = geometry.getAttribute('position'); 34386 34387 for (let i = 0, l = points.length; i < l; i++) { 34388 position.setXYZ(points[i], _vector.x, _vector.y, _vector.z); 34389 } 34390 } 34391 } 34392 34393 const _box = /*@__PURE__*/new Box3(); 34394 34395 class BoxHelper extends LineSegments { 34396 constructor(object, color = 0xffff00) { 34397 const indices = new Uint16Array([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7]); 34398 const positions = new Float32Array(8 * 3); 34399 const geometry = new BufferGeometry(); 34400 geometry.setIndex(new BufferAttribute(indices, 1)); 34401 geometry.setAttribute('position', new BufferAttribute(positions, 3)); 34402 super(geometry, new LineBasicMaterial({ 34403 color: color, 34404 toneMapped: false 34405 })); 34406 this.object = object; 34407 this.type = 'BoxHelper'; 34408 this.matrixAutoUpdate = false; 34409 this.update(); 34410 } 34411 34412 update(object) { 34413 if (object !== undefined) { 34414 console.warn('THREE.BoxHelper: .update() has no longer arguments.'); 34415 } 34416 34417 if (this.object !== undefined) { 34418 _box.setFromObject(this.object); 34419 } 34420 34421 if (_box.isEmpty()) return; 34422 const min = _box.min; 34423 const max = _box.max; 34424 /* 34425 5____4 34426 1/___0/| 34427 | 6__|_7 34428 2/___3/ 34429 0: max.x, max.y, max.z 34430 1: min.x, max.y, max.z 34431 2: min.x, min.y, max.z 34432 3: max.x, min.y, max.z 34433 4: max.x, max.y, min.z 34434 5: min.x, max.y, min.z 34435 6: min.x, min.y, min.z 34436 7: max.x, min.y, min.z 34437 */ 34438 34439 const position = this.geometry.attributes.position; 34440 const array = position.array; 34441 array[0] = max.x; 34442 array[1] = max.y; 34443 array[2] = max.z; 34444 array[3] = min.x; 34445 array[4] = max.y; 34446 array[5] = max.z; 34447 array[6] = min.x; 34448 array[7] = min.y; 34449 array[8] = max.z; 34450 array[9] = max.x; 34451 array[10] = min.y; 34452 array[11] = max.z; 34453 array[12] = max.x; 34454 array[13] = max.y; 34455 array[14] = min.z; 34456 array[15] = min.x; 34457 array[16] = max.y; 34458 array[17] = min.z; 34459 array[18] = min.x; 34460 array[19] = min.y; 34461 array[20] = min.z; 34462 array[21] = max.x; 34463 array[22] = min.y; 34464 array[23] = min.z; 34465 position.needsUpdate = true; 34466 this.geometry.computeBoundingSphere(); 34467 } 34468 34469 setFromObject(object) { 34470 this.object = object; 34471 this.update(); 34472 return this; 34473 } 34474 34475 copy(source) { 34476 LineSegments.prototype.copy.call(this, source); 34477 this.object = source.object; 34478 return this; 34479 } 34480 34481 } 34482 34483 class Box3Helper extends LineSegments { 34484 constructor(box, color = 0xffff00) { 34485 const indices = new Uint16Array([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7]); 34486 const positions = [1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1]; 34487 const geometry = new BufferGeometry(); 34488 geometry.setIndex(new BufferAttribute(indices, 1)); 34489 geometry.setAttribute('position', new Float32BufferAttribute(positions, 3)); 34490 super(geometry, new LineBasicMaterial({ 34491 color: color, 34492 toneMapped: false 34493 })); 34494 this.box = box; 34495 this.type = 'Box3Helper'; 34496 this.geometry.computeBoundingSphere(); 34497 } 34498 34499 updateMatrixWorld(force) { 34500 const box = this.box; 34501 if (box.isEmpty()) return; 34502 box.getCenter(this.position); 34503 box.getSize(this.scale); 34504 this.scale.multiplyScalar(0.5); 34505 super.updateMatrixWorld(force); 34506 } 34507 34508 } 34509 34510 class PlaneHelper extends Line { 34511 constructor(plane, size = 1, hex = 0xffff00) { 34512 const color = hex; 34513 const positions = [1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0]; 34514 const geometry = new BufferGeometry(); 34515 geometry.setAttribute('position', new Float32BufferAttribute(positions, 3)); 34516 geometry.computeBoundingSphere(); 34517 super(geometry, new LineBasicMaterial({ 34518 color: color, 34519 toneMapped: false 34520 })); 34521 this.type = 'PlaneHelper'; 34522 this.plane = plane; 34523 this.size = size; 34524 const positions2 = [1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1]; 34525 const geometry2 = new BufferGeometry(); 34526 geometry2.setAttribute('position', new Float32BufferAttribute(positions2, 3)); 34527 geometry2.computeBoundingSphere(); 34528 this.add(new Mesh(geometry2, new MeshBasicMaterial({ 34529 color: color, 34530 opacity: 0.2, 34531 transparent: true, 34532 depthWrite: false, 34533 toneMapped: false 34534 }))); 34535 } 34536 34537 updateMatrixWorld(force) { 34538 let scale = -this.plane.constant; 34539 if (Math.abs(scale) < 1e-8) scale = 1e-8; // sign does not matter 34540 34541 this.scale.set(0.5 * this.size, 0.5 * this.size, scale); 34542 this.children[0].material.side = scale < 0 ? BackSide : FrontSide; // renderer flips side when determinant < 0; flipping not wanted here 34543 34544 this.lookAt(this.plane.normal); 34545 super.updateMatrixWorld(force); 34546 } 34547 34548 } 34549 34550 const _axis = /*@__PURE__*/new Vector3(); 34551 34552 let _lineGeometry, _coneGeometry; 34553 34554 class ArrowHelper extends Object3D { 34555 // dir is assumed to be normalized 34556 constructor(dir = new Vector3(0, 0, 1), origin = new Vector3(0, 0, 0), length = 1, color = 0xffff00, headLength = length * 0.2, headWidth = headLength * 0.2) { 34557 super(); 34558 this.type = 'ArrowHelper'; 34559 34560 if (_lineGeometry === undefined) { 34561 _lineGeometry = new BufferGeometry(); 34562 34563 _lineGeometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 0, 1, 0], 3)); 34564 34565 _coneGeometry = new CylinderGeometry(0, 0.5, 1, 5, 1); 34566 34567 _coneGeometry.translate(0, -0.5, 0); 34568 } 34569 34570 this.position.copy(origin); 34571 this.line = new Line(_lineGeometry, new LineBasicMaterial({ 34572 color: color, 34573 toneMapped: false 34574 })); 34575 this.line.matrixAutoUpdate = false;
vendor: 3,735 bytes, lines 34576-34717
34576 this.add(this.line); 34577 this.cone = new Mesh(_coneGeometry, new MeshBasicMaterial({ 34578 color: color, 34579 toneMapped: false 34580 })); 34581 this.cone.matrixAutoUpdate = false; 34582 this.add(this.cone); 34583 this.setDirection(dir); 34584 this.setLength(length, headLength, headWidth); 34585 } 34586 34587 setDirection(dir) { 34588 // dir is assumed to be normalized 34589 if (dir.y > 0.99999) { 34590 this.quaternion.set(0, 0, 0, 1); 34591 } else if (dir.y < -0.99999) { 34592 this.quaternion.set(1, 0, 0, 0); 34593 } else { 34594 _axis.set(dir.z, 0, -dir.x).normalize(); 34595 34596 const radians = Math.acos(dir.y); 34597 this.quaternion.setFromAxisAngle(_axis, radians); 34598 } 34599 } 34600 34601 setLength(length, headLength = length * 0.2, headWidth = headLength * 0.2) { 34602 this.line.scale.set(1, Math.max(0.0001, length - headLength), 1); // see #17458 34603 34604 this.line.updateMatrix(); 34605 this.cone.scale.set(headWidth, headLength, headWidth); 34606 this.cone.position.y = length; 34607 this.cone.updateMatrix(); 34608 } 34609 34610 setColor(color) { 34611 this.line.material.color.set(color); 34612 this.cone.material.color.set(color); 34613 } 34614 34615 copy(source) { 34616 super.copy(source, false); 34617 this.line.copy(source.line); 34618 this.cone.copy(source.cone); 34619 return this; 34620 } 34621 34622 } 34623 34624 class AxesHelper extends LineSegments { 34625 constructor(size = 1) { 34626 const vertices = [0, 0, 0, size, 0, 0, 0, 0, 0, 0, size, 0, 0, 0, 0, 0, 0, size]; 34627 const colors = [1, 0, 0, 1, 0.6, 0, 0, 1, 0, 0.6, 1, 0, 0, 0, 1, 0, 0.6, 1]; 34628 const geometry = new BufferGeometry(); 34629 geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); 34630 geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); 34631 const material = new LineBasicMaterial({ 34632 vertexColors: true, 34633 toneMapped: false 34634 }); 34635 super(geometry, material); 34636 this.type = 'AxesHelper'; 34637 } 34638 34639 setColors(xAxisColor, yAxisColor, zAxisColor) { 34640 const color = new Color(); 34641 const array = this.geometry.attributes.color.array; 34642 color.set(xAxisColor); 34643 color.toArray(array, 0); 34644 color.toArray(array, 3); 34645 color.set(yAxisColor); 34646 color.toArray(array, 6); 34647 color.toArray(array, 9); 34648 color.set(zAxisColor); 34649 color.toArray(array, 12); 34650 color.toArray(array, 15); 34651 this.geometry.attributes.color.needsUpdate = true; 34652 return this; 34653 } 34654 34655 dispose() { 34656 this.geometry.dispose(); 34657 this.material.dispose(); 34658 } 34659 34660 } 34661 34662 class ShapePath { 34663 constructor() { 34664 this.type = 'ShapePath'; 34665 this.color = new Color(); 34666 this.subPaths = []; 34667 this.currentPath = null; 34668 } 34669 34670 moveTo(x, y) { 34671 this.currentPath = new Path(); 34672 this.subPaths.push(this.currentPath); 34673 this.currentPath.moveTo(x, y); 34674 return this; 34675 } 34676 34677 lineTo(x, y) { 34678 this.currentPath.lineTo(x, y); 34679 return this; 34680 } 34681 34682 quadraticCurveTo(aCPx, aCPy, aX, aY) { 34683 this.currentPath.quadraticCurveTo(aCPx, aCPy, aX, aY); 34684 return this; 34685 } 34686 34687 bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) { 34688 this.currentPath.bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY); 34689 return this; 34690 } 34691 34692 splineThru(pts) { 34693 this.currentPath.splineThru(pts); 34694 return this; 34695 } 34696 34697 toShapes(isCCW, noHoles) { 34698 function toShapesNoHoles(inSubpaths) { 34699 const shapes = []; 34700 34701 for (let i = 0, l = inSubpaths.length; i < l; i++) { 34702 const tmpPath = inSubpaths[i]; 34703 const tmpShape = new Shape(); 34704 tmpShape.curves = tmpPath.curves; 34705 shapes.push(tmpShape); 34706 } 34707 34708 return shapes; 34709 } 34710 34711 function isPointInsidePolygon(inPt, inPolygon) { 34712 const polyLen = inPolygon.length; // inPt on polygon contour => immediate success or 34713 // toggling of inside/outside at every single! intersection point of an edge 34714 // with the horizontal line through inPt, left of inPt 34715 // not counting lowerY endpoints of edges and whole edges on that line 34716 34717 let inside = false;
vendor: 5,023 bytes, lines 34718-34891
34718 34719 for (let p = polyLen - 1, q = 0; q < polyLen; p = q++) { 34720 let edgeLowPt = inPolygon[p]; 34721 let edgeHighPt = inPolygon[q]; 34722 let edgeDx = edgeHighPt.x - edgeLowPt.x; 34723 let edgeDy = edgeHighPt.y - edgeLowPt.y; 34724 34725 if (Math.abs(edgeDy) > Number.EPSILON) { 34726 // not parallel 34727 if (edgeDy < 0) { 34728 edgeLowPt = inPolygon[q]; 34729 edgeDx = -edgeDx; 34730 edgeHighPt = inPolygon[p]; 34731 edgeDy = -edgeDy; 34732 } 34733 34734 if (inPt.y < edgeLowPt.y || inPt.y > edgeHighPt.y) continue; 34735 34736 if (inPt.y === edgeLowPt.y) { 34737 if (inPt.x === edgeLowPt.x) return true; // inPt is on contour ? 34738 // continue; // no intersection or edgeLowPt => doesn't count !!! 34739 } else { 34740 const perpEdge = edgeDy * (inPt.x - edgeLowPt.x) - edgeDx * (inPt.y - edgeLowPt.y); 34741 if (perpEdge === 0) return true; // inPt is on contour ? 34742 34743 if (perpEdge < 0) continue; 34744 inside = !inside; // true intersection left of inPt 34745 } 34746 } else { 34747 // parallel or collinear 34748 if (inPt.y !== edgeLowPt.y) continue; // parallel 34749 // edge lies on the same horizontal line as inPt 34750 34751 if (edgeHighPt.x <= inPt.x && inPt.x <= edgeLowPt.x || edgeLowPt.x <= inPt.x && inPt.x <= edgeHighPt.x) return true; // inPt: Point on contour ! 34752 // continue; 34753 } 34754 } 34755 34756 return inside; 34757 } 34758 34759 const isClockWise = ShapeUtils.isClockWise; 34760 const subPaths = this.subPaths; 34761 if (subPaths.length === 0) return []; 34762 if (noHoles === true) return toShapesNoHoles(subPaths); 34763 let solid, tmpPath, tmpShape; 34764 const shapes = []; 34765 34766 if (subPaths.length === 1) { 34767 tmpPath = subPaths[0]; 34768 tmpShape = new Shape(); 34769 tmpShape.curves = tmpPath.curves; 34770 shapes.push(tmpShape); 34771 return shapes; 34772 } 34773 34774 let holesFirst = !isClockWise(subPaths[0].getPoints()); 34775 holesFirst = isCCW ? !holesFirst : holesFirst; // console.log("Holes first", holesFirst); 34776 34777 const betterShapeHoles = []; 34778 const newShapes = []; 34779 let newShapeHoles = []; 34780 let mainIdx = 0; 34781 let tmpPoints; 34782 newShapes[mainIdx] = undefined; 34783 newShapeHoles[mainIdx] = []; 34784 34785 for (let i = 0, l = subPaths.length; i < l; i++) { 34786 tmpPath = subPaths[i]; 34787 tmpPoints = tmpPath.getPoints(); 34788 solid = isClockWise(tmpPoints); 34789 solid = isCCW ? !solid : solid; 34790 34791 if (solid) { 34792 if (!holesFirst && newShapes[mainIdx]) mainIdx++; 34793 newShapes[mainIdx] = { 34794 s: new Shape(), 34795 p: tmpPoints 34796 }; 34797 newShapes[mainIdx].s.curves = tmpPath.curves; 34798 if (holesFirst) mainIdx++; 34799 newShapeHoles[mainIdx] = []; //console.log('cw', i); 34800 } else { 34801 newShapeHoles[mainIdx].push({ 34802 h: tmpPath, 34803 p: tmpPoints[0] 34804 }); //console.log('ccw', i); 34805 } 34806 } // only Holes? -> probably all Shapes with wrong orientation 34807 34808 34809 if (!newShapes[0]) return toShapesNoHoles(subPaths); 34810 34811 if (newShapes.length > 1) { 34812 let ambiguous = false; 34813 const toChange = []; 34814 34815 for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) { 34816 betterShapeHoles[sIdx] = []; 34817 } 34818 34819 for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) { 34820 const sho = newShapeHoles[sIdx]; 34821 34822 for (let hIdx = 0; hIdx < sho.length; hIdx++) { 34823 const ho = sho[hIdx]; 34824 let hole_unassigned = true; 34825 34826 for (let s2Idx = 0; s2Idx < newShapes.length; s2Idx++) { 34827 if (isPointInsidePolygon(ho.p, newShapes[s2Idx].p)) { 34828 if (sIdx !== s2Idx) toChange.push({ 34829 froms: sIdx, 34830 tos: s2Idx, 34831 hole: hIdx 34832 }); 34833 34834 if (hole_unassigned) { 34835 hole_unassigned = false; 34836 betterShapeHoles[s2Idx].push(ho); 34837 } else { 34838 ambiguous = true; 34839 } 34840 } 34841 } 34842 34843 if (hole_unassigned) { 34844 betterShapeHoles[sIdx].push(ho); 34845 } 34846 } 34847 } // console.log("ambiguous: ", ambiguous); 34848 34849 34850 if (toChange.length > 0) { 34851 // console.log("to change: ", toChange); 34852 if (!ambiguous) newShapeHoles = betterShapeHoles; 34853 } 34854 } 34855 34856 let tmpHoles; 34857 34858 for (let i = 0, il = newShapes.length; i < il; i++) { 34859 tmpShape = newShapes[i].s; 34860 shapes.push(tmpShape); 34861 tmpHoles = newShapeHoles[i]; 34862 34863 for (let j = 0, jl = tmpHoles.length; j < jl; j++) { 34864 tmpShape.holes.push(tmpHoles[j].h); 34865 } 34866 } //console.log("shape", shapes); 34867 34868 34869 return shapes; 34870 } 34871 34872 } 34873 34874 const _floatView = new Float32Array(1); 34875 34876 const _int32View = new Int32Array(_floatView.buffer); 34877 34878 class DataUtils { 34879 // Converts float32 to float16 (stored as uint16 value). 34880 static toHalfFloat(val) { 34881 if (val > 65504) { 34882 console.warn('THREE.DataUtils.toHalfFloat(): value exceeds 65504.'); 34883 val = 65504; // maximum representable value in float16 34884 } // Source: http://gamedev.stackexchange.com/questions/17326/conversion-of-a-number-from-single-precision-floating-point-representation-to-a/17410#17410 34885 34886 /* This method is faster than the OpenEXR implementation (very often 34887 * used, eg. in Ogre), with the additional benefit of rounding, inspired 34888 * by James Tursa?s half-precision code. */ 34889 34890 34891 _floatView[0] = val;
34892 const x = _int32View[0]; 34893 let bits = x >> 16 & 0x8000; 34894 /* Get the sign */ 34895 34896 let m = x >> 12 & 0x07ff; 34897 /* Keep one extra bit for rounding */ 34898 34899 const e = x >> 23 & 0xff; 34900 /* Using int is faster here */ 34901 34902 /* If zero, or denormal, or exponent underflows too much for a denormal 34903 * half, return signed zero. */ 34904 34905 if (e < 103) return bits; 34906 /* If NaN, return NaN. If Inf or exponent overflow, return Inf. */ 34907 34908 if (e > 142) { 34909 bits |= 0x7c00; 34910 /* If exponent was 0xff and one mantissa bit was set, it means NaN, 34911 * not Inf, so make sure we set one mantissa bit too. */ 34912 34913 bits |= (e == 255 ? 0 : 1) && x & 0x007fffff; 34914 return bits; 34915 } 34916 /* If exponent underflows but not too much, return a denormal */ 34917 34918 34919 if (e < 113) { 34920 m |= 0x0800; 34921 /* Extra rounding may overflow and set mantissa to 0 and exponent 34922 * to 1, which is OK. */ 34923 34924 bits |= (m >> 114 - e) + (m >> 113 - e & 1); 34925 return bits; 34926 } 34927 34928 bits |= e - 112 << 10 | m >> 1; 34929 /* Extra rounding. An overflow will set mantissa to 0 and increment 34930 * the exponent, which is OK. */ 34931 34932 bits += m & 1; 34933 return bits; 34934 } 34935 34936 } 34937 34938 const LineStrip = 0; 34939 const LinePieces = 1; 34940 const NoColors = 0; 34941 const FaceColors = 1; 34942 const VertexColors = 2; 34943 function MeshFaceMaterial(materials) { 34944 console.warn('THREE.MeshFaceMaterial has been removed. Use an Array instead.'); 34945 return materials; 34946 } 34947 function MultiMaterial(materials = []) { 34948 console.warn('THREE.MultiMaterial has been removed. Use an Array instead.'); 34949 materials.isMultiMaterial = true; 34950 materials.materials = materials; 34951 34952 materials.clone = function () { 34953 return materials.slice(); 34954 }; 34955 34956 return materials; 34957 } 34958 function PointCloud(geometry, material) { 34959 console.warn('THREE.PointCloud has been renamed to THREE.Points.'); 34960 return new Points(geometry, material); 34961 } 34962 function Particle(material) { 34963 console.warn('THREE.Particle has been renamed to THREE.Sprite.'); 34964 return new Sprite(material); 34965 } 34966 function ParticleSystem(geometry, material) { 34967 console.warn('THREE.ParticleSystem has been renamed to THREE.Points.'); 34968 return new Points(geometry, material); 34969 } 34970 function PointCloudMaterial(parameters) { 34971 console.warn('THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.'); 34972 return new PointsMaterial(parameters); 34973 } 34974 function ParticleBasicMaterial(parameters) { 34975 console.warn('THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.'); 34976 return new PointsMaterial(parameters); 34977 } 34978 function ParticleSystemMaterial(parameters) { 34979 console.warn('THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.'); 34980 return new PointsMaterial(parameters); 34981 } 34982 function Vertex(x, y, z) { 34983 console.warn('THREE.Vertex has been removed. Use THREE.Vector3 instead.'); 34984 return new Vector3(x, y, z); 34985 } // 34986 34987 function DynamicBufferAttribute(array, itemSize) { 34988 console.warn('THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setUsage( THREE.DynamicDrawUsage ) instead.'); 34989 return new BufferAttribute(array, itemSize).setUsage(DynamicDrawUsage); 34990 } 34991 function Int8Attribute(array, itemSize) { 34992 console.warn('THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.'); 34993 return new Int8BufferAttribute(array, itemSize); 34994 } 34995 function Uint8Attribute(array, itemSize) { 34996 console.warn('THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.'); 34997 return new Uint8BufferAttribute(array, itemSize); 34998 } 34999 function Uint8ClampedAttribute(array, itemSize) { 35000 console.warn('THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.'); 35001 return new Uint8ClampedBufferAttribute(array, itemSize); 35002 } 35003 function Int16Attribute(array, itemSize) { 35004 console.warn('THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.'); 35005 return new Int16BufferAttribute(array, itemSize); 35006 } 35007 function Uint16Attribute(array, itemSize) { 35008 console.warn('THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.'); 35009 return new Uint16BufferAttribute(array, itemSize); 35010 } 35011 function Int32Attribute(array, itemSize) { 35012 console.warn('THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.'); 35013 return new Int32BufferAttribute(array, itemSize); 35014 } 35015 function Uint32Attribute(array, itemSize) { 35016 console.warn('THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.'); 35017 return new Uint32BufferAttribute(array, itemSize); 35018 } 35019 function Float32Attribute(array, itemSize) { 35020 console.warn('THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.'); 35021 return new Float32BufferAttribute(array, itemSize); 35022 } 35023 function Float64Attribute(array, itemSize) { 35024 console.warn('THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.'); 35025 return new Float64BufferAttribute(array, itemSize); 35026 } // 35027 35028 Curve.create = function (construct, getPoint) { 35029 console.log('THREE.Curve.create() has been deprecated'); 35030 construct.prototype = Object.create(Curve.prototype);
35031 construct.prototype.constructor = construct; 35032 construct.prototype.getPoint = getPoint; 35033 return construct; 35034 }; // 35035 35036 35037 Path.prototype.fromPoints = function (points) { 35038 console.warn('THREE.Path: .fromPoints() has been renamed to .setFromPoints().'); 35039 return this.setFromPoints(points); 35040 }; // 35041 35042 35043 function AxisHelper(size) { 35044 console.warn('THREE.AxisHelper has been renamed to THREE.AxesHelper.'); 35045 return new AxesHelper(size); 35046 } 35047 function BoundingBoxHelper(object, color) { 35048 console.warn('THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.'); 35049 return new BoxHelper(object, color); 35050 } 35051 function EdgesHelper(object, hex) { 35052 console.warn('THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.'); 35053 return new LineSegments(new EdgesGeometry(object.geometry), new LineBasicMaterial({ 35054 color: hex !== undefined ? hex : 0xffffff 35055 })); 35056 } 35057 35058 GridHelper.prototype.setColors = function () { 35059 console.error('THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.'); 35060 }; 35061 35062 SkeletonHelper.prototype.update = function () { 35063 console.error('THREE.SkeletonHelper: update() no longer needs to be called.'); 35064 }; 35065 35066 function WireframeHelper(object, hex) { 35067 console.warn('THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.'); 35068 return new LineSegments(new WireframeGeometry(object.geometry), new LineBasicMaterial({ 35069 color: hex !== undefined ? hex : 0xffffff 35070 })); 35071 } // 35072 35073 Loader.prototype.extractUrlBase = function (url) { 35074 console.warn('THREE.Loader: .extractUrlBase() has been deprecated. Use THREE.LoaderUtils.extractUrlBase() instead.'); 35075 return LoaderUtils.extractUrlBase(url); 35076 }; 35077 35078 Loader.Handlers = { 35079 add: function () { 35080 console.error('THREE.Loader: Handlers.add() has been removed. Use LoadingManager.addHandler() instead.'); 35081 }, 35082 get: function () { 35083 console.error('THREE.Loader: Handlers.get() has been removed. Use LoadingManager.getHandler() instead.'); 35084 } 35085 }; 35086 function XHRLoader(manager) { 35087 console.warn('THREE.XHRLoader has been renamed to THREE.FileLoader.'); 35088 return new FileLoader(manager); 35089 } 35090 function BinaryTextureLoader(manager) { 35091 console.warn('THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.'); 35092 return new DataTextureLoader(manager); 35093 } // 35094 35095 Box2.prototype.center = function (optionalTarget) { 35096 console.warn('THREE.Box2: .center() has been renamed to .getCenter().'); 35097 return this.getCenter(optionalTarget); 35098 }; 35099 35100 Box2.prototype.empty = function () { 35101 console.warn('THREE.Box2: .empty() has been renamed to .isEmpty().'); 35102 return this.isEmpty(); 35103 }; 35104 35105 Box2.prototype.isIntersectionBox = function (box) { 35106 console.warn('THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().'); 35107 return this.intersectsBox(box); 35108 }; 35109 35110 Box2.prototype.size = function (optionalTarget) { 35111 console.warn('THREE.Box2: .size() has been renamed to .getSize().'); 35112 return this.getSize(optionalTarget); 35113 }; // 35114 35115 35116 Box3.prototype.center = function (optionalTarget) { 35117 console.warn('THREE.Box3: .center() has been renamed to .getCenter().'); 35118 return this.getCenter(optionalTarget); 35119 }; 35120 35121 Box3.prototype.empty = function () { 35122 console.warn('THREE.Box3: .empty() has been renamed to .isEmpty().'); 35123 return this.isEmpty(); 35124 }; 35125 35126 Box3.prototype.isIntersectionBox = function (box) { 35127 console.warn('THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().'); 35128 return this.intersectsBox(box); 35129 }; 35130 35131 Box3.prototype.isIntersectionSphere = function (sphere) { 35132 console.warn('THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().'); 35133 return this.intersectsSphere(sphere); 35134 }; 35135 35136 Box3.prototype.size = function (optionalTarget) { 35137 console.warn('THREE.Box3: .size() has been renamed to .getSize().'); 35138 return this.getSize(optionalTarget); 35139 }; // 35140 35141 35142 Sphere.prototype.empty = function () { 35143 console.warn('THREE.Sphere: .empty() has been renamed to .isEmpty().'); 35144 return this.isEmpty(); 35145 }; // 35146 35147 35148 Frustum.prototype.setFromMatrix = function (m) { 35149 console.warn('THREE.Frustum: .setFromMatrix() has been renamed to .setFromProjectionMatrix().'); 35150 return this.setFromProjectionMatrix(m); 35151 }; // 35152 35153 35154 Line3.prototype.center = function (optionalTarget) { 35155 console.warn('THREE.Line3: .center() has been renamed to .getCenter().'); 35156 return this.getCenter(optionalTarget); 35157 }; // 35158 35159 35160 Matrix3.prototype.flattenToArrayOffset = function (array, offset) { 35161 console.warn('THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.'); 35162 return this.toArray(array, offset); 35163 }; 35164 35165 Matrix3.prototype.multiplyVector3 = function (vector) {
35166 console.warn('THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.'); 35167 return vector.applyMatrix3(this); 35168 }; 35169 35170 Matrix3.prototype.multiplyVector3Array = function () { 35171 console.error('THREE.Matrix3: .multiplyVector3Array() has been removed.'); 35172 }; 35173 35174 Matrix3.prototype.applyToBufferAttribute = function (attribute) { 35175 console.warn('THREE.Matrix3: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix3( matrix ) instead.'); 35176 return attribute.applyMatrix3(this); 35177 }; 35178 35179 Matrix3.prototype.applyToVector3Array = function () { 35180 console.error('THREE.Matrix3: .applyToVector3Array() has been removed.'); 35181 }; 35182 35183 Matrix3.prototype.getInverse = function (matrix) { 35184 console.warn('THREE.Matrix3: .getInverse() has been removed. Use matrixInv.copy( matrix ).invert(); instead.'); 35185 return this.copy(matrix).invert(); 35186 }; // 35187 35188 35189 Matrix4.prototype.extractPosition = function (m) { 35190 console.warn('THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().'); 35191 return this.copyPosition(m); 35192 }; 35193 35194 Matrix4.prototype.flattenToArrayOffset = function (array, offset) { 35195 console.warn('THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.'); 35196 return this.toArray(array, offset); 35197 }; 35198 35199 Matrix4.prototype.getPosition = function () { 35200 console.warn('THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.'); 35201 return new Vector3().setFromMatrixColumn(this, 3); 35202 }; 35203 35204 Matrix4.prototype.setRotationFromQuaternion = function (q) { 35205 console.warn('THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().'); 35206 return this.makeRotationFromQuaternion(q); 35207 }; 35208 35209 Matrix4.prototype.multiplyToArray = function () { 35210 console.warn('THREE.Matrix4: .multiplyToArray() has been removed.'); 35211 }; 35212 35213 Matrix4.prototype.multiplyVector3 = function (vector) {
35214 console.warn('THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.'); 35215 return vector.applyMatrix4(this); 35216 }; 35217 35218 Matrix4.prototype.multiplyVector4 = function (vector) { 35219 console.warn('THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.'); 35220 return vector.applyMatrix4(this); 35221 }; 35222 35223 Matrix4.prototype.multiplyVector3Array = function () { 35224 console.error('THREE.Matrix4: .multiplyVector3Array() has been removed.'); 35225 }; 35226 35227 Matrix4.prototype.rotateAxis = function (v) { 35228 console.warn('THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.'); 35229 v.transformDirection(this); 35230 }; 35231 35232 Matrix4.prototype.crossVector = function (vector) { 35233 console.warn('THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.'); 35234 return vector.applyMatrix4(this); 35235 }; 35236 35237 Matrix4.prototype.translate = function () { 35238 console.error('THREE.Matrix4: .translate() has been removed.'); 35239 }; 35240 35241 Matrix4.prototype.rotateX = function () { 35242 console.error('THREE.Matrix4: .rotateX() has been removed.'); 35243 }; 35244 35245 Matrix4.prototype.rotateY = function () { 35246 console.error('THREE.Matrix4: .rotateY() has been removed.'); 35247 }; 35248 35249 Matrix4.prototype.rotateZ = function () { 35250 console.error('THREE.Matrix4: .rotateZ() has been removed.'); 35251 }; 35252 35253 Matrix4.prototype.rotateByAxis = function () { 35254 console.error('THREE.Matrix4: .rotateByAxis() has been removed.'); 35255 }; 35256 35257 Matrix4.prototype.applyToBufferAttribute = function (attribute) { 35258 console.warn('THREE.Matrix4: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix4( matrix ) instead.'); 35259 return attribute.applyMatrix4(this); 35260 }; 35261 35262 Matrix4.prototype.applyToVector3Array = function () { 35263 console.error('THREE.Matrix4: .applyToVector3Array() has been removed.'); 35264 }; 35265 35266 Matrix4.prototype.makeFrustum = function (left, right, bottom, top, near, far) { 35267 console.warn('THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.'); 35268 return this.makePerspective(left, right, top, bottom, near, far); 35269 }; 35270 35271 Matrix4.prototype.getInverse = function (matrix) { 35272 console.warn('THREE.Matrix4: .getInverse() has been removed. Use matrixInv.copy( matrix ).invert(); instead.'); 35273 return this.copy(matrix).invert(); 35274 }; // 35275 35276 35277 Plane.prototype.isIntersectionLine = function (line) { 35278 console.warn('THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().'); 35279 return this.intersectsLine(line); 35280 }; // 35281 35282 35283 Quaternion.prototype.multiplyVector3 = function (vector) {
35284 console.warn('THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.'); 35285 return vector.applyQuaternion(this); 35286 }; 35287 35288 Quaternion.prototype.inverse = function () { 35289 console.warn('THREE.Quaternion: .inverse() has been renamed to invert().'); 35290 return this.invert(); 35291 }; // 35292 35293 35294 Ray.prototype.isIntersectionBox = function (box) { 35295 console.warn('THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().'); 35296 return this.intersectsBox(box); 35297 }; 35298 35299 Ray.prototype.isIntersectionPlane = function (plane) { 35300 console.warn('THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().'); 35301 return this.intersectsPlane(plane); 35302 }; 35303 35304 Ray.prototype.isIntersectionSphere = function (sphere) { 35305 console.warn('THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().'); 35306 return this.intersectsSphere(sphere); 35307 }; // 35308 35309 35310 Triangle.prototype.area = function () { 35311 console.warn('THREE.Triangle: .area() has been renamed to .getArea().'); 35312 return this.getArea(); 35313 }; 35314 35315 Triangle.prototype.barycoordFromPoint = function (point, target) { 35316 console.warn('THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().'); 35317 return this.getBarycoord(point, target); 35318 }; 35319 35320 Triangle.prototype.midpoint = function (target) { 35321 console.warn('THREE.Triangle: .midpoint() has been renamed to .getMidpoint().'); 35322 return this.getMidpoint(target); 35323 }; 35324 35325 Triangle.prototypenormal = function (target) { 35326 console.warn('THREE.Triangle: .normal() has been renamed to .getNormal().'); 35327 return this.getNormal(target); 35328 }; 35329 35330 Triangle.prototype.plane = function (target) { 35331 console.warn('THREE.Triangle: .plane() has been renamed to .getPlane().'); 35332 return this.getPlane(target); 35333 }; 35334 35335 Triangle.barycoordFromPoint = function (point, a, b, c, target) { 35336 console.warn('THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().'); 35337 return Triangle.getBarycoord(point, a, b, c, target); 35338 }; 35339 35340 Triangle.normal = function (a, b, c, target) { 35341 console.warn('THREE.Triangle: .normal() has been renamed to .getNormal().'); 35342 return Triangle.getNormal(a, b, c, target); 35343 }; // 35344 35345 35346 Shape.prototype.extractAllPoints = function (divisions) { 35347 console.warn('THREE.Shape: .extractAllPoints() has been removed. Use .extractPoints() instead.'); 35348 return this.extractPoints(divisions); 35349 }; 35350 35351 Shape.prototype.extrude = function (options) { 35352 console.warn('THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.'); 35353 return new ExtrudeGeometry(this, options); 35354 }; 35355 35356 Shape.prototype.makeGeometry = function (options) { 35357 console.warn('THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.'); 35358 return new ShapeGeometry(this, options); 35359 }; // 35360 35361 35362 Vector2.prototype.fromAttribute = function (attribute, index, offset) { 35363 console.warn('THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().'); 35364 return this.fromBufferAttribute(attribute, index, offset); 35365 }; 35366 35367 Vector2.prototype.distanceToManhattan = function (v) { 35368 console.warn('THREE.Vector2: .distanceToManhattan() has been renamed to .manhattanDistanceTo().'); 35369 return this.manhattanDistanceTo(v); 35370 }; 35371 35372 Vector2.prototype.lengthManhattan = function () { 35373 console.warn('THREE.Vector2: .lengthManhattan() has been renamed to .manhattanLength().'); 35374 return this.manhattanLength(); 35375 }; // 35376 35377 35378 Vector3.prototype.setEulerFromRotationMatrix = function () { 35379 console.error('THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.'); 35380 }; 35381 35382 Vector3.prototype.setEulerFromQuaternion = function () { 35383 console.error('THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.'); 35384 }; 35385 35386 Vector3.prototype.getPositionFromMatrix = function (m) { 35387 console.warn('THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().'); 35388 return this.setFromMatrixPosition(m); 35389 }; 35390 35391 Vector3.prototype.getScaleFromMatrix = function (m) { 35392 console.warn('THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().'); 35393 return this.setFromMatrixScale(m); 35394 }; 35395
vendor: 9,256 bytes, lines 35396-35658
35396 Vector3.prototype.getColumnFromMatrix = function (index, matrix) { 35397 console.warn('THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().'); 35398 return this.setFromMatrixColumn(matrix, index); 35399 }; 35400 35401 Vector3.prototype.applyProjection = function (m) { 35402 console.warn('THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.'); 35403 return this.applyMatrix4(m); 35404 }; 35405 35406 Vector3.prototype.fromAttribute = function (attribute, index, offset) { 35407 console.warn('THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().'); 35408 return this.fromBufferAttribute(attribute, index, offset); 35409 }; 35410 35411 Vector3.prototype.distanceToManhattan = function (v) { 35412 console.warn('THREE.Vector3: .distanceToManhattan() has been renamed to .manhattanDistanceTo().'); 35413 return this.manhattanDistanceTo(v); 35414 }; 35415 35416 Vector3.prototype.lengthManhattan = function () { 35417 console.warn('THREE.Vector3: .lengthManhattan() has been renamed to .manhattanLength().'); 35418 return this.manhattanLength(); 35419 }; // 35420 35421 35422 Vector4.prototype.fromAttribute = function (attribute, index, offset) { 35423 console.warn('THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().'); 35424 return this.fromBufferAttribute(attribute, index, offset); 35425 }; 35426 35427 Vector4.prototype.lengthManhattan = function () { 35428 console.warn('THREE.Vector4: .lengthManhattan() has been renamed to .manhattanLength().'); 35429 return this.manhattanLength(); 35430 }; // 35431 35432 35433 Object3D.prototype.getChildByName = function (name) { 35434 console.warn('THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().'); 35435 return this.getObjectByName(name); 35436 }; 35437 35438 Object3D.prototype.renderDepth = function () { 35439 console.warn('THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.'); 35440 }; 35441 35442 Object3D.prototype.translate = function (distance, axis) { 35443 console.warn('THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.'); 35444 return this.translateOnAxis(axis, distance); 35445 }; 35446 35447 Object3D.prototype.getWorldRotation = function () { 35448 console.error('THREE.Object3D: .getWorldRotation() has been removed. Use THREE.Object3D.getWorldQuaternion( target ) instead.'); 35449 }; 35450 35451 Object3D.prototype.applyMatrix = function (matrix) { 35452 console.warn('THREE.Object3D: .applyMatrix() has been renamed to .applyMatrix4().'); 35453 return this.applyMatrix4(matrix); 35454 }; 35455 35456 Object.defineProperties(Object3D.prototype, { 35457 eulerOrder: { 35458 get: function () { 35459 console.warn('THREE.Object3D: .eulerOrder is now .rotation.order.'); 35460 return this.rotation.order; 35461 }, 35462 set: function (value) { 35463 console.warn('THREE.Object3D: .eulerOrder is now .rotation.order.'); 35464 this.rotation.order = value; 35465 } 35466 }, 35467 useQuaternion: { 35468 get: function () { 35469 console.warn('THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.'); 35470 }, 35471 set: function () { 35472 console.warn('THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.'); 35473 } 35474 } 35475 }); 35476 35477 Mesh.prototype.setDrawMode = function () { 35478 console.error('THREE.Mesh: .setDrawMode() has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.'); 35479 }; 35480 35481 Object.defineProperties(Mesh.prototype, { 35482 drawMode: { 35483 get: function () { 35484 console.error('THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode.'); 35485 return TrianglesDrawMode; 35486 }, 35487 set: function () { 35488 console.error('THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.'); 35489 } 35490 } 35491 }); 35492 35493 SkinnedMesh.prototype.initBones = function () { 35494 console.error('THREE.SkinnedMesh: initBones() has been removed.'); 35495 }; // 35496 35497 35498 PerspectiveCamera.prototype.setLens = function (focalLength, filmGauge) { 35499 console.warn('THREE.PerspectiveCamera.setLens is deprecated. ' + 'Use .setFocalLength and .filmGauge for a photographic setup.'); 35500 if (filmGauge !== undefined) this.filmGauge = filmGauge; 35501 this.setFocalLength(focalLength); 35502 }; // 35503 35504 35505 Object.defineProperties(Light.prototype, { 35506 onlyShadow: { 35507 set: function () { 35508 console.warn('THREE.Light: .onlyShadow has been removed.'); 35509 } 35510 }, 35511 shadowCameraFov: { 35512 set: function (value) { 35513 console.warn('THREE.Light: .shadowCameraFov is now .shadow.camera.fov.'); 35514 this.shadow.camera.fov = value; 35515 } 35516 }, 35517 shadowCameraLeft: { 35518 set: function (value) { 35519 console.warn('THREE.Light: .shadowCameraLeft is now .shadow.camera.left.'); 35520 this.shadow.camera.left = value; 35521 } 35522 }, 35523 shadowCameraRight: { 35524 set: function (value) { 35525 console.warn('THREE.Light: .shadowCameraRight is now .shadow.camera.right.'); 35526 this.shadow.camera.right = value; 35527 } 35528 }, 35529 shadowCameraTop: { 35530 set: function (value) { 35531 console.warn('THREE.Light: .shadowCameraTop is now .shadow.camera.top.'); 35532 this.shadow.camera.top = value; 35533 } 35534 }, 35535 shadowCameraBottom: { 35536 set: function (value) { 35537 console.warn('THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.'); 35538 this.shadow.camera.bottom = value; 35539 } 35540 }, 35541 shadowCameraNear: { 35542 set: function (value) { 35543 console.warn('THREE.Light: .shadowCameraNear is now .shadow.camera.near.'); 35544 this.shadow.camera.near = value; 35545 } 35546 }, 35547 shadowCameraFar: { 35548 set: function (value) { 35549 console.warn('THREE.Light: .shadowCameraFar is now .shadow.camera.far.'); 35550 this.shadow.camera.far = value; 35551 } 35552 }, 35553 shadowCameraVisible: { 35554 set: function () { 35555 console.warn('THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.'); 35556 } 35557 }, 35558 shadowBias: { 35559 set: function (value) { 35560 console.warn('THREE.Light: .shadowBias is now .shadow.bias.'); 35561 this.shadow.bias = value; 35562 } 35563 }, 35564 shadowDarkness: { 35565 set: function () { 35566 console.warn('THREE.Light: .shadowDarkness has been removed.'); 35567 } 35568 }, 35569 shadowMapWidth: { 35570 set: function (value) { 35571 console.warn('THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.'); 35572 this.shadow.mapSize.width = value; 35573 } 35574 }, 35575 shadowMapHeight: { 35576 set: function (value) { 35577 console.warn('THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.'); 35578 this.shadow.mapSize.height = value; 35579 } 35580 } 35581 }); // 35582 35583 Object.defineProperties(BufferAttribute.prototype, { 35584 length: { 35585 get: function () { 35586 console.warn('THREE.BufferAttribute: .length has been deprecated. Use .count instead.'); 35587 return this.array.length; 35588 } 35589 }, 35590 dynamic: { 35591 get: function () { 35592 console.warn('THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.'); 35593 return this.usage === DynamicDrawUsage; 35594 }, 35595 set: function () { 35596 console.warn('THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.'); 35597 this.setUsage(DynamicDrawUsage); 35598 } 35599 } 35600 }); 35601 35602 BufferAttribute.prototype.setDynamic = function (value) { 35603 console.warn('THREE.BufferAttribute: .setDynamic() has been deprecated. Use .setUsage() instead.'); 35604 this.setUsage(value === true ? DynamicDrawUsage : StaticDrawUsage); 35605 return this; 35606 }; 35607 35608 BufferAttribute.prototype.copyIndicesArray = function () { 35609 console.error('THREE.BufferAttribute: .copyIndicesArray() has been removed.'); 35610 }, BufferAttribute.prototype.setArray = function () { 35611 console.error('THREE.BufferAttribute: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers'); 35612 }; // 35613 35614 BufferGeometry.prototype.addIndex = function (index) { 35615 console.warn('THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().'); 35616 this.setIndex(index); 35617 }; 35618 35619 BufferGeometry.prototype.addAttribute = function (name, attribute) { 35620 console.warn('THREE.BufferGeometry: .addAttribute() has been renamed to .setAttribute().'); 35621 35622 if (!(attribute && attribute.isBufferAttribute) && !(attribute && attribute.isInterleavedBufferAttribute)) { 35623 console.warn('THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).'); 35624 return this.setAttribute(name, new BufferAttribute(arguments[1], arguments[2])); 35625 } 35626 35627 if (name === 'index') { 35628 console.warn('THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.'); 35629 this.setIndex(attribute); 35630 return this; 35631 } 35632 35633 return this.setAttribute(name, attribute); 35634 }; 35635 35636 BufferGeometry.prototype.addDrawCall = function (start, count, indexOffset) { 35637 if (indexOffset !== undefined) { 35638 console.warn('THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.'); 35639 } 35640 35641 console.warn('THREE.BufferGeometry: .addDrawCall() is now .addGroup().'); 35642 this.addGroup(start, count); 35643 }; 35644 35645 BufferGeometry.prototype.clearDrawCalls = function () { 35646 console.warn('THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().'); 35647 this.clearGroups(); 35648 }; 35649 35650 BufferGeometry.prototype.computeOffsets = function () { 35651 console.warn('THREE.BufferGeometry: .computeOffsets() has been removed.'); 35652 }; 35653 35654 BufferGeometry.prototype.removeAttribute = function (name) { 35655 console.warn('THREE.BufferGeometry: .removeAttribute() has been renamed to .deleteAttribute().'); 35656 return this.deleteAttribute(name); 35657 }; 35658
35659 BufferGeometry.prototype.applyMatrix = function (matrix) { 35660 console.warn('THREE.BufferGeometry: .applyMatrix() has been renamed to .applyMatrix4().'); 35661 return this.applyMatrix4(matrix); 35662 }; 35663 35664 Object.defineProperties(BufferGeometry.prototype, { 35665 drawcalls: { 35666 get: function () { 35667 console.error('THREE.BufferGeometry: .drawcalls has been renamed to .groups.'); 35668 return this.groups; 35669 } 35670 }, 35671 offsets: { 35672 get: function () { 35673 console.warn('THREE.BufferGeometry: .offsets has been renamed to .groups.'); 35674 return this.groups; 35675 } 35676 } 35677 }); 35678 35679 InterleavedBuffer.prototype.setDynamic = function (value) { 35680 console.warn('THREE.InterleavedBuffer: .setDynamic() has been deprecated. Use .setUsage() instead.'); 35681 this.setUsage(value === true ? DynamicDrawUsage : StaticDrawUsage); 35682 return this; 35683 }; 35684 35685 InterleavedBuffer.prototype.setArray = function () { 35686 console.error('THREE.InterleavedBuffer: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers'); 35687 }; // 35688 35689 35690 ExtrudeGeometry.prototype.getArrays = function () { 35691 console.error('THREE.ExtrudeGeometry: .getArrays() has been removed.'); 35692 }; 35693 35694 ExtrudeGeometry.prototype.addShapeList = function () { 35695 console.error('THREE.ExtrudeGeometry: .addShapeList() has been removed.'); 35696 }; 35697 35698 ExtrudeGeometry.prototype.addShape = function () { 35699 console.error('THREE.ExtrudeGeometry: .addShape() has been removed.'); 35700 }; // 35701 35702 35703 Scene.prototype.dispose = function () { 35704 console.error('THREE.Scene: .dispose() has been removed.'); 35705 }; // 35706 35707 35708 Uniform.prototype.onUpdate = function () { 35709 console.warn('THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.'); 35710 return this; 35711 }; // 35712 35713 35714 Object.defineProperties(Material.prototype, { 35715 wrapAround: { 35716 get: function () { 35717 console.warn('THREE.Material: .wrapAround has been removed.'); 35718 }, 35719 set: function () { 35720 console.warn('THREE.Material: .wrapAround has been removed.'); 35721 } 35722 }, 35723 overdraw: { 35724 get: function () { 35725 console.warn('THREE.Material: .overdraw has been removed.'); 35726 }, 35727 set: function () { 35728 console.warn('THREE.Material: .overdraw has been removed.'); 35729 } 35730 }, 35731 wrapRGB: { 35732 get: function () { 35733 console.warn('THREE.Material: .wrapRGB has been removed.'); 35734 return new Color(); 35735 } 35736 }, 35737 shading: { 35738 get: function () { 35739 console.error('THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.'); 35740 }, 35741 set: function (value) { 35742 console.warn('THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.'); 35743 this.flatShading = value === FlatShading; 35744 } 35745 }, 35746 stencilMask: { 35747 get: function () { 35748 console.warn('THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.'); 35749 return this.stencilFuncMask; 35750 }, 35751 set: function (value) { 35752 console.warn('THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.'); 35753 this.stencilFuncMask = value; 35754 } 35755 }, 35756 vertexTangents: { 35757 get: function () { 35758 console.warn('THREE.' + this.type + ': .vertexTangents has been removed.'); 35759 }, 35760 set: function () { 35761 console.warn('THREE.' + this.type + ': .vertexTangents has been removed.'); 35762 } 35763 } 35764 }); 35765 Object.defineProperties(ShaderMaterial.prototype, { 35766 derivatives: { 35767 get: function () { 35768 console.warn('THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.'); 35769 return this.extensions.derivatives; 35770 }, 35771 set: function (value) { 35772 console.warn('THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.'); 35773 this.extensions.derivatives = value; 35774 } 35775 } 35776 }); // 35777 35778 WebGLRenderer.prototype.clearTarget = function (renderTarget, color, depth, stencil) { 35779 console.warn('THREE.WebGLRenderer: .clearTarget() has been deprecated. Use .setRenderTarget() and .clear() instead.'); 35780 this.setRenderTarget(renderTarget); 35781 this.clear(color, depth, stencil); 35782 }; 35783 35784 WebGLRenderer.prototype.animate = function (callback) { 35785 console.warn('THREE.WebGLRenderer: .animate() is now .setAnimationLoop().'); 35786 this.setAnimationLoop(callback); 35787 }; 35788 35789 WebGLRenderer.prototype.getCurrentRenderTarget = function () { 35790 console.warn('THREE.WebGLRenderer: .getCurrentRenderTarget() is now .getRenderTarget().'); 35791 return this.getRenderTarget(); 35792 }; 35793 35794 WebGLRenderer.prototype.getMaxAnisotropy = function () { 35795 console.warn('THREE.WebGLRenderer: .getMaxAnisotropy() is now .capabilities.getMaxAnisotropy().'); 35796 return this.capabilities.getMaxAnisotropy(); 35797 }; 35798 35799 WebGLRenderer.prototype.getPrecision = function () { 35800 console.warn('THREE.WebGLRenderer: .getPrecision() is now .capabilities.precision.'); 35801 return this.capabilities.precision; 35802 }; 35803 35804 WebGLRenderer.prototype.resetGLState = function () { 35805 console.warn('THREE.WebGLRenderer: .resetGLState() is now .state.reset().'); 35806 return this.state.reset(); 35807 }; 35808 35809 WebGLRenderer.prototype.supportsFloatTextures = function () { 35810 console.warn('THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).'); 35811 return this.extensions.get('OES_texture_float'); 35812 }; 35813 35814 WebGLRenderer.prototype.supportsHalfFloatTextures = function () { 35815 console.warn('THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).'); 35816 return this.extensions.get('OES_texture_half_float'); 35817 }; 35818 35819 WebGLRenderer.prototype.supportsStandardDerivatives = function () { 35820 console.warn('THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).'); 35821 return this.extensions.get('OES_standard_derivatives'); 35822 }; 35823 35824 WebGLRenderer.prototype.supportsCompressedTextureS3TC = function () { 35825 console.warn('THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).'); 35826 return this.extensions.get('WEBGL_compressed_texture_s3tc'); 35827 }; 35828 35829 WebGLRenderer.prototype.supportsCompressedTexturePVRTC = function () { 35830 console.warn('THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).'); 35831 return this.extensions.get('WEBGL_compressed_texture_pvrtc'); 35832 }; 35833 35834 WebGLRenderer.prototype.supportsBlendMinMax = function () { 35835 console.warn('THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).'); 35836 return this.extensions.get('EXT_blend_minmax'); 35837 }; 35838 35839 WebGLRenderer.prototype.supportsVertexTextures = function () { 35840 console.warn('THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.'); 35841 return this.capabilities.vertexTextures; 35842 }; 35843 35844 WebGLRenderer.prototype.supportsInstancedArrays = function () { 35845 console.warn('THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \'ANGLE_
vendor: 4,353 bytes, lines 35845-35978
35845instanced_arrays\' ).'); 35846 return this.extensions.get('ANGLE_instanced_arrays'); 35847 }; 35848 35849 WebGLRenderer.prototype.enableScissorTest = function (boolean) { 35850 console.warn('THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().'); 35851 this.setScissorTest(boolean); 35852 }; 35853 35854 WebGLRenderer.prototype.initMaterial = function () { 35855 console.warn('THREE.WebGLRenderer: .initMaterial() has been removed.'); 35856 }; 35857 35858 WebGLRenderer.prototype.addPrePlugin = function () { 35859 console.warn('THREE.WebGLRenderer: .addPrePlugin() has been removed.'); 35860 }; 35861 35862 WebGLRenderer.prototype.addPostPlugin = function () { 35863 console.warn('THREE.WebGLRenderer: .addPostPlugin() has been removed.'); 35864 }; 35865 35866 WebGLRenderer.prototype.updateShadowMap = function () { 35867 console.warn('THREE.WebGLRenderer: .updateShadowMap() has been removed.'); 35868 }; 35869 35870 WebGLRenderer.prototype.setFaceCulling = function () { 35871 console.warn('THREE.WebGLRenderer: .setFaceCulling() has been removed.'); 35872 }; 35873 35874 WebGLRenderer.prototype.allocTextureUnit = function () { 35875 console.warn('THREE.WebGLRenderer: .allocTextureUnit() has been removed.'); 35876 }; 35877 35878 WebGLRenderer.prototype.setTexture = function () { 35879 console.warn('THREE.WebGLRenderer: .setTexture() has been removed.'); 35880 }; 35881 35882 WebGLRenderer.prototype.setTexture2D = function () { 35883 console.warn('THREE.WebGLRenderer: .setTexture2D() has been removed.'); 35884 }; 35885 35886 WebGLRenderer.prototype.setTextureCube = function () { 35887 console.warn('THREE.WebGLRenderer: .setTextureCube() has been removed.'); 35888 }; 35889 35890 WebGLRenderer.prototype.getActiveMipMapLevel = function () { 35891 console.warn('THREE.WebGLRenderer: .getActiveMipMapLevel() is now .getActiveMipmapLevel().'); 35892 return this.getActiveMipmapLevel(); 35893 }; 35894 35895 Object.defineProperties(WebGLRenderer.prototype, { 35896 shadowMapEnabled: { 35897 get: function () { 35898 return this.shadowMap.enabled; 35899 }, 35900 set: function (value) { 35901 console.warn('THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.'); 35902 this.shadowMap.enabled = value; 35903 } 35904 }, 35905 shadowMapType: { 35906 get: function () { 35907 return this.shadowMap.type; 35908 }, 35909 set: function (value) { 35910 console.warn('THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.'); 35911 this.shadowMap.type = value; 35912 } 35913 }, 35914 shadowMapCullFace: { 35915 get: function () { 35916 console.warn('THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.'); 35917 return undefined; 35918 }, 35919 set: function () { 35920 console.warn('THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.'); 35921 } 35922 }, 35923 context: { 35924 get: function () { 35925 console.warn('THREE.WebGLRenderer: .context has been removed. Use .getContext() instead.'); 35926 return this.getContext(); 35927 } 35928 }, 35929 vr: { 35930 get: function () { 35931 console.warn('THREE.WebGLRenderer: .vr has been renamed to .xr'); 35932 return this.xr; 35933 } 35934 }, 35935 gammaInput: { 35936 get: function () { 35937 console.warn('THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.'); 35938 return false; 35939 }, 35940 set: function () { 35941 console.warn('THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.'); 35942 } 35943 }, 35944 gammaOutput: { 35945 get: function () { 35946 console.warn('THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.'); 35947 return false; 35948 }, 35949 set: function (value) { 35950 console.warn('THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.'); 35951 this.outputEncoding = value === true ? sRGBEncoding : LinearEncoding; 35952 } 35953 }, 35954 toneMappingWhitePoint: { 35955 get: function () { 35956 console.warn('THREE.WebGLRenderer: .toneMappingWhitePoint has been removed.'); 35957 return 1.0; 35958 }, 35959 set: function () { 35960 console.warn('THREE.WebGLRenderer: .toneMappingWhitePoint has been removed.'); 35961 } 35962 }, 35963 gammaFactor: { 35964 get: function () { 35965 console.warn('THREE.WebGLRenderer: .gammaFactor has been removed.'); 35966 return 2; 35967 }, 35968 set: function () { 35969 console.warn('THREE.WebGLRenderer: .gammaFactor has been removed.'); 35970 } 35971 } 35972 }); 35973 Object.defineProperties(WebGLShadowMap.prototype, { 35974 cullFace: { 35975 get: function () { 35976 console.warn('THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.'); 35977 return undefined; 35978 },
35979 set: function () { 35980 console.warn('THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.'); 35981 } 35982 }, 35983 renderReverseSided: { 35984 get: function () { 35985 console.warn('THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.'); 35986 return undefined; 35987 }, 35988 set: function () { 35989 console.warn('THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.'); 35990 } 35991 }, 35992 renderSingleSided: { 35993 get: function () { 35994 console.warn('THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.'); 35995 return undefined; 35996 }, 35997 set: function () { 35998 console.warn('THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.'); 35999 } 36000 } 36001 }); 36002 function WebGLRenderTargetCube(width, height, options) { 36003 console.warn('THREE.WebGLRenderTargetCube( width, height, options ) is now WebGLCubeRenderTarget( size, options ).'); 36004 return new WebGLCubeRenderTarget(width, options); 36005 } // 36006 36007 Object.defineProperties(WebGLRenderTarget.prototype, { 36008 wrapS: { 36009 get: function () { 36010 console.warn('THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.'); 36011 return this.texture.wrapS; 36012 }, 36013 set: function (value) { 36014 console.warn('THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.'); 36015 this.texture.wrapS = value; 36016 } 36017 }, 36018 wrapT: { 36019 get: function () { 36020 console.warn('THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.'); 36021 return this.texture.wrapT; 36022 }, 36023 set: function (value) { 36024 console.warn('THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.'); 36025 this.texture.wrapT = value; 36026 } 36027 }, 36028 magFilter: { 36029 get: function () { 36030 console.warn('THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.'); 36031 return this.texture.magFilter; 36032 }, 36033 set: function (value) { 36034 console.warn('THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.'); 36035 this.texture.magFilter = value; 36036 } 36037 }, 36038 minFilter: { 36039 get: function () { 36040 console.warn('THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.'); 36041 return this.texture.minFilter; 36042 }, 36043 set: function (value) { 36044 console.warn('THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.'); 36045 this.texture.minFilter = value; 36046 } 36047 }, 36048 anisotropy: { 36049 get: function () { 36050 console.warn('THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.'); 36051 return this.texture.anisotropy; 36052 }, 36053 set: function (value) { 36054 console.warn('THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.'); 36055 this.texture.anisotropy = value; 36056 } 36057 }, 36058 offset: { 36059 get: function () { 36060 console.warn('THREE.WebGLRenderTarget: .offset is now .texture.offset.'); 36061 return this.texture.offset; 36062 }, 36063 set: function (value) { 36064 console.warn('THREE.WebGLRenderTarget: .offset is now .texture.offset.'); 36065 this.texture.offset = value; 36066 } 36067 }, 36068 repeat: { 36069 get: function () { 36070 console.warn('THREE.WebGLRenderTarget: .repeat is now .texture.repeat.'); 36071 return this.texture.repeat; 36072 }, 36073 set: function (value) { 36074 console.warn('THREE.WebGLRenderTarget: .repeat is now .texture.repeat.'); 36075 this.texture.repeat = value; 36076 } 36077 }, 36078 format: { 36079 get: function () { 36080 console.warn('THREE.WebGLRenderTarget: .format is now .texture.format.'); 36081 return this.texture.format; 36082 }, 36083 set: function (value) { 36084 console.warn('THREE.WebGLRenderTarget: .format is now .texture.format.'); 36085 this.texture.format = value; 36086 } 36087 }, 36088 type: { 36089 get: function () { 36090 console.warn('THREE.WebGLRenderTarget: .type is now .texture.type.'); 36091 return this.texture.type; 36092 }, 36093 set: function (value) { 36094 console.warn('THREE.WebGLRenderTarget: .type is now .texture.type.'); 36095 this.texture.type = value; 36096 } 36097 }, 36098 generateMipmaps: { 36099 get: function () { 36100 console.warn('THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.'); 36101 return this.texture.generateMipmaps; 36102 }, 36103 set: function (value) { 36104 console.warn('THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.'); 36105 this.texture.generateMipmaps = value; 36106 } 36107 } 36108 }); // 36109 36110 Audio.prototype.load = function (file) { 36111 console.warn('THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.'); 36112 const scope = this; 36113 const audioLoader = new AudioLoader(); 36114 audioLoader.load(file, function (buffer) { 36115 scope.setBuffer(buffer); 36116 }); 36117 return this; 36118 }; 36119 36120 AudioAnalyser.prototype.getData = function () { 36121 console.warn('THREE.AudioAnalyser: .getData() is now .getFrequencyData().'); 36122 return this.getFrequencyData(); 36123 }; // 36124 36125 36126 CubeCamera.prototype.updateCubeMap = function (renderer, scene) { 36127 console.warn('THREE.CubeCamera: .updateCubeMap() is now .update(
36127).'); 36128 return this.update(renderer, scene); 36129 }; 36130 36131 CubeCamera.prototype.clear = function (renderer, color, depth, stencil) { 36132 console.warn('THREE.CubeCamera: .clear() is now .renderTarget.clear().'); 36133 return this.renderTarget.clear(renderer, color, depth, stencil); 36134 }; 36135 36136 ImageUtils.crossOrigin = undefined; 36137 36138 ImageUtils.loadTexture = function (url, mapping, onLoad, onError) { 36139 console.warn('THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.'); 36140 const loader = new TextureLoader(); 36141 loader.setCrossOrigin(this.crossOrigin); 36142 const texture = loader.load(url, onLoad, undefined, onError); 36143 if (mapping) texture.mapping = mapping; 36144 return texture; 36145 }; 36146 36147 ImageUtils.loadTextureCube = function (urls, mapping, onLoad, onError) { 36148 console.warn('THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.'); 36149 const loader = new CubeTextureLoader(); 36150 loader.setCrossOrigin(this.crossOrigin); 36151 const texture = loader.load(urls, onLoad, undefined, onError); 36152 if (mapping) texture.mapping = mapping; 36153 return texture; 36154 }; 36155 36156 ImageUtils.loadCompressedTexture = function () { 36157 console.error('THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.'); 36158 }; 36159 36160 ImageUtils.loadCompressedTextureCube = function () { 36161 console.error('THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.'); 36162 }; // 36163 36164 36165 function CanvasRenderer() { 36166 console.error('THREE.CanvasRenderer has been removed'); 36167 } // 36168 36169 function JSONLoader() { 36170 console.error('THREE.JSONLoader has been removed.'); 36171 } // 36172 36173 const SceneUtils = { 36174 createMultiMaterialObject: function () { 36175 console.error('THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js'); 36176 }, 36177 detach: function () { 36178 console.error('THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js'); 36179 }, 36180 attach: function () { 36181 console.error('THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js'); 36182 } 36183 }; // 36184 36185 function LensFlare() { 36186 console.error('THREE.LensFlare has been moved to /examples/jsm/objects/Lensflare.js'); 36187 } // 36188 36189 function ParametricGeometry() { 36190 console.error('THREE.ParametricGeometry has been moved to /examples/jsm/geometries/ParametricGeometry.js'); 36191 return new BufferGeometry(); 36192 } 36193 function TextGeometry() { 36194 console.error('THREE.TextGeometry has been moved to /examples/jsm/geometries/TextGeometry.js'); 36195 return new BufferGeometry(); 36196 } 36197 function FontLoader() { 36198 console.error('THREE.FontLoader has been moved to /examples/jsm/loaders/FontLoader.js'); 36199 } 36200 function Font() { 36201 console.error('THREE.Font has been moved to /examples/jsm/loaders/FontLoader.js'); 36202 } 36203 function ImmediateRenderObject() { 36204 console.error('THREE.ImmediateRenderObject has been removed.'); 36205 } 36206 36207 if (typeof __THREE_DEVTOOLS__ !== 'undefined') { 36208 __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('register', { 36209 detail: { 36210 revision: REVISION 36211 } 36212 })); 36213 } 36214 36215 if (typeof window !== 'undefined') { 36216 if (window.__THREE__) { 36217 console.warn('WARNING: Multiple instances of Three.js being imported.'); 36218 } else { 36219 window.__THREE__ = REVISION; 36220 } 36221 } 36222 36223 exports.ACESFilmicToneMapping = ACESFilmicToneMapping; 36224 exports.AddEquation = AddEquation; 36225 exports.AddOperation = AddOperation; 36226 exports.AdditiveAnimationBlendMode = AdditiveAnimationBlendMode; 36227 exports.AdditiveBlending = AdditiveBlending; 36228 exports.AlphaFormat = AlphaFormat; 36229 exports.AlwaysDepth = AlwaysDepth; 36230 exports.AlwaysStencilFunc = AlwaysStencilFunc; 36231 exports.AmbientLight = AmbientLight; 36232 exports.AmbientLightProbe = AmbientLightProbe; 36233 exports.AnimationClip = AnimationClip; 36234 exports.AnimationLoader = AnimationLoader; 36235 exports.AnimationMixer = AnimationMixer; 36236 exports.AnimationObjectGroup = AnimationObjectGroup; 36237 exports.AnimationUtils = AnimationUtils; 36238 exports.ArcCurve = ArcCurve; 36239 exports.ArrayCamera = ArrayCamera; 36240 exports.ArrowHelper = ArrowHelper; 36241 exports.Audio = Audio; 36242 exports.AudioAnalyser = AudioAnalyser; 36243 exports.AudioContext = AudioContext; 36244 exports.AudioListener = AudioListener; 36245 exports.AudioLoader = AudioLoader;
36246 exports.AxesHelper = AxesHelper; 36247 exports.AxisHelper = AxisHelper; 36248 exports.BackSide = BackSide; 36249 exports.BasicDepthPacking = BasicDepthPacking; 36250 exports.BasicShadowMap = BasicShadowMap; 36251 exports.BinaryTextureLoader = BinaryTextureLoader; 36252 exports.Bone = Bone; 36253 exports.BooleanKeyframeTrack = BooleanKeyframeTrack; 36254 exports.BoundingBoxHelper = BoundingBoxHelper; 36255 exports.Box2 = Box2; 36256 exports.Box3 = Box3; 36257 exports.Box3Helper = Box3Helper; 36258 exports.BoxBufferGeometry = BoxGeometry; 36259 exports.BoxGeometry = BoxGeometry; 36260 exports.BoxHelper = BoxHelper; 36261 exports.BufferAttribute = BufferAttribute; 36262 exports.BufferGeometry = BufferGeometry; 36263 exports.BufferGeometryLoader = BufferGeometryLoader; 36264 exports.ByteType = ByteType; 36265 exports.Cache = Cache; 36266 exports.Camera = Camera; 36267 exports.CameraHelper = CameraHelper; 36268 exports.CanvasRenderer = CanvasRenderer; 36269 exports.CanvasTexture = CanvasTexture; 36270 exports.CatmullRomCurve3 = CatmullRomCurve3; 36271 exports.CineonToneMapping = CineonToneMapping; 36272 exports.CircleBufferGeometry = CircleGeometry; 36273 exports.CircleGeometry = CircleGeometry; 36274 exports.ClampToEdgeWrapping = ClampToEdgeWrapping; 36275 exports.Clock = Clock; 36276 exports.Color = Color; 36277 exports.ColorKeyframeTrack = ColorKeyframeTrack; 36278 exports.CompressedTexture = CompressedTexture; 36279 exports.CompressedTextureLoader = CompressedTextureLoader; 36280 exports.ConeBufferGeometry = ConeGeometry; 36281 exports.ConeGeometry = ConeGeometry; 36282 exports.CubeCamera = CubeCamera; 36283 exports.CubeReflectionMapping = CubeReflectionMapping; 36284 exports.CubeRefractionMapping = CubeRefractionMapping; 36285 exports.CubeTexture = CubeTexture; 36286 exports.CubeTextureLoader = CubeTextureLoader; 36287 exports.CubeUVReflectionMapping = CubeUVReflectionMapping; 36288 exports.CubeUVRefractionMapping = CubeUVRefractionMapping; 36289 exports.CubicBezierCurve = CubicBezierCurve; 36290 exports.CubicBezierCurve3 = CubicBezierCurve3; 36291 exports.CubicInterpolant = CubicInterpolant; 36292 exports.CullFaceBack = CullFaceBack; 36293 exports.CullFaceFront = CullFaceFront; 36294 exports.CullFaceFrontBack = CullFaceFrontBack; 36295 exports.CullFaceNone = CullFaceNone; 36296 exports.Curve = Curve; 36297 exports.CurvePath = CurvePath; 36298 exports.CustomBlending = CustomBlending; 36299 exports.CustomToneMapping = CustomToneMapping; 36300 exports.CylinderBufferGeometry = CylinderGeometry; 36301 exports.CylinderGeometry = CylinderGeometry; 36302 exports.Cylindrical = Cylindrical; 36303 exports.DataTexture = DataTexture; 36304 exports.DataTexture2DArray = DataTexture2DArray; 36305 exports.DataTexture3D = DataTexture3D; 36306 exports.DataTextureLoader = DataTextureLoader; 36307 exports.DataUtils = DataUtils; 36308 exports.DecrementStencilOp = DecrementStencilOp; 36309 exports.DecrementWrapStencilOp = DecrementWrapStencilOp; 36310 exports.DefaultLoadingManager = DefaultLoadingManager; 36311 exports.DepthFormat = DepthFormat; 36312 exports.DepthStencilFormat = DepthStencilFormat; 36313 exports.DepthTexture = DepthTexture; 36314 exports.DirectionalLight = DirectionalLight; 36315 exports.DirectionalLightHelper = DirectionalLightHelper; 36316 exports.DiscreteInterpolant = DiscreteInterpolant; 36317 exports.DodecahedronBufferGeometry = DodecahedronGeometry; 36318 exports.DodecahedronGeometry = DodecahedronGeometry; 36319 exports.DoubleSide = DoubleSide; 36320 exports.DstAlphaFactor = DstAlphaFactor; 36321 exports.DstColorFactor = DstColorFactor; 36322 exports.DynamicBufferAttribute = DynamicBufferAttribute; 36323 exports.DynamicCopyUsage = DynamicCopyUsage; 36324 exports.DynamicDrawUsage = DynamicDrawUsage; 36325 exports.DynamicReadUsage = DynamicReadUsage; 36326 exports.EdgesGeometry = EdgesGeometry; 36327 exports.EdgesHelper = EdgesHelper; 36328 exports.EllipseCurve = EllipseCurve; 36329 exports.EqualDepth = EqualDepth; 36330 exports.EqualStencilFunc = EqualStencilFunc; 36331 exports.EquirectangularReflectionMapping = EquirectangularReflectionMapping; 36332 exports.EquirectangularRefractionMapping = EquirectangularRefractionMapping; 36333 exports.Euler = Euler; 36334 exports.EventDispatcher = EventDispatcher;
36335 exports.ExtrudeBufferGeometry = ExtrudeGeometry; 36336 exports.ExtrudeGeometry = ExtrudeGeometry; 36337 exports.FaceColors = FaceColors; 36338 exports.FileLoader = FileLoader; 36339 exports.FlatShading = FlatShading; 36340 exports.Float16BufferAttribute = Float16BufferAttribute; 36341 exports.Float32Attribute = Float32Attribute; 36342 exports.Float32BufferAttribute = Float32BufferAttribute; 36343 exports.Float64Attribute = Float64Attribute; 36344 exports.Float64BufferAttribute = Float64BufferAttribute; 36345 exports.FloatType = FloatType; 36346 exports.Fog = Fog; 36347 exports.FogExp2 = FogExp2; 36348 exports.Font = Font; 36349 exports.FontLoader = FontLoader; 36350 exports.FramebufferTexture = FramebufferTexture; 36351 exports.FrontSide = FrontSide; 36352 exports.Frustum = Frustum; 36353 exports.GLBufferAttribute = GLBufferAttribute; 36354 exports.GLSL1 = GLSL1; 36355 exports.GLSL3 = GLSL3; 36356 exports.GreaterDepth = GreaterDepth; 36357 exports.GreaterEqualDepth = GreaterEqualDepth; 36358 exports.GreaterEqualStencilFunc = GreaterEqualStencilFunc; 36359 exports.GreaterStencilFunc = GreaterStencilFunc; 36360 exports.GridHelper = GridHelper; 36361 exports.Group = Group; 36362 exports.HalfFloatType = HalfFloatType; 36363 exports.HemisphereLight = HemisphereLight; 36364 exports.HemisphereLightHelper = HemisphereLightHelper; 36365 exports.HemisphereLightProbe = HemisphereLightProbe; 36366 exports.IcosahedronBufferGeometry = IcosahedronGeometry; 36367 exports.IcosahedronGeometry = IcosahedronGeometry; 36368 exports.ImageBitmapLoader = ImageBitmapLoader; 36369 exports.ImageLoader = ImageLoader; 36370 exports.ImageUtils = ImageUtils; 36371 exports.ImmediateRenderObject = ImmediateRenderObject; 36372 exports.IncrementStencilOp = IncrementStencilOp; 36373 exports.IncrementWrapStencilOp = IncrementWrapStencilOp; 36374 exports.InstancedBufferAttribute = InstancedBufferAttribute; 36375 exports.InstancedBufferGeometry = InstancedBufferGeometry; 36376 exports.InstancedInterleavedBuffer = InstancedInterleavedBuffer; 36377 exports.InstancedMesh = InstancedMesh; 36378 exports.Int16Attribute = Int16Attribute; 36379 exports.Int16BufferAttribute = Int16BufferAttribute; 36380 exports.Int32Attribute = Int32Attribute; 36381 exports.Int32BufferAttribute = Int32BufferAttribute; 36382 exports.Int8Attribute = Int8Attribute; 36383 exports.Int8BufferAttribute = Int8BufferAttribute; 36384 exports.IntType = IntType; 36385 exports.InterleavedBuffer = InterleavedBuffer; 36386 exports.InterleavedBufferAttribute = InterleavedBufferAttribute; 36387 exports.Interpolant = Interpolant; 36388 exports.InterpolateDiscrete = InterpolateDiscrete; 36389 exports.InterpolateLinear = InterpolateLinear; 36390 exports.InterpolateSmooth = InterpolateSmooth; 36391 exports.InvertStencilOp = InvertStencilOp; 36392 exports.JSONLoader = JSONLoader; 36393 exports.KeepStencilOp = KeepStencilOp; 36394 exports.KeyframeTrack = KeyframeTrack; 36395 exports.LOD = LOD; 36396 exports.LatheBufferGeometry = LatheGeometry; 36397 exports.LatheGeometry = LatheGeometry; 36398 exports.Layers = Layers; 36399 exports.LensFlare = LensFlare; 36400 exports.LessDepth = LessDepth; 36401 exports.LessEqualDepth = LessEqualDepth; 36402 exports.LessEqualStencilFunc = LessEqualStencilFunc; 36403 exports.LessStencilFunc = LessStencilFunc; 36404 exports.Light = Light; 36405 exports.LightProbe = LightProbe; 36406 exports.Line = Line; 36407 exports.Line3 = Line3; 36408 exports.LineBasicMaterial = LineBasicMaterial; 36409 exports.LineCurve = LineCurve; 36410 exports.LineCurve3 = LineCurve3; 36411 exports.LineDashedMaterial = LineDashedMaterial; 36412 exports.LineLoop = LineLoop; 36413 exports.LinePieces = LinePieces; 36414 exports.LineSegments = LineSegments; 36415 exports.LineStrip = LineStrip; 36416 exports.LinearEncoding = LinearEncoding; 36417 exports.LinearFilter = LinearFilter; 36418 exports.LinearInterpolant = LinearInterpolant; 36419 exports.LinearMipMapLinearFilter = LinearMipMapLinearFilter; 36420 exports.LinearMipMapNearestFilter = LinearMipMapNearestFilter; 36421 exports.LinearMipmapLinearFilter = LinearMipmapLinearFilter; 36422 exports.LinearMipmapNearestFilter = LinearMipmapNearestFilter; 36423 exports.LinearToneMapping = LinearToneMapping; 36424 exports.Loader = Loader; 36425 exports.LoaderUtils = LoaderUtils; 36426 exports.LoadingManager = LoadingManager; 36427 exports.LoopOnce = LoopOnce; 36428 exports.LoopPingPong = LoopPingPong; 36429 exports.LoopRepeat = LoopRepeat; 36430 exports.LuminanceAlphaFormat = LuminanceAlphaFormat; 36431 exports.LuminanceFormat = LuminanceFormat; 36432 exports.MOUSE = MOUSE; 36433 exports.Material = Material;
36434 exports.MaterialLoader = MaterialLoader; 36435 exports.Math = MathUtils; 36436 exports.MathUtils = MathUtils; 36437 exports.Matrix3 = Matrix3; 36438 exports.Matrix4 = Matrix4; 36439 exports.MaxEquation = MaxEquation; 36440 exports.Mesh = Mesh; 36441 exports.MeshBasicMaterial = MeshBasicMaterial; 36442 exports.MeshDepthMaterial = MeshDepthMaterial; 36443 exports.MeshDistanceMaterial = MeshDistanceMaterial; 36444 exports.MeshFaceMaterial = MeshFaceMaterial; 36445 exports.MeshLambertMaterial = MeshLambertMaterial; 36446 exports.MeshMatcapMaterial = MeshMatcapMaterial; 36447 exports.MeshNormalMaterial = MeshNormalMaterial; 36448 exports.MeshPhongMaterial = MeshPhongMaterial; 36449 exports.MeshPhysicalMaterial = MeshPhysicalMaterial; 36450 exports.MeshStandardMaterial = MeshStandardMaterial; 36451 exports.MeshToonMaterial = MeshToonMaterial; 36452 exports.MinEquation = MinEquation; 36453 exports.MirroredRepeatWrapping = MirroredRepeatWrapping; 36454 exports.MixOperation = MixOperation; 36455 exports.MultiMaterial = MultiMaterial; 36456 exports.MultiplyBlending = MultiplyBlending; 36457 exports.MultiplyOperation = MultiplyOperation; 36458 exports.NearestFilter = NearestFilter; 36459 exports.NearestMipMapLinearFilter = NearestMipMapLinearFilter; 36460 exports.NearestMipMapNearestFilter = NearestMipMapNearestFilter; 36461 exports.NearestMipmapLinearFilter = NearestMipmapLinearFilter; 36462 exports.NearestMipmapNearestFilter = NearestMipmapNearestFilter; 36463 exports.NeverDepth = NeverDepth; 36464 exports.NeverStencilFunc = NeverStencilFunc; 36465 exports.NoBlending = NoBlending; 36466 exports.NoColors = NoColors; 36467 exports.NoToneMapping = NoToneMapping; 36468 exports.NormalAnimationBlendMode = NormalAnimationBlendMode; 36469 exports.NormalBlending = NormalBlending; 36470 exports.NotEqualDepth = NotEqualDepth; 36471 exports.NotEqualStencilFunc = NotEqualStencilFunc; 36472 exports.NumberKeyframeTrack = NumberKeyframeTrack; 36473 exports.Object3D = Object3D; 36474 exports.ObjectLoader = ObjectLoader; 36475 exports.ObjectSpaceNormalMap = ObjectSpaceNormalMap; 36476 exports.OctahedronBufferGeometry = OctahedronGeometry; 36477 exports.OctahedronGeometry = OctahedronGeometry; 36478 exports.OneFactor = OneFactor; 36479 exports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor; 36480 exports.OneMinusDstColorFactor = OneMinusDstColorFactor; 36481 exports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor; 36482 exports.OneMinusSrcColorFactor = OneMinusSrcColorFactor; 36483 exports.OrthographicCamera = OrthographicCamera; 36484 exports.PCFShadowMap = PCFShadowMap; 36485 exports.PCFSoftShadowMap = PCFSoftShadowMap; 36486 exports.PMREMGenerator = PMREMGenerator; 36487 exports.ParametricGeometry = ParametricGeometry; 36488 exports.Particle = Particle; 36489 exports.ParticleBasicMaterial = ParticleBasicMaterial; 36490 exports.ParticleSystem = ParticleSystem; 36491 exports.ParticleSystemMaterial = ParticleSystemMaterial; 36492 exports.Path = Path; 36493 exports.PerspectiveCamera = PerspectiveCamera; 36494 exports.Plane = Plane; 36495 exports.PlaneBufferGeometry = PlaneGeometry; 36496 exports.PlaneGeometry = PlaneGeometry; 36497 exports.PlaneHelper = PlaneHelper; 36498 exports.PointCloud = PointCloud; 36499 exports.PointCloudMaterial = PointCloudMaterial; 36500 exports.PointLight = PointLight; 36501 exports.PointLightHelper = PointLightHelper; 36502 exports.Points = Points; 36503 exports.PointsMaterial = PointsMaterial; 36504 exports.PolarGridHelper = PolarGridHelper; 36505 exports.PolyhedronBufferGeometry = PolyhedronGeometry; 36506 exports.PolyhedronGeometry = PolyhedronGeometry; 36507 exports.PositionalAudio = PositionalAudio; 36508 exports.PropertyBinding = PropertyBinding; 36509 exports.PropertyMixer = PropertyMixer; 36510 exports.QuadraticBezierCurve = QuadraticBezierCurve; 36511 exports.QuadraticBezierCurve3 = QuadraticBezierCurve3; 36512 exports.Quaternion = Quaternion; 36513 exports.QuaternionKeyframeTrack = QuaternionKeyframeTrack; 36514 exports.QuaternionLinearInterpolant = QuaternionLinearInterpolant; 36515 exports.REVISION = REVISION; 36516 exports.RGBADepthPacking = RGBADepthPacking; 36517 exports.RGBAFormat = RGBAFormat; 36518 exports.RGBAIntegerFormat = RGBAIntegerFormat; 36519 exports.RGBA_ASTC_10x10_Format = RGBA_ASTC_10x10_Format; 36520 exports.RGBA_ASTC_10x5_Format = RGBA_ASTC_10x5_Format; 36521 exports.RGBA_ASTC_10x6_Format = RGBA_ASTC_10x6_Format; 36522 exports.RGBA_ASTC_10x8_Format = RGBA_ASTC_10x8_Format; 36523 exports.RGBA_ASTC_12x10_Format = RGBA_ASTC_12x10_Format; 36524 exports.RGBA_ASTC_12x12_Format = RGBA_ASTC_12x12_Format; 36525 exports.RGBA_ASTC_4x4_Format = RGBA_ASTC_4x4_Format; 36526 exports.RGBA_ASTC_5x4_Format = RGBA_ASTC_5x4_Format; 36527 exports.RGBA_ASTC_5x5_Format = RGBA_ASTC_5x5_Format; 36528 exports.RGBA_ASTC_6x5_Format = RGBA_ASTC_6x5_Format; 36529 exports.RGBA_ASTC_6x6_Format = RGBA_ASTC_6x6_Format; 36530 exports.RGBA_ASTC_8x5_Format = RGBA_ASTC_8x5_Format; 36531 exports.RGBA_ASTC_8x6_Format = RGBA_ASTC_8x6_Format; 36532 exports.RGBA_ASTC_8x8_Format = RGBA_ASTC_8x8_Format; 36533 exports.RGBA_BPTC_Format = RGBA_BPTC_Format; 36534 exports.RGBA_ETC2_EAC_Format = RGBA_ETC2_EAC_Format; 36535 exports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format; 36536 exports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format; 36537 exports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format; 36538 exports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format; 36539 exports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format; 36540 exports.RGBFormat = RGBFormat; 36541 exports.RGBIntegerFormat = RGBIntegerFormat; 36542 exports.RGB_ETC1_Format = RGB_ETC1_Format; 36543 exports.RGB_ETC2_Format = RGB_ETC2_Format; 36544 exports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format; 36545 exports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format; 36546 exports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format; 36547 exports.RGFormat = RGFormat; 36548 exports.RGIntegerFormat = RGIntegerFormat; 36549 exports.RawShaderMaterial = RawShaderMaterial;
36550 exports.Ray = Ray; 36551 exports.Raycaster = Raycaster; 36552 exports.RectAreaLight = RectAreaLight; 36553 exports.RedFormat = RedFormat; 36554 exports.RedIntegerFormat = RedIntegerFormat; 36555 exports.ReinhardToneMapping = ReinhardToneMapping; 36556 exports.RepeatWrapping = RepeatWrapping; 36557 exports.ReplaceStencilOp = ReplaceStencilOp; 36558 exports.ReverseSubtractEquation = ReverseSubtractEquation; 36559 exports.RingBufferGeometry = RingGeometry; 36560 exports.RingGeometry = RingGeometry; 36561 exports.SRGB8_ALPHA8_ASTC_10x10_Format = SRGB8_ALPHA8_ASTC_10x10_Format; 36562 exports.SRGB8_ALPHA8_ASTC_10x5_Format = SRGB8_ALPHA8_ASTC_10x5_Format; 36563 exports.SRGB8_ALPHA8_ASTC_10x6_Format = SRGB8_ALPHA8_ASTC_10x6_Format; 36564 exports.SRGB8_ALPHA8_ASTC_10x8_Format = SRGB8_ALPHA8_ASTC_10x8_Format; 36565 exports.SRGB8_ALPHA8_ASTC_12x10_Format = SRGB8_ALPHA8_ASTC_12x10_Format; 36566 exports.SRGB8_ALPHA8_ASTC_12x12_Format = SRGB8_ALPHA8_ASTC_12x12_Format; 36567 exports.SRGB8_ALPHA8_ASTC_4x4_Format = SRGB8_ALPHA8_ASTC_4x4_Format; 36568 exports.SRGB8_ALPHA8_ASTC_5x4_Format = SRGB8_ALPHA8_ASTC_5x4_Format; 36569 exports.SRGB8_ALPHA8_ASTC_5x5_Format = SRGB8_ALPHA8_ASTC_5x5_Format; 36570 exports.SRGB8_ALPHA8_ASTC_6x5_Format = SRGB8_ALPHA8_ASTC_6x5_Format; 36571 exports.SRGB8_ALPHA8_ASTC_6x6_Format = SRGB8_ALPHA8_ASTC_6x6_Format; 36572 exports.SRGB8_ALPHA8_ASTC_8x5_Format = SRGB8_ALPHA8_ASTC_8x5_Format; 36573 exports.SRGB8_ALPHA8_ASTC_8x6_Format = SRGB8_ALPHA8_ASTC_8x6_Format; 36574 exports.SRGB8_ALPHA8_ASTC_8x8_Format = SRGB8_ALPHA8_ASTC_8x8_Format; 36575 exports.Scene = Scene; 36576 exports.SceneUtils = SceneUtils; 36577 exports.ShaderChunk = ShaderChunk; 36578 exports.ShaderLib = ShaderLib; 36579 exports.ShaderMaterial = ShaderMaterial; 36580 exports.ShadowMaterial = ShadowMaterial; 36581 exports.Shape = Shape; 36582 exports.ShapeBufferGeometry = ShapeGeometry; 36583 exports.ShapeGeometry = ShapeGeometry; 36584 exports.ShapePath = ShapePath; 36585 exports.ShapeUtils = ShapeUtils; 36586 exports.ShortType = ShortType; 36587 exports.Skeleton = Skeleton; 36588 exports.SkeletonHelper = SkeletonHelper; 36589 exports.SkinnedMesh = SkinnedMesh; 36590 exports.SmoothShading = SmoothShading; 36591 exports.Sphere = Sphere; 36592 exports.SphereBufferGeometry = SphereGeometry; 36593 exports.SphereGeometry = SphereGeometry; 36594 exports.Spherical = Spherical; 36595 exports.SphericalHarmonics3 = SphericalHarmonics3; 36596 exports.SplineCurve = SplineCurve; 36597 exports.SpotLight = SpotLight; 36598 exports.SpotLightHelper = SpotLightHelper; 36599 exports.Sprite = Sprite; 36600 exports.SpriteMaterial = SpriteMaterial; 36601 exports.SrcAlphaFactor = SrcAlphaFactor; 36602 exports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor; 36603 exports.SrcColorFactor = SrcColorFactor; 36604 exports.StaticCopyUsage = StaticCopyUsage; 36605 exports.StaticDrawUsage = StaticDrawUsage; 36606 exports.StaticReadUsage = StaticReadUsage; 36607 exports.StereoCamera = StereoCamera; 36608 exports.StreamCopyUsage = StreamCopyUsage; 36609 exports.StreamDrawUsage = StreamDrawUsage;
36610 exports.StreamReadUsage = StreamReadUsage; 36611 exports.StringKeyframeTrack = StringKeyframeTrack; 36612 exports.SubtractEquation = SubtractEquation; 36613 exports.SubtractiveBlending = SubtractiveBlending; 36614 exports.TOUCH = TOUCH; 36615 exports.TangentSpaceNormalMap = TangentSpaceNormalMap; 36616 exports.TetrahedronBufferGeometry = TetrahedronGeometry; 36617 exports.TetrahedronGeometry = TetrahedronGeometry; 36618 exports.TextGeometry = TextGeometry; 36619 exports.Texture = Texture; 36620 exports.TextureLoader = TextureLoader; 36621 exports.TorusBufferGeometry = TorusGeometry; 36622 exports.TorusGeometry = TorusGeometry; 36623 exports.TorusKnotBufferGeometry = TorusKnotGeometry; 36624 exports.TorusKnotGeometry = TorusKnotGeometry; 36625 exports.Triangle = Triangle; 36626 exports.TriangleFanDrawMode = TriangleFanDrawMode; 36627 exports.TriangleStripDrawMode = TriangleStripDrawMode; 36628 exports.TrianglesDrawMode = TrianglesDrawMode; 36629 exports.TubeBufferGeometry = TubeGeometry; 36630 exports.TubeGeometry = TubeGeometry; 36631 exports.UVMapping = UVMapping; 36632 exports.Uint16Attribute = Uint16Attribute; 36633 exports.Uint16BufferAttribute = Uint16BufferAttribute; 36634 exports.Uint32Attribute = Uint32Attribute; 36635 exports.Uint32BufferAttribute = Uint32BufferAttribute; 36636 exports.Uint8Attribute = Uint8Attribute; 36637 exports.Uint8BufferAttribute = Uint8BufferAttribute; 36638 exports.Uint8ClampedAttribute = Uint8ClampedAttribute; 36639 exports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute; 36640 exports.Uniform = Uniform; 36641 exports.UniformsLib = UniformsLib; 36642 exports.UniformsUtils = UniformsUtils; 36643 exports.UnsignedByteType = UnsignedByteType; 36644 exports.UnsignedInt248Type = UnsignedInt248Type; 36645 exports.UnsignedIntType = UnsignedIntType; 36646 exports.UnsignedShort4444Type = UnsignedShort4444Type; 36647 exports.UnsignedShort5551Type = UnsignedShort5551Type; 36648 exports.UnsignedShort565Type = UnsignedShort565Type; 36649 exports.UnsignedShortType = UnsignedShortType; 36650 exports.VSMShadowMap = VSMShadowMap; 36651 exports.Vector2 = Vector2; 36652 exports.Vector3 = Vector3; 36653 exports.Vector4 = Vector4; 36654 exports.VectorKeyframeTrack = VectorKeyframeTrack; 36655 exports.Vertex = Vertex; 36656 exports.VertexColors = VertexColors; 36657 exports.VideoTexture = VideoTexture; 36658 exports.WebGL1Renderer = WebGL1Renderer; 36659 exports.WebGLCubeRenderTarget = WebGLCubeRenderTarget; 36660 exports.WebGLMultipleRenderTargets = WebGLMultipleRenderTargets; 36661 exports.WebGLMultisampleRenderTarget = WebGLMultisampleRenderTarget; 36662 exports.WebGLRenderTarget = WebGLRenderTarget; 36663 exports.WebGLRenderTargetCube = WebGLRenderTargetCube; 36664 exports.WebGLRenderer = WebGLRenderer; 36665 exports.WebGLUtils = WebGLUtils; 36666 exports.WireframeGeometry = WireframeGeometry; 36667 exports.WireframeHelper = WireframeHelper; 36668 exports.WrapAroundEnding = WrapAroundEnding; 36669 exports.XHRLoader = XHRLoader; 36670 exports.ZeroCurvatureEnding = ZeroCurvatureEnding; 36671 exports.ZeroFactor = ZeroFactor; 36672 exports.ZeroSlopeEnding = ZeroSlopeEnding; 36673 exports.ZeroStencilOp = ZeroStencilOp; 36674 exports.sRGBEncoding = sRGBEncoding; 36675 36676 Object.defineProperty(exports, '__esModule', { value: true }); 36677 36678}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.