vendor: 38,373 bytes, lines 1-1258
1// node_modules/solid-js/dist/solid.js 2var sharedConfig = { 3 context: void 0, 4 registry: void 0, 5 effects: void 0, 6 done: false, 7 getContextId() { 8 return getContextId(this.context.count); 9 }, 10 getNextContextId() { 11 return getContextId(this.context.count++); 12 } 13}; 14function getContextId(count) { 15 const num = String(count), len = num.length - 1; 16 return sharedConfig.context.id + (len ? String.fromCharCode(96 + len) : "") + num; 17} 18function setHydrateContext(context) { 19 sharedConfig.context = context; 20} 21function nextHydrateContext() { 22 return { 23 ...sharedConfig.context, 24 id: sharedConfig.getNextContextId(), 25 count: 0 26 }; 27} 28var IS_DEV = false; 29var equalFn = (a, b) => a === b; 30var $PROXY = Symbol("solid-proxy"); 31var SUPPORTS_PROXY = typeof Proxy === "function"; 32var $TRACK = Symbol("solid-track"); 33var $DEVCOMP = Symbol("solid-dev-component"); 34var signalOptions = { 35 equals: equalFn 36}; 37var ERROR = null; 38var runEffects = runQueue; 39var STALE = 1; 40var PENDING = 2; 41var UNOWNED = { 42 owned: null, 43 cleanups: null, 44 context: null, 45 owner: null 46}; 47var NO_INIT = {}; 48var Owner = null; 49var Transition = null; 50var Scheduler = null; 51var ExternalSourceConfig = null; 52var Listener = null; 53var Updates = null; 54var Effects = null; 55var ExecCount = 0; 56function createRoot(fn, detachedOwner) { 57 const listener = Listener, owner = Owner, unowned = fn.length === 0, current = detachedOwner === void 0 ? owner : detachedOwner, root = unowned ? UNOWNED : { 58 owned: null, 59 cleanups: null, 60 context: current ? current.context : null, 61 owner: current 62 }, updateFn = unowned ? fn : () => fn(() => untrack(() => cleanNode(root))); 63 Owner = root; 64 Listener = null; 65 try { 66 return runUpdates(updateFn, true); 67 } finally { 68 Listener = listener; 69 Owner = owner; 70 } 71} 72function createSignal(value, options) { 73 options = options ? Object.assign({}, signalOptions, options) : signalOptions; 74 const s = { 75 value, 76 observers: null, 77 observerSlots: null, 78 comparator: options.equals || void 0 79 }; 80 const setter = (value2) => { 81 if (typeof value2 === "function") { 82 if (Transition && Transition.running && Transition.sources.has(s)) value2 = value2(s.tValue); 83 else value2 = value2(s.value); 84 } 85 return writeSignal(s, value2); 86 }; 87 return [readSignal.bind(s), setter]; 88} 89function createComputed(fn, value, options) { 90 const c = createComputation(fn, value, true, STALE); 91 if (Scheduler && Transition && Transition.running) Updates.push(c); 92 else updateComputation(c); 93} 94function createRenderEffect(fn, value, options) { 95 const c = createComputation(fn, value, false, STALE); 96 if (Scheduler && Transition && Transition.running) Updates.push(c); 97 else updateComputation(c); 98} 99function createEffect(fn, value, options) { 100 runEffects = runUserEffects; 101 const c = createComputation(fn, value, false, STALE), s = SuspenseContext && useContext(SuspenseContext); 102 if (s) c.suspense = s; 103 if (!options || !options.render) c.user = true; 104 Effects ? Effects.push(c) : updateComputation(c); 105} 106function createMemo(fn, value, options) { 107 options = options ? Object.assign({}, signalOptions, options) : signalOptions; 108 const c = createComputation(fn, value, true, 0); 109 c.observers = null; 110 c.observerSlots = null; 111 c.comparator = options.equals || void 0; 112 if (Scheduler && Transition && Transition.running) { 113 c.tState = STALE; 114 Updates.push(c); 115 } else updateComputation(c); 116 return readSignal.bind(c); 117} 118function isPromise(v) { 119 return v && typeof v === "object" && "then" in v; 120} 121function createResource(pSource, pFetcher, pOptions) { 122 let source; 123 let fetcher; 124 let options; 125 if (typeof pFetcher === "function") { 126 source = pSource; 127 fetcher = pFetcher; 128 options = pOptions || {}; 129 } else { 130 source = true; 131 fetcher = pSource; 132 options = pFetcher || {}; 133 } 134 let pr = null, initP = NO_INIT, id = null, loadedUnderTransition = false, scheduled = false, resolved = "initialValue" in options, dynamic = typeof source === "function" && createMemo(source); 135 const contexts = /* @__PURE__ */ new Set(), [value, setValue] = (options.storage || createSignal)(options.initialValue), [error2, setError] = createSignal(void 0), [track, trigger] = createSignal(void 0, { 136 equals: false 137 }), [state, setState] = createSignal(resolved ? "ready" : "unresolved"); 138 if (sharedConfig.context) { 139 id = sharedConfig.getNextContextId(); 140 if (options.ssrLoadFrom === "initial") initP = options.initialValue; 141 else if (sharedConfig.load && sharedConfig.has(id)) initP = sharedConfig.load(id); 142 } 143 function loadEnd(p, v, error3, key) { 144 if (pr === p) { 145 pr = null; 146 key !== void 0 && (resolved = true); 147 if ((p === initP || v === initP) && options.onHydrated) queueMicrotask(() => options.onHydrated(key, { 148 value: v 149 })); 150 initP = NO_INIT; 151 if (Transition && p && loadedUnderTransition) { 152 Transition.promises.delete(p); 153 loadedUnderTransition = false; 154 runUpdates(() => { 155 Transition.running = true; 156 completeLoad(v, error3); 157 }, false); 158 } else completeLoad(v, error3); 159 } 160 return v; 161 } 162 function completeLoad(v, err) { 163 runUpdates(() => { 164 if (err === void 0) setValue(() => v); 165 setState(err !== void 0 ? "errored" : resolved ? "ready" : "unresolved"); 166 setError(err); 167 for (const c of contexts.keys()) c.decrement(); 168 contexts.clear(); 169 }, false); 170 } 171 function read() { 172 const c = SuspenseContext && useContext(SuspenseContext), v = value(), err = error2(); 173 if (err !== void 0 && !pr) throw err; 174 if (Listener && !Listener.user && c) { 175 createComputed(() => { 176 track(); 177 if (pr) { 178 if (c.resolved && Transition && loadedUnderTransition) Transition.promises.add(pr); 179 else if (!contexts.has(c)) { 180 c.increment(); 181 contexts.add(c); 182 } 183 } 184 }); 185 } 186 return v; 187 } 188 function load(refetching = true) { 189 if (refetching !== false && scheduled) return; 190 scheduled = false; 191 const lookup = dynamic ? dynamic() : source; 192 loadedUnderTransition = Transition && Transition.running; 193 if (lookup == null || lookup === false) { 194 loadEnd(pr, untrack(value)); 195 return; 196 } 197 if (Transition && pr) Transition.promises.delete(pr); 198 let error3; 199 const p = initP !== NO_INIT ? initP : untrack(() => { 200 try { 201 return fetcher(lookup, { 202 value: value(), 203 refetching 204 }); 205 } catch (fetcherError) { 206 error3 = fetcherError; 207 } 208 }); 209 if (error3 !== void 0) { 210 loadEnd(pr, void 0, castError(error3), lookup); 211 return; 212 } else if (!isPromise(p)) { 213 loadEnd(pr, p, void 0, lookup); 214 return p; 215 } 216 pr = p; 217 if ("v" in p) { 218 if (p.s === 1) loadEnd(pr, p.v, void 0, lookup); 219 else loadEnd(pr, void 0, castError(p.v), lookup); 220 return p; 221 } 222 scheduled = true; 223 queueMicrotask(() => scheduled = false); 224 runUpdates(() => { 225 setState(resolved ? "refreshing" : "pending"); 226 trigger(); 227 }, false); 228 return p.then((v) => loadEnd(p, v, void 0, lookup), (e) => loadEnd(p, void 0, castError(e), lookup)); 229 } 230 Object.defineProperties(read, { 231 state: { 232 get: () => state() 233 }, 234 error: { 235 get: () => error2() 236 }, 237 loading: { 238 get() { 239 const s = state(); 240 return s === "pending" || s === "refreshing"; 241 } 242 }, 243 latest: { 244 get() { 245 if (!resolved) return read(); 246 const err = error2(); 247 if (err && !pr) throw err; 248 return value(); 249 } 250 } 251 }); 252 let owner = Owner; 253 if (dynamic) createComputed(() => (owner = Owner, load(false))); 254 else load(false); 255 return [read, { 256 refetch: (info) => runWithOwner(owner, () => load(info)), 257 mutate: setValue 258 }]; 259} 260function batch(fn) { 261 return runUpdates(fn, false); 262} 263function untrack(fn) { 264 if (!ExternalSourceConfig && Listener === null) return fn(); 265 const listener = Listener; 266 Listener = null; 267 try { 268 if (ExternalSourceConfig) return ExternalSourceConfig.untrack(fn); 269 return fn(); 270 } finally { 271 Listener = listener; 272 } 273} 274function on(deps, fn, options) { 275 const isArray = Array.isArray(deps); 276 let prevInput; 277 let defer = options && options.defer; 278 return (prevValue) => { 279 let input; 280 if (isArray) { 281 input = Array(deps.length); 282 for (let i = 0; i < deps.length; i++) input[i] = deps[i](); 283 } else input = deps(); 284 if (defer) { 285 defer = false; 286 return prevValue; 287 } 288 const result = untrack(() => fn(input, prevInput, prevValue)); 289 prevInput = input; 290 return result; 291 }; 292} 293function onMount(fn) { 294 createEffect(() => untrack(fn)); 295} 296function onCleanup(fn) { 297 if (Owner === null) ; 298 else if (Owner.cleanups === null) Owner.cleanups = [fn]; 299 else Owner.cleanups.push(fn); 300 return fn; 301} 302function catchError(fn, handler) { 303 ERROR || (ERROR = Symbol("error")); 304 Owner = createComputation(void 0, void 0, true); 305 Owner.context = { 306 ...Owner.context, 307 [ERROR]: [handler] 308 }; 309 if (Transition && Transition.running) Transition.sources.add(Owner); 310 try { 311 return fn(); 312 } catch (err) { 313 handleError(err); 314 } finally { 315 Owner = Owner.owner; 316 } 317} 318function getListener() { 319 return Listener; 320} 321function getOwner() { 322 return Owner; 323} 324function runWithOwner(o, fn) { 325 const prev = Owner; 326 const prevListener = Listener; 327 Owner = o; 328 Listener = null; 329 try { 330 return runUpdates(fn, true); 331 } catch (err) { 332 handleError(err); 333 } finally { 334 Owner = prev; 335 Listener = prevListener; 336 } 337} 338function startTransition(fn) { 339 if (Transition && Transition.running) { 340 fn(); 341 return Transition.done; 342 } 343 const l = Listener; 344 const o = Owner; 345 return Promise.resolve().then(() => { 346 Listener = l; 347 Owner = o; 348 let t; 349 if (Scheduler || SuspenseContext) { 350 t = Transition || (Transition = { 351 sources: /* @__PURE__ */ new Set(), 352 effects: [], 353 promises: /* @__PURE__ */ new Set(), 354 disposed: /* @__PURE__ */ new Set(), 355 queue: /* @__PURE__ */ new Set(), 356 running: true 357 }); 358 t.done || (t.done = new Promise((res) => t.resolve = res)); 359 t.running = true; 360 } 361 runUpdates(fn, false); 362 Listener = Owner = null; 363 return t ? t.done : void 0; 364 }); 365} 366var [transPending, setTransPending] = /* @__PURE__ */ createSignal(false); 367function resumeEffects(e) { 368 Effects.push.apply(Effects, e); 369 e.length = 0; 370} 371function createContext(defaultValue, options) { 372 const id = Symbol("context"); 373 return { 374 id, 375 Provider: createProvider(id), 376 defaultValue 377 }; 378} 379function useContext(context) { 380 let value; 381 return Owner && Owner.context && (value = Owner.context[context.id]) !== void 0 ? value : context.defaultValue; 382} 383function children(fn) { 384 const children2 = createMemo(fn); 385 const memo2 = createMemo(() => resolveChildren(children2())); 386 memo2.toArray = () => { 387 const c = memo2(); 388 return Array.isArray(c) ? c : c != null ? [c] : []; 389 }; 390 return memo2; 391} 392var SuspenseContext; 393function getSuspenseContext() { 394 return SuspenseContext || (SuspenseContext = createContext()); 395} 396function readSignal() { 397 const runningTransition = Transition && Transition.running; 398 if (this.sources && (runningTransition ? this.tState : this.state)) { 399 if ((runningTransition ? this.tState : this.state) === STALE) updateComputation(this); 400 else { 401 const updates = Updates; 402 Updates = null; 403 runUpdates(() => lookUpstream(this), false); 404 Updates = updates; 405 } 406 } 407 if (Listener) { 408 const sSlot = this.observers ? this.observers.length : 0; 409 if (!Listener.sources) { 410 Listener.sources = [this]; 411 Listener.sourceSlots = [sSlot]; 412 } else { 413 Listener.sources.push(this); 414 Listener.sourceSlots.push(sSlot); 415 } 416 if (!this.observers) { 417 this.observers = [Listener]; 418 this.observerSlots = [Listener.sources.length - 1]; 419 } else { 420 this.observers.push(Listener); 421 this.observerSlots.push(Listener.sources.length - 1); 422 } 423 } 424 if (runningTransition && Transition.sources.has(this)) return this.tValue; 425 return this.value; 426} 427function writeSignal(node, value, isComp) { 428 let current = Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value; 429 if (!node.comparator || !node.comparator(current, value)) { 430 if (Transition) { 431 const TransitionRunning = Transition.running; 432 if (TransitionRunning || !isComp && Transition.sources.has(node)) { 433 Transition.sources.add(node); 434 node.tValue = value; 435 } 436 if (!TransitionRunning) node.value = value; 437 } else node.value = value; 438 if (node.observers && node.observers.length) { 439 runUpdates(() => { 440 for (let i = 0; i < node.observers.length; i += 1) { 441 const o = node.observers[i]; 442 const TransitionRunning = Transition && Transition.running; 443 if (TransitionRunning && Transition.disposed.has(o)) continue; 444 if (TransitionRunning ? !o.tState : !o.state) { 445 if (o.pure) Updates.push(o); 446 else Effects.push(o); 447 if (o.observers) markDownstream(o); 448 } 449 if (!TransitionRunning) o.state = STALE; 450 else o.tState = STALE; 451 } 452 if (Updates.length > 1e6) { 453 Updates = []; 454 if (IS_DEV) ; 455 throw new Error(); 456 } 457 }, false); 458 } 459 } 460 return value; 461} 462function updateComputation(node) { 463 if (!node.fn) return; 464 cleanNode(node); 465 const time = ExecCount; 466 runComputation(node, Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value, time); 467 if (Transition && !Transition.running && Transition.sources.has(node)) { 468 queueMicrotask(() => { 469 runUpdates(() => { 470 Transition && (Transition.running = true); 471 Listener = Owner = node; 472 runComputation(node, node.tValue, time); 473 Listener = Owner = null; 474 }, false); 475 }); 476 } 477} 478function runComputation(node, value, time) { 479 let nextValue; 480 const owner = Owner, listener = Listener; 481 Listener = Owner = node; 482 try { 483 nextValue = node.fn(value); 484 } catch (err) { 485 if (node.pure) { 486 if (Transition && Transition.running) { 487 node.tState = STALE; 488 node.tOwned && node.tOwned.forEach(cleanNode); 489 node.tOwned = void 0; 490 } else { 491 node.state = STALE; 492 node.owned && node.owned.forEach(cleanNode); 493 node.owned = null; 494 } 495 } 496 node.updatedAt = time + 1; 497 return handleError(err); 498 } finally { 499 Listener = listener; 500 Owner = owner; 501 } 502 if (!node.updatedAt || node.updatedAt <= time) { 503 if (node.updatedAt != null && "observers" in node) { 504 writeSignal(node, nextValue, true); 505 } else if (Transition && Transition.running && node.pure) { 506 Transition.sources.add(node); 507 node.tValue = nextValue; 508 } else node.value = nextValue; 509 node.updatedAt = time; 510 } 511} 512function createComputation(fn, init, pure, state = STALE, options) { 513 const c = { 514 fn, 515 state, 516 updatedAt: null, 517 owned: null, 518 sources: null, 519 sourceSlots: null, 520 cleanups: null, 521 value: init, 522 owner: Owner, 523 context: Owner ? Owner.context : null, 524 pure 525 }; 526 if (Transition && Transition.running) { 527 c.state = 0; 528 c.tState = state; 529 } 530 if (Owner === null) ; 531 else if (Owner !== UNOWNED) { 532 if (Transition && Transition.running && Owner.pure) { 533 if (!Owner.tOwned) Owner.tOwned = [c]; 534 else Owner.tOwned.push(c); 535 } else { 536 if (!Owner.owned) Owner.owned = [c]; 537 else Owner.owned.push(c); 538 } 539 } 540 if (ExternalSourceConfig && c.fn) { 541 const [track, trigger] = createSignal(void 0, { 542 equals: false 543 }); 544 const ordinary = ExternalSourceConfig.factory(c.fn, trigger); 545 onCleanup(() => ordinary.dispose()); 546 const triggerInTransition = () => startTransition(trigger).then(() => inTransition.dispose()); 547 const inTransition = ExternalSourceConfig.factory(c.fn, triggerInTransition); 548 c.fn = (x) => { 549 track(); 550 return Transition && Transition.running ? inTransition.track(x) : ordinary.track(x); 551 }; 552 } 553 return c; 554} 555function runTop(node) { 556 const runningTransition = Transition && Transition.running; 557 if ((runningTransition ? node.tState : node.state) === 0) return; 558 if ((runningTransition ? node.tState : node.state) === PENDING) return lookUpstream(node); 559 if (node.suspense && untrack(node.suspense.inFallback)) return node.suspense.effects.push(node); 560 const ancestors = [node]; 561 while ((node = node.owner) && (!node.updatedAt || node.updatedAt < ExecCount)) { 562 if (runningTransition && Transition.disposed.has(node)) return; 563 if (runningTransition ? node.tState : node.state) ancestors.push(node); 564 } 565 for (let i = ancestors.length - 1; i >= 0; i--) { 566 node = ancestors[i]; 567 if (runningTransition) { 568 let top = node, prev = ancestors[i + 1]; 569 while ((top = top.owner) && top !== prev) { 570 if (Transition.disposed.has(top)) return; 571 } 572 } 573 if ((runningTransition ? node.tState : node.state) === STALE) { 574 updateComputation(node); 575 } else if ((runningTransition ? node.tState : node.state) === PENDING) { 576 const updates = Updates; 577 Updates = null; 578 runUpdates(() => lookUpstream(node, ancestors[0]), false); 579 Updates = updates; 580 } 581 } 582} 583function runUpdates(fn, init) { 584 if (Updates) return fn(); 585 let wait = false; 586 if (!init) Updates = []; 587 if (Effects) wait = true; 588 else Effects = []; 589 ExecCount++; 590 try { 591 const res = fn(); 592 completeUpdates(wait); 593 return res; 594 } catch (err) { 595 if (!wait) Effects = null; 596 Updates = null; 597 handleError(err); 598 } 599} 600function completeUpdates(wait) { 601 if (Updates) { 602 if (Scheduler && Transition && Transition.running) scheduleQueue(Updates); 603 else runQueue(Updates); 604 Updates = null; 605 } 606 if (wait) return; 607 let res; 608 if (Transition) { 609 if (!Transition.promises.size && !Transition.queue.size) { 610 const sources = Transition.sources; 611 const disposed = Transition.disposed; 612 Effects.push.apply(Effects, Transition.effects); 613 res = Transition.resolve; 614 for (const e2 of Effects) { 615 "tState" in e2 && (e2.state = e2.tState); 616 delete e2.tState; 617 } 618 Transition = null; 619 runUpdates(() => { 620 for (const d of disposed) cleanNode(d); 621 for (const v of sources) { 622 v.value = v.tValue; 623 if (v.owned) { 624 for (let i = 0, len = v.owned.length; i < len; i++) cleanNode(v.owned[i]); 625 } 626 if (v.tOwned) v.owned = v.tOwned; 627 delete v.tValue; 628 delete v.tOwned; 629 v.tState = 0; 630 } 631 setTransPending(false); 632 }, false); 633 } else if (Transition.running) { 634 Transition.running = false; 635 Transition.effects.push.apply(Transition.effects, Effects); 636 Effects = null; 637 setTransPending(true); 638 return; 639 } 640 } 641 const e = Effects; 642 Effects = null; 643 if (e.length) runUpdates(() => runEffects(e), false); 644 if (res) res(); 645} 646function runQueue(queue) { 647 for (let i = 0; i < queue.length; i++) runTop(queue[i]); 648} 649function scheduleQueue(queue) { 650 for (let i = 0; i < queue.length; i++) { 651 const item = queue[i]; 652 const tasks = Transition.queue; 653 if (!tasks.has(item)) { 654 tasks.add(item); 655 Scheduler(() => { 656 tasks.delete(item); 657 runUpdates(() => { 658 Transition.running = true; 659 runTop(item); 660 }, false); 661 Transition && (Transition.running = false); 662 }); 663 } 664 } 665} 666function runUserEffects(queue) { 667 let i, userLength = 0; 668 for (i = 0; i < queue.length; i++) { 669 const e = queue[i]; 670 if (!e.user) runTop(e); 671 else queue[userLength++] = e; 672 } 673 if (sharedConfig.context) { 674 if (sharedConfig.count) { 675 sharedConfig.effects || (sharedConfig.effects = []); 676 sharedConfig.effects.push(...queue.slice(0, userLength)); 677 return; 678 } 679 setHydrateContext(); 680 } 681 if (sharedConfig.effects && (sharedConfig.done || !sharedConfig.count)) { 682 queue = [...sharedConfig.effects, ...queue]; 683 userLength += sharedConfig.effects.length; 684 delete sharedConfig.effects; 685 } 686 for (i = 0; i < userLength; i++) runTop(queue[i]); 687} 688function lookUpstream(node, ignore) { 689 const runningTransition = Transition && Transition.running; 690 if (runningTransition) node.tState = 0; 691 else node.state = 0; 692 for (let i = 0; i < node.sources.length; i += 1) { 693 const source = node.sources[i]; 694 if (source.sources) { 695 const state = runningTransition ? source.tState : source.state; 696 if (state === STALE) { 697 if (source !== ignore && (!source.updatedAt || source.updatedAt < ExecCount)) runTop(source); 698 } else if (state === PENDING) lookUpstream(source, ignore); 699 } 700 } 701} 702function markDownstream(node) { 703 const runningTransition = Transition && Transition.running; 704 for (let i = 0; i < node.observers.length; i += 1) { 705 const o = node.observers[i]; 706 if (runningTransition ? !o.tState : !o.state) { 707 if (runningTransition) o.tState = PENDING; 708 else o.state = PENDING; 709 if (o.pure) Updates.push(o); 710 else Effects.push(o); 711 o.observers && markDownstream(o); 712 } 713 } 714} 715function cleanNode(node) { 716 let i; 717 if (node.sources) { 718 while (node.sources.length) { 719 const source = node.sources.pop(), index = node.sourceSlots.pop(), obs = source.observers; 720 if (obs && obs.length) { 721 const n = obs.pop(), s = source.observerSlots.pop(); 722 if (index < obs.length) { 723 n.sourceSlots[s] = index; 724 obs[index] = n; 725 source.observerSlots[index] = s; 726 } 727 } 728 } 729 } 730 if (node.tOwned) { 731 for (i = node.tOwned.length - 1; i >= 0; i--) cleanNode(node.tOwned[i]); 732 delete node.tOwned; 733 } 734 if (Transition && Transition.running && node.pure) { 735 reset(node, true); 736 } else if (node.owned) { 737 for (i = node.owned.length - 1; i >= 0; i--) cleanNode(node.owned[i]); 738 node.owned = null; 739 } 740 if (node.cleanups) { 741 for (i = node.cleanups.length - 1; i >= 0; i--) node.cleanups[i](); 742 node.cleanups = null; 743 } 744 if (Transition && Transition.running) node.tState = 0; 745 else node.state = 0; 746} 747function reset(node, top) { 748 if (!top) { 749 node.tState = 0; 750 Transition.disposed.add(node); 751 } 752 if (node.owned) { 753 for (let i = 0; i < node.owned.length; i++) reset(node.owned[i]); 754 } 755} 756function castError(err) { 757 if (err instanceof Error) return err; 758 return new Error(typeof err === "string" ? err : "Unknown error", { 759 cause: err 760 }); 761} 762function runErrors(err, fns, owner) { 763 try { 764 for (const f of fns) f(err); 765 } catch (e) { 766 handleError(e, owner && owner.owner || null); 767 } 768} 769function handleError(err, owner = Owner) { 770 const fns = ERROR && owner && owner.context && owner.context[ERROR]; 771 const error2 = castError(err); 772 if (!fns) throw error2; 773 if (Effects) Effects.push({ 774 fn() { 775 runErrors(error2, fns, owner); 776 }, 777 state: STALE 778 }); 779 else runErrors(error2, fns, owner); 780} 781function resolveChildren(children2) { 782 if (typeof children2 === "function" && !children2.length) return resolveChildren(children2()); 783 if (Array.isArray(children2)) { 784 const results = []; 785 for (let i = 0; i < children2.length; i++) { 786 const result = resolveChildren(children2[i]); 787 Array.isArray(result) ? results.push.apply(results, result) : results.push(result); 788 } 789 return results; 790 } 791 return children2; 792} 793function createProvider(id, options) { 794 return function provider(props) { 795 let res; 796 createRenderEffect(() => res = untrack(() => { 797 Owner.context = { 798 ...Owner.context, 799 [id]: props.value 800 }; 801 return children(() => props.children); 802 }), void 0); 803 return res; 804 }; 805} 806var FALLBACK = Symbol("fallback"); 807function dispose(d) { 808 for (let i = 0; i < d.length; i++) d[i](); 809} 810function mapArray(list, mapFn, options = {}) { 811 let items = [], mapped = [], disposers = [], len = 0, indexes = mapFn.length > 1 ? [] : null; 812 onCleanup(() => dispose(disposers)); 813 return () => { 814 let newItems = list() || [], newLen = newItems.length, i, j; 815 newItems[$TRACK]; 816 return untrack(() => { 817 let newIndices, newIndicesNext, temp, tempdisposers, tempIndexes, start, end, newEnd, item; 818 if (newLen === 0) { 819 if (len !== 0) { 820 dispose(disposers); 821 disposers = []; 822 items = []; 823 mapped = []; 824 len = 0; 825 indexes && (indexes = []); 826 } 827 if (options.fallback) { 828 items = [FALLBACK]; 829 mapped[0] = createRoot((disposer) => { 830 disposers[0] = disposer; 831 return options.fallback(); 832 }); 833 len = 1; 834 } 835 } else if (len === 0) { 836 mapped = new Array(newLen); 837 for (j = 0; j < newLen; j++) { 838 items[j] = newItems[j]; 839 mapped[j] = createRoot(mapper); 840 } 841 len = newLen; 842 } else { 843 temp = new Array(newLen); 844 tempdisposers = new Array(newLen); 845 indexes && (tempIndexes = new Array(newLen)); 846 for (start = 0, end = Math.min(len, newLen); start < end && items[start] === newItems[start]; start++) ; 847 for (end = len - 1, newEnd = newLen - 1; end >= start && newEnd >= start && items[end] === newItems[newEnd]; end--, newEnd--) { 848 temp[newEnd] = mapped[end]; 849 tempdisposers[newEnd] = disposers[end]; 850 indexes && (tempIndexes[newEnd] = indexes[end]); 851 } 852 newIndices = /* @__PURE__ */ new Map(); 853 newIndicesNext = new Array(newEnd + 1); 854 for (j = newEnd; j >= start; j--) { 855 item = newItems[j]; 856 i = newIndices.get(item); 857 newIndicesNext[j] = i === void 0 ? -1 : i; 858 newIndices.set(item, j); 859 } 860 for (i = start; i <= end; i++) { 861 item = items[i]; 862 j = newIndices.get(item); 863 if (j !== void 0 && j !== -1) { 864 temp[j] = mapped[i]; 865 tempdisposers[j] = disposers[i]; 866 indexes && (tempIndexes[j] = indexes[i]); 867 j = newIndicesNext[j]; 868 newIndices.set(item, j); 869 } else disposers[i](); 870 } 871 for (j = start; j < newLen; j++) { 872 if (j in temp) { 873 mapped[j] = temp[j]; 874 disposers[j] = tempdisposers[j]; 875 if (indexes) { 876 indexes[j] = tempIndexes[j]; 877 indexes[j](j); 878 } 879 } else mapped[j] = createRoot(mapper); 880 } 881 mapped = mapped.slice(0, len = newLen); 882 items = newItems.slice(0); 883 } 884 return mapped; 885 }); 886 function mapper(disposer) { 887 disposers[j] = disposer; 888 if (indexes) { 889 const [s, set] = createSignal(j); 890 indexes[j] = set; 891 return mapFn(newItems[j], s); 892 } 893 return mapFn(newItems[j]); 894 } 895 }; 896} 897var hydrationEnabled = false; 898function createComponent(Comp, props) { 899 if (hydrationEnabled) { 900 if (sharedConfig.context) { 901 const c = sharedConfig.context; 902 setHydrateContext(nextHydrateContext()); 903 const r = untrack(() => Comp(props || {})); 904 setHydrateContext(c); 905 return r; 906 } 907 } 908 return untrack(() => Comp(props || {})); 909} 910function trueFn() { 911 return true; 912} 913var propTraps = { 914 get(_, property, receiver) { 915 if (property === $PROXY) return receiver; 916 return _.get(property); 917 }, 918 has(_, property) { 919 if (property === $PROXY) return true; 920 return _.has(property); 921 }, 922 set: trueFn, 923 deleteProperty: trueFn, 924 getOwnPropertyDescriptor(_, property) { 925 return { 926 configurable: true, 927 enumerable: true, 928 get() { 929 return _.get(property); 930 }, 931 set: trueFn, 932 deleteProperty: trueFn 933 }; 934 }, 935 ownKeys(_) { 936 return _.keys(); 937 } 938}; 939function resolveSource(s) { 940 return !(s = typeof s === "function" ? s() : s) ? {} : s; 941} 942function resolveSources() { 943 for (let i = 0, length = this.length; i < length; ++i) { 944 const v = this[i](); 945 if (v !== void 0) return v; 946 } 947} 948function mergeProps(...sources) { 949 let proxy = false; 950 for (let i = 0; i < sources.length; i++) { 951 const s = sources[i]; 952 proxy = proxy || !!s && $PROXY in s; 953 sources[i] = typeof s === "function" ? (proxy = true, createMemo(s)) : s; 954 } 955 if (SUPPORTS_PROXY && proxy) { 956 return new Proxy({ 957 get(property) { 958 for (let i = sources.length - 1; i >= 0; i--) { 959 const v = resolveSource(sources[i])[property]; 960 if (v !== void 0) return v; 961 } 962 }, 963 has(property) { 964 for (let i = sources.length - 1; i >= 0; i--) { 965 if (property in resolveSource(sources[i])) return true; 966 } 967 return false; 968 }, 969 keys() { 970 const keys = []; 971 for (let i = 0; i < sources.length; i++) keys.push(...Object.keys(resolveSource(sources[i]))); 972 return [...new Set(keys)]; 973 } 974 }, propTraps); 975 } 976 const sourcesMap = {}; 977 const defined = /* @__PURE__ */ Object.create(null); 978 for (let i = sources.length - 1; i >= 0; i--) { 979 const source = sources[i]; 980 if (!source) continue; 981 const sourceKeys = Object.getOwnPropertyNames(source); 982 for (let i2 = sourceKeys.length - 1; i2 >= 0; i2--) { 983 const key = sourceKeys[i2]; 984 if (key === "__proto__" || key === "constructor") continue; 985 const desc = Object.getOwnPropertyDescriptor(source, key); 986 if (!defined[key]) { 987 defined[key] = desc.get ? { 988 enumerable: true, 989 configurable: true, 990 get: resolveSources.bind(sourcesMap[key] = [desc.get.bind(source)]) 991 } : desc.value !== void 0 ? desc : void 0; 992 } else { 993 const sources2 = sourcesMap[key]; 994 if (sources2) { 995 if (desc.get) sources2.push(desc.get.bind(source)); 996 else if (desc.value !== void 0) sources2.push(() => desc.value); 997 } 998 } 999 } 1000 } 1001 const target = {}; 1002 const definedKeys = Object.keys(defined); 1003 for (let i = definedKeys.length - 1; i >= 0; i--) { 1004 const key = definedKeys[i], desc = defined[key]; 1005 if (desc && desc.get) Object.defineProperty(target, key, desc); 1006 else target[key] = desc ? desc.value : void 0; 1007 } 1008 return target; 1009} 1010function splitProps(props, ...keys) { 1011 const len = keys.length; 1012 if (SUPPORTS_PROXY && $PROXY in props) { 1013 const blocked = len > 1 ? keys.flat() : keys[0]; 1014 const res = keys.map((k) => { 1015 return new Proxy({ 1016 get(property) { 1017 return k.includes(property) ? props[property] : void 0; 1018 }, 1019 has(property) { 1020 return k.includes(property) && property in props; 1021 }, 1022 keys() { 1023 return k.filter((property) => property in props); 1024 } 1025 }, propTraps); 1026 }); 1027 res.push(new Proxy({ 1028 get(property) { 1029 return blocked.includes(property) ? void 0 : props[property]; 1030 }, 1031 has(property) { 1032 return blocked.includes(property) ? false : property in props; 1033 }, 1034 keys() { 1035 return Object.keys(props).filter((k) => !blocked.includes(k)); 1036 } 1037 }, propTraps)); 1038 return res; 1039 } 1040 const objects = []; 1041 for (let i = 0; i <= len; i++) { 1042 objects[i] = {}; 1043 } 1044 for (const propName of Object.getOwnPropertyNames(props)) { 1045 let keyIndex = len; 1046 for (let i = 0; i < keys.length; i++) { 1047 if (keys[i].includes(propName)) { 1048 keyIndex = i; 1049 break; 1050 } 1051 } 1052 const desc = Object.getOwnPropertyDescriptor(props, propName); 1053 const isDefaultDesc = !desc.get && !desc.set && desc.enumerable && desc.writable && desc.configurable; 1054 isDefaultDesc ? objects[keyIndex][propName] = desc.value : Object.defineProperty(objects[keyIndex], propName, desc); 1055 } 1056 return objects; 1057} 1058function lazy(fn) { 1059 let comp; 1060 let p; 1061 const wrap = (props) => { 1062 const ctx = sharedConfig.context; 1063 if (ctx) { 1064 const [s, set] = createSignal(); 1065 sharedConfig.count || (sharedConfig.count = 0); 1066 sharedConfig.count++; 1067 (p || (p = fn())).then((mod) => { 1068 !sharedConfig.done && setHydrateContext(ctx); 1069 sharedConfig.count--; 1070 set(() => mod.default); 1071 setHydrateContext(); 1072 }); 1073 comp = s; 1074 } else if (!comp) { 1075 const [s] = createResource(() => (p || (p = fn())).then((mod) => mod.default)); 1076 comp = s; 1077 } 1078 let Comp; 1079 return createMemo(() => (Comp = comp()) ? untrack(() => { 1080 if (IS_DEV) ; 1081 if (!ctx || sharedConfig.done) return Comp(props); 1082 const c = sharedConfig.context; 1083 setHydrateContext(ctx); 1084 const r = Comp(props); 1085 setHydrateContext(c); 1086 return r; 1087 }) : ""); 1088 }; 1089 wrap.preload = () => p || ((p = fn()).then((mod) => comp = () => mod.default), p); 1090 return wrap; 1091} 1092var counter = 0; 1093function createUniqueId() { 1094 const ctx = sharedConfig.context; 1095 return ctx ? sharedConfig.getNextContextId() : `cl-${counter++}`; 1096} 1097var narrowedError = (name) => `Stale read from <${name}>.`; 1098function For(props) { 1099 const fallback = "fallback" in props && { 1100 fallback: () => props.fallback 1101 }; 1102 return createMemo(mapArray(() => props.each, props.children, fallback || void 0)); 1103} 1104function Show(props) { 1105 const keyed = props.keyed; 1106 const conditionValue = createMemo(() => props.when, void 0, void 0); 1107 const condition = keyed ? conditionValue : createMemo(conditionValue, void 0, { 1108 equals: (a, b) => !a === !b 1109 }); 1110 return createMemo(() => { 1111 const c = condition(); 1112 if (c) { 1113 const child = props.children; 1114 const fn = typeof child === "function" && child.length > 0; 1115 return fn ? untrack(() => child(keyed ? c : () => { 1116 if (!untrack(condition)) throw narrowedError("Show"); 1117 return conditionValue(); 1118 })) : child; 1119 } 1120 return props.fallback; 1121 }, void 0, void 0); 1122} 1123function Switch(props) { 1124 const chs = children(() => props.children); 1125 const switchFunc = createMemo(() => { 1126 const ch = chs(); 1127 const mps = Array.isArray(ch) ? ch : [ch]; 1128 let func = () => void 0; 1129 for (let i = 0; i < mps.length; i++) { 1130 const index = i; 1131 const mp = mps[i]; 1132 const prevFunc = func; 1133 const conditionValue = createMemo(() => prevFunc() ? void 0 : mp.when, void 0, void 0); 1134 const condition = mp.keyed ? conditionValue : createMemo(conditionValue, void 0, { 1135 equals: (a, b) => !a === !b 1136 }); 1137 func = () => prevFunc() || (condition() ? [index, conditionValue, mp] : void 0); 1138 } 1139 return func; 1140 }); 1141 return createMemo(() => { 1142 const sel = switchFunc()(); 1143 if (!sel) return props.fallback; 1144 const [index, conditionValue, mp] = sel; 1145 const child = mp.children; 1146 const fn = typeof child === "function" && child.length > 0; 1147 return fn ? untrack(() => child(mp.keyed ? conditionValue() : () => { 1148 if (untrack(switchFunc)()?.[0] !== index) throw narrowedError("Match"); 1149 return conditionValue(); 1150 })) : child; 1151 }, void 0, void 0); 1152} 1153function Match(props) { 1154 return props; 1155} 1156var Errors; 1157function ErrorBoundary(props) { 1158 let err; 1159 if (sharedConfig.context && sharedConfig.load) err = sharedConfig.load(sharedConfig.getContextId()); 1160 const [errored, setErrored] = createSignal(err, void 0); 1161 Errors || (Errors = /* @__PURE__ */ new Set()); 1162 Errors.add(setErrored); 1163 onCleanup(() => Errors.delete(setErrored)); 1164 return createMemo(() => { 1165 let e; 1166 if (e = errored()) { 1167 const f = props.fallback; 1168 return typeof f === "function" && f.length ? untrack(() => f(e, () => setErrored())) : f; 1169 } 1170 return catchError(() => props.children, setErrored); 1171 }, void 0, void 0); 1172} 1173var SuspenseListContext = /* @__PURE__ */ createContext(); 1174function Suspense(props) { 1175 let counter2 = 0, show, ctx, p, flicker, error2; 1176 const [inFallback, setFallback] = createSignal(false), SuspenseContext2 = getSuspenseContext(), store = { 1177 increment: () => { 1178 if (++counter2 === 1) setFallback(true); 1179 }, 1180 decrement: () => { 1181 if (--counter2 === 0) setFallback(false); 1182 }, 1183 inFallback, 1184 effects: [], 1185 resolved: false 1186 }, owner = getOwner(); 1187 if (sharedConfig.context && sharedConfig.load) { 1188 const key = sharedConfig.getContextId(); 1189 let ref = sharedConfig.load(key); 1190 if (ref) { 1191 if (typeof ref !== "object" || ref.s !== 1) p = ref; 1192 else sharedConfig.gather(key); 1193 } 1194 if (p && p !== "$$f") { 1195 const [s, set] = createSignal(void 0, { 1196 equals: false 1197 }); 1198 flicker = s; 1199 p.then(() => { 1200 if (sharedConfig.done) return set(); 1201 sharedConfig.gather(key); 1202 setHydrateContext(ctx); 1203 set(); 1204 setHydrateContext(); 1205 }, (err) => { 1206 error2 = err; 1207 set(); 1208 }); 1209 } 1210 } 1211 const listContext = useContext(SuspenseListContext); 1212 if (listContext) show = listContext.register(store.inFallback); 1213 let dispose2; 1214 onCleanup(() => dispose2 && dispose2()); 1215 return createComponent(SuspenseContext2.Provider, { 1216 value: store, 1217 get children() { 1218 return createMemo(() => { 1219 if (error2) throw error2; 1220 ctx = sharedConfig.context; 1221 if (flicker) { 1222 flicker(); 1223 return flicker = void 0; 1224 } 1225 if (ctx && p === "$$f") setHydrateContext(); 1226 const rendered = createMemo(() => props.children); 1227 return createMemo((prev) => { 1228 const inFallback2 = store.inFallback(), { 1229 showContent = true, 1230 showFallback = true 1231 } = show ? show() : {}; 1232 if ((!inFallback2 || p && p !== "$$f") && showContent) { 1233 store.resolved = true; 1234 dispose2 && dispose2(); 1235 dispose2 = ctx = p = void 0; 1236 resumeEffects(store.effects); 1237 return rendered(); 1238 } 1239 if (!showFallback) return; 1240 if (dispose2) return prev; 1241 return createRoot((disposer) => { 1242 dispose2 = disposer; 1243 if (ctx) { 1244 setHydrateContext({ 1245 id: ctx.id + "F", 1246 count: 0 1247 }); 1248 ctx = void 0; 1249 } 1250 return props.fallback; 1251 }, owner); 1252 }); 1253 }); 1254 } 1255 }); 1256} 1257var DEV = void 0; 1258
vendor: 23,256 bytes, lines 1259-1999
1259// node_modules/solid-js/web/dist/web.js 1260var booleans = [ 1261 "allowfullscreen", 1262 "async", 1263 "alpha", 1264 "autofocus", 1265 "autoplay", 1266 "checked", 1267 "controls", 1268 "default", 1269 "disabled", 1270 "formnovalidate", 1271 "hidden", 1272 "indeterminate", 1273 "inert", 1274 "ismap", 1275 "loop", 1276 "multiple", 1277 "muted", 1278 "nomodule", 1279 "novalidate", 1280 "open", 1281 "playsinline", 1282 "readonly", 1283 "required", 1284 "reversed", 1285 "seamless", 1286 "selected", 1287 "adauctionheaders", 1288 "browsingtopics", 1289 "credentialless", 1290 "defaultchecked", 1291 "defaultmuted", 1292 "defaultselected", 1293 "defer", 1294 "disablepictureinpicture", 1295 "disableremoteplayback", 1296 "preservespitch", 1297 "shadowrootclonable", 1298 "shadowrootcustomelementregistry", 1299 "shadowrootdelegatesfocus", 1300 "shadowrootserializable", 1301 "sharedstoragewritable" 1302]; 1303var Properties = /* @__PURE__ */ new Set([ 1304 "className", 1305 "value", 1306 "readOnly", 1307 "noValidate", 1308 "formNoValidate", 1309 "isMap", 1310 "noModule", 1311 "playsInline", 1312 "adAuctionHeaders", 1313 "allowFullscreen", 1314 "browsingTopics", 1315 "defaultChecked", 1316 "defaultMuted", 1317 "defaultSelected", 1318 "disablePictureInPicture", 1319 "disableRemotePlayback", 1320 "preservesPitch", 1321 "shadowRootClonable", 1322 "shadowRootCustomElementRegistry", 1323 "shadowRootDelegatesFocus", 1324 "shadowRootSerializable", 1325 "sharedStorageWritable", 1326 ...booleans 1327]); 1328var ChildProperties = /* @__PURE__ */ new Set(["innerHTML", "textContent", "innerText", "children"]); 1329var Aliases = /* @__PURE__ */ Object.assign(/* @__PURE__ */ Object.create(null), { 1330 className: "class", 1331 htmlFor: "for" 1332}); 1333var PropAliases = /* @__PURE__ */ Object.assign(/* @__PURE__ */ Object.create(null), { 1334 class: "className", 1335 novalidate: { 1336 $: "noValidate", 1337 FORM: 1 1338 }, 1339 formnovalidate: { 1340 $: "formNoValidate", 1341 BUTTON: 1, 1342 INPUT: 1 1343 }, 1344 ismap: { 1345 $: "isMap", 1346 IMG: 1 1347 }, 1348 nomodule: { 1349 $: "noModule", 1350 SCRIPT: 1 1351 }, 1352 playsinline: { 1353 $: "playsInline", 1354 VIDEO: 1 1355 }, 1356 readonly: { 1357 $: "readOnly", 1358 INPUT: 1, 1359 TEXTAREA: 1 1360 }, 1361 adauctionheaders: { 1362 $: "adAuctionHeaders", 1363 IFRAME: 1 1364 }, 1365 allowfullscreen: { 1366 $: "allowFullscreen", 1367 IFRAME: 1 1368 }, 1369 browsingtopics: { 1370 $: "browsingTopics", 1371 IMG: 1 1372 }, 1373 defaultchecked: { 1374 $: "defaultChecked", 1375 INPUT: 1 1376 }, 1377 defaultmuted: { 1378 $: "defaultMuted", 1379 AUDIO: 1, 1380 VIDEO: 1 1381 }, 1382 defaultselected: { 1383 $: "defaultSelected", 1384 OPTION: 1 1385 }, 1386 disablepictureinpicture: { 1387 $: "disablePictureInPicture", 1388 VIDEO: 1 1389 }, 1390 disableremoteplayback: { 1391 $: "disableRemotePlayback", 1392 AUDIO: 1, 1393 VIDEO: 1 1394 }, 1395 preservespitch: { 1396 $: "preservesPitch", 1397 AUDIO: 1, 1398 VIDEO: 1 1399 }, 1400 shadowrootclonable: { 1401 $: "shadowRootClonable", 1402 TEMPLATE: 1 1403 }, 1404 shadowrootdelegatesfocus: { 1405 $: "shadowRootDelegatesFocus", 1406 TEMPLATE: 1 1407 }, 1408 shadowrootserializable: { 1409 $: "shadowRootSerializable", 1410 TEMPLATE: 1 1411 }, 1412 sharedstoragewritable: { 1413 $: "sharedStorageWritable", 1414 IFRAME: 1, 1415 IMG: 1 1416 } 1417}); 1418function getPropAlias(prop, tagName) { 1419 const a = PropAliases[prop]; 1420 return typeof a === "object" ? a[tagName] ? a["$"] : void 0 : a; 1421} 1422var DelegatedEvents = /* @__PURE__ */ new Set(["beforeinput", "click", "dblclick", "contextmenu", "focusin", "focusout", "input", "keydown", "keyup", "mousedown", "mousemove", "mouseout", "mouseover", "mouseup", "pointerdown", "pointermove", "pointerout", "pointerover", "pointerup", "touchend", "touchmove", "touchstart"]); 1423var SVGElements = /* @__PURE__ */ new Set([ 1424 "altGlyph", 1425 "altGlyphDef", 1426 "altGlyphItem", 1427 "animate", 1428 "animateColor", 1429 "animateMotion", 1430 "animateTransform", 1431 "circle", 1432 "clipPath", 1433 "color-profile", 1434 "cursor", 1435 "defs", 1436 "desc", 1437 "ellipse", 1438 "feBlend", 1439 "feColorMatrix", 1440 "feComponentTransfer", 1441 "feComposite", 1442 "feConvolveMatrix", 1443 "feDiffuseLighting", 1444 "feDisplacementMap", 1445 "feDistantLight", 1446 "feDropShadow", 1447 "feFlood", 1448 "feFuncA", 1449 "feFuncB", 1450 "feFuncG", 1451 "feFuncR", 1452 "feGaussianBlur", 1453 "feImage", 1454 "feMerge", 1455 "feMergeNode", 1456 "feMorphology", 1457 "feOffset", 1458 "fePointLight", 1459 "feSpecularLighting", 1460 "feSpotLight", 1461 "feTile", 1462 "feTurbulence", 1463 "filter", 1464 "font", 1465 "font-face", 1466 "font-face-format", 1467 "font-face-name", 1468 "font-face-src", 1469 "font-face-uri", 1470 "foreignObject", 1471 "g", 1472 "glyph", 1473 "glyphRef", 1474 "hkern", 1475 "image", 1476 "line", 1477 "linearGradient", 1478 "marker", 1479 "mask", 1480 "metadata", 1481 "missing-glyph", 1482 "mpath", 1483 "path", 1484 "pattern", 1485 "polygon", 1486 "polyline", 1487 "radialGradient", 1488 "rect", 1489 "set", 1490 "stop", 1491 "svg", 1492 "switch", 1493 "symbol", 1494 "text", 1495 "textPath", 1496 "tref", 1497 "tspan", 1498 "use", 1499 "view", 1500 "vkern" 1501]); 1502var SVGNamespace = { 1503 xlink: "http://www.w3.org/1999/xlink", 1504 xml: "http://www.w3.org/XML/1998/namespace" 1505}; 1506var memo = (fn) => createMemo(() => fn()); 1507function reconcileArrays(parentNode, a, b) { 1508 let bLength = b.length, aEnd = a.length, bEnd = bLength, aStart = 0, bStart = 0, after = a[aEnd - 1].nextSibling, map = null; 1509 while (aStart < aEnd || bStart < bEnd) { 1510 if (a[aStart] === b[bStart]) { 1511 aStart++; 1512 bStart++; 1513 continue; 1514 } 1515 while (a[aEnd - 1] === b[bEnd - 1]) { 1516 aEnd--; 1517 bEnd--; 1518 } 1519 if (aEnd === aStart) { 1520 const node = bEnd < bLength ? bStart ? b[bStart - 1].nextSibling : b[bEnd - bStart] : after; 1521 while (bStart < bEnd) parentNode.insertBefore(b[bStart++], node); 1522 } else if (bEnd === bStart) { 1523 while (aStart < aEnd) { 1524 if (!map || !map.has(a[aStart])) a[aStart].remove(); 1525 aStart++; 1526 } 1527 } else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) { 1528 const node = a[--aEnd].nextSibling; 1529 parentNode.insertBefore(b[bStart++], a[aStart++].nextSibling); 1530 parentNode.insertBefore(b[--bEnd], node); 1531 a[aEnd] = b[bEnd]; 1532 } else { 1533 if (!map) { 1534 map = /* @__PURE__ */ new Map(); 1535 let i = bStart; 1536 while (i < bEnd) map.set(b[i], i++); 1537 } 1538 const index = map.get(a[aStart]); 1539 if (index != null) { 1540 if (bStart < index && index < bEnd) { 1541 let i = aStart, sequence = 1, t; 1542 while (++i < aEnd && i < bEnd) { 1543 if ((t = map.get(a[i])) == null || t !== index + sequence) break; 1544 sequence++; 1545 } 1546 if (sequence > index - bStart) { 1547 const node = a[aStart]; 1548 while (bStart < index) parentNode.insertBefore(b[bStart++], node); 1549 } else parentNode.replaceChild(b[bStart++], a[aStart++]); 1550 } else aStart++; 1551 } else a[aStart++].remove(); 1552 } 1553 } 1554} 1555var $$EVENTS = "_$DX_DELEGATE"; 1556function render(code, element, init, options = {}) { 1557 let disposer; 1558 createRoot((dispose2) => { 1559 disposer = dispose2; 1560 element === document ? code() : insert(element, code(), element.firstChild ? null : void 0, init); 1561 }, options.owner); 1562 return () => { 1563 disposer(); 1564 element.textContent = ""; 1565 }; 1566} 1567function template(html, isImportNode, isSVG, isMathML) { 1568 let node; 1569 const create = () => { 1570 const t = isMathML ? document.createElementNS("http://www.w3.org/1998/Math/MathML", "template") : document.createElement("template"); 1571 t.innerHTML = html; 1572 return isSVG ? t.content.firstChild.firstChild : isMathML ? t.firstChild : t.content.firstChild; 1573 }; 1574 const fn = isImportNode ? () => untrack(() => document.importNode(node || (node = create()), true)) : () => (node || (node = create())).cloneNode(true); 1575 fn.cloneNode = fn; 1576 return fn; 1577} 1578function delegateEvents(eventNames, document2 = window.document) { 1579 const e = document2[$$EVENTS] || (document2[$$EVENTS] = /* @__PURE__ */ new Set()); 1580 for (let i = 0, l = eventNames.length; i < l; i++) { 1581 const name = eventNames[i]; 1582 if (!e.has(name)) { 1583 e.add(name); 1584 document2.addEventListener(name, eventHandler); 1585 } 1586 } 1587} 1588function setAttribute(node, name, value) { 1589 if (isHydrating(node)) return; 1590 if (value == null) node.removeAttribute(name); 1591 else node.setAttribute(name, value); 1592} 1593function setAttributeNS(node, namespace, name, value) { 1594 if (isHydrating(node)) return; 1595 if (value == null) node.removeAttributeNS(namespace, name); 1596 else node.setAttributeNS(namespace, name, value); 1597} 1598function setBoolAttribute(node, name, value) { 1599 if (isHydrating(node)) return; 1600 value ? node.setAttribute(name, "") : node.removeAttribute(name); 1601} 1602function className(node, value) { 1603 if (isHydrating(node)) return; 1604 if (value == null) node.removeAttribute("class"); 1605 else node.className = value; 1606} 1607function addEventListener(node, name, handler, delegate) { 1608 if (delegate) { 1609 if (Array.isArray(handler)) { 1610 node[`$$${name}`] = handler[0]; 1611 node[`$$${name}Data`] = handler[1]; 1612 } else node[`$$${name}`] = handler; 1613 } else if (Array.isArray(handler)) { 1614 const handlerFn = handler[0]; 1615 node.addEventListener(name, handler[0] = (e) => handlerFn.call(node, handler[1], e)); 1616 } else node.addEventListener(name, handler, typeof handler !== "function" && handler); 1617} 1618function classList(node, value, prev = {}) { 1619 const classKeys = Object.keys(value || {}), prevKeys = Object.keys(prev); 1620 let i, len; 1621 for (i = 0, len = prevKeys.length; i < len; i++) { 1622 const key = prevKeys[i]; 1623 if (!key || key === "undefined" || value[key]) continue; 1624 toggleClassKey(node, key, false); 1625 delete prev[key]; 1626 } 1627 for (i = 0, len = classKeys.length; i < len; i++) { 1628 const key = classKeys[i], classValue = !!value[key]; 1629 if (!key || key === "undefined" || prev[key] === classValue || !classValue) continue; 1630 toggleClassKey(node, key, true); 1631 prev[key] = classValue; 1632 } 1633 return prev; 1634} 1635function style(node, value, prev) { 1636 if (!value) return prev ? setAttribute(node, "style") : value; 1637 const nodeStyle = node.style; 1638 if (typeof value === "string") return nodeStyle.cssText = value; 1639 typeof prev === "string" && (nodeStyle.cssText = prev = void 0); 1640 prev || (prev = {}); 1641 value || (value = {}); 1642 let v, s; 1643 for (s in prev) { 1644 value[s] == null && nodeStyle.removeProperty(s); 1645 delete prev[s]; 1646 } 1647 for (s in value) { 1648 v = value[s]; 1649 if (v !== prev[s]) { 1650 nodeStyle.setProperty(s, v); 1651 prev[s] = v; 1652 } 1653 } 1654 return prev; 1655} 1656function spread(node, props = {}, isSVG, skipChildren) { 1657 const prevProps = {}; 1658 if (!skipChildren) { 1659 createRenderEffect(() => prevProps.children = insertExpression(node, props.children, prevProps.children)); 1660 } 1661 createRenderEffect(() => typeof props.ref === "function" && use(props.ref, node)); 1662 createRenderEffect(() => assign(node, props, isSVG, true, prevProps, true)); 1663 return prevProps; 1664} 1665function use(fn, element, arg) { 1666 return untrack(() => fn(element, arg)); 1667} 1668function insert(parent, accessor, marker, initial) { 1669 if (marker !== void 0 && !initial) initial = []; 1670 if (typeof accessor !== "function") return insertExpression(parent, accessor, initial, marker); 1671 createRenderEffect((current) => insertExpression(parent, accessor(), current, marker), initial); 1672} 1673function assign(node, props, isSVG, skipChildren, prevProps = {}, skipRef = false) { 1674 props || (props = {}); 1675 for (const prop in prevProps) { 1676 if (!(prop in props)) { 1677 if (prop === "children") continue; 1678 prevProps[prop] = assignProp(node, prop, null, prevProps[prop], isSVG, skipRef, props); 1679 } 1680 } 1681 for (const prop in props) { 1682 if (prop === "children") { 1683 if (!skipChildren) insertExpression(node, props.children); 1684 continue; 1685 } 1686 const value = props[prop]; 1687 prevProps[prop] = assignProp(node, prop, value, prevProps[prop], isSVG, skipRef, props); 1688 } 1689} 1690function getNextElement(template2) { 1691 let node, key, hydrating = isHydrating(); 1692 if (!hydrating || !(node = sharedConfig.registry.get(key = getHydrationKey()))) { 1693 return template2(); 1694 } 1695 if (sharedConfig.completed) sharedConfig.completed.add(node); 1696 sharedConfig.registry.delete(key); 1697 return node; 1698} 1699function isHydrating(node) { 1700 return !!sharedConfig.context && !sharedConfig.done && (!node || node.isConnected); 1701} 1702function toPropertyName(name) { 1703 return name.toLowerCase().replace(/-([a-z])/g, (_, w) => w.toUpperCase()); 1704} 1705function toggleClassKey(node, key, value) { 1706 const classNames = key.trim().split(/\s+/); 1707 for (let i = 0, nameLen = classNames.length; i < nameLen; i++) node.classList.toggle(classNames[i], value); 1708} 1709function assignProp(node, prop, value, prev, isSVG, skipRef, props) { 1710 let isCE, isProp, isChildProp, propAlias, forceProp; 1711 if (prop === "style") return style(node, value, prev); 1712 if (prop === "classList") return classList(node, value, prev); 1713 if (value === prev) return prev; 1714 if (prop === "ref") { 1715 if (!skipRef) value(node); 1716 } else if (prop.slice(0, 3) === "on:") { 1717 const e = prop.slice(3); 1718 prev && node.removeEventListener(e, prev, typeof prev !== "function" && prev); 1719 value && node.addEventListener(e, value, typeof value !== "function" && value); 1720 } else if (prop.slice(0, 10) === "oncapture:") { 1721 const e = prop.slice(10); 1722 prev && node.removeEventListener(e, prev, true); 1723 value && node.addEventListener(e, value, true); 1724 } else if (prop.slice(0, 2) === "on") { 1725 const name = prop.slice(2).toLowerCase(); 1726 const delegate = DelegatedEvents.has(name); 1727 if (!delegate && prev) { 1728 const h = Array.isArray(prev) ? prev[0] : prev; 1729 node.removeEventListener(name, h); 1730 } 1731 if (delegate || value) { 1732 addEventListener(node, name, value, delegate); 1733 delegate && delegateEvents([name]); 1734 } 1735 } else if (prop.slice(0, 5) === "attr:") { 1736 setAttribute(node, prop.slice(5), value); 1737 } else if (prop.slice(0, 5) === "bool:") { 1738 setBoolAttribute(node, prop.slice(5), value); 1739 } else if ((forceProp = prop.slice(0, 5) === "prop:") || (isChildProp = ChildProperties.has(prop)) || !isSVG && ((propAlias = getPropAlias(prop, node.tagName)) || (isProp = Properties.has(prop))) || (isCE = node.nodeName.includes("-") || "is" in props)) { 1740 if (forceProp) { 1741 prop = prop.slice(5); 1742 isProp = true; 1743 } else if (isHydrating(node)) return value; 1744 if (prop === "class" || prop === "className") className(node, value); 1745 else if (isCE && !isProp && !isChildProp) node[toPropertyName(prop)] = value; 1746 else node[propAlias || prop] = value; 1747 } else { 1748 const ns = isSVG && prop.indexOf(":") > -1 && SVGNamespace[prop.split(":")[0]]; 1749 if (ns) setAttributeNS(node, ns, prop, value); 1750 else setAttribute(node, Aliases[prop] || prop, value); 1751 } 1752 return value; 1753} 1754function eventHandler(e) { 1755 if (sharedConfig.registry && sharedConfig.events) { 1756 if (sharedConfig.events.find(([el, ev]) => ev === e)) return; 1757 } 1758 let node = e.target; 1759 const key = `$$${e.type}`; 1760 const oriTarget = e.target; 1761 const oriCurrentTarget = e.currentTarget; 1762 const retarget = (value) => Object.defineProperty(e, "target", { 1763 configurable: true, 1764 value 1765 }); 1766 const handleNode = () => { 1767 const handler = node[key]; 1768 if (handler && !node.disabled) { 1769 const data = node[`${key}Data`]; 1770 data !== void 0 ? handler.call(node, data, e) : handler.call(node, e); 1771 if (e.cancelBubble) return; 1772 } 1773 node.host && typeof node.host !== "string" && !node.host._$host && node.contains(e.target) && retarget(node.host); 1774 return true; 1775 }; 1776 const walkUpTree = () => { 1777 while (handleNode() && (node = node._$host || node.parentNode || node.host)) ; 1778 }; 1779 Object.defineProperty(e, "currentTarget", { 1780 configurable: true, 1781 get() { 1782 return node || document; 1783 } 1784 }); 1785 if (sharedConfig.registry && !sharedConfig.done) sharedConfig.done = _$HY.done = true; 1786 if (e.composedPath) { 1787 const path = e.composedPath(); 1788 retarget(path[0]); 1789 for (let i = 0; i < path.length - 2; i++) { 1790 node = path[i]; 1791 if (!handleNode()) break; 1792 if (node._$host) { 1793 node = node._$host; 1794 walkUpTree(); 1795 break; 1796 } 1797 if (node.parentNode === oriCurrentTarget) { 1798 break; 1799 } 1800 } 1801 } else walkUpTree(); 1802 retarget(oriTarget); 1803} 1804function insertExpression(parent, value, current, marker, unwrapArray) { 1805 const hydrating = isHydrating(parent); 1806 if (hydrating) { 1807 !current && (current = [...parent.childNodes]); 1808 let cleaned = []; 1809 for (let i = 0; i < current.length; i++) { 1810 const node = current[i]; 1811 if (node.nodeType === 8 && node.data.slice(0, 2) === "!$") node.remove(); 1812 else cleaned.push(node); 1813 } 1814 current = cleaned; 1815 } 1816 while (typeof current === "function") current = current(); 1817 if (value === current) return current; 1818 const t = typeof value, multi = marker !== void 0; 1819 parent = multi && current[0] && current[0].parentNode || parent; 1820 if (t === "string" || t === "number") { 1821 if (hydrating) return current; 1822 if (t === "number") { 1823 value = value.toString(); 1824 if (value === current) return current; 1825 } 1826 if (multi) { 1827 let node = current[0]; 1828 if (node && node.nodeType === 3) { 1829 node.data !== value && (node.data = value); 1830 } else node = document.createTextNode(value); 1831 current = cleanChildren(parent, current, marker, node); 1832 } else { 1833 if (current !== "" && typeof current === "string") { 1834 current = parent.firstChild.data = value; 1835 } else current = parent.textContent = value; 1836 } 1837 } else if (value == null || t === "boolean") { 1838 if (hydrating) return current; 1839 current = cleanChildren(parent, current, marker); 1840 } else if (t === "function") { 1841 createRenderEffect(() => { 1842 let v = value(); 1843 while (typeof v === "function") v = v(); 1844 current = insertExpression(parent, v, current, marker); 1845 }); 1846 return () => current; 1847 } else if (Array.isArray(value)) { 1848 const array = []; 1849 const currentArray = current && Array.isArray(current); 1850 if (normalizeIncomingArray(array, value, current, unwrapArray)) { 1851 createRenderEffect(() => current = insertExpression(parent, array, current, marker, true)); 1852 return () => current; 1853 } 1854 if (hydrating) { 1855 if (!array.length) return current; 1856 if (marker === void 0) return current = [...parent.childNodes]; 1857 let node = array[0]; 1858 if (node.parentNode !== parent) return current; 1859 const nodes = [node]; 1860 while ((node = node.nextSibling) !== marker) nodes.push(node); 1861 return current = nodes; 1862 } 1863 if (array.length === 0) { 1864 current = cleanChildren(parent, current, marker); 1865 if (multi) return current; 1866 } else if (currentArray) { 1867 if (current.length === 0) { 1868 appendNodes(parent, array, marker); 1869 } else reconcileArrays(parent, current, array); 1870 } else { 1871 current && cleanChildren(parent); 1872 appendNodes(parent, array); 1873 } 1874 current = array; 1875 } else if (value.nodeType) { 1876 if (hydrating && value.parentNode) return current = multi ? [value] : value; 1877 if (Array.isArray(current)) { 1878 if (multi) return current = cleanChildren(parent, current, marker, value); 1879 cleanChildren(parent, current, null, value); 1880 } else if (current == null || current === "" || !parent.firstChild) { 1881 parent.appendChild(value); 1882 } else parent.replaceChild(value, parent.firstChild); 1883 current = value; 1884 } else ; 1885 return current; 1886} 1887function normalizeIncomingArray(normalized, array, current, unwrap) { 1888 let dynamic = false; 1889 for (let i = 0, len = array.length; i < len; i++) { 1890 let item = array[i], prev = current && current[normalized.length], t; 1891 if (item == null || item === true || item === false) ; 1892 else if ((t = typeof item) === "object" && item.nodeType) { 1893 normalized.push(item); 1894 } else if (Array.isArray(item)) { 1895 dynamic = normalizeIncomingArray(normalized, item, prev) || dynamic; 1896 } else if (t === "function") { 1897 if (unwrap) { 1898 while (typeof item === "function") item = item(); 1899 dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item], Array.isArray(prev) ? prev : [prev]) || dynamic; 1900 } else { 1901 normalized.push(item); 1902 dynamic = true; 1903 } 1904 } else { 1905 const value = String(item); 1906 if (prev && prev.nodeType === 3 && prev.data === value) normalized.push(prev); 1907 else normalized.push(document.createTextNode(value)); 1908 } 1909 } 1910 return dynamic; 1911} 1912function appendNodes(parent, array, marker = null) { 1913 for (let i = 0, len = array.length; i < len; i++) parent.insertBefore(array[i], marker); 1914} 1915function cleanChildren(parent, current, marker, replacement) { 1916 if (marker === void 0) return parent.textContent = ""; 1917 const node = replacement || document.createTextNode(""); 1918 if (current.length) { 1919 let inserted = false; 1920 for (let i = current.length - 1; i >= 0; i--) { 1921 const el = current[i]; 1922 if (node !== el) { 1923 const isParent = el.parentNode === parent; 1924 if (!inserted && !i) isParent ? parent.replaceChild(node, el) : parent.insertBefore(node, marker); 1925 else isParent && el.remove(); 1926 } else inserted = true; 1927 } 1928 } else parent.insertBefore(node, marker); 1929 return [node]; 1930} 1931function getHydrationKey() { 1932 return sharedConfig.getNextContextId(); 1933} 1934var voidFn = () => void 0; 1935var RequestContext = Symbol(); 1936function ssrElement(name, props, children2, needsId) { 1937} 1938var isServer = false; 1939var SVG_NAMESPACE = "http://www.w3.org/2000/svg"; 1940function createElement(tagName, isSVG = false, is = void 0) { 1941 return isSVG ? document.createElementNS(SVG_NAMESPACE, tagName) : document.createElement(tagName, { 1942 is 1943 }); 1944} 1945function Portal(props) { 1946 const { 1947 useShadow 1948 } = props, marker = document.createTextNode(""), mount = () => props.mount || document.body, owner = getOwner(); 1949 let content; 1950 let hydrating = !!sharedConfig.context; 1951 createEffect(() => { 1952 if (hydrating) getOwner().user = hydrating = false; 1953 content || (content = runWithOwner(owner, () => createMemo(() => props.children))); 1954 const el = mount(); 1955 if (el instanceof HTMLHeadElement) { 1956 const [clean, setClean] = createSignal(false); 1957 const cleanup = () => setClean(true); 1958 createRoot((dispose2) => insert(el, () => !clean() ? content() : dispose2(), null)); 1959 onCleanup(cleanup); 1960 } else { 1961 const container = createElement(props.isSVG ? "g" : "div", props.isSVG), renderRoot = useShadow && container.attachShadow ? container.attachShadow({ 1962 mode: "open" 1963 }) : container; 1964 Object.defineProperty(container, "_$host", { 1965 get() { 1966 return marker.parentNode; 1967 }, 1968 configurable: true 1969 }); 1970 insert(renderRoot, content); 1971 el.appendChild(container); 1972 props.ref && props.ref(container); 1973 onCleanup(() => el.removeChild(container)); 1974 } 1975 }, void 0, { 1976 render: !hydrating 1977 }); 1978 return marker; 1979} 1980function createDynamic(component, props) { 1981 const cached = createMemo(component); 1982 return createMemo(() => { 1983 const component2 = cached(); 1984 switch (typeof component2) { 1985 case "function": 1986 return untrack(() => component2(props)); 1987 case "string": 1988 const isSvg = SVGElements.has(component2); 1989 const el = sharedConfig.context ? getNextElement() : createElement(component2, isSvg, untrack(() => props.is)); 1990 spread(el, props, isSvg); 1991 return el; 1992 } 1993 }); 1994} 1995function Dynamic(props) { 1996 const [, others] = splitProps(props, ["component"]); 1997 return createDynamic(() => props.component, others); 1998} 1999
vendor: 690,010 bytes, lines 2000-22524
2000// node_modules/three/build/three.core.js 2001var REVISION = "184"; 2002var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 }; 2003var CullFaceNone = 0; 2004var CullFaceBack = 1; 2005var CullFaceFront = 2; 2006var BasicShadowMap = 0; 2007var PCFShadowMap = 1; 2008var PCFSoftShadowMap = 2; 2009var VSMShadowMap = 3; 2010var FrontSide = 0; 2011var BackSide = 1; 2012var DoubleSide = 2; 2013var NoBlending = 0; 2014var NormalBlending = 1; 2015var AdditiveBlending = 2; 2016var SubtractiveBlending = 3; 2017var MultiplyBlending = 4; 2018var CustomBlending = 5; 2019var MaterialBlending = 6; 2020var AddEquation = 100; 2021var SubtractEquation = 101; 2022var ReverseSubtractEquation = 102; 2023var MinEquation = 103; 2024var MaxEquation = 104; 2025var ZeroFactor = 200; 2026var OneFactor = 201; 2027var SrcColorFactor = 202; 2028var OneMinusSrcColorFactor = 203; 2029var SrcAlphaFactor = 204; 2030var OneMinusSrcAlphaFactor = 205; 2031var DstAlphaFactor = 206; 2032var OneMinusDstAlphaFactor = 207; 2033var DstColorFactor = 208; 2034var OneMinusDstColorFactor = 209; 2035var SrcAlphaSaturateFactor = 210; 2036var ConstantColorFactor = 211; 2037var OneMinusConstantColorFactor = 212; 2038var ConstantAlphaFactor = 213; 2039var OneMinusConstantAlphaFactor = 214; 2040var NeverDepth = 0; 2041var AlwaysDepth = 1; 2042var LessDepth = 2; 2043var LessEqualDepth = 3; 2044var EqualDepth = 4; 2045var GreaterEqualDepth = 5; 2046var GreaterDepth = 6; 2047var NotEqualDepth = 7; 2048var MultiplyOperation = 0; 2049var MixOperation = 1; 2050var AddOperation = 2; 2051var NoToneMapping = 0; 2052var LinearToneMapping = 1; 2053var ReinhardToneMapping = 2; 2054var CineonToneMapping = 3; 2055var ACESFilmicToneMapping = 4; 2056var CustomToneMapping = 5; 2057var AgXToneMapping = 6; 2058var NeutralToneMapping = 7; 2059var AttachedBindMode = "attached"; 2060var DetachedBindMode = "detached"; 2061var UVMapping = 300; 2062var CubeReflectionMapping = 301; 2063var CubeRefractionMapping = 302; 2064var EquirectangularReflectionMapping = 303; 2065var EquirectangularRefractionMapping = 304; 2066var CubeUVReflectionMapping = 306; 2067var RepeatWrapping = 1e3; 2068var ClampToEdgeWrapping = 1001; 2069var MirroredRepeatWrapping = 1002; 2070var NearestFilter = 1003; 2071var NearestMipmapNearestFilter = 1004; 2072var NearestMipmapLinearFilter = 1005; 2073var LinearFilter = 1006; 2074var LinearMipmapNearestFilter = 1007; 2075var LinearMipmapLinearFilter = 1008; 2076var LinearMipMapLinearFilter = 1008; 2077var UnsignedByteType = 1009; 2078var ByteType = 1010; 2079var ShortType = 1011; 2080var UnsignedShortType = 1012; 2081var IntType = 1013; 2082var UnsignedIntType = 1014; 2083var FloatType = 1015; 2084var HalfFloatType = 1016; 2085var UnsignedShort4444Type = 1017; 2086var UnsignedShort5551Type = 1018; 2087var UnsignedInt248Type = 1020; 2088var UnsignedInt5999Type = 35902; 2089var UnsignedInt101111Type = 35899; 2090var AlphaFormat = 1021; 2091var RGBFormat = 1022; 2092var RGBAFormat = 1023; 2093var DepthFormat = 1026; 2094var DepthStencilFormat = 1027; 2095var RedFormat = 1028; 2096var RedIntegerFormat = 1029; 2097var RGFormat = 1030; 2098var RGIntegerFormat = 1031; 2099var RGBIntegerFormat = 1032; 2100var RGBAIntegerFormat = 1033; 2101var RGB_S3TC_DXT1_Format = 33776; 2102var RGBA_S3TC_DXT1_Format = 33777; 2103var RGBA_S3TC_DXT3_Format = 33778; 2104var RGBA_S3TC_DXT5_Format = 33779; 2105var RGB_PVRTC_4BPPV1_Format = 35840; 2106var RGB_PVRTC_2BPPV1_Format = 35841; 2107var RGBA_PVRTC_4BPPV1_Format = 35842; 2108var RGBA_PVRTC_2BPPV1_Format = 35843; 2109var RGB_ETC1_Format = 36196; 2110var RGB_ETC2_Format = 37492; 2111var RGBA_ETC2_EAC_Format = 37496; 2112var R11_EAC_Format = 37488; 2113var SIGNED_R11_EAC_Format = 37489; 2114var RG11_EAC_Format = 37490; 2115var SIGNED_RG11_EAC_Format = 37491; 2116var RGBA_ASTC_4x4_Format = 37808; 2117var RGBA_ASTC_5x4_Format = 37809; 2118var RGBA_ASTC_5x5_Format = 37810; 2119var RGBA_ASTC_6x5_Format = 37811; 2120var RGBA_ASTC_6x6_Format = 37812; 2121var RGBA_ASTC_8x5_Format = 37813; 2122var RGBA_ASTC_8x6_Format = 37814; 2123var RGBA_ASTC_8x8_Format = 37815; 2124var RGBA_ASTC_10x5_Format = 37816; 2125var RGBA_ASTC_10x6_Format = 37817; 2126var RGBA_ASTC_10x8_Format = 37818; 2127var RGBA_ASTC_10x10_Format = 37819; 2128var RGBA_ASTC_12x10_Format = 37820; 2129var RGBA_ASTC_12x12_Format = 37821; 2130var RGBA_BPTC_Format = 36492; 2131var RGB_BPTC_SIGNED_Format = 36494; 2132var RGB_BPTC_UNSIGNED_Format = 36495; 2133var RED_RGTC1_Format = 36283; 2134var SIGNED_RED_RGTC1_Format = 36284; 2135var RED_GREEN_RGTC2_Format = 36285; 2136var SIGNED_RED_GREEN_RGTC2_Format = 36286; 2137var InterpolateDiscrete = 2300; 2138var InterpolateLinear = 2301; 2139var InterpolateSmooth = 2302; 2140var InterpolateBezier = 2303; 2141var ZeroCurvatureEnding = 2400; 2142var ZeroSlopeEnding = 2401; 2143var WrapAroundEnding = 2402; 2144var NormalAnimationBlendMode = 2500; 2145var TrianglesDrawMode = 0; 2146var TriangleStripDrawMode = 1; 2147var TriangleFanDrawMode = 2; 2148var BasicDepthPacking = 3200; 2149var TangentSpaceNormalMap = 0; 2150var ObjectSpaceNormalMap = 1; 2151var NoColorSpace = ""; 2152var SRGBColorSpace = "srgb"; 2153var LinearSRGBColorSpace = "srgb-linear"; 2154var LinearTransfer = "linear"; 2155var SRGBTransfer = "srgb"; 2156var NoNormalPacking = ""; 2157var NormalRGPacking = "rg"; 2158var NormalGAPacking = "ga"; 2159var ZeroStencilOp = 0; 2160var KeepStencilOp = 7680; 2161var ReplaceStencilOp = 7681; 2162var IncrementStencilOp = 7682; 2163var DecrementStencilOp = 7683; 2164var IncrementWrapStencilOp = 34055; 2165var DecrementWrapStencilOp = 34056; 2166var InvertStencilOp = 5386; 2167var NeverStencilFunc = 512; 2168var LessStencilFunc = 513; 2169var EqualStencilFunc = 514; 2170var LessEqualStencilFunc = 515; 2171var GreaterStencilFunc = 516; 2172var NotEqualStencilFunc = 517; 2173var GreaterEqualStencilFunc = 518; 2174var AlwaysStencilFunc = 519; 2175var NeverCompare = 512; 2176var LessCompare = 513; 2177var EqualCompare = 514; 2178var LessEqualCompare = 515; 2179var GreaterCompare = 516; 2180var NotEqualCompare = 517; 2181var GreaterEqualCompare = 518; 2182var AlwaysCompare = 519; 2183var StaticDrawUsage = 35044; 2184var DynamicDrawUsage = 35048; 2185var GLSL3 = "300 es"; 2186var WebGLCoordinateSystem = 2e3; 2187var WebGPUCoordinateSystem = 2001; 2188var TimestampQuery = { 2189 COMPUTE: "compute", 2190 RENDER: "render" 2191}; 2192var Compatibility = { 2193 TEXTURE_COMPARE: "depthTextureCompare" 2194}; 2195function arrayNeedsUint32(array) { 2196 for (let i = array.length - 1; i >= 0; --i) { 2197 if (array[i] >= 65535) return true; 2198 } 2199 return false; 2200} 2201function isTypedArray(array) { 2202 return ArrayBuffer.isView(array) && !(array instanceof DataView); 2203} 2204function createElementNS(name) { 2205 return document.createElementNS("http://www.w3.org/1999/xhtml", name); 2206} 2207function createCanvasElement() { 2208 const canvas = createElementNS("canvas"); 2209 canvas.style.display = "block"; 2210 return canvas; 2211} 2212var _cache = {}; 2213var _setConsoleFunction = null; 2214function log(...params) { 2215 const message = "THREE." + params.shift(); 2216 if (_setConsoleFunction) { 2217 _setConsoleFunction("log", message, ...params); 2218 } else { 2219 console.log(message, ...params); 2220 } 2221} 2222function enhanceLogMessage(params) { 2223 const message = params[0]; 2224 if (typeof message === "string" && message.startsWith("TSL:")) { 2225 const stackTrace = params[1]; 2226 if (stackTrace && stackTrace.isStackTrace) { 2227 params[0] += " " + stackTrace.getLocation(); 2228 } else { 2229 params[1] = 'Stack trace not available. Enable "THREE.Node.captureStackTrace" to capture stack traces.'; 2230 } 2231 } 2232 return params; 2233} 2234function warn(...params) { 2235 params = enhanceLogMessage(params); 2236 const message = "THREE." + params.shift(); 2237 if (_setConsoleFunction) { 2238 _setConsoleFunction("warn", message, ...params); 2239 } else { 2240 const stackTrace = params[0]; 2241 if (stackTrace && stackTrace.isStackTrace) { 2242 console.warn(stackTrace.getError(message)); 2243 } else { 2244 console.warn(message, ...params); 2245 } 2246 } 2247} 2248function error(...params) { 2249 params = enhanceLogMessage(params); 2250 const message = "THREE." + params.shift(); 2251 if (_setConsoleFunction) { 2252 _setConsoleFunction("error", message, ...params); 2253 } else { 2254 const stackTrace = params[0]; 2255 if (stackTrace && stackTrace.isStackTrace) { 2256 console.error(stackTrace.getError(message)); 2257 } else { 2258 console.error(message, ...params); 2259 } 2260 } 2261} 2262function warnOnce(...params) { 2263 const message = params.join(" "); 2264 if (message in _cache) return; 2265 _cache[message] = true; 2266 warn(...params); 2267} 2268function yieldToMain() { 2269 if (typeof self !== "undefined" && typeof self.scheduler !== "undefined" && typeof self.scheduler.yield !== "undefined") { 2270 return self.scheduler.yield(); 2271 } 2272 return new Promise((resolve) => { 2273 requestAnimationFrame(resolve); 2274 }); 2275} 2276function probeAsync(gl, sync, interval) { 2277 return new Promise(function(resolve, reject) { 2278 function probe() { 2279 switch (gl.clientWaitSync(sync, gl.SYNC_FLUSH_COMMANDS_BIT, 0)) { 2280 case gl.WAIT_FAILED: 2281 reject(); 2282 break; 2283 case gl.TIMEOUT_EXPIRED: 2284 setTimeout(probe, interval); 2285 break; 2286 default: 2287 resolve(); 2288 } 2289 } 2290 setTimeout(probe, interval); 2291 }); 2292} 2293var ReversedDepthFuncs = { 2294 [NeverDepth]: AlwaysDepth, 2295 [LessDepth]: GreaterDepth, 2296 [EqualDepth]: NotEqualDepth, 2297 [LessEqualDepth]: GreaterEqualDepth, 2298 [AlwaysDepth]: NeverDepth, 2299 [GreaterDepth]: LessDepth, 2300 [NotEqualDepth]: EqualDepth, 2301 [GreaterEqualDepth]: LessEqualDepth 2302}; 2303var EventDispatcher = class { 2304 /** 2305 * Adds the given event listener to the given event type. 2306 * 2307 * @param {string} type - The type of event to listen to. 2308 * @param {Function} listener - The function that gets called when the event is fired. 2309 */ 2310 addEventListener(type, listener) { 2311 if (this._listeners === void 0) this._listeners = {}; 2312 const listeners = this._listeners; 2313 if (listeners[type] === void 0) { 2314 listeners[type] = []; 2315 } 2316 if (listeners[type].indexOf(listener) === -1) { 2317 listeners[type].push(listener); 2318 } 2319 } 2320 /** 2321 * Returns `true` if the given event listener has been added to the given event type. 2322 * 2323 * @param {string} type - The type of event. 2324 * @param {Function} listener - The listener to check. 2325 * @return {boolean} Whether the given event listener has been added to the given event type. 2326 */ 2327 hasEventListener(type, listener) { 2328 const listeners = this._listeners; 2329 if (listeners === void 0) return false; 2330 return listeners[type] !== void 0 && listeners[type].indexOf(listener) !== -1; 2331 } 2332 /** 2333 * Removes the given event listener from the given event type. 2334 * 2335 * @param {string} type - The type of event. 2336 * @param {Function} listener - The listener to remove. 2337 */ 2338 removeEventListener(type, listener) { 2339 const listeners = this._listeners; 2340 if (listeners === void 0) return; 2341 const listenerArray = listeners[type]; 2342 if (listenerArray !== void 0) { 2343 const index = listenerArray.indexOf(listener); 2344 if (index !== -1) { 2345 listenerArray.splice(index, 1); 2346 } 2347 } 2348 } 2349 /** 2350 * Dispatches an event object. 2351 * 2352 * @param {Object} event - The event that gets fired. 2353 */ 2354 dispatchEvent(event) { 2355 const listeners = this._listeners; 2356 if (listeners === void 0) return; 2357 const listenerArray = listeners[event.type]; 2358 if (listenerArray !== void 0) { 2359 event.target = this; 2360 const array = listenerArray.slice(0); 2361 for (let i = 0, l = array.length; i < l; i++) { 2362 array[i].call(this, event); 2363 } 2364 event.target = null; 2365 } 2366 } 2367}; 2368var _lut = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af", "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf", "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df", "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff"]; 2369var _seed = 1234567; 2370var DEG2RAD = Math.PI / 180; 2371var RAD2DEG = 180 / Math.PI; 2372function generateUUID() { 2373 const d0 = Math.random() * 4294967295 | 0; 2374 const d1 = Math.random() * 4294967295 | 0; 2375 const d2 = Math.random() * 4294967295 | 0; 2376 const d3 = Math.random() * 4294967295 | 0; 2377 const uuid = _lut[d0 & 255] + _lut[d0 >> 8 & 255] + _lut[d0 >> 16 & 255] + _lut[d0 >> 24 & 255] + "-" + _lut[d1 & 255] + _lut[d1 >> 8 & 255] + "-" + _lut[d1 >> 16 & 15 | 64] + _lut[d1 >> 24 & 255] + "-" + _lut[d2 & 63 | 128] + _lut[d2 >> 8 & 255] + "-" + _lut[d2 >> 16 & 255] + _lut[d2 >> 24 & 255] + _lut[d3 & 255] + _lut[d3 >> 8 & 255] + _lut[d3 >> 16 & 255] + _lut[d3 >> 24 & 255]; 2378 return uuid.toLowerCase(); 2379} 2380function clamp(value, min, max) { 2381 return Math.max(min, Math.min(max, value)); 2382} 2383function euclideanModulo(n, m) { 2384 return (n % m + m) % m; 2385} 2386function mapLinear(x, a1, a2, b1, b2) { 2387 return b1 + (x - a1) * (b2 - b1) / (a2 - a1); 2388} 2389function inverseLerp(x, y, value) { 2390 if (x !== y) { 2391 return (value - x) / (y - x); 2392 } else { 2393 return 0; 2394 } 2395} 2396function lerp(x, y, t) { 2397 return (1 - t) * x + t * y; 2398} 2399function damp(x, y, lambda, dt) { 2400 return lerp(x, y, 1 - Math.exp(-lambda * dt)); 2401} 2402function pingpong(x, length = 1) { 2403 return length - Math.abs(euclideanModulo(x, length * 2) - length); 2404} 2405function smoothstep(x, min, max) { 2406 if (x <= min) return 0; 2407 if (x >= max) return 1; 2408 x = (x - min) / (max - min); 2409 return x * x * (3 - 2 * x); 2410} 2411function smootherstep(x, min, max) { 2412 if (x <= min) return 0; 2413 if (x >= max) return 1; 2414 x = (x - min) / (max - min); 2415 return x * x * x * (x * (x * 6 - 15) + 10); 2416} 2417function randInt(low, high) { 2418 return low + Math.floor(Math.random() * (high - low + 1)); 2419} 2420function randFloat(low, high) { 2421 return low + Math.random() * (high - low); 2422} 2423function randFloatSpread(range) { 2424 return range * (0.5 - Math.random()); 2425} 2426function seededRandom(s) { 2427 if (s !== void 0) _seed = s; 2428 let t = _seed += 1831565813; 2429 t = Math.imul(t ^ t >>> 15, t | 1); 2430 t ^= t + Math.imul(t ^ t >>> 7, t | 61); 2431 return ((t ^ t >>> 14) >>> 0) / 4294967296; 2432} 2433function degToRad(degrees) { 2434 return degrees * DEG2RAD; 2435} 2436function radToDeg(radians) { 2437 return radians * RAD2DEG; 2438} 2439function isPowerOfTwo(value) { 2440 return (value & value - 1) === 0 && value !== 0; 2441} 2442function ceilPowerOfTwo(value) { 2443 return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2)); 2444} 2445function floorPowerOfTwo(value) { 2446 return Math.pow(2, Math.floor(Math.log(value) / Math.LN2)); 2447} 2448function setQuaternionFromProperEuler(q, a, b, c, order) { 2449 const cos = Math.cos; 2450 const sin = Math.sin; 2451 const c2 = cos(b / 2); 2452 const s2 = sin(b / 2); 2453 const c13 = cos((a + c) / 2); 2454 const s13 = sin((a + c) / 2); 2455 const c1_3 = cos((a - c) / 2); 2456 const s1_3 = sin((a - c) / 2); 2457 const c3_1 = cos((c - a) / 2); 2458 const s3_1 = sin((c - a) / 2); 2459 switch (order) { 2460 case "XYX": 2461 q.set(c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13); 2462 break; 2463 case "YZY": 2464 q.set(s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13); 2465 break; 2466 case "ZXZ": 2467 q.set(s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13); 2468 break; 2469 case "XZX": 2470 q.set(c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13); 2471 break; 2472 case "YXY": 2473 q.set(s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13); 2474 break; 2475 case "ZYZ": 2476 q.set(s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13); 2477 break; 2478 default: 2479 warn("MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: " + order); 2480 } 2481} 2482function denormalize(value, array) { 2483 switch (array.constructor) { 2484 case Float32Array: 2485 return value; 2486 case Uint32Array: 2487 return value / 4294967295; 2488 case Uint16Array: 2489 return value / 65535; 2490 case Uint8Array: 2491 return value / 255; 2492 case Int32Array: 2493 return Math.max(value / 2147483647, -1); 2494 case Int16Array: 2495 return Math.max(value / 32767, -1); 2496 case Int8Array: 2497 return Math.max(value / 127, -1); 2498 default: 2499 throw new Error("Invalid component type."); 2500 } 2501} 2502function normalize(value, array) { 2503 switch (array.constructor) { 2504 case Float32Array: 2505 return value; 2506 case Uint32Array: 2507 return Math.round(value * 4294967295); 2508 case Uint16Array: 2509 return Math.round(value * 65535); 2510 case Uint8Array: 2511 return Math.round(value * 255); 2512 case Int32Array: 2513 return Math.round(value * 2147483647); 2514 case Int16Array: 2515 return Math.round(value * 32767); 2516 case Int8Array: 2517 return Math.round(value * 127); 2518 default: 2519 throw new Error("Invalid component type."); 2520 } 2521} 2522var MathUtils = { 2523 DEG2RAD, 2524 RAD2DEG, 2525 /** 2526 * Generate a [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier) 2527 * (universally unique identifier). 2528 * 2529 * @static 2530 * @method 2531 * @return {string} The UUID. 2532 */ 2533 generateUUID, 2534 /** 2535 * Clamps the given value between min and max. 2536 * 2537 * @static 2538 * @method 2539 * @param {number} value - The value to clamp. 2540 * @param {number} min - The min value. 2541 * @param {number} max - The max value. 2542 * @return {number} The clamped value. 2543 */ 2544 clamp, 2545 /** 2546 * Computes the Euclidean modulo of the given parameters that 2547 * is `( ( n % m ) + m ) % m`. 2548 * 2549 * @static 2550 * @method 2551 * @param {number} n - The first parameter. 2552 * @param {number} m - The second parameter. 2553 * @return {number} The Euclidean modulo. 2554 */ 2555 euclideanModulo, 2556 /** 2557 * Performs a linear mapping from range `<a1, a2>` to range `<b1, b2>` 2558 * for the given value. 2559 * 2560 * @static 2561 * @method 2562 * @param {number} x - The value to be mapped. 2563 * @param {number} a1 - Minimum value for range A. 2564 * @param {number} a2 - Maximum value for range A. 2565 * @param {number} b1 - Minimum value for range B. 2566 * @param {number} b2 - Maximum value for range B. 2567 * @return {number} The mapped value. 2568 */ 2569 mapLinear, 2570 /** 2571 * Returns the percentage in the closed interval `[0, 1]` of the given value 2572 * between the start and end point. 2573 * 2574 * @static 2575 * @method 2576 * @param {number} x - The start point 2577 * @param {number} y - The end point. 2578 * @param {number} value - A value between start and end. 2579 * @return {number} The interpolation factor. 2580 */ 2581 inverseLerp, 2582 /** 2583 * Returns a value linearly interpolated from two known points based on the given interval - 2584 * `t = 0` will return `x` and `t = 1` will return `y`. 2585 * 2586 * @static 2587 * @method 2588 * @param {number} x - The start point 2589 * @param {number} y - The end point. 2590 * @param {number} t - The interpolation factor in the closed interval `[0, 1]`. 2591 * @return {number} The interpolated value. 2592 */ 2593 lerp, 2594 /** 2595 * Smoothly interpolate a number from `x` to `y` in a spring-like manner using a delta 2596 * time to maintain frame rate independent movement. For details, see 2597 * [Frame rate independent damping using lerp](http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/). 2598 * 2599 * @static 2600 * @method 2601 * @param {number} x - The current point. 2602 * @param {number} y - The target point. 2603 * @param {number} lambda - A higher lambda value will make the movement more sudden, 2604 * and a lower value will make the movement more gradual. 2605 * @param {number} dt - Delta time in seconds. 2606 * @return {number} The interpolated value. 2607 */ 2608 damp, 2609 /** 2610 * Returns a value that alternates between `0` and the given `length` parameter. 2611 * 2612 * @static 2613 * @method 2614 * @param {number} x - The value to pingpong. 2615 * @param {number} [length=1] - The positive value the function will pingpong to. 2616 * @return {number} The alternated value. 2617 */ 2618 pingpong, 2619 /** 2620 * Returns a value in the range `[0,1]` that represents the percentage that `x` has 2621 * moved between `min` and `max`, but smoothed or slowed down the closer `x` is to 2622 * the `min` and `max`. 2623 * 2624 * See [Smoothstep](http://en.wikipedia.org/wiki/Smoothstep) for more details. 2625 * 2626 * @static 2627 * @method 2628 * @param {number} x - The value to evaluate based on its position between min and max. 2629 * @param {number} min - The min value. Any x value below min will be `0`. 2630 * @param {number} max - The max value. Any x value above max will be `1`. 2631 * @return {number} The alternated value. 2632 */ 2633 smoothstep, 2634 /** 2635 * A [variation on smoothstep](https://en.wikipedia.org/wiki/Smoothstep#Variations) 2636 * that has zero 1st and 2nd order derivatives at x=0 and x=1. 2637 * 2638 * @static 2639 * @method 2640 * @param {number} x - The value to evaluate based on its position between min and max. 2641 * @param {number} min - The min value. Any x value below min will be `0`. 2642 * @param {number} max - The max value. Any x value above max will be `1`. 2643 * @return {number} The alternated value. 2644 */ 2645 smootherstep, 2646 /** 2647 * Returns a random integer from `<low, high>` interval. 2648 * 2649 * @static 2650 * @method 2651 * @param {number} low - The lower value boundary. 2652 * @param {number} high - The upper value boundary 2653 * @return {number} A random integer. 2654 */ 2655 randInt, 2656 /** 2657 * Returns a random float from `<low, high>` interval. 2658 * 2659 * @static 2660 * @method 2661 * @param {number} low - The lower value boundary. 2662 * @param {number} high - The upper value boundary 2663 * @return {number} A random float. 2664 */ 2665 randFloat, 2666 /** 2667 * Returns a random integer from `<-range/2, range/2>` interval. 2668 * 2669 * @static 2670 * @method 2671 * @param {number} range - Defines the value range. 2672 * @return {number} A random float. 2673 */ 2674 randFloatSpread, 2675 /** 2676 * Returns a deterministic pseudo-random float in the interval `[0, 1]`. 2677 * 2678 * @static 2679 * @method 2680 * @param {number} [s] - The integer seed. 2681 * @return {number} A random float. 2682 */ 2683 seededRandom, 2684 /** 2685 * Converts degrees to radians. 2686 * 2687 * @static 2688 * @method 2689 * @param {number} degrees - A value in degrees. 2690 * @return {number} The converted value in radians. 2691 */ 2692 degToRad, 2693 /** 2694 * Converts radians to degrees. 2695 * 2696 * @static 2697 * @method 2698 * @param {number} radians - A value in radians. 2699 * @return {number} The converted value in degrees. 2700 */ 2701 radToDeg, 2702 /** 2703 * Returns `true` if the given number is a power of two. 2704 * 2705 * @static 2706 * @method 2707 * @param {number} value - The value to check. 2708 * @return {boolean} Whether the given number is a power of two or not. 2709 */ 2710 isPowerOfTwo, 2711 /** 2712 * Returns the smallest power of two that is greater than or equal to the given number. 2713 * 2714 * @static 2715 * @method 2716 * @param {number} value - The value to find a POT for. 2717 * @return {number} The smallest power of two that is greater than or equal to the given number. 2718 */ 2719 ceilPowerOfTwo, 2720 /** 2721 * Returns the largest power of two that is less than or equal to the given number. 2722 * 2723 * @static 2724 * @method 2725 * @param {number} value - The value to find a POT for. 2726 * @return {number} The largest power of two that is less than or equal to the given number. 2727 */ 2728 floorPowerOfTwo, 2729 /** 2730 * Sets the given quaternion from the [Intrinsic Proper Euler Angles](https://en.wikipedia.org/wiki/Euler_angles) 2731 * defined by the given angles and order. 2732 * 2733 * Rotations are applied to the axes in the order specified by order: 2734 * rotation by angle `a` is applied first, then by angle `b`, then by angle `c`. 2735 * 2736 * @static 2737 * @method 2738 * @param {Quaternion} q - The quaternion to set. 2739 * @param {number} a - The rotation applied to the first axis, in radians. 2740 * @param {number} b - The rotation applied to the second axis, in radians. 2741 * @param {number} c - The rotation applied to the third axis, in radians. 2742 * @param {('XYX'|'XZX'|'YXY'|'YZY'|'ZXZ'|'ZYZ')} order - A string specifying the axes order. 2743 */ 2744 setQuaternionFromProperEuler, 2745 /** 2746 * Normalizes the given value according to the given typed array. 2747 * 2748 * @static 2749 * @method 2750 * @param {number} value - The float value in the range `[0,1]` to normalize. 2751 * @param {TypedArray} array - The typed array that defines the data type of the value. 2752 * @return {number} The normalize value. 2753 */ 2754 normalize, 2755 /** 2756 * Denormalizes the given value according to the given typed array. 2757 * 2758 * @static 2759 * @method 2760 * @param {number} value - The value to denormalize. 2761 * @param {TypedArray} array - The typed array that defines the data type of the value. 2762 * @return {number} The denormalize (float) value in the range `[0,1]`. 2763 */ 2764 denormalize 2765}; 2766var Vector2 = class _Vector2 { 2767 static { 2768 _Vector2.prototype.isVector2 = true; 2769 } 2770 /** 2771 * Constructs a new 2D vector. 2772 * 2773 * @param {number} [x=0] - The x value of this vector. 2774 * @param {number} [y=0] - The y value of this vector. 2775 */ 2776 constructor(x = 0, y = 0) { 2777 this.x = x; 2778 this.y = y; 2779 } 2780 /** 2781 * Alias for {@link Vector2#x}. 2782 * 2783 * @type {number} 2784 */ 2785 get width() { 2786 return this.x; 2787 } 2788 set width(value) { 2789 this.x = value; 2790 } 2791 /** 2792 * Alias for {@link Vector2#y}. 2793 * 2794 * @type {number} 2795 */ 2796 get height() { 2797 return this.y; 2798 } 2799 set height(value) { 2800 this.y = value; 2801 } 2802 /** 2803 * Sets the vector components. 2804 * 2805 * @param {number} x - The value of the x component. 2806 * @param {number} y - The value of the y component. 2807 * @return {Vector2} A reference to this vector. 2808 */ 2809 set(x, y) { 2810 this.x = x; 2811 this.y = y; 2812 return this; 2813 } 2814 /** 2815 * Sets the vector components to the same value. 2816 * 2817 * @param {number} scalar - The value to set for all vector components. 2818 * @return {Vector2} A reference to this vector. 2819 */ 2820 setScalar(scalar) { 2821 this.x = scalar; 2822 this.y = scalar; 2823 return this; 2824 } 2825 /** 2826 * Sets the vector's x component to the given value 2827 * 2828 * @param {number} x - The value to set. 2829 * @return {Vector2} A reference to this vector. 2830 */ 2831 setX(x) { 2832 this.x = x; 2833 return this; 2834 } 2835 /** 2836 * Sets the vector's y component to the given value 2837 * 2838 * @param {number} y - The value to set. 2839 * @return {Vector2} A reference to this vector. 2840 */ 2841 setY(y) { 2842 this.y = y; 2843 return this; 2844 } 2845 /** 2846 * Allows to set a vector component with an index. 2847 * 2848 * @param {number} index - The component index. `0` equals to x, `1` equals to y. 2849 * @param {number} value - The value to set. 2850 * @return {Vector2} A reference to this vector. 2851 */ 2852 setComponent(index, value) { 2853 switch (index) { 2854 case 0: 2855 this.x = value; 2856 break; 2857 case 1: 2858 this.y = value; 2859 break; 2860 default: 2861 throw new Error("index is out of range: " + index); 2862 } 2863 return this; 2864 } 2865 /** 2866 * Returns the value of the vector component which matches the given index. 2867 * 2868 * @param {number} index - The component index. `0` equals to x, `1` equals to y. 2869 * @return {number} A vector component value. 2870 */ 2871 getComponent(index) { 2872 switch (index) { 2873 case 0: 2874 return this.x; 2875 case 1: 2876 return this.y; 2877 default: 2878 throw new Error("index is out of range: " + index); 2879 } 2880 } 2881 /** 2882 * Returns a new vector with copied values from this instance. 2883 * 2884 * @return {Vector2} A clone of this instance. 2885 */ 2886 clone() { 2887 return new this.constructor(this.x, this.y); 2888 } 2889 /** 2890 * Copies the values of the given vector to this instance. 2891 * 2892 * @param {Vector2} v - The vector to copy. 2893 * @return {Vector2} A reference to this vector. 2894 */ 2895 copy(v) { 2896 this.x = v.x; 2897 this.y = v.y; 2898 return this; 2899 } 2900 /** 2901 * Adds the given vector to this instance. 2902 * 2903 * @param {Vector2} v - The vector to add. 2904 * @return {Vector2} A reference to this vector. 2905 */ 2906 add(v) { 2907 this.x += v.x; 2908 this.y += v.y; 2909 return this; 2910 } 2911 /** 2912 * Adds the given scalar value to all components of this instance. 2913 * 2914 * @param {number} s - The scalar to add. 2915 * @return {Vector2} A reference to this vector. 2916 */ 2917 addScalar(s) { 2918 this.x += s; 2919 this.y += s; 2920 return this; 2921 } 2922 /** 2923 * Adds the given vectors and stores the result in this instance. 2924 * 2925 * @param {Vector2} a - The first vector. 2926 * @param {Vector2} b - The second vector. 2927 * @return {Vector2} A reference to this vector. 2928 */ 2929 addVectors(a, b) { 2930 this.x = a.x + b.x; 2931 this.y = a.y + b.y; 2932 return this; 2933 } 2934 /** 2935 * Adds the given vector scaled by the given factor to this instance. 2936 * 2937 * @param {Vector2} v - The vector. 2938 * @param {number} s - The factor that scales `v`. 2939 * @return {Vector2} A reference to this vector. 2940 */ 2941 addScaledVector(v, s) { 2942 this.x += v.x * s; 2943 this.y += v.y * s; 2944 return this; 2945 } 2946 /** 2947 * Subtracts the given vector from this instance. 2948 * 2949 * @param {Vector2} v - The vector to subtract. 2950 * @return {Vector2} A reference to this vector. 2951 */ 2952 sub(v) { 2953 this.x -= v.x; 2954 this.y -= v.y; 2955 return this; 2956 } 2957 /** 2958 * Subtracts the given scalar value from all components of this instance. 2959 * 2960 * @param {number} s - The scalar to subtract. 2961 * @return {Vector2} A reference to this vector. 2962 */ 2963 subScalar(s) { 2964 this.x -= s; 2965 this.y -= s; 2966 return this; 2967 } 2968 /** 2969 * Subtracts the given vectors and stores the result in this instance. 2970 * 2971 * @param {Vector2} a - The first vector. 2972 * @param {Vector2} b - The second vector. 2973 * @return {Vector2} A reference to this vector. 2974 */ 2975 subVectors(a, b) { 2976 this.x = a.x - b.x; 2977 this.y = a.y - b.y; 2978 return this; 2979 } 2980 /** 2981 * Multiplies the given vector with this instance. 2982 * 2983 * @param {Vector2} v - The vector to multiply. 2984 * @return {Vector2} A reference to this vector. 2985 */ 2986 multiply(v) { 2987 this.x *= v.x; 2988 this.y *= v.y; 2989 return this; 2990 } 2991 /** 2992 * Multiplies the given scalar value with all components of this instance. 2993 * 2994 * @param {number} scalar - The scalar to multiply. 2995 * @return {Vector2} A reference to this vector. 2996 */ 2997 multiplyScalar(scalar) { 2998 this.x *= scalar; 2999 this.y *= scalar; 3000 return this; 3001 } 3002 /** 3003 * Divides this instance by the given vector. 3004 * 3005 * @param {Vector2} v - The vector to divide. 3006 * @return {Vector2} A reference to this vector. 3007 */ 3008 divide(v) { 3009 this.x /= v.x; 3010 this.y /= v.y; 3011 return this; 3012 } 3013 /** 3014 * Divides this vector by the given scalar. 3015 * 3016 * @param {number} scalar - The scalar to divide. 3017 * @return {Vector2} A reference to this vector. 3018 */ 3019 divideScalar(scalar) { 3020 return this.multiplyScalar(1 / scalar); 3021 } 3022 /** 3023 * Multiplies this vector (with an implicit 1 as the 3rd component) by 3024 * the given 3x3 matrix. 3025 * 3026 * @param {Matrix3} m - The matrix to apply. 3027 * @return {Vector2} A reference to this vector. 3028 */ 3029 applyMatrix3(m) { 3030 const x = this.x, y = this.y; 3031 const e = m.elements; 3032 this.x = e[0] * x + e[3] * y + e[6]; 3033 this.y = e[1] * x + e[4] * y + e[7]; 3034 return this; 3035 } 3036 /** 3037 * If this vector's x or y value is greater than the given vector's x or y 3038 * value, replace that value with the corresponding min value. 3039 * 3040 * @param {Vector2} v - The vector. 3041 * @return {Vector2} A reference to this vector. 3042 */ 3043 min(v) { 3044 this.x = Math.min(this.x, v.x); 3045 this.y = Math.min(this.y, v.y); 3046 return this; 3047 } 3048 /** 3049 * If this vector's x or y value is less than the given vector's x or y 3050 * value, replace that value with the corresponding max value. 3051 * 3052 * @param {Vector2} v - The vector. 3053 * @return {Vector2} A reference to this vector. 3054 */ 3055 max(v) { 3056 this.x = Math.max(this.x, v.x); 3057 this.y = Math.max(this.y, v.y); 3058 return this; 3059 } 3060 /** 3061 * If this vector's x or y value is greater than the max vector's x or y 3062 * value, it is replaced by the corresponding value. 3063 * If this vector's x or y value is less than the min vector's x or y value, 3064 * it is replaced by the corresponding value. 3065 * 3066 * @param {Vector2} min - The minimum x and y values. 3067 * @param {Vector2} max - The maximum x and y values in the desired range. 3068 * @return {Vector2} A reference to this vector. 3069 */ 3070 clamp(min, max) { 3071 this.x = clamp(this.x, min.x, max.x); 3072 this.y = clamp(this.y, min.y, max.y); 3073 return this; 3074 } 3075 /** 3076 * If this vector's x or y values are greater than the max value, they are 3077 * replaced by the max value. 3078 * If this vector's x or y values are less than the min value, they are 3079 * replaced by the min value. 3080 * 3081 * @param {number} minVal - The minimum value the components will be clamped to. 3082 * @param {number} maxVal - The maximum value the components will be clamped to. 3083 * @return {Vector2} A reference to this vector. 3084 */ 3085 clampScalar(minVal, maxVal) { 3086 this.x = clamp(this.x, minVal, maxVal); 3087 this.y = clamp(this.y, minVal, maxVal); 3088 return this; 3089 } 3090 /** 3091 * If this vector's length is greater than the max value, it is replaced by 3092 * the max value. 3093 * If this vector's length is less than the min value, it is replaced by the 3094 * min value. 3095 * 3096 * @param {number} min - The minimum value the vector length will be clamped to. 3097 * @param {number} max - The maximum value the vector length will be clamped to. 3098 * @return {Vector2} A reference to this vector. 3099 */ 3100 clampLength(min, max) { 3101 const length = this.length(); 3102 return this.divideScalar(length || 1).multiplyScalar(clamp(length, min, max)); 3103 } 3104 /** 3105 * The components of this vector are rounded down to the nearest integer value. 3106 * 3107 * @return {Vector2} A reference to this vector. 3108 */ 3109 floor() { 3110 this.x = Math.floor(this.x); 3111 this.y = Math.floor(this.y); 3112 return this; 3113 } 3114 /** 3115 * The components of this vector are rounded up to the nearest integer value. 3116 * 3117 * @return {Vector2} A reference to this vector. 3118 */ 3119 ceil() { 3120 this.x = Math.ceil(this.x); 3121 this.y = Math.ceil(this.y); 3122 return this; 3123 } 3124 /** 3125 * The components of this vector are rounded to the nearest integer value 3126 * 3127 * @return {Vector2} A reference to this vector. 3128 */ 3129 round() { 3130 this.x = Math.round(this.x); 3131 this.y = Math.round(this.y); 3132 return this; 3133 } 3134 /** 3135 * The components of this vector are rounded towards zero (up if negative, 3136 * down if positive) to an integer value. 3137 * 3138 * @return {Vector2} A reference to this vector. 3139 */ 3140 roundToZero() { 3141 this.x = Math.trunc(this.x); 3142 this.y = Math.trunc(this.y); 3143 return this; 3144 } 3145 /** 3146 * Inverts this vector - i.e. sets x = -x and y = -y. 3147 * 3148 * @return {Vector2} A reference to this vector. 3149 */ 3150 negate() { 3151 this.x = -this.x; 3152 this.y = -this.y; 3153 return this; 3154 } 3155 /** 3156 * Calculates the dot product of the given vector with this instance. 3157 * 3158 * @param {Vector2} v - The vector to compute the dot product with. 3159 * @return {number} The result of the dot product. 3160 */ 3161 dot(v) { 3162 return this.x * v.x + this.y * v.y; 3163 } 3164 /** 3165 * Calculates the cross product of the given vector with this instance. 3166 * 3167 * @param {Vector2} v - The vector to compute the cross product with. 3168 * @return {number} The result of the cross product. 3169 */ 3170 cross(v) { 3171 return this.x * v.y - this.y * v.x; 3172 } 3173 /** 3174 * Computes the square of the Euclidean length (straight-line length) from 3175 * (0, 0) to (x, y). If you are comparing the lengths of vectors, you should 3176 * compare the length squared instead as it is slightly more efficient to calculate. 3177 * 3178 * @return {number} The square length of this vector. 3179 */ 3180 lengthSq() { 3181 return this.x * this.x + this.y * this.y; 3182 } 3183 /** 3184 * Computes the Euclidean length (straight-line length) from (0, 0) to (x, y). 3185 * 3186 * @return {number} The length of this vector. 3187 */ 3188 length() { 3189 return Math.sqrt(this.x * this.x + this.y * this.y); 3190 } 3191 /** 3192 * Computes the Manhattan length of this vector. 3193 * 3194 * @return {number} The length of this vector. 3195 */ 3196 manhattanLength() { 3197 return Math.abs(this.x) + Math.abs(this.y); 3198 } 3199 /** 3200 * Converts this vector to a unit vector - that is, sets it equal to a vector 3201 * with the same direction as this one, but with a vector length of `1`. 3202 * 3203 * @return {Vector2} A reference to this vector. 3204 */ 3205 normalize() { 3206 return this.divideScalar(this.length() || 1); 3207 } 3208 /** 3209 * Computes the angle in radians of this vector with respect to the positive x-axis. 3210 * 3211 * @return {number} The angle in radians. 3212 */ 3213 angle() { 3214 const angle = Math.atan2(-this.y, -this.x) + Math.PI; 3215 return angle; 3216 } 3217 /** 3218 * Returns the angle between the given vector and this instance in radians. 3219 * 3220 * @param {Vector2} v - The vector to compute the angle with. 3221 * @return {number} The angle in radians. 3222 */ 3223 angleTo(v) { 3224 const denominator = Math.sqrt(this.lengthSq() * v.lengthSq()); 3225 if (denominator === 0) return Math.PI / 2; 3226 const theta = this.dot(v) / denominator; 3227 return Math.acos(clamp(theta, -1, 1)); 3228 } 3229 /** 3230 * Computes the distance from the given vector to this instance. 3231 * 3232 * @param {Vector2} v - The vector to compute the distance to. 3233 * @return {number} The distance. 3234 */ 3235 distanceTo(v) { 3236 return Math.sqrt(this.distanceToSquared(v)); 3237 } 3238 /** 3239 * Computes the squared distance from the given vector to this instance. 3240 * If you are just comparing the distance with another distance, you should compare 3241 * the distance squared instead as it is slightly more efficient to calculate. 3242 * 3243 * @param {Vector2} v - The vector to compute the squared distance to. 3244 * @return {number} The squared distance. 3245 */ 3246 distanceToSquared(v) { 3247 const dx = this.x - v.x, dy = this.y - v.y; 3248 return dx * dx + dy * dy; 3249 } 3250 /** 3251 * Computes the Manhattan distance from the given vector to this instance. 3252 * 3253 * @param {Vector2} v - The vector to compute the Manhattan distance to. 3254 * @return {number} The Manhattan distance. 3255 */ 3256 manhattanDistanceTo(v) { 3257 return Math.abs(this.x - v.x) + Math.abs(this.y - v.y); 3258 } 3259 /** 3260 * Sets this vector to a vector with the same direction as this one, but 3261 * with the specified length. 3262 * 3263 * @param {number} length - The new length of this vector. 3264 * @return {Vector2} A reference to this vector. 3265 */ 3266 setLength(length) { 3267 return this.normalize().multiplyScalar(length); 3268 } 3269 /** 3270 * Linearly interpolates between the given vector and this instance, where 3271 * alpha is the percent distance along the line - alpha = 0 will be this 3272 * vector, and alpha = 1 will be the given one. 3273 * 3274 * @param {Vector2} v - The vector to interpolate towards. 3275 * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`. 3276 * @return {Vector2} A reference to this vector. 3277 */ 3278 lerp(v, alpha) { 3279 this.x += (v.x - this.x) * alpha; 3280 this.y += (v.y - this.y) * alpha; 3281 return this; 3282 } 3283 /** 3284 * Linearly interpolates between the given vectors, where alpha is the percent 3285 * distance along the line - alpha = 0 will be first vector, and alpha = 1 will 3286 * be the second one. The result is stored in this instance. 3287 * 3288 * @param {Vector2} v1 - The first vector. 3289 * @param {Vector2} v2 - The second vector. 3290 * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`. 3291 * @return {Vector2} A reference to this vector. 3292 */ 3293 lerpVectors(v1, v2, alpha) { 3294 this.x = v1.x + (v2.x - v1.x) * alpha; 3295 this.y = v1.y + (v2.y - v1.y) * alpha; 3296 return this; 3297 } 3298 /** 3299 * Returns `true` if this vector is equal with the given one. 3300 * 3301 * @param {Vector2} v - The vector to test for equality. 3302 * @return {boolean} Whether this vector is equal with the given one. 3303 */ 3304 equals(v) { 3305 return v.x === this.x && v.y === this.y; 3306 } 3307 /** 3308 * Sets this vector's x value to be `array[ offset ]` and y 3309 * value to be `array[ offset + 1 ]`. 3310 * 3311 * @param {Array<number>} array - An array holding the vector component values. 3312 * @param {number} [offset=0] - The offset into the array. 3313 * @return {Vector2} A reference to this vector. 3314 */ 3315 fromArray(array, offset = 0) { 3316 this.x = array[offset]; 3317 this.y = array[offset + 1]; 3318 return this; 3319 } 3320 /** 3321 * Writes the components of this vector to the given array. If no array is provided, 3322 * the method returns a new instance. 3323 * 3324 * @param {Array<number>} [array=[]] - The target array holding the vector components. 3325 * @param {number} [offset=0] - Index of the first element in the array. 3326 * @return {Array<number>} The vector components. 3327 */ 3328 toArray(array = [], offset = 0) { 3329 array[offset] = this.x; 3330 array[offset + 1] = this.y; 3331 return array; 3332 } 3333 /** 3334 * Sets the components of this vector from the given buffer attribute. 3335 * 3336 * @param {BufferAttribute} attribute - The buffer attribute holding vector data. 3337 * @param {number} index - The index into the attribute. 3338 * @return {Vector2} A reference to this vector. 3339 */ 3340 fromBufferAttribute(attribute, index) { 3341 this.x = attribute.getX(index); 3342 this.y = attribute.getY(index); 3343 return this; 3344 } 3345 /** 3346 * Rotates this vector around the given center by the given angle. 3347 * 3348 * @param {Vector2} center - The point around which to rotate. 3349 * @param {number} angle - The angle to rotate, in radians. 3350 * @return {Vector2} A reference to this vector. 3351 */ 3352 rotateAround(center, angle) { 3353 const c = Math.cos(angle), s = Math.sin(angle); 3354 const x = this.x - center.x; 3355 const y = this.y - center.y; 3356 this.x = x * c - y * s + center.x; 3357 this.y = x * s + y * c + center.y; 3358 return this; 3359 } 3360 /** 3361 * Sets each component of this vector to a pseudo-random value between `0` and 3362 * `1`, excluding `1`. 3363 * 3364 * @return {Vector2} A reference to this vector. 3365 */ 3366 random() { 3367 this.x = Math.random(); 3368 this.y = Math.random(); 3369 return this; 3370 } 3371 *[Symbol.iterator]() { 3372 yield this.x; 3373 yield this.y; 3374 } 3375}; 3376var Quaternion = class { 3377 /** 3378 * Constructs a new quaternion. 3379 * 3380 * @param {number} [x=0] - The x value of this quaternion. 3381 * @param {number} [y=0] - The y value of this quaternion. 3382 * @param {number} [z=0] - The z value of this quaternion. 3383 * @param {number} [w=1] - The w value of this quaternion. 3384 */ 3385 constructor(x = 0, y = 0, z = 0, w = 1) { 3386 this.isQuaternion = true; 3387 this._x = x; 3388 this._y = y; 3389 this._z = z; 3390 this._w = w; 3391 } 3392 /** 3393 * Interpolates between two quaternions via SLERP. This implementation assumes the 3394 * quaternion data are managed in flat arrays. 3395 * 3396 * @param {Array<number>} dst - The destination array. 3397 * @param {number} dstOffset - An offset into the destination array. 3398 * @param {Array<number>} src0 - The source array of the first quaternion. 3399 * @param {number} srcOffset0 - An offset into the first source array. 3400 * @param {Array<number>} src1 - The source array of the second quaternion. 3401 * @param {number} srcOffset1 - An offset into the second source array. 3402 * @param {number} t - The interpolation factor. A value in the range `[0,1]` will interpolate. A value outside the range `[0,1]` will extrapolate. 3403 * @see {@link Quaternion#slerp} 3404 */ 3405 static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) { 3406 let x0 = src0[srcOffset0 + 0], y0 = src0[srcOffset0 + 1], z0 = src0[srcOffset0 + 2], w0 = src0[srcOffset0 + 3]; 3407 let x1 = src1[srcOffset1 + 0], y1 = src1[srcOffset1 + 1], z1 = src1[srcOffset1 + 2], w1 = src1[srcOffset1 + 3]; 3408 if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) { 3409 let dot = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1; 3410 if (dot < 0) { 3411 x1 = -x1; 3412 y1 = -y1; 3413 z1 = -z1; 3414 w1 = -w1; 3415 dot = -dot; 3416 } 3417 let s = 1 - t; 3418 if (dot < 0.9995) { 3419 const theta = Math.acos(dot); 3420 const sin = Math.sin(theta); 3421 s = Math.sin(s * theta) / sin; 3422 t = Math.sin(t * theta) / sin; 3423 x0 = x0 * s + x1 * t; 3424 y0 = y0 * s + y1 * t; 3425 z0 = z0 * s + z1 * t; 3426 w0 = w0 * s + w1 * t; 3427 } else { 3428 x0 = x0 * s + x1 * t; 3429 y0 = y0 * s + y1 * t; 3430 z0 = z0 * s + z1 * t; 3431 w0 = w0 * s + w1 * t; 3432 const f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0); 3433 x0 *= f; 3434 y0 *= f; 3435 z0 *= f; 3436 w0 *= f; 3437 } 3438 } 3439 dst[dstOffset] = x0; 3440 dst[dstOffset + 1] = y0; 3441 dst[dstOffset + 2] = z0; 3442 dst[dstOffset + 3] = w0; 3443 } 3444 /** 3445 * Multiplies two quaternions. This implementation assumes the quaternion data are managed 3446 * in flat arrays. 3447 * 3448 * @param {Array<number>} dst - The destination array. 3449 * @param {number} dstOffset - An offset into the destination array. 3450 * @param {Array<number>} src0 - The source array of the first quaternion. 3451 * @param {number} srcOffset0 - An offset into the first source array. 3452 * @param {Array<number>} src1 - The source array of the second quaternion. 3453 * @param {number} srcOffset1 - An offset into the second source array. 3454 * @return {Array<number>} The destination array. 3455 * @see {@link Quaternion#multiplyQuaternions}. 3456 */ 3457 static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) { 3458 const x0 = src0[srcOffset0]; 3459 const y0 = src0[srcOffset0 + 1]; 3460 const z0 = src0[srcOffset0 + 2]; 3461 const w0 = src0[srcOffset0 + 3]; 3462 const x1 = src1[srcOffset1]; 3463 const y1 = src1[srcOffset1 + 1]; 3464 const z1 = src1[srcOffset1 + 2]; 3465 const w1 = src1[srcOffset1 + 3]; 3466 dst[dstOffset] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1; 3467 dst[dstOffset + 1] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1; 3468 dst[dstOffset + 2] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1; 3469 dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1; 3470 return dst; 3471 } 3472 /** 3473 * The x value of this quaternion. 3474 * 3475 * @type {number} 3476 * @default 0 3477 */ 3478 get x() { 3479 return this._x; 3480 } 3481 set x(value) { 3482 this._x = value; 3483 this._onChangeCallback(); 3484 } 3485 /** 3486 * The y value of this quaternion. 3487 * 3488 * @type {number} 3489 * @default 0 3490 */ 3491 get y() { 3492 return this._y; 3493 } 3494 set y(value) { 3495 this._y = value; 3496 this._onChangeCallback(); 3497 } 3498 /** 3499 * The z value of this quaternion. 3500 * 3501 * @type {number} 3502 * @default 0 3503 */ 3504 get z() { 3505 return this._z; 3506 } 3507 set z(value) { 3508 this._z = value; 3509 this._onChangeCallback(); 3510 } 3511 /** 3512 * The w value of this quaternion. 3513 * 3514 * @type {number} 3515 * @default 1 3516 */ 3517 get w() { 3518 return this._w; 3519 } 3520 set w(value) { 3521 this._w = value; 3522 this._onChangeCallback(); 3523 } 3524 /** 3525 * Sets the quaternion components. 3526 * 3527 * @param {number} x - The x value of this quaternion. 3528 * @param {number} y - The y value of this quaternion. 3529 * @param {number} z - The z value of this quaternion. 3530 * @param {number} w - The w value of this quaternion. 3531 * @return {Quaternion} A reference to this quaternion. 3532 */ 3533 set(x, y, z, w) { 3534 this._x = x; 3535 this._y = y; 3536 this._z = z; 3537 this._w = w; 3538 this._onChangeCallback(); 3539 return this; 3540 } 3541 /** 3542 * Returns a new quaternion with copied values from this instance. 3543 * 3544 * @return {Quaternion} A clone of this instance. 3545 */ 3546 clone() { 3547 return new this.constructor(this._x, this._y, this._z, this._w); 3548 } 3549 /** 3550 * Copies the values of the given quaternion to this instance. 3551 * 3552 * @param {Quaternion} quaternion - The quaternion to copy. 3553 * @return {Quaternion} A reference to this quaternion. 3554 */ 3555 copy(quaternion) { 3556 this._x = quaternion.x; 3557 this._y = quaternion.y; 3558 this._z = quaternion.z; 3559 this._w = quaternion.w; 3560 this._onChangeCallback(); 3561 return this; 3562 } 3563 /** 3564 * Sets this quaternion from the rotation specified by the given 3565 * Euler angles. 3566 * 3567 * @param {Euler} euler - The Euler angles. 3568 * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not. 3569 * @return {Quaternion} A reference to this quaternion. 3570 */ 3571 setFromEuler(euler, update = true) { 3572 const x = euler._x, y = euler._y, z = euler._z, order = euler._order; 3573 const cos = Math.cos; 3574 const sin = Math.sin; 3575 const c1 = cos(x / 2); 3576 const c2 = cos(y / 2); 3577 const c3 = cos(z / 2); 3578 const s1 = sin(x / 2); 3579 const s2 = sin(y / 2); 3580 const s3 = sin(z / 2); 3581 switch (order) { 3582 case "XYZ": 3583 this._x = s1 * c2 * c3 + c1 * s2 * s3; 3584 this._y = c1 * s2 * c3 - s1 * c2 * s3; 3585 this._z = c1 * c2 * s3 + s1 * s2 * c3; 3586 this._w = c1 * c2 * c3 - s1 * s2 * s3; 3587 break; 3588 case "YXZ": 3589 this._x = s1 * c2 * c3 + c1 * s2 * s3; 3590 this._y = c1 * s2 * c3 - s1 * c2 * s3; 3591 this._z = c1 * c2 * s3 - s1 * s2 * c3; 3592 this._w = c1 * c2 * c3 + s1 * s2 * s3; 3593 break; 3594 case "ZXY": 3595 this._x = s1 * c2 * c3 - c1 * s2 * s3; 3596 this._y = c1 * s2 * c3 + s1 * c2 * s3; 3597 this._z = c1 * c2 * s3 + s1 * s2 * c3; 3598 this._w = c1 * c2 * c3 - s1 * s2 * s3; 3599 break; 3600 case "ZYX": 3601 this._x = s1 * c2 * c3 - c1 * s2 * s3; 3602 this._y = c1 * s2 * c3 + s1 * c2 * s3; 3603 this._z = c1 * c2 * s3 - s1 * s2 * c3; 3604 this._w = c1 * c2 * c3 + s1 * s2 * s3; 3605 break; 3606 case "YZX": 3607 this._x = s1 * c2 * c3 + c1 * s2 * s3; 3608 this._y = c1 * s2 * c3 + s1 * c2 * s3; 3609 this._z = c1 * c2 * s3 - s1 * s2 * c3; 3610 this._w = c1 * c2 * c3 - s1 * s2 * s3; 3611 break; 3612 case "XZY": 3613 this._x = s1 * c2 * c3 - c1 * s2 * s3; 3614 this._y = c1 * s2 * c3 - s1 * c2 * s3; 3615 this._z = c1 * c2 * s3 + s1 * s2 * c3; 3616 this._w = c1 * c2 * c3 + s1 * s2 * s3; 3617 break; 3618 default: 3619 warn("Quaternion: .setFromEuler() encountered an unknown order: " + order); 3620 } 3621 if (update === true) this._onChangeCallback(); 3622 return this; 3623 } 3624 /** 3625 * Sets this quaternion from the given axis and angle. 3626 * 3627 * @param {Vector3} axis - The normalized axis. 3628 * @param {number} angle - The angle in radians. 3629 * @return {Quaternion} A reference to this quaternion. 3630 */ 3631 setFromAxisAngle(axis, angle) { 3632 const halfAngle = angle / 2, s = Math.sin(halfAngle); 3633 this._x = axis.x * s; 3634 this._y = axis.y * s; 3635 this._z = axis.z * s; 3636 this._w = Math.cos(halfAngle); 3637 this._onChangeCallback(); 3638 return this; 3639 } 3640 /** 3641 * Sets this quaternion from the given rotation matrix. 3642 * 3643 * @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled). 3644 * @return {Quaternion} A reference to this quaternion. 3645 */ 3646 setFromRotationMatrix(m) { 3647 const te = m.elements, m11 = te[0], m12 = te[4], m13 = te[8], m21 = te[1], m22 = te[5], m23 = te[9], m31 = te[2], m32 = te[6], m33 = te[10], trace = m11 + m22 + m33; 3648 if (trace > 0) { 3649 const s = 0.5 / Math.sqrt(trace + 1); 3650 this._w = 0.25 / s; 3651 this._x = (m32 - m23) * s; 3652 this._y = (m13 - m31) * s; 3653 this._z = (m21 - m12) * s; 3654 } else if (m11 > m22 && m11 > m33) { 3655 const s = 2 * Math.sqrt(1 + m11 - m22 - m33); 3656 this._w = (m32 - m23) / s; 3657 this._x = 0.25 * s; 3658 this._y = (m12 + m21) / s; 3659 this._z = (m13 + m31) / s; 3660 } else if (m22 > m33) { 3661 const s = 2 * Math.sqrt(1 + m22 - m11 - m33); 3662 this._w = (m13 - m31) / s; 3663 this._x = (m12 + m21) / s; 3664 this._y = 0.25 * s; 3665 this._z = (m23 + m32) / s; 3666 } else { 3667 const s = 2 * Math.sqrt(1 + m33 - m11 - m22); 3668 this._w = (m21 - m12) / s; 3669 this._x = (m13 + m31) / s; 3670 this._y = (m23 + m32) / s; 3671 this._z = 0.25 * s; 3672 } 3673 this._onChangeCallback(); 3674 return this; 3675 } 3676 /** 3677 * Sets this quaternion to the rotation required to rotate the direction vector 3678 * `vFrom` to the direction vector `vTo`. 3679 * 3680 * @param {Vector3} vFrom - The first (normalized) direction vector. 3681 * @param {Vector3} vTo - The second (normalized) direction vector. 3682 * @return {Quaternion} A reference to this quaternion. 3683 */ 3684 setFromUnitVectors(vFrom, vTo) { 3685 let r = vFrom.dot(vTo) + 1; 3686 if (r < 1e-8) { 3687 r = 0; 3688 if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) { 3689 this._x = -vFrom.y; 3690 this._y = vFrom.x; 3691 this._z = 0; 3692 this._w = r; 3693 } else { 3694 this._x = 0; 3695 this._y = -vFrom.z; 3696 this._z = vFrom.y; 3697 this._w = r; 3698 } 3699 } else { 3700 this._x = vFrom.y * vTo.z - vFrom.z * vTo.y; 3701 this._y = vFrom.z * vTo.x - vFrom.x * vTo.z; 3702 this._z = vFrom.x * vTo.y - vFrom.y * vTo.x; 3703 this._w = r; 3704 } 3705 return this.normalize(); 3706 } 3707 /** 3708 * Returns the angle between this quaternion and the given one in radians. 3709 * 3710 * @param {Quaternion} q - The quaternion to compute the angle with. 3711 * @return {number} The angle in radians. 3712 */ 3713 angleTo(q) { 3714 return 2 * Math.acos(Math.abs(clamp(this.dot(q), -1, 1))); 3715 } 3716 /** 3717 * Rotates this quaternion by a given angular step to the given quaternion. 3718 * The method ensures that the final quaternion will not overshoot `q`. 3719 * 3720 * @param {Quaternion} q - The target quaternion. 3721 * @param {number} step - The angular step in radians. 3722 * @return {Quaternion} A reference to this quaternion. 3723 */ 3724 rotateTowards(q, step) { 3725 const angle = this.angleTo(q); 3726 if (angle === 0) return this; 3727 const t = Math.min(1, step / angle); 3728 this.slerp(q, t); 3729 return this; 3730 } 3731 /** 3732 * Sets this quaternion to the identity quaternion; that is, to the 3733 * quaternion that represents "no rotation". 3734 * 3735 * @return {Quaternion} A reference to this quaternion. 3736 */ 3737 identity() { 3738 return this.set(0, 0, 0, 1); 3739 } 3740 /** 3741 * Inverts this quaternion via {@link Quaternion#conjugate}. The 3742 * quaternion is assumed to have unit length. 3743 * 3744 * @return {Quaternion} A reference to this quaternion. 3745 */ 3746 invert() { 3747 return this.conjugate(); 3748 } 3749 /** 3750 * Returns the rotational conjugate of this quaternion. The conjugate of a 3751 * quaternion represents the same rotation in the opposite direction about 3752 * the rotational axis. 3753 * 3754 * @return {Quaternion} A reference to this quaternion. 3755 */ 3756 conjugate() { 3757 this._x *= -1; 3758 this._y *= -1; 3759 this._z *= -1; 3760 this._onChangeCallback(); 3761 return this; 3762 } 3763 /** 3764 * Calculates the dot product of this quaternion and the given one. 3765 * 3766 * @param {Quaternion} v - The quaternion to compute the dot product with. 3767 * @return {number} The result of the dot product. 3768 */ 3769 dot(v) { 3770 return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; 3771 } 3772 /** 3773 * Computes the squared Euclidean length (straight-line length) of this quaternion, 3774 * considered as a 4 dimensional vector. This can be useful if you are comparing the 3775 * lengths of two quaternions, as this is a slightly more efficient calculation than 3776 * {@link Quaternion#length}. 3777 * 3778 * @return {number} The squared Euclidean length. 3779 */ 3780 lengthSq() { 3781 return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; 3782 } 3783 /** 3784 * Computes the Euclidean length (straight-line length) of this quaternion, 3785 * considered as a 4 dimensional vector. 3786 * 3787 * @return {number} The Euclidean length. 3788 */ 3789 length() { 3790 return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w); 3791 } 3792 /** 3793 * Normalizes this quaternion - that is, calculated the quaternion that performs 3794 * the same rotation as this one, but has a length equal to `1`. 3795 * 3796 * @return {Quaternion} A reference to this quaternion. 3797 */ 3798 normalize() { 3799 let l = this.length(); 3800 if (l === 0) { 3801 this._x = 0; 3802 this._y = 0; 3803 this._z = 0; 3804 this._w = 1; 3805 } else { 3806 l = 1 / l; 3807 this._x = this._x * l; 3808 this._y = this._y * l; 3809 this._z = this._z * l; 3810 this._w = this._w * l; 3811 } 3812 this._onChangeCallback(); 3813 return this; 3814 } 3815 /** 3816 * Multiplies this quaternion by the given one. 3817 * 3818 * @param {Quaternion} q - The quaternion. 3819 * @return {Quaternion} A reference to this quaternion. 3820 */ 3821 multiply(q) { 3822 return this.multiplyQuaternions(this, q); 3823 } 3824 /** 3825 * Pre-multiplies this quaternion by the given one. 3826 * 3827 * @param {Quaternion} q - The quaternion. 3828 * @return {Quaternion} A reference to this quaternion. 3829 */ 3830 premultiply(q) { 3831 return this.multiplyQuaternions(q, this); 3832 } 3833 /** 3834 * Multiplies the given quaternions and stores the result in this instance. 3835 * 3836 * @param {Quaternion} a - The first quaternion. 3837 * @param {Quaternion} b - The second quaternion. 3838 * @return {Quaternion} A reference to this quaternion. 3839 */ 3840 multiplyQuaternions(a, b) { 3841 const qax = a._x, qay = a._y, qaz = a._z, qaw = a._w; 3842 const qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; 3843 this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; 3844 this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; 3845 this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; 3846 this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; 3847 this._onChangeCallback(); 3848 return this; 3849 } 3850 /** 3851 * Performs a spherical linear interpolation between this quaternion and the target quaternion. 3852 * 3853 * @param {Quaternion} qb - The target quaternion. 3854 * @param {number} t - The interpolation factor. A value in the range `[0,1]` will interpolate. A value outside the range `[0,1]` will extrapolate. 3855 * @return {Quaternion} A reference to this quaternion. 3856 */ 3857 slerp(qb, t) { 3858 let x = qb._x, y = qb._y, z = qb._z, w = qb._w; 3859 let dot = this.dot(qb); 3860 if (dot < 0) { 3861 x = -x; 3862 y = -y; 3863 z = -z; 3864 w = -w; 3865 dot = -dot; 3866 } 3867 let s = 1 - t; 3868 if (dot < 0.9995) { 3869 const theta = Math.acos(dot); 3870 const sin = Math.sin(theta); 3871 s = Math.sin(s * theta) / sin; 3872 t = Math.sin(t * theta) / sin; 3873 this._x = this._x * s + x * t; 3874 this._y = this._y * s + y * t; 3875 this._z = this._z * s + z * t; 3876 this._w = this._w * s + w * t; 3877 this._onChangeCallback(); 3878 } else { 3879 this._x = this._x * s + x * t; 3880 this._y = this._y * s + y * t; 3881 this._z = this._z * s + z * t; 3882 this._w = this._w * s + w * t; 3883 this.normalize(); 3884 } 3885 return this; 3886 } 3887 /** 3888 * Performs a spherical linear interpolation between the given quaternions 3889 * and stores the result in this quaternion. 3890 * 3891 * @param {Quaternion} qa - The source quaternion. 3892 * @param {Quaternion} qb - The target quaternion. 3893 * @param {number} t - The interpolation factor in the closed interval `[0, 1]`. 3894 * @return {Quaternion} A reference to this quaternion. 3895 */ 3896 slerpQuaternions(qa, qb, t) { 3897 return this.copy(qa).slerp(qb, t); 3898 } 3899 /** 3900 * Sets this quaternion to a uniformly random, normalized quaternion. 3901 * 3902 * @return {Quaternion} A reference to this quaternion. 3903 */ 3904 random() { 3905 const theta1 = 2 * Math.PI * Math.random(); 3906 const theta2 = 2 * Math.PI * Math.random(); 3907 const x0 = Math.random(); 3908 const r1 = Math.sqrt(1 - x0); 3909 const r2 = Math.sqrt(x0); 3910 return this.set( 3911 r1 * Math.sin(theta1), 3912 r1 * Math.cos(theta1), 3913 r2 * Math.sin(theta2), 3914 r2 * Math.cos(theta2) 3915 ); 3916 } 3917 /** 3918 * Returns `true` if this quaternion is equal with the given one. 3919 * 3920 * @param {Quaternion} quaternion - The quaternion to test for equality. 3921 * @return {boolean} Whether this quaternion is equal with the given one. 3922 */ 3923 equals(quaternion) { 3924 return quaternion._x === this._x && quaternion._y === this._y && quaternion._z === this._z && quaternion._w === this._w; 3925 } 3926 /** 3927 * Sets this quaternion's components from the given array. 3928 * 3929 * @param {Array<number>} array - An array holding the quaternion component values. 3930 * @param {number} [offset=0] - The offset into the array. 3931 * @return {Quaternion} A reference to this quaternion. 3932 */ 3933 fromArray(array, offset = 0) { 3934 this._x = array[offset]; 3935 this._y = array[offset + 1]; 3936 this._z = array[offset + 2]; 3937 this._w = array[offset + 3]; 3938 this._onChangeCallback(); 3939 return this; 3940 } 3941 /** 3942 * Writes the components of this quaternion to the given array. If no array is provided, 3943 * the method returns a new instance. 3944 * 3945 * @param {Array<number>} [array=[]] - The target array holding the quaternion components. 3946 * @param {number} [offset=0] - Index of the first element in the array. 3947 * @return {Array<number>} The quaternion components. 3948 */ 3949 toArray(array = [], offset = 0) { 3950 array[offset] = this._x; 3951 array[offset + 1] = this._y; 3952 array[offset + 2] = this._z; 3953 array[offset + 3] = this._w; 3954 return array; 3955 } 3956 /** 3957 * Sets the components of this quaternion from the given buffer attribute. 3958 * 3959 * @param {BufferAttribute} attribute - The buffer attribute holding quaternion data. 3960 * @param {number} index - The index into the attribute. 3961 * @return {Quaternion} A reference to this quaternion. 3962 */ 3963 fromBufferAttribute(attribute, index) { 3964 this._x = attribute.getX(index); 3965 this._y = attribute.getY(index); 3966 this._z = attribute.getZ(index); 3967 this._w = attribute.getW(index); 3968 this._onChangeCallback(); 3969 return this; 3970 } 3971 /** 3972 * This methods defines the serialization result of this class. Returns the 3973 * numerical elements of this quaternion in an array of format `[x, y, z, w]`. 3974 * 3975 * @return {Array<number>} The serialized quaternion. 3976 */ 3977 toJSON() { 3978 return this.toArray(); 3979 } 3980 _onChange(callback) { 3981 this._onChangeCallback = callback; 3982 return this; 3983 } 3984 _onChangeCallback() { 3985 } 3986 *[Symbol.iterator]() { 3987 yield this._x; 3988 yield this._y; 3989 yield this._z; 3990 yield this._w; 3991 } 3992}; 3993var Vector3 = class _Vector3 { 3994 static { 3995 _Vector3.prototype.isVector3 = true; 3996 } 3997 /** 3998 * Constructs a new 3D vector. 3999 * 4000 * @param {number} [x=0] - The x value of this vector. 4001 * @param {number} [y=0] - The y value of this vector. 4002 * @param {number} [z=0] - The z value of this vector. 4003 */ 4004 constructor(x = 0, y = 0, z = 0) { 4005 this.x = x; 4006 this.y = y; 4007 this.z = z; 4008 } 4009 /** 4010 * Sets the vector components. 4011 * 4012 * @param {number} x - The value of the x component. 4013 * @param {number} y - The value of the y component. 4014 * @param {number} z - The value of the z component. 4015 * @return {Vector3} A reference to this vector. 4016 */ 4017 set(x, y, z) { 4018 if (z === void 0) z = this.z; 4019 this.x = x; 4020 this.y = y; 4021 this.z = z; 4022 return this; 4023 } 4024 /** 4025 * Sets the vector components to the same value. 4026 * 4027 * @param {number} scalar - The value to set for all vector components. 4028 * @return {Vector3} A reference to this vector. 4029 */ 4030 setScalar(scalar) { 4031 this.x = scalar; 4032 this.y = scalar; 4033 this.z = scalar; 4034 return this; 4035 } 4036 /** 4037 * Sets the vector's x component to the given value. 4038 * 4039 * @param {number} x - The value to set. 4040 * @return {Vector3} A reference to this vector. 4041 */ 4042 setX(x) { 4043 this.x = x; 4044 return this; 4045 } 4046 /** 4047 * Sets the vector's y component to the given value. 4048 * 4049 * @param {number} y - The value to set. 4050 * @return {Vector3} A reference to this vector. 4051 */ 4052 setY(y) { 4053 this.y = y; 4054 return this; 4055 } 4056 /** 4057 * Sets the vector's z component to the given value. 4058 * 4059 * @param {number} z - The value to set. 4060 * @return {Vector3} A reference to this vector. 4061 */ 4062 setZ(z) { 4063 this.z = z; 4064 return this; 4065 } 4066 /** 4067 * Allows to set a vector component with an index. 4068 * 4069 * @param {number} index - The component index. `0` equals to x, `1` equals to y, `2` equals to z. 4070 * @param {number} value - The value to set. 4071 * @return {Vector3} A reference to this vector. 4072 */ 4073 setComponent(index, value) { 4074 switch (index) { 4075 case 0: 4076 this.x = value; 4077 break; 4078 case 1: 4079 this.y = value; 4080 break; 4081 case 2: 4082 this.z = value; 4083 break; 4084 default: 4085 throw new Error("index is out of range: " + index); 4086 } 4087 return this; 4088 } 4089 /** 4090 * Returns the value of the vector component which matches the given index. 4091 * 4092 * @param {number} index - The component index. `0` equals to x, `1` equals to y, `2` equals to z. 4093 * @return {number} A vector component value. 4094 */ 4095 getComponent(index) { 4096 switch (index) { 4097 case 0: 4098 return this.x; 4099 case 1: 4100 return this.y; 4101 case 2: 4102 return this.z; 4103 default: 4104 throw new Error("index is out of range: " + index); 4105 } 4106 } 4107 /** 4108 * Returns a new vector with copied values from this instance. 4109 * 4110 * @return {Vector3} A clone of this instance. 4111 */ 4112 clone() { 4113 return new this.constructor(this.x, this.y, this.z); 4114 } 4115 /** 4116 * Copies the values of the given vector to this instance. 4117 * 4118 * @param {Vector3} v - The vector to copy. 4119 * @return {Vector3} A reference to this vector. 4120 */ 4121 copy(v) { 4122 this.x = v.x; 4123 this.y = v.y; 4124 this.z = v.z; 4125 return this; 4126 } 4127 /** 4128 * Adds the given vector to this instance. 4129 * 4130 * @param {Vector3} v - The vector to add. 4131 * @return {Vector3} A reference to this vector. 4132 */ 4133 add(v) { 4134 this.x += v.x; 4135 this.y += v.y; 4136 this.z += v.z; 4137 return this; 4138 } 4139 /** 4140 * Adds the given scalar value to all components of this instance. 4141 * 4142 * @param {number} s - The scalar to add. 4143 * @return {Vector3} A reference to this vector. 4144 */ 4145 addScalar(s) { 4146 this.x += s; 4147 this.y += s; 4148 this.z += s; 4149 return this; 4150 } 4151 /** 4152 * Adds the given vectors and stores the result in this instance. 4153 * 4154 * @param {Vector3} a - The first vector. 4155 * @param {Vector3} b - The second vector. 4156 * @return {Vector3} A reference to this vector. 4157 */ 4158 addVectors(a, b) { 4159 this.x = a.x + b.x; 4160 this.y = a.y + b.y; 4161 this.z = a.z + b.z; 4162 return this; 4163 } 4164 /** 4165 * Adds the given vector scaled by the given factor to this instance. 4166 * 4167 * @param {Vector3|Vector4} v - The vector. 4168 * @param {number} s - The factor that scales `v`. 4169 * @return {Vector3} A reference to this vector. 4170 */ 4171 addScaledVector(v, s) { 4172 this.x += v.x * s; 4173 this.y += v.y * s; 4174 this.z += v.z * s; 4175 return this; 4176 } 4177 /** 4178 * Subtracts the given vector from this instance. 4179 * 4180 * @param {Vector3} v - The vector to subtract. 4181 * @return {Vector3} A reference to this vector. 4182 */ 4183 sub(v) { 4184 this.x -= v.x; 4185 this.y -= v.y; 4186 this.z -= v.z; 4187 return this; 4188 } 4189 /** 4190 * Subtracts the given scalar value from all components of this instance. 4191 * 4192 * @param {number} s - The scalar to subtract. 4193 * @return {Vector3} A reference to this vector. 4194 */ 4195 subScalar(s) { 4196 this.x -= s; 4197 this.y -= s; 4198 this.z -= s; 4199 return this; 4200 } 4201 /** 4202 * Subtracts the given vectors and stores the result in this instance. 4203 * 4204 * @param {Vector3} a - The first vector. 4205 * @param {Vector3} b - The second vector. 4206 * @return {Vector3} A reference to this vector. 4207 */ 4208 subVectors(a, b) { 4209 this.x = a.x - b.x; 4210 this.y = a.y - b.y; 4211 this.z = a.z - b.z; 4212 return this; 4213 } 4214 /** 4215 * Multiplies the given vector with this instance. 4216 * 4217 * @param {Vector3} v - The vector to multiply. 4218 * @return {Vector3} A reference to this vector. 4219 */ 4220 multiply(v) { 4221 this.x *= v.x; 4222 this.y *= v.y; 4223 this.z *= v.z; 4224 return this; 4225 } 4226 /** 4227 * Multiplies the given scalar value with all components of this instance. 4228 * 4229 * @param {number} scalar - The scalar to multiply. 4230 * @return {Vector3} A reference to this vector. 4231 */ 4232 multiplyScalar(scalar) { 4233 this.x *= scalar; 4234 this.y *= scalar; 4235 this.z *= scalar; 4236 return this; 4237 } 4238 /** 4239 * Multiplies the given vectors and stores the result in this instance. 4240 * 4241 * @param {Vector3} a - The first vector. 4242 * @param {Vector3} b - The second vector. 4243 * @return {Vector3} A reference to this vector. 4244 */ 4245 multiplyVectors(a, b) { 4246 this.x = a.x * b.x; 4247 this.y = a.y * b.y; 4248 this.z = a.z * b.z; 4249 return this; 4250 } 4251 /** 4252 * Applies the given Euler rotation to this vector. 4253 * 4254 * @param {Euler} euler - The Euler angles. 4255 * @return {Vector3} A reference to this vector. 4256 */ 4257 applyEuler(euler) { 4258 return this.applyQuaternion(_quaternion$5.setFromEuler(euler)); 4259 } 4260 /** 4261 * Applies a rotation specified by an axis and an angle to this vector. 4262 * 4263 * @param {Vector3} axis - A normalized vector representing the rotation axis. 4264 * @param {number} angle - The angle in radians. 4265 * @return {Vector3} A reference to this vector. 4266 */ 4267 applyAxisAngle(axis, angle) { 4268 return this.applyQuaternion(_quaternion$5.setFromAxisAngle(axis, angle)); 4269 } 4270 /** 4271 * Multiplies this vector with the given 3x3 matrix. 4272 * 4273 * @param {Matrix3} m - The 3x3 matrix. 4274 * @return {Vector3} A reference to this vector. 4275 */ 4276 applyMatrix3(m) { 4277 const x = this.x, y = this.y, z = this.z; 4278 const e = m.elements; 4279 this.x = e[0] * x + e[3] * y + e[6] * z; 4280 this.y = e[1] * x + e[4] * y + e[7] * z; 4281 this.z = e[2] * x + e[5] * y + e[8] * z; 4282 return this; 4283 } 4284 /** 4285 * Multiplies this vector by the given normal matrix and normalizes 4286 * the result. 4287 * 4288 * @param {Matrix3} m - The normal matrix. 4289 * @return {Vector3} A reference to this vector. 4290 */ 4291 applyNormalMatrix(m) { 4292 return this.applyMatrix3(m).normalize(); 4293 } 4294 /** 4295 * Multiplies this vector (with an implicit 1 in the 4th dimension) by m, and 4296 * divides by perspective. 4297 * 4298 * @param {Matrix4} m - The matrix to apply. 4299 * @return {Vector3} A reference to this vector. 4300 */ 4301 applyMatrix4(m) { 4302 const x = this.x, y = this.y, z = this.z; 4303 const e = m.elements; 4304 const w = 1 / (e[3] * x + e[7] * y + e[11] * z + e[15]); 4305 this.x = (e[0] * x + e[4] * y + e[8] * z + e[12]) * w; 4306 this.y = (e[1] * x + e[5] * y + e[9] * z + e[13]) * w; 4307 this.z = (e[2] * x + e[6] * y + e[10] * z + e[14]) * w; 4308 return this; 4309 } 4310 /** 4311 * Applies the given Quaternion to this vector. 4312 * 4313 * @param {Quaternion} q - The Quaternion. 4314 * @return {Vector3} A reference to this vector. 4315 */ 4316 applyQuaternion(q) { 4317 const vx = this.x, vy = this.y, vz = this.z; 4318 const qx = q.x, qy = q.y, qz = q.z, qw = q.w; 4319 const tx = 2 * (qy * vz - qz * vy); 4320 const ty = 2 * (qz * vx - qx * vz); 4321 const tz = 2 * (qx * vy - qy * vx); 4322 this.x = vx + qw * tx + qy * tz - qz * ty; 4323 this.y = vy + qw * ty + qz * tx - qx * tz; 4324 this.z = vz + qw * tz + qx * ty - qy * tx; 4325 return this; 4326 } 4327 /** 4328 * Projects this vector from world space into the camera's normalized 4329 * device coordinate (NDC) space. 4330 * 4331 * @param {Camera} camera - The camera. 4332 * @return {Vector3} A reference to this vector. 4333 */ 4334 project(camera) { 4335 return this.applyMatrix4(camera.matrixWorldInverse).applyMatrix4(camera.projectionMatrix); 4336 } 4337 /** 4338 * Unprojects this vector from the camera's normalized device coordinate (NDC) 4339 * space into world space. 4340 * 4341 * @param {Camera} camera - The camera. 4342 * @return {Vector3} A reference to this vector. 4343 */ 4344 unproject(camera) { 4345 return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld); 4346 } 4347 /** 4348 * Transforms the direction of this vector by a matrix (the upper left 3 x 3 4349 * subset of the given 4x4 matrix and then normalizes the result. 4350 * 4351 * @param {Matrix4} m - The matrix. 4352 * @return {Vector3} A reference to this vector. 4353 */ 4354 transformDirection(m) { 4355 const x = this.x, y = this.y, z = this.z; 4356 const e = m.elements; 4357 this.x = e[0] * x + e[4] * y + e[8] * z; 4358 this.y = e[1] * x + e[5] * y + e[9] * z; 4359 this.z = e[2] * x + e[6] * y + e[10] * z; 4360 return this.normalize(); 4361 } 4362 /** 4363 * Divides this instance by the given vector. 4364 * 4365 * @param {Vector3} v - The vector to divide. 4366 * @return {Vector3} A reference to this vector. 4367 */ 4368 divide(v) { 4369 this.x /= v.x; 4370 this.y /= v.y; 4371 this.z /= v.z; 4372 return this; 4373 } 4374 /** 4375 * Divides this vector by the given scalar. 4376 * 4377 * @param {number} scalar - The scalar to divide. 4378 * @return {Vector3} A reference to this vector. 4379 */ 4380 divideScalar(scalar) { 4381 return this.multiplyScalar(1 / scalar); 4382 } 4383 /** 4384 * If this vector's x, y or z value is greater than the given vector's x, y or z 4385 * value, replace that value with the corresponding min value. 4386 * 4387 * @param {Vector3} v - The vector. 4388 * @return {Vector3} A reference to this vector. 4389 */ 4390 min(v) { 4391 this.x = Math.min(this.x, v.x); 4392 this.y = Math.min(this.y, v.y); 4393 this.z = Math.min(this.z, v.z); 4394 return this; 4395 } 4396 /** 4397 * If this vector's x, y or z value is less than the given vector's x, y or z 4398 * value, replace that value with the corresponding max value. 4399 * 4400 * @param {Vector3} v - The vector. 4401 * @return {Vector3} A reference to this vector. 4402 */ 4403 max(v) { 4404 this.x = Math.max(this.x, v.x); 4405 this.y = Math.max(this.y, v.y); 4406 this.z = Math.max(this.z, v.z); 4407 return this; 4408 } 4409 /** 4410 * If this vector's x, y or z value is greater than the max vector's x, y or z 4411 * value, it is replaced by the corresponding value. 4412 * If this vector's x, y or z value is less than the min vector's x, y or z value, 4413 * it is replaced by the corresponding value. 4414 * 4415 * @param {Vector3} min - The minimum x, y and z values. 4416 * @param {Vector3} max - The maximum x, y and z values in the desired range. 4417 * @return {Vector3} A reference to this vector. 4418 */ 4419 clamp(min, max) { 4420 this.x = clamp(this.x, min.x, max.x); 4421 this.y = clamp(this.y, min.y, max.y); 4422 this.z = clamp(this.z, min.z, max.z); 4423 return this; 4424 } 4425 /** 4426 * If this vector's x, y or z values are greater than the max value, they are 4427 * replaced by the max value. 4428 * If this vector's x, y or z values are less than the min value, they are 4429 * replaced by the min value. 4430 * 4431 * @param {number} minVal - The minimum value the components will be clamped to. 4432 * @param {number} maxVal - The maximum value the components will be clamped to. 4433 * @return {Vector3} A reference to this vector. 4434 */ 4435 clampScalar(minVal, maxVal) { 4436 this.x = clamp(this.x, minVal, maxVal); 4437 this.y = clamp(this.y, minVal, maxVal); 4438 this.z = clamp(this.z, minVal, maxVal); 4439 return this; 4440 } 4441 /** 4442 * If this vector's length is greater than the max value, it is replaced by 4443 * the max value. 4444 * If this vector's length is less than the min value, it is replaced by the 4445 * min value. 4446 * 4447 * @param {number} min - The minimum value the vector length will be clamped to. 4448 * @param {number} max - The maximum value the vector length will be clamped to. 4449 * @return {Vector3} A reference to this vector. 4450 */ 4451 clampLength(min, max) { 4452 const length = this.length(); 4453 return this.divideScalar(length || 1).multiplyScalar(clamp(length, min, max)); 4454 } 4455 /** 4456 * The components of this vector are rounded down to the nearest integer value. 4457 * 4458 * @return {Vector3} A reference to this vector. 4459 */ 4460 floor() { 4461 this.x = Math.floor(this.x); 4462 this.y = Math.floor(this.y); 4463 this.z = Math.floor(this.z); 4464 return this; 4465 } 4466 /** 4467 * The components of this vector are rounded up to the nearest integer value. 4468 * 4469 * @return {Vector3} A reference to this vector. 4470 */ 4471 ceil() { 4472 this.x = Math.ceil(this.x); 4473 this.y = Math.ceil(this.y); 4474 this.z = Math.ceil(this.z); 4475 return this; 4476 } 4477 /** 4478 * The components of this vector are rounded to the nearest integer value 4479 * 4480 * @return {Vector3} A reference to this vector. 4481 */ 4482 round() { 4483 this.x = Math.round(this.x); 4484 this.y = Math.round(this.y); 4485 this.z = Math.round(this.z); 4486 return this; 4487 } 4488 /** 4489 * The components of this vector are rounded towards zero (up if negative, 4490 * down if positive) to an integer value. 4491 * 4492 * @return {Vector3} A reference to this vector. 4493 */ 4494 roundToZero() { 4495 this.x = Math.trunc(this.x); 4496 this.y = Math.trunc(this.y); 4497 this.z = Math.trunc(this.z); 4498 return this; 4499 } 4500 /** 4501 * Inverts this vector - i.e. sets x = -x, y = -y and z = -z. 4502 * 4503 * @return {Vector3} A reference to this vector. 4504 */ 4505 negate() { 4506 this.x = -this.x; 4507 this.y = -this.y; 4508 this.z = -this.z; 4509 return this; 4510 } 4511 /** 4512 * Calculates the dot product of the given vector with this instance. 4513 * 4514 * @param {Vector3} v - The vector to compute the dot product with. 4515 * @return {number} The result of the dot product. 4516 */ 4517 dot(v) { 4518 return this.x * v.x + this.y * v.y + this.z * v.z; 4519 } 4520 /** 4521 * Computes the square of the Euclidean length (straight-line length) from 4522 * (0, 0, 0) to (x, y, z). If you are comparing the lengths of vectors, you should 4523 * compare the length squared instead as it is slightly more efficient to calculate. 4524 * 4525 * @return {number} The square length of this vector. 4526 */ 4527 lengthSq() { 4528 return this.x * this.x + this.y * this.y + this.z * this.z; 4529 } 4530 /** 4531 * Computes the Euclidean length (straight-line length) from (0, 0, 0) to (x, y, z). 4532 * 4533 * @return {number} The length of this vector. 4534 */ 4535 length() { 4536 return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); 4537 } 4538 /** 4539 * Computes the Manhattan length of this vector. 4540 * 4541 * @return {number} The length of this vector. 4542 */ 4543 manhattanLength() { 4544 return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z); 4545 } 4546 /** 4547 * Converts this vector to a unit vector - that is, sets it equal to a vector 4548 * with the same direction as this one, but with a vector length of `1`. 4549 * 4550 * @return {Vector3} A reference to this vector. 4551 */ 4552 normalize() { 4553 return this.divideScalar(this.length() || 1); 4554 } 4555 /** 4556 * Sets this vector to a vector with the same direction as this one, but 4557 * with the specified length. 4558 * 4559 * @param {number} length - The new length of this vector. 4560 * @return {Vector3} A reference to this vector. 4561 */ 4562 setLength(length) { 4563 return this.normalize().multiplyScalar(length); 4564 } 4565 /** 4566 * Linearly interpolates between the given vector and this instance, where 4567 * alpha is the percent distance along the line - alpha = 0 will be this 4568 * vector, and alpha = 1 will be the given one. 4569 * 4570 * @param {Vector3} v - The vector to interpolate towards. 4571 * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`. 4572 * @return {Vector3} A reference to this vector. 4573 */ 4574 lerp(v, alpha) { 4575 this.x += (v.x - this.x) * alpha; 4576 this.y += (v.y - this.y) * alpha; 4577 this.z += (v.z - this.z) * alpha; 4578 return this; 4579 } 4580 /** 4581 * Linearly interpolates between the given vectors, where alpha is the percent 4582 * distance along the line - alpha = 0 will be first vector, and alpha = 1 will 4583 * be the second one. The result is stored in this instance. 4584 * 4585 * @param {Vector3} v1 - The first vector. 4586 * @param {Vector3} v2 - The second vector. 4587 * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`. 4588 * @return {Vector3} A reference to this vector. 4589 */ 4590 lerpVectors(v1, v2, alpha) { 4591 this.x = v1.x + (v2.x - v1.x) * alpha; 4592 this.y = v1.y + (v2.y - v1.y) * alpha; 4593 this.z = v1.z + (v2.z - v1.z) * alpha; 4594 return this; 4595 } 4596 /** 4597 * Calculates the cross product of the given vector with this instance. 4598 * 4599 * @param {Vector3} v - The vector to compute the cross product with. 4600 * @return {Vector3} The result of the cross product. 4601 */ 4602 cross(v) { 4603 return this.crossVectors(this, v); 4604 } 4605 /** 4606 * Calculates the cross product of the given vectors and stores the result 4607 * in this instance. 4608 * 4609 * @param {Vector3} a - The first vector. 4610 * @param {Vector3} b - The second vector. 4611 * @return {Vector3} A reference to this vector. 4612 */ 4613 crossVectors(a, b) { 4614 const ax = a.x, ay = a.y, az = a.z; 4615 const bx = b.x, by = b.y, bz = b.z; 4616 this.x = ay * bz - az * by; 4617 this.y = az * bx - ax * bz; 4618 this.z = ax * by - ay * bx; 4619 return this; 4620 } 4621 /** 4622 * Projects this vector onto the given one. 4623 * 4624 * @param {Vector3} v - The vector to project to. 4625 * @return {Vector3} A reference to this vector. 4626 */ 4627 projectOnVector(v) { 4628 const denominator = v.lengthSq(); 4629 if (denominator === 0) return this.set(0, 0, 0); 4630 const scalar = v.dot(this) / denominator; 4631 return this.copy(v).multiplyScalar(scalar); 4632 } 4633 /** 4634 * Projects this vector onto a plane by subtracting this 4635 * vector projected onto the plane's normal from this vector. 4636 * 4637 * @param {Vector3} planeNormal - The plane normal. 4638 * @return {Vector3} A reference to this vector. 4639 */ 4640 projectOnPlane(planeNormal) { 4641 _vector$c.copy(this).projectOnVector(planeNormal); 4642 return this.sub(_vector$c); 4643 } 4644 /** 4645 * Reflects this vector off a plane orthogonal to the given normal vector. 4646 * 4647 * @param {Vector3} normal - The (normalized) normal vector. 4648 * @return {Vector3} A reference to this vector. 4649 */ 4650 reflect(normal) { 4651 return this.sub(_vector$c.copy(normal).multiplyScalar(2 * this.dot(normal))); 4652 } 4653 /** 4654 * Returns the angle between the given vector and this instance in radians. 4655 * 4656 * @param {Vector3} v - The vector to compute the angle with. 4657 * @return {number} The angle in radians. 4658 */ 4659 angleTo(v) { 4660 const denominator = Math.sqrt(this.lengthSq() * v.lengthSq()); 4661 if (denominator === 0) return Math.PI / 2; 4662 const theta = this.dot(v) / denominator; 4663 return Math.acos(clamp(theta, -1, 1)); 4664 } 4665 /** 4666 * Computes the distance from the given vector to this instance. 4667 * 4668 * @param {Vector3} v - The vector to compute the distance to. 4669 * @return {number} The distance. 4670 */ 4671 distanceTo(v) { 4672 return Math.sqrt(this.distanceToSquared(v)); 4673 } 4674 /** 4675 * Computes the squared distance from the given vector to this instance. 4676 * If you are just comparing the distance with another distance, you should compare 4677 * the distance squared instead as it is slightly more efficient to calculate. 4678 * 4679 * @param {Vector3} v - The vector to compute the squared distance to. 4680 * @return {number} The squared distance. 4681 */ 4682 distanceToSquared(v) { 4683 const dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; 4684 return dx * dx + dy * dy + dz * dz; 4685 } 4686 /** 4687 * Computes the Manhattan distance from the given vector to this instance. 4688 * 4689 * @param {Vector3} v - The vector to compute the Manhattan distance to. 4690 * @return {number} The Manhattan distance. 4691 */ 4692 manhattanDistanceTo(v) { 4693 return Math.abs(this.x - v.x) + Math.abs(this.y - v.y) + Math.abs(this.z - v.z); 4694 } 4695 /** 4696 * Sets the vector components from the given spherical coordinates. 4697 * 4698 * @param {Spherical} s - The spherical coordinates. 4699 * @return {Vector3} A reference to this vector. 4700 */ 4701 setFromSpherical(s) { 4702 return this.setFromSphericalCoords(s.radius, s.phi, s.theta); 4703 } 4704 /** 4705 * Sets the vector components from the given spherical coordinates. 4706 * 4707 * @param {number} radius - The radius. 4708 * @param {number} phi - The phi angle in radians. 4709 * @param {number} theta - The theta angle in radians. 4710 * @return {Vector3} A reference to this vector. 4711 */ 4712 setFromSphericalCoords(radius, phi, theta) { 4713 const sinPhiRadius = Math.sin(phi) * radius; 4714 this.x = sinPhiRadius * Math.sin(theta); 4715 this.y = Math.cos(phi) * radius; 4716 this.z = sinPhiRadius * Math.cos(theta); 4717 return this; 4718 } 4719 /** 4720 * Sets the vector components from the given cylindrical coordinates. 4721 * 4722 * @param {Cylindrical} c - The cylindrical coordinates. 4723 * @return {Vector3} A reference to this vector. 4724 */ 4725 setFromCylindrical(c) { 4726 return this.setFromCylindricalCoords(c.radius, c.theta, c.y); 4727 } 4728 /** 4729 * Sets the vector components from the given cylindrical coordinates. 4730 * 4731 * @param {number} radius - The radius. 4732 * @param {number} theta - The theta angle in radians. 4733 * @param {number} y - The y value. 4734 * @return {Vector3} A reference to this vector. 4735 */ 4736 setFromCylindricalCoords(radius, theta, y) { 4737 this.x = radius * Math.sin(theta); 4738 this.y = y; 4739 this.z = radius * Math.cos(theta); 4740 return this; 4741 } 4742 /** 4743 * Sets the vector components to the position elements of the 4744 * given transformation matrix. 4745 * 4746 * @param {Matrix4} m - The 4x4 matrix. 4747 * @return {Vector3} A reference to this vector. 4748 */ 4749 setFromMatrixPosition(m) { 4750 const e = m.elements; 4751 this.x = e[12]; 4752 this.y = e[13]; 4753 this.z = e[14]; 4754 return this; 4755 } 4756 /** 4757 * Sets the vector components to the scale elements of the 4758 * given transformation matrix. 4759 * 4760 * @param {Matrix4} m - The 4x4 matrix. 4761 * @return {Vector3} A reference to this vector. 4762 */ 4763 setFromMatrixScale(m) { 4764 const sx = this.setFromMatrixColumn(m, 0).length(); 4765 const sy = this.setFromMatrixColumn(m, 1).length(); 4766 const sz = this.setFromMatrixColumn(m, 2).length(); 4767 this.x = sx; 4768 this.y = sy; 4769 this.z = sz; 4770 return this; 4771 } 4772 /** 4773 * Sets the vector components from the specified matrix column. 4774 * 4775 * @param {Matrix4} m - The 4x4 matrix. 4776 * @param {number} index - The column index. 4777 * @return {Vector3} A reference to this vector. 4778 */ 4779 setFromMatrixColumn(m, index) { 4780 return this.fromArray(m.elements, index * 4); 4781 } 4782 /** 4783 * Sets the vector components from the specified matrix column. 4784 * 4785 * @param {Matrix3} m - The 3x3 matrix. 4786 * @param {number} index - The column index. 4787 * @return {Vector3} A reference to this vector. 4788 */ 4789 setFromMatrix3Column(m, index) { 4790 return this.fromArray(m.elements, index * 3); 4791 } 4792 /** 4793 * Sets the vector components from the given Euler angles. 4794 * 4795 * @param {Euler} e - The Euler angles to set. 4796 * @return {Vector3} A reference to this vector. 4797 */ 4798 setFromEuler(e) { 4799 this.x = e._x; 4800 this.y = e._y; 4801 this.z = e._z; 4802 return this; 4803 } 4804 /** 4805 * Sets the vector components from the RGB components of the 4806 * given color. 4807 * 4808 * @param {Color} c - The color to set. 4809 * @return {Vector3} A reference to this vector. 4810 */ 4811 setFromColor(c) { 4812 this.x = c.r; 4813 this.y = c.g; 4814 this.z = c.b; 4815 return this; 4816 } 4817 /** 4818 * Returns `true` if this vector is equal with the given one. 4819 * 4820 * @param {Vector3} v - The vector to test for equality. 4821 * @return {boolean} Whether this vector is equal with the given one. 4822 */ 4823 equals(v) { 4824 return v.x === this.x && v.y === this.y && v.z === this.z; 4825 } 4826 /** 4827 * Sets this vector's x value to be `array[ offset ]`, y value to be `array[ offset + 1 ]` 4828 * and z value to be `array[ offset + 2 ]`. 4829 * 4830 * @param {Array<number>} array - An array holding the vector component values. 4831 * @param {number} [offset=0] - The offset into the array. 4832 * @return {Vector3} A reference to this vector. 4833 */ 4834 fromArray(array, offset = 0) { 4835 this.x = array[offset]; 4836 this.y = array[offset + 1]; 4837 this.z = array[offset + 2]; 4838 return this; 4839 } 4840 /** 4841 * Writes the components of this vector to the given array. If no array is provided, 4842 * the method returns a new instance. 4843 * 4844 * @param {Array<number>} [array=[]] - The target array holding the vector components. 4845 * @param {number} [offset=0] - Index of the first element in the array. 4846 * @return {Array<number>} The vector components. 4847 */ 4848 toArray(array = [], offset = 0) { 4849 array[offset] = this.x; 4850 array[offset + 1] = this.y; 4851 array[offset + 2] = this.z; 4852 return array; 4853 } 4854 /** 4855 * Sets the components of this vector from the given buffer attribute. 4856 * 4857 * @param {BufferAttribute} attribute - The buffer attribute holding vector data. 4858 * @param {number} index - The index into the attribute. 4859 * @return {Vector3} A reference to this vector. 4860 */ 4861 fromBufferAttribute(attribute, index) { 4862 this.x = attribute.getX(index); 4863 this.y = attribute.getY(index); 4864 this.z = attribute.getZ(index); 4865 return this; 4866 } 4867 /** 4868 * Sets each component of this vector to a pseudo-random value between `0` and 4869 * `1`, excluding `1`. 4870 * 4871 * @return {Vector3} A reference to this vector. 4872 */ 4873 random() { 4874 this.x = Math.random(); 4875 this.y = Math.random(); 4876 this.z = Math.random(); 4877 return this; 4878 } 4879 /** 4880 * Sets this vector to a uniformly random point on a unit sphere. 4881 * 4882 * @return {Vector3} A reference to this vector. 4883 */ 4884 randomDirection() { 4885 const theta = Math.random() * Math.PI * 2; 4886 const u = Math.random() * 2 - 1; 4887 const c = Math.sqrt(1 - u * u); 4888 this.x = c * Math.cos(theta); 4889 this.y = u; 4890 this.z = c * Math.sin(theta); 4891 return this; 4892 } 4893 *[Symbol.iterator]() { 4894 yield this.x; 4895 yield this.y; 4896 yield this.z; 4897 } 4898}; 4899var _vector$c = /* @__PURE__ */ new Vector3(); 4900var _quaternion$5 = /* @__PURE__ */ new Quaternion(); 4901var Matrix3 = class _Matrix3 { 4902 static { 4903 _Matrix3.prototype.isMatrix3 = true; 4904 } 4905 /** 4906 * Constructs a new 3x3 matrix. The arguments are supposed to be 4907 * in row-major order. If no arguments are provided, the constructor 4908 * initializes the matrix as an identity matrix. 4909 * 4910 * @param {number} [n11] - 1-1 matrix element. 4911 * @param {number} [n12] - 1-2 matrix element. 4912 * @param {number} [n13] - 1-3 matrix element. 4913 * @param {number} [n21] - 2-1 matrix element. 4914 * @param {number} [n22] - 2-2 matrix element. 4915 * @param {number} [n23] - 2-3 matrix element. 4916 * @param {number} [n31] - 3-1 matrix element. 4917 * @param {number} [n32] - 3-2 matrix element. 4918 * @param {number} [n33] - 3-3 matrix element. 4919 */ 4920 constructor(n11, n12, n13, n21, n22, n23, n31, n32, n33) { 4921 this.elements = [ 4922 1, 4923 0, 4924 0, 4925 0, 4926 1, 4927 0, 4928 0, 4929 0, 4930 1 4931 ]; 4932 if (n11 !== void 0) { 4933 this.set(n11, n12, n13, n21, n22, n23, n31, n32, n33); 4934 } 4935 } 4936 /** 4937 * Sets the elements of the matrix.The arguments are supposed to be 4938 * in row-major order. 4939 * 4940 * @param {number} [n11] - 1-1 matrix element. 4941 * @param {number} [n12] - 1-2 matrix element. 4942 * @param {number} [n13] - 1-3 matrix element. 4943 * @param {number} [n21] - 2-1 matrix element. 4944 * @param {number} [n22] - 2-2 matrix element. 4945 * @param {number} [n23] - 2-3 matrix element. 4946 * @param {number} [n31] - 3-1 matrix element. 4947 * @param {number} [n32] - 3-2 matrix element. 4948 * @param {number} [n33] - 3-3 matrix element. 4949 * @return {Matrix3} A reference to this matrix. 4950 */ 4951 set(n11, n12, n13, n21, n22, n23, n31, n32, n33) { 4952 const te = this.elements; 4953 te[0] = n11; 4954 te[1] = n21; 4955 te[2] = n31; 4956 te[3] = n12; 4957 te[4] = n22; 4958 te[5] = n32; 4959 te[6] = n13; 4960 te[7] = n23; 4961 te[8] = n33; 4962 return this; 4963 } 4964 /** 4965 * Sets this matrix to the 3x3 identity matrix. 4966 * 4967 * @return {Matrix3} A reference to this matrix. 4968 */ 4969 identity() { 4970 this.set( 4971 1, 4972 0, 4973 0, 4974 0, 4975 1, 4976 0, 4977 0, 4978 0, 4979 1 4980 ); 4981 return this; 4982 } 4983 /** 4984 * Copies the values of the given matrix to this instance. 4985 * 4986 * @param {Matrix3} m - The matrix to copy. 4987 * @return {Matrix3} A reference to this matrix. 4988 */ 4989 copy(m) { 4990 const te = this.elements; 4991 const me = m.elements; 4992 te[0] = me[0]; 4993 te[1] = me[1]; 4994 te[2] = me[2]; 4995 te[3] = me[3]; 4996 te[4] = me[4]; 4997 te[5] = me[5]; 4998 te[6] = me[6]; 4999 te[7] = me[7]; 5000 te[8] = me[8]; 5001 return this; 5002 } 5003 /** 5004 * Extracts the basis of this matrix into the three axis vectors provided. 5005 * 5006 * @param {Vector3} xAxis - The basis's x axis. 5007 * @param {Vector3} yAxis - The basis's y axis. 5008 * @param {Vector3} zAxis - The basis's z axis. 5009 * @return {Matrix3} A reference to this matrix. 5010 */ 5011 extractBasis(xAxis, yAxis, zAxis) { 5012 xAxis.setFromMatrix3Column(this, 0); 5013 yAxis.setFromMatrix3Column(this, 1); 5014 zAxis.setFromMatrix3Column(this, 2); 5015 return this; 5016 } 5017 /** 5018 * Set this matrix to the upper 3x3 matrix of the given 4x4 matrix. 5019 * 5020 * @param {Matrix4} m - The 4x4 matrix. 5021 * @return {Matrix3} A reference to this matrix. 5022 */ 5023 setFromMatrix4(m) { 5024 const me = m.elements; 5025 this.set( 5026 me[0], 5027 me[4], 5028 me[8], 5029 me[1], 5030 me[5], 5031 me[9], 5032 me[2], 5033 me[6], 5034 me[10] 5035 ); 5036 return this; 5037 } 5038 /** 5039 * Post-multiplies this matrix by the given 3x3 matrix. 5040 * 5041 * @param {Matrix3} m - The matrix to multiply with. 5042 * @return {Matrix3} A reference to this matrix. 5043 */ 5044 multiply(m) { 5045 return this.multiplyMatrices(this, m); 5046 } 5047 /** 5048 * Pre-multiplies this matrix by the given 3x3 matrix. 5049 * 5050 * @param {Matrix3} m - The matrix to multiply with. 5051 * @return {Matrix3} A reference to this matrix. 5052 */ 5053 premultiply(m) { 5054 return this.multiplyMatrices(m, this); 5055 } 5056 /** 5057 * Multiples the given 3x3 matrices and stores the result 5058 * in this matrix. 5059 * 5060 * @param {Matrix3} a - The first matrix. 5061 * @param {Matrix3} b - The second matrix. 5062 * @return {Matrix3} A reference to this matrix. 5063 */ 5064 multiplyMatrices(a, b) { 5065 const ae = a.elements; 5066 const be = b.elements; 5067 const te = this.elements; 5068 const a11 = ae[0], a12 = ae[3], a13 = ae[6]; 5069 const a21 = ae[1], a22 = ae[4], a23 = ae[7]; 5070 const a31 = ae[2], a32 = ae[5], a33 = ae[8]; 5071 const b11 = be[0], b12 = be[3], b13 = be[6]; 5072 const b21 = be[1], b22 = be[4], b23 = be[7]; 5073 const b31 = be[2], b32 = be[5], b33 = be[8]; 5074 te[0] = a11 * b11 + a12 * b21 + a13 * b31; 5075 te[3] = a11 * b12 + a12 * b22 + a13 * b32; 5076 te[6] = a11 * b13 + a12 * b23 + a13 * b33; 5077 te[1] = a21 * b11 + a22 * b21 + a23 * b31; 5078 te[4] = a21 * b12 + a22 * b22 + a23 * b32; 5079 te[7] = a21 * b13 + a22 * b23 + a23 * b33; 5080 te[2] = a31 * b11 + a32 * b21 + a33 * b31; 5081 te[5] = a31 * b12 + a32 * b22 + a33 * b32; 5082 te[8] = a31 * b13 + a32 * b23 + a33 * b33; 5083 return this; 5084 } 5085 /** 5086 * Multiplies every component of the matrix by the given scalar. 5087 * 5088 * @param {number} s - The scalar. 5089 * @return {Matrix3} A reference to this matrix. 5090 */ 5091 multiplyScalar(s) { 5092 const te = this.elements; 5093 te[0] *= s; 5094 te[3] *= s; 5095 te[6] *= s; 5096 te[1] *= s; 5097 te[4] *= s; 5098 te[7] *= s; 5099 te[2] *= s; 5100 te[5] *= s; 5101 te[8] *= s; 5102 return this; 5103 } 5104 /** 5105 * Computes and returns the determinant of this matrix. 5106 * 5107 * @return {number} The determinant. 5108 */ 5109 determinant() { 5110 const te = this.elements; 5111 const a = te[0], b = te[1], c = te[2], d = te[3], e = te[4], f = te[5], g = te[6], h = te[7], i = te[8]; 5112 return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; 5113 } 5114 /** 5115 * Inverts this matrix, using the [analytic method](https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution). 5116 * You can not invert with a determinant of zero. If you attempt this, the method produces 5117 * a zero matrix instead. 5118 * 5119 * @return {Matrix3} A reference to this matrix. 5120 */ 5121 invert() { 5122 const te = this.elements, n11 = te[0], n21 = te[1], n31 = te[2], n12 = te[3], n22 = te[4], n32 = te[5], n13 = te[6], n23 = te[7], n33 = te[8], t11 = n33 * n22 - n32 * n23, t12 = n32 * n13 - n33 * n12, t13 = n23 * n12 - n22 * n13, det = n11 * t11 + n21 * t12 + n31 * t13; 5123 if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0); 5124 const detInv = 1 / det; 5125 te[0] = t11 * detInv; 5126 te[1] = (n31 * n23 - n33 * n21) * detInv; 5127 te[2] = (n32 * n21 - n31 * n22) * detInv; 5128 te[3] = t12 * detInv; 5129 te[4] = (n33 * n11 - n31 * n13) * detInv; 5130 te[5] = (n31 * n12 - n32 * n11) * detInv; 5131 te[6] = t13 * detInv; 5132 te[7] = (n21 * n13 - n23 * n11) * detInv; 5133 te[8] = (n22 * n11 - n21 * n12) * detInv; 5134 return this; 5135 } 5136 /** 5137 * Transposes this matrix in place. 5138 * 5139 * @return {Matrix3} A reference to this matrix. 5140 */ 5141 transpose() { 5142 let tmp; 5143 const m = this.elements; 5144 tmp = m[1]; 5145 m[1] = m[3]; 5146 m[3] = tmp; 5147 tmp = m[2]; 5148 m[2] = m[6]; 5149 m[6] = tmp; 5150 tmp = m[5]; 5151 m[5] = m[7]; 5152 m[7] = tmp; 5153 return this; 5154 } 5155 /** 5156 * Computes the normal matrix which is the inverse transpose of the upper 5157 * left 3x3 portion of the given 4x4 matrix. 5158 * 5159 * @param {Matrix4} matrix4 - The 4x4 matrix. 5160 * @return {Matrix3} A reference to this matrix. 5161 */ 5162 getNormalMatrix(matrix4) { 5163 return this.setFromMatrix4(matrix4).invert().transpose(); 5164 } 5165 /** 5166 * Transposes this matrix into the supplied array, and returns itself unchanged. 5167 * 5168 * @param {Array<number>} r - An array to store the transposed matrix elements. 5169 * @return {Matrix3} A reference to this matrix. 5170 */ 5171 transposeIntoArray(r) { 5172 const m = this.elements; 5173 r[0] = m[0]; 5174 r[1] = m[3]; 5175 r[2] = m[6]; 5176 r[3] = m[1]; 5177 r[4] = m[4]; 5178 r[5] = m[7]; 5179 r[6] = m[2]; 5180 r[7] = m[5]; 5181 r[8] = m[8]; 5182 return this; 5183 } 5184 /** 5185 * Sets the UV transform matrix from offset, repeat, rotation, and center. 5186 * 5187 * @param {number} tx - Offset x. 5188 * @param {number} ty - Offset y. 5189 * @param {number} sx - Repeat x. 5190 * @param {number} sy - Repeat y. 5191 * @param {number} rotation - Rotation, in radians. Positive values rotate counterclockwise. 5192 * @param {number} cx - Center x of rotation. 5193 * @param {number} cy - Center y of rotation 5194 * @return {Matrix3} A reference to this matrix. 5195 */ 5196 setUvTransform(tx, ty, sx, sy, rotation, cx, cy) { 5197 const c = Math.cos(rotation); 5198 const s = Math.sin(rotation); 5199 this.set( 5200 sx * c, 5201 sx * s, 5202 -sx * (c * cx + s * cy) + cx + tx, 5203 -sy * s, 5204 sy * c, 5205 -sy * (-s * cx + c * cy) + cy + ty, 5206 0, 5207 0, 5208 1 5209 ); 5210 return this; 5211 } 5212 /** 5213 * Scales this matrix with the given scalar values. 5214 * 5215 * @param {number} sx - The amount to scale in the X axis. 5216 * @param {number} sy - The amount to scale in the Y axis. 5217 * @return {Matrix3} A reference to this matrix. 5218 */ 5219 scale(sx, sy) { 5220 this.premultiply(_m3.makeScale(sx, sy)); 5221 return this; 5222 } 5223 /** 5224 * Rotates this matrix by the given angle. 5225 * 5226 * @param {number} theta - The rotation in radians. 5227 * @return {Matrix3} A reference to this matrix. 5228 */ 5229 rotate(theta) { 5230 this.premultiply(_m3.makeRotation(-theta)); 5231 return this; 5232 } 5233 /** 5234 * Translates this matrix by the given scalar values. 5235 * 5236 * @param {number} tx - The amount to translate in the X axis. 5237 * @param {number} ty - The amount to translate in the Y axis. 5238 * @return {Matrix3} A reference to this matrix. 5239 */ 5240 translate(tx, ty) { 5241 this.premultiply(_m3.makeTranslation(tx, ty)); 5242 return this; 5243 } 5244 // for 2D Transforms 5245 /** 5246 * Sets this matrix as a 2D translation transform. 5247 * 5248 * @param {number|Vector2} x - The amount to translate in the X axis or alternatively a translation vector. 5249 * @param {number} y - The amount to translate in the Y axis. 5250 * @return {Matrix3} A reference to this matrix. 5251 */ 5252 makeTranslation(x, y) { 5253 if (x.isVector2) { 5254 this.set( 5255 1, 5256 0, 5257 x.x, 5258 0, 5259 1, 5260 x.y, 5261 0, 5262 0, 5263 1 5264 ); 5265 } else { 5266 this.set( 5267 1, 5268 0, 5269 x, 5270 0, 5271 1, 5272 y, 5273 0, 5274 0, 5275 1 5276 ); 5277 } 5278 return this; 5279 } 5280 /** 5281 * Sets this matrix as a 2D rotational transformation. 5282 * 5283 * @param {number} theta - The rotation in radians. 5284 * @return {Matrix3} A reference to this matrix. 5285 */ 5286 makeRotation(theta) { 5287 const c = Math.cos(theta); 5288 const s = Math.sin(theta); 5289 this.set( 5290 c, 5291 -s, 5292 0, 5293 s, 5294 c, 5295 0, 5296 0, 5297 0, 5298 1 5299 ); 5300 return this; 5301 } 5302 /** 5303 * Sets this matrix as a 2D scale transform. 5304 * 5305 * @param {number} x - The amount to scale in the X axis. 5306 * @param {number} y - The amount to scale in the Y axis. 5307 * @return {Matrix3} A reference to this matrix. 5308 */ 5309 makeScale(x, y) { 5310 this.set( 5311 x, 5312 0, 5313 0, 5314 0, 5315 y, 5316 0, 5317 0, 5318 0, 5319 1 5320 ); 5321 return this; 5322 } 5323 /** 5324 * Returns `true` if this matrix is equal with the given one. 5325 * 5326 * @param {Matrix3} matrix - The matrix to test for equality. 5327 * @return {boolean} Whether this matrix is equal with the given one. 5328 */ 5329 equals(matrix) { 5330 const te = this.elements; 5331 const me = matrix.elements; 5332 for (let i = 0; i < 9; i++) { 5333 if (te[i] !== me[i]) return false; 5334 } 5335 return true; 5336 } 5337 /** 5338 * Sets the elements of the matrix from the given array. 5339 * 5340 * @param {Array<number>} array - The matrix elements in column-major order. 5341 * @param {number} [offset=0] - Index of the first element in the array. 5342 * @return {Matrix3} A reference to this matrix. 5343 */ 5344 fromArray(array, offset = 0) { 5345 for (let i = 0; i < 9; i++) { 5346 this.elements[i] = array[i + offset]; 5347 } 5348 return this; 5349 } 5350 /** 5351 * Writes the elements of this matrix to the given array. If no array is provided, 5352 * the method returns a new instance. 5353 * 5354 * @param {Array<number>} [array=[]] - The target array holding the matrix elements in column-major order. 5355 * @param {number} [offset=0] - Index of the first element in the array. 5356 * @return {Array<number>} The matrix elements in column-major order. 5357 */ 5358 toArray(array = [], offset = 0) { 5359 const te = this.elements; 5360 array[offset] = te[0]; 5361 array[offset + 1] = te[1]; 5362 array[offset + 2] = te[2]; 5363 array[offset + 3] = te[3]; 5364 array[offset + 4] = te[4]; 5365 array[offset + 5] = te[5]; 5366 array[offset + 6] = te[6]; 5367 array[offset + 7] = te[7]; 5368 array[offset + 8] = te[8]; 5369 return array; 5370 } 5371 /** 5372 * Returns a matrix with copied values from this instance. 5373 * 5374 * @return {Matrix3} A clone of this instance. 5375 */ 5376 clone() { 5377 return new this.constructor().fromArray(this.elements); 5378 } 5379}; 5380var _m3 = /* @__PURE__ */ new Matrix3(); 5381var LINEAR_REC709_TO_XYZ = /* @__PURE__ */ new Matrix3().set( 5382 0.4123908, 5383 0.3575843, 5384 0.1804808, 5385 0.212639, 5386 0.7151687, 5387 0.0721923, 5388 0.0193308, 5389 0.1191948, 5390 0.9505322 5391); 5392var XYZ_TO_LINEAR_REC709 = /* @__PURE__ */ new Matrix3().set( 5393 3.2409699, 5394 -1.5373832, 5395 -0.4986108, 5396 -0.9692436, 5397 1.8759675, 5398 0.0415551, 5399 0.0556301, 5400 -0.203977, 5401 1.0569715 5402); 5403function createColorManagement() { 5404 const ColorManagement2 = { 5405 enabled: true, 5406 workingColorSpace: LinearSRGBColorSpace, 5407 /** 5408 * Implementations of supported color spaces. 5409 * 5410 * Required: 5411 * - primaries: chromaticity coordinates [ rx ry gx gy bx by ] 5412 * - whitePoint: reference white [ x y ] 5413 * - transfer: transfer function (pre-defined) 5414 * - toXYZ: Matrix3 RGB to XYZ transform 5415 * - fromXYZ: Matrix3 XYZ to RGB transform 5416 * - luminanceCoefficients: RGB luminance coefficients 5417 * 5418 * Optional: 5419 * - outputColorSpaceConfig: { drawingBufferColorSpace: ColorSpace, toneMappingMode: 'extended' | 'standard' } 5420 * - workingColorSpaceConfig: { unpackColorSpace: ColorSpace } 5421 * 5422 * Reference: 5423 * - https://www.russellcottrell.com/photo/matrixCalculator.htm 5424 */ 5425 spaces: {}, 5426 convert: function(color, sourceColorSpace, targetColorSpace) { 5427 if (this.enabled === false || sourceColorSpace === targetColorSpace || !sourceColorSpace || !targetColorSpace) { 5428 return color; 5429 } 5430 if (this.spaces[sourceColorSpace].transfer === SRGBTransfer) { 5431 color.r = SRGBToLinear(color.r); 5432 color.g = SRGBToLinear(color.g); 5433 color.b = SRGBToLinear(color.b); 5434 } 5435 if (this.spaces[sourceColorSpace].primaries !== this.spaces[targetColorSpace].primaries) { 5436 color.applyMatrix3(this.spaces[sourceColorSpace].toXYZ); 5437 color.applyMatrix3(this.spaces[targetColorSpace].fromXYZ); 5438 } 5439 if (this.spaces[targetColorSpace].transfer === SRGBTransfer) { 5440 color.r = LinearToSRGB(color.r); 5441 color.g = LinearToSRGB(color.g); 5442 color.b = LinearToSRGB(color.b); 5443 } 5444 return color; 5445 }, 5446 workingToColorSpace: function(color, targetColorSpace) { 5447 return this.convert(color, this.workingColorSpace, targetColorSpace); 5448 }, 5449 colorSpaceToWorking: function(color, sourceColorSpace) { 5450 return this.convert(color, sourceColorSpace, this.workingColorSpace); 5451 }, 5452 getPrimaries: function(colorSpace) { 5453 return this.spaces[colorSpace].primaries; 5454 }, 5455 getTransfer: function(colorSpace) { 5456 if (colorSpace === NoColorSpace) return LinearTransfer; 5457 return this.spaces[colorSpace].transfer; 5458 }, 5459 getToneMappingMode: function(colorSpace) { 5460 return this.spaces[colorSpace].outputColorSpaceConfig.toneMappingMode || "standard"; 5461 }, 5462 getLuminanceCoefficients: function(target, colorSpace = this.workingColorSpace) { 5463 return target.fromArray(this.spaces[colorSpace].luminanceCoefficients); 5464 }, 5465 define: function(colorSpaces) { 5466 Object.assign(this.spaces, colorSpaces); 5467 }, 5468 // Internal APIs 5469 _getMatrix: function(targetMatrix, sourceColorSpace, targetColorSpace) { 5470 return targetMatrix.copy(this.spaces[sourceColorSpace].toXYZ).multiply(this.spaces[targetColorSpace].fromXYZ); 5471 }, 5472 _getDrawingBufferColorSpace: function(colorSpace) { 5473 return this.spaces[colorSpace].outputColorSpaceConfig.drawingBufferColorSpace; 5474 }, 5475 _getUnpackColorSpace: function(colorSpace = this.workingColorSpace) { 5476 return this.spaces[colorSpace].workingColorSpaceConfig.unpackColorSpace; 5477 }, 5478 // Deprecated 5479 fromWorkingColorSpace: function(color, targetColorSpace) { 5480 warnOnce("ColorManagement: .fromWorkingColorSpace() has been renamed to .workingToColorSpace()."); 5481 return ColorManagement2.workingToColorSpace(color, targetColorSpace); 5482 }, 5483 toWorkingColorSpace: function(color, sourceColorSpace) { 5484 warnOnce("ColorManagement: .toWorkingColorSpace() has been renamed to .colorSpaceToWorking()."); 5485 return ColorManagement2.colorSpaceToWorking(color, sourceColorSpace); 5486 } 5487 }; 5488 const REC709_PRIMARIES = [0.64, 0.33, 0.3, 0.6, 0.15, 0.06]; 5489 const REC709_LUMINANCE_COEFFICIENTS = [0.2126, 0.7152, 0.0722]; 5490 const D65 = [0.3127, 0.329]; 5491 ColorManagement2.define({ 5492 [LinearSRGBColorSpace]: { 5493 primaries: REC709_PRIMARIES, 5494 whitePoint: D65, 5495 transfer: LinearTransfer, 5496 toXYZ: LINEAR_REC709_TO_XYZ, 5497 fromXYZ: XYZ_TO_LINEAR_REC709, 5498 luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS, 5499 workingColorSpaceConfig: { unpackColorSpace: SRGBColorSpace }, 5500 outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace } 5501 }, 5502 [SRGBColorSpace]: { 5503 primaries: REC709_PRIMARIES, 5504 whitePoint: D65, 5505 transfer: SRGBTransfer, 5506 toXYZ: LINEAR_REC709_TO_XYZ, 5507 fromXYZ: XYZ_TO_LINEAR_REC709, 5508 luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS, 5509 outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace } 5510 } 5511 }); 5512 return ColorManagement2; 5513} 5514var ColorManagement = /* @__PURE__ */ createColorManagement(); 5515function SRGBToLinear(c) { 5516 return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4); 5517} 5518function LinearToSRGB(c) { 5519 return c < 31308e-7 ? c * 12.92 : 1.055 * Math.pow(c, 0.41666) - 0.055; 5520} 5521var _canvas; 5522var ImageUtils = class { 5523 /** 5524 * Returns a data URI containing a representation of the given image. 5525 * 5526 * @param {(HTMLImageElement|HTMLCanvasElement)} image - The image object. 5527 * @param {string} [type='image/png'] - Indicates the image format. 5528 * @return {string} The data URI. 5529 */ 5530 static getDataURL(image, type = "image/png") { 5531 if (/^data:/i.test(image.src)) { 5532 return image.src; 5533 } 5534 if (typeof HTMLCanvasElement === "undefined") { 5535 return image.src; 5536 } 5537 let canvas; 5538 if (image instanceof HTMLCanvasElement) { 5539 canvas = image; 5540 } else { 5541 if (_canvas === void 0) _canvas = createElementNS("canvas"); 5542 _canvas.width = image.width; 5543 _canvas.height = image.height; 5544 const context = _canvas.getContext("2d"); 5545 if (image instanceof ImageData) { 5546 context.putImageData(image, 0, 0); 5547 } else { 5548 context.drawImage(image, 0, 0, image.width, image.height); 5549 } 5550 canvas = _canvas; 5551 } 5552 return canvas.toDataURL(type); 5553 } 5554 /** 5555 * Converts the given sRGB image data to linear color space. 5556 * 5557 * @param {(HTMLImageElement|HTMLCanvasElement|ImageBitmap|Object)} image - The image object. 5558 * @return {HTMLCanvasElement|Object} The converted image. 5559 */ 5560 static sRGBToLinear(image) { 5561 if (typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== "undefined" && image instanceof HTMLCanvasElement || typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap) { 5562 const canvas = createElementNS("canvas"); 5563 canvas.width = image.width; 5564 canvas.height = image.height; 5565 const context = canvas.getContext("2d"); 5566 context.drawImage(image, 0, 0, image.width, image.height); 5567 const imageData = context.getImageData(0, 0, image.width, image.height); 5568 const data = imageData.data; 5569 for (let i = 0; i < data.length; i++) { 5570 data[i] = SRGBToLinear(data[i] / 255) * 255; 5571 } 5572 context.putImageData(imageData, 0, 0); 5573 return canvas; 5574 } else if (image.data) { 5575 const data = image.data.slice(0); 5576 for (let i = 0; i < data.length; i++) { 5577 if (data instanceof Uint8Array || data instanceof Uint8ClampedArray) { 5578 data[i] = Math.floor(SRGBToLinear(data[i] / 255) * 255); 5579 } else { 5580 data[i] = SRGBToLinear(data[i]); 5581 } 5582 } 5583 return { 5584 data, 5585 width: image.width, 5586 height: image.height 5587 }; 5588 } else { 5589 warn("ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied."); 5590 return image; 5591 } 5592 } 5593}; 5594var _sourceId = 0; 5595var Source = class { 5596 /** 5597 * Constructs a new video texture. 5598 * 5599 * @param {any} [data=null] - The data definition of a texture. 5600 */ 5601 constructor(data = null) { 5602 this.isSource = true; 5603 Object.defineProperty(this, "id", { value: _sourceId++ }); 5604 this.uuid = generateUUID(); 5605 this.data = data; 5606 this.dataReady = true; 5607 this.version = 0; 5608 } 5609 /** 5610 * Returns the dimensions of the source into the given target vector. 5611 * 5612 * @param {(Vector2|Vector3)} target - The target object the result is written into. 5613 * @return {(Vector2|Vector3)} The dimensions of the source. 5614 */ 5615 getSize(target) { 5616 const data = this.data; 5617 if (typeof HTMLVideoElement !== "undefined" && data instanceof HTMLVideoElement) { 5618 target.set(data.videoWidth, data.videoHeight, 0); 5619 } else if (typeof VideoFrame !== "undefined" && data instanceof VideoFrame) { 5620 target.set(data.displayWidth, data.displayHeight, 0); 5621 } else if (data !== null) { 5622 target.set(data.width, data.height, data.depth || 0); 5623 } else { 5624 target.set(0, 0, 0); 5625 } 5626 return target; 5627 } 5628 /** 5629 * When the property is set to `true`, the engine allocates the memory 5630 * for the texture (if necessary) and triggers the actual texture upload 5631 * to the GPU next time the source is used. 5632 * 5633 * @type {boolean} 5634 * @default false 5635 * @param {boolean} value 5636 */ 5637 set needsUpdate(value) { 5638 if (value === true) this.version++; 5639 } 5640 /** 5641 * Serializes the source into JSON. 5642 * 5643 * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. 5644 * @return {Object} A JSON object representing the serialized source. 5645 * @see {@link ObjectLoader#parse} 5646 */ 5647 toJSON(meta) { 5648 const isRootObject = meta === void 0 || typeof meta === "string"; 5649 if (!isRootObject && meta.images[this.uuid] !== void 0) { 5650 return meta.images[this.uuid]; 5651 } 5652 const output = { 5653 uuid: this.uuid, 5654 url: "" 5655 }; 5656 const data = this.data; 5657 if (data !== null) { 5658 let url; 5659 if (Array.isArray(data)) { 5660 url = []; 5661 for (let i = 0, l = data.length; i < l; i++) { 5662 if (data[i].isDataTexture) { 5663 url.push(serializeImage(data[i].image)); 5664 } else { 5665 url.push(serializeImage(data[i])); 5666 } 5667 } 5668 } else { 5669 url = serializeImage(data); 5670 } 5671 output.url = url; 5672 } 5673 if (!isRootObject) { 5674 meta.images[this.uuid] = output; 5675 } 5676 return output; 5677 } 5678}; 5679function serializeImage(image) { 5680 if (typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== "undefined" && image instanceof HTMLCanvasElement || typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap) { 5681 return ImageUtils.getDataURL(image); 5682 } else { 5683 if (image.data) { 5684 return { 5685 data: Array.from(image.data), 5686 width: image.width, 5687 height: image.height, 5688 type: image.data.constructor.name 5689 }; 5690 } else { 5691 warn("Texture: Unable to serialize Texture."); 5692 return {}; 5693 } 5694 } 5695} 5696var _textureId = 0; 5697var _tempVec3 = /* @__PURE__ */ new Vector3(); 5698var Texture = class _Texture extends EventDispatcher { 5699 /** 5700 * Constructs a new texture. 5701 * 5702 * @param {?Object} [image=Texture.DEFAULT_IMAGE] - The image holding the texture data. 5703 * @param {number} [mapping=Texture.DEFAULT_MAPPING] - The texture mapping. 5704 * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value. 5705 * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value. 5706 * @param {number} [magFilter=LinearFilter] - The mag filter value. 5707 * @param {number} [minFilter=LinearMipmapLinearFilter] - The min filter value. 5708 * @param {number} [format=RGBAFormat] - The texture format. 5709 * @param {number} [type=UnsignedByteType] - The texture type. 5710 * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value. 5711 * @param {string} [colorSpace=NoColorSpace] - The color space. 5712 */ 5713 constructor(image = _Texture.DEFAULT_IMAGE, mapping = _Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = _Texture.DEFAULT_ANISOTROPY, colorSpace = NoColorSpace) { 5714 super(); 5715 this.isTexture = true; 5716 Object.defineProperty(this, "id", { value: _textureId++ }); 5717 this.uuid = generateUUID(); 5718 this.name = ""; 5719 this.source = new Source(image); 5720 this.mipmaps = []; 5721 this.mapping = mapping; 5722 this.channel = 0; 5723 this.wrapS = wrapS; 5724 this.wrapT = wrapT; 5725 this.magFilter = magFilter; 5726 this.minFilter = minFilter; 5727 this.anisotropy = anisotropy; 5728 this.format = format; 5729 this.internalFormat = null; 5730 this.type = type; 5731 this.offset = new Vector2(0, 0); 5732 this.repeat = new Vector2(1, 1); 5733 this.center = new Vector2(0, 0); 5734 this.rotation = 0; 5735 this.matrixAutoUpdate = true; 5736 this.matrix = new Matrix3(); 5737 this.generateMipmaps = true; 5738 this.premultiplyAlpha = false; 5739 this.flipY = true; 5740 this.unpackAlignment = 4; 5741 this.colorSpace = colorSpace; 5742 this.userData = {}; 5743 this.updateRanges = []; 5744 this.version = 0; 5745 this.onUpdate = null; 5746 this.renderTarget = null; 5747 this.isRenderTargetTexture = false; 5748 this.isArrayTexture = image && image.depth && image.depth > 1 ? true : false; 5749 this.pmremVersion = 0; 5750 this.normalized = false; 5751 } 5752 /** 5753 * The width of the texture in pixels. 5754 */ 5755 get width() { 5756 return this.source.getSize(_tempVec3).x; 5757 } 5758 /** 5759 * The height of the texture in pixels. 5760 */ 5761 get height() { 5762 return this.source.getSize(_tempVec3).y; 5763 } 5764 /** 5765 * The depth of the texture in pixels. 5766 */ 5767 get depth() { 5768 return this.source.getSize(_tempVec3).z; 5769 } 5770 /** 5771 * The image object holding the texture data. 5772 * 5773 * @type {?Object} 5774 */ 5775 get image() { 5776 return this.source.data; 5777 } 5778 set image(value) { 5779 this.source.data = value; 5780 } 5781 /** 5782 * Updates the texture transformation matrix from the properties {@link Texture#offset}, 5783 * {@link Texture#repeat}, {@link Texture#rotation}, and {@link Texture#center}. 5784 */ 5785 updateMatrix() { 5786 this.matrix.setUvTransform(this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y); 5787 } 5788 /** 5789 * Adds a range of data in the data texture to be updated on the GPU. 5790 * 5791 * @param {number} start - Position at which to start update. 5792 * @param {number} count - The number of components to update. 5793 */ 5794 addUpdateRange(start, count) { 5795 this.updateRanges.push({ start, count }); 5796 } 5797 /** 5798 * Clears the update ranges. 5799 */ 5800 clearUpdateRanges() { 5801 this.updateRanges.length = 0; 5802 } 5803 /** 5804 * Returns a new texture with copied values from this instance. 5805 * 5806 * @return {Texture} A clone of this instance. 5807 */ 5808 clone() { 5809 return new this.constructor().copy(this); 5810 } 5811 /** 5812 * Copies the values of the given texture to this instance. 5813 * 5814 * @param {Texture} source - The texture to copy. 5815 * @return {Texture} A reference to this instance. 5816 */ 5817 copy(source) { 5818 this.name = source.name; 5819 this.source = source.source; 5820 this.mipmaps = source.mipmaps.slice(0); 5821 this.mapping = source.mapping; 5822 this.channel = source.channel; 5823 this.wrapS = source.wrapS; 5824 this.wrapT = source.wrapT; 5825 this.magFilter = source.magFilter; 5826 this.minFilter = source.minFilter; 5827 this.anisotropy = source.anisotropy; 5828 this.format = source.format; 5829 this.internalFormat = source.internalFormat; 5830 this.type = source.type; 5831 this.normalized = source.normalized; 5832 this.offset.copy(source.offset); 5833 this.repeat.copy(source.repeat); 5834 this.center.copy(source.center); 5835 this.rotation = source.rotation; 5836 this.matrixAutoUpdate = source.matrixAutoUpdate; 5837 this.matrix.copy(source.matrix); 5838 this.generateMipmaps = source.generateMipmaps; 5839 this.premultiplyAlpha = source.premultiplyAlpha; 5840 this.flipY = source.flipY; 5841 this.unpackAlignment = source.unpackAlignment; 5842 this.colorSpace = source.colorSpace; 5843 this.renderTarget = source.renderTarget; 5844 this.isRenderTargetTexture = source.isRenderTargetTexture; 5845 this.isArrayTexture = source.isArrayTexture; 5846 this.userData = JSON.parse(JSON.stringify(source.userData)); 5847 this.needsUpdate = true; 5848 return this; 5849 } 5850 /** 5851 * Sets this texture's properties based on `values`. 5852 * @param {Object} values - A container with texture parameters. 5853 */ 5854 setValues(values) { 5855 for (const key in values) { 5856 const newValue = values[key]; 5857 if (newValue === void 0) { 5858 warn(`Texture.setValues(): parameter '${key}' has value of undefined.`); 5859 continue; 5860 } 5861 const currentValue = this[key]; 5862 if (currentValue === void 0) { 5863 warn(`Texture.setValues(): property '${key}' does not exist.`); 5864 continue; 5865 } 5866 if (currentValue && newValue && (currentValue.isVector2 && newValue.isVector2)) { 5867 currentValue.copy(newValue); 5868 } else if (currentValue && newValue && (currentValue.isVector3 && newValue.isVector3)) { 5869 currentValue.copy(newValue); 5870 } else if (currentValue && newValue && (currentValue.isMatrix3 && newValue.isMatrix3)) { 5871 currentValue.copy(newValue); 5872 } else { 5873 this[key] = newValue; 5874 } 5875 } 5876 } 5877 /** 5878 * Serializes the texture into JSON. 5879 * 5880 * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. 5881 * @return {Object} A JSON object representing the serialized texture. 5882 * @see {@link ObjectLoader#parse} 5883 */ 5884 toJSON(meta) { 5885 const isRootObject = meta === void 0 || typeof meta === "string"; 5886 if (!isRootObject && meta.textures[this.uuid] !== void 0) { 5887 return meta.textures[this.uuid]; 5888 } 5889 const output = { 5890 metadata: { 5891 version: 4.7, 5892 type: "Texture", 5893 generator: "Texture.toJSON" 5894 }, 5895 uuid: this.uuid, 5896 name: this.name, 5897 image: this.source.toJSON(meta).uuid, 5898 mapping: this.mapping, 5899 channel: this.channel, 5900 repeat: [this.repeat.x, this.repeat.y], 5901 offset: [this.offset.x, this.offset.y], 5902 center: [this.center.x, this.center.y], 5903 rotation: this.rotation, 5904 wrap: [this.wrapS, this.wrapT], 5905 format: this.format, 5906 internalFormat: this.internalFormat, 5907 type: this.type, 5908 normalized: this.normalized, 5909 colorSpace: this.colorSpace, 5910 minFilter: this.minFilter, 5911 magFilter: this.magFilter, 5912 anisotropy: this.anisotropy, 5913 flipY: this.flipY, 5914 generateMipmaps: this.generateMipmaps, 5915 premultiplyAlpha: this.premultiplyAlpha, 5916 unpackAlignment: this.unpackAlignment 5917 }; 5918 if (Object.keys(this.userData).length > 0) output.userData = this.userData; 5919 if (!isRootObject) { 5920 meta.textures[this.uuid] = output; 5921 } 5922 return output; 5923 } 5924 /** 5925 * Frees the GPU-related resources allocated by this instance. Call this 5926 * method whenever this instance is no longer used in your app. 5927 * 5928 * @fires Texture#dispose 5929 */ 5930 dispose() { 5931 this.dispatchEvent({ type: "dispose" }); 5932 } 5933 /** 5934 * Transforms the given uv vector with the textures uv transformation matrix. 5935 * 5936 * @param {Vector2} uv - The uv vector. 5937 * @return {Vector2} The transformed uv vector. 5938 */ 5939 transformUv(uv) { 5940 if (this.mapping !== UVMapping) return uv; 5941 uv.applyMatrix3(this.matrix); 5942 if (uv.x < 0 || uv.x > 1) { 5943 switch (this.wrapS) { 5944 case RepeatWrapping: 5945 uv.x = uv.x - Math.floor(uv.x); 5946 break; 5947 case ClampToEdgeWrapping: 5948 uv.x = uv.x < 0 ? 0 : 1; 5949 break; 5950 case MirroredRepeatWrapping: 5951 if (Math.abs(Math.floor(uv.x) % 2) === 1) { 5952 uv.x = Math.ceil(uv.x) - uv.x; 5953 } else { 5954 uv.x = uv.x - Math.floor(uv.x); 5955 } 5956 break; 5957 } 5958 } 5959 if (uv.y < 0 || uv.y > 1) { 5960 switch (this.wrapT) { 5961 case RepeatWrapping: 5962 uv.y = uv.y - Math.floor(uv.y); 5963 break; 5964 case ClampToEdgeWrapping: 5965 uv.y = uv.y < 0 ? 0 : 1; 5966 break; 5967 case MirroredRepeatWrapping: 5968 if (Math.abs(Math.floor(uv.y) % 2) === 1) { 5969 uv.y = Math.ceil(uv.y) - uv.y; 5970 } else { 5971 uv.y = uv.y - Math.floor(uv.y); 5972 } 5973 break; 5974 } 5975 } 5976 if (this.flipY) { 5977 uv.y = 1 - uv.y; 5978 } 5979 return uv; 5980 } 5981 /** 5982 * Setting this property to `true` indicates the engine the texture 5983 * must be updated in the next render. This triggers a texture upload 5984 * to the GPU and ensures correct texture parameter configuration. 5985 * 5986 * @type {boolean} 5987 * @default false 5988 * @param {boolean} value 5989 */ 5990 set needsUpdate(value) { 5991 if (value === true) { 5992 this.version++; 5993 this.source.needsUpdate = true; 5994 } 5995 } 5996 /** 5997 * Setting this property to `true` indicates the engine the PMREM 5998 * must be regenerated. 5999 * 6000 * @type {boolean} 6001 * @default false 6002 * @param {boolean} value 6003 */ 6004 set needsPMREMUpdate(value) { 6005 if (value === true) { 6006 this.pmremVersion++; 6007 } 6008 } 6009}; 6010Texture.DEFAULT_IMAGE = null; 6011Texture.DEFAULT_MAPPING = UVMapping; 6012Texture.DEFAULT_ANISOTROPY = 1; 6013var Vector4 = class _Vector4 { 6014 static { 6015 _Vector4.prototype.isVector4 = true; 6016 } 6017 /** 6018 * Constructs a new 4D vector. 6019 * 6020 * @param {number} [x=0] - The x value of this vector. 6021 * @param {number} [y=0] - The y value of this vector. 6022 * @param {number} [z=0] - The z value of this vector. 6023 * @param {number} [w=1] - The w value of this vector. 6024 */ 6025 constructor(x = 0, y = 0, z = 0, w = 1) { 6026 this.x = x; 6027 this.y = y; 6028 this.z = z; 6029 this.w = w; 6030 } 6031 /** 6032 * Alias for {@link Vector4#z}. 6033 * 6034 * @type {number} 6035 */ 6036 get width() { 6037 return this.z; 6038 } 6039 set width(value) { 6040 this.z = value; 6041 } 6042 /** 6043 * Alias for {@link Vector4#w}. 6044 * 6045 * @type {number} 6046 */ 6047 get height() { 6048 return this.w; 6049 } 6050 set height(value) { 6051 this.w = value; 6052 } 6053 /** 6054 * Sets the vector components. 6055 * 6056 * @param {number} x - The value of the x component. 6057 * @param {number} y - The value of the y component. 6058 * @param {number} z - The value of the z component. 6059 * @param {number} w - The value of the w component. 6060 * @return {Vector4} A reference to this vector. 6061 */ 6062 set(x, y, z, w) { 6063 this.x = x; 6064 this.y = y; 6065 this.z = z; 6066 this.w = w; 6067 return this; 6068 } 6069 /** 6070 * Sets the vector components to the same value. 6071 * 6072 * @param {number} scalar - The value to set for all vector components. 6073 * @return {Vector4} A reference to this vector. 6074 */ 6075 setScalar(scalar) { 6076 this.x = scalar; 6077 this.y = scalar; 6078 this.z = scalar; 6079 this.w = scalar; 6080 return this; 6081 } 6082 /** 6083 * Sets the vector's x component to the given value 6084 * 6085 * @param {number} x - The value to set. 6086 * @return {Vector4} A reference to this vector. 6087 */ 6088 setX(x) { 6089 this.x = x; 6090 return this; 6091 } 6092 /** 6093 * Sets the vector's y component to the given value 6094 * 6095 * @param {number} y - The value to set. 6096 * @return {Vector4} A reference to this vector. 6097 */ 6098 setY(y) { 6099 this.y = y; 6100 return this; 6101 } 6102 /** 6103 * Sets the vector's z component to the given value 6104 * 6105 * @param {number} z - The value to set. 6106 * @return {Vector4} A reference to this vector. 6107 */ 6108 setZ(z) { 6109 this.z = z; 6110 return this; 6111 } 6112 /** 6113 * Sets the vector's w component to the given value 6114 * 6115 * @param {number} w - The value to set. 6116 * @return {Vector4} A reference to this vector. 6117 */ 6118 setW(w) { 6119 this.w = w; 6120 return this; 6121 } 6122 /** 6123 * Allows to set a vector component with an index. 6124 * 6125 * @param {number} index - The component index. `0` equals to x, `1` equals to y, 6126 * `2` equals to z, `3` equals to w. 6127 * @param {number} value - The value to set. 6128 * @return {Vector4} A reference to this vector. 6129 */ 6130 setComponent(index, value) { 6131 switch (index) { 6132 case 0: 6133 this.x = value; 6134 break; 6135 case 1: 6136 this.y = value; 6137 break; 6138 case 2: 6139 this.z = value; 6140 break; 6141 case 3: 6142 this.w = value; 6143 break; 6144 default: 6145 throw new Error("index is out of range: " + index); 6146 } 6147 return this; 6148 } 6149 /** 6150 * Returns the value of the vector component which matches the given index. 6151 * 6152 * @param {number} index - The component index. `0` equals to x, `1` equals to y, 6153 * `2` equals to z, `3` equals to w. 6154 * @return {number} A vector component value. 6155 */ 6156 getComponent(index) { 6157 switch (index) { 6158 case 0: 6159 return this.x; 6160 case 1: 6161 return this.y; 6162 case 2: 6163 return this.z; 6164 case 3: 6165 return this.w; 6166 default: 6167 throw new Error("index is out of range: " + index); 6168 } 6169 } 6170 /** 6171 * Returns a new vector with copied values from this instance. 6172 * 6173 * @return {Vector4} A clone of this instance. 6174 */ 6175 clone() { 6176 return new this.constructor(this.x, this.y, this.z, this.w); 6177 } 6178 /** 6179 * Copies the values of the given vector to this instance. 6180 * 6181 * @param {Vector3|Vector4} v - The vector to copy. 6182 * @return {Vector4} A reference to this vector. 6183 */ 6184 copy(v) { 6185 this.x = v.x; 6186 this.y = v.y; 6187 this.z = v.z; 6188 this.w = v.w !== void 0 ? v.w : 1; 6189 return this; 6190 } 6191 /** 6192 * Adds the given vector to this instance. 6193 * 6194 * @param {Vector4} v - The vector to add. 6195 * @return {Vector4} A reference to this vector. 6196 */ 6197 add(v) { 6198 this.x += v.x; 6199 this.y += v.y; 6200 this.z += v.z; 6201 this.w += v.w; 6202 return this; 6203 } 6204 /** 6205 * Adds the given scalar value to all components of this instance. 6206 * 6207 * @param {number} s - The scalar to add. 6208 * @return {Vector4} A reference to this vector. 6209 */ 6210 addScalar(s) { 6211 this.x += s; 6212 this.y += s; 6213 this.z += s; 6214 this.w += s; 6215 return this; 6216 } 6217 /** 6218 * Adds the given vectors and stores the result in this instance. 6219 * 6220 * @param {Vector4} a - The first vector. 6221 * @param {Vector4} b - The second vector. 6222 * @return {Vector4} A reference to this vector. 6223 */ 6224 addVectors(a, b) { 6225 this.x = a.x + b.x; 6226 this.y = a.y + b.y; 6227 this.z = a.z + b.z; 6228 this.w = a.w + b.w; 6229 return this; 6230 } 6231 /** 6232 * Adds the given vector scaled by the given factor to this instance. 6233 * 6234 * @param {Vector4} v - The vector. 6235 * @param {number} s - The factor that scales `v`. 6236 * @return {Vector4} A reference to this vector. 6237 */ 6238 addScaledVector(v, s) { 6239 this.x += v.x * s; 6240 this.y += v.y * s; 6241 this.z += v.z * s; 6242 this.w += v.w * s; 6243 return this; 6244 } 6245 /** 6246 * Subtracts the given vector from this instance. 6247 * 6248 * @param {Vector4} v - The vector to subtract. 6249 * @return {Vector4} A reference to this vector. 6250 */ 6251 sub(v) { 6252 this.x -= v.x; 6253 this.y -= v.y; 6254 this.z -= v.z; 6255 this.w -= v.w; 6256 return this; 6257 } 6258 /** 6259 * Subtracts the given scalar value from all components of this instance. 6260 * 6261 * @param {number} s - The scalar to subtract. 6262 * @return {Vector4} A reference to this vector. 6263 */ 6264 subScalar(s) { 6265 this.x -= s; 6266 this.y -= s; 6267 this.z -= s; 6268 this.w -= s; 6269 return this; 6270 } 6271 /** 6272 * Subtracts the given vectors and stores the result in this instance. 6273 * 6274 * @param {Vector4} a - The first vector. 6275 * @param {Vector4} b - The second vector. 6276 * @return {Vector4} A reference to this vector. 6277 */ 6278 subVectors(a, b) { 6279 this.x = a.x - b.x; 6280 this.y = a.y - b.y; 6281 this.z = a.z - b.z; 6282 this.w = a.w - b.w; 6283 return this; 6284 } 6285 /** 6286 * Multiplies the given vector with this instance. 6287 * 6288 * @param {Vector4} v - The vector to multiply. 6289 * @return {Vector4} A reference to this vector. 6290 */ 6291 multiply(v) { 6292 this.x *= v.x; 6293 this.y *= v.y; 6294 this.z *= v.z; 6295 this.w *= v.w; 6296 return this; 6297 } 6298 /** 6299 * Multiplies the given scalar value with all components of this instance. 6300 * 6301 * @param {number} scalar - The scalar to multiply. 6302 * @return {Vector4} A reference to this vector. 6303 */ 6304 multiplyScalar(scalar) { 6305 this.x *= scalar; 6306 this.y *= scalar; 6307 this.z *= scalar; 6308 this.w *= scalar; 6309 return this; 6310 } 6311 /** 6312 * Multiplies this vector with the given 4x4 matrix. 6313 * 6314 * @param {Matrix4} m - The 4x4 matrix. 6315 * @return {Vector4} A reference to this vector. 6316 */ 6317 applyMatrix4(m) { 6318 const x = this.x, y = this.y, z = this.z, w = this.w; 6319 const e = m.elements; 6320 this.x = e[0] * x + e[4] * y + e[8] * z + e[12] * w; 6321 this.y = e[1] * x + e[5] * y + e[9] * z + e[13] * w; 6322 this.z = e[2] * x + e[6] * y + e[10] * z + e[14] * w; 6323 this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w; 6324 return this; 6325 } 6326 /** 6327 * Divides this instance by the given vector. 6328 * 6329 * @param {Vector4} v - The vector to divide. 6330 * @return {Vector4} A reference to this vector. 6331 */ 6332 divide(v) { 6333 this.x /= v.x; 6334 this.y /= v.y; 6335 this.z /= v.z; 6336 this.w /= v.w; 6337 return this; 6338 } 6339 /** 6340 * Divides this vector by the given scalar. 6341 * 6342 * @param {number} scalar - The scalar to divide. 6343 * @return {Vector4} A reference to this vector. 6344 */ 6345 divideScalar(scalar) { 6346 return this.multiplyScalar(1 / scalar); 6347 } 6348 /** 6349 * Sets the x, y and z components of this 6350 * vector to the quaternion's axis and w to the angle. 6351 * 6352 * @param {Quaternion} q - The Quaternion to set. 6353 * @return {Vector4} A reference to this vector. 6354 */ 6355 setAxisAngleFromQuaternion(q) { 6356 this.w = 2 * Math.acos(q.w); 6357 const s = Math.sqrt(1 - q.w * q.w); 6358 if (s < 1e-4) { 6359 this.x = 1; 6360 this.y = 0; 6361 this.z = 0; 6362 } else { 6363 this.x = q.x / s; 6364 this.y = q.y / s; 6365 this.z = q.z / s; 6366 } 6367 return this; 6368 } 6369 /** 6370 * Sets the x, y and z components of this 6371 * vector to the axis of rotation and w to the angle. 6372 * 6373 * @param {Matrix4} m - A 4x4 matrix of which the upper left 3x3 matrix is a pure rotation matrix. 6374 * @return {Vector4} A reference to this vector. 6375 */ 6376 setAxisAngleFromRotationMatrix(m) { 6377 let angle, x, y, z; 6378 const epsilon = 0.01, epsilon2 = 0.1, te = m.elements, m11 = te[0], m12 = te[4], m13 = te[8], m21 = te[1], m22 = te[5], m23 = te[9], m31 = te[2], m32 = te[6], m33 = te[10]; 6379 if (Math.abs(m12 - m21) < epsilon && Math.abs(m13 - m31) < epsilon && Math.abs(m23 - m32) < epsilon) { 6380 if (Math.abs(m12 + m21) < epsilon2 && Math.abs(m13 + m31) < epsilon2 && Math.abs(m23 + m32) < epsilon2 && Math.abs(m11 + m22 + m33 - 3) < epsilon2) { 6381 this.set(1, 0, 0, 0); 6382 return this; 6383 } 6384 angle = Math.PI; 6385 const xx = (m11 + 1) / 2; 6386 const yy = (m22 + 1) / 2; 6387 const zz = (m33 + 1) / 2; 6388 const xy = (m12 + m21) / 4; 6389 const xz = (m13 + m31) / 4; 6390 const yz = (m23 + m32) / 4; 6391 if (xx > yy && xx > zz) { 6392 if (xx < epsilon) { 6393 x = 0; 6394 y = 0.707106781; 6395 z = 0.707106781; 6396 } else { 6397 x = Math.sqrt(xx); 6398 y = xy / x; 6399 z = xz / x; 6400 } 6401 } else if (yy > zz) { 6402 if (yy < epsilon) { 6403 x = 0.707106781; 6404 y = 0; 6405 z = 0.707106781; 6406 } else { 6407 y = Math.sqrt(yy); 6408 x = xy / y; 6409 z = yz / y; 6410 } 6411 } else { 6412 if (zz < epsilon) { 6413 x = 0.707106781; 6414 y = 0.707106781; 6415 z = 0; 6416 } else { 6417 z = Math.sqrt(zz); 6418 x = xz / z; 6419 y = yz / z; 6420 } 6421 } 6422 this.set(x, y, z, angle); 6423 return this; 6424 } 6425 let s = Math.sqrt((m32 - m23) * (m32 - m23) + (m13 - m31) * (m13 - m31) + (m21 - m12) * (m21 - m12)); 6426 if (Math.abs(s) < 1e-3) s = 1; 6427 this.x = (m32 - m23) / s; 6428 this.y = (m13 - m31) / s; 6429 this.z = (m21 - m12) / s; 6430 this.w = Math.acos((m11 + m22 + m33 - 1) / 2); 6431 return this; 6432 } 6433 /** 6434 * Sets the vector components to the position elements of the 6435 * given transformation matrix. 6436 * 6437 * @param {Matrix4} m - The 4x4 matrix. 6438 * @return {Vector4} A reference to this vector. 6439 */ 6440 setFromMatrixPosition(m) { 6441 const e = m.elements; 6442 this.x = e[12]; 6443 this.y = e[13]; 6444 this.z = e[14]; 6445 this.w = e[15]; 6446 return this; 6447 } 6448 /** 6449 * If this vector's x, y, z or w value is greater than the given vector's x, y, z or w 6450 * value, replace that value with the corresponding min value. 6451 * 6452 * @param {Vector4} v - The vector. 6453 * @return {Vector4} A reference to this vector. 6454 */ 6455 min(v) { 6456 this.x = Math.min(this.x, v.x); 6457 this.y = Math.min(this.y, v.y); 6458 this.z = Math.min(this.z, v.z); 6459 this.w = Math.min(this.w, v.w); 6460 return this; 6461 } 6462 /** 6463 * If this vector's x, y, z or w value is less than the given vector's x, y, z or w 6464 * value, replace that value with the corresponding max value. 6465 * 6466 * @param {Vector4} v - The vector. 6467 * @return {Vector4} A reference to this vector. 6468 */ 6469 max(v) { 6470 this.x = Math.max(this.x, v.x); 6471 this.y = Math.max(this.y, v.y); 6472 this.z = Math.max(this.z, v.z); 6473 this.w = Math.max(this.w, v.w); 6474 return this; 6475 } 6476 /** 6477 * If this vector's x, y, z or w value is greater than the max vector's x, y, z or w 6478 * value, it is replaced by the corresponding value. 6479 * If this vector's x, y, z or w value is less than the min vector's x, y, z or w value, 6480 * it is replaced by the corresponding value. 6481 * 6482 * @param {Vector4} min - The minimum x, y and z values. 6483 * @param {Vector4} max - The maximum x, y and z values in the desired range. 6484 * @return {Vector4} A reference to this vector. 6485 */ 6486 clamp(min, max) { 6487 this.x = clamp(this.x, min.x, max.x); 6488 this.y = clamp(this.y, min.y, max.y); 6489 this.z = clamp(this.z, min.z, max.z); 6490 this.w = clamp(this.w, min.w, max.w); 6491 return this; 6492 } 6493 /** 6494 * If this vector's x, y, z or w values are greater than the max value, they are 6495 * replaced by the max value. 6496 * If this vector's x, y, z or w values are less than the min value, they are 6497 * replaced by the min value. 6498 * 6499 * @param {number} minVal - The minimum value the components will be clamped to. 6500 * @param {number} maxVal - The maximum value the components will be clamped to. 6501 * @return {Vector4} A reference to this vector. 6502 */ 6503 clampScalar(minVal, maxVal) { 6504 this.x = clamp(this.x, minVal, maxVal); 6505 this.y = clamp(this.y, minVal, maxVal); 6506 this.z = clamp(this.z, minVal, maxVal); 6507 this.w = clamp(this.w, minVal, maxVal); 6508 return this; 6509 } 6510 /** 6511 * If this vector's length is greater than the max value, it is replaced by 6512 * the max value. 6513 * If this vector's length is less than the min value, it is replaced by the 6514 * min value. 6515 * 6516 * @param {number} min - The minimum value the vector length will be clamped to. 6517 * @param {number} max - The maximum value the vector length will be clamped to. 6518 * @return {Vector4} A reference to this vector. 6519 */ 6520 clampLength(min, max) { 6521 const length = this.length(); 6522 return this.divideScalar(length || 1).multiplyScalar(clamp(length, min, max)); 6523 } 6524 /** 6525 * The components of this vector are rounded down to the nearest integer value. 6526 * 6527 * @return {Vector4} A reference to this vector. 6528 */ 6529 floor() { 6530 this.x = Math.floor(this.x); 6531 this.y = Math.floor(this.y); 6532 this.z = Math.floor(this.z); 6533 this.w = Math.floor(this.w); 6534 return this; 6535 } 6536 /** 6537 * The components of this vector are rounded up to the nearest integer value. 6538 * 6539 * @return {Vector4} A reference to this vector. 6540 */ 6541 ceil() { 6542 this.x = Math.ceil(this.x); 6543 this.y = Math.ceil(this.y); 6544 this.z = Math.ceil(this.z); 6545 this.w = Math.ceil(this.w); 6546 return this; 6547 } 6548 /** 6549 * The components of this vector are rounded to the nearest integer value 6550 * 6551 * @return {Vector4} A reference to this vector. 6552 */ 6553 round() { 6554 this.x = Math.round(this.x); 6555 this.y = Math.round(this.y); 6556 this.z = Math.round(this.z); 6557 this.w = Math.round(this.w); 6558 return this; 6559 } 6560 /** 6561 * The components of this vector are rounded towards zero (up if negative, 6562 * down if positive) to an integer value. 6563 * 6564 * @return {Vector4} A reference to this vector. 6565 */ 6566 roundToZero() { 6567 this.x = Math.trunc(this.x); 6568 this.y = Math.trunc(this.y); 6569 this.z = Math.trunc(this.z); 6570 this.w = Math.trunc(this.w); 6571 return this; 6572 } 6573 /** 6574 * Inverts this vector - i.e. sets x = -x, y = -y, z = -z, w = -w. 6575 * 6576 * @return {Vector4} A reference to this vector. 6577 */ 6578 negate() { 6579 this.x = -this.x; 6580 this.y = -this.y; 6581 this.z = -this.z; 6582 this.w = -this.w; 6583 return this; 6584 } 6585 /** 6586 * Calculates the dot product of the given vector with this instance. 6587 * 6588 * @param {Vector4} v - The vector to compute the dot product with. 6589 * @return {number} The result of the dot product. 6590 */ 6591 dot(v) { 6592 return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; 6593 } 6594 /** 6595 * Computes the square of the Euclidean length (straight-line length) from 6596 * (0, 0, 0, 0) to (x, y, z, w). If you are comparing the lengths of vectors, you should 6597 * compare the length squared instead as it is slightly more efficient to calculate. 6598 * 6599 * @return {number} The square length of this vector. 6600 */ 6601 lengthSq() { 6602 return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; 6603 } 6604 /** 6605 * Computes the Euclidean length (straight-line length) from (0, 0, 0, 0) to (x, y, z, w). 6606 * 6607 * @return {number} The length of this vector. 6608 */ 6609 length() { 6610 return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); 6611 } 6612 /** 6613 * Computes the Manhattan length of this vector. 6614 * 6615 * @return {number} The length of this vector. 6616 */ 6617 manhattanLength() { 6618 return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z) + Math.abs(this.w); 6619 } 6620 /** 6621 * Converts this vector to a unit vector - that is, sets it equal to a vector 6622 * with the same direction as this one, but with a vector length of `1`. 6623 * 6624 * @return {Vector4} A reference to this vector. 6625 */ 6626 normalize() { 6627 return this.divideScalar(this.length() || 1); 6628 } 6629 /** 6630 * Sets this vector to a vector with the same direction as this one, but 6631 * with the specified length. 6632 * 6633 * @param {number} length - The new length of this vector. 6634 * @return {Vector4} A reference to this vector. 6635 */ 6636 setLength(length) { 6637 return this.normalize().multiplyScalar(length); 6638 } 6639 /** 6640 * Linearly interpolates between the given vector and this instance, where 6641 * alpha is the percent distance along the line - alpha = 0 will be this 6642 * vector, and alpha = 1 will be the given one. 6643 * 6644 * @param {Vector4} v - The vector to interpolate towards. 6645 * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`. 6646 * @return {Vector4} A reference to this vector. 6647 */ 6648 lerp(v, alpha) { 6649 this.x += (v.x - this.x) * alpha; 6650 this.y += (v.y - this.y) * alpha; 6651 this.z += (v.z - this.z) * alpha; 6652 this.w += (v.w - this.w) * alpha; 6653 return this; 6654 } 6655 /** 6656 * Linearly interpolates between the given vectors, where alpha is the percent 6657 * distance along the line - alpha = 0 will be first vector, and alpha = 1 will 6658 * be the second one. The result is stored in this instance. 6659 * 6660 * @param {Vector4} v1 - The first vector. 6661 * @param {Vector4} v2 - The second vector. 6662 * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`. 6663 * @return {Vector4} A reference to this vector. 6664 */ 6665 lerpVectors(v1, v2, alpha) { 6666 this.x = v1.x + (v2.x - v1.x) * alpha; 6667 this.y = v1.y + (v2.y - v1.y) * alpha; 6668 this.z = v1.z + (v2.z - v1.z) * alpha; 6669 this.w = v1.w + (v2.w - v1.w) * alpha; 6670 return this; 6671 } 6672 /** 6673 * Returns `true` if this vector is equal with the given one. 6674 * 6675 * @param {Vector4} v - The vector to test for equality. 6676 * @return {boolean} Whether this vector is equal with the given one. 6677 */ 6678 equals(v) { 6679 return v.x === this.x && v.y === this.y && v.z === this.z && v.w === this.w; 6680 } 6681 /** 6682 * Sets this vector's x value to be `array[ offset ]`, y value to be `array[ offset + 1 ]`, 6683 * z value to be `array[ offset + 2 ]`, w value to be `array[ offset + 3 ]`. 6684 * 6685 * @param {Array<number>} array - An array holding the vector component values. 6686 * @param {number} [offset=0] - The offset into the array. 6687 * @return {Vector4} A reference to this vector. 6688 */ 6689 fromArray(array, offset = 0) { 6690 this.x = array[offset]; 6691 this.y = array[offset + 1]; 6692 this.z = array[offset + 2]; 6693 this.w = array[offset + 3]; 6694 return this; 6695 } 6696 /** 6697 * Writes the components of this vector to the given array. If no array is provided, 6698 * the method returns a new instance. 6699 * 6700 * @param {Array<number>} [array=[]] - The target array holding the vector components. 6701 * @param {number} [offset=0] - Index of the first element in the array. 6702 * @return {Array<number>} The vector components. 6703 */ 6704 toArray(array = [], offset = 0) { 6705 array[offset] = this.x; 6706 array[offset + 1] = this.y; 6707 array[offset + 2] = this.z; 6708 array[offset + 3] = this.w; 6709 return array; 6710 } 6711 /** 6712 * Sets the components of this vector from the given buffer attribute. 6713 * 6714 * @param {BufferAttribute} attribute - The buffer attribute holding vector data. 6715 * @param {number} index - The index into the attribute. 6716 * @return {Vector4} A reference to this vector. 6717 */ 6718 fromBufferAttribute(attribute, index) { 6719 this.x = attribute.getX(index); 6720 this.y = attribute.getY(index); 6721 this.z = attribute.getZ(index); 6722 this.w = attribute.getW(index); 6723 return this; 6724 } 6725 /** 6726 * Sets each component of this vector to a pseudo-random value between `0` and 6727 * `1`, excluding `1`. 6728 * 6729 * @return {Vector4} A reference to this vector. 6730 */ 6731 random() { 6732 this.x = Math.random(); 6733 this.y = Math.random(); 6734 this.z = Math.random(); 6735 this.w = Math.random(); 6736 return this; 6737 } 6738 *[Symbol.iterator]() { 6739 yield this.x; 6740 yield this.y; 6741 yield this.z; 6742 yield this.w; 6743 } 6744}; 6745var RenderTarget = class extends EventDispatcher { 6746 /** 6747 * Render target options. 6748 * 6749 * @typedef {Object} RenderTarget~Options 6750 * @property {boolean} [generateMipmaps=false] - Whether to generate mipmaps or not. 6751 * @property {number} [magFilter=LinearFilter] - The mag filter. 6752 * @property {number} [minFilter=LinearFilter] - The min filter. 6753 * @property {number} [format=RGBAFormat] - The texture format. 6754 * @property {number} [type=UnsignedByteType] - The texture type. 6755 * @property {?string} [internalFormat=null] - The texture's internal format. 6756 * @property {number} [wrapS=ClampToEdgeWrapping] - The texture's uv wrapping mode. 6757 * @property {number} [wrapT=ClampToEdgeWrapping] - The texture's uv wrapping mode. 6758 * @property {number} [anisotropy=1] - The texture's anisotropy value. 6759 * @property {string} [colorSpace=NoColorSpace] - The texture's color space. 6760 * @property {boolean} [depthBuffer=true] - Whether to allocate a depth buffer or not. 6761 * @property {boolean} [stencilBuffer=false] - Whether to allocate a stencil buffer or not. 6762 * @property {boolean} [resolveDepthBuffer=true] - Whether to resolve the depth buffer or not. 6763 * @property {boolean} [resolveStencilBuffer=true] - Whether to resolve the stencil buffer or not. 6764 * @property {?Texture} [depthTexture=null] - Reference to a depth texture. 6765 * @property {number} [samples=0] - The MSAA samples count. 6766 * @property {number} [count=1] - Defines the number of color attachments . Must be at least `1`. 6767 * @property {number} [depth=1] - The texture depth. 6768 * @property {boolean} [multiview=false] - Whether this target is used for multiview rendering. 6769 */ 6770 /** 6771 * Constructs a new render target. 6772 * 6773 * @param {number} [width=1] - The width of the render target. 6774 * @param {number} [height=1] - The height of the render target. 6775 * @param {RenderTarget~Options} [options] - The configuration object. 6776 */ 6777 constructor(width = 1, height = 1, options = {}) { 6778 super(); 6779 options = Object.assign({ 6780 generateMipmaps: false, 6781 internalFormat: null, 6782 minFilter: LinearFilter, 6783 depthBuffer: true, 6784 stencilBuffer: false, 6785 resolveDepthBuffer: true, 6786 resolveStencilBuffer: true, 6787 depthTexture: null, 6788 samples: 0, 6789 count: 1, 6790 depth: 1, 6791 multiview: false 6792 }, options); 6793 this.isRenderTarget = true; 6794 this.width = width; 6795 this.height = height; 6796 this.depth = options.depth; 6797 this.scissor = new Vector4(0, 0, width, height); 6798 this.scissorTest = false; 6799 this.viewport = new Vector4(0, 0, width, height); 6800 this.textures = []; 6801 const image = { width, height, depth: options.depth }; 6802 const texture = new Texture(image); 6803 const count = options.count; 6804 for (let i = 0; i < count; i++) { 6805 this.textures[i] = texture.clone(); 6806 this.textures[i].isRenderTargetTexture = true; 6807 this.textures[i].renderTarget = this; 6808 } 6809 this._setTextureOptions(options); 6810 this.depthBuffer = options.depthBuffer; 6811 this.stencilBuffer = options.stencilBuffer; 6812 this.resolveDepthBuffer = options.resolveDepthBuffer; 6813 this.resolveStencilBuffer = options.resolveStencilBuffer; 6814 this._depthTexture = null; 6815 this.depthTexture = options.depthTexture; 6816 this.samples = options.samples; 6817 this.multiview = options.multiview; 6818 } 6819 _setTextureOptions(options = {}) { 6820 const values = { 6821 minFilter: LinearFilter, 6822 generateMipmaps: false, 6823 flipY: false, 6824 internalFormat: null 6825 }; 6826 if (options.mapping !== void 0) values.mapping = options.mapping; 6827 if (options.wrapS !== void 0) values.wrapS = options.wrapS; 6828 if (options.wrapT !== void 0) values.wrapT = options.wrapT; 6829 if (options.wrapR !== void 0) values.wrapR = options.wrapR; 6830 if (options.magFilter !== void 0) values.magFilter = options.magFilter; 6831 if (options.minFilter !== void 0) values.minFilter = options.minFilter; 6832 if (options.format !== void 0) values.format = options.format; 6833 if (options.type !== void 0) values.type = options.type; 6834 if (options.anisotropy !== void 0) values.anisotropy = options.anisotropy; 6835 if (options.colorSpace !== void 0) values.colorSpace = options.colorSpace; 6836 if (options.flipY !== void 0) values.flipY = options.flipY; 6837 if (options.generateMipmaps !== void 0) values.generateMipmaps = options.generateMipmaps; 6838 if (options.internalFormat !== void 0) values.internalFormat = options.internalFormat; 6839 for (let i = 0; i < this.textures.length; i++) { 6840 const texture = this.textures[i]; 6841 texture.setValues(values); 6842 } 6843 } 6844 /** 6845 * The texture representing the default color attachment. 6846 * 6847 * @type {Texture} 6848 */ 6849 get texture() { 6850 return this.textures[0]; 6851 } 6852 set texture(value) { 6853 this.textures[0] = value; 6854 } 6855 set depthTexture(current) { 6856 if (this._depthTexture !== null) this._depthTexture.renderTarget = null; 6857 if (current !== null) current.renderTarget = this; 6858 this._depthTexture = current; 6859 } 6860 /** 6861 * Instead of saving the depth in a renderbuffer, a texture 6862 * can be used instead which is useful for further processing 6863 * e.g. in context of post-processing. 6864 * 6865 * @type {?DepthTexture} 6866 * @default null 6867 */ 6868 get depthTexture() { 6869 return this._depthTexture; 6870 } 6871 /** 6872 * Sets the size of this render target. 6873 * 6874 * @param {number} width - The width. 6875 * @param {number} height - The height. 6876 * @param {number} [depth=1] - The depth. 6877 */ 6878 setSize(width, height, depth = 1) { 6879 if (this.width !== width || this.height !== height || this.depth !== depth) { 6880 this.width = width; 6881 this.height = height; 6882 this.depth = depth; 6883 for (let i = 0, il = this.textures.length; i < il; i++) { 6884 this.textures[i].image.width = width; 6885 this.textures[i].image.height = height; 6886 this.textures[i].image.depth = depth; 6887 if (this.textures[i].isData3DTexture !== true) { 6888 this.textures[i].isArrayTexture = this.textures[i].image.depth > 1; 6889 } 6890 } 6891 this.dispose(); 6892 } 6893 this.viewport.set(0, 0, width, height); 6894 this.scissor.set(0, 0, width, height); 6895 } 6896 /** 6897 * Returns a new render target with copied values from this instance. 6898 * 6899 * @return {RenderTarget} A clone of this instance. 6900 */ 6901 clone() { 6902 return new this.constructor().copy(this); 6903 } 6904 /** 6905 * Copies the settings of the given render target. This is a structural copy so 6906 * no resources are shared between render targets after the copy. That includes 6907 * all MRT textures and the depth texture. 6908 * 6909 * @param {RenderTarget} source - The render target to copy. 6910 * @return {RenderTarget} A reference to this instance. 6911 */ 6912 copy(source) { 6913 this.width = source.width; 6914 this.height = source.height; 6915 this.depth = source.depth; 6916 this.scissor.copy(source.scissor); 6917 this.scissorTest = source.scissorTest; 6918 this.viewport.copy(source.viewport); 6919 this.textures.length = 0; 6920 for (let i = 0, il = source.textures.length; i < il; i++) { 6921 this.textures[i] = source.textures[i].clone(); 6922 this.textures[i].isRenderTargetTexture = true; 6923 this.textures[i].renderTarget = this; 6924 const image = Object.assign({}, source.textures[i].image); 6925 this.textures[i].source = new Source(image); 6926 } 6927 this.depthBuffer = source.depthBuffer; 6928 this.stencilBuffer = source.stencilBuffer; 6929 this.resolveDepthBuffer = source.resolveDepthBuffer; 6930 this.resolveStencilBuffer = source.resolveStencilBuffer; 6931 if (source.depthTexture !== null) this.depthTexture = source.depthTexture.clone(); 6932 this.samples = source.samples; 6933 this.multiview = source.multiview; 6934 return this; 6935 } 6936 /** 6937 * Frees the GPU-related resources allocated by this instance. Call this 6938 * method whenever this instance is no longer used in your app. 6939 * 6940 * @fires RenderTarget#dispose 6941 */ 6942 dispose() { 6943 this.dispatchEvent({ type: "dispose" }); 6944 } 6945}; 6946var WebGLRenderTarget = class extends RenderTarget { 6947 /** 6948 * Constructs a new 3D render target. 6949 * 6950 * @param {number} [width=1] - The width of the render target. 6951 * @param {number} [height=1] - The height of the render target. 6952 * @param {RenderTarget~Options} [options] - The configuration object. 6953 */ 6954 constructor(width = 1, height = 1, options = {}) { 6955 super(width, height, options); 6956 this.isWebGLRenderTarget = true; 6957 } 6958}; 6959var DataArrayTexture = class extends Texture { 6960 /** 6961 * Constructs a new data array texture. 6962 * 6963 * @param {?TypedArray} [data=null] - The buffer data. 6964 * @param {number} [width=1] - The width of the texture. 6965 * @param {number} [height=1] - The height of the texture. 6966 * @param {number} [depth=1] - The depth of the texture. 6967 */ 6968 constructor(data = null, width = 1, height = 1, depth = 1) { 6969 super(null); 6970 this.isDataArrayTexture = true; 6971 this.image = { data, width, height, depth }; 6972 this.magFilter = NearestFilter; 6973 this.minFilter = NearestFilter; 6974 this.wrapR = ClampToEdgeWrapping; 6975 this.generateMipmaps = false; 6976 this.flipY = false; 6977 this.unpackAlignment = 1; 6978 this.layerUpdates = /* @__PURE__ */ new Set(); 6979 } 6980 /** 6981 * Describes that a specific layer of the texture needs to be updated. 6982 * Normally when {@link Texture#needsUpdate} is set to `true`, the 6983 * entire data texture array is sent to the GPU. Marking specific 6984 * layers will only transmit subsets of all mipmaps associated with a 6985 * specific depth in the array which is often much more performant. 6986 * 6987 * @param {number} layerIndex - The layer index that should be updated. 6988 */ 6989 addLayerUpdate(layerIndex) { 6990 this.layerUpdates.add(layerIndex); 6991 } 6992 /** 6993 * Resets the layer updates registry. 6994 */ 6995 clearLayerUpdates() { 6996 this.layerUpdates.clear(); 6997 } 6998}; 6999var Data3DTexture = class extends Texture { 7000 /** 7001 * Constructs a new data array texture. 7002 * 7003 * @param {?TypedArray} [data=null] - The buffer data. 7004 * @param {number} [width=1] - The width of the texture. 7005 * @param {number} [height=1] - The height of the texture. 7006 * @param {number} [depth=1] - The depth of the texture. 7007 */ 7008 constructor(data = null, width = 1, height = 1, depth = 1) { 7009 super(null); 7010 this.isData3DTexture = true; 7011 this.image = { data, width, height, depth }; 7012 this.magFilter = NearestFilter; 7013 this.minFilter = NearestFilter; 7014 this.wrapR = ClampToEdgeWrapping; 7015 this.generateMipmaps = false; 7016 this.flipY = false; 7017 this.unpackAlignment = 1; 7018 } 7019}; 7020var Matrix4 = class _Matrix4 { 7021 static { 7022 _Matrix4.prototype.isMatrix4 = true; 7023 } 7024 /** 7025 * Constructs a new 4x4 matrix. The arguments are supposed to be 7026 * in row-major order. If no arguments are provided, the constructor 7027 * initializes the matrix as an identity matrix. 7028 * 7029 * @param {number} [n11] - 1-1 matrix element. 7030 * @param {number} [n12] - 1-2 matrix element. 7031 * @param {number} [n13] - 1-3 matrix element. 7032 * @param {number} [n14] - 1-4 matrix element. 7033 * @param {number} [n21] - 2-1 matrix element. 7034 * @param {number} [n22] - 2-2 matrix element. 7035 * @param {number} [n23] - 2-3 matrix element. 7036 * @param {number} [n24] - 2-4 matrix element. 7037 * @param {number} [n31] - 3-1 matrix element. 7038 * @param {number} [n32] - 3-2 matrix element. 7039 * @param {number} [n33] - 3-3 matrix element. 7040 * @param {number} [n34] - 3-4 matrix element. 7041 * @param {number} [n41] - 4-1 matrix element. 7042 * @param {number} [n42] - 4-2 matrix element. 7043 * @param {number} [n43] - 4-3 matrix element. 7044 * @param {number} [n44] - 4-4 matrix element. 7045 */ 7046 constructor(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) { 7047 this.elements = [ 7048 1, 7049 0, 7050 0, 7051 0, 7052 0, 7053 1, 7054 0, 7055 0, 7056 0, 7057 0, 7058 1, 7059 0, 7060 0, 7061 0, 7062 0, 7063 1 7064 ]; 7065 if (n11 !== void 0) { 7066 this.set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44); 7067 } 7068 } 7069 /** 7070 * Sets the elements of the matrix.The arguments are supposed to be 7071 * in row-major order. 7072 * 7073 * @param {number} [n11] - 1-1 matrix element. 7074 * @param {number} [n12] - 1-2 matrix element. 7075 * @param {number} [n13] - 1-3 matrix element. 7076 * @param {number} [n14] - 1-4 matrix element. 7077 * @param {number} [n21] - 2-1 matrix element. 7078 * @param {number} [n22] - 2-2 matrix element. 7079 * @param {number} [n23] - 2-3 matrix element. 7080 * @param {number} [n24] - 2-4 matrix element. 7081 * @param {number} [n31] - 3-1 matrix element. 7082 * @param {number} [n32] - 3-2 matrix element. 7083 * @param {number} [n33] - 3-3 matrix element. 7084 * @param {number} [n34] - 3-4 matrix element. 7085 * @param {number} [n41] - 4-1 matrix element. 7086 * @param {number} [n42] - 4-2 matrix element. 7087 * @param {number} [n43] - 4-3 matrix element. 7088 * @param {number} [n44] - 4-4 matrix element. 7089 * @return {Matrix4} A reference to this matrix. 7090 */ 7091 set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) { 7092 const te = this.elements; 7093 te[0] = n11; 7094 te[4] = n12; 7095 te[8] = n13; 7096 te[12] = n14; 7097 te[1] = n21; 7098 te[5] = n22; 7099 te[9] = n23; 7100 te[13] = n24; 7101 te[2] = n31; 7102 te[6] = n32; 7103 te[10] = n33; 7104 te[14] = n34; 7105 te[3] = n41; 7106 te[7] = n42; 7107 te[11] = n43; 7108 te[15] = n44; 7109 return this; 7110 } 7111 /** 7112 * Sets this matrix to the 4x4 identity matrix. 7113 * 7114 * @return {Matrix4} A reference to this matrix. 7115 */ 7116 identity() { 7117 this.set( 7118 1, 7119 0, 7120 0, 7121 0, 7122 0, 7123 1, 7124 0, 7125 0, 7126 0, 7127 0, 7128 1, 7129 0, 7130 0, 7131 0, 7132 0, 7133 1 7134 ); 7135 return this; 7136 } 7137 /** 7138 * Returns a matrix with copied values from this instance. 7139 * 7140 * @return {Matrix4} A clone of this instance. 7141 */ 7142 clone() { 7143 return new _Matrix4().fromArray(this.elements); 7144 } 7145 /** 7146 * Copies the values of the given matrix to this instance. 7147 * 7148 * @param {Matrix4} m - The matrix to copy. 7149 * @return {Matrix4} A reference to this matrix. 7150 */ 7151 copy(m) { 7152 const te = this.elements; 7153 const me = m.elements; 7154 te[0] = me[0]; 7155 te[1] = me[1]; 7156 te[2] = me[2]; 7157 te[3] = me[3]; 7158 te[4] = me[4]; 7159 te[5] = me[5]; 7160 te[6] = me[6]; 7161 te[7] = me[7]; 7162 te[8] = me[8]; 7163 te[9] = me[9]; 7164 te[10] = me[10]; 7165 te[11] = me[11]; 7166 te[12] = me[12]; 7167 te[13] = me[13]; 7168 te[14] = me[14]; 7169 te[15] = me[15]; 7170 return this; 7171 } 7172 /** 7173 * Copies the translation component of the given matrix 7174 * into this matrix's translation component. 7175 * 7176 * @param {Matrix4} m - The matrix to copy the translation component. 7177 * @return {Matrix4} A reference to this matrix. 7178 */ 7179 copyPosition(m) { 7180 const te = this.elements, me = m.elements; 7181 te[12] = me[12]; 7182 te[13] = me[13]; 7183 te[14] = me[14]; 7184 return this; 7185 } 7186 /** 7187 * Set the upper 3x3 elements of this matrix to the values of given 3x3 matrix. 7188 * 7189 * @param {Matrix3} m - The 3x3 matrix. 7190 * @return {Matrix4} A reference to this matrix. 7191 */ 7192 setFromMatrix3(m) { 7193 const me = m.elements; 7194 this.set( 7195 me[0], 7196 me[3], 7197 me[6], 7198 0, 7199 me[1], 7200 me[4], 7201 me[7], 7202 0, 7203 me[2], 7204 me[5], 7205 me[8], 7206 0, 7207 0, 7208 0, 7209 0, 7210 1 7211 ); 7212 return this; 7213 } 7214 /** 7215 * Extracts the basis of this matrix into the three axis vectors provided. 7216 * 7217 * @param {Vector3} xAxis - The basis's x axis. 7218 * @param {Vector3} yAxis - The basis's y axis. 7219 * @param {Vector3} zAxis - The basis's z axis. 7220 * @return {Matrix4} A reference to this matrix. 7221 */ 7222 extractBasis(xAxis, yAxis, zAxis) { 7223 if (this.determinant() === 0) { 7224 xAxis.set(1, 0, 0); 7225 yAxis.set(0, 1, 0); 7226 zAxis.set(0, 0, 1); 7227 return this; 7228 } 7229 xAxis.setFromMatrixColumn(this, 0); 7230 yAxis.setFromMatrixColumn(this, 1); 7231 zAxis.setFromMatrixColumn(this, 2); 7232 return this; 7233 } 7234 /** 7235 * Sets the given basis vectors to this matrix. 7236 * 7237 * @param {Vector3} xAxis - The basis's x axis. 7238 * @param {Vector3} yAxis - The basis's y axis. 7239 * @param {Vector3} zAxis - The basis's z axis. 7240 * @return {Matrix4} A reference to this matrix. 7241 */ 7242 makeBasis(xAxis, yAxis, zAxis) { 7243 this.set( 7244 xAxis.x, 7245 yAxis.x, 7246 zAxis.x, 7247 0, 7248 xAxis.y, 7249 yAxis.y, 7250 zAxis.y, 7251 0, 7252 xAxis.z, 7253 yAxis.z, 7254 zAxis.z, 7255 0, 7256 0, 7257 0, 7258 0, 7259 1 7260 ); 7261 return this; 7262 } 7263 /** 7264 * Extracts the rotation component of the given matrix 7265 * into this matrix's rotation component. 7266 * 7267 * Note: This method does not support reflection matrices. 7268 * 7269 * @param {Matrix4} m - The matrix. 7270 * @return {Matrix4} A reference to this matrix. 7271 */ 7272 extractRotation(m) { 7273 if (m.determinant() === 0) { 7274 return this.identity(); 7275 } 7276 const te = this.elements; 7277 const me = m.elements; 7278 const scaleX = 1 / _v1$7.setFromMatrixColumn(m, 0).length(); 7279 const scaleY = 1 / _v1$7.setFromMatrixColumn(m, 1).length(); 7280 const scaleZ = 1 / _v1$7.setFromMatrixColumn(m, 2).length(); 7281 te[0] = me[0] * scaleX; 7282 te[1] = me[1] * scaleX; 7283 te[2] = me[2] * scaleX; 7284 te[3] = 0; 7285 te[4] = me[4] * scaleY; 7286 te[5] = me[5] * scaleY; 7287 te[6] = me[6] * scaleY; 7288 te[7] = 0; 7289 te[8] = me[8] * scaleZ; 7290 te[9] = me[9] * scaleZ; 7291 te[10] = me[10] * scaleZ; 7292 te[11] = 0; 7293 te[12] = 0; 7294 te[13] = 0; 7295 te[14] = 0; 7296 te[15] = 1; 7297 return this; 7298 } 7299 /** 7300 * Sets the rotation component (the upper left 3x3 matrix) of this matrix to 7301 * the rotation specified by the given Euler angles. The rest of 7302 * the matrix is set to the identity. Depending on the {@link Euler#order}, 7303 * there are six possible outcomes. See [this page](https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix) 7304 * for a complete list. 7305 * 7306 * @param {Euler} euler - The Euler angles. 7307 * @return {Matrix4} A reference to this matrix. 7308 */ 7309 makeRotationFromEuler(euler) { 7310 const te = this.elements; 7311 const x = euler.x, y = euler.y, z = euler.z; 7312 const a = Math.cos(x), b = Math.sin(x); 7313 const c = Math.cos(y), d = Math.sin(y); 7314 const e = Math.cos(z), f = Math.sin(z); 7315 if (euler.order === "XYZ") { 7316 const ae = a * e, af = a * f, be = b * e, bf = b * f; 7317 te[0] = c * e; 7318 te[4] = -c * f; 7319 te[8] = d; 7320 te[1] = af + be * d; 7321 te[5] = ae - bf * d; 7322 te[9] = -b * c; 7323 te[2] = bf - ae * d; 7324 te[6] = be + af * d; 7325 te[10] = a * c; 7326 } else if (euler.order === "YXZ") { 7327 const ce = c * e, cf = c * f, de = d * e, df = d * f; 7328 te[0] = ce + df * b; 7329 te[4] = de * b - cf; 7330 te[8] = a * d; 7331 te[1] = a * f; 7332 te[5] = a * e; 7333 te[9] = -b; 7334 te[2] = cf * b - de; 7335 te[6] = df + ce * b; 7336 te[10] = a * c; 7337 } else if (euler.order === "ZXY") { 7338 const ce = c * e, cf = c * f, de = d * e, df = d * f; 7339 te[0] = ce - df * b; 7340 te[4] = -a * f; 7341 te[8] = de + cf * b; 7342 te[1] = cf + de * b; 7343 te[5] = a * e; 7344 te[9] = df - ce * b; 7345 te[2] = -a * d; 7346 te[6] = b; 7347 te[10] = a * c; 7348 } else if (euler.order === "ZYX") { 7349 const ae = a * e, af = a * f, be = b * e, bf = b * f; 7350 te[0] = c * e; 7351 te[4] = be * d - af; 7352 te[8] = ae * d + bf; 7353 te[1] = c * f; 7354 te[5] = bf * d + ae; 7355 te[9] = af * d - be; 7356 te[2] = -d; 7357 te[6] = b * c; 7358 te[10] = a * c; 7359 } else if (euler.order === "YZX") { 7360 const ac = a * c, ad = a * d, bc = b * c, bd = b * d; 7361 te[0] = c * e; 7362 te[4] = bd - ac * f; 7363 te[8] = bc * f + ad; 7364 te[1] = f; 7365 te[5] = a * e; 7366 te[9] = -b * e; 7367 te[2] = -d * e; 7368 te[6] = ad * f + bc; 7369 te[10] = ac - bd * f; 7370 } else if (euler.order === "XZY") { 7371 const ac = a * c, ad = a * d, bc = b * c, bd = b * d; 7372 te[0] = c * e; 7373 te[4] = -f; 7374 te[8] = d * e; 7375 te[1] = ac * f + bd; 7376 te[5] = a * e; 7377 te[9] = ad * f - bc; 7378 te[2] = bc * f - ad; 7379 te[6] = b * e; 7380 te[10] = bd * f + ac; 7381 } 7382 te[3] = 0; 7383 te[7] = 0; 7384 te[11] = 0; 7385 te[12] = 0; 7386 te[13] = 0; 7387 te[14] = 0; 7388 te[15] = 1; 7389 return this; 7390 } 7391 /** 7392 * Sets the rotation component of this matrix to the rotation specified by 7393 * the given Quaternion as outlined [here](https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion) 7394 * The rest of the matrix is set to the identity. 7395 * 7396 * @param {Quaternion} q - The Quaternion. 7397 * @return {Matrix4} A reference to this matrix. 7398 */ 7399 makeRotationFromQuaternion(q) { 7400 return this.compose(_zero, q, _one); 7401 } 7402 /** 7403 * Sets the rotation component of the transformation matrix, looking from `eye` towards 7404 * `target`, and oriented by the up-direction. 7405 * 7406 * @param {Vector3} eye - The eye vector. 7407 * @param {Vector3} target - The target vector. 7408 * @param {Vector3} up - The up vector. 7409 * @return {Matrix4} A reference to this matrix. 7410 */ 7411 lookAt(eye, target, up) { 7412 const te = this.elements; 7413 _z.subVectors(eye, target); 7414 if (_z.lengthSq() === 0) { 7415 _z.z = 1; 7416 } 7417 _z.normalize(); 7418 _x.crossVectors(up, _z); 7419 if (_x.lengthSq() === 0) { 7420 if (Math.abs(up.z) === 1) { 7421 _z.x += 1e-4; 7422 } else { 7423 _z.z += 1e-4; 7424 } 7425 _z.normalize(); 7426 _x.crossVectors(up, _z); 7427 } 7428 _x.normalize(); 7429 _y.crossVectors(_z, _x); 7430 te[0] = _x.x; 7431 te[4] = _y.x; 7432 te[8] = _z.x; 7433 te[1] = _x.y; 7434 te[5] = _y.y; 7435 te[9] = _z.y; 7436 te[2] = _x.z; 7437 te[6] = _y.z; 7438 te[10] = _z.z; 7439 return this; 7440 } 7441 /** 7442 * Post-multiplies this matrix by the given 4x4 matrix. 7443 * 7444 * @param {Matrix4} m - The matrix to multiply with. 7445 * @return {Matrix4} A reference to this matrix. 7446 */ 7447 multiply(m) { 7448 return this.multiplyMatrices(this, m); 7449 } 7450 /** 7451 * Pre-multiplies this matrix by the given 4x4 matrix. 7452 * 7453 * @param {Matrix4} m - The matrix to multiply with. 7454 * @return {Matrix4} A reference to this matrix. 7455 */ 7456 premultiply(m) { 7457 return this.multiplyMatrices(m, this); 7458 } 7459 /** 7460 * Multiples the given 4x4 matrices and stores the result 7461 * in this matrix. 7462 * 7463 * @param {Matrix4} a - The first matrix. 7464 * @param {Matrix4} b - The second matrix. 7465 * @return {Matrix4} A reference to this matrix. 7466 */ 7467 multiplyMatrices(a, b) { 7468 const ae = a.elements; 7469 const be = b.elements; 7470 const te = this.elements; 7471 const a11 = ae[0], a12 = ae[4], a13 = ae[8], a14 = ae[12]; 7472 const a21 = ae[1], a22 = ae[5], a23 = ae[9], a24 = ae[13]; 7473 const a31 = ae[2], a32 = ae[6], a33 = ae[10], a34 = ae[14]; 7474 const a41 = ae[3], a42 = ae[7], a43 = ae[11], a44 = ae[15]; 7475 const b11 = be[0], b12 = be[4], b13 = be[8], b14 = be[12]; 7476 const b21 = be[1], b22 = be[5], b23 = be[9], b24 = be[13]; 7477 const b31 = be[2], b32 = be[6], b33 = be[10], b34 = be[14]; 7478 const b41 = be[3], b42 = be[7], b43 = be[11], b44 = be[15]; 7479 te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; 7480 te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; 7481 te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; 7482 te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; 7483 te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; 7484 te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; 7485 te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; 7486 te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; 7487 te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; 7488 te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; 7489 te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; 7490 te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; 7491 te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; 7492 te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; 7493 te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; 7494 te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; 7495 return this; 7496 } 7497 /** 7498 * Multiplies every component of the matrix by the given scalar. 7499 * 7500 * @param {number} s - The scalar. 7501 * @return {Matrix4} A reference to this matrix. 7502 */ 7503 multiplyScalar(s) { 7504 const te = this.elements; 7505 te[0] *= s; 7506 te[4] *= s; 7507 te[8] *= s; 7508 te[12] *= s; 7509 te[1] *= s; 7510 te[5] *= s; 7511 te[9] *= s; 7512 te[13] *= s; 7513 te[2] *= s; 7514 te[6] *= s; 7515 te[10] *= s; 7516 te[14] *= s; 7517 te[3] *= s; 7518 te[7] *= s; 7519 te[11] *= s; 7520 te[15] *= s; 7521 return this; 7522 } 7523 /** 7524 * Computes and returns the determinant of this matrix. 7525 * 7526 * Based on the method outlined [here](http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.html). 7527 * 7528 * @return {number} The determinant. 7529 */ 7530 determinant() { 7531 const te = this.elements; 7532 const n11 = te[0], n12 = te[4], n13 = te[8], n14 = te[12]; 7533 const n21 = te[1], n22 = te[5], n23 = te[9], n24 = te[13]; 7534 const n31 = te[2], n32 = te[6], n33 = te[10], n34 = te[14]; 7535 const n41 = te[3], n42 = te[7], n43 = te[11], n44 = te[15]; 7536 const t11 = n23 * n34 - n24 * n33; 7537 const t12 = n22 * n34 - n24 * n32; 7538 const t13 = n22 * n33 - n23 * n32; 7539 const t21 = n21 * n34 - n24 * n31; 7540 const t22 = n21 * n33 - n23 * n31; 7541 const t23 = n21 * n32 - n22 * n31; 7542 return n11 * (n42 * t11 - n43 * t12 + n44 * t13) - n12 * (n41 * t11 - n43 * t21 + n44 * t22) + n13 * (n41 * t12 - n42 * t21 + n44 * t23) - n14 * (n41 * t13 - n42 * t22 + n43 * t23); 7543 } 7544 /** 7545 * Transposes this matrix in place. 7546 * 7547 * @return {Matrix4} A reference to this matrix. 7548 */ 7549 transpose() { 7550 const te = this.elements; 7551 let tmp; 7552 tmp = te[1]; 7553 te[1] = te[4]; 7554 te[4] = tmp; 7555 tmp = te[2]; 7556 te[2] = te[8]; 7557 te[8] = tmp; 7558 tmp = te[6]; 7559 te[6] = te[9]; 7560 te[9] = tmp; 7561 tmp = te[3]; 7562 te[3] = te[12]; 7563 te[12] = tmp; 7564 tmp = te[7]; 7565 te[7] = te[13]; 7566 te[13] = tmp; 7567 tmp = te[11]; 7568 te[11] = te[14]; 7569 te[14] = tmp; 7570 return this; 7571 } 7572 /** 7573 * Sets the position component for this matrix from the given vector, 7574 * without affecting the rest of the matrix. 7575 * 7576 * @param {number|Vector3} x - The x component of the vector or alternatively the vector object. 7577 * @param {number} y - The y component of the vector. 7578 * @param {number} z - The z component of the vector. 7579 * @return {Matrix4} A reference to this matrix. 7580 */ 7581 setPosition(x, y, z) { 7582 const te = this.elements; 7583 if (x.isVector3) { 7584 te[12] = x.x; 7585 te[13] = x.y; 7586 te[14] = x.z; 7587 } else { 7588 te[12] = x; 7589 te[13] = y; 7590 te[14] = z; 7591 } 7592 return this; 7593 } 7594 /** 7595 * Inverts this matrix, using the [analytic method](https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution). 7596 * You can not invert with a determinant of zero. If you attempt this, the method produces 7597 * a zero matrix instead. 7598 * 7599 * @return {Matrix4} A reference to this matrix. 7600 */ 7601 invert() { 7602 const te = this.elements, n11 = te[0], n21 = te[1], n31 = te[2], n41 = te[3], n12 = te[4], n22 = te[5], n32 = te[6], n42 = te[7], n13 = te[8], n23 = te[9], n33 = te[10], n43 = te[11], n14 = te[12], n24 = te[13], n34 = te[14], n44 = te[15], t1 = n11 * n22 - n21 * n12, t2 = n11 * n32 - n31 * n12, t3 = n11 * n42 - n41 * n12, t4 = n21 * n32 - n31 * n22, t5 = n21 * n42 - n41 * n22, t6 = n31 * n42 - n41 * n32, t7 = n13 * n24 - n23 * n14, t8 = n13 * n34 - n33 * n14, t9 = n13 * n44 - n43 * n14, t10 = n23 * n34 - n33 * n24, t11 = n23 * n44 - n43 * n24, t12 = n33 * n44 - n43 * n34; 7603 const det = t1 * t12 - t2 * t11 + t3 * t10 + t4 * t9 - t5 * t8 + t6 * t7; 7604 if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 7605 const detInv = 1 / det; 7606 te[0] = (n22 * t12 - n32 * t11 + n42 * t10) * detInv; 7607 te[1] = (n31 * t11 - n21 * t12 - n41 * t10) * detInv; 7608 te[2] = (n24 * t6 - n34 * t5 + n44 * t4) * detInv; 7609 te[3] = (n33 * t5 - n23 * t6 - n43 * t4) * detInv; 7610 te[4] = (n32 * t9 - n12 * t12 - n42 * t8) * detInv; 7611 te[5] = (n11 * t12 - n31 * t9 + n41 * t8) * detInv; 7612 te[6] = (n34 * t3 - n14 * t6 - n44 * t2) * detInv; 7613 te[7] = (n13 * t6 - n33 * t3 + n43 * t2) * detInv; 7614 te[8] = (n12 * t11 - n22 * t9 + n42 * t7) * detInv; 7615 te[9] = (n21 * t9 - n11 * t11 - n41 * t7) * detInv; 7616 te[10] = (n14 * t5 - n24 * t3 + n44 * t1) * detInv; 7617 te[11] = (n23 * t3 - n13 * t5 - n43 * t1) * detInv; 7618 te[12] = (n22 * t8 - n12 * t10 - n32 * t7) * detInv; 7619 te[13] = (n11 * t10 - n21 * t8 + n31 * t7) * detInv; 7620 te[14] = (n24 * t2 - n14 * t4 - n34 * t1) * detInv; 7621 te[15] = (n13 * t4 - n23 * t2 + n33 * t1) * detInv; 7622 return this; 7623 } 7624 /** 7625 * Multiplies the columns of this matrix by the given vector. 7626 * 7627 * @param {Vector3} v - The scale vector. 7628 * @return {Matrix4} A reference to this matrix. 7629 */ 7630 scale(v) { 7631 const te = this.elements; 7632 const x = v.x, y = v.y, z = v.z; 7633 te[0] *= x; 7634 te[4] *= y; 7635 te[8] *= z; 7636 te[1] *= x; 7637 te[5] *= y; 7638 te[9] *= z; 7639 te[2] *= x; 7640 te[6] *= y; 7641 te[10] *= z; 7642 te[3] *= x; 7643 te[7] *= y; 7644 te[11] *= z; 7645 return this; 7646 } 7647 /** 7648 * Gets the maximum scale value of the three axes. 7649 * 7650 * @return {number} The maximum scale. 7651 */ 7652 getMaxScaleOnAxis() { 7653 const te = this.elements; 7654 const scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2]; 7655 const scaleYSq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6]; 7656 const scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10]; 7657 return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq)); 7658 } 7659 /** 7660 * Sets this matrix as a translation transform from the given vector. 7661 * 7662 * @param {number|Vector3} x - The amount to translate in the X axis or alternatively a translation vector. 7663 * @param {number} y - The amount to translate in the Y axis. 7664 * @param {number} z - The amount to translate in the z axis. 7665 * @return {Matrix4} A reference to this matrix. 7666 */ 7667 makeTranslation(x, y, z) { 7668 if (x.isVector3) { 7669 this.set( 7670 1, 7671 0, 7672 0, 7673 x.x, 7674 0, 7675 1, 7676 0, 7677 x.y, 7678 0, 7679 0, 7680 1, 7681 x.z, 7682 0, 7683 0, 7684 0, 7685 1 7686 ); 7687 } else { 7688 this.set( 7689 1, 7690 0, 7691 0, 7692 x, 7693 0, 7694 1, 7695 0, 7696 y, 7697 0, 7698 0, 7699 1, 7700 z, 7701 0, 7702 0, 7703 0, 7704 1 7705 ); 7706 } 7707 return this; 7708 } 7709 /** 7710 * Sets this matrix as a rotational transformation around the X axis by 7711 * the given angle. 7712 * 7713 * @param {number} theta - The rotation in radians. 7714 * @return {Matrix4} A reference to this matrix. 7715 */ 7716 makeRotationX(theta) { 7717 const c = Math.cos(theta), s = Math.sin(theta); 7718 this.set( 7719 1, 7720 0, 7721 0, 7722 0, 7723 0, 7724 c, 7725 -s, 7726 0, 7727 0, 7728 s, 7729 c, 7730 0, 7731 0, 7732 0, 7733 0, 7734 1 7735 ); 7736 return this; 7737 } 7738 /** 7739 * Sets this matrix as a rotational transformation around the Y axis by 7740 * the given angle. 7741 * 7742 * @param {number} theta - The rotation in radians. 7743 * @return {Matrix4} A reference to this matrix. 7744 */ 7745 makeRotationY(theta) { 7746 const c = Math.cos(theta), s = Math.sin(theta); 7747 this.set( 7748 c, 7749 0, 7750 s, 7751 0, 7752 0, 7753 1, 7754 0, 7755 0, 7756 -s, 7757 0, 7758 c, 7759 0, 7760 0, 7761 0, 7762 0, 7763 1 7764 ); 7765 return this; 7766 } 7767 /** 7768 * Sets this matrix as a rotational transformation around the Z axis by 7769 * the given angle. 7770 * 7771 * @param {number} theta - The rotation in radians. 7772 * @return {Matrix4} A reference to this matrix. 7773 */ 7774 makeRotationZ(theta) { 7775 const c = Math.cos(theta), s = Math.sin(theta); 7776 this.set( 7777 c, 7778 -s, 7779 0, 7780 0, 7781 s, 7782 c, 7783 0, 7784 0, 7785 0, 7786 0, 7787 1, 7788 0, 7789 0, 7790 0, 7791 0, 7792 1 7793 ); 7794 return this; 7795 } 7796 /** 7797 * Sets this matrix as a rotational transformation around the given axis by 7798 * the given angle. 7799 * 7800 * This is a somewhat controversial but mathematically sound alternative to 7801 * rotating via Quaternions. See the discussion [here](https://www.gamedev.net/articles/programming/math-and-physics/do-we-really-need-quaternions-r1199). 7802 * 7803 * @param {Vector3} axis - The normalized rotation axis. 7804 * @param {number} angle - The rotation in radians. 7805 * @return {Matrix4} A reference to this matrix. 7806 */ 7807 makeRotationAxis(axis, angle) { 7808 const c = Math.cos(angle); 7809 const s = Math.sin(angle); 7810 const t = 1 - c; 7811 const x = axis.x, y = axis.y, z = axis.z; 7812 const tx = t * x, ty = t * y; 7813 this.set( 7814 tx * x + c, 7815 tx * y - s * z, 7816 tx * z + s * y, 7817 0, 7818 tx * y + s * z, 7819 ty * y + c, 7820 ty * z - s * x, 7821 0, 7822 tx * z - s * y, 7823 ty * z + s * x, 7824 t * z * z + c, 7825 0, 7826 0, 7827 0, 7828 0, 7829 1 7830 ); 7831 return this; 7832 } 7833 /** 7834 * Sets this matrix as a scale transformation. 7835 * 7836 * @param {number} x - The amount to scale in the X axis. 7837 * @param {number} y - The amount to scale in the Y axis. 7838 * @param {number} z - The amount to scale in the Z axis. 7839 * @return {Matrix4} A reference to this matrix. 7840 */ 7841 makeScale(x, y, z) { 7842 this.set( 7843 x, 7844 0, 7845 0, 7846 0, 7847 0, 7848 y, 7849 0, 7850 0, 7851 0, 7852 0, 7853 z, 7854 0, 7855 0, 7856 0, 7857 0, 7858 1 7859 ); 7860 return this; 7861 } 7862 /** 7863 * Sets this matrix as a shear transformation. 7864 * 7865 * @param {number} xy - The amount to shear X by Y. 7866 * @param {number} xz - The amount to shear X by Z. 7867 * @param {number} yx - The amount to shear Y by X. 7868 * @param {number} yz - The amount to shear Y by Z. 7869 * @param {number} zx - The amount to shear Z by X. 7870 * @param {number} zy - The amount to shear Z by Y. 7871 * @return {Matrix4} A reference to this matrix. 7872 */ 7873 makeShear(xy, xz, yx, yz, zx, zy) { 7874 this.set( 7875 1, 7876 yx, 7877 zx, 7878 0, 7879 xy, 7880 1, 7881 zy, 7882 0, 7883 xz, 7884 yz, 7885 1, 7886 0, 7887 0, 7888 0, 7889 0, 7890 1 7891 ); 7892 return this; 7893 } 7894 /** 7895 * Sets this matrix to the transformation composed of the given position, 7896 * rotation (Quaternion) and scale. 7897 * 7898 * @param {Vector3} position - The position vector. 7899 * @param {Quaternion} quaternion - The rotation as a Quaternion. 7900 * @param {Vector3} scale - The scale vector. 7901 * @return {Matrix4} A reference to this matrix. 7902 */ 7903 compose(position, quaternion, scale) { 7904 const te = this.elements; 7905 const x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w; 7906 const x2 = x + x, y2 = y + y, z2 = z + z; 7907 const xx = x * x2, xy = x * y2, xz = x * z2; 7908 const yy = y * y2, yz = y * z2, zz = z * z2; 7909 const wx = w * x2, wy = w * y2, wz = w * z2; 7910 const sx = scale.x, sy = scale.y, sz = scale.z; 7911 te[0] = (1 - (yy + zz)) * sx; 7912 te[1] = (xy + wz) * sx; 7913 te[2] = (xz - wy) * sx; 7914 te[3] = 0; 7915 te[4] = (xy - wz) * sy; 7916 te[5] = (1 - (xx + zz)) * sy; 7917 te[6] = (yz + wx) * sy; 7918 te[7] = 0; 7919 te[8] = (xz + wy) * sz; 7920 te[9] = (yz - wx) * sz; 7921 te[10] = (1 - (xx + yy)) * sz; 7922 te[11] = 0; 7923 te[12] = position.x; 7924 te[13] = position.y; 7925 te[14] = position.z; 7926 te[15] = 1; 7927 return this; 7928 } 7929 /** 7930 * Decomposes this matrix into its position, rotation and scale components 7931 * and provides the result in the given objects. 7932 * 7933 * Note: Not all matrices are decomposable in this way. For example, if an 7934 * object has a non-uniformly scaled parent, then the object's world matrix 7935 * may not be decomposable, and this method may not be appropriate. 7936 * 7937 * @param {Vector3} position - The position vector. 7938 * @param {Quaternion} quaternion - The rotation as a Quaternion. 7939 * @param {Vector3} scale - The scale vector. 7940 * @return {Matrix4} A reference to this matrix. 7941 */ 7942 decompose(position, quaternion, scale) { 7943 const te = this.elements; 7944 position.x = te[12]; 7945 position.y = te[13]; 7946 position.z = te[14]; 7947 const det = this.determinant(); 7948 if (det === 0) { 7949 scale.set(1, 1, 1); 7950 quaternion.identity(); 7951 return this; 7952 } 7953 let sx = _v1$7.set(te[0], te[1], te[2]).length(); 7954 const sy = _v1$7.set(te[4], te[5], te[6]).length(); 7955 const sz = _v1$7.set(te[8], te[9], te[10]).length(); 7956 if (det < 0) sx = -sx; 7957 _m1$2.copy(this); 7958 const invSX = 1 / sx; 7959 const invSY = 1 / sy; 7960 const invSZ = 1 / sz; 7961 _m1$2.elements[0] *= invSX; 7962 _m1$2.elements[1] *= invSX; 7963 _m1$2.elements[2] *= invSX; 7964 _m1$2.elements[4] *= invSY; 7965 _m1$2.elements[5] *= invSY; 7966 _m1$2.elements[6] *= invSY; 7967 _m1$2.elements[8] *= invSZ; 7968 _m1$2.elements[9] *= invSZ; 7969 _m1$2.elements[10] *= invSZ; 7970 quaternion.setFromRotationMatrix(_m1$2); 7971 scale.x = sx; 7972 scale.y = sy; 7973 scale.z = sz; 7974 return this; 7975 } 7976 /** 7977 * Creates a perspective projection matrix. This is used internally by 7978 * {@link PerspectiveCamera#updateProjectionMatrix}. 7979 7980 * @param {number} left - Left boundary of the viewing frustum at the near plane. 7981 * @param {number} right - Right boundary of the viewing frustum at the near plane. 7982 * @param {number} top - Top boundary of the viewing frustum at the near plane. 7983 * @param {number} bottom - Bottom boundary of the viewing frustum at the near plane. 7984 * @param {number} near - The distance from the camera to the near plane. 7985 * @param {number} far - The distance from the camera to the far plane. 7986 * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system. 7987 * @param {boolean} [reversedDepth=false] - Whether to use a reversed depth. 7988 * @return {Matrix4} A reference to this matrix. 7989 */ 7990 makePerspective(left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem, reversedDepth = false) { 7991 const te = this.elements; 7992 const x = 2 * near / (right - left); 7993 const y = 2 * near / (top - bottom); 7994 const a = (right + left) / (right - left); 7995 const b = (top + bottom) / (top - bottom); 7996 let c, d; 7997 if (reversedDepth) { 7998 c = near / (far - near); 7999 d = far * near / (far - near); 8000 } else { 8001 if (coordinateSystem === WebGLCoordinateSystem) { 8002 c = -(far + near) / (far - near); 8003 d = -2 * far * near / (far - near); 8004 } else if (coordinateSystem === WebGPUCoordinateSystem) { 8005 c = -far / (far - near); 8006 d = -far * near / (far - near); 8007 } else { 8008 throw new Error("THREE.Matrix4.makePerspective(): Invalid coordinate system: " + coordinateSystem); 8009 } 8010 } 8011 te[0] = x; 8012 te[4] = 0; 8013 te[8] = a; 8014 te[12] = 0; 8015 te[1] = 0; 8016 te[5] = y; 8017 te[9] = b; 8018 te[13] = 0; 8019 te[2] = 0; 8020 te[6] = 0; 8021 te[10] = c; 8022 te[14] = d; 8023 te[3] = 0; 8024 te[7] = 0; 8025 te[11] = -1; 8026 te[15] = 0; 8027 return this; 8028 } 8029 /** 8030 * Creates a orthographic projection matrix. This is used internally by 8031 * {@link OrthographicCamera#updateProjectionMatrix}. 8032 8033 * @param {number} left - Left boundary of the viewing frustum at the near plane. 8034 * @param {number} right - Right boundary of the viewing frustum at the near plane. 8035 * @param {number} top - Top boundary of the viewing frustum at the near plane. 8036 * @param {number} bottom - Bottom boundary of the viewing frustum at the near plane. 8037 * @param {number} near - The distance from the camera to the near plane. 8038 * @param {number} far - The distance from the camera to the far plane. 8039 * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system. 8040 * @param {boolean} [reversedDepth=false] - Whether to use a reversed depth. 8041 * @return {Matrix4} A reference to this matrix. 8042 */ 8043 makeOrthographic(left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem, reversedDepth = false) { 8044 const te = this.elements; 8045 const x = 2 / (right - left); 8046 const y = 2 / (top - bottom); 8047 const a = -(right + left) / (right - left); 8048 const b = -(top + bottom) / (top - bottom); 8049 let c, d; 8050 if (reversedDepth) { 8051 c = 1 / (far - near); 8052 d = far / (far - near); 8053 } else { 8054 if (coordinateSystem === WebGLCoordinateSystem) { 8055 c = -2 / (far - near); 8056 d = -(far + near) / (far - near); 8057 } else if (coordinateSystem === WebGPUCoordinateSystem) { 8058 c = -1 / (far - near); 8059 d = -near / (far - near); 8060 } else { 8061 throw new Error("THREE.Matrix4.makeOrthographic(): Invalid coordinate system: " + coordinateSystem); 8062 } 8063 } 8064 te[0] = x; 8065 te[4] = 0; 8066 te[8] = 0; 8067 te[12] = a; 8068 te[1] = 0; 8069 te[5] = y; 8070 te[9] = 0; 8071 te[13] = b; 8072 te[2] = 0; 8073 te[6] = 0; 8074 te[10] = c; 8075 te[14] = d; 8076 te[3] = 0; 8077 te[7] = 0; 8078 te[11] = 0; 8079 te[15] = 1; 8080 return this; 8081 } 8082 /** 8083 * Returns `true` if this matrix is equal with the given one. 8084 * 8085 * @param {Matrix4} matrix - The matrix to test for equality. 8086 * @return {boolean} Whether this matrix is equal with the given one. 8087 */ 8088 equals(matrix) { 8089 const te = this.elements; 8090 const me = matrix.elements; 8091 for (let i = 0; i < 16; i++) { 8092 if (te[i] !== me[i]) return false; 8093 } 8094 return true; 8095 } 8096 /** 8097 * Sets the elements of the matrix from the given array. 8098 * 8099 * @param {Array<number>} array - The matrix elements in column-major order. 8100 * @param {number} [offset=0] - Index of the first element in the array. 8101 * @return {Matrix4} A reference to this matrix. 8102 */ 8103 fromArray(array, offset = 0) { 8104 for (let i = 0; i < 16; i++) { 8105 this.elements[i] = array[i + offset]; 8106 } 8107 return this; 8108 } 8109 /** 8110 * Writes the elements of this matrix to the given array. If no array is provided, 8111 * the method returns a new instance. 8112 * 8113 * @param {Array<number>} [array=[]] - The target array holding the matrix elements in column-major order. 8114 * @param {number} [offset=0] - Index of the first element in the array. 8115 * @return {Array<number>} The matrix elements in column-major order. 8116 */ 8117 toArray(array = [], offset = 0) { 8118 const te = this.elements; 8119 array[offset] = te[0]; 8120 array[offset + 1] = te[1]; 8121 array[offset + 2] = te[2]; 8122 array[offset + 3] = te[3]; 8123 array[offset + 4] = te[4]; 8124 array[offset + 5] = te[5]; 8125 array[offset + 6] = te[6]; 8126 array[offset + 7] = te[7]; 8127 array[offset + 8] = te[8]; 8128 array[offset + 9] = te[9]; 8129 array[offset + 10] = te[10]; 8130 array[offset + 11] = te[11]; 8131 array[offset + 12] = te[12]; 8132 array[offset + 13] = te[13]; 8133 array[offset + 14] = te[14]; 8134 array[offset + 15] = te[15]; 8135 return array; 8136 } 8137}; 8138var _v1$7 = /* @__PURE__ */ new Vector3(); 8139var _m1$2 = /* @__PURE__ */ new Matrix4(); 8140var _zero = /* @__PURE__ */ new Vector3(0, 0, 0); 8141var _one = /* @__PURE__ */ new Vector3(1, 1, 1); 8142var _x = /* @__PURE__ */ new Vector3(); 8143var _y = /* @__PURE__ */ new Vector3(); 8144var _z = /* @__PURE__ */ new Vector3(); 8145var _matrix$2 = /* @__PURE__ */ new Matrix4(); 8146var _quaternion$4 = /* @__PURE__ */ new Quaternion(); 8147var Euler = class _Euler { 8148 /** 8149 * Constructs a new euler instance. 8150 * 8151 * @param {number} [x=0] - The angle of the x axis in radians. 8152 * @param {number} [y=0] - The angle of the y axis in radians. 8153 * @param {number} [z=0] - The angle of the z axis in radians. 8154 * @param {string} [order=Euler.DEFAULT_ORDER] - A string representing the order that the rotations are applied. 8155 */ 8156 constructor(x = 0, y = 0, z = 0, order = _Euler.DEFAULT_ORDER) { 8157 this.isEuler = true; 8158 this._x = x; 8159 this._y = y; 8160 this._z = z; 8161 this._order = order; 8162 } 8163 /** 8164 * The angle of the x axis in radians. 8165 * 8166 * @type {number} 8167 * @default 0 8168 */ 8169 get x() { 8170 return this._x; 8171 } 8172 set x(value) { 8173 this._x = value; 8174 this._onChangeCallback(); 8175 } 8176 /** 8177 * The angle of the y axis in radians. 8178 * 8179 * @type {number} 8180 * @default 0 8181 */ 8182 get y() { 8183 return this._y; 8184 } 8185 set y(value) { 8186 this._y = value; 8187 this._onChangeCallback(); 8188 } 8189 /** 8190 * The angle of the z axis in radians. 8191 * 8192 * @type {number} 8193 * @default 0 8194 */ 8195 get z() { 8196 return this._z; 8197 } 8198 set z(value) { 8199 this._z = value; 8200 this._onChangeCallback(); 8201 } 8202 /** 8203 * A string representing the order that the rotations are applied. 8204 * 8205 * @type {string} 8206 * @default 'XYZ' 8207 */ 8208 get order() { 8209 return this._order; 8210 } 8211 set order(value) { 8212 this._order = value; 8213 this._onChangeCallback(); 8214 } 8215 /** 8216 * Sets the Euler components. 8217 * 8218 * @param {number} x - The angle of the x axis in radians. 8219 * @param {number} y - The angle of the y axis in radians. 8220 * @param {number} z - The angle of the z axis in radians. 8221 * @param {string} [order] - A string representing the order that the rotations are applied. 8222 * @return {Euler} A reference to this Euler instance. 8223 */ 8224 set(x, y, z, order = this._order) { 8225 this._x = x; 8226 this._y = y; 8227 this._z = z; 8228 this._order = order; 8229 this._onChangeCallback(); 8230 return this; 8231 } 8232 /** 8233 * Returns a new Euler instance with copied values from this instance. 8234 * 8235 * @return {Euler} A clone of this instance. 8236 */ 8237 clone() { 8238 return new this.constructor(this._x, this._y, this._z, this._order); 8239 } 8240 /** 8241 * Copies the values of the given Euler instance to this instance. 8242 * 8243 * @param {Euler} euler - The Euler instance to copy. 8244 * @return {Euler} A reference to this Euler instance. 8245 */ 8246 copy(euler) { 8247 this._x = euler._x; 8248 this._y = euler._y; 8249 this._z = euler._z; 8250 this._order = euler._order; 8251 this._onChangeCallback(); 8252 return this; 8253 } 8254 /** 8255 * Sets the angles of this Euler instance from a pure rotation matrix. 8256 * 8257 * @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled). 8258 * @param {string} [order] - A string representing the order that the rotations are applied. 8259 * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not. 8260 * @return {Euler} A reference to this Euler instance. 8261 */ 8262 setFromRotationMatrix(m, order = this._order, update = true) { 8263 const te = m.elements; 8264 const m11 = te[0], m12 = te[4], m13 = te[8]; 8265 const m21 = te[1], m22 = te[5], m23 = te[9]; 8266 const m31 = te[2], m32 = te[6], m33 = te[10]; 8267 switch (order) { 8268 case "XYZ": 8269 this._y = Math.asin(clamp(m13, -1, 1)); 8270 if (Math.abs(m13) < 0.9999999) { 8271 this._x = Math.atan2(-m23, m33); 8272 this._z = Math.atan2(-m12, m11); 8273 } else { 8274 this._x = Math.atan2(m32, m22); 8275 this._z = 0; 8276 } 8277 break; 8278 case "YXZ": 8279 this._x = Math.asin(-clamp(m23, -1, 1)); 8280 if (Math.abs(m23) < 0.9999999) { 8281 this._y = Math.atan2(m13, m33); 8282 this._z = Math.atan2(m21, m22); 8283 } else { 8284 this._y = Math.atan2(-m31, m11); 8285 this._z = 0; 8286 } 8287 break; 8288 case "ZXY": 8289 this._x = Math.asin(clamp(m32, -1, 1)); 8290 if (Math.abs(m32) < 0.9999999) { 8291 this._y = Math.atan2(-m31, m33); 8292 this._z = Math.atan2(-m12, m22); 8293 } else { 8294 this._y = 0; 8295 this._z = Math.atan2(m21, m11); 8296 } 8297 break; 8298 case "ZYX": 8299 this._y = Math.asin(-clamp(m31, -1, 1)); 8300 if (Math.abs(m31) < 0.9999999) { 8301 this._x = Math.atan2(m32, m33); 8302 this._z = Math.atan2(m21, m11); 8303 } else { 8304 this._x = 0; 8305 this._z = Math.atan2(-m12, m22); 8306 } 8307 break; 8308 case "YZX": 8309 this._z = Math.asin(clamp(m21, -1, 1)); 8310 if (Math.abs(m21) < 0.9999999) { 8311 this._x = Math.atan2(-m23, m22); 8312 this._y = Math.atan2(-m31, m11); 8313 } else { 8314 this._x = 0; 8315 this._y = Math.atan2(m13, m33); 8316 } 8317 break; 8318 case "XZY": 8319 this._z = Math.asin(-clamp(m12, -1, 1)); 8320 if (Math.abs(m12) < 0.9999999) { 8321 this._x = Math.atan2(m32, m22); 8322 this._y = Math.atan2(m13, m11); 8323 } else { 8324 this._x = Math.atan2(-m23, m33); 8325 this._y = 0; 8326 } 8327 break; 8328 default: 8329 warn("Euler: .setFromRotationMatrix() encountered an unknown order: " + order); 8330 } 8331 this._order = order; 8332 if (update === true) this._onChangeCallback(); 8333 return this; 8334 } 8335 /** 8336 * Sets the angles of this Euler instance from a normalized quaternion. 8337 * 8338 * @param {Quaternion} q - A normalized Quaternion. 8339 * @param {string} [order] - A string representing the order that the rotations are applied. 8340 * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not. 8341 * @return {Euler} A reference to this Euler instance. 8342 */ 8343 setFromQuaternion(q, order, update) { 8344 _matrix$2.makeRotationFromQuaternion(q); 8345 return this.setFromRotationMatrix(_matrix$2, order, update); 8346 } 8347 /** 8348 * Sets the angles of this Euler instance from the given vector. 8349 * 8350 * @param {Vector3} v - The vector. 8351 * @param {string} [order] - A string representing the order that the rotations are applied. 8352 * @return {Euler} A reference to this Euler instance. 8353 */ 8354 setFromVector3(v, order = this._order) { 8355 return this.set(v.x, v.y, v.z, order); 8356 } 8357 /** 8358 * Resets the euler angle with a new order by creating a quaternion from this 8359 * euler angle and then setting this euler angle with the quaternion and the 8360 * new order. 8361 * 8362 * Warning: This discards revolution information. 8363 * 8364 * @param {string} [newOrder] - A string representing the new order that the rotations are applied. 8365 * @return {Euler} A reference to this Euler instance. 8366 */ 8367 reorder(newOrder) { 8368 _quaternion$4.setFromEuler(this); 8369 return this.setFromQuaternion(_quaternion$4, newOrder); 8370 } 8371 /** 8372 * Returns `true` if this Euler instance is equal with the given one. 8373 * 8374 * @param {Euler} euler - The Euler instance to test for equality. 8375 * @return {boolean} Whether this Euler instance is equal with the given one. 8376 */ 8377 equals(euler) { 8378 return euler._x === this._x && euler._y === this._y && euler._z === this._z && euler._order === this._order; 8379 } 8380 /** 8381 * Sets this Euler instance's components to values from the given array. The first three 8382 * entries of the array are assign to the x,y and z components. An optional fourth entry 8383 * defines the Euler order. 8384 * 8385 * @param {Array<number,number,number,?string>} array - An array holding the Euler component values. 8386 * @return {Euler} A reference to this Euler instance. 8387 */ 8388 fromArray(array) { 8389 this._x = array[0]; 8390 this._y = array[1]; 8391 this._z = array[2]; 8392 if (array[3] !== void 0) this._order = array[3]; 8393 this._onChangeCallback(); 8394 return this; 8395 } 8396 /** 8397 * Writes the components of this Euler instance to the given array. If no array is provided, 8398 * the method returns a new instance. 8399 * 8400 * @param {Array<number,number,number,string>} [array=[]] - The target array holding the Euler components. 8401 * @param {number} [offset=0] - Index of the first element in the array. 8402 * @return {Array<number,number,number,string>} The Euler components. 8403 */ 8404 toArray(array = [], offset = 0) { 8405 array[offset] = this._x; 8406 array[offset + 1] = this._y; 8407 array[offset + 2] = this._z; 8408 array[offset + 3] = this._order; 8409 return array; 8410 } 8411 _onChange(callback) { 8412 this._onChangeCallback = callback; 8413 return this; 8414 } 8415 _onChangeCallback() { 8416 } 8417 *[Symbol.iterator]() { 8418 yield this._x; 8419 yield this._y; 8420 yield this._z; 8421 yield this._order; 8422 } 8423}; 8424Euler.DEFAULT_ORDER = "XYZ"; 8425var Layers = class { 8426 /** 8427 * Constructs a new layers instance, with membership 8428 * initially set to layer `0`. 8429 */ 8430 constructor() { 8431 this.mask = 1 | 0; 8432 } 8433 /** 8434 * Sets membership to the given layer, and remove membership all other layers. 8435 * 8436 * @param {number} layer - The layer to set. 8437 */ 8438 set(layer) { 8439 this.mask = (1 << layer | 0) >>> 0; 8440 } 8441 /** 8442 * Adds membership of the given layer. 8443 * 8444 * @param {number} layer - The layer to enable. 8445 */ 8446 enable(layer) { 8447 this.mask |= 1 << layer | 0; 8448 } 8449 /** 8450 * Adds membership to all layers. 8451 */ 8452 enableAll() { 8453 this.mask = 4294967295 | 0; 8454 } 8455 /** 8456 * Toggles the membership of the given layer. 8457 * 8458 * @param {number} layer - The layer to toggle. 8459 */ 8460 toggle(layer) { 8461 this.mask ^= 1 << layer | 0; 8462 } 8463 /** 8464 * Removes membership of the given layer. 8465 * 8466 * @param {number} layer - The layer to enable. 8467 */ 8468 disable(layer) { 8469 this.mask &= ~(1 << layer | 0); 8470 } 8471 /** 8472 * Removes the membership from all layers. 8473 */ 8474 disableAll() { 8475 this.mask = 0; 8476 } 8477 /** 8478 * Returns `true` if this and the given layers object have at least one 8479 * layer in common. 8480 * 8481 * @param {Layers} layers - The layers to test. 8482 * @return {boolean } Whether this and the given layers object have at least one layer in common or not. 8483 */ 8484 test(layers) { 8485 return (this.mask & layers.mask) !== 0; 8486 } 8487 /** 8488 * Returns `true` if the given layer is enabled. 8489 * 8490 * @param {number} layer - The layer to test. 8491 * @return {boolean } Whether the given layer is enabled or not. 8492 */ 8493 isEnabled(layer) { 8494 return (this.mask & (1 << layer | 0)) !== 0; 8495 } 8496}; 8497var _object3DId = 0; 8498var _v1$6 = /* @__PURE__ */ new Vector3(); 8499var _q1 = /* @__PURE__ */ new Quaternion(); 8500var _m1$1 = /* @__PURE__ */ new Matrix4(); 8501var _target = /* @__PURE__ */ new Vector3(); 8502var _position$4 = /* @__PURE__ */ new Vector3(); 8503var _scale$3 = /* @__PURE__ */ new Vector3(); 8504var _quaternion$3 = /* @__PURE__ */ new Quaternion(); 8505var _xAxis = /* @__PURE__ */ new Vector3(1, 0, 0); 8506var _yAxis = /* @__PURE__ */ new Vector3(0, 1, 0); 8507var _zAxis = /* @__PURE__ */ new Vector3(0, 0, 1); 8508var _addedEvent = { type: "added" }; 8509var _removedEvent = { type: "removed" }; 8510var _childaddedEvent = { type: "childadded", child: null }; 8511var _childremovedEvent = { type: "childremoved", child: null }; 8512var Object3D = class _Object3D extends EventDispatcher { 8513 /** 8514 * Constructs a new 3D object. 8515 */ 8516 constructor() { 8517 super(); 8518 this.isObject3D = true; 8519 Object.defineProperty(this, "id", { value: _object3DId++ }); 8520 this.uuid = generateUUID(); 8521 this.name = ""; 8522 this.type = "Object3D"; 8523 this.parent = null; 8524 this.children = []; 8525 this.up = _Object3D.DEFAULT_UP.clone(); 8526 const position = new Vector3(); 8527 const rotation = new Euler(); 8528 const quaternion = new Quaternion(); 8529 const scale = new Vector3(1, 1, 1); 8530 function onRotationChange() { 8531 quaternion.setFromEuler(rotation, false); 8532 } 8533 function onQuaternionChange() { 8534 rotation.setFromQuaternion(quaternion, void 0, false); 8535 } 8536 rotation._onChange(onRotationChange); 8537 quaternion._onChange(onQuaternionChange); 8538 Object.defineProperties(this, { 8539 /** 8540 * Represents the object's local position. 8541 * 8542 * @name Object3D#position 8543 * @type {Vector3} 8544 * @default (0,0,0) 8545 */ 8546 position: { 8547 configurable: true, 8548 enumerable: true, 8549 value: position 8550 }, 8551 /** 8552 * Represents the object's local rotation as Euler angles, in radians. 8553 * 8554 * @name Object3D#rotation 8555 * @type {Euler} 8556 * @default (0,0,0) 8557 */ 8558 rotation: { 8559 configurable: true, 8560 enumerable: true, 8561 value: rotation 8562 }, 8563 /** 8564 * Represents the object's local rotation as Quaternions. 8565 * 8566 * @name Object3D#quaternion 8567 * @type {Quaternion} 8568 */ 8569 quaternion: { 8570 configurable: true, 8571 enumerable: true, 8572 value: quaternion 8573 }, 8574 /** 8575 * Represents the object's local scale. 8576 * 8577 * @name Object3D#scale 8578 * @type {Vector3} 8579 * @default (1,1,1) 8580 */ 8581 scale: { 8582 configurable: true, 8583 enumerable: true, 8584 value: scale 8585 }, 8586 /** 8587 * Represents the object's model-view matrix. 8588 * 8589 * @name Object3D#modelViewMatrix 8590 * @type {Matrix4} 8591 */ 8592 modelViewMatrix: { 8593 value: new Matrix4() 8594 }, 8595 /** 8596 * Represents the object's normal matrix. 8597 * 8598 * @name Object3D#normalMatrix 8599 * @type {Matrix3} 8600 */ 8601 normalMatrix: { 8602 value: new Matrix3() 8603 } 8604 }); 8605 this.matrix = new Matrix4(); 8606 this.matrixWorld = new Matrix4(); 8607 this.matrixAutoUpdate = _Object3D.DEFAULT_MATRIX_AUTO_UPDATE; 8608 this.matrixWorldAutoUpdate = _Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE; 8609 this.matrixWorldNeedsUpdate = false; 8610 this.layers = new Layers(); 8611 this.visible = true; 8612 this.castShadow = false; 8613 this.receiveShadow = false; 8614 this.frustumCulled = true; 8615 this.renderOrder = 0; 8616 this.animations = []; 8617 this.customDepthMaterial = void 0; 8618 this.customDistanceMaterial = void 0; 8619 this.static = false; 8620 this.userData = {}; 8621 this.pivot = null; 8622 } 8623 /** 8624 * A callback that is executed immediately before a 3D object is rendered to a shadow map. 8625 * 8626 * @param {Renderer|WebGLRenderer} renderer - The renderer. 8627 * @param {Object3D} object - The 3D object. 8628 * @param {Camera} camera - The camera that is used to render the scene. 8629 * @param {Camera} shadowCamera - The shadow camera. 8630 * @param {BufferGeometry} geometry - The 3D object's geometry. 8631 * @param {Material} depthMaterial - The depth material. 8632 * @param {Object} group - The geometry group data. 8633 */ 8634 onBeforeShadow() { 8635 } 8636 /** 8637 * A callback that is executed immediately after a 3D object is rendered to a shadow map. 8638 * 8639 * @param {Renderer|WebGLRenderer} renderer - The renderer. 8640 * @param {Object3D} object - The 3D object. 8641 * @param {Camera} camera - The camera that is used to render the scene. 8642 * @param {Camera} shadowCamera - The shadow camera. 8643 * @param {BufferGeometry} geometry - The 3D object's geometry. 8644 * @param {Material} depthMaterial - The depth material. 8645 * @param {Object} group - The geometry group data. 8646 */ 8647 onAfterShadow() { 8648 } 8649 /** 8650 * A callback that is executed immediately before a 3D object is rendered. 8651 * 8652 * @param {Renderer|WebGLRenderer} renderer - The renderer. 8653 * @param {Object3D} object - The 3D object. 8654 * @param {Camera} camera - The camera that is used to render the scene. 8655 * @param {BufferGeometry} geometry - The 3D object's geometry. 8656 * @param {Material} material - The 3D object's material. 8657 * @param {Object} group - The geometry group data. 8658 */ 8659 onBeforeRender() { 8660 } 8661 /** 8662 * A callback that is executed immediately after a 3D object is rendered. 8663 * 8664 * @param {Renderer|WebGLRenderer} renderer - The renderer. 8665 * @param {Object3D} object - The 3D object. 8666 * @param {Camera} camera - The camera that is used to render the scene. 8667 * @param {BufferGeometry} geometry - The 3D object's geometry. 8668 * @param {Material} material - The 3D object's material. 8669 * @param {Object} group - The geometry group data. 8670 */ 8671 onAfterRender() { 8672 } 8673 /** 8674 * Applies the given transformation matrix to the object and updates the object's position, 8675 * rotation and scale. 8676 * 8677 * @param {Matrix4} matrix - The transformation matrix. 8678 */ 8679 applyMatrix4(matrix) { 8680 if (this.matrixAutoUpdate) this.updateMatrix(); 8681 this.matrix.premultiply(matrix); 8682 this.matrix.decompose(this.position, this.quaternion, this.scale); 8683 } 8684 /** 8685 * Applies a rotation represented by given the quaternion to the 3D object. 8686 * 8687 * @param {Quaternion} q - The quaternion. 8688 * @return {Object3D} A reference to this instance. 8689 */ 8690 applyQuaternion(q) { 8691 this.quaternion.premultiply(q); 8692 return this; 8693 } 8694 /** 8695 * Sets the given rotation represented as an axis/angle couple to the 3D object. 8696 * 8697 * @param {Vector3} axis - The (normalized) axis vector. 8698 * @param {number} angle - The angle in radians. 8699 */ 8700 setRotationFromAxisAngle(axis, angle) { 8701 this.quaternion.setFromAxisAngle(axis, angle); 8702 } 8703 /** 8704 * Sets the given rotation represented as Euler angles to the 3D object. 8705 * 8706 * @param {Euler} euler - The Euler angles. 8707 */ 8708 setRotationFromEuler(euler) { 8709 this.quaternion.setFromEuler(euler, true); 8710 } 8711 /** 8712 * Sets the given rotation represented as rotation matrix to the 3D object. 8713 * 8714 * @param {Matrix4} m - Although a 4x4 matrix is expected, the upper 3x3 portion must be 8715 * a pure rotation matrix (i.e, unscaled). 8716 */ 8717 setRotationFromMatrix(m) { 8718 this.quaternion.setFromRotationMatrix(m); 8719 } 8720 /** 8721 * Sets the given rotation represented as a Quaternion to the 3D object. 8722 * 8723 * @param {Quaternion} q - The Quaternion 8724 */ 8725 setRotationFromQuaternion(q) { 8726 this.quaternion.copy(q); 8727 } 8728 /** 8729 * Rotates the 3D object along an axis in local space. 8730 * 8731 * @param {Vector3} axis - The (normalized) axis vector. 8732 * @param {number} angle - The angle in radians. 8733 * @return {Object3D} A reference to this instance. 8734 */ 8735 rotateOnAxis(axis, angle) { 8736 _q1.setFromAxisAngle(axis, angle); 8737 this.quaternion.multiply(_q1); 8738 return this; 8739 } 8740 /** 8741 * Rotates the 3D object along an axis in world space. 8742 * 8743 * @param {Vector3} axis - The (normalized) axis vector. 8744 * @param {number} angle - The angle in radians. 8745 * @return {Object3D} A reference to this instance. 8746 */ 8747 rotateOnWorldAxis(axis, angle) { 8748 _q1.setFromAxisAngle(axis, angle); 8749 this.quaternion.premultiply(_q1); 8750 return this; 8751 } 8752 /** 8753 * Rotates the 3D object around its X axis in local space. 8754 * 8755 * @param {number} angle - The angle in radians. 8756 * @return {Object3D} A reference to this instance. 8757 */ 8758 rotateX(angle) { 8759 return this.rotateOnAxis(_xAxis, angle); 8760 } 8761 /** 8762 * Rotates the 3D object around its Y axis in local space. 8763 * 8764 * @param {number} angle - The angle in radians. 8765 * @return {Object3D} A reference to this instance. 8766 */ 8767 rotateY(angle) { 8768 return this.rotateOnAxis(_yAxis, angle); 8769 } 8770 /** 8771 * Rotates the 3D object around its Z axis in local space. 8772 * 8773 * @param {number} angle - The angle in radians. 8774 * @return {Object3D} A reference to this instance. 8775 */ 8776 rotateZ(angle) { 8777 return this.rotateOnAxis(_zAxis, angle); 8778 } 8779 /** 8780 * Translate the 3D object by a distance along the given axis in local space. 8781 * 8782 * @param {Vector3} axis - The (normalized) axis vector. 8783 * @param {number} distance - The distance in world units. 8784 * @return {Object3D} A reference to this instance. 8785 */ 8786 translateOnAxis(axis, distance) { 8787 _v1$6.copy(axis).applyQuaternion(this.quaternion); 8788 this.position.add(_v1$6.multiplyScalar(distance)); 8789 return this; 8790 } 8791 /** 8792 * Translate the 3D object by a distance along its X-axis in local space. 8793 * 8794 * @param {number} distance - The distance in world units. 8795 * @return {Object3D} A reference to this instance. 8796 */ 8797 translateX(distance) { 8798 return this.translateOnAxis(_xAxis, distance); 8799 } 8800 /** 8801 * Translate the 3D object by a distance along its Y-axis in local space. 8802 * 8803 * @param {number} distance - The distance in world units. 8804 * @return {Object3D} A reference to this instance. 8805 */ 8806 translateY(distance) { 8807 return this.translateOnAxis(_yAxis, distance); 8808 } 8809 /** 8810 * Translate the 3D object by a distance along its Z-axis in local space. 8811 * 8812 * @param {number} distance - The distance in world units. 8813 * @return {Object3D} A reference to this instance. 8814 */ 8815 translateZ(distance) { 8816 return this.translateOnAxis(_zAxis, distance); 8817 } 8818 /** 8819 * Converts the given vector from this 3D object's local space to world space. 8820 * 8821 * @param {Vector3} vector - The vector to convert. 8822 * @return {Vector3} The converted vector. 8823 */ 8824 localToWorld(vector) { 8825 this.updateWorldMatrix(true, false); 8826 return vector.applyMatrix4(this.matrixWorld); 8827 } 8828 /** 8829 * Converts the given vector from this 3D object's world space to local space. 8830 * 8831 * @param {Vector3} vector - The vector to convert. 8832 * @return {Vector3} The converted vector. 8833 */ 8834 worldToLocal(vector) { 8835 this.updateWorldMatrix(true, false); 8836 return vector.applyMatrix4(_m1$1.copy(this.matrixWorld).invert()); 8837 } 8838 /** 8839 * Rotates the object to face a point in world space. 8840 * 8841 * This method does not support objects having non-uniformly-scaled parent(s). 8842 * 8843 * @param {number|Vector3} x - The x coordinate in world space. Alternatively, a vector representing a position in world space 8844 * @param {number} [y] - The y coordinate in world space. 8845 * @param {number} [z] - The z coordinate in world space. 8846 */ 8847 lookAt(x, y, z) { 8848 if (x.isVector3) { 8849 _target.copy(x); 8850 } else { 8851 _target.set(x, y, z); 8852 } 8853 const parent = this.parent; 8854 this.updateWorldMatrix(true, false); 8855 _position$4.setFromMatrixPosition(this.matrixWorld); 8856 if (this.isCamera || this.isLight) { 8857 _m1$1.lookAt(_position$4, _target, this.up); 8858 } else { 8859 _m1$1.lookAt(_target, _position$4, this.up); 8860 } 8861 this.quaternion.setFromRotationMatrix(_m1$1); 8862 if (parent) { 8863 _m1$1.extractRotation(parent.matrixWorld); 8864 _q1.setFromRotationMatrix(_m1$1); 8865 this.quaternion.premultiply(_q1.invert()); 8866 } 8867 } 8868 /** 8869 * Adds the given 3D object as a child to this 3D object. An arbitrary number of 8870 * objects may be added. Any current parent on an object passed in here will be 8871 * removed, since an object can have at most one parent. 8872 * 8873 * @fires Object3D#added 8874 * @fires Object3D#childadded 8875 * @param {Object3D} object - The 3D object to add. 8876 * @return {Object3D} A reference to this instance. 8877 */ 8878 add(object) { 8879 if (arguments.length > 1) { 8880 for (let i = 0; i < arguments.length; i++) { 8881 this.add(arguments[i]); 8882 } 8883 return this; 8884 } 8885 if (object === this) { 8886 error("Object3D.add: object can't be added as a child of itself.", object); 8887 return this; 8888 } 8889 if (object && object.isObject3D) { 8890 object.removeFromParent(); 8891 object.parent = this; 8892 this.children.push(object); 8893 object.dispatchEvent(_addedEvent); 8894 _childaddedEvent.child = object; 8895 this.dispatchEvent(_childaddedEvent); 8896 _childaddedEvent.child = null; 8897 } else { 8898 error("Object3D.add: object not an instance of THREE.Object3D.", object); 8899 } 8900 return this; 8901 } 8902 /** 8903 * Removes the given 3D object as child from this 3D object. 8904 * An arbitrary number of objects may be removed. 8905 * 8906 * @fires Object3D#removed 8907 * @fires Object3D#childremoved 8908 * @param {Object3D} object - The 3D object to remove. 8909 * @return {Object3D} A reference to this instance. 8910 */ 8911 remove(object) { 8912 if (arguments.length > 1) { 8913 for (let i = 0; i < arguments.length; i++) { 8914 this.remove(arguments[i]); 8915 } 8916 return this; 8917 } 8918 const index = this.children.indexOf(object); 8919 if (index !== -1) { 8920 object.parent = null; 8921 this.children.splice(index, 1); 8922 object.dispatchEvent(_removedEvent); 8923 _childremovedEvent.child = object; 8924 this.dispatchEvent(_childremovedEvent); 8925 _childremovedEvent.child = null; 8926 } 8927 return this; 8928 } 8929 /** 8930 * Removes this 3D object from its current parent. 8931 * 8932 * @fires Object3D#removed 8933 * @fires Object3D#childremoved 8934 * @return {Object3D} A reference to this instance. 8935 */ 8936 removeFromParent() { 8937 const parent = this.parent; 8938 if (parent !== null) { 8939 parent.remove(this); 8940 } 8941 return this; 8942 } 8943 /** 8944 * Removes all child objects. 8945 * 8946 * @fires Object3D#removed 8947 * @fires Object3D#childremoved 8948 * @return {Object3D} A reference to this instance. 8949 */ 8950 clear() { 8951 return this.remove(...this.children); 8952 } 8953 /** 8954 * Adds the given 3D object as a child of this 3D object, while maintaining the object's world 8955 * transform. This method does not support scene graphs having non-uniformly-scaled nodes(s). 8956 * 8957 * @fires Object3D#added 8958 * @fires Object3D#childadded 8959 * @param {Object3D} object - The 3D object to attach. 8960 * @return {Object3D} A reference to this instance. 8961 */ 8962 attach(object) { 8963 this.updateWorldMatrix(true, false); 8964 _m1$1.copy(this.matrixWorld).invert(); 8965 if (object.parent !== null) { 8966 object.parent.updateWorldMatrix(true, false); 8967 _m1$1.multiply(object.parent.matrixWorld); 8968 } 8969 object.applyMatrix4(_m1$1); 8970 object.removeFromParent(); 8971 object.parent = this; 8972 this.children.push(object); 8973 object.updateWorldMatrix(false, true); 8974 object.dispatchEvent(_addedEvent); 8975 _childaddedEvent.child = object; 8976 this.dispatchEvent(_childaddedEvent); 8977 _childaddedEvent.child = null; 8978 return this; 8979 } 8980 /** 8981 * Searches through the 3D object and its children, starting with the 3D object 8982 * itself, and returns the first with a matching ID. 8983 * 8984 * @param {number} id - The id. 8985 * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found. 8986 */ 8987 getObjectById(id) { 8988 return this.getObjectByProperty("id", id); 8989 } 8990 /** 8991 * Searches through the 3D object and its children, starting with the 3D object 8992 * itself, and returns the first with a matching name. 8993 * 8994 * @param {string} name - The name. 8995 * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found. 8996 */ 8997 getObjectByName(name) { 8998 return this.getObjectByProperty("name", name); 8999 } 9000 /** 9001 * Searches through the 3D object and its children, starting with the 3D object 9002 * itself, and returns the first with a matching property value. 9003 * 9004 * @param {string} name - The name of the property. 9005 * @param {any} value - The value. 9006 * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found. 9007 */ 9008 getObjectByProperty(name, value) { 9009 if (this[name] === value) return this; 9010 for (let i = 0, l = this.children.length; i < l; i++) { 9011 const child = this.children[i]; 9012 const object = child.getObjectByProperty(name, value); 9013 if (object !== void 0) { 9014 return object; 9015 } 9016 } 9017 return void 0; 9018 } 9019 /** 9020 * Searches through the 3D object and its children, starting with the 3D object 9021 * itself, and returns all 3D objects with a matching property value. 9022 * 9023 * @param {string} name - The name of the property. 9024 * @param {any} value - The value. 9025 * @param {Array<Object3D>} result - The method stores the result in this array. 9026 * @return {Array<Object3D>} The found 3D objects. 9027 */ 9028 getObjectsByProperty(name, value, result = []) { 9029 if (this[name] === value) result.push(this); 9030 const children2 = this.children; 9031 for (let i = 0, l = children2.length; i < l; i++) { 9032 children2[i].getObjectsByProperty(name, value, result); 9033 } 9034 return result; 9035 } 9036 /** 9037 * Returns a vector representing the position of the 3D object in world space. 9038 * 9039 * @param {Vector3} target - The target vector the result is stored to. 9040 * @return {Vector3} The 3D object's position in world space. 9041 */ 9042 getWorldPosition(target) { 9043 this.updateWorldMatrix(true, false); 9044 return target.setFromMatrixPosition(this.matrixWorld); 9045 } 9046 /** 9047 * Returns a Quaternion representing the position of the 3D object in world space. 9048 * 9049 * @param {Quaternion} target - The target Quaternion the result is stored to. 9050 * @return {Quaternion} The 3D object's rotation in world space. 9051 */ 9052 getWorldQuaternion(target) { 9053 this.updateWorldMatrix(true, false); 9054 this.matrixWorld.decompose(_position$4, target, _scale$3); 9055 return target; 9056 } 9057 /** 9058 * Returns a vector representing the scale of the 3D object in world space. 9059 * 9060 * @param {Vector3} target - The target vector the result is stored to. 9061 * @return {Vector3} The 3D object's scale in world space. 9062 */ 9063 getWorldScale(target) { 9064 this.updateWorldMatrix(true, false); 9065 this.matrixWorld.decompose(_position$4, _quaternion$3, target); 9066 return target; 9067 } 9068 /** 9069 * Returns a vector representing the ("look") direction of the 3D object in world space. 9070 * 9071 * @param {Vector3} target - The target vector the result is stored to. 9072 * @return {Vector3} The 3D object's direction in world space. 9073 */ 9074 getWorldDirection(target) { 9075 this.updateWorldMatrix(true, false); 9076 const e = this.matrixWorld.elements; 9077 return target.set(e[8], e[9], e[10]).normalize(); 9078 } 9079 /** 9080 * Abstract method to get intersections between a casted ray and this 9081 * 3D object. Renderable 3D objects such as {@link Mesh}, {@link Line} or {@link Points} 9082 * implement this method in order to use raycasting. 9083 * 9084 * @abstract 9085 * @param {Raycaster} raycaster - The raycaster. 9086 * @param {Array<Object>} intersects - An array holding the result of the method. 9087 */ 9088 raycast() { 9089 } 9090 /** 9091 * Executes the callback on this 3D object and all descendants. 9092 * 9093 * Note: Modifying the scene graph inside the callback is discouraged. 9094 * 9095 * @param {Function} callback - A callback function that allows to process the current 3D object. 9096 */ 9097 traverse(callback) { 9098 callback(this); 9099 const children2 = this.children; 9100 for (let i = 0, l = children2.length; i < l; i++) { 9101 children2[i].traverse(callback); 9102 } 9103 } 9104 /** 9105 * Like {@link Object3D#traverse}, but the callback will only be executed for visible 3D objects. 9106 * Descendants of invisible 3D objects are not traversed. 9107 * 9108 * Note: Modifying the scene graph inside the callback is discouraged. 9109 * 9110 * @param {Function} callback - A callback function that allows to process the current 3D object. 9111 */ 9112 traverseVisible(callback) { 9113 if (this.visible === false) return; 9114 callback(this); 9115 const children2 = this.children; 9116 for (let i = 0, l = children2.length; i < l; i++) { 9117 children2[i].traverseVisible(callback); 9118 } 9119 } 9120 /** 9121 * Like {@link Object3D#traverse}, but the callback will only be executed for all ancestors. 9122 * 9123 * Note: Modifying the scene graph inside the callback is discouraged. 9124 * 9125 * @param {Function} callback - A callback function that allows to process the current 3D object. 9126 */ 9127 traverseAncestors(callback) { 9128 const parent = this.parent; 9129 if (parent !== null) { 9130 callback(parent); 9131 parent.traverseAncestors(callback); 9132 } 9133 } 9134 /** 9135 * Updates the transformation matrix in local space by computing it from the current 9136 * position, rotation and scale values. 9137 */ 9138 updateMatrix() { 9139 this.matrix.compose(this.position, this.quaternion, this.scale); 9140 const pivot = this.pivot; 9141 if (pivot !== null) { 9142 const px = pivot.x, py = pivot.y, pz = pivot.z; 9143 const te = this.matrix.elements; 9144 te[12] += px - te[0] * px - te[4] * py - te[8] * pz; 9145 te[13] += py - te[1] * px - te[5] * py - te[9] * pz; 9146 te[14] += pz - te[2] * px - te[6] * py - te[10] * pz; 9147 } 9148 this.matrixWorldNeedsUpdate = true; 9149 } 9150 /** 9151 * Updates the transformation matrix in world space of this 3D objects and its descendants. 9152 * 9153 * To ensure correct results, this method also recomputes the 3D object's transformation matrix in 9154 * local space. The computation of the local and world matrix can be controlled with the 9155 * {@link Object3D#matrixAutoUpdate} and {@link Object3D#matrixWorldAutoUpdate} flags which are both 9156 * `true` by default. Set these flags to `false` if you need more control over the update matrix process. 9157 * 9158 * @param {boolean} [force=false] - When set to `true`, a recomputation of world matrices is forced even 9159 * when {@link Object3D#matrixWorldNeedsUpdate} is `false`. 9160 */ 9161 updateMatrixWorld(force) { 9162 if (this.matrixAutoUpdate) this.updateMatrix(); 9163 if (this.matrixWorldNeedsUpdate || force) { 9164 if (this.matrixWorldAutoUpdate === true) { 9165 if (this.parent === null) { 9166 this.matrixWorld.copy(this.matrix); 9167 } else { 9168 this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix); 9169 } 9170 } 9171 this.matrixWorldNeedsUpdate = false; 9172 force = true; 9173 } 9174 const children2 = this.children; 9175 for (let i = 0, l = children2.length; i < l; i++) { 9176 const child = children2[i]; 9177 child.updateMatrixWorld(force); 9178 } 9179 } 9180 /** 9181 * An alternative version of {@link Object3D#updateMatrixWorld} with more control over the 9182 * update of ancestor and descendant nodes. 9183 * 9184 * @param {boolean} [updateParents=false] Whether ancestor nodes should be updated or not. 9185 * @param {boolean} [updateChildren=false] Whether descendant nodes should be updated or not. 9186 */ 9187 updateWorldMatrix(updateParents, updateChildren) { 9188 const parent = this.parent; 9189 if (updateParents === true && parent !== null) { 9190 parent.updateWorldMatrix(true, false); 9191 } 9192 if (this.matrixAutoUpdate) this.updateMatrix(); 9193 if (this.matrixWorldAutoUpdate === true) { 9194 if (this.parent === null) { 9195 this.matrixWorld.copy(this.matrix); 9196 } else { 9197 this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix); 9198 } 9199 } 9200 if (updateChildren === true) { 9201 const children2 = this.children; 9202 for (let i = 0, l = children2.length; i < l; i++) { 9203 const child = children2[i]; 9204 child.updateWorldMatrix(false, true); 9205 } 9206 } 9207 } 9208 /** 9209 * Serializes the 3D object into JSON. 9210 * 9211 * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. 9212 * @return {Object} A JSON object representing the serialized 3D object. 9213 * @see {@link ObjectLoader#parse} 9214 */ 9215 toJSON(meta) { 9216 const isRootObject = meta === void 0 || typeof meta === "string"; 9217 const output = {}; 9218 if (isRootObject) { 9219 meta = { 9220 geometries: {}, 9221 materials: {}, 9222 textures: {}, 9223 images: {}, 9224 shapes: {}, 9225 skeletons: {}, 9226 animations: {}, 9227 nodes: {} 9228 }; 9229 output.metadata = { 9230 version: 4.7, 9231 type: "Object", 9232 generator: "Object3D.toJSON" 9233 }; 9234 } 9235 const object = {}; 9236 object.uuid = this.uuid; 9237 object.type = this.type; 9238 if (this.name !== "") object.name = this.name; 9239 if (this.castShadow === true) object.castShadow = true; 9240 if (this.receiveShadow === true) object.receiveShadow = true; 9241 if (this.visible === false) object.visible = false; 9242 if (this.frustumCulled === false) object.frustumCulled = false; 9243 if (this.renderOrder !== 0) object.renderOrder = this.renderOrder; 9244 if (this.static !== false) object.static = this.static; 9245 if (Object.keys(this.userData).length > 0) object.userData = this.userData; 9246 object.layers = this.layers.mask; 9247 object.matrix = this.matrix.toArray(); 9248 object.up = this.up.toArray(); 9249 if (this.pivot !== null) object.pivot = this.pivot.toArray(); 9250 if (this.matrixAutoUpdate === false) object.matrixAutoUpdate = false; 9251 if (this.morphTargetDictionary !== void 0) object.morphTargetDictionary = Object.assign({}, this.morphTargetDictionary); 9252 if (this.morphTargetInfluences !== void 0) object.morphTargetInfluences = this.morphTargetInfluences.slice(); 9253 if (this.isInstancedMesh) { 9254 object.type = "InstancedMesh"; 9255 object.count = this.count; 9256 object.instanceMatrix = this.instanceMatrix.toJSON(); 9257 if (this.instanceColor !== null) object.instanceColor = this.instanceColor.toJSON(); 9258 } 9259 if (this.isBatchedMesh) { 9260 object.type = "BatchedMesh"; 9261 object.perObjectFrustumCulled = this.perObjectFrustumCulled; 9262 object.sortObjects = this.sortObjects; 9263 object.drawRanges = this._drawRanges; 9264 object.reservedRanges = this._reservedRanges; 9265 object.geometryInfo = this._geometryInfo.map((info) => ({ 9266 ...info, 9267 boundingBox: info.boundingBox ? info.boundingBox.toJSON() : void 0, 9268 boundingSphere: info.boundingSphere ? info.boundingSphere.toJSON() : void 0 9269 })); 9270 object.instanceInfo = this._instanceInfo.map((info) => ({ ...info })); 9271 object.availableInstanceIds = this._availableInstanceIds.slice(); 9272 object.availableGeometryIds = this._availableGeometryIds.slice(); 9273 object.nextIndexStart = this._nextIndexStart; 9274 object.nextVertexStart = this._nextVertexStart; 9275 object.geometryCount = this._geometryCount; 9276 object.maxInstanceCount = this._maxInstanceCount; 9277 object.maxVertexCount = this._maxVertexCount; 9278 object.maxIndexCount = this._maxIndexCount; 9279 object.geometryInitialized = this._geometryInitialized; 9280 object.matricesTexture = this._matricesTexture.toJSON(meta); 9281 object.indirectTexture = this._indirectTexture.toJSON(meta); 9282 if (this._colorsTexture !== null) { 9283 object.colorsTexture = this._colorsTexture.toJSON(meta); 9284 } 9285 if (this.boundingSphere !== null) { 9286 object.boundingSphere = this.boundingSphere.toJSON(); 9287 } 9288 if (this.boundingBox !== null) { 9289 object.boundingBox = this.boundingBox.toJSON(); 9290 } 9291 } 9292 function serialize(library, element) { 9293 if (library[element.uuid] === void 0) { 9294 library[element.uuid] = element.toJSON(meta); 9295 } 9296 return element.uuid; 9297 } 9298 if (this.isScene) { 9299 if (this.background) { 9300 if (this.background.isColor) { 9301 object.background = this.background.toJSON(); 9302 } else if (this.background.isTexture) { 9303 object.background = this.background.toJSON(meta).uuid; 9304 } 9305 } 9306 if (this.environment && this.environment.isTexture && this.environment.isRenderTargetTexture !== true) { 9307 object.environment = this.environment.toJSON(meta).uuid; 9308 } 9309 } else if (this.isMesh || this.isLine || this.isPoints) { 9310 object.geometry = serialize(meta.geometries, this.geometry); 9311 const parameters = this.geometry.parameters; 9312 if (parameters !== void 0 && parameters.shapes !== void 0) { 9313 const shapes = parameters.shapes; 9314 if (Array.isArray(shapes)) { 9315 for (let i = 0, l = shapes.length; i < l; i++) { 9316 const shape = shapes[i]; 9317 serialize(meta.shapes, shape); 9318 } 9319 } else { 9320 serialize(meta.shapes, shapes); 9321 } 9322 } 9323 } 9324 if (this.isSkinnedMesh) { 9325 object.bindMode = this.bindMode; 9326 object.bindMatrix = this.bindMatrix.toArray(); 9327 if (this.skeleton !== void 0) { 9328 serialize(meta.skeletons, this.skeleton); 9329 object.skeleton = this.skeleton.uuid; 9330 } 9331 } 9332 if (this.material !== void 0) { 9333 if (Array.isArray(this.material)) { 9334 const uuids = []; 9335 for (let i = 0, l = this.material.length; i < l; i++) { 9336 uuids.push(serialize(meta.materials, this.material[i])); 9337 } 9338 object.material = uuids; 9339 } else { 9340 object.material = serialize(meta.materials, this.material); 9341 } 9342 } 9343 if (this.children.length > 0) { 9344 object.children = []; 9345 for (let i = 0; i < this.children.length; i++) { 9346 object.children.push(this.children[i].toJSON(meta).object); 9347 } 9348 } 9349 if (this.animations.length > 0) { 9350 object.animations = []; 9351 for (let i = 0; i < this.animations.length; i++) { 9352 const animation = this.animations[i]; 9353 object.animations.push(serialize(meta.animations, animation)); 9354 } 9355 } 9356 if (isRootObject) { 9357 const geometries = extractFromCache(meta.geometries); 9358 const materials = extractFromCache(meta.materials); 9359 const textures = extractFromCache(meta.textures); 9360 const images = extractFromCache(meta.images); 9361 const shapes = extractFromCache(meta.shapes); 9362 const skeletons = extractFromCache(meta.skeletons); 9363 const animations = extractFromCache(meta.animations); 9364 const nodes = extractFromCache(meta.nodes); 9365 if (geometries.length > 0) output.geometries = geometries; 9366 if (materials.length > 0) output.materials = materials; 9367 if (textures.length > 0) output.textures = textures; 9368 if (images.length > 0) output.images = images; 9369 if (shapes.length > 0) output.shapes = shapes; 9370 if (skeletons.length > 0) output.skeletons = skeletons; 9371 if (animations.length > 0) output.animations = animations; 9372 if (nodes.length > 0) output.nodes = nodes; 9373 } 9374 output.object = object; 9375 return output; 9376 function extractFromCache(cache) { 9377 const values = []; 9378 for (const key in cache) { 9379 const data = cache[key]; 9380 delete data.metadata; 9381 values.push(data); 9382 } 9383 return values; 9384 } 9385 } 9386 /** 9387 * Returns a new 3D object with copied values from this instance. 9388 * 9389 * @param {boolean} [recursive=true] - When set to `true`, descendants of the 3D object are also cloned. 9390 * @return {Object3D} A clone of this instance. 9391 */ 9392 clone(recursive) { 9393 return new this.constructor().copy(this, recursive); 9394 } 9395 /** 9396 * Copies the values of the given 3D object to this instance. 9397 * 9398 * @param {Object3D} source - The 3D object to copy. 9399 * @param {boolean} [recursive=true] - When set to `true`, descendants of the 3D object are cloned. 9400 * @return {Object3D} A reference to this instance. 9401 */ 9402 copy(source, recursive = true) { 9403 this.name = source.name; 9404 this.up.copy(source.up); 9405 this.position.copy(source.position); 9406 this.rotation.order = source.rotation.order; 9407 this.quaternion.copy(source.quaternion); 9408 this.scale.copy(source.scale); 9409 this.pivot = source.pivot !== null ? source.pivot.clone() : null; 9410 this.matrix.copy(source.matrix); 9411 this.matrixWorld.copy(source.matrixWorld); 9412 this.matrixAutoUpdate = source.matrixAutoUpdate; 9413 this.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate; 9414 this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; 9415 this.layers.mask = source.layers.mask; 9416 this.visible = source.visible; 9417 this.castShadow = source.castShadow; 9418 this.receiveShadow = source.receiveShadow; 9419 this.frustumCulled = source.frustumCulled; 9420 this.renderOrder = source.renderOrder; 9421 this.static = source.static; 9422 this.animations = source.animations.slice(); 9423 this.userData = JSON.parse(JSON.stringify(source.userData)); 9424 if (recursive === true) { 9425 for (let i = 0; i < source.children.length; i++) { 9426 const child = source.children[i]; 9427 this.add(child.clone()); 9428 } 9429 } 9430 return this; 9431 } 9432}; 9433Object3D.DEFAULT_UP = /* @__PURE__ */ new Vector3(0, 1, 0); 9434Object3D.DEFAULT_MATRIX_AUTO_UPDATE = true; 9435Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = true; 9436var Group = class extends Object3D { 9437 constructor() { 9438 super(); 9439 this.isGroup = true; 9440 this.type = "Group"; 9441 } 9442}; 9443var _moveEvent = { type: "move" }; 9444var WebXRController = class { 9445 /** 9446 * Constructs a new XR controller. 9447 */ 9448 constructor() { 9449 this._targetRay = null; 9450 this._grip = null; 9451 this._hand = null; 9452 } 9453 /** 9454 * Returns a group representing the hand space of the XR controller. 9455 * 9456 * @return {Group} A group representing the hand space of the XR controller. 9457 */ 9458 getHandSpace() { 9459 if (this._hand === null) { 9460 this._hand = new Group(); 9461 this._hand.matrixAutoUpdate = false; 9462 this._hand.visible = false; 9463 this._hand.joints = {}; 9464 this._hand.inputState = { pinching: false }; 9465 } 9466 return this._hand; 9467 } 9468 /** 9469 * Returns a group representing the target ray space of the XR controller. 9470 * 9471 * @return {Group} A group representing the target ray space of the XR controller. 9472 */ 9473 getTargetRaySpace() { 9474 if (this._targetRay === null) { 9475 this._targetRay = new Group(); 9476 this._targetRay.matrixAutoUpdate = false; 9477 this._targetRay.visible = false; 9478 this._targetRay.hasLinearVelocity = false; 9479 this._targetRay.linearVelocity = new Vector3(); 9480 this._targetRay.hasAngularVelocity = false; 9481 this._targetRay.angularVelocity = new Vector3(); 9482 } 9483 return this._targetRay; 9484 } 9485 /** 9486 * Returns a group representing the grip space of the XR controller. 9487 * 9488 * @return {Group} A group representing the grip space of the XR controller. 9489 */ 9490 getGripSpace() { 9491 if (this._grip === null) { 9492 this._grip = new Group(); 9493 this._grip.matrixAutoUpdate = false; 9494 this._grip.visible = false; 9495 this._grip.hasLinearVelocity = false; 9496 this._grip.linearVelocity = new Vector3(); 9497 this._grip.hasAngularVelocity = false; 9498 this._grip.angularVelocity = new Vector3(); 9499 this._grip.eventsEnabled = false; 9500 } 9501 return this._grip; 9502 } 9503 /** 9504 * Dispatches the given event to the groups representing 9505 * the different coordinate spaces of the XR controller. 9506 * 9507 * @param {Object} event - The event to dispatch. 9508 * @return {WebXRController} A reference to this instance. 9509 */ 9510 dispatchEvent(event) { 9511 if (this._targetRay !== null) { 9512 this._targetRay.dispatchEvent(event); 9513 } 9514 if (this._grip !== null) { 9515 this._grip.dispatchEvent(event); 9516 } 9517 if (this._hand !== null) { 9518 this._hand.dispatchEvent(event); 9519 } 9520 return this; 9521 } 9522 /** 9523 * Connects the controller with the given XR input source. 9524 * 9525 * @param {XRInputSource} inputSource - The input source. 9526 * @return {WebXRController} A reference to this instance. 9527 */ 9528 connect(inputSource) { 9529 if (inputSource && inputSource.hand) { 9530 const hand = this._hand; 9531 if (hand) { 9532 for (const inputjoint of inputSource.hand.values()) { 9533 this._getHandJoint(hand, inputjoint); 9534 } 9535 } 9536 } 9537 this.dispatchEvent({ type: "connected", data: inputSource }); 9538 return this; 9539 } 9540 /** 9541 * Disconnects the controller from the given XR input source. 9542 * 9543 * @param {XRInputSource} inputSource - The input source. 9544 * @return {WebXRController} A reference to this instance. 9545 */ 9546 disconnect(inputSource) { 9547 this.dispatchEvent({ type: "disconnected", data: inputSource }); 9548 if (this._targetRay !== null) { 9549 this._targetRay.visible = false; 9550 } 9551 if (this._grip !== null) { 9552 this._grip.visible = false; 9553 } 9554 if (this._hand !== null) { 9555 this._hand.visible = false; 9556 } 9557 return this; 9558 } 9559 /** 9560 * Updates the controller with the given input source, XR frame and reference space. 9561 * This updates the transformations of the groups that represent the different 9562 * coordinate systems of the controller. 9563 * 9564 * @param {XRInputSource} inputSource - The input source. 9565 * @param {XRFrame} frame - The XR frame. 9566 * @param {XRReferenceSpace} referenceSpace - The reference space. 9567 * @return {WebXRController} A reference to this instance. 9568 */ 9569 update(inputSource, frame, referenceSpace) { 9570 let inputPose = null; 9571 let gripPose = null; 9572 let handPose = null; 9573 const targetRay = this._targetRay; 9574 const grip = this._grip; 9575 const hand = this._hand; 9576 if (inputSource && frame.session.visibilityState !== "visible-blurred") { 9577 if (hand && inputSource.hand) { 9578 handPose = true; 9579 for (const inputjoint of inputSource.hand.values()) { 9580 const jointPose = frame.getJointPose(inputjoint, referenceSpace); 9581 const joint = this._getHandJoint(hand, inputjoint); 9582 if (jointPose !== null) { 9583 joint.matrix.fromArray(jointPose.transform.matrix); 9584 joint.matrix.decompose(joint.position, joint.rotation, joint.scale); 9585 joint.matrixWorldNeedsUpdate = true; 9586 joint.jointRadius = jointPose.radius; 9587 } 9588 joint.visible = jointPose !== null; 9589 } 9590 const indexTip = hand.joints["index-finger-tip"]; 9591 const thumbTip = hand.joints["thumb-tip"]; 9592 const distance = indexTip.position.distanceTo(thumbTip.position); 9593 const distanceToPinch = 0.02; 9594 const threshold = 5e-3; 9595 if (hand.inputState.pinching && distance > distanceToPinch + threshold) { 9596 hand.inputState.pinching = false; 9597 this.dispatchEvent({ 9598 type: "pinchend", 9599 handedness: inputSource.handedness, 9600 target: this 9601 }); 9602 } else if (!hand.inputState.pinching && distance <= distanceToPinch - threshold) { 9603 hand.inputState.pinching = true; 9604 this.dispatchEvent({ 9605 type: "pinchstart", 9606 handedness: inputSource.handedness, 9607 target: this 9608 }); 9609 } 9610 } else { 9611 if (grip !== null && inputSource.gripSpace) { 9612 gripPose = frame.getPose(inputSource.gripSpace, referenceSpace); 9613 if (gripPose !== null) { 9614 grip.matrix.fromArray(gripPose.transform.matrix); 9615 grip.matrix.decompose(grip.position, grip.rotation, grip.scale); 9616 grip.matrixWorldNeedsUpdate = true; 9617 if (gripPose.linearVelocity) { 9618 grip.hasLinearVelocity = true; 9619 grip.linearVelocity.copy(gripPose.linearVelocity); 9620 } else { 9621 grip.hasLinearVelocity = false; 9622 } 9623 if (gripPose.angularVelocity) { 9624 grip.hasAngularVelocity = true; 9625 grip.angularVelocity.copy(gripPose.angularVelocity); 9626 } else { 9627 grip.hasAngularVelocity = false; 9628 } 9629 if (grip.eventsEnabled) { 9630 grip.dispatchEvent({ 9631 type: "gripUpdated", 9632 data: inputSource, 9633 target: this 9634 }); 9635 } 9636 } 9637 } 9638 } 9639 if (targetRay !== null) { 9640 inputPose = frame.getPose(inputSource.targetRaySpace, referenceSpace); 9641 if (inputPose === null && gripPose !== null) { 9642 inputPose = gripPose; 9643 } 9644 if (inputPose !== null) { 9645 targetRay.matrix.fromArray(inputPose.transform.matrix); 9646 targetRay.matrix.decompose(targetRay.position, targetRay.rotation, targetRay.scale); 9647 targetRay.matrixWorldNeedsUpdate = true; 9648 if (inputPose.linearVelocity) { 9649 targetRay.hasLinearVelocity = true; 9650 targetRay.linearVelocity.copy(inputPose.linearVelocity); 9651 } else { 9652 targetRay.hasLinearVelocity = false; 9653 } 9654 if (inputPose.angularVelocity) { 9655 targetRay.hasAngularVelocity = true; 9656 targetRay.angularVelocity.copy(inputPose.angularVelocity); 9657 } else { 9658 targetRay.hasAngularVelocity = false; 9659 } 9660 this.dispatchEvent(_moveEvent); 9661 } 9662 } 9663 } 9664 if (targetRay !== null) { 9665 targetRay.visible = inputPose !== null; 9666 } 9667 if (grip !== null) { 9668 grip.visible = gripPose !== null; 9669 } 9670 if (hand !== null) { 9671 hand.visible = handPose !== null; 9672 } 9673 return this; 9674 } 9675 /** 9676 * Returns a group representing the hand joint for the given input joint. 9677 * 9678 * @private 9679 * @param {Group} hand - The group representing the hand space. 9680 * @param {XRJointSpace} inputjoint - The hand joint data. 9681 * @return {Group} A group representing the hand joint for the given input joint. 9682 */ 9683 _getHandJoint(hand, inputjoint) { 9684 if (hand.joints[inputjoint.jointName] === void 0) { 9685 const joint = new Group(); 9686 joint.matrixAutoUpdate = false; 9687 joint.visible = false; 9688 hand.joints[inputjoint.jointName] = joint; 9689 hand.add(joint); 9690 } 9691 return hand.joints[inputjoint.jointName]; 9692 } 9693}; 9694var _colorKeywords = { 9695 "aliceblue": 15792383, 9696 "antiquewhite": 16444375, 9697 "aqua": 65535, 9698 "aquamarine": 8388564, 9699 "azure": 15794175, 9700 "beige": 16119260, 9701 "bisque": 16770244, 9702 "black": 0, 9703 "blanchedalmond": 16772045, 9704 "blue": 255, 9705 "blueviolet": 9055202, 9706 "brown": 10824234, 9707 "burlywood": 14596231, 9708 "cadetblue": 6266528, 9709 "chartreuse": 8388352, 9710 "chocolate": 13789470, 9711 "coral": 16744272, 9712 "cornflowerblue": 6591981, 9713 "cornsilk": 16775388, 9714 "crimson": 14423100, 9715 "cyan": 65535, 9716 "darkblue": 139, 9717 "darkcyan": 35723, 9718 "darkgoldenrod": 12092939, 9719 "darkgray": 11119017, 9720 "darkgreen": 25600, 9721 "darkgrey": 11119017, 9722 "darkkhaki": 12433259, 9723 "darkmagenta": 9109643, 9724 "darkolivegreen": 5597999, 9725 "darkorange": 16747520, 9726 "darkorchid": 10040012, 9727 "darkred": 9109504, 9728 "darksalmon": 15308410, 9729 "darkseagreen": 9419919, 9730 "darkslateblue": 4734347, 9731 "darkslategray": 3100495, 9732 "darkslategrey": 3100495, 9733 "darkturquoise": 52945, 9734 "darkviolet": 9699539, 9735 "deeppink": 16716947, 9736 "deepskyblue": 49151, 9737 "dimgray": 6908265, 9738 "dimgrey": 6908265, 9739 "dodgerblue": 2003199, 9740 "firebrick": 11674146, 9741 "floralwhite": 16775920, 9742 "forestgreen": 2263842, 9743 "fuchsia": 16711935, 9744 "gainsboro": 14474460, 9745 "ghostwhite": 16316671, 9746 "gold": 16766720, 9747 "goldenrod": 14329120, 9748 "gray": 8421504, 9749 "green": 32768, 9750 "greenyellow": 11403055, 9751 "grey": 8421504, 9752 "honeydew": 15794160, 9753 "hotpink": 16738740, 9754 "indianred": 13458524, 9755 "indigo": 4915330, 9756 "ivory": 16777200, 9757 "khaki": 15787660, 9758 "lavender": 15132410, 9759 "lavenderblush": 16773365, 9760 "lawngreen": 8190976, 9761 "lemonchiffon": 16775885, 9762 "lightblue": 11393254, 9763 "lightcoral": 15761536, 9764 "lightcyan": 14745599, 9765 "lightgoldenrodyellow": 16448210, 9766 "lightgray": 13882323, 9767 "lightgreen": 9498256, 9768 "lightgrey": 13882323, 9769 "lightpink": 16758465, 9770 "lightsalmon": 16752762, 9771 "lightseagreen": 2142890, 9772 "lightskyblue": 8900346, 9773 "lightslategray": 7833753, 9774 "lightslategrey": 7833753, 9775 "lightsteelblue": 11584734, 9776 "lightyellow": 16777184, 9777 "lime": 65280, 9778 "limegreen": 3329330, 9779 "linen": 16445670, 9780 "magenta": 16711935, 9781 "maroon": 8388608, 9782 "mediumaquamarine": 6737322, 9783 "mediumblue": 205, 9784 "mediumorchid": 12211667, 9785 "mediumpurple": 9662683, 9786 "mediumseagreen": 3978097, 9787 "mediumslateblue": 8087790, 9788 "mediumspringgreen": 64154, 9789 "mediumturquoise": 4772300, 9790 "mediumvioletred": 13047173, 9791 "midnightblue": 1644912, 9792 "mintcream": 16121850, 9793 "mistyrose": 16770273, 9794 "moccasin": 16770229, 9795 "navajowhite": 16768685, 9796 "navy": 128, 9797 "oldlace": 16643558, 9798 "olive": 8421376, 9799 "olivedrab": 7048739, 9800 "orange": 16753920, 9801 "orangered": 16729344, 9802 "orchid": 14315734, 9803 "palegoldenrod": 15657130, 9804 "palegreen": 10025880, 9805 "paleturquoise": 11529966, 9806 "palevioletred": 14381203, 9807 "papayawhip": 16773077, 9808 "peachpuff": 16767673, 9809 "peru": 13468991, 9810 "pink": 16761035, 9811 "plum": 14524637, 9812 "powderblue": 11591910, 9813 "purple": 8388736, 9814 "rebeccapurple": 6697881, 9815 "red": 16711680, 9816 "rosybrown": 12357519, 9817 "royalblue": 4286945, 9818 "saddlebrown": 9127187, 9819 "salmon": 16416882, 9820 "sandybrown": 16032864, 9821 "seagreen": 3050327, 9822 "seashell": 16774638, 9823 "sienna": 10506797, 9824 "silver": 12632256, 9825 "skyblue": 8900331, 9826 "slateblue": 6970061, 9827 "slategray": 7372944, 9828 "slategrey": 7372944, 9829 "snow": 16775930, 9830 "springgreen": 65407, 9831 "steelblue": 4620980, 9832 "tan": 13808780, 9833 "teal": 32896, 9834 "thistle": 14204888, 9835 "tomato": 16737095, 9836 "turquoise": 4251856, 9837 "violet": 15631086, 9838 "wheat": 16113331, 9839 "white": 16777215, 9840 "whitesmoke": 16119285, 9841 "yellow": 16776960, 9842 "yellowgreen": 10145074 9843}; 9844var _hslA = { h: 0, s: 0, l: 0 }; 9845var _hslB = { h: 0, s: 0, l: 0 }; 9846function hue2rgb(p, q, t) { 9847 if (t < 0) t += 1; 9848 if (t > 1) t -= 1; 9849 if (t < 1 / 6) return p + (q - p) * 6 * t; 9850 if (t < 1 / 2) return q; 9851 if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t); 9852 return p; 9853} 9854var Color = class { 9855 /** 9856 * Constructs a new color. 9857 * 9858 * Note that standard method of specifying color in three.js is with a hexadecimal triplet, 9859 * and that method is used throughout the rest of the documentation. 9860 * 9861 * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are 9862 * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance. 9863 * @param {number} [g] - The green component. 9864 * @param {number} [b] - The blue component. 9865 */ 9866 constructor(r, g, b) { 9867 this.isColor = true; 9868 this.r = 1; 9869 this.g = 1; 9870 this.b = 1; 9871 return this.set(r, g, b); 9872 } 9873 /** 9874 * Sets the colors's components from the given values. 9875 * 9876 * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are 9877 * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance. 9878 * @param {number} [g] - The green component. 9879 * @param {number} [b] - The blue component. 9880 * @return {Color} A reference to this color. 9881 */ 9882 set(r, g, b) { 9883 if (g === void 0 && b === void 0) { 9884 const value = r; 9885 if (value && value.isColor) { 9886 this.copy(value); 9887 } else if (typeof value === "number") { 9888 this.setHex(value); 9889 } else if (typeof value === "string") { 9890 this.setStyle(value); 9891 } 9892 } else { 9893 this.setRGB(r, g, b); 9894 } 9895 return this; 9896 } 9897 /** 9898 * Sets the colors's components to the given scalar value. 9899 * 9900 * @param {number} scalar - The scalar value. 9901 * @return {Color} A reference to this color. 9902 */ 9903 setScalar(scalar) { 9904 this.r = scalar; 9905 this.g = scalar; 9906 this.b = scalar; 9907 return this; 9908 } 9909 /** 9910 * Sets this color from a hexadecimal value. 9911 * 9912 * @param {number} hex - The hexadecimal value. 9913 * @param {string} [colorSpace=SRGBColorSpace] - The color space. 9914 * @return {Color} A reference to this color. 9915 */ 9916 setHex(hex, colorSpace = SRGBColorSpace) { 9917 hex = Math.floor(hex); 9918 this.r = (hex >> 16 & 255) / 255; 9919 this.g = (hex >> 8 & 255) / 255; 9920 this.b = (hex & 255) / 255; 9921 ColorManagement.colorSpaceToWorking(this, colorSpace); 9922 return this; 9923 } 9924 /** 9925 * Sets this color from RGB values. 9926 * 9927 * @param {number} r - Red channel value between `0.0` and `1.0`. 9928 * @param {number} g - Green channel value between `0.0` and `1.0`. 9929 * @param {number} b - Blue channel value between `0.0` and `1.0`. 9930 * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. 9931 * @return {Color} A reference to this color. 9932 */ 9933 setRGB(r, g, b, colorSpace = ColorManagement.workingColorSpace) { 9934 this.r = r; 9935 this.g = g; 9936 this.b = b; 9937 ColorManagement.colorSpaceToWorking(this, colorSpace); 9938 return this; 9939 } 9940 /** 9941 * Sets this color from RGB values. 9942 * 9943 * @param {number} h - Hue value between `0.0` and `1.0`. 9944 * @param {number} s - Saturation value between `0.0` and `1.0`. 9945 * @param {number} l - Lightness value between `0.0` and `1.0`. 9946 * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. 9947 * @return {Color} A reference to this color. 9948 */ 9949 setHSL(h, s, l, colorSpace = ColorManagement.workingColorSpace) { 9950 h = euclideanModulo(h, 1); 9951 s = clamp(s, 0, 1); 9952 l = clamp(l, 0, 1); 9953 if (s === 0) { 9954 this.r = this.g = this.b = l; 9955 } else { 9956 const p = l <= 0.5 ? l * (1 + s) : l + s - l * s; 9957 const q = 2 * l - p; 9958 this.r = hue2rgb(q, p, h + 1 / 3); 9959 this.g = hue2rgb(q, p, h); 9960 this.b = hue2rgb(q, p, h - 1 / 3); 9961 } 9962 ColorManagement.colorSpaceToWorking(this, colorSpace); 9963 return this; 9964 } 9965 /** 9966 * Sets this color from a CSS-style string. For example, `rgb(250, 0,0)`, 9967 * `rgb(100%, 0%, 0%)`, `hsl(0, 100%, 50%)`, `#ff0000`, `#f00`, or `red` ( or 9968 * any [X11 color name](https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart) - 9969 * all 140 color names are supported). 9970 * 9971 * @param {string} style - Color as a CSS-style string. 9972 * @param {string} [colorSpace=SRGBColorSpace] - The color space. 9973 * @return {Color} A reference to this color. 9974 */ 9975 setStyle(style2, colorSpace = SRGBColorSpace) { 9976 function handleAlpha(string) { 9977 if (string === void 0) return; 9978 if (parseFloat(string) < 1) { 9979 warn("Color: Alpha component of " + style2 + " will be ignored."); 9980 } 9981 } 9982 let m; 9983 if (m = /^(\w+)\(([^\)]*)\)/.exec(style2)) { 9984 let color; 9985 const name = m[1]; 9986 const components = m[2]; 9987 switch (name) { 9988 case "rgb": 9989 case "rgba": 9990 if (color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { 9991 handleAlpha(color[4]); 9992 return this.setRGB( 9993 Math.min(255, parseInt(color[1], 10)) / 255, 9994 Math.min(255, parseInt(color[2], 10)) / 255, 9995 Math.min(255, parseInt(color[3], 10)) / 255, 9996 colorSpace 9997 ); 9998 } 9999 if (color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { 10000 handleAlpha(color[4]); 10001 return this.setRGB( 10002 Math.min(100, parseInt(color[1], 10)) / 100, 10003 Math.min(100, parseInt(color[2], 10)) / 100, 10004 Math.min(100, parseInt(color[3], 10)) / 100, 10005 colorSpace 10006 ); 10007 } 10008 break; 10009 case "hsl": 10010 case "hsla": 10011 if (color = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { 10012 handleAlpha(color[4]); 10013 return this.setHSL( 10014 parseFloat(color[1]) / 360, 10015 parseFloat(color[2]) / 100, 10016 parseFloat(color[3]) / 100, 10017 colorSpace 10018 ); 10019 } 10020 break; 10021 default: 10022 warn("Color: Unknown color model " + style2); 10023 } 10024 } else if (m = /^\#([A-Fa-f\d]+)$/.exec(style2)) { 10025 const hex = m[1]; 10026 const size = hex.length; 10027 if (size === 3) { 10028 return this.setRGB( 10029 parseInt(hex.charAt(0), 16) / 15, 10030 parseInt(hex.charAt(1), 16) / 15, 10031 parseInt(hex.charAt(2), 16) / 15, 10032 colorSpace 10033 ); 10034 } else if (size === 6) { 10035 return this.setHex(parseInt(hex, 16), colorSpace); 10036 } else { 10037 warn("Color: Invalid hex color " + style2); 10038 } 10039 } else if (style2 && style2.length > 0) { 10040 return this.setColorName(style2, colorSpace); 10041 } 10042 return this; 10043 } 10044 /** 10045 * Sets this color from a color name. Faster than {@link Color#setStyle} if 10046 * you don't need the other CSS-style formats. 10047 * 10048 * For convenience, the list of names is exposed in `Color.NAMES` as a hash. 10049 * ```js 10050 * Color.NAMES.aliceblue // returns 0xF0F8FF 10051 * ``` 10052 * 10053 * @param {string} style - The color name. 10054 * @param {string} [colorSpace=SRGBColorSpace] - The color space. 10055 * @return {Color} A reference to this color. 10056 */ 10057 setColorName(style2, colorSpace = SRGBColorSpace) { 10058 const hex = _colorKeywords[style2.toLowerCase()]; 10059 if (hex !== void 0) { 10060 this.setHex(hex, colorSpace); 10061 } else { 10062 warn("Color: Unknown color " + style2); 10063 } 10064 return this; 10065 } 10066 /** 10067 * Returns a new color with copied values from this instance. 10068 * 10069 * @return {Color} A clone of this instance. 10070 */ 10071 clone() { 10072 return new this.constructor(this.r, this.g, this.b); 10073 } 10074 /** 10075 * Copies the values of the given color to this instance. 10076 * 10077 * @param {Color} color - The color to copy. 10078 * @return {Color} A reference to this color. 10079 */ 10080 copy(color) { 10081 this.r = color.r; 10082 this.g = color.g; 10083 this.b = color.b; 10084 return this; 10085 } 10086 /** 10087 * Copies the given color into this color, and then converts this color from 10088 * `SRGBColorSpace` to `LinearSRGBColorSpace`. 10089 * 10090 * @param {Color} color - The color to copy/convert. 10091 * @return {Color} A reference to this color. 10092 */ 10093 copySRGBToLinear(color) { 10094 this.r = SRGBToLinear(color.r); 10095 this.g = SRGBToLinear(color.g); 10096 this.b = SRGBToLinear(color.b); 10097 return this; 10098 } 10099 /** 10100 * Copies the given color into this color, and then converts this color from 10101 * `LinearSRGBColorSpace` to `SRGBColorSpace`. 10102 * 10103 * @param {Color} color - The color to copy/convert. 10104 * @return {Color} A reference to this color. 10105 */ 10106 copyLinearToSRGB(color) { 10107 this.r = LinearToSRGB(color.r); 10108 this.g = LinearToSRGB(color.g); 10109 this.b = LinearToSRGB(color.b); 10110 return this; 10111 } 10112 /** 10113 * Converts this color from `SRGBColorSpace` to `LinearSRGBColorSpace`. 10114 * 10115 * @return {Color} A reference to this color. 10116 */ 10117 convertSRGBToLinear() { 10118 this.copySRGBToLinear(this); 10119 return this; 10120 } 10121 /** 10122 * Converts this color from `LinearSRGBColorSpace` to `SRGBColorSpace`. 10123 * 10124 * @return {Color} A reference to this color. 10125 */ 10126 convertLinearToSRGB() { 10127 this.copyLinearToSRGB(this); 10128 return this; 10129 } 10130 /** 10131 * Returns the hexadecimal value of this color. 10132 * 10133 * @param {string} [colorSpace=SRGBColorSpace] - The color space. 10134 * @return {number} The hexadecimal value. 10135 */ 10136 getHex(colorSpace = SRGBColorSpace) { 10137 ColorManagement.workingToColorSpace(_color.copy(this), colorSpace); 10138 return Math.round(clamp(_color.r * 255, 0, 255)) * 65536 + Math.round(clamp(_color.g * 255, 0, 255)) * 256 + Math.round(clamp(_color.b * 255, 0, 255)); 10139 } 10140 /** 10141 * Returns the hexadecimal value of this color as a string (for example, 'FFFFFF'). 10142 * 10143 * @param {string} [colorSpace=SRGBColorSpace] - The color space. 10144 * @return {string} The hexadecimal value as a string. 10145 */ 10146 getHexString(colorSpace = SRGBColorSpace) { 10147 return ("000000" + this.getHex(colorSpace).toString(16)).slice(-6); 10148 } 10149 /** 10150 * Converts the colors RGB values into the HSL format and stores them into the 10151 * given target object. 10152 * 10153 * @param {{h:number,s:number,l:number}} target - The target object that is used to store the method's result. 10154 * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. 10155 * @return {{h:number,s:number,l:number}} The HSL representation of this color. 10156 */ 10157 getHSL(target, colorSpace = ColorManagement.workingColorSpace) { 10158 ColorManagement.workingToColorSpace(_color.copy(this), colorSpace); 10159 const r = _color.r, g = _color.g, b = _color.b; 10160 const max = Math.max(r, g, b); 10161 const min = Math.min(r, g, b); 10162 let hue, saturation; 10163 const lightness = (min + max) / 2; 10164 if (min === max) { 10165 hue = 0; 10166 saturation = 0; 10167 } else { 10168 const delta = max - min; 10169 saturation = lightness <= 0.5 ? delta / (max + min) : delta / (2 - max - min); 10170 switch (max) { 10171 case r: 10172 hue = (g - b) / delta + (g < b ? 6 : 0); 10173 break; 10174 case g: 10175 hue = (b - r) / delta + 2; 10176 break; 10177 case b: 10178 hue = (r - g) / delta + 4; 10179 break; 10180 } 10181 hue /= 6; 10182 } 10183 target.h = hue; 10184 target.s = saturation; 10185 target.l = lightness; 10186 return target; 10187 } 10188 /** 10189 * Returns the RGB values of this color and stores them into the given target object. 10190 * 10191 * @param {Color} target - The target color that is used to store the method's result. 10192 * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. 10193 * @return {Color} The RGB representation of this color. 10194 */ 10195 getRGB(target, colorSpace = ColorManagement.workingColorSpace) { 10196 ColorManagement.workingToColorSpace(_color.copy(this), colorSpace); 10197 target.r = _color.r; 10198 target.g = _color.g; 10199 target.b = _color.b; 10200 return target; 10201 } 10202 /** 10203 * Returns the value of this color as a CSS style string. Example: `rgb(255,0,0)`. 10204 * 10205 * @param {string} [colorSpace=SRGBColorSpace] - The color space. 10206 * @return {string} The CSS representation of this color. 10207 */ 10208 getStyle(colorSpace = SRGBColorSpace) { 10209 ColorManagement.workingToColorSpace(_color.copy(this), colorSpace); 10210 const r = _color.r, g = _color.g, b = _color.b; 10211 if (colorSpace !== SRGBColorSpace) { 10212 return `color(${colorSpace} ${r.toFixed(3)} ${g.toFixed(3)} ${b.toFixed(3)})`; 10213 } 10214 return `rgb(${Math.round(r * 255)},${Math.round(g * 255)},${Math.round(b * 255)})`; 10215 } 10216 /** 10217 * Adds the given HSL values to this color's values. 10218 * Internally, this converts the color's RGB values to HSL, adds HSL 10219 * and then converts the color back to RGB. 10220 * 10221 * @param {number} h - Hue value between `0.0` and `1.0`. 10222 * @param {number} s - Saturation value between `0.0` and `1.0`. 10223 * @param {number} l - Lightness value between `0.0` and `1.0`. 10224 * @return {Color} A reference to this color. 10225 */ 10226 offsetHSL(h, s, l) { 10227 this.getHSL(_hslA); 10228 return this.setHSL(_hslA.h + h, _hslA.s + s, _hslA.l + l); 10229 } 10230 /** 10231 * Adds the RGB values of the given color to the RGB values of this color. 10232 * 10233 * @param {Color} color - The color to add. 10234 * @return {Color} A reference to this color. 10235 */ 10236 add(color) { 10237 this.r += color.r; 10238 this.g += color.g; 10239 this.b += color.b; 10240 return this; 10241 } 10242 /** 10243 * Adds the RGB values of the given colors and stores the result in this instance. 10244 * 10245 * @param {Color} color1 - The first color. 10246 * @param {Color} color2 - The second color. 10247 * @return {Color} A reference to this color. 10248 */ 10249 addColors(color1, color2) { 10250 this.r = color1.r + color2.r; 10251 this.g = color1.g + color2.g; 10252 this.b = color1.b + color2.b; 10253 return this; 10254 } 10255 /** 10256 * Adds the given scalar value to the RGB values of this color. 10257 * 10258 * @param {number} s - The scalar to add. 10259 * @return {Color} A reference to this color. 10260 */ 10261 addScalar(s) { 10262 this.r += s; 10263 this.g += s; 10264 this.b += s; 10265 return this; 10266 } 10267 /** 10268 * Subtracts the RGB values of the given color from the RGB values of this color. 10269 * 10270 * @param {Color} color - The color to subtract. 10271 * @return {Color} A reference to this color. 10272 */ 10273 sub(color) { 10274 this.r = Math.max(0, this.r - color.r); 10275 this.g = Math.max(0, this.g - color.g); 10276 this.b = Math.max(0, this.b - color.b); 10277 return this; 10278 } 10279 /** 10280 * Multiplies the RGB values of the given color with the RGB values of this color. 10281 * 10282 * @param {Color} color - The color to multiply. 10283 * @return {Color} A reference to this color. 10284 */ 10285 multiply(color) { 10286 this.r *= color.r; 10287 this.g *= color.g; 10288 this.b *= color.b; 10289 return this; 10290 } 10291 /** 10292 * Multiplies the given scalar value with the RGB values of this color. 10293 * 10294 * @param {number} s - The scalar to multiply. 10295 * @return {Color} A reference to this color. 10296 */ 10297 multiplyScalar(s) { 10298 this.r *= s; 10299 this.g *= s; 10300 this.b *= s; 10301 return this; 10302 } 10303 /** 10304 * Linearly interpolates this color's RGB values toward the RGB values of the 10305 * given color. The alpha argument can be thought of as the ratio between 10306 * the two colors, where `0.0` is this color and `1.0` is the first argument. 10307 * 10308 * @param {Color} color - The color to converge on. 10309 * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`. 10310 * @return {Color} A reference to this color. 10311 */ 10312 lerp(color, alpha) { 10313 this.r += (color.r - this.r) * alpha; 10314 this.g += (color.g - this.g) * alpha; 10315 this.b += (color.b - this.b) * alpha; 10316 return this; 10317 } 10318 /** 10319 * Linearly interpolates between the given colors and stores the result in this instance. 10320 * The alpha argument can be thought of as the ratio between the two colors, where `0.0` 10321 * is the first and `1.0` is the second color. 10322 * 10323 * @param {Color} color1 - The first color. 10324 * @param {Color} color2 - The second color. 10325 * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`. 10326 * @return {Color} A reference to this color. 10327 */ 10328 lerpColors(color1, color2, alpha) { 10329 this.r = color1.r + (color2.r - color1.r) * alpha; 10330 this.g = color1.g + (color2.g - color1.g) * alpha; 10331 this.b = color1.b + (color2.b - color1.b) * alpha; 10332 return this; 10333 } 10334 /** 10335 * Linearly interpolates this color's HSL values toward the HSL values of the 10336 * given color. It differs from {@link Color#lerp} by not interpolating straight 10337 * from one color to the other, but instead going through all the hues in between 10338 * those two colors. The alpha argument can be thought of as the ratio between 10339 * the two colors, where 0.0 is this color and 1.0 is the first argument. 10340 * 10341 * @param {Color} color - The color to converge on. 10342 * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`. 10343 * @return {Color} A reference to this color. 10344 */ 10345 lerpHSL(color, alpha) { 10346 this.getHSL(_hslA); 10347 color.getHSL(_hslB); 10348 const h = lerp(_hslA.h, _hslB.h, alpha); 10349 const s = lerp(_hslA.s, _hslB.s, alpha); 10350 const l = lerp(_hslA.l, _hslB.l, alpha); 10351 this.setHSL(h, s, l); 10352 return this; 10353 } 10354 /** 10355 * Sets the color's RGB components from the given 3D vector. 10356 * 10357 * @param {Vector3} v - The vector to set. 10358 * @return {Color} A reference to this color. 10359 */ 10360 setFromVector3(v) { 10361 this.r = v.x; 10362 this.g = v.y; 10363 this.b = v.z; 10364 return this; 10365 } 10366 /** 10367 * Transforms this color with the given 3x3 matrix. 10368 * 10369 * @param {Matrix3} m - The matrix. 10370 * @return {Color} A reference to this color. 10371 */ 10372 applyMatrix3(m) { 10373 const r = this.r, g = this.g, b = this.b; 10374 const e = m.elements; 10375 this.r = e[0] * r + e[3] * g + e[6] * b; 10376 this.g = e[1] * r + e[4] * g + e[7] * b; 10377 this.b = e[2] * r + e[5] * g + e[8] * b; 10378 return this; 10379 } 10380 /** 10381 * Returns `true` if this color is equal with the given one. 10382 * 10383 * @param {Color} c - The color to test for equality. 10384 * @return {boolean} Whether this bounding color is equal with the given one. 10385 */ 10386 equals(c) { 10387 return c.r === this.r && c.g === this.g && c.b === this.b; 10388 } 10389 /** 10390 * Sets this color's RGB components from the given array. 10391 * 10392 * @param {Array<number>} array - An array holding the RGB values. 10393 * @param {number} [offset=0] - The offset into the array. 10394 * @return {Color} A reference to this color. 10395 */ 10396 fromArray(array, offset = 0) { 10397 this.r = array[offset]; 10398 this.g = array[offset + 1]; 10399 this.b = array[offset + 2]; 10400 return this; 10401 } 10402 /** 10403 * Writes the RGB components of this color to the given array. If no array is provided, 10404 * the method returns a new instance. 10405 * 10406 * @param {Array<number>} [array=[]] - The target array holding the color components. 10407 * @param {number} [offset=0] - Index of the first element in the array. 10408 * @return {Array<number>} The color components. 10409 */ 10410 toArray(array = [], offset = 0) { 10411 array[offset] = this.r; 10412 array[offset + 1] = this.g; 10413 array[offset + 2] = this.b; 10414 return array; 10415 } 10416 /** 10417 * Sets the components of this color from the given buffer attribute. 10418 * 10419 * @param {BufferAttribute} attribute - The buffer attribute holding color data. 10420 * @param {number} index - The index into the attribute. 10421 * @return {Color} A reference to this color. 10422 */ 10423 fromBufferAttribute(attribute, index) { 10424 this.r = attribute.getX(index); 10425 this.g = attribute.getY(index); 10426 this.b = attribute.getZ(index); 10427 return this; 10428 } 10429 /** 10430 * This methods defines the serialization result of this class. Returns the color 10431 * as a hexadecimal value. 10432 * 10433 * @return {number} The hexadecimal value. 10434 */ 10435 toJSON() { 10436 return this.getHex(); 10437 } 10438 *[Symbol.iterator]() { 10439 yield this.r; 10440 yield this.g; 10441 yield this.b; 10442 } 10443}; 10444var _color = /* @__PURE__ */ new Color(); 10445Color.NAMES = _colorKeywords; 10446var Scene = class extends Object3D { 10447 /** 10448 * Constructs a new scene. 10449 */ 10450 constructor() { 10451 super(); 10452 this.isScene = true; 10453 this.type = "Scene"; 10454 this.background = null; 10455 this.environment = null; 10456 this.fog = null; 10457 this.backgroundBlurriness = 0; 10458 this.backgroundIntensity = 1; 10459 this.backgroundRotation = new Euler(); 10460 this.environmentIntensity = 1; 10461 this.environmentRotation = new Euler(); 10462 this.overrideMaterial = null; 10463 if (typeof __THREE_DEVTOOLS__ !== "undefined") { 10464 __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe", { detail: this })); 10465 } 10466 } 10467 copy(source, recursive) { 10468 super.copy(source, recursive); 10469 if (source.background !== null) this.background = source.background.clone(); 10470 if (source.environment !== null) this.environment = source.environment.clone(); 10471 if (source.fog !== null) this.fog = source.fog.clone(); 10472 this.backgroundBlurriness = source.backgroundBlurriness; 10473 this.backgroundIntensity = source.backgroundIntensity; 10474 this.backgroundRotation.copy(source.backgroundRotation); 10475 this.environmentIntensity = source.environmentIntensity; 10476 this.environmentRotation.copy(source.environmentRotation); 10477 if (source.overrideMaterial !== null) this.overrideMaterial = source.overrideMaterial.clone(); 10478 this.matrixAutoUpdate = source.matrixAutoUpdate; 10479 return this; 10480 } 10481 toJSON(meta) { 10482 const data = super.toJSON(meta); 10483 if (this.fog !== null) data.object.fog = this.fog.toJSON(); 10484 if (this.backgroundBlurriness > 0) data.object.backgroundBlurriness = this.backgroundBlurriness; 10485 if (this.backgroundIntensity !== 1) data.object.backgroundIntensity = this.backgroundIntensity; 10486 data.object.backgroundRotation = this.backgroundRotation.toArray(); 10487 if (this.environmentIntensity !== 1) data.object.environmentIntensity = this.environmentIntensity; 10488 data.object.environmentRotation = this.environmentRotation.toArray(); 10489 return data; 10490 } 10491}; 10492var _v0$2 = /* @__PURE__ */ new Vector3(); 10493var _v1$5 = /* @__PURE__ */ new Vector3(); 10494var _v2$4 = /* @__PURE__ */ new Vector3(); 10495var _v3$2 = /* @__PURE__ */ new Vector3(); 10496var _vab = /* @__PURE__ */ new Vector3(); 10497var _vac = /* @__PURE__ */ new Vector3(); 10498var _vbc = /* @__PURE__ */ new Vector3(); 10499var _vap = /* @__PURE__ */ new Vector3(); 10500var _vbp = /* @__PURE__ */ new Vector3(); 10501var _vcp = /* @__PURE__ */ new Vector3(); 10502var _v40 = /* @__PURE__ */ new Vector4(); 10503var _v41 = /* @__PURE__ */ new Vector4(); 10504var _v42 = /* @__PURE__ */ new Vector4(); 10505var Triangle = class _Triangle { 10506 /** 10507 * Constructs a new triangle. 10508 * 10509 * @param {Vector3} [a=(0,0,0)] - The first corner of the triangle. 10510 * @param {Vector3} [b=(0,0,0)] - The second corner of the triangle. 10511 * @param {Vector3} [c=(0,0,0)] - The third corner of the triangle. 10512 */ 10513 constructor(a = new Vector3(), b = new Vector3(), c = new Vector3()) { 10514 this.a = a; 10515 this.b = b; 10516 this.c = c; 10517 } 10518 /** 10519 * Computes the normal vector of a triangle. 10520 * 10521 * @param {Vector3} a - The first corner of the triangle. 10522 * @param {Vector3} b - The second corner of the triangle. 10523 * @param {Vector3} c - The third corner of the triangle. 10524 * @param {Vector3} target - The target vector that is used to store the method's result. 10525 * @return {Vector3} The triangle's normal. 10526 */ 10527 static getNormal(a, b, c, target) { 10528 target.subVectors(c, b); 10529 _v0$2.subVectors(a, b); 10530 target.cross(_v0$2); 10531 const targetLengthSq = target.lengthSq(); 10532 if (targetLengthSq > 0) { 10533 return target.multiplyScalar(1 / Math.sqrt(targetLengthSq)); 10534 } 10535 return target.set(0, 0, 0); 10536 } 10537 /** 10538 * Computes a barycentric coordinates from the given vector. 10539 * Returns `null` if the triangle is degenerate. 10540 * 10541 * @param {Vector3} point - A point in 3D space. 10542 * @param {Vector3} a - The first corner of the triangle. 10543 * @param {Vector3} b - The second corner of the triangle. 10544 * @param {Vector3} c - The third corner of the triangle. 10545 * @param {Vector3} target - The target vector that is used to store the method's result. 10546 * @return {?Vector3} The barycentric coordinates for the given point 10547 */ 10548 static getBarycoord(point, a, b, c, target) { 10549 _v0$2.subVectors(c, a); 10550 _v1$5.subVectors(b, a); 10551 _v2$4.subVectors(point, a); 10552 const dot00 = _v0$2.dot(_v0$2); 10553 const dot01 = _v0$2.dot(_v1$5); 10554 const dot02 = _v0$2.dot(_v2$4); 10555 const dot11 = _v1$5.dot(_v1$5); 10556 const dot12 = _v1$5.dot(_v2$4); 10557 const denom = dot00 * dot11 - dot01 * dot01; 10558 if (denom === 0) { 10559 target.set(0, 0, 0); 10560 return null; 10561 } 10562 const invDenom = 1 / denom; 10563 const u = (dot11 * dot02 - dot01 * dot12) * invDenom; 10564 const v = (dot00 * dot12 - dot01 * dot02) * invDenom; 10565 return target.set(1 - u - v, v, u); 10566 } 10567 /** 10568 * Returns `true` if the given point, when projected onto the plane of the 10569 * triangle, lies within the triangle. 10570 * 10571 * @param {Vector3} point - The point in 3D space to test. 10572 * @param {Vector3} a - The first corner of the triangle. 10573 * @param {Vector3} b - The second corner of the triangle. 10574 * @param {Vector3} c - The third corner of the triangle. 10575 * @return {boolean} Whether the given point, when projected onto the plane of the 10576 * triangle, lies within the triangle or not. 10577 */ 10578 static containsPoint(point, a, b, c) { 10579 if (this.getBarycoord(point, a, b, c, _v3$2) === null) { 10580 return false; 10581 } 10582 return _v3$2.x >= 0 && _v3$2.y >= 0 && _v3$2.x + _v3$2.y <= 1; 10583 } 10584 /** 10585 * Computes the value barycentrically interpolated for the given point on the 10586 * triangle. Returns `null` if the triangle is degenerate. 10587 * 10588 * @param {Vector3} point - Position of interpolated point. 10589 * @param {Vector3} p1 - The first corner of the triangle. 10590 * @param {Vector3} p2 - The second corner of the triangle. 10591 * @param {Vector3} p3 - The third corner of the triangle. 10592 * @param {Vector3} v1 - Value to interpolate of first vertex. 10593 * @param {Vector3} v2 - Value to interpolate of second vertex. 10594 * @param {Vector3} v3 - Value to interpolate of third vertex. 10595 * @param {Vector3} target - The target vector that is used to store the method's result. 10596 * @return {?Vector3} The interpolated value. 10597 */ 10598 static getInterpolation(point, p1, p2, p3, v1, v2, v3, target) { 10599 if (this.getBarycoord(point, p1, p2, p3, _v3$2) === null) { 10600 target.x = 0; 10601 target.y = 0; 10602 if ("z" in target) target.z = 0; 10603 if ("w" in target) target.w = 0; 10604 return null; 10605 } 10606 target.setScalar(0); 10607 target.addScaledVector(v1, _v3$2.x); 10608 target.addScaledVector(v2, _v3$2.y); 10609 target.addScaledVector(v3, _v3$2.z); 10610 return target; 10611 } 10612 /** 10613 * Computes the value barycentrically interpolated for the given attribute and indices. 10614 * 10615 * @param {BufferAttribute} attr - The attribute to interpolate. 10616 * @param {number} i1 - Index of first vertex. 10617 * @param {number} i2 - Index of second vertex. 10618 * @param {number} i3 - Index of third vertex. 10619 * @param {Vector3} barycoord - The barycoordinate value to use to interpolate. 10620 * @param {Vector3} target - The target vector that is used to store the method's result. 10621 * @return {Vector3} The interpolated attribute value. 10622 */ 10623 static getInterpolatedAttribute(attr, i1, i2, i3, barycoord, target) { 10624 _v40.setScalar(0); 10625 _v41.setScalar(0); 10626 _v42.setScalar(0); 10627 _v40.fromBufferAttribute(attr, i1); 10628 _v41.fromBufferAttribute(attr, i2); 10629 _v42.fromBufferAttribute(attr, i3); 10630 target.setScalar(0); 10631 target.addScaledVector(_v40, barycoord.x); 10632 target.addScaledVector(_v41, barycoord.y); 10633 target.addScaledVector(_v42, barycoord.z); 10634 return target; 10635 } 10636 /** 10637 * Returns `true` if the triangle is oriented towards the given direction. 10638 * 10639 * @param {Vector3} a - The first corner of the triangle. 10640 * @param {Vector3} b - The second corner of the triangle. 10641 * @param {Vector3} c - The third corner of the triangle. 10642 * @param {Vector3} direction - The (normalized) direction vector. 10643 * @return {boolean} Whether the triangle is oriented towards the given direction or not. 10644 */ 10645 static isFrontFacing(a, b, c, direction) { 10646 _v0$2.subVectors(c, b); 10647 _v1$5.subVectors(a, b); 10648 return _v0$2.cross(_v1$5).dot(direction) < 0; 10649 } 10650 /** 10651 * Sets the triangle's vertices by copying the given values. 10652 * 10653 * @param {Vector3} a - The first corner of the triangle. 10654 * @param {Vector3} b - The second corner of the triangle. 10655 * @param {Vector3} c - The third corner of the triangle. 10656 * @return {Triangle} A reference to this triangle. 10657 */ 10658 set(a, b, c) { 10659 this.a.copy(a); 10660 this.b.copy(b); 10661 this.c.copy(c); 10662 return this; 10663 } 10664 /** 10665 * Sets the triangle's vertices by copying the given array values. 10666 * 10667 * @param {Array<Vector3>} points - An array with 3D points. 10668 * @param {number} i0 - The array index representing the first corner of the triangle. 10669 * @param {number} i1 - The array index representing the second corner of the triangle. 10670 * @param {number} i2 - The array index representing the third corner of the triangle. 10671 * @return {Triangle} A reference to this triangle. 10672 */ 10673 setFromPointsAndIndices(points, i0, i1, i2) { 10674 this.a.copy(points[i0]); 10675 this.b.copy(points[i1]); 10676 this.c.copy(points[i2]); 10677 return this; 10678 } 10679 /** 10680 * Sets the triangle's vertices by copying the given attribute values. 10681 * 10682 * @param {BufferAttribute} attribute - A buffer attribute with 3D points data. 10683 * @param {number} i0 - The attribute index representing the first corner of the triangle. 10684 * @param {number} i1 - The attribute index representing the second corner of the triangle. 10685 * @param {number} i2 - The attribute index representing the third corner of the triangle. 10686 * @return {Triangle} A reference to this triangle. 10687 */ 10688 setFromAttributeAndIndices(attribute, i0, i1, i2) { 10689 this.a.fromBufferAttribute(attribute, i0); 10690 this.b.fromBufferAttribute(attribute, i1); 10691 this.c.fromBufferAttribute(attribute, i2); 10692 return this; 10693 } 10694 /** 10695 * Returns a new triangle with copied values from this instance. 10696 * 10697 * @return {Triangle} A clone of this instance. 10698 */ 10699 clone() { 10700 return new this.constructor().copy(this); 10701 } 10702 /** 10703 * Copies the values of the given triangle to this instance. 10704 * 10705 * @param {Triangle} triangle - The triangle to copy. 10706 * @return {Triangle} A reference to this triangle. 10707 */ 10708 copy(triangle) { 10709 this.a.copy(triangle.a); 10710 this.b.copy(triangle.b); 10711 this.c.copy(triangle.c); 10712 return this; 10713 } 10714 /** 10715 * Computes the area of the triangle. 10716 * 10717 * @return {number} The triangle's area. 10718 */ 10719 getArea() { 10720 _v0$2.subVectors(this.c, this.b); 10721 _v1$5.subVectors(this.a, this.b); 10722 return _v0$2.cross(_v1$5).length() * 0.5; 10723 } 10724 /** 10725 * Computes the midpoint of the triangle. 10726 * 10727 * @param {Vector3} target - The target vector that is used to store the method's result. 10728 * @return {Vector3} The triangle's midpoint. 10729 */ 10730 getMidpoint(target) { 10731 return target.addVectors(this.a, this.b).add(this.c).multiplyScalar(1 / 3); 10732 } 10733 /** 10734 * Computes the normal of the triangle. 10735 * 10736 * @param {Vector3} target - The target vector that is used to store the method's result. 10737 * @return {Vector3} The triangle's normal. 10738 */ 10739 getNormal(target) { 10740 return _Triangle.getNormal(this.a, this.b, this.c, target); 10741 } 10742 /** 10743 * Computes a plane the triangle lies within. 10744 * 10745 * @param {Plane} target - The target vector that is used to store the method's result. 10746 * @return {Plane} The plane the triangle lies within. 10747 */ 10748 getPlane(target) { 10749 return target.setFromCoplanarPoints(this.a, this.b, this.c); 10750 } 10751 /** 10752 * Computes a barycentric coordinates from the given vector. 10753 * Returns `null` if the triangle is degenerate. 10754 * 10755 * @param {Vector3} point - A point in 3D space. 10756 * @param {Vector3} target - The target vector that is used to store the method's result. 10757 * @return {?Vector3} The barycentric coordinates for the given point 10758 */ 10759 getBarycoord(point, target) { 10760 return _Triangle.getBarycoord(point, this.a, this.b, this.c, target); 10761 } 10762 /** 10763 * Computes the value barycentrically interpolated for the given point on the 10764 * triangle. Returns `null` if the triangle is degenerate. 10765 * 10766 * @param {Vector3} point - Position of interpolated point. 10767 * @param {Vector3} v1 - Value to interpolate of first vertex. 10768 * @param {Vector3} v2 - Value to interpolate of second vertex. 10769 * @param {Vector3} v3 - Value to interpolate of third vertex. 10770 * @param {Vector3} target - The target vector that is used to store the method's result. 10771 * @return {?Vector3} The interpolated value. 10772 */ 10773 getInterpolation(point, v1, v2, v3, target) { 10774 return _Triangle.getInterpolation(point, this.a, this.b, this.c, v1, v2, v3, target); 10775 } 10776 /** 10777 * Returns `true` if the given point, when projected onto the plane of the 10778 * triangle, lies within the triangle. 10779 * 10780 * @param {Vector3} point - The point in 3D space to test. 10781 * @return {boolean} Whether the given point, when projected onto the plane of the 10782 * triangle, lies within the triangle or not. 10783 */ 10784 containsPoint(point) { 10785 return _Triangle.containsPoint(point, this.a, this.b, this.c); 10786 } 10787 /** 10788 * Returns `true` if the triangle is oriented towards the given direction. 10789 * 10790 * @param {Vector3} direction - The (normalized) direction vector. 10791 * @return {boolean} Whether the triangle is oriented towards the given direction or not. 10792 */ 10793 isFrontFacing(direction) { 10794 return _Triangle.isFrontFacing(this.a, this.b, this.c, direction); 10795 } 10796 /** 10797 * Returns `true` if this triangle intersects with the given box. 10798 * 10799 * @param {Box3} box - The box to intersect. 10800 * @return {boolean} Whether this triangle intersects with the given box or not. 10801 */ 10802 intersectsBox(box) { 10803 return box.intersectsTriangle(this); 10804 } 10805 /** 10806 * Returns the closest point on the triangle to the given point. 10807 * 10808 * @param {Vector3} p - The point to compute the closest point for. 10809 * @param {Vector3} target - The target vector that is used to store the method's result. 10810 * @return {Vector3} The closest point on the triangle. 10811 */ 10812 closestPointToPoint(p, target) { 10813 const a = this.a, b = this.b, c = this.c; 10814 let v, w; 10815 _vab.subVectors(b, a); 10816 _vac.subVectors(c, a); 10817 _vap.subVectors(p, a); 10818 const d1 = _vab.dot(_vap); 10819 const d2 = _vac.dot(_vap); 10820 if (d1 <= 0 && d2 <= 0) { 10821 return target.copy(a); 10822 } 10823 _vbp.subVectors(p, b); 10824 const d3 = _vab.dot(_vbp); 10825 const d4 = _vac.dot(_vbp); 10826 if (d3 >= 0 && d4 <= d3) { 10827 return target.copy(b); 10828 } 10829 const vc = d1 * d4 - d3 * d2; 10830 if (vc <= 0 && d1 >= 0 && d3 <= 0) { 10831 v = d1 / (d1 - d3); 10832 return target.copy(a).addScaledVector(_vab, v); 10833 } 10834 _vcp.subVectors(p, c); 10835 const d5 = _vab.dot(_vcp); 10836 const d6 = _vac.dot(_vcp); 10837 if (d6 >= 0 && d5 <= d6) { 10838 return target.copy(c); 10839 } 10840 const vb = d5 * d2 - d1 * d6; 10841 if (vb <= 0 && d2 >= 0 && d6 <= 0) { 10842 w = d2 / (d2 - d6); 10843 return target.copy(a).addScaledVector(_vac, w); 10844 } 10845 const va = d3 * d6 - d5 * d4; 10846 if (va <= 0 && d4 - d3 >= 0 && d5 - d6 >= 0) { 10847 _vbc.subVectors(c, b); 10848 w = (d4 - d3) / (d4 - d3 + (d5 - d6)); 10849 return target.copy(b).addScaledVector(_vbc, w); 10850 } 10851 const denom = 1 / (va + vb + vc); 10852 v = vb * denom; 10853 w = vc * denom; 10854 return target.copy(a).addScaledVector(_vab, v).addScaledVector(_vac, w); 10855 } 10856 /** 10857 * Returns `true` if this triangle is equal with the given one. 10858 * 10859 * @param {Triangle} triangle - The triangle to test for equality. 10860 * @return {boolean} Whether this triangle is equal with the given one. 10861 */ 10862 equals(triangle) { 10863 return triangle.a.equals(this.a) && triangle.b.equals(this.b) && triangle.c.equals(this.c); 10864 } 10865}; 10866var Box3 = class { 10867 /** 10868 * Constructs a new bounding box. 10869 * 10870 * @param {Vector3} [min=(Infinity,Infinity,Infinity)] - A vector representing the lower boundary of the box. 10871 * @param {Vector3} [max=(-Infinity,-Infinity,-Infinity)] - A vector representing the upper boundary of the box. 10872 */ 10873 constructor(min = new Vector3(Infinity, Infinity, Infinity), max = new Vector3(-Infinity, -Infinity, -Infinity)) { 10874 this.isBox3 = true; 10875 this.min = min; 10876 this.max = max; 10877 } 10878 /** 10879 * Sets the lower and upper boundaries of this box. 10880 * Please note that this method only copies the values from the given objects. 10881 * 10882 * @param {Vector3} min - The lower boundary of the box. 10883 * @param {Vector3} max - The upper boundary of the box. 10884 * @return {Box3} A reference to this bounding box. 10885 */ 10886 set(min, max) { 10887 this.min.copy(min); 10888 this.max.copy(max); 10889 return this; 10890 } 10891 /** 10892 * Sets the upper and lower bounds of this box so it encloses the position data 10893 * in the given array. 10894 * 10895 * @param {Array<number>} array - An array holding 3D position data. 10896 * @return {Box3} A reference to this bounding box. 10897 */ 10898 setFromArray(array) { 10899 this.makeEmpty(); 10900 for (let i = 0, il = array.length; i < il; i += 3) { 10901 this.expandByPoint(_vector$b.fromArray(array, i)); 10902 } 10903 return this; 10904 } 10905 /** 10906 * Sets the upper and lower bounds of this box so it encloses the position data 10907 * in the given buffer attribute. 10908 * 10909 * @param {BufferAttribute} attribute - A buffer attribute holding 3D position data. 10910 * @return {Box3} A reference to this bounding box. 10911 */ 10912 setFromBufferAttribute(attribute) { 10913 this.makeEmpty(); 10914 for (let i = 0, il = attribute.count; i < il; i++) { 10915 this.expandByPoint(_vector$b.fromBufferAttribute(attribute, i)); 10916 } 10917 return this; 10918 } 10919 /** 10920 * Sets the upper and lower bounds of this box so it encloses the position data 10921 * in the given array. 10922 * 10923 * @param {Array<Vector3>} points - An array holding 3D position data as instances of {@link Vector3}. 10924 * @return {Box3} A reference to this bounding box. 10925 */ 10926 setFromPoints(points) { 10927 this.makeEmpty(); 10928 for (let i = 0, il = points.length; i < il; i++) { 10929 this.expandByPoint(points[i]); 10930 } 10931 return this; 10932 } 10933 /** 10934 * Centers this box on the given center vector and sets this box's width, height and 10935 * depth to the given size values. 10936 * 10937 * @param {Vector3} center - The center of the box. 10938 * @param {Vector3} size - The x, y and z dimensions of the box. 10939 * @return {Box3} A reference to this bounding box. 10940 */ 10941 setFromCenterAndSize(center, size) { 10942 const halfSize = _vector$b.copy(size).multiplyScalar(0.5); 10943 this.min.copy(center).sub(halfSize); 10944 this.max.copy(center).add(halfSize); 10945 return this; 10946 } 10947 /** 10948 * Computes the world-axis-aligned bounding box for the given 3D object 10949 * (including its children), accounting for the object's, and children's, 10950 * world transforms. The function may result in a larger box than strictly necessary. 10951 * 10952 * @param {Object3D} object - The 3D object to compute the bounding box for. 10953 * @param {boolean} [precise=false] - If set to `true`, the method computes the smallest 10954 * world-axis-aligned bounding box at the expense of more computation. 10955 * @return {Box3} A reference to this bounding box. 10956 */ 10957 setFromObject(object, precise = false) { 10958 this.makeEmpty(); 10959 return this.expandByObject(object, precise); 10960 } 10961 /** 10962 * Returns a new box with copied values from this instance. 10963 * 10964 * @return {Box3} A clone of this instance. 10965 */ 10966 clone() { 10967 return new this.constructor().copy(this); 10968 } 10969 /** 10970 * Copies the values of the given box to this instance. 10971 * 10972 * @param {Box3} box - The box to copy. 10973 * @return {Box3} A reference to this bounding box. 10974 */ 10975 copy(box) { 10976 this.min.copy(box.min); 10977 this.max.copy(box.max); 10978 return this; 10979 } 10980 /** 10981 * Makes this box empty which means in encloses a zero space in 3D. 10982 * 10983 * @return {Box3} A reference to this bounding box. 10984 */ 10985 makeEmpty() { 10986 this.min.x = this.min.y = this.min.z = Infinity; 10987 this.max.x = this.max.y = this.max.z = -Infinity; 10988 return this; 10989 } 10990 /** 10991 * Returns true if this box includes zero points within its bounds. 10992 * Note that a box with equal lower and upper bounds still includes one 10993 * point, the one both bounds share. 10994 * 10995 * @return {boolean} Whether this box is empty or not. 10996 */ 10997 isEmpty() { 10998 return this.max.x < this.min.x || this.max.y < this.min.y || this.max.z < this.min.z; 10999 } 11000 /** 11001 * Returns the center point of this box. 11002 * 11003 * @param {Vector3} target - The target vector that is used to store the method's result. 11004 * @return {Vector3} The center point. 11005 */ 11006 getCenter(target) { 11007 return this.isEmpty() ? target.set(0, 0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5); 11008 } 11009 /** 11010 * Returns the dimensions of this box. 11011 * 11012 * @param {Vector3} target - The target vector that is used to store the method's result. 11013 * @return {Vector3} The size. 11014 */ 11015 getSize(target) { 11016 return this.isEmpty() ? target.set(0, 0, 0) : target.subVectors(this.max, this.min); 11017 } 11018 /** 11019 * Expands the boundaries of this box to include the given point. 11020 * 11021 * @param {Vector3} point - The point that should be included by the bounding box. 11022 * @return {Box3} A reference to this bounding box. 11023 */ 11024 expandByPoint(point) { 11025 this.min.min(point); 11026 this.max.max(point); 11027 return this; 11028 } 11029 /** 11030 * Expands this box equilaterally by the given vector. The width of this 11031 * box will be expanded by the x component of the vector in both 11032 * directions. The height of this box will be expanded by the y component of 11033 * the vector in both directions. The depth of this box will be 11034 * expanded by the z component of the vector in both directions. 11035 * 11036 * @param {Vector3} vector - The vector that should expand the bounding box. 11037 * @return {Box3} A reference to this bounding box. 11038 */ 11039 expandByVector(vector) { 11040 this.min.sub(vector); 11041 this.max.add(vector); 11042 return this; 11043 } 11044 /** 11045 * Expands each dimension of the box by the given scalar. If negative, the 11046 * dimensions of the box will be contracted. 11047 * 11048 * @param {number} scalar - The scalar value that should expand the bounding box. 11049 * @return {Box3} A reference to this bounding box. 11050 */ 11051 expandByScalar(scalar) { 11052 this.min.addScalar(-scalar); 11053 this.max.addScalar(scalar); 11054 return this; 11055 } 11056 /** 11057 * Expands the boundaries of this box to include the given 3D object and 11058 * its children, accounting for the object's, and children's, world 11059 * transforms. The function may result in a larger box than strictly 11060 * necessary (unless the precise parameter is set to true). 11061 * 11062 * @param {Object3D} object - The 3D object that should expand the bounding box. 11063 * @param {boolean} precise - If set to `true`, the method expands the bounding box 11064 * as little as necessary at the expense of more computation. 11065 * @return {Box3} A reference to this bounding box. 11066 */ 11067 expandByObject(object, precise = false) { 11068 object.updateWorldMatrix(false, false); 11069 const geometry = object.geometry; 11070 if (geometry !== void 0) { 11071 const positionAttribute = geometry.getAttribute("position"); 11072 if (precise === true && positionAttribute !== void 0 && object.isInstancedMesh !== true) { 11073 for (let i = 0, l = positionAttribute.count; i < l; i++) { 11074 if (object.isMesh === true) { 11075 object.getVertexPosition(i, _vector$b); 11076 } else { 11077 _vector$b.fromBufferAttribute(positionAttribute, i); 11078 } 11079 _vector$b.applyMatrix4(object.matrixWorld); 11080 this.expandByPoint(_vector$b); 11081 } 11082 } else { 11083 if (object.boundingBox !== void 0) { 11084 if (object.boundingBox === null) { 11085 object.computeBoundingBox(); 11086 } 11087 _box$4.copy(object.boundingBox); 11088 } else { 11089 if (geometry.boundingBox === null) { 11090 geometry.computeBoundingBox(); 11091 } 11092 _box$4.copy(geometry.boundingBox); 11093 } 11094 _box$4.applyMatrix4(object.matrixWorld); 11095 this.union(_box$4); 11096 } 11097 } 11098 const children2 = object.children; 11099 for (let i = 0, l = children2.length; i < l; i++) { 11100 this.expandByObject(children2[i], precise); 11101 } 11102 return this; 11103 } 11104 /** 11105 * Returns `true` if the given point lies within or on the boundaries of this box. 11106 * 11107 * @param {Vector3} point - The point to test. 11108 * @return {boolean} Whether the bounding box contains the given point or not. 11109 */ 11110 containsPoint(point) { 11111 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; 11112 } 11113 /** 11114 * Returns `true` if this bounding box includes the entirety of the given bounding box. 11115 * If this box and the given one are identical, this function also returns `true`. 11116 * 11117 * @param {Box3} box - The bounding box to test. 11118 * @return {boolean} Whether the bounding box contains the given bounding box or not. 11119 */ 11120 containsBox(box) { 11121 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; 11122 } 11123 /** 11124 * Returns a point as a proportion of this box's width, height and depth. 11125 * 11126 * @param {Vector3} point - A point in 3D space. 11127 * @param {Vector3} target - The target vector that is used to store the method's result. 11128 * @return {Vector3} A point as a proportion of this box's width, height and depth. 11129 */ 11130 getParameter(point, target) { 11131 return target.set( 11132 (point.x - this.min.x) / (this.max.x - this.min.x), 11133 (point.y - this.min.y) / (this.max.y - this.min.y), 11134 (point.z - this.min.z) / (this.max.z - this.min.z) 11135 ); 11136 } 11137 /** 11138 * Returns `true` if the given bounding box intersects with this bounding box. 11139 * 11140 * @param {Box3} box - The bounding box to test. 11141 * @return {boolean} Whether the given bounding box intersects with this bounding box. 11142 */ 11143 intersectsBox(box) { 11144 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; 11145 } 11146 /** 11147 * Returns `true` if the given bounding sphere intersects with this bounding box. 11148 * 11149 * @param {Sphere} sphere - The bounding sphere to test. 11150 * @return {boolean} Whether the given bounding sphere intersects with this bounding box. 11151 */ 11152 intersectsSphere(sphere) { 11153 this.clampPoint(sphere.center, _vector$b); 11154 return _vector$b.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius; 11155 } 11156 /** 11157 * Returns `true` if the given plane intersects with this bounding box. 11158 * 11159 * @param {Plane} plane - The plane to test. 11160 * @return {boolean} Whether the given plane intersects with this bounding box. 11161 */ 11162 intersectsPlane(plane) { 11163 let min, max; 11164 if (plane.normal.x > 0) { 11165 min = plane.normal.x * this.min.x; 11166 max = plane.normal.x * this.max.x; 11167 } else { 11168 min = plane.normal.x * this.max.x; 11169 max = plane.normal.x * this.min.x; 11170 } 11171 if (plane.normal.y > 0) { 11172 min += plane.normal.y * this.min.y; 11173 max += plane.normal.y * this.max.y; 11174 } else { 11175 min += plane.normal.y * this.max.y; 11176 max += plane.normal.y * this.min.y; 11177 } 11178 if (plane.normal.z > 0) { 11179 min += plane.normal.z * this.min.z; 11180 max += plane.normal.z * this.max.z; 11181 } else { 11182 min += plane.normal.z * this.max.z; 11183 max += plane.normal.z * this.min.z; 11184 } 11185 return min <= -plane.constant && max >= -plane.constant; 11186 } 11187 /** 11188 * Returns `true` if the given triangle intersects with this bounding box. 11189 * 11190 * @param {Triangle} triangle - The triangle to test. 11191 * @return {boolean} Whether the given triangle intersects with this bounding box. 11192 */ 11193 intersectsTriangle(triangle) { 11194 if (this.isEmpty()) { 11195 return false; 11196 } 11197 this.getCenter(_center); 11198 _extents.subVectors(this.max, _center); 11199 _v0$1.subVectors(triangle.a, _center); 11200 _v1$4.subVectors(triangle.b, _center); 11201 _v2$3.subVectors(triangle.c, _center); 11202 _f0.subVectors(_v1$4, _v0$1); 11203 _f1.subVectors(_v2$3, _v1$4); 11204 _f2.subVectors(_v0$1, _v2$3); 11205 let axes = [ 11206 0, 11207 -_f0.z, 11208 _f0.y, 11209 0, 11210 -_f1.z, 11211 _f1.y, 11212 0, 11213 -_f2.z, 11214 _f2.y, 11215 _f0.z, 11216 0, 11217 -_f0.x, 11218 _f1.z, 11219 0, 11220 -_f1.x, 11221 _f2.z, 11222 0, 11223 -_f2.x, 11224 -_f0.y, 11225 _f0.x, 11226 0, 11227 -_f1.y, 11228 _f1.x, 11229 0, 11230 -_f2.y, 11231 _f2.x, 11232 0 11233 ]; 11234 if (!satForAxes(axes, _v0$1, _v1$4, _v2$3, _extents)) { 11235 return false; 11236 } 11237 axes = [1, 0, 0, 0, 1, 0, 0, 0, 1]; 11238 if (!satForAxes(axes, _v0$1, _v1$4, _v2$3, _extents)) { 11239 return false; 11240 } 11241 _triangleNormal.crossVectors(_f0, _f1); 11242 axes = [_triangleNormal.x, _triangleNormal.y, _triangleNormal.z]; 11243 return satForAxes(axes, _v0$1, _v1$4, _v2$3, _extents); 11244 } 11245 /** 11246 * Clamps the given point within the bounds of this box. 11247 * 11248 * @param {Vector3} point - The point to clamp. 11249 * @param {Vector3} target - The target vector that is used to store the method's result. 11250 * @return {Vector3} The clamped point. 11251 */ 11252 clampPoint(point, target) { 11253 return target.copy(point).clamp(this.min, this.max); 11254 } 11255 /** 11256 * Returns the euclidean distance from any edge of this box to the specified point. If 11257 * the given point lies inside of this box, the distance will be `0`. 11258 * 11259 * @param {Vector3} point - The point to compute the distance to. 11260 * @return {number} The euclidean distance. 11261 */ 11262 distanceToPoint(point) { 11263 return this.clampPoint(point, _vector$b).distanceTo(point); 11264 } 11265 /** 11266 * Returns a bounding sphere that encloses this bounding box. 11267 * 11268 * @param {Sphere} target - The target sphere that is used to store the method's result. 11269 * @return {Sphere} The bounding sphere that encloses this bounding box. 11270 */ 11271 getBoundingSphere(target) { 11272 if (this.isEmpty()) { 11273 target.makeEmpty(); 11274 } else { 11275 this.getCenter(target.center); 11276 target.radius = this.getSize(_vector$b).length() * 0.5; 11277 } 11278 return target; 11279 } 11280 /** 11281 * Computes the intersection of this bounding box and the given one, setting the upper 11282 * bound of this box to the lesser of the two boxes' upper bounds and the 11283 * lower bound of this box to the greater of the two boxes' lower bounds. If 11284 * there's no overlap, makes this box empty. 11285 * 11286 * @param {Box3} box - The bounding box to intersect with. 11287 * @return {Box3} A reference to this bounding box. 11288 */ 11289 intersect(box) { 11290 this.min.max(box.min); 11291 this.max.min(box.max); 11292 if (this.isEmpty()) this.makeEmpty(); 11293 return this; 11294 } 11295 /** 11296 * Computes the union of this box and another and the given one, setting the upper 11297 * bound of this box to the greater of the two boxes' upper bounds and the 11298 * lower bound of this box to the lesser of the two boxes' lower bounds. 11299 * 11300 * @param {Box3} box - The bounding box that will be unioned with this instance. 11301 * @return {Box3} A reference to this bounding box. 11302 */ 11303 union(box) { 11304 this.min.min(box.min); 11305 this.max.max(box.max); 11306 return this; 11307 } 11308 /** 11309 * Transforms this bounding box by the given 4x4 transformation matrix. 11310 * 11311 * @param {Matrix4} matrix - The transformation matrix. 11312 * @return {Box3} A reference to this bounding box. 11313 */ 11314 applyMatrix4(matrix) { 11315 if (this.isEmpty()) return this; 11316 _points[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(matrix); 11317 _points[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(matrix); 11318 _points[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(matrix); 11319 _points[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(matrix); 11320 _points[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(matrix); 11321 _points[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(matrix); 11322 _points[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(matrix); 11323 _points[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(matrix); 11324 this.setFromPoints(_points); 11325 return this; 11326 } 11327 /** 11328 * Adds the given offset to both the upper and lower bounds of this bounding box, 11329 * effectively moving it in 3D space. 11330 * 11331 * @param {Vector3} offset - The offset that should be used to translate the bounding box. 11332 * @return {Box3} A reference to this bounding box. 11333 */ 11334 translate(offset) { 11335 this.min.add(offset); 11336 this.max.add(offset); 11337 return this; 11338 } 11339 /** 11340 * Returns `true` if this bounding box is equal with the given one. 11341 * 11342 * @param {Box3} box - The box to test for equality. 11343 * @return {boolean} Whether this bounding box is equal with the given one. 11344 */ 11345 equals(box) { 11346 return box.min.equals(this.min) && box.max.equals(this.max); 11347 } 11348 /** 11349 * Returns a serialized structure of the bounding box. 11350 * 11351 * @return {Object} Serialized structure with fields representing the object state. 11352 */ 11353 toJSON() { 11354 return { 11355 min: this.min.toArray(), 11356 max: this.max.toArray() 11357 }; 11358 } 11359 /** 11360 * Returns a serialized structure of the bounding box. 11361 * 11362 * @param {Object} json - The serialized json to set the box from. 11363 * @return {Box3} A reference to this bounding box. 11364 */ 11365 fromJSON(json) { 11366 this.min.fromArray(json.min); 11367 this.max.fromArray(json.max); 11368 return this; 11369 } 11370}; 11371var _points = [ 11372 /* @__PURE__ */ new Vector3(), 11373 /* @__PURE__ */ new Vector3(), 11374 /* @__PURE__ */ new Vector3(), 11375 /* @__PURE__ */ new Vector3(), 11376 /* @__PURE__ */ new Vector3(), 11377 /* @__PURE__ */ new Vector3(), 11378 /* @__PURE__ */ new Vector3(), 11379 /* @__PURE__ */ new Vector3() 11380]; 11381var _vector$b = /* @__PURE__ */ new Vector3(); 11382var _box$4 = /* @__PURE__ */ new Box3(); 11383var _v0$1 = /* @__PURE__ */ new Vector3(); 11384var _v1$4 = /* @__PURE__ */ new Vector3(); 11385var _v2$3 = /* @__PURE__ */ new Vector3(); 11386var _f0 = /* @__PURE__ */ new Vector3(); 11387var _f1 = /* @__PURE__ */ new Vector3(); 11388var _f2 = /* @__PURE__ */ new Vector3(); 11389var _center = /* @__PURE__ */ new Vector3(); 11390var _extents = /* @__PURE__ */ new Vector3(); 11391var _triangleNormal = /* @__PURE__ */ new Vector3(); 11392var _testAxis = /* @__PURE__ */ new Vector3(); 11393function satForAxes(axes, v0, v1, v2, extents) { 11394 for (let i = 0, j = axes.length - 3; i <= j; i += 3) { 11395 _testAxis.fromArray(axes, i); 11396 const r = extents.x * Math.abs(_testAxis.x) + extents.y * Math.abs(_testAxis.y) + extents.z * Math.abs(_testAxis.z); 11397 const p0 = v0.dot(_testAxis); 11398 const p1 = v1.dot(_testAxis); 11399 const p2 = v2.dot(_testAxis); 11400 if (Math.max(-Math.max(p0, p1, p2), Math.min(p0, p1, p2)) > r) { 11401 return false; 11402 } 11403 } 11404 return true; 11405} 11406var _tables = /* @__PURE__ */ _generateTables(); 11407function _generateTables() { 11408 const buffer = new ArrayBuffer(4); 11409 const floatView = new Float32Array(buffer); 11410 const uint32View = new Uint32Array(buffer); 11411 const baseTable = new Uint32Array(512); 11412 const shiftTable = new Uint32Array(512); 11413 for (let i = 0; i < 256; ++i) { 11414 const e = i - 127; 11415 if (e < -27) { 11416 baseTable[i] = 0; 11417 baseTable[i | 256] = 32768; 11418 shiftTable[i] = 24; 11419 shiftTable[i | 256] = 24; 11420 } else if (e < -14) { 11421 baseTable[i] = 1024 >> -e - 14; 11422 baseTable[i | 256] = 1024 >> -e - 14 | 32768; 11423 shiftTable[i] = -e - 1; 11424 shiftTable[i | 256] = -e - 1; 11425 } else if (e <= 15) { 11426 baseTable[i] = e + 15 << 10; 11427 baseTable[i | 256] = e + 15 << 10 | 32768; 11428 shiftTable[i] = 13; 11429 shiftTable[i | 256] = 13; 11430 } else if (e < 128) { 11431 baseTable[i] = 31744; 11432 baseTable[i | 256] = 64512; 11433 shiftTable[i] = 24; 11434 shiftTable[i | 256] = 24; 11435 } else { 11436 baseTable[i] = 31744; 11437 baseTable[i | 256] = 64512; 11438 shiftTable[i] = 13; 11439 shiftTable[i | 256] = 13; 11440 } 11441 } 11442 const mantissaTable = new Uint32Array(2048); 11443 const exponentTable = new Uint32Array(64); 11444 const offsetTable = new Uint32Array(64); 11445 for (let i = 1; i < 1024; ++i) { 11446 let m = i << 13; 11447 let e = 0; 11448 while ((m & 8388608) === 0) { 11449 m <<= 1; 11450 e -= 8388608; 11451 } 11452 m &= -8388609; 11453 e += 947912704; 11454 mantissaTable[i] = m | e; 11455 } 11456 for (let i = 1024; i < 2048; ++i) { 11457 mantissaTable[i] = 939524096 + (i - 1024 << 13); 11458 } 11459 for (let i = 1; i < 31; ++i) { 11460 exponentTable[i] = i << 23; 11461 } 11462 exponentTable[31] = 1199570944; 11463 exponentTable[32] = 2147483648; 11464 for (let i = 33; i < 63; ++i) { 11465 exponentTable[i] = 2147483648 + (i - 32 << 23); 11466 } 11467 exponentTable[63] = 3347054592; 11468 for (let i = 1; i < 64; ++i) { 11469 if (i !== 32) { 11470 offsetTable[i] = 1024; 11471 } 11472 } 11473 return { 11474 floatView, 11475 uint32View, 11476 baseTable, 11477 shiftTable, 11478 mantissaTable, 11479 exponentTable, 11480 offsetTable 11481 }; 11482} 11483function toHalfFloat(val) { 11484 if (Math.abs(val) > 65504) warn("DataUtils.toHalfFloat(): Value out of range."); 11485 val = clamp(val, -65504, 65504); 11486 _tables.floatView[0] = val; 11487 const f = _tables.uint32View[0]; 11488 const e = f >> 23 & 511; 11489 return _tables.baseTable[e] + ((f & 8388607) >> _tables.shiftTable[e]); 11490} 11491function fromHalfFloat(val) { 11492 const m = val >> 10; 11493 _tables.uint32View[0] = _tables.mantissaTable[_tables.offsetTable[m] + (val & 1023)] + _tables.exponentTable[m]; 11494 return _tables.floatView[0]; 11495} 11496var _vector$a = /* @__PURE__ */ new Vector3(); 11497var _vector2$1 = /* @__PURE__ */ new Vector2(); 11498var _id$2 = 0; 11499var BufferAttribute = class extends EventDispatcher { 11500 /** 11501 * Constructs a new buffer attribute. 11502 * 11503 * @param {TypedArray} array - The array holding the attribute data. 11504 * @param {number} itemSize - The item size. 11505 * @param {boolean} [normalized=false] - Whether the data are normalized or not. 11506 */ 11507 constructor(array, itemSize, normalized = false) { 11508 super(); 11509 if (Array.isArray(array)) { 11510 throw new TypeError("THREE.BufferAttribute: array should be a Typed Array."); 11511 } 11512 this.isBufferAttribute = true; 11513 Object.defineProperty(this, "id", { value: _id$2++ }); 11514 this.name = ""; 11515 this.array = array; 11516 this.itemSize = itemSize; 11517 this.count = array !== void 0 ? array.length / itemSize : 0; 11518 this.normalized = normalized; 11519 this.usage = StaticDrawUsage; 11520 this.updateRanges = []; 11521 this.gpuType = FloatType; 11522 this.version = 0; 11523 } 11524 /** 11525 * A callback function that is executed after the renderer has transferred the attribute 11526 * array data to the GPU. 11527 */ 11528 onUploadCallback() { 11529 } 11530 /** 11531 * Flag to indicate that this attribute has changed and should be re-sent to 11532 * the GPU. Set this to `true` when you modify the value of the array. 11533 * 11534 * @type {number} 11535 * @default false 11536 * @param {boolean} value 11537 */ 11538 set needsUpdate(value) { 11539 if (value === true) this.version++; 11540 } 11541 /** 11542 * Sets the usage of this buffer attribute. 11543 * 11544 * @param {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} value - The usage to set. 11545 * @return {BufferAttribute} A reference to this buffer attribute. 11546 */ 11547 setUsage(value) { 11548 this.usage = value; 11549 return this; 11550 } 11551 /** 11552 * Adds a range of data in the data array to be updated on the GPU. 11553 * 11554 * @param {number} start - Position at which to start update. 11555 * @param {number} count - The number of components to update. 11556 */ 11557 addUpdateRange(start, count) { 11558 this.updateRanges.push({ start, count }); 11559 } 11560 /** 11561 * Clears the update ranges. 11562 */ 11563 clearUpdateRanges() { 11564 this.updateRanges.length = 0; 11565 } 11566 /** 11567 * Copies the values of the given buffer attribute to this instance. 11568 * 11569 * @param {BufferAttribute} source - The buffer attribute to copy. 11570 * @return {BufferAttribute} A reference to this instance. 11571 */ 11572 copy(source) { 11573 this.name = source.name; 11574 this.array = new source.array.constructor(source.array); 11575 this.itemSize = source.itemSize; 11576 this.count = source.count; 11577 this.normalized = source.normalized; 11578 this.usage = source.usage; 11579 this.gpuType = source.gpuType; 11580 return this; 11581 } 11582 /** 11583 * Copies a vector from the given buffer attribute to this one. The start 11584 * and destination position in the attribute buffers are represented by the 11585 * given indices. 11586 * 11587 * @param {number} index1 - The destination index into this buffer attribute. 11588 * @param {BufferAttribute} attribute - The buffer attribute to copy from. 11589 * @param {number} index2 - The source index into the given buffer attribute. 11590 * @return {BufferAttribute} A reference to this instance. 11591 */ 11592 copyAt(index1, attribute, index2) { 11593 index1 *= this.itemSize; 11594 index2 *= attribute.itemSize; 11595 for (let i = 0, l = this.itemSize; i < l; i++) { 11596 this.array[index1 + i] = attribute.array[index2 + i]; 11597 } 11598 return this; 11599 } 11600 /** 11601 * Copies the given array data into this buffer attribute. 11602 * 11603 * @param {(TypedArray|Array)} array - The array to copy. 11604 * @return {BufferAttribute} A reference to this instance. 11605 */ 11606 copyArray(array) { 11607 this.array.set(array); 11608 return this; 11609 } 11610 /** 11611 * Applies the given 3x3 matrix to the given attribute. Works with 11612 * item size `2` and `3`. 11613 * 11614 * @param {Matrix3} m - The matrix to apply. 11615 * @return {BufferAttribute} A reference to this instance. 11616 */ 11617 applyMatrix3(m) { 11618 if (this.itemSize === 2) { 11619 for (let i = 0, l = this.count; i < l; i++) { 11620 _vector2$1.fromBufferAttribute(this, i); 11621 _vector2$1.applyMatrix3(m); 11622 this.setXY(i, _vector2$1.x, _vector2$1.y); 11623 } 11624 } else if (this.itemSize === 3) { 11625 for (let i = 0, l = this.count; i < l; i++) { 11626 _vector$a.fromBufferAttribute(this, i); 11627 _vector$a.applyMatrix3(m); 11628 this.setXYZ(i, _vector$a.x, _vector$a.y, _vector$a.z); 11629 } 11630 } 11631 return this; 11632 } 11633 /** 11634 * Applies the given 4x4 matrix to the given attribute. Only works with 11635 * item size `3`. 11636 * 11637 * @param {Matrix4} m - The matrix to apply. 11638 * @return {BufferAttribute} A reference to this instance. 11639 */ 11640 applyMatrix4(m) { 11641 for (let i = 0, l = this.count; i < l; i++) { 11642 _vector$a.fromBufferAttribute(this, i); 11643 _vector$a.applyMatrix4(m); 11644 this.setXYZ(i, _vector$a.x, _vector$a.y, _vector$a.z); 11645 } 11646 return this; 11647 } 11648 /** 11649 * Applies the given 3x3 normal matrix to the given attribute. Only works with 11650 * item size `3`. 11651 * 11652 * @param {Matrix3} m - The normal matrix to apply. 11653 * @return {BufferAttribute} A reference to this instance. 11654 */ 11655 applyNormalMatrix(m) { 11656 for (let i = 0, l = this.count; i < l; i++) { 11657 _vector$a.fromBufferAttribute(this, i); 11658 _vector$a.applyNormalMatrix(m); 11659 this.setXYZ(i, _vector$a.x, _vector$a.y, _vector$a.z); 11660 } 11661 return this; 11662 } 11663 /** 11664 * Applies the given 4x4 matrix to the given attribute. Only works with 11665 * item size `3` and with direction vectors. 11666 * 11667 * @param {Matrix4} m - The matrix to apply. 11668 * @return {BufferAttribute} A reference to this instance. 11669 */ 11670 transformDirection(m) { 11671 for (let i = 0, l = this.count; i < l; i++) { 11672 _vector$a.fromBufferAttribute(this, i); 11673 _vector$a.transformDirection(m); 11674 this.setXYZ(i, _vector$a.x, _vector$a.y, _vector$a.z); 11675 } 11676 return this; 11677 } 11678 /** 11679 * Sets the given array data in the buffer attribute. 11680 * 11681 * @param {(TypedArray|Array)} value - The array data to set. 11682 * @param {number} [offset=0] - The offset in this buffer attribute's array. 11683 * @return {BufferAttribute} A reference to this instance. 11684 */ 11685 set(value, offset = 0) { 11686 this.array.set(value, offset); 11687 return this; 11688 } 11689 /** 11690 * Returns the given component of the vector at the given index. 11691 * 11692 * @param {number} index - The index into the buffer attribute. 11693 * @param {number} component - The component index. 11694 * @return {number} The returned value. 11695 */ 11696 getComponent(index, component) { 11697 let value = this.array[index * this.itemSize + component]; 11698 if (this.normalized) value = denormalize(value, this.array); 11699 return value; 11700 } 11701 /** 11702 * Sets the given value to the given component of the vector at the given index. 11703 * 11704 * @param {number} index - The index into the buffer attribute. 11705 * @param {number} component - The component index. 11706 * @param {number} value - The value to set. 11707 * @return {BufferAttribute} A reference to this instance. 11708 */ 11709 setComponent(index, component, value) { 11710 if (this.normalized) value = normalize(value, this.array); 11711 this.array[index * this.itemSize + component] = value; 11712 return this; 11713 } 11714 /** 11715 * Returns the x component of the vector at the given index. 11716 * 11717 * @param {number} index - The index into the buffer attribute. 11718 * @return {number} The x component. 11719 */ 11720 getX(index) { 11721 let x = this.array[index * this.itemSize]; 11722 if (this.normalized) x = denormalize(x, this.array); 11723 return x; 11724 } 11725 /** 11726 * Sets the x component of the vector at the given index. 11727 * 11728 * @param {number} index - The index into the buffer attribute. 11729 * @param {number} x - The value to set. 11730 * @return {BufferAttribute} A reference to this instance. 11731 */ 11732 setX(index, x) { 11733 if (this.normalized) x = normalize(x, this.array); 11734 this.array[index * this.itemSize] = x; 11735 return this; 11736 } 11737 /** 11738 * Returns the y component of the vector at the given index. 11739 * 11740 * @param {number} index - The index into the buffer attribute. 11741 * @return {number} The y component. 11742 */ 11743 getY(index) { 11744 let y = this.array[index * this.itemSize + 1]; 11745 if (this.normalized) y = denormalize(y, this.array); 11746 return y; 11747 } 11748 /** 11749 * Sets the y component of the vector at the given index. 11750 * 11751 * @param {number} index - The index into the buffer attribute. 11752 * @param {number} y - The value to set. 11753 * @return {BufferAttribute} A reference to this instance. 11754 */ 11755 setY(index, y) { 11756 if (this.normalized) y = normalize(y, this.array); 11757 this.array[index * this.itemSize + 1] = y; 11758 return this; 11759 } 11760 /** 11761 * Returns the z component of the vector at the given index. 11762 * 11763 * @param {number} index - The index into the buffer attribute. 11764 * @return {number} The z component. 11765 */ 11766 getZ(index) { 11767 let z = this.array[index * this.itemSize + 2]; 11768 if (this.normalized) z = denormalize(z, this.array); 11769 return z; 11770 } 11771 /** 11772 * Sets the z component of the vector at the given index. 11773 * 11774 * @param {number} index - The index into the buffer attribute. 11775 * @param {number} z - The value to set. 11776 * @return {BufferAttribute} A reference to this instance. 11777 */ 11778 setZ(index, z) { 11779 if (this.normalized) z = normalize(z, this.array); 11780 this.array[index * this.itemSize + 2] = z; 11781 return this; 11782 } 11783 /** 11784 * Returns the w component of the vector at the given index. 11785 * 11786 * @param {number} index - The index into the buffer attribute. 11787 * @return {number} The w component. 11788 */ 11789 getW(index) { 11790 let w = this.array[index * this.itemSize + 3]; 11791 if (this.normalized) w = denormalize(w, this.array); 11792 return w; 11793 } 11794 /** 11795 * Sets the w component of the vector at the given index. 11796 * 11797 * @param {number} index - The index into the buffer attribute. 11798 * @param {number} w - The value to set. 11799 * @return {BufferAttribute} A reference to this instance. 11800 */ 11801 setW(index, w) { 11802 if (this.normalized) w = normalize(w, this.array); 11803 this.array[index * this.itemSize + 3] = w; 11804 return this; 11805 } 11806 /** 11807 * Sets the x and y component of the vector at the given index. 11808 * 11809 * @param {number} index - The index into the buffer attribute. 11810 * @param {number} x - The value for the x component to set. 11811 * @param {number} y - The value for the y component to set. 11812 * @return {BufferAttribute} A reference to this instance. 11813 */ 11814 setXY(index, x, y) { 11815 index *= this.itemSize; 11816 if (this.normalized) { 11817 x = normalize(x, this.array); 11818 y = normalize(y, this.array); 11819 } 11820 this.array[index + 0] = x; 11821 this.array[index + 1] = y; 11822 return this; 11823 } 11824 /** 11825 * Sets the x, y and z component of the vector at the given index. 11826 * 11827 * @param {number} index - The index into the buffer attribute. 11828 * @param {number} x - The value for the x component to set. 11829 * @param {number} y - The value for the y component to set. 11830 * @param {number} z - The value for the z component to set. 11831 * @return {BufferAttribute} A reference to this instance. 11832 */ 11833 setXYZ(index, x, y, z) { 11834 index *= this.itemSize; 11835 if (this.normalized) { 11836 x = normalize(x, this.array); 11837 y = normalize(y, this.array); 11838 z = normalize(z, this.array); 11839 } 11840 this.array[index + 0] = x; 11841 this.array[index + 1] = y; 11842 this.array[index + 2] = z; 11843 return this; 11844 } 11845 /** 11846 * Sets the x, y, z and w component of the vector at the given index. 11847 * 11848 * @param {number} index - The index into the buffer attribute. 11849 * @param {number} x - The value for the x component to set. 11850 * @param {number} y - The value for the y component to set. 11851 * @param {number} z - The value for the z component to set. 11852 * @param {number} w - The value for the w component to set. 11853 * @return {BufferAttribute} A reference to this instance. 11854 */ 11855 setXYZW(index, x, y, z, w) { 11856 index *= this.itemSize; 11857 if (this.normalized) { 11858 x = normalize(x, this.array); 11859 y = normalize(y, this.array); 11860 z = normalize(z, this.array); 11861 w = normalize(w, this.array); 11862 } 11863 this.array[index + 0] = x; 11864 this.array[index + 1] = y; 11865 this.array[index + 2] = z; 11866 this.array[index + 3] = w; 11867 return this; 11868 } 11869 /** 11870 * Sets the given callback function that is executed after the Renderer has transferred 11871 * the attribute array data to the GPU. Can be used to perform clean-up operations after 11872 * the upload when attribute data are not needed anymore on the CPU side. 11873 * 11874 * @param {Function} callback - The `onUpload()` callback. 11875 * @return {BufferAttribute} A reference to this instance. 11876 */ 11877 onUpload(callback) { 11878 this.onUploadCallback = callback; 11879 return this; 11880 } 11881 /** 11882 * Returns a new buffer attribute with copied values from this instance. 11883 * 11884 * @return {BufferAttribute} A clone of this instance. 11885 */ 11886 clone() { 11887 return new this.constructor(this.array, this.itemSize).copy(this); 11888 } 11889 /** 11890 * Serializes the buffer attribute into JSON. 11891 * 11892 * @return {Object} A JSON object representing the serialized buffer attribute. 11893 */ 11894 toJSON() { 11895 const data = { 11896 itemSize: this.itemSize, 11897 type: this.array.constructor.name, 11898 array: Array.from(this.array), 11899 normalized: this.normalized 11900 }; 11901 if (this.name !== "") data.name = this.name; 11902 if (this.usage !== StaticDrawUsage) data.usage = this.usage; 11903 return data; 11904 } 11905 /** 11906 * Disposes of the buffer attribute. Available only in {@link WebGPURenderer}. 11907 */ 11908 dispose() { 11909 this.dispatchEvent({ type: "dispose" }); 11910 } 11911}; 11912var Uint16BufferAttribute = class extends BufferAttribute { 11913 /** 11914 * Constructs a new buffer attribute. 11915 * 11916 * @param {(Array<number>|Uint16Array)} array - The array holding the attribute data. 11917 * @param {number} itemSize - The item size. 11918 * @param {boolean} [normalized=false] - Whether the data are normalized or not. 11919 */ 11920 constructor(array, itemSize, normalized) { 11921 super(new Uint16Array(array), itemSize, normalized); 11922 } 11923}; 11924var Uint32BufferAttribute = class extends BufferAttribute { 11925 /** 11926 * Constructs a new buffer attribute. 11927 * 11928 * @param {(Array<number>|Uint32Array)} array - The array holding the attribute data. 11929 * @param {number} itemSize - The item size. 11930 * @param {boolean} [normalized=false] - Whether the data are normalized or not. 11931 */ 11932 constructor(array, itemSize, normalized) { 11933 super(new Uint32Array(array), itemSize, normalized); 11934 } 11935}; 11936var Float16BufferAttribute = class extends BufferAttribute { 11937 /** 11938 * Constructs a new buffer attribute. 11939 * 11940 * @param {(Array<number>|Uint16Array)} array - The array holding the attribute data. 11941 * @param {number} itemSize - The item size. 11942 * @param {boolean} [normalized=false] - Whether the data are normalized or not. 11943 */ 11944 constructor(array, itemSize, normalized) { 11945 super(new Uint16Array(array), itemSize, normalized); 11946 this.isFloat16BufferAttribute = true; 11947 } 11948 getX(index) { 11949 let x = fromHalfFloat(this.array[index * this.itemSize]); 11950 if (this.normalized) x = denormalize(x, this.array); 11951 return x; 11952 } 11953 setX(index, x) { 11954 if (this.normalized) x = normalize(x, this.array); 11955 this.array[index * this.itemSize] = toHalfFloat(x); 11956 return this; 11957 } 11958 getY(index) { 11959 let y = fromHalfFloat(this.array[index * this.itemSize + 1]); 11960 if (this.normalized) y = denormalize(y, this.array); 11961 return y; 11962 } 11963 setY(index, y) { 11964 if (this.normalized) y = normalize(y, this.array); 11965 this.array[index * this.itemSize + 1] = toHalfFloat(y); 11966 return this; 11967 } 11968 getZ(index) { 11969 let z = fromHalfFloat(this.array[index * this.itemSize + 2]); 11970 if (this.normalized) z = denormalize(z, this.array); 11971 return z; 11972 } 11973 setZ(index, z) { 11974 if (this.normalized) z = normalize(z, this.array); 11975 this.array[index * this.itemSize + 2] = toHalfFloat(z); 11976 return this; 11977 } 11978 getW(index) { 11979 let w = fromHalfFloat(this.array[index * this.itemSize + 3]); 11980 if (this.normalized) w = denormalize(w, this.array); 11981 return w; 11982 } 11983 setW(index, w) { 11984 if (this.normalized) w = normalize(w, this.array); 11985 this.array[index * this.itemSize + 3] = toHalfFloat(w); 11986 return this; 11987 } 11988 setXY(index, x, y) { 11989 index *= this.itemSize; 11990 if (this.normalized) { 11991 x = normalize(x, this.array); 11992 y = normalize(y, this.array); 11993 } 11994 this.array[index + 0] = toHalfFloat(x); 11995 this.array[index + 1] = toHalfFloat(y); 11996 return this; 11997 } 11998 setXYZ(index, x, y, z) { 11999 index *= this.itemSize; 12000 if (this.normalized) { 12001 x = normalize(x, this.array); 12002 y = normalize(y, this.array); 12003 z = normalize(z, this.array); 12004 } 12005 this.array[index + 0] = toHalfFloat(x); 12006 this.array[index + 1] = toHalfFloat(y); 12007 this.array[index + 2] = toHalfFloat(z); 12008 return this; 12009 } 12010 setXYZW(index, x, y, z, w) { 12011 index *= this.itemSize; 12012 if (this.normalized) { 12013 x = normalize(x, this.array); 12014 y = normalize(y, this.array); 12015 z = normalize(z, this.array); 12016 w = normalize(w, this.array); 12017 } 12018 this.array[index + 0] = toHalfFloat(x); 12019 this.array[index + 1] = toHalfFloat(y); 12020 this.array[index + 2] = toHalfFloat(z); 12021 this.array[index + 3] = toHalfFloat(w); 12022 return this; 12023 } 12024}; 12025var Float32BufferAttribute = class extends BufferAttribute { 12026 /** 12027 * Constructs a new buffer attribute. 12028 * 12029 * @param {(Array<number>|Float32Array)} array - The array holding the attribute data. 12030 * @param {number} itemSize - The item size. 12031 * @param {boolean} [normalized=false] - Whether the data are normalized or not. 12032 */ 12033 constructor(array, itemSize, normalized) { 12034 super(new Float32Array(array), itemSize, normalized); 12035 } 12036}; 12037var _box$3 = /* @__PURE__ */ new Box3(); 12038var _v1$3 = /* @__PURE__ */ new Vector3(); 12039var _v2$2 = /* @__PURE__ */ new Vector3(); 12040var Sphere = class { 12041 /** 12042 * Constructs a new sphere. 12043 * 12044 * @param {Vector3} [center=(0,0,0)] - The center of the sphere 12045 * @param {number} [radius=-1] - The radius of the sphere. 12046 */ 12047 constructor(center = new Vector3(), radius = -1) { 12048 this.isSphere = true; 12049 this.center = center; 12050 this.radius = radius; 12051 } 12052 /** 12053 * Sets the sphere's components by copying the given values. 12054 * 12055 * @param {Vector3} center - The center. 12056 * @param {number} radius - The radius. 12057 * @return {Sphere} A reference to this sphere. 12058 */ 12059 set(center, radius) { 12060 this.center.copy(center); 12061 this.radius = radius; 12062 return this; 12063 } 12064 /** 12065 * Computes the minimum bounding sphere for list of points. 12066 * If the optional center point is given, it is used as the sphere's 12067 * center. Otherwise, the center of the axis-aligned bounding box 12068 * encompassing the points is calculated. 12069 * 12070 * @param {Array<Vector3>} points - A list of points in 3D space. 12071 * @param {Vector3} [optionalCenter] - The center of the sphere. 12072 * @return {Sphere} A reference to this sphere. 12073 */ 12074 setFromPoints(points, optionalCenter) { 12075 const center = this.center; 12076 if (optionalCenter !== void 0) { 12077 center.copy(optionalCenter); 12078 } else { 12079 _box$3.setFromPoints(points).getCenter(center); 12080 } 12081 let maxRadiusSq = 0; 12082 for (let i = 0, il = points.length; i < il; i++) { 12083 maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(points[i])); 12084 } 12085 this.radius = Math.sqrt(maxRadiusSq); 12086 return this; 12087 } 12088 /** 12089 * Copies the values of the given sphere to this instance. 12090 * 12091 * @param {Sphere} sphere - The sphere to copy. 12092 * @return {Sphere} A reference to this sphere. 12093 */ 12094 copy(sphere) { 12095 this.center.copy(sphere.center); 12096 this.radius = sphere.radius; 12097 return this; 12098 } 12099 /** 12100 * Returns `true` if the sphere is empty (the radius set to a negative number). 12101 * 12102 * Spheres with a radius of `0` contain only their center point and are not 12103 * considered to be empty. 12104 * 12105 * @return {boolean} Whether this sphere is empty or not. 12106 */ 12107 isEmpty() { 12108 return this.radius < 0; 12109 } 12110 /** 12111 * Makes this sphere empty which means in encloses a zero space in 3D. 12112 * 12113 * @return {Sphere} A reference to this sphere. 12114 */ 12115 makeEmpty() { 12116 this.center.set(0, 0, 0); 12117 this.radius = -1; 12118 return this; 12119 } 12120 /** 12121 * Returns `true` if this sphere contains the given point inclusive of 12122 * the surface of the sphere. 12123 * 12124 * @param {Vector3} point - The point to check. 12125 * @return {boolean} Whether this sphere contains the given point or not. 12126 */ 12127 containsPoint(point) { 12128 return point.distanceToSquared(this.center) <= this.radius * this.radius; 12129 } 12130 /** 12131 * Returns the closest distance from the boundary of the sphere to the 12132 * given point. If the sphere contains the point, the distance will 12133 * be negative. 12134 * 12135 * @param {Vector3} point - The point to compute the distance to. 12136 * @return {number} The distance to the point. 12137 */ 12138 distanceToPoint(point) { 12139 return point.distanceTo(this.center) - this.radius; 12140 } 12141 /** 12142 * Returns `true` if this sphere intersects with the given one. 12143 * 12144 * @param {Sphere} sphere - The sphere to test. 12145 * @return {boolean} Whether this sphere intersects with the given one or not. 12146 */ 12147 intersectsSphere(sphere) { 12148 const radiusSum = this.radius + sphere.radius; 12149 return sphere.center.distanceToSquared(this.center) <= radiusSum * radiusSum; 12150 } 12151 /** 12152 * Returns `true` if this sphere intersects with the given box. 12153 * 12154 * @param {Box3} box - The box to test. 12155 * @return {boolean} Whether this sphere intersects with the given box or not. 12156 */ 12157 intersectsBox(box) { 12158 return box.intersectsSphere(this); 12159 } 12160 /** 12161 * Returns `true` if this sphere intersects with the given plane. 12162 * 12163 * @param {Plane} plane - The plane to test. 12164 * @return {boolean} Whether this sphere intersects with the given plane or not. 12165 */ 12166 intersectsPlane(plane) { 12167 return Math.abs(plane.distanceToPoint(this.center)) <= this.radius; 12168 } 12169 /** 12170 * Clamps a point within the sphere. If the point is outside the sphere, it 12171 * will clamp it to the closest point on the edge of the sphere. Points 12172 * already inside the sphere will not be affected. 12173 * 12174 * @param {Vector3} point - The plane to clamp. 12175 * @param {Vector3} target - The target vector that is used to store the method's result. 12176 * @return {Vector3} The clamped point. 12177 */ 12178 clampPoint(point, target) { 12179 const deltaLengthSq = this.center.distanceToSquared(point); 12180 target.copy(point); 12181 if (deltaLengthSq > this.radius * this.radius) { 12182 target.sub(this.center).normalize(); 12183 target.multiplyScalar(this.radius).add(this.center); 12184 } 12185 return target; 12186 } 12187 /** 12188 * Returns a bounding box that encloses this sphere. 12189 * 12190 * @param {Box3} target - The target box that is used to store the method's result. 12191 * @return {Box3} The bounding box that encloses this sphere. 12192 */ 12193 getBoundingBox(target) { 12194 if (this.isEmpty()) { 12195 target.makeEmpty(); 12196 return target; 12197 } 12198 target.set(this.center, this.center); 12199 target.expandByScalar(this.radius); 12200 return target; 12201 } 12202 /** 12203 * Transforms this sphere with the given 4x4 transformation matrix. 12204 * 12205 * @param {Matrix4} matrix - The transformation matrix. 12206 * @return {Sphere} A reference to this sphere. 12207 */ 12208 applyMatrix4(matrix) { 12209 this.center.applyMatrix4(matrix); 12210 this.radius = this.radius * matrix.getMaxScaleOnAxis(); 12211 return this; 12212 } 12213 /** 12214 * Translates the sphere's center by the given offset. 12215 * 12216 * @param {Vector3} offset - The offset. 12217 * @return {Sphere} A reference to this sphere. 12218 */ 12219 translate(offset) { 12220 this.center.add(offset); 12221 return this; 12222 } 12223 /** 12224 * Expands the boundaries of this sphere to include the given point. 12225 * 12226 * @param {Vector3} point - The point to include. 12227 * @return {Sphere} A reference to this sphere. 12228 */ 12229 expandByPoint(point) { 12230 if (this.isEmpty()) { 12231 this.center.copy(point); 12232 this.radius = 0; 12233 return this; 12234 } 12235 _v1$3.subVectors(point, this.center); 12236 const lengthSq = _v1$3.lengthSq(); 12237 if (lengthSq > this.radius * this.radius) { 12238 const length = Math.sqrt(lengthSq); 12239 const delta = (length - this.radius) * 0.5; 12240 this.center.addScaledVector(_v1$3, delta / length); 12241 this.radius += delta; 12242 } 12243 return this; 12244 } 12245 /** 12246 * Expands this sphere to enclose both the original sphere and the given sphere. 12247 * 12248 * @param {Sphere} sphere - The sphere to include. 12249 * @return {Sphere} A reference to this sphere. 12250 */ 12251 union(sphere) { 12252 if (sphere.isEmpty()) { 12253 return this; 12254 } 12255 if (this.isEmpty()) { 12256 this.copy(sphere); 12257 return this; 12258 } 12259 if (this.center.equals(sphere.center) === true) { 12260 this.radius = Math.max(this.radius, sphere.radius); 12261 } else { 12262 _v2$2.subVectors(sphere.center, this.center).setLength(sphere.radius); 12263 this.expandByPoint(_v1$3.copy(sphere.center).add(_v2$2)); 12264 this.expandByPoint(_v1$3.copy(sphere.center).sub(_v2$2)); 12265 } 12266 return this; 12267 } 12268 /** 12269 * Returns `true` if this sphere is equal with the given one. 12270 * 12271 * @param {Sphere} sphere - The sphere to test for equality. 12272 * @return {boolean} Whether this bounding sphere is equal with the given one. 12273 */ 12274 equals(sphere) { 12275 return sphere.center.equals(this.center) && sphere.radius === this.radius; 12276 } 12277 /** 12278 * Returns a new sphere with copied values from this instance. 12279 * 12280 * @return {Sphere} A clone of this instance. 12281 */ 12282 clone() { 12283 return new this.constructor().copy(this); 12284 } 12285 /** 12286 * Returns a serialized structure of the bounding sphere. 12287 * 12288 * @return {Object} Serialized structure with fields representing the object state. 12289 */ 12290 toJSON() { 12291 return { 12292 radius: this.radius, 12293 center: this.center.toArray() 12294 }; 12295 } 12296 /** 12297 * Returns a serialized structure of the bounding sphere. 12298 * 12299 * @param {Object} json - The serialized json to set the sphere from. 12300 * @return {Sphere} A reference to this bounding sphere. 12301 */ 12302 fromJSON(json) { 12303 this.radius = json.radius; 12304 this.center.fromArray(json.center); 12305 return this; 12306 } 12307}; 12308var _id$1 = 0; 12309var _m1 = /* @__PURE__ */ new Matrix4(); 12310var _obj = /* @__PURE__ */ new Object3D(); 12311var _offset = /* @__PURE__ */ new Vector3(); 12312var _box$2 = /* @__PURE__ */ new Box3(); 12313var _boxMorphTargets = /* @__PURE__ */ new Box3(); 12314var _vector$9 = /* @__PURE__ */ new Vector3(); 12315var BufferGeometry = class _BufferGeometry extends EventDispatcher { 12316 /** 12317 * Constructs a new geometry. 12318 */ 12319 constructor() { 12320 super(); 12321 this.isBufferGeometry = true; 12322 Object.defineProperty(this, "id", { value: _id$1++ }); 12323 this.uuid = generateUUID(); 12324 this.name = ""; 12325 this.type = "BufferGeometry"; 12326 this.index = null; 12327 this.indirect = null; 12328 this.indirectOffset = 0; 12329 this.attributes = {}; 12330 this.morphAttributes = {}; 12331 this.morphTargetsRelative = false; 12332 this.groups = []; 12333 this.boundingBox = null; 12334 this.boundingSphere = null; 12335 this.drawRange = { start: 0, count: Infinity }; 12336 this.userData = {}; 12337 } 12338 /** 12339 * Returns the index of this geometry. 12340 * 12341 * @return {?BufferAttribute} The index. Returns `null` if no index is defined. 12342 */ 12343 getIndex() { 12344 return this.index; 12345 } 12346 /** 12347 * Sets the given index to this geometry. 12348 * 12349 * @param {Array<number>|BufferAttribute} index - The index to set. 12350 * @return {BufferGeometry} A reference to this instance. 12351 */ 12352 setIndex(index) { 12353 if (Array.isArray(index)) { 12354 this.index = new (arrayNeedsUint32(index) ? Uint32BufferAttribute : Uint16BufferAttribute)(index, 1); 12355 } else { 12356 this.index = index; 12357 } 12358 return this; 12359 } 12360 /** 12361 * Sets the given indirect attribute to this geometry. 12362 * 12363 * @param {BufferAttribute} indirect - The attribute holding indirect draw calls. 12364 * @param {number|Array<number>} [indirectOffset=0] - The offset, in bytes, into the indirect drawing buffer where the value data begins. If an array is provided, multiple indirect draw calls will be made for each offset. 12365 * @return {BufferGeometry} A reference to this instance. 12366 */ 12367 setIndirect(indirect, indirectOffset = 0) { 12368 this.indirect = indirect; 12369 this.indirectOffset = indirectOffset; 12370 return this; 12371 } 12372 /** 12373 * Returns the indirect attribute of this geometry. 12374 * 12375 * @return {?BufferAttribute} The indirect attribute. Returns `null` if no indirect attribute is defined. 12376 */ 12377 getIndirect() { 12378 return this.indirect; 12379 } 12380 /** 12381 * Returns the buffer attribute for the given name. 12382 * 12383 * @param {string} name - The attribute name. 12384 * @return {BufferAttribute|InterleavedBufferAttribute|undefined} The buffer attribute. 12385 * Returns `undefined` if not attribute has been found. 12386 */ 12387 getAttribute(name) { 12388 return this.attributes[name]; 12389 } 12390 /** 12391 * Sets the given attribute for the given name. 12392 * 12393 * @param {string} name - The attribute name. 12394 * @param {BufferAttribute|InterleavedBufferAttribute} attribute - The attribute to set. 12395 * @return {BufferGeometry} A reference to this instance. 12396 */ 12397 setAttribute(name, attribute) { 12398 this.attributes[name] = attribute; 12399 return this; 12400 } 12401 /** 12402 * Deletes the attribute for the given name. 12403 * 12404 * @param {string} name - The attribute name to delete. 12405 * @return {BufferGeometry} A reference to this instance. 12406 */ 12407 deleteAttribute(name) { 12408 delete this.attributes[name]; 12409 return this; 12410 } 12411 /** 12412 * Returns `true` if this geometry has an attribute for the given name. 12413 * 12414 * @param {string} name - The attribute name. 12415 * @return {boolean} Whether this geometry has an attribute for the given name or not. 12416 */ 12417 hasAttribute(name) { 12418 return this.attributes[name] !== void 0; 12419 } 12420 /** 12421 * Adds a group to this geometry. 12422 * 12423 * @param {number} start - The first element in this draw call. That is the first 12424 * vertex for non-indexed geometry, otherwise the first triangle index. 12425 * @param {number} count - Specifies how many vertices (or indices) are part of this group. 12426 * @param {number} [materialIndex=0] - The material array index to use. 12427 */ 12428 addGroup(start, count, materialIndex = 0) { 12429 this.groups.push({ 12430 start, 12431 count, 12432 materialIndex 12433 }); 12434 } 12435 /** 12436 * Clears all groups. 12437 */ 12438 clearGroups() { 12439 this.groups = []; 12440 } 12441 /** 12442 * Sets the draw range for this geometry. 12443 * 12444 * @param {number} start - The first vertex for non-indexed geometry, otherwise the first triangle index. 12445 * @param {number} count - For non-indexed BufferGeometry, `count` is the number of vertices to render. 12446 * For indexed BufferGeometry, `count` is the number of indices to render. 12447 */ 12448 setDrawRange(start, count) { 12449 this.drawRange.start = start; 12450 this.drawRange.count = count; 12451 } 12452 /** 12453 * Applies the given 4x4 transformation matrix to the geometry. 12454 * 12455 * @param {Matrix4} matrix - The matrix to apply. 12456 * @return {BufferGeometry} A reference to this instance. 12457 */ 12458 applyMatrix4(matrix) { 12459 const position = this.attributes.position; 12460 if (position !== void 0) { 12461 position.applyMatrix4(matrix); 12462 position.needsUpdate = true; 12463 } 12464 const normal = this.attributes.normal; 12465 if (normal !== void 0) { 12466 const normalMatrix = new Matrix3().getNormalMatrix(matrix); 12467 normal.applyNormalMatrix(normalMatrix); 12468 normal.needsUpdate = true; 12469 } 12470 const tangent = this.attributes.tangent; 12471 if (tangent !== void 0) { 12472 tangent.transformDirection(matrix); 12473 tangent.needsUpdate = true; 12474 } 12475 if (this.boundingBox !== null) { 12476 this.computeBoundingBox(); 12477 } 12478 if (this.boundingSphere !== null) { 12479 this.computeBoundingSphere(); 12480 } 12481 return this; 12482 } 12483 /** 12484 * Applies the rotation represented by the Quaternion to the geometry. 12485 * 12486 * @param {Quaternion} q - The Quaternion to apply. 12487 * @return {BufferGeometry} A reference to this instance. 12488 */ 12489 applyQuaternion(q) { 12490 _m1.makeRotationFromQuaternion(q); 12491 this.applyMatrix4(_m1); 12492 return this; 12493 } 12494 /** 12495 * Rotates the geometry about the X axis. This is typically done as a one time 12496 * operation, and not during a loop. Use {@link Object3D#rotation} for typical 12497 * real-time mesh rotation. 12498 * 12499 * @param {number} angle - The angle in radians. 12500 * @return {BufferGeometry} A reference to this instance. 12501 */ 12502 rotateX(angle) { 12503 _m1.makeRotationX(angle); 12504 this.applyMatrix4(_m1); 12505 return this; 12506 } 12507 /** 12508 * Rotates the geometry about the Y axis. This is typically done as a one time 12509 * operation, and not during a loop. Use {@link Object3D#rotation} for typical 12510 * real-time mesh rotation. 12511 * 12512 * @param {number} angle - The angle in radians. 12513 * @return {BufferGeometry} A reference to this instance. 12514 */ 12515 rotateY(angle) { 12516 _m1.makeRotationY(angle); 12517 this.applyMatrix4(_m1); 12518 return this; 12519 } 12520 /** 12521 * Rotates the geometry about the Z axis. This is typically done as a one time 12522 * operation, and not during a loop. Use {@link Object3D#rotation} for typical 12523 * real-time mesh rotation. 12524 * 12525 * @param {number} angle - The angle in radians. 12526 * @return {BufferGeometry} A reference to this instance. 12527 */ 12528 rotateZ(angle) { 12529 _m1.makeRotationZ(angle); 12530 this.applyMatrix4(_m1); 12531 return this; 12532 } 12533 /** 12534 * Translates the geometry. This is typically done as a one time 12535 * operation, and not during a loop. Use {@link Object3D#position} for typical 12536 * real-time mesh rotation. 12537 * 12538 * @param {number} x - The x offset. 12539 * @param {number} y - The y offset. 12540 * @param {number} z - The z offset. 12541 * @return {BufferGeometry} A reference to this instance. 12542 */ 12543 translate(x, y, z) { 12544 _m1.makeTranslation(x, y, z); 12545 this.applyMatrix4(_m1); 12546 return this; 12547 } 12548 /** 12549 * Scales the geometry. This is typically done as a one time 12550 * operation, and not during a loop. Use {@link Object3D#scale} for typical 12551 * real-time mesh rotation. 12552 * 12553 * @param {number} x - The x scale. 12554 * @param {number} y - The y scale. 12555 * @param {number} z - The z scale. 12556 * @return {BufferGeometry} A reference to this instance. 12557 */ 12558 scale(x, y, z) { 12559 _m1.makeScale(x, y, z); 12560 this.applyMatrix4(_m1); 12561 return this; 12562 } 12563 /** 12564 * Rotates the geometry to face a point in 3D space. This is typically done as a one time 12565 * operation, and not during a loop. Use {@link Object3D#lookAt} for typical 12566 * real-time mesh rotation. 12567 * 12568 * @param {Vector3} vector - The target point. 12569 * @return {BufferGeometry} A reference to this instance. 12570 */ 12571 lookAt(vector) { 12572 _obj.lookAt(vector); 12573 _obj.updateMatrix(); 12574 this.applyMatrix4(_obj.matrix); 12575 return this; 12576 } 12577 /** 12578 * Center the geometry based on its bounding box. 12579 * 12580 * @return {BufferGeometry} A reference to this instance. 12581 */ 12582 center() { 12583 this.computeBoundingBox(); 12584 this.boundingBox.getCenter(_offset).negate(); 12585 this.translate(_offset.x, _offset.y, _offset.z); 12586 return this; 12587 } 12588 /** 12589 * Defines a geometry by creating a `position` attribute based on the given array of points. The array 12590 * can hold 2D or 3D vectors. When using two-dimensional data, the `z` coordinate for all vertices is 12591 * set to `0`. 12592 * 12593 * If the method is used with an existing `position` attribute, the vertex data are overwritten with the 12594 * data from the array. The length of the array must match the vertex count. 12595 * 12596 * @param {Array<Vector2>|Array<Vector3>} points - The points. 12597 * @return {BufferGeometry} A reference to this instance. 12598 */ 12599 setFromPoints(points) { 12600 const positionAttribute = this.getAttribute("position"); 12601 if (positionAttribute === void 0) { 12602 const position = []; 12603 for (let i = 0, l = points.length; i < l; i++) { 12604 const point = points[i]; 12605 position.push(point.x, point.y, point.z || 0); 12606 } 12607 this.setAttribute("position", new Float32BufferAttribute(position, 3)); 12608 } else { 12609 const l = Math.min(points.length, positionAttribute.count); 12610 for (let i = 0; i < l; i++) { 12611 const point = points[i]; 12612 positionAttribute.setXYZ(i, point.x, point.y, point.z || 0); 12613 } 12614 if (points.length > positionAttribute.count) { 12615 warn("BufferGeometry: Buffer size too small for points data. Use .dispose() and create a new geometry."); 12616 } 12617 positionAttribute.needsUpdate = true; 12618 } 12619 return this; 12620 } 12621 /** 12622 * Computes the bounding box of the geometry, and updates the `boundingBox` member. 12623 * The bounding box is not computed by the engine; it must be computed by your app. 12624 * You may need to recompute the bounding box if the geometry vertices are modified. 12625 */ 12626 computeBoundingBox() { 12627 if (this.boundingBox === null) { 12628 this.boundingBox = new Box3(); 12629 } 12630 const position = this.attributes.position; 12631 const morphAttributesPosition = this.morphAttributes.position; 12632 if (position && position.isGLBufferAttribute) { 12633 error("BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box.", this); 12634 this.boundingBox.set( 12635 new Vector3(-Infinity, -Infinity, -Infinity), 12636 new Vector3(Infinity, Infinity, Infinity) 12637 ); 12638 return; 12639 } 12640 if (position !== void 0) { 12641 this.boundingBox.setFromBufferAttribute(position); 12642 if (morphAttributesPosition) { 12643 for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { 12644 const morphAttribute = morphAttributesPosition[i]; 12645 _box$2.setFromBufferAttribute(morphAttribute); 12646 if (this.morphTargetsRelative) { 12647 _vector$9.addVectors(this.boundingBox.min, _box$2.min); 12648 this.boundingBox.expandByPoint(_vector$9); 12649 _vector$9.addVectors(this.boundingBox.max, _box$2.max); 12650 this.boundingBox.expandByPoint(_vector$9); 12651 } else { 12652 this.boundingBox.expandByPoint(_box$2.min); 12653 this.boundingBox.expandByPoint(_box$2.max); 12654 } 12655 } 12656 } 12657 } else { 12658 this.boundingBox.makeEmpty(); 12659 } 12660 if (isNaN(this.boundingBox.min.x) || isNaN(this.boundingBox.min.y) || isNaN(this.boundingBox.min.z)) { 12661 error('BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this); 12662 } 12663 } 12664 /** 12665 * Computes the bounding sphere of the geometry, and updates the `boundingSphere` member. 12666 * The engine automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling. 12667 * You may need to recompute the bounding sphere if the geometry vertices are modified. 12668 */ 12669 computeBoundingSphere() { 12670 if (this.boundingSphere === null) { 12671 this.boundingSphere = new Sphere(); 12672 } 12673 const position = this.attributes.position; 12674 const morphAttributesPosition = this.morphAttributes.position; 12675 if (position && position.isGLBufferAttribute) { 12676 error("BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere.", this); 12677 this.boundingSphere.set(new Vector3(), Infinity); 12678 return; 12679 } 12680 if (position) { 12681 const center = this.boundingSphere.center; 12682 _box$2.setFromBufferAttribute(position); 12683 if (morphAttributesPosition) { 12684 for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { 12685 const morphAttribute = morphAttributesPosition[i]; 12686 _boxMorphTargets.setFromBufferAttribute(morphAttribute); 12687 if (this.morphTargetsRelative) { 12688 _vector$9.addVectors(_box$2.min, _boxMorphTargets.min); 12689 _box$2.expandByPoint(_vector$9); 12690 _vector$9.addVectors(_box$2.max, _boxMorphTargets.max); 12691 _box$2.expandByPoint(_vector$9); 12692 } else { 12693 _box$2.expandByPoint(_boxMorphTargets.min); 12694 _box$2.expandByPoint(_boxMorphTargets.max); 12695 } 12696 } 12697 } 12698 _box$2.getCenter(center); 12699 let maxRadiusSq = 0; 12700 for (let i = 0, il = position.count; i < il; i++) { 12701 _vector$9.fromBufferAttribute(position, i); 12702 maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$9)); 12703 } 12704 if (morphAttributesPosition) { 12705 for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { 12706 const morphAttribute = morphAttributesPosition[i]; 12707 const morphTargetsRelative = this.morphTargetsRelative; 12708 for (let j = 0, jl = morphAttribute.count; j < jl; j++) { 12709 _vector$9.fromBufferAttribute(morphAttribute, j); 12710 if (morphTargetsRelative) { 12711 _offset.fromBufferAttribute(position, j); 12712 _vector$9.add(_offset); 12713 } 12714 maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$9)); 12715 } 12716 } 12717 } 12718 this.boundingSphere.radius = Math.sqrt(maxRadiusSq); 12719 if (isNaN(this.boundingSphere.radius)) { 12720 error('BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this); 12721 } 12722 } 12723 } 12724 /** 12725 * Calculates and adds a tangent attribute to this geometry. 12726 * 12727 * The computation is only supported for indexed geometries and if position, normal, and uv attributes 12728 * are defined. When using a tangent space normal map, prefer the MikkTSpace algorithm provided by 12729 * {@link BufferGeometryUtils#computeMikkTSpaceTangents} instead. 12730 */ 12731 computeTangents() { 12732 const index = this.index; 12733 const attributes = this.attributes; 12734 if (index === null || attributes.position === void 0 || attributes.normal === void 0 || attributes.uv === void 0) { 12735 error("BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)"); 12736 return; 12737 } 12738 const positionAttribute = attributes.position; 12739 const normalAttribute = attributes.normal; 12740 const uvAttribute = attributes.uv; 12741 if (this.hasAttribute("tangent") === false) { 12742 this.setAttribute("tangent", new BufferAttribute(new Float32Array(4 * positionAttribute.count), 4)); 12743 } 12744 const tangentAttribute = this.getAttribute("tangent"); 12745 const tan1 = [], tan2 = []; 12746 for (let i = 0; i < positionAttribute.count; i++) { 12747 tan1[i] = new Vector3(); 12748 tan2[i] = new Vector3(); 12749 } 12750 const vA = new Vector3(), vB = new Vector3(), vC = new Vector3(), uvA = new Vector2(), uvB = new Vector2(), uvC = new Vector2(), sdir = new Vector3(), tdir = new Vector3(); 12751 function handleTriangle(a, b, c) { 12752 vA.fromBufferAttribute(positionAttribute, a); 12753 vB.fromBufferAttribute(positionAttribute, b); 12754 vC.fromBufferAttribute(positionAttribute, c); 12755 uvA.fromBufferAttribute(uvAttribute, a); 12756 uvB.fromBufferAttribute(uvAttribute, b); 12757 uvC.fromBufferAttribute(uvAttribute, c); 12758 vB.sub(vA); 12759 vC.sub(vA); 12760 uvB.sub(uvA); 12761 uvC.sub(uvA); 12762 const r = 1 / (uvB.x * uvC.y - uvC.x * uvB.y); 12763 if (!isFinite(r)) return; 12764 sdir.copy(vB).multiplyScalar(uvC.y).addScaledVector(vC, -uvB.y).multiplyScalar(r); 12765 tdir.copy(vC).multiplyScalar(uvB.x).addScaledVector(vB, -uvC.x).multiplyScalar(r); 12766 tan1[a].add(sdir); 12767 tan1[b].add(sdir); 12768 tan1[c].add(sdir); 12769 tan2[a].add(tdir); 12770 tan2[b].add(tdir); 12771 tan2[c].add(tdir); 12772 } 12773 let groups = this.groups; 12774 if (groups.length === 0) { 12775 groups = [{ 12776 start: 0, 12777 count: index.count 12778 }]; 12779 } 12780 for (let i = 0, il = groups.length; i < il; ++i) { 12781 const group = groups[i]; 12782 const start = group.start; 12783 const count = group.count; 12784 for (let j = start, jl = start + count; j < jl; j += 3) { 12785 handleTriangle( 12786 index.getX(j + 0), 12787 index.getX(j + 1), 12788 index.getX(j + 2) 12789 ); 12790 } 12791 } 12792 const tmp = new Vector3(), tmp2 = new Vector3(); 12793 const n = new Vector3(), n2 = new Vector3(); 12794 function handleVertex(v) { 12795 n.fromBufferAttribute(normalAttribute, v); 12796 n2.copy(n); 12797 const t = tan1[v]; 12798 tmp.copy(t); 12799 tmp.sub(n.multiplyScalar(n.dot(t))).normalize(); 12800 tmp2.crossVectors(n2, t); 12801 const test = tmp2.dot(tan2[v]); 12802 const w = test < 0 ? -1 : 1; 12803 tangentAttribute.setXYZW(v, tmp.x, tmp.y, tmp.z, w); 12804 } 12805 for (let i = 0, il = groups.length; i < il; ++i) { 12806 const group = groups[i]; 12807 const start = group.start; 12808 const count = group.count; 12809 for (let j = start, jl = start + count; j < jl; j += 3) { 12810 handleVertex(index.getX(j + 0)); 12811 handleVertex(index.getX(j + 1)); 12812 handleVertex(index.getX(j + 2)); 12813 } 12814 } 12815 } 12816 /** 12817 * Computes vertex normals for the given vertex data. For indexed geometries, the method sets 12818 * each vertex normal to be the average of the face normals of the faces that share that vertex. 12819 * For non-indexed geometries, vertices are not shared, and the method sets each vertex normal 12820 * to be the same as the face normal. 12821 */ 12822 computeVertexNormals() { 12823 const index = this.index; 12824 const positionAttribute = this.getAttribute("position"); 12825 if (positionAttribute !== void 0) { 12826 let normalAttribute = this.getAttribute("normal"); 12827 if (normalAttribute === void 0) { 12828 normalAttribute = new BufferAttribute(new Float32Array(positionAttribute.count * 3), 3); 12829 this.setAttribute("normal", normalAttribute); 12830 } else { 12831 for (let i = 0, il = normalAttribute.count; i < il; i++) { 12832 normalAttribute.setXYZ(i, 0, 0, 0); 12833 } 12834 } 12835 const pA = new Vector3(), pB = new Vector3(), pC = new Vector3(); 12836 const nA = new Vector3(), nB = new Vector3(), nC = new Vector3(); 12837 const cb = new Vector3(), ab = new Vector3(); 12838 if (index) { 12839 for (let i = 0, il = index.count; i < il; i += 3) { 12840 const vA = index.getX(i + 0); 12841 const vB = index.getX(i + 1); 12842 const vC = index.getX(i + 2); 12843 pA.fromBufferAttribute(positionAttribute, vA); 12844 pB.fromBufferAttribute(positionAttribute, vB); 12845 pC.fromBufferAttribute(positionAttribute, vC); 12846 cb.subVectors(pC, pB); 12847 ab.subVectors(pA, pB); 12848 cb.cross(ab); 12849 nA.fromBufferAttribute(normalAttribute, vA); 12850 nB.fromBufferAttribute(normalAttribute, vB); 12851 nC.fromBufferAttribute(normalAttribute, vC); 12852 nA.add(cb); 12853 nB.add(cb); 12854 nC.add(cb); 12855 normalAttribute.setXYZ(vA, nA.x, nA.y, nA.z); 12856 normalAttribute.setXYZ(vB, nB.x, nB.y, nB.z); 12857 normalAttribute.setXYZ(vC, nC.x, nC.y, nC.z); 12858 } 12859 } else { 12860 for (let i = 0, il = positionAttribute.count; i < il; i += 3) { 12861 pA.fromBufferAttribute(positionAttribute, i + 0); 12862 pB.fromBufferAttribute(positionAttribute, i + 1); 12863 pC.fromBufferAttribute(positionAttribute, i + 2); 12864 cb.subVectors(pC, pB); 12865 ab.subVectors(pA, pB); 12866 cb.cross(ab); 12867 normalAttribute.setXYZ(i + 0, cb.x, cb.y, cb.z); 12868 normalAttribute.setXYZ(i + 1, cb.x, cb.y, cb.z); 12869 normalAttribute.setXYZ(i + 2, cb.x, cb.y, cb.z); 12870 } 12871 } 12872 this.normalizeNormals(); 12873 normalAttribute.needsUpdate = true; 12874 } 12875 } 12876 /** 12877 * Ensures every normal vector in a geometry will have a magnitude of `1`. This will 12878 * correct lighting on the geometry surfaces. 12879 */ 12880 normalizeNormals() { 12881 const normals = this.attributes.normal; 12882 for (let i = 0, il = normals.count; i < il; i++) { 12883 _vector$9.fromBufferAttribute(normals, i); 12884 _vector$9.normalize(); 12885 normals.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); 12886 } 12887 } 12888 /** 12889 * Return a new non-index version of this indexed geometry. If the geometry 12890 * is already non-indexed, the method is a NOOP. 12891 * 12892 * @return {BufferGeometry} The non-indexed version of this indexed geometry. 12893 */ 12894 toNonIndexed() { 12895 function convertBufferAttribute(attribute, indices2) { 12896 const array = attribute.array; 12897 const itemSize = attribute.itemSize; 12898 const normalized = attribute.normalized; 12899 const array2 = new array.constructor(indices2.length * itemSize); 12900 let index = 0, index2 = 0; 12901 for (let i = 0, l = indices2.length; i < l; i++) { 12902 if (attribute.isInterleavedBufferAttribute) { 12903 index = indices2[i] * attribute.data.stride + attribute.offset; 12904 } else { 12905 index = indices2[i] * itemSize; 12906 } 12907 for (let j = 0; j < itemSize; j++) { 12908 array2[index2++] = array[index++]; 12909 } 12910 } 12911 return new BufferAttribute(array2, itemSize, normalized); 12912 } 12913 if (this.index === null) { 12914 warn("BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed."); 12915 return this; 12916 } 12917 const geometry2 = new _BufferGeometry(); 12918 const indices = this.index.array; 12919 const attributes = this.attributes; 12920 for (const name in attributes) { 12921 const attribute = attributes[name]; 12922 const newAttribute = convertBufferAttribute(attribute, indices); 12923 geometry2.setAttribute(name, newAttribute); 12924 } 12925 const morphAttributes = this.morphAttributes; 12926 for (const name in morphAttributes) { 12927 const morphArray = []; 12928 const morphAttribute = morphAttributes[name]; 12929 for (let i = 0, il = morphAttribute.length; i < il; i++) { 12930 const attribute = morphAttribute[i]; 12931 const newAttribute = convertBufferAttribute(attribute, indices); 12932 morphArray.push(newAttribute); 12933 } 12934 geometry2.morphAttributes[name] = morphArray; 12935 } 12936 geometry2.morphTargetsRelative = this.morphTargetsRelative; 12937 const groups = this.groups; 12938 for (let i = 0, l = groups.length; i < l; i++) { 12939 const group = groups[i]; 12940 geometry2.addGroup(group.start, group.count, group.materialIndex); 12941 } 12942 return geometry2; 12943 } 12944 /** 12945 * Serializes the geometry into JSON. 12946 * 12947 * @return {Object} A JSON object representing the serialized geometry. 12948 */ 12949 toJSON() { 12950 const data = { 12951 metadata: { 12952 version: 4.7, 12953 type: "BufferGeometry", 12954 generator: "BufferGeometry.toJSON" 12955 } 12956 }; 12957 data.uuid = this.uuid; 12958 data.type = this.type; 12959 if (this.name !== "") data.name = this.name; 12960 if (Object.keys(this.userData).length > 0) data.userData = this.userData; 12961 if (this.parameters !== void 0) { 12962 const parameters = this.parameters; 12963 for (const key in parameters) { 12964 if (parameters[key] !== void 0) data[key] = parameters[key]; 12965 } 12966 return data; 12967 } 12968 data.data = { attributes: {} }; 12969 const index = this.index; 12970 if (index !== null) { 12971 data.data.index = { 12972 type: index.array.constructor.name, 12973 array: Array.prototype.slice.call(index.array) 12974 }; 12975 } 12976 const attributes = this.attributes; 12977 for (const key in attributes) { 12978 const attribute = attributes[key]; 12979 data.data.attributes[key] = attribute.toJSON(data.data); 12980 } 12981 const morphAttributes = {}; 12982 let hasMorphAttributes = false; 12983 for (const key in this.morphAttributes) { 12984 const attributeArray = this.morphAttributes[key]; 12985 const array = []; 12986 for (let i = 0, il = attributeArray.length; i < il; i++) { 12987 const attribute = attributeArray[i]; 12988 array.push(attribute.toJSON(data.data)); 12989 } 12990 if (array.length > 0) { 12991 morphAttributes[key] = array; 12992 hasMorphAttributes = true; 12993 } 12994 } 12995 if (hasMorphAttributes) { 12996 data.data.morphAttributes = morphAttributes; 12997 data.data.morphTargetsRelative = this.morphTargetsRelative; 12998 } 12999 const groups = this.groups; 13000 if (groups.length > 0) { 13001 data.data.groups = JSON.parse(JSON.stringify(groups)); 13002 } 13003 const boundingSphere = this.boundingSphere; 13004 if (boundingSphere !== null) { 13005 data.data.boundingSphere = boundingSphere.toJSON(); 13006 } 13007 return data; 13008 } 13009 /** 13010 * Returns a new geometry with copied values from this instance. 13011 * 13012 * @return {BufferGeometry} A clone of this instance. 13013 */ 13014 clone() { 13015 return new this.constructor().copy(this); 13016 } 13017 /** 13018 * Copies the values of the given geometry to this instance. 13019 * 13020 * @param {BufferGeometry} source - The geometry to copy. 13021 * @return {BufferGeometry} A reference to this instance. 13022 */ 13023 copy(source) { 13024 this.index = null; 13025 this.attributes = {}; 13026 this.morphAttributes = {}; 13027 this.groups = []; 13028 this.boundingBox = null; 13029 this.boundingSphere = null; 13030 const data = {}; 13031 this.name = source.name; 13032 const index = source.index; 13033 if (index !== null) { 13034 this.setIndex(index.clone()); 13035 } 13036 const attributes = source.attributes; 13037 for (const name in attributes) { 13038 const attribute = attributes[name]; 13039 this.setAttribute(name, attribute.clone(data)); 13040 } 13041 const morphAttributes = source.morphAttributes; 13042 for (const name in morphAttributes) { 13043 const array = []; 13044 const morphAttribute = morphAttributes[name]; 13045 for (let i = 0, l = morphAttribute.length; i < l; i++) { 13046 array.push(morphAttribute[i].clone(data)); 13047 } 13048 this.morphAttributes[name] = array; 13049 } 13050 this.morphTargetsRelative = source.morphTargetsRelative; 13051 const groups = source.groups; 13052 for (let i = 0, l = groups.length; i < l; i++) { 13053 const group = groups[i]; 13054 this.addGroup(group.start, group.count, group.materialIndex); 13055 } 13056 const boundingBox = source.boundingBox; 13057 if (boundingBox !== null) { 13058 this.boundingBox = boundingBox.clone(); 13059 } 13060 const boundingSphere = source.boundingSphere; 13061 if (boundingSphere !== null) { 13062 this.boundingSphere = boundingSphere.clone(); 13063 } 13064 this.drawRange.start = source.drawRange.start; 13065 this.drawRange.count = source.drawRange.count; 13066 this.userData = source.userData; 13067 return this; 13068 } 13069 /** 13070 * Frees the GPU-related resources allocated by this instance. Call this 13071 * method whenever this instance is no longer used in your app. 13072 * 13073 * @fires BufferGeometry#dispose 13074 */ 13075 dispose() { 13076 this.dispatchEvent({ type: "dispose" }); 13077 } 13078}; 13079var InterleavedBuffer = class { 13080 /** 13081 * Constructs a new interleaved buffer. 13082 * 13083 * @param {TypedArray} array - A typed array with a shared buffer storing attribute data. 13084 * @param {number} stride - The number of typed-array elements per vertex. 13085 */ 13086 constructor(array, stride) { 13087 this.isInterleavedBuffer = true; 13088 this.array = array; 13089 this.stride = stride; 13090 this.count = array !== void 0 ? array.length / stride : 0; 13091 this.usage = StaticDrawUsage; 13092 this.updateRanges = []; 13093 this.version = 0; 13094 this.uuid = generateUUID(); 13095 } 13096 /** 13097 * A callback function that is executed after the renderer has transferred the attribute array 13098 * data to the GPU. 13099 */ 13100 onUploadCallback() { 13101 } 13102 /** 13103 * Flag to indicate that this attribute has changed and should be re-sent to 13104 * the GPU. Set this to `true` when you modify the value of the array. 13105 * 13106 * @type {number} 13107 * @default false 13108 * @param {boolean} value 13109 */ 13110 set needsUpdate(value) { 13111 if (value === true) this.version++; 13112 } 13113 /** 13114 * Sets the usage of this interleaved buffer. 13115 * 13116 * @param {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} value - The usage to set. 13117 * @return {InterleavedBuffer} A reference to this interleaved buffer. 13118 */ 13119 setUsage(value) { 13120 this.usage = value; 13121 return this; 13122 } 13123 /** 13124 * Adds a range of data in the data array to be updated on the GPU. 13125 * 13126 * @param {number} start - Position at which to start update. 13127 * @param {number} count - The number of components to update. 13128 */ 13129 addUpdateRange(start, count) { 13130 this.updateRanges.push({ start, count }); 13131 } 13132 /** 13133 * Clears the update ranges. 13134 */ 13135 clearUpdateRanges() { 13136 this.updateRanges.length = 0; 13137 } 13138 /** 13139 * Copies the values of the given interleaved buffer to this instance. 13140 * 13141 * @param {InterleavedBuffer} source - The interleaved buffer to copy. 13142 * @return {InterleavedBuffer} A reference to this instance. 13143 */ 13144 copy(source) { 13145 this.array = new source.array.constructor(source.array); 13146 this.count = source.count; 13147 this.stride = source.stride; 13148 this.usage = source.usage; 13149 return this; 13150 } 13151 /** 13152 * Copies a vector from the given interleaved buffer to this one. The start 13153 * and destination position in the attribute buffers are represented by the 13154 * given indices. 13155 * 13156 * @param {number} index1 - The destination index into this interleaved buffer. 13157 * @param {InterleavedBuffer} interleavedBuffer - The interleaved buffer to copy from. 13158 * @param {number} index2 - The source index into the given interleaved buffer. 13159 * @return {InterleavedBuffer} A reference to this instance. 13160 */ 13161 copyAt(index1, interleavedBuffer, index2) { 13162 index1 *= this.stride; 13163 index2 *= interleavedBuffer.stride; 13164 for (let i = 0, l = this.stride; i < l; i++) { 13165 this.array[index1 + i] = interleavedBuffer.array[index2 + i]; 13166 } 13167 return this; 13168 } 13169 /** 13170 * Sets the given array data in the interleaved buffer. 13171 * 13172 * @param {(TypedArray|Array)} value - The array data to set. 13173 * @param {number} [offset=0] - The offset in this interleaved buffer's array. 13174 * @return {InterleavedBuffer} A reference to this instance. 13175 */ 13176 set(value, offset = 0) { 13177 this.array.set(value, offset); 13178 return this; 13179 } 13180 /** 13181 * Returns a new interleaved buffer with copied values from this instance. 13182 * 13183 * @param {Object} [data] - An object with shared array buffers that allows to retain shared structures. 13184 * @return {InterleavedBuffer} A clone of this instance. 13185 */ 13186 clone(data) { 13187 if (data.arrayBuffers === void 0) { 13188 data.arrayBuffers = {}; 13189 } 13190 if (this.array.buffer._uuid === void 0) { 13191 this.array.buffer._uuid = generateUUID(); 13192 } 13193 if (data.arrayBuffers[this.array.buffer._uuid] === void 0) { 13194 data.arrayBuffers[this.array.buffer._uuid] = this.array.slice(0).buffer; 13195 } 13196 const array = new this.array.constructor(data.arrayBuffers[this.array.buffer._uuid]); 13197 const ib = new this.constructor(array, this.stride); 13198 ib.setUsage(this.usage); 13199 return ib; 13200 } 13201 /** 13202 * Sets the given callback function that is executed after the Renderer has transferred 13203 * the array data to the GPU. Can be used to perform clean-up operations after 13204 * the upload when data are not needed anymore on the CPU side. 13205 * 13206 * @param {Function} callback - The `onUpload()` callback. 13207 * @return {InterleavedBuffer} A reference to this instance. 13208 */ 13209 onUpload(callback) { 13210 this.onUploadCallback = callback; 13211 return this; 13212 } 13213 /** 13214 * Serializes the interleaved buffer into JSON. 13215 * 13216 * @param {Object} [data] - An optional value holding meta information about the serialization. 13217 * @return {Object} A JSON object representing the serialized interleaved buffer. 13218 */ 13219 toJSON(data) { 13220 if (data.arrayBuffers === void 0) { 13221 data.arrayBuffers = {}; 13222 } 13223 if (this.array.buffer._uuid === void 0) { 13224 this.array.buffer._uuid = generateUUID(); 13225 } 13226 if (data.arrayBuffers[this.array.buffer._uuid] === void 0) { 13227 data.arrayBuffers[this.array.buffer._uuid] = Array.from(new Uint32Array(this.array.buffer)); 13228 } 13229 return { 13230 uuid: this.uuid, 13231 buffer: this.array.buffer._uuid, 13232 type: this.array.constructor.name, 13233 stride: this.stride 13234 }; 13235 } 13236}; 13237var _vector$8 = /* @__PURE__ */ new Vector3(); 13238var InterleavedBufferAttribute = class _InterleavedBufferAttribute { 13239 /** 13240 * Constructs a new interleaved buffer attribute. 13241 * 13242 * @param {InterleavedBuffer} interleavedBuffer - The buffer holding the interleaved data. 13243 * @param {number} itemSize - The item size. 13244 * @param {number} offset - The attribute offset into the buffer. 13245 * @param {boolean} [normalized=false] - Whether the data are normalized or not. 13246 */ 13247 constructor(interleavedBuffer, itemSize, offset, normalized = false) { 13248 this.isInterleavedBufferAttribute = true; 13249 this.name = ""; 13250 this.data = interleavedBuffer; 13251 this.itemSize = itemSize; 13252 this.offset = offset; 13253 this.normalized = normalized; 13254 } 13255 /** 13256 * The item count of this buffer attribute. 13257 * 13258 * @type {number} 13259 * @readonly 13260 */ 13261 get count() { 13262 return this.data.count; 13263 } 13264 /** 13265 * The array holding the interleaved buffer attribute data. 13266 * 13267 * @type {TypedArray} 13268 */ 13269 get array() { 13270 return this.data.array; 13271 } 13272 /** 13273 * Flag to indicate that this attribute has changed and should be re-sent to 13274 * the GPU. Set this to `true` when you modify the value of the array. 13275 * 13276 * @type {number} 13277 * @default false 13278 * @param {boolean} value 13279 */ 13280 set needsUpdate(value) { 13281 this.data.needsUpdate = value; 13282 } 13283 /** 13284 * Applies the given 4x4 matrix to the given attribute. Only works with 13285 * item size `3`. 13286 * 13287 * @param {Matrix4} m - The matrix to apply. 13288 * @return {InterleavedBufferAttribute} A reference to this instance. 13289 */ 13290 applyMatrix4(m) { 13291 for (let i = 0, l = this.data.count; i < l; i++) { 13292 _vector$8.fromBufferAttribute(this, i); 13293 _vector$8.applyMatrix4(m); 13294 this.setXYZ(i, _vector$8.x, _vector$8.y, _vector$8.z); 13295 } 13296 return this; 13297 } 13298 /** 13299 * Applies the given 3x3 normal matrix to the given attribute. Only works with 13300 * item size `3`. 13301 * 13302 * @param {Matrix3} m - The normal matrix to apply. 13303 * @return {InterleavedBufferAttribute} A reference to this instance. 13304 */ 13305 applyNormalMatrix(m) { 13306 for (let i = 0, l = this.count; i < l; i++) { 13307 _vector$8.fromBufferAttribute(this, i); 13308 _vector$8.applyNormalMatrix(m); 13309 this.setXYZ(i, _vector$8.x, _vector$8.y, _vector$8.z); 13310 } 13311 return this; 13312 } 13313 /** 13314 * Applies the given 4x4 matrix to the given attribute. Only works with 13315 * item size `3` and with direction vectors. 13316 * 13317 * @param {Matrix4} m - The matrix to apply. 13318 * @return {InterleavedBufferAttribute} A reference to this instance. 13319 */ 13320 transformDirection(m) { 13321 for (let i = 0, l = this.count; i < l; i++) { 13322 _vector$8.fromBufferAttribute(this, i); 13323 _vector$8.transformDirection(m); 13324 this.setXYZ(i, _vector$8.x, _vector$8.y, _vector$8.z); 13325 } 13326 return this; 13327 } 13328 /** 13329 * Returns the given component of the vector at the given index. 13330 * 13331 * @param {number} index - The index into the buffer attribute. 13332 * @param {number} component - The component index. 13333 * @return {number} The returned value. 13334 */ 13335 getComponent(index, component) { 13336 let value = this.array[index * this.data.stride + this.offset + component]; 13337 if (this.normalized) value = denormalize(value, this.array); 13338 return value; 13339 } 13340 /** 13341 * Sets the given value to the given component of the vector at the given index. 13342 * 13343 * @param {number} index - The index into the buffer attribute. 13344 * @param {number} component - The component index. 13345 * @param {number} value - The value to set. 13346 * @return {InterleavedBufferAttribute} A reference to this instance. 13347 */ 13348 setComponent(index, component, value) { 13349 if (this.normalized) value = normalize(value, this.array); 13350 this.data.array[index * this.data.stride + this.offset + component] = value; 13351 return this; 13352 } 13353 /** 13354 * Sets the x component of the vector at the given index. 13355 * 13356 * @param {number} index - The index into the buffer attribute. 13357 * @param {number} x - The value to set. 13358 * @return {InterleavedBufferAttribute} A reference to this instance. 13359 */ 13360 setX(index, x) { 13361 if (this.normalized) x = normalize(x, this.array); 13362 this.data.array[index * this.data.stride + this.offset] = x; 13363 return this; 13364 } 13365 /** 13366 * Sets the y component of the vector at the given index. 13367 * 13368 * @param {number} index - The index into the buffer attribute. 13369 * @param {number} y - The value to set. 13370 * @return {InterleavedBufferAttribute} A reference to this instance. 13371 */ 13372 setY(index, y) { 13373 if (this.normalized) y = normalize(y, this.array); 13374 this.data.array[index * this.data.stride + this.offset + 1] = y; 13375 return this; 13376 } 13377 /** 13378 * Sets the z component of the vector at the given index. 13379 * 13380 * @param {number} index - The index into the buffer attribute. 13381 * @param {number} z - The value to set. 13382 * @return {InterleavedBufferAttribute} A reference to this instance. 13383 */ 13384 setZ(index, z) { 13385 if (this.normalized) z = normalize(z, this.array); 13386 this.data.array[index * this.data.stride + this.offset + 2] = z; 13387 return this; 13388 } 13389 /** 13390 * Sets the w component of the vector at the given index. 13391 * 13392 * @param {number} index - The index into the buffer attribute. 13393 * @param {number} w - The value to set. 13394 * @return {InterleavedBufferAttribute} A reference to this instance. 13395 */ 13396 setW(index, w) { 13397 if (this.normalized) w = normalize(w, this.array); 13398 this.data.array[index * this.data.stride + this.offset + 3] = w; 13399 return this; 13400 } 13401 /** 13402 * Returns the x component of the vector at the given index. 13403 * 13404 * @param {number} index - The index into the buffer attribute. 13405 * @return {number} The x component. 13406 */ 13407 getX(index) { 13408 let x = this.data.array[index * this.data.stride + this.offset]; 13409 if (this.normalized) x = denormalize(x, this.array); 13410 return x; 13411 } 13412 /** 13413 * Returns the y component of the vector at the given index. 13414 * 13415 * @param {number} index - The index into the buffer attribute. 13416 * @return {number} The y component. 13417 */ 13418 getY(index) { 13419 let y = this.data.array[index * this.data.stride + this.offset + 1]; 13420 if (this.normalized) y = denormalize(y, this.array); 13421 return y; 13422 } 13423 /** 13424 * Returns the z component of the vector at the given index. 13425 * 13426 * @param {number} index - The index into the buffer attribute. 13427 * @return {number} The z component. 13428 */ 13429 getZ(index) { 13430 let z = this.data.array[index * this.data.stride + this.offset + 2]; 13431 if (this.normalized) z = denormalize(z, this.array); 13432 return z; 13433 } 13434 /** 13435 * Returns the w component of the vector at the given index. 13436 * 13437 * @param {number} index - The index into the buffer attribute. 13438 * @return {number} The w component. 13439 */ 13440 getW(index) { 13441 let w = this.data.array[index * this.data.stride + this.offset + 3]; 13442 if (this.normalized) w = denormalize(w, this.array); 13443 return w; 13444 } 13445 /** 13446 * Sets the x and y component of the vector at the given index. 13447 * 13448 * @param {number} index - The index into the buffer attribute. 13449 * @param {number} x - The value for the x component to set. 13450 * @param {number} y - The value for the y component to set. 13451 * @return {InterleavedBufferAttribute} A reference to this instance. 13452 */ 13453 setXY(index, x, y) { 13454 index = index * this.data.stride + this.offset; 13455 if (this.normalized) { 13456 x = normalize(x, this.array); 13457 y = normalize(y, this.array); 13458 } 13459 this.data.array[index + 0] = x; 13460 this.data.array[index + 1] = y; 13461 return this; 13462 } 13463 /** 13464 * Sets the x, y and z component of the vector at the given index. 13465 * 13466 * @param {number} index - The index into the buffer attribute. 13467 * @param {number} x - The value for the x component to set. 13468 * @param {number} y - The value for the y component to set. 13469 * @param {number} z - The value for the z component to set. 13470 * @return {InterleavedBufferAttribute} A reference to this instance. 13471 */ 13472 setXYZ(index, x, y, z) { 13473 index = index * this.data.stride + this.offset; 13474 if (this.normalized) { 13475 x = normalize(x, this.array); 13476 y = normalize(y, this.array); 13477 z = normalize(z, this.array); 13478 } 13479 this.data.array[index + 0] = x; 13480 this.data.array[index + 1] = y; 13481 this.data.array[index + 2] = z; 13482 return this; 13483 } 13484 /** 13485 * Sets the x, y, z and w component of the vector at the given index. 13486 * 13487 * @param {number} index - The index into the buffer attribute. 13488 * @param {number} x - The value for the x component to set. 13489 * @param {number} y - The value for the y component to set. 13490 * @param {number} z - The value for the z component to set. 13491 * @param {number} w - The value for the w component to set. 13492 * @return {InterleavedBufferAttribute} A reference to this instance. 13493 */ 13494 setXYZW(index, x, y, z, w) { 13495 index = index * this.data.stride + this.offset; 13496 if (this.normalized) { 13497 x = normalize(x, this.array); 13498 y = normalize(y, this.array); 13499 z = normalize(z, this.array); 13500 w = normalize(w, this.array); 13501 } 13502 this.data.array[index + 0] = x; 13503 this.data.array[index + 1] = y; 13504 this.data.array[index + 2] = z; 13505 this.data.array[index + 3] = w; 13506 return this; 13507 } 13508 /** 13509 * Returns a new buffer attribute with copied values from this instance. 13510 * 13511 * If no parameter is provided, cloning an interleaved buffer attribute will de-interleave buffer data. 13512 * 13513 * @param {Object} [data] - An object with interleaved buffers that allows to retain the interleaved property. 13514 * @return {BufferAttribute|InterleavedBufferAttribute} A clone of this instance. 13515 */ 13516 clone(data) { 13517 if (data === void 0) { 13518 log("InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data."); 13519 const array = []; 13520 for (let i = 0; i < this.count; i++) { 13521 const index = i * this.data.stride + this.offset; 13522 for (let j = 0; j < this.itemSize; j++) { 13523 array.push(this.data.array[index + j]); 13524 } 13525 } 13526 return new BufferAttribute(new this.array.constructor(array), this.itemSize, this.normalized); 13527 } else { 13528 if (data.interleavedBuffers === void 0) { 13529 data.interleavedBuffers = {}; 13530 } 13531 if (data.interleavedBuffers[this.data.uuid] === void 0) { 13532 data.interleavedBuffers[this.data.uuid] = this.data.clone(data); 13533 } 13534 return new _InterleavedBufferAttribute(data.interleavedBuffers[this.data.uuid], this.itemSize, this.offset, this.normalized); 13535 } 13536 } 13537 /** 13538 * Serializes the buffer attribute into JSON. 13539 * 13540 * If no parameter is provided, cloning an interleaved buffer attribute will de-interleave buffer data. 13541 * 13542 * @param {Object} [data] - An optional value holding meta information about the serialization. 13543 * @return {Object} A JSON object representing the serialized buffer attribute. 13544 */ 13545 toJSON(data) { 13546 if (data === void 0) { 13547 log("InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data."); 13548 const array = []; 13549 for (let i = 0; i < this.count; i++) { 13550 const index = i * this.data.stride + this.offset; 13551 for (let j = 0; j < this.itemSize; j++) { 13552 array.push(this.data.array[index + j]); 13553 } 13554 } 13555 return { 13556 itemSize: this.itemSize, 13557 type: this.array.constructor.name, 13558 array, 13559 normalized: this.normalized 13560 }; 13561 } else { 13562 if (data.interleavedBuffers === void 0) { 13563 data.interleavedBuffers = {}; 13564 } 13565 if (data.interleavedBuffers[this.data.uuid] === void 0) { 13566 data.interleavedBuffers[this.data.uuid] = this.data.toJSON(data); 13567 } 13568 return { 13569 isInterleavedBufferAttribute: true, 13570 itemSize: this.itemSize, 13571 data: this.data.uuid, 13572 offset: this.offset, 13573 normalized: this.normalized 13574 }; 13575 } 13576 } 13577}; 13578var _materialId = 0; 13579var Material = class extends EventDispatcher { 13580 /** 13581 * Constructs a new material. 13582 */ 13583 constructor() { 13584 super(); 13585 this.isMaterial = true; 13586 Object.defineProperty(this, "id", { value: _materialId++ }); 13587 this.uuid = generateUUID(); 13588 this.name = ""; 13589 this.type = "Material"; 13590 this.blending = NormalBlending; 13591 this.side = FrontSide; 13592 this.vertexColors = false; 13593 this.opacity = 1; 13594 this.transparent = false; 13595 this.alphaHash = false; 13596 this.blendSrc = SrcAlphaFactor; 13597 this.blendDst = OneMinusSrcAlphaFactor; 13598 this.blendEquation = AddEquation; 13599 this.blendSrcAlpha = null; 13600 this.blendDstAlpha = null; 13601 this.blendEquationAlpha = null; 13602 this.blendColor = new Color(0, 0, 0); 13603 this.blendAlpha = 0; 13604 this.depthFunc = LessEqualDepth; 13605 this.depthTest = true; 13606 this.depthWrite = true; 13607 this.stencilWriteMask = 255; 13608 this.stencilFunc = AlwaysStencilFunc; 13609 this.stencilRef = 0; 13610 this.stencilFuncMask = 255; 13611 this.stencilFail = KeepStencilOp; 13612 this.stencilZFail = KeepStencilOp; 13613 this.stencilZPass = KeepStencilOp; 13614 this.stencilWrite = false; 13615 this.clippingPlanes = null; 13616 this.clipIntersection = false; 13617 this.clipShadows = false; 13618 this.shadowSide = null; 13619 this.colorWrite = true; 13620 this.precision = null; 13621 this.polygonOffset = false; 13622 this.polygonOffsetFactor = 0; 13623 this.polygonOffsetUnits = 0; 13624 this.dithering = false; 13625 this.alphaToCoverage = false; 13626 this.premultipliedAlpha = false; 13627 this.forceSinglePass = false; 13628 this.allowOverride = true; 13629 this.visible = true; 13630 this.toneMapped = true; 13631 this.userData = {}; 13632 this.version = 0; 13633 this._alphaTest = 0; 13634 } 13635 /** 13636 * Sets the alpha value to be used when running an alpha test. The material 13637 * will not be rendered if the opacity is lower than this value. 13638 * 13639 * @type {number} 13640 * @readonly 13641 * @default 0 13642 */ 13643 get alphaTest() { 13644 return this._alphaTest; 13645 } 13646 set alphaTest(value) { 13647 if (this._alphaTest > 0 !== value > 0) { 13648 this.version++; 13649 } 13650 this._alphaTest = value; 13651 } 13652 /** 13653 * An optional callback that is executed immediately before the material is used to render a 3D object. 13654 * 13655 * This method can only be used when rendering with {@link WebGLRenderer}. 13656 * 13657 * @param {WebGLRenderer} renderer - The renderer. 13658 * @param {Scene} scene - The scene. 13659 * @param {Camera} camera - The camera that is used to render the scene. 13660 * @param {BufferGeometry} geometry - The 3D object's geometry. 13661 * @param {Object3D} object - The 3D object. 13662 * @param {Object} group - The geometry group data. 13663 */ 13664 onBeforeRender() { 13665 } 13666 /** 13667 * An optional callback that is executed immediately before the shader 13668 * program is compiled. This function is called with the shader source code 13669 * as a parameter. Useful for the modification of built-in materials. 13670 * 13671 * This method can only be used when rendering with {@link WebGLRenderer}. The 13672 * recommended approach when customizing materials is to use `WebGPURenderer` with the new 13673 * Node Material system and [TSL](https://github.com/mrdoob/three.js/wiki/Three.js-Shading-Language). 13674 * 13675 * @param {{vertexShader:string,fragmentShader:string,uniforms:Object}} shaderobject - The object holds the uniforms and the vertex and fragment shader source. 13676 * @param {WebGLRenderer} renderer - A reference to the renderer. 13677 */ 13678 onBeforeCompile() { 13679 } 13680 /** 13681 * In case {@link Material#onBeforeCompile} is used, this callback can be used to identify 13682 * values of settings used in `onBeforeCompile()`, so three.js can reuse a cached 13683 * shader or recompile the shader for this material as needed. 13684 * 13685 * This method can only be used when rendering with {@link WebGLRenderer}. 13686 * 13687 * @return {string} The custom program cache key. 13688 */ 13689 customProgramCacheKey() { 13690 return this.onBeforeCompile.toString(); 13691 } 13692 /** 13693 * This method can be used to set default values from parameter objects. 13694 * It is a generic implementation so it can be used with different types 13695 * of materials. 13696 * 13697 * @param {Object} [values] - The material values to set. 13698 */ 13699 setValues(values) { 13700 if (values === void 0) return; 13701 for (const key in values) { 13702 const newValue = values[key]; 13703 if (newValue === void 0) { 13704 warn(`Material: parameter '${key}' has value of undefined.`); 13705 continue; 13706 } 13707 const currentValue = this[key]; 13708 if (currentValue === void 0) { 13709 warn(`Material: '${key}' is not a property of THREE.${this.type}.`); 13710 continue; 13711 } 13712 if (currentValue && currentValue.isColor) { 13713 currentValue.set(newValue); 13714 } else if (currentValue && currentValue.isVector3 && (newValue && newValue.isVector3)) { 13715 currentValue.copy(newValue); 13716 } else { 13717 this[key] = newValue; 13718 } 13719 } 13720 } 13721 /** 13722 * Serializes the material into JSON. 13723 * 13724 * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. 13725 * @return {Object} A JSON object representing the serialized material. 13726 * @see {@link ObjectLoader#parse} 13727 */ 13728 toJSON(meta) { 13729 const isRootObject = meta === void 0 || typeof meta === "string"; 13730 if (isRootObject) { 13731 meta = { 13732 textures: {}, 13733 images: {} 13734 }; 13735 } 13736 const data = { 13737 metadata: { 13738 version: 4.7, 13739 type: "Material", 13740 generator: "Material.toJSON" 13741 } 13742 }; 13743 data.uuid = this.uuid; 13744 data.type = this.type; 13745 if (this.name !== "") data.name = this.name; 13746 if (this.color && this.color.isColor) data.color = this.color.getHex(); 13747 if (this.roughness !== void 0) data.roughness = this.roughness; 13748 if (this.metalness !== void 0) data.metalness = this.metalness; 13749 if (this.sheen !== void 0) data.sheen = this.sheen; 13750 if (this.sheenColor && this.sheenColor.isColor) data.sheenColor = this.sheenColor.getHex(); 13751 if (this.sheenRoughness !== void 0) data.sheenRoughness = this.sheenRoughness; 13752 if (this.emissive && this.emissive.isColor) data.emissive = this.emissive.getHex(); 13753 if (this.emissiveIntensity !== void 0 && this.emissiveIntensity !== 1) data.emissiveIntensity = this.emissiveIntensity; 13754 if (this.specular && this.specular.isColor) data.specular = this.specular.getHex(); 13755 if (this.specularIntensity !== void 0) data.specularIntensity = this.specularIntensity; 13756 if (this.specularColor && this.specularColor.isColor) data.specularColor = this.specularColor.getHex(); 13757 if (this.shininess !== void 0) data.shininess = this.shininess; 13758 if (this.clearcoat !== void 0) data.clearcoat = this.clearcoat; 13759 if (this.clearcoatRoughness !== void 0) data.clearcoatRoughness = this.clearcoatRoughness; 13760 if (this.clearcoatMap && this.clearcoatMap.isTexture) { 13761 data.clearcoatMap = this.clearcoatMap.toJSON(meta).uuid; 13762 } 13763 if (this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture) { 13764 data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON(meta).uuid; 13765 } 13766 if (this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture) { 13767 data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON(meta).uuid; 13768 data.clearcoatNormalScale = this.clearcoatNormalScale.toArray(); 13769 } 13770 if (this.sheenColorMap && this.sheenColorMap.isTexture) { 13771 data.sheenColorMap = this.sheenColorMap.toJSON(meta).uuid; 13772 } 13773 if (this.sheenRoughnessMap && this.sheenRoughnessMap.isTexture) { 13774 data.sheenRoughnessMap = this.sheenRoughnessMap.toJSON(meta).uuid; 13775 } 13776 if (this.dispersion !== void 0) data.dispersion = this.dispersion; 13777 if (this.iridescence !== void 0) data.iridescence = this.iridescence; 13778 if (this.iridescenceIOR !== void 0) data.iridescenceIOR = this.iridescenceIOR; 13779 if (this.iridescenceThicknessRange !== void 0) data.iridescenceThicknessRange = this.iridescenceThicknessRange; 13780 if (this.iridescenceMap && this.iridescenceMap.isTexture) { 13781 data.iridescenceMap = this.iridescenceMap.toJSON(meta).uuid; 13782 } 13783 if (this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture) { 13784 data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON(meta).uuid; 13785 } 13786 if (this.anisotropy !== void 0) data.anisotropy = this.anisotropy; 13787 if (this.anisotropyRotation !== void 0) data.anisotropyRotation = this.anisotropyRotation; 13788 if (this.anisotropyMap && this.anisotropyMap.isTexture) { 13789 data.anisotropyMap = this.anisotropyMap.toJSON(meta).uuid; 13790 } 13791 if (this.map && this.map.isTexture) data.map = this.map.toJSON(meta).uuid; 13792 if (this.matcap && this.matcap.isTexture) data.matcap = this.matcap.toJSON(meta).uuid; 13793 if (this.alphaMap && this.alphaMap.isTexture) data.alphaMap = this.alphaMap.toJSON(meta).uuid; 13794 if (this.lightMap && this.lightMap.isTexture) { 13795 data.lightMap = this.lightMap.toJSON(meta).uuid; 13796 data.lightMapIntensity = this.lightMapIntensity; 13797 } 13798 if (this.aoMap && this.aoMap.isTexture) { 13799 data.aoMap = this.aoMap.toJSON(meta).uuid; 13800 data.aoMapIntensity = this.aoMapIntensity; 13801 } 13802 if (this.bumpMap && this.bumpMap.isTexture) { 13803 data.bumpMap = this.bumpMap.toJSON(meta).uuid; 13804 data.bumpScale = this.bumpScale; 13805 } 13806 if (this.normalMap && this.normalMap.isTexture) { 13807 data.normalMap = this.normalMap.toJSON(meta).uuid; 13808 data.normalMapType = this.normalMapType; 13809 data.normalScale = this.normalScale.toArray(); 13810 } 13811 if (this.displacementMap && this.displacementMap.isTexture) { 13812 data.displacementMap = this.displacementMap.toJSON(meta).uuid; 13813 data.displacementScale = this.displacementScale; 13814 data.displacementBias = this.displacementBias; 13815 } 13816 if (this.roughnessMap && this.roughnessMap.isTexture) data.roughnessMap = this.roughnessMap.toJSON(meta).uuid; 13817 if (this.metalnessMap && this.metalnessMap.isTexture) data.metalnessMap = this.metalnessMap.toJSON(meta).uuid; 13818 if (this.emissiveMap && this.emissiveMap.isTexture) data.emissiveMap = this.emissiveMap.toJSON(meta).uuid; 13819 if (this.specularMap && this.specularMap.isTexture) data.specularMap = this.specularMap.toJSON(meta).uuid; 13820 if (this.specularIntensityMap && this.specularIntensityMap.isTexture) data.specularIntensityMap = this.specularIntensityMap.toJSON(meta).uuid; 13821 if (this.specularColorMap && this.specularColorMap.isTexture) data.specularColorMap = this.specularColorMap.toJSON(meta).uuid; 13822 if (this.envMap && this.envMap.isTexture) { 13823 data.envMap = this.envMap.toJSON(meta).uuid; 13824 if (this.combine !== void 0) data.combine = this.combine; 13825 } 13826 if (this.envMapRotation !== void 0) data.envMapRotation = this.envMapRotation.toArray(); 13827 if (this.envMapIntensity !== void 0) data.envMapIntensity = this.envMapIntensity; 13828 if (this.reflectivity !== void 0) data.reflectivity = this.reflectivity; 13829 if (this.refractionRatio !== void 0) data.refractionRatio = this.refractionRatio; 13830 if (this.gradientMap && this.gradientMap.isTexture) { 13831 data.gradientMap = this.gradientMap.toJSON(meta).uuid; 13832 } 13833 if (this.transmission !== void 0) data.transmission = this.transmission; 13834 if (this.transmissionMap && this.transmissionMap.isTexture) data.transmissionMap = this.transmissionMap.toJSON(meta).uuid; 13835 if (this.thickness !== void 0) data.thickness = this.thickness; 13836 if (this.thicknessMap && this.thicknessMap.isTexture) data.thicknessMap = this.thicknessMap.toJSON(meta).uuid; 13837 if (this.attenuationDistance !== void 0 && this.attenuationDistance !== Infinity) data.attenuationDistance = this.attenuationDistance; 13838 if (this.attenuationColor !== void 0) data.attenuationColor = this.attenuationColor.getHex(); 13839 if (this.size !== void 0) data.size = this.size; 13840 if (this.shadowSide !== null) data.shadowSide = this.shadowSide; 13841 if (this.sizeAttenuation !== void 0) data.sizeAttenuation = this.sizeAttenuation; 13842 if (this.blending !== NormalBlending) data.blending = this.blending; 13843 if (this.side !== FrontSide) data.side = this.side; 13844 if (this.vertexColors === true) data.vertexColors = true; 13845 if (this.opacity < 1) data.opacity = this.opacity; 13846 if (this.transparent === true) data.transparent = true; 13847 if (this.blendSrc !== SrcAlphaFactor) data.blendSrc = this.blendSrc; 13848 if (this.blendDst !== OneMinusSrcAlphaFactor) data.blendDst = this.blendDst; 13849 if (this.blendEquation !== AddEquation) data.blendEquation = this.blendEquation; 13850 if (this.blendSrcAlpha !== null) data.blendSrcAlpha = this.blendSrcAlpha; 13851 if (this.blendDstAlpha !== null) data.blendDstAlpha = this.blendDstAlpha; 13852 if (this.blendEquationAlpha !== null) data.blendEquationAlpha = this.blendEquationAlpha; 13853 if (this.blendColor && this.blendColor.isColor) data.blendColor = this.blendColor.getHex(); 13854 if (this.blendAlpha !== 0) data.blendAlpha = this.blendAlpha; 13855 if (this.depthFunc !== LessEqualDepth) data.depthFunc = this.depthFunc; 13856 if (this.depthTest === false) data.depthTest = this.depthTest; 13857 if (this.depthWrite === false) data.depthWrite = this.depthWrite; 13858 if (this.colorWrite === false) data.colorWrite = this.colorWrite; 13859 if (this.stencilWriteMask !== 255) data.stencilWriteMask = this.stencilWriteMask; 13860 if (this.stencilFunc !== AlwaysStencilFunc) data.stencilFunc = this.stencilFunc; 13861 if (this.stencilRef !== 0) data.stencilRef = this.stencilRef; 13862 if (this.stencilFuncMask !== 255) data.stencilFuncMask = this.stencilFuncMask; 13863 if (this.stencilFail !== KeepStencilOp) data.stencilFail = this.stencilFail; 13864 if (this.stencilZFail !== KeepStencilOp) data.stencilZFail = this.stencilZFail; 13865 if (this.stencilZPass !== KeepStencilOp) data.stencilZPass = this.stencilZPass; 13866 if (this.stencilWrite === true) data.stencilWrite = this.stencilWrite; 13867 if (this.rotation !== void 0 && this.rotation !== 0) data.rotation = this.rotation; 13868 if (this.polygonOffset === true) data.polygonOffset = true; 13869 if (this.polygonOffsetFactor !== 0) data.polygonOffsetFactor = this.polygonOffsetFactor; 13870 if (this.polygonOffsetUnits !== 0) data.polygonOffsetUnits = this.polygonOffsetUnits; 13871 if (this.linewidth !== void 0 && this.linewidth !== 1) data.linewidth = this.linewidth; 13872 if (this.dashSize !== void 0) data.dashSize = this.dashSize; 13873 if (this.gapSize !== void 0) data.gapSize = this.gapSize; 13874 if (this.scale !== void 0) data.scale = this.scale; 13875 if (this.dithering === true) data.dithering = true; 13876 if (this.alphaTest > 0) data.alphaTest = this.alphaTest; 13877 if (this.alphaHash === true) data.alphaHash = true; 13878 if (this.alphaToCoverage === true) data.alphaToCoverage = true; 13879 if (this.premultipliedAlpha === true) data.premultipliedAlpha = true; 13880 if (this.forceSinglePass === true) data.forceSinglePass = true; 13881 if (this.allowOverride === false) data.allowOverride = false; 13882 if (this.wireframe === true) data.wireframe = true; 13883 if (this.wireframeLinewidth > 1) data.wireframeLinewidth = this.wireframeLinewidth; 13884 if (this.wireframeLinecap !== "round") data.wireframeLinecap = this.wireframeLinecap; 13885 if (this.wireframeLinejoin !== "round") data.wireframeLinejoin = this.wireframeLinejoin; 13886 if (this.flatShading === true) data.flatShading = true; 13887 if (this.visible === false) data.visible = false; 13888 if (this.toneMapped === false) data.toneMapped = false; 13889 if (this.fog === false) data.fog = false; 13890 if (Object.keys(this.userData).length > 0) data.userData = this.userData; 13891 function extractFromCache(cache) { 13892 const values = []; 13893 for (const key in cache) { 13894 const data2 = cache[key]; 13895 delete data2.metadata; 13896 values.push(data2); 13897 } 13898 return values; 13899 } 13900 if (isRootObject) { 13901 const textures = extractFromCache(meta.textures); 13902 const images = extractFromCache(meta.images); 13903 if (textures.length > 0) data.textures = textures; 13904 if (images.length > 0) data.images = images; 13905 } 13906 return data; 13907 } 13908 /** 13909 * Returns a new material with copied values from this instance. 13910 * 13911 * @return {Material} A clone of this instance. 13912 */ 13913 clone() { 13914 return new this.constructor().copy(this); 13915 } 13916 /** 13917 * Copies the values of the given material to this instance. 13918 * 13919 * @param {Material} source - The material to copy. 13920 * @return {Material} A reference to this instance. 13921 */ 13922 copy(source) { 13923 this.name = source.name; 13924 this.blending = source.blending; 13925 this.side = source.side; 13926 this.vertexColors = source.vertexColors; 13927 this.opacity = source.opacity; 13928 this.transparent = source.transparent; 13929 this.blendSrc = source.blendSrc; 13930 this.blendDst = source.blendDst; 13931 this.blendEquation = source.blendEquation; 13932 this.blendSrcAlpha = source.blendSrcAlpha; 13933 this.blendDstAlpha = source.blendDstAlpha; 13934 this.blendEquationAlpha = source.blendEquationAlpha; 13935 this.blendColor.copy(source.blendColor); 13936 this.blendAlpha = source.blendAlpha; 13937 this.depthFunc = source.depthFunc; 13938 this.depthTest = source.depthTest; 13939 this.depthWrite = source.depthWrite; 13940 this.stencilWriteMask = source.stencilWriteMask; 13941 this.stencilFunc = source.stencilFunc; 13942 this.stencilRef = source.stencilRef; 13943 this.stencilFuncMask = source.stencilFuncMask; 13944 this.stencilFail = source.stencilFail; 13945 this.stencilZFail = source.stencilZFail; 13946 this.stencilZPass = source.stencilZPass; 13947 this.stencilWrite = source.stencilWrite; 13948 const srcPlanes = source.clippingPlanes; 13949 let dstPlanes = null; 13950 if (srcPlanes !== null) { 13951 const n = srcPlanes.length; 13952 dstPlanes = new Array(n); 13953 for (let i = 0; i !== n; ++i) { 13954 dstPlanes[i] = srcPlanes[i].clone(); 13955 } 13956 } 13957 this.clippingPlanes = dstPlanes; 13958 this.clipIntersection = source.clipIntersection; 13959 this.clipShadows = source.clipShadows; 13960 this.shadowSide = source.shadowSide; 13961 this.colorWrite = source.colorWrite; 13962 this.precision = source.precision; 13963 this.polygonOffset = source.polygonOffset; 13964 this.polygonOffsetFactor = source.polygonOffsetFactor; 13965 this.polygonOffsetUnits = source.polygonOffsetUnits; 13966 this.dithering = source.dithering; 13967 this.alphaTest = source.alphaTest; 13968 this.alphaHash = source.alphaHash; 13969 this.alphaToCoverage = source.alphaToCoverage; 13970 this.premultipliedAlpha = source.premultipliedAlpha; 13971 this.forceSinglePass = source.forceSinglePass; 13972 this.allowOverride = source.allowOverride; 13973 this.visible = source.visible; 13974 this.toneMapped = source.toneMapped; 13975 this.userData = JSON.parse(JSON.stringify(source.userData)); 13976 return this; 13977 } 13978 /** 13979 * Frees the GPU-related resources allocated by this instance. Call this 13980 * method whenever this instance is no longer used in your app. 13981 * 13982 * @fires Material#dispose 13983 */ 13984 dispose() { 13985 this.dispatchEvent({ type: "dispose" }); 13986 } 13987 /** 13988 * Setting this property to `true` indicates the engine the material 13989 * needs to be recompiled. 13990 * 13991 * @type {boolean} 13992 * @default false 13993 * @param {boolean} value 13994 */ 13995 set needsUpdate(value) { 13996 if (value === true) this.version++; 13997 } 13998}; 13999var SpriteMaterial = class extends Material { 14000 /** 14001 * Constructs a new sprite material. 14002 * 14003 * @param {Object} [parameters] - An object with one or more properties 14004 * defining the material's appearance. Any property of the material 14005 * (including any property from inherited materials) can be passed 14006 * in here. Color values can be passed any type of value accepted 14007 * by {@link Color#set}. 14008 */ 14009 constructor(parameters) { 14010 super(); 14011 this.isSpriteMaterial = true; 14012 this.type = "SpriteMaterial"; 14013 this.color = new Color(16777215); 14014 this.map = null; 14015 this.alphaMap = null; 14016 this.rotation = 0; 14017 this.sizeAttenuation = true; 14018 this.transparent = true; 14019 this.fog = true; 14020 this.setValues(parameters); 14021 } 14022 copy(source) { 14023 super.copy(source); 14024 this.color.copy(source.color); 14025 this.map = source.map; 14026 this.alphaMap = source.alphaMap; 14027 this.rotation = source.rotation; 14028 this.sizeAttenuation = source.sizeAttenuation; 14029 this.fog = source.fog; 14030 return this; 14031 } 14032}; 14033var _vector$7 = /* @__PURE__ */ new Vector3(); 14034var _segCenter = /* @__PURE__ */ new Vector3(); 14035var _segDir = /* @__PURE__ */ new Vector3(); 14036var _diff = /* @__PURE__ */ new Vector3(); 14037var _edge1 = /* @__PURE__ */ new Vector3(); 14038var _edge2 = /* @__PURE__ */ new Vector3(); 14039var _normal$1 = /* @__PURE__ */ new Vector3(); 14040var Ray = class { 14041 /** 14042 * Constructs a new ray. 14043 * 14044 * @param {Vector3} [origin=(0,0,0)] - The origin of the ray. 14045 * @param {Vector3} [direction=(0,0,-1)] - The (normalized) direction of the ray. 14046 */ 14047 constructor(origin = new Vector3(), direction = new Vector3(0, 0, -1)) { 14048 this.origin = origin; 14049 this.direction = direction; 14050 } 14051 /** 14052 * Sets the ray's components by copying the given values. 14053 * 14054 * @param {Vector3} origin - The origin. 14055 * @param {Vector3} direction - The direction. 14056 * @return {Ray} A reference to this ray. 14057 */ 14058 set(origin, direction) { 14059 this.origin.copy(origin); 14060 this.direction.copy(direction); 14061 return this; 14062 } 14063 /** 14064 * Copies the values of the given ray to this instance. 14065 * 14066 * @param {Ray} ray - The ray to copy. 14067 * @return {Ray} A reference to this ray. 14068 */ 14069 copy(ray) { 14070 this.origin.copy(ray.origin); 14071 this.direction.copy(ray.direction); 14072 return this; 14073 } 14074 /** 14075 * Returns a vector that is located at a given distance along this ray. 14076 * 14077 * @param {number} t - The distance along the ray to retrieve a position for. 14078 * @param {Vector3} target - The target vector that is used to store the method's result. 14079 * @return {Vector3} A position on the ray. 14080 */ 14081 at(t, target) { 14082 return target.copy(this.origin).addScaledVector(this.direction, t); 14083 } 14084 /** 14085 * Adjusts the direction of the ray to point at the given vector in world space. 14086 * 14087 * @param {Vector3} v - The target position. 14088 * @return {Ray} A reference to this ray. 14089 */ 14090 lookAt(v) { 14091 this.direction.copy(v).sub(this.origin).normalize(); 14092 return this; 14093 } 14094 /** 14095 * Shift the origin of this ray along its direction by the given distance. 14096 * 14097 * @param {number} t - The distance along the ray to interpolate. 14098 * @return {Ray} A reference to this ray. 14099 */ 14100 recast(t) { 14101 this.origin.copy(this.at(t, _vector$7)); 14102 return this; 14103 } 14104 /** 14105 * Returns the point along this ray that is closest to the given point. 14106 * 14107 * @param {Vector3} point - A point in 3D space to get the closet location on the ray for. 14108 * @param {Vector3} target - The target vector that is used to store the method's result. 14109 * @return {Vector3} The closest point on this ray. 14110 */ 14111 closestPointToPoint(point, target) { 14112 target.subVectors(point, this.origin); 14113 const directionDistance = target.dot(this.direction); 14114 if (directionDistance < 0) { 14115 return target.copy(this.origin); 14116 } 14117 return target.copy(this.origin).addScaledVector(this.direction, directionDistance); 14118 } 14119 /** 14120 * Returns the distance of the closest approach between this ray and the given point. 14121 * 14122 * @param {Vector3} point - A point in 3D space to compute the distance to. 14123 * @return {number} The distance. 14124 */ 14125 distanceToPoint(point) { 14126 return Math.sqrt(this.distanceSqToPoint(point)); 14127 } 14128 /** 14129 * Returns the squared distance of the closest approach between this ray and the given point. 14130 * 14131 * @param {Vector3} point - A point in 3D space to compute the distance to. 14132 * @return {number} The squared distance. 14133 */ 14134 distanceSqToPoint(point) { 14135 const directionDistance = _vector$7.subVectors(point, this.origin).dot(this.direction); 14136 if (directionDistance < 0) { 14137 return this.origin.distanceToSquared(point); 14138 } 14139 _vector$7.copy(this.origin).addScaledVector(this.direction, directionDistance); 14140 return _vector$7.distanceToSquared(point); 14141 } 14142 /** 14143 * Returns the squared distance between this ray and the given line segment. 14144 * 14145 * @param {Vector3} v0 - The start point of the line segment. 14146 * @param {Vector3} v1 - The end point of the line segment. 14147 * @param {Vector3} [optionalPointOnRay] - When provided, it receives the point on this ray that is closest to the segment. 14148 * @param {Vector3} [optionalPointOnSegment] - When provided, it receives the point on the line segment that is closest to this ray. 14149 * @return {number} The squared distance. 14150 */ 14151 distanceSqToSegment(v0, v1, optionalPointOnRay, optionalPointOnSegment) { 14152 _segCenter.copy(v0).add(v1).multiplyScalar(0.5); 14153 _segDir.copy(v1).sub(v0).normalize(); 14154 _diff.copy(this.origin).sub(_segCenter); 14155 const segExtent = v0.distanceTo(v1) * 0.5; 14156 const a01 = -this.direction.dot(_segDir); 14157 const b0 = _diff.dot(this.direction); 14158 const b1 = -_diff.dot(_segDir); 14159 const c = _diff.lengthSq(); 14160 const det = Math.abs(1 - a01 * a01); 14161 let s0, s1, sqrDist, extDet; 14162 if (det > 0) { 14163 s0 = a01 * b1 - b0; 14164 s1 = a01 * b0 - b1; 14165 extDet = segExtent * det; 14166 if (s0 >= 0) { 14167 if (s1 >= -extDet) { 14168 if (s1 <= extDet) { 14169 const invDet = 1 / det; 14170 s0 *= invDet; 14171 s1 *= invDet; 14172 sqrDist = s0 * (s0 + a01 * s1 + 2 * b0) + s1 * (a01 * s0 + s1 + 2 * b1) + c; 14173 } else { 14174 s1 = segExtent; 14175 s0 = Math.max(0, -(a01 * s1 + b0)); 14176 sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; 14177 } 14178 } else { 14179 s1 = -segExtent; 14180 s0 = Math.max(0, -(a01 * s1 + b0)); 14181 sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; 14182 } 14183 } else { 14184 if (s1 <= -extDet) { 14185 s0 = Math.max(0, -(-a01 * segExtent + b0)); 14186 s1 = s0 > 0 ? -segExtent : Math.min(Math.max(-segExtent, -b1), segExtent); 14187 sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; 14188 } else if (s1 <= extDet) { 14189 s0 = 0; 14190 s1 = Math.min(Math.max(-segExtent, -b1), segExtent); 14191 sqrDist = s1 * (s1 + 2 * b1) + c; 14192 } else { 14193 s0 = Math.max(0, -(a01 * segExtent + b0)); 14194 s1 = s0 > 0 ? segExtent : Math.min(Math.max(-segExtent, -b1), segExtent); 14195 sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; 14196 } 14197 } 14198 } else { 14199 s1 = a01 > 0 ? -segExtent : segExtent; 14200 s0 = Math.max(0, -(a01 * s1 + b0)); 14201 sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; 14202 } 14203 if (optionalPointOnRay) { 14204 optionalPointOnRay.copy(this.origin).addScaledVector(this.direction, s0); 14205 } 14206 if (optionalPointOnSegment) { 14207 optionalPointOnSegment.copy(_segCenter).addScaledVector(_segDir, s1); 14208 } 14209 return sqrDist; 14210 } 14211 /** 14212 * Intersects this ray with the given sphere, returning the intersection 14213 * point or `null` if there is no intersection. 14214 * 14215 * @param {Sphere} sphere - The sphere to intersect. 14216 * @param {Vector3} target - The target vector that is used to store the method's result. 14217 * @return {?Vector3} The intersection point. 14218 */ 14219 intersectSphere(sphere, target) { 14220 _vector$7.subVectors(sphere.center, this.origin); 14221 const tca = _vector$7.dot(this.direction); 14222 const d2 = _vector$7.dot(_vector$7) - tca * tca; 14223 const radius2 = sphere.radius * sphere.radius; 14224 if (d2 > radius2) return null; 14225 const thc = Math.sqrt(radius2 - d2); 14226 const t0 = tca - thc; 14227 const t1 = tca + thc; 14228 if (t1 < 0) return null; 14229 if (t0 < 0) return this.at(t1, target); 14230 return this.at(t0, target); 14231 } 14232 /** 14233 * Returns `true` if this ray intersects with the given sphere. 14234 * 14235 * @param {Sphere} sphere - The sphere to intersect. 14236 * @return {boolean} Whether this ray intersects with the given sphere or not. 14237 */ 14238 intersectsSphere(sphere) { 14239 if (sphere.radius < 0) return false; 14240 return this.distanceSqToPoint(sphere.center) <= sphere.radius * sphere.radius; 14241 } 14242 /** 14243 * Computes the distance from the ray's origin to the given plane. Returns `null` if the ray 14244 * does not intersect with the plane. 14245 * 14246 * @param {Plane} plane - The plane to compute the distance to. 14247 * @return {?number} Whether this ray intersects with the given sphere or not. 14248 */ 14249 distanceToPlane(plane) { 14250 const denominator = plane.normal.dot(this.direction); 14251 if (denominator === 0) { 14252 if (plane.distanceToPoint(this.origin) === 0) { 14253 return 0; 14254 } 14255 return null; 14256 } 14257 const t = -(this.origin.dot(plane.normal) + plane.constant) / denominator; 14258 return t >= 0 ? t : null; 14259 } 14260 /** 14261 * Intersects this ray with the given plane, returning the intersection 14262 * point or `null` if there is no intersection. 14263 * 14264 * @param {Plane} plane - The plane to intersect. 14265 * @param {Vector3} target - The target vector that is used to store the method's result. 14266 * @return {?Vector3} The intersection point. 14267 */ 14268 intersectPlane(plane, target) { 14269 const t = this.distanceToPlane(plane); 14270 if (t === null) { 14271 return null; 14272 } 14273 return this.at(t, target); 14274 } 14275 /** 14276 * Returns `true` if this ray intersects with the given plane. 14277 * 14278 * @param {Plane} plane - The plane to intersect. 14279 * @return {boolean} Whether this ray intersects with the given plane or not. 14280 */ 14281 intersectsPlane(plane) { 14282 const distToPoint = plane.distanceToPoint(this.origin); 14283 if (distToPoint === 0) { 14284 return true; 14285 } 14286 const denominator = plane.normal.dot(this.direction); 14287 if (denominator * distToPoint < 0) { 14288 return true; 14289 } 14290 return false; 14291 } 14292 /** 14293 * Intersects this ray with the given bounding box, returning the intersection 14294 * point or `null` if there is no intersection. 14295 * 14296 * @param {Box3} box - The box to intersect. 14297 * @param {Vector3} target - The target vector that is used to store the method's result. 14298 * @return {?Vector3} The intersection point. 14299 */ 14300 intersectBox(box, target) { 14301 let tmin, tmax, tymin, tymax, tzmin, tzmax; 14302 const invdirx = 1 / this.direction.x, invdiry = 1 / this.direction.y, invdirz = 1 / this.direction.z; 14303 const origin = this.origin; 14304 if (invdirx >= 0) { 14305 tmin = (box.min.x - origin.x) * invdirx; 14306 tmax = (box.max.x - origin.x) * invdirx; 14307 } else { 14308 tmin = (box.max.x - origin.x) * invdirx; 14309 tmax = (box.min.x - origin.x) * invdirx; 14310 } 14311 if (invdiry >= 0) { 14312 tymin = (box.min.y - origin.y) * invdiry; 14313 tymax = (box.max.y - origin.y) * invdiry; 14314 } else { 14315 tymin = (box.max.y - origin.y) * invdiry; 14316 tymax = (box.min.y - origin.y) * invdiry; 14317 } 14318 if (tmin > tymax || tymin > tmax) return null; 14319 if (tymin > tmin || isNaN(tmin)) tmin = tymin; 14320 if (tymax < tmax || isNaN(tmax)) tmax = tymax; 14321 if (invdirz >= 0) { 14322 tzmin = (box.min.z - origin.z) * invdirz; 14323 tzmax = (box.max.z - origin.z) * invdirz; 14324 } else { 14325 tzmin = (box.max.z - origin.z) * invdirz; 14326 tzmax = (box.min.z - origin.z) * invdirz; 14327 } 14328 if (tmin > tzmax || tzmin > tmax) return null; 14329 if (tzmin > tmin || tmin !== tmin) tmin = tzmin; 14330 if (tzmax < tmax || tmax !== tmax) tmax = tzmax; 14331 if (tmax < 0) return null; 14332 return this.at(tmin >= 0 ? tmin : tmax, target); 14333 } 14334 /** 14335 * Returns `true` if this ray intersects with the given box. 14336 * 14337 * @param {Box3} box - The box to intersect. 14338 * @return {boolean} Whether this ray intersects with the given box or not. 14339 */ 14340 intersectsBox(box) { 14341 return this.intersectBox(box, _vector$7) !== null; 14342 } 14343 /** 14344 * Intersects this ray with the given triangle, returning the intersection 14345 * point or `null` if there is no intersection. 14346 * 14347 * @param {Vector3} a - The first vertex of the triangle. 14348 * @param {Vector3} b - The second vertex of the triangle. 14349 * @param {Vector3} c - The third vertex of the triangle. 14350 * @param {boolean} backfaceCulling - Whether to use backface culling or not. 14351 * @param {Vector3} target - The target vector that is used to store the method's result. 14352 * @return {?Vector3} The intersection point. 14353 */ 14354 intersectTriangle(a, b, c, backfaceCulling, target) { 14355 _edge1.subVectors(b, a); 14356 _edge2.subVectors(c, a); 14357 _normal$1.crossVectors(_edge1, _edge2); 14358 let DdN = this.direction.dot(_normal$1); 14359 let sign2; 14360 if (DdN > 0) { 14361 if (backfaceCulling) return null; 14362 sign2 = 1; 14363 } else if (DdN < 0) { 14364 sign2 = -1; 14365 DdN = -DdN; 14366 } else { 14367 return null; 14368 } 14369 _diff.subVectors(this.origin, a); 14370 const DdQxE2 = sign2 * this.direction.dot(_edge2.crossVectors(_diff, _edge2)); 14371 if (DdQxE2 < 0) { 14372 return null; 14373 } 14374 const DdE1xQ = sign2 * this.direction.dot(_edge1.cross(_diff)); 14375 if (DdE1xQ < 0) { 14376 return null; 14377 } 14378 if (DdQxE2 + DdE1xQ > DdN) { 14379 return null; 14380 } 14381 const QdN = -sign2 * _diff.dot(_normal$1); 14382 if (QdN < 0) { 14383 return null; 14384 } 14385 return this.at(QdN / DdN, target); 14386 } 14387 /** 14388 * Transforms this ray with the given 4x4 transformation matrix. 14389 * 14390 * @param {Matrix4} matrix4 - The transformation matrix. 14391 * @return {Ray} A reference to this ray. 14392 */ 14393 applyMatrix4(matrix4) { 14394 this.origin.applyMatrix4(matrix4); 14395 this.direction.transformDirection(matrix4); 14396 return this; 14397 } 14398 /** 14399 * Returns `true` if this ray is equal with the given one. 14400 * 14401 * @param {Ray} ray - The ray to test for equality. 14402 * @return {boolean} Whether this ray is equal with the given one. 14403 */ 14404 equals(ray) { 14405 return ray.origin.equals(this.origin) && ray.direction.equals(this.direction); 14406 } 14407 /** 14408 * Returns a new ray with copied values from this instance. 14409 * 14410 * @return {Ray} A clone of this instance. 14411 */ 14412 clone() { 14413 return new this.constructor().copy(this); 14414 } 14415}; 14416var MeshBasicMaterial = class extends Material { 14417 /** 14418 * Constructs a new mesh basic material. 14419 * 14420 * @param {Object} [parameters] - An object with one or more properties 14421 * defining the material's appearance. Any property of the material 14422 * (including any property from inherited materials) can be passed 14423 * in here. Color values can be passed any type of value accepted 14424 * by {@link Color#set}. 14425 */ 14426 constructor(parameters) { 14427 super(); 14428 this.isMeshBasicMaterial = true; 14429 this.type = "MeshBasicMaterial"; 14430 this.color = new Color(16777215); 14431 this.map = null; 14432 this.lightMap = null; 14433 this.lightMapIntensity = 1; 14434 this.aoMap = null; 14435 this.aoMapIntensity = 1; 14436 this.specularMap = null; 14437 this.alphaMap = null; 14438 this.envMap = null; 14439 this.envMapRotation = new Euler(); 14440 this.combine = MultiplyOperation; 14441 this.reflectivity = 1; 14442 this.refractionRatio = 0.98; 14443 this.wireframe = false; 14444 this.wireframeLinewidth = 1; 14445 this.wireframeLinecap = "round"; 14446 this.wireframeLinejoin = "round"; 14447 this.fog = true; 14448 this.setValues(parameters); 14449 } 14450 copy(source) { 14451 super.copy(source); 14452 this.color.copy(source.color); 14453 this.map = source.map; 14454 this.lightMap = source.lightMap; 14455 this.lightMapIntensity = source.lightMapIntensity; 14456 this.aoMap = source.aoMap; 14457 this.aoMapIntensity = source.aoMapIntensity; 14458 this.specularMap = source.specularMap; 14459 this.alphaMap = source.alphaMap; 14460 this.envMap = source.envMap; 14461 this.envMapRotation.copy(source.envMapRotation); 14462 this.combine = source.combine; 14463 this.reflectivity = source.reflectivity; 14464 this.refractionRatio = source.refractionRatio; 14465 this.wireframe = source.wireframe; 14466 this.wireframeLinewidth = source.wireframeLinewidth; 14467 this.wireframeLinecap = source.wireframeLinecap; 14468 this.wireframeLinejoin = source.wireframeLinejoin; 14469 this.fog = source.fog; 14470 return this; 14471 } 14472}; 14473var _inverseMatrix$3 = /* @__PURE__ */ new Matrix4(); 14474var _ray$3 = /* @__PURE__ */ new Ray(); 14475var _sphere$6 = /* @__PURE__ */ new Sphere(); 14476var _sphereHitAt = /* @__PURE__ */ new Vector3(); 14477var _vA = /* @__PURE__ */ new Vector3(); 14478var _vB = /* @__PURE__ */ new Vector3(); 14479var _vC = /* @__PURE__ */ new Vector3(); 14480var _tempA = /* @__PURE__ */ new Vector3(); 14481var _morphA = /* @__PURE__ */ new Vector3(); 14482var _intersectionPoint = /* @__PURE__ */ new Vector3(); 14483var _intersectionPointWorld = /* @__PURE__ */ new Vector3(); 14484var Mesh = class extends Object3D { 14485 /** 14486 * Constructs a new mesh. 14487 * 14488 * @param {BufferGeometry} [geometry] - The mesh geometry. 14489 * @param {Material|Array<Material>} [material] - The mesh material. 14490 */ 14491 constructor(geometry = new BufferGeometry(), material = new MeshBasicMaterial()) { 14492 super(); 14493 this.isMesh = true; 14494 this.type = "Mesh"; 14495 this.geometry = geometry; 14496 this.material = material; 14497 this.morphTargetDictionary = void 0; 14498 this.morphTargetInfluences = void 0; 14499 this.count = 1; 14500 this.updateMorphTargets(); 14501 } 14502 copy(source, recursive) { 14503 super.copy(source, recursive); 14504 if (source.morphTargetInfluences !== void 0) { 14505 this.morphTargetInfluences = source.morphTargetInfluences.slice(); 14506 } 14507 if (source.morphTargetDictionary !== void 0) { 14508 this.morphTargetDictionary = Object.assign({}, source.morphTargetDictionary); 14509 } 14510 this.material = Array.isArray(source.material) ? source.material.slice() : source.material; 14511 this.geometry = source.geometry; 14512 return this; 14513 } 14514 /** 14515 * Sets the values of {@link Mesh#morphTargetDictionary} and {@link Mesh#morphTargetInfluences} 14516 * to make sure existing morph targets can influence this 3D object. 14517 */ 14518 updateMorphTargets() { 14519 const geometry = this.geometry; 14520 const morphAttributes = geometry.morphAttributes; 14521 const keys = Object.keys(morphAttributes); 14522 if (keys.length > 0) { 14523 const morphAttribute = morphAttributes[keys[0]]; 14524 if (morphAttribute !== void 0) { 14525 this.morphTargetInfluences = []; 14526 this.morphTargetDictionary = {}; 14527 for (let m = 0, ml = morphAttribute.length; m < ml; m++) { 14528 const name = morphAttribute[m].name || String(m); 14529 this.morphTargetInfluences.push(0); 14530 this.morphTargetDictionary[name] = m; 14531 } 14532 } 14533 } 14534 } 14535 /** 14536 * Returns the local-space position of the vertex at the given index, taking into 14537 * account the current animation state of both morph targets and skinning. 14538 * 14539 * @param {number} index - The vertex index. 14540 * @param {Vector3} target - The target object that is used to store the method's result. 14541 * @return {Vector3} The vertex position in local space. 14542 */ 14543 getVertexPosition(index, target) { 14544 const geometry = this.geometry; 14545 const position = geometry.attributes.position; 14546 const morphPosition = geometry.morphAttributes.position; 14547 const morphTargetsRelative = geometry.morphTargetsRelative; 14548 target.fromBufferAttribute(position, index); 14549 const morphInfluences = this.morphTargetInfluences; 14550 if (morphPosition && morphInfluences) { 14551 _morphA.set(0, 0, 0); 14552 for (let i = 0, il = morphPosition.length; i < il; i++) { 14553 const influence = morphInfluences[i]; 14554 const morphAttribute = morphPosition[i]; 14555 if (influence === 0) continue; 14556 _tempA.fromBufferAttribute(morphAttribute, index); 14557 if (morphTargetsRelative) { 14558 _morphA.addScaledVector(_tempA, influence); 14559 } else { 14560 _morphA.addScaledVector(_tempA.sub(target), influence); 14561 } 14562 } 14563 target.add(_morphA); 14564 } 14565 return target; 14566 } 14567 /** 14568 * Computes intersection points between a casted ray and this line. 14569 * 14570 * @param {Raycaster} raycaster - The raycaster. 14571 * @param {Array<Object>} intersects - The target array that holds the intersection points. 14572 */ 14573 raycast(raycaster, intersects2) { 14574 const geometry = this.geometry; 14575 const material = this.material; 14576 const matrixWorld = this.matrixWorld; 14577 if (material === void 0) return; 14578 if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); 14579 _sphere$6.copy(geometry.boundingSphere); 14580 _sphere$6.applyMatrix4(matrixWorld); 14581 _ray$3.copy(raycaster.ray).recast(raycaster.near); 14582 if (_sphere$6.containsPoint(_ray$3.origin) === false) { 14583 if (_ray$3.intersectSphere(_sphere$6, _sphereHitAt) === null) return; 14584 if (_ray$3.origin.distanceToSquared(_sphereHitAt) > (raycaster.far - raycaster.near) ** 2) return; 14585 } 14586 _inverseMatrix$3.copy(matrixWorld).invert(); 14587 _ray$3.copy(raycaster.ray).applyMatrix4(_inverseMatrix$3); 14588 if (geometry.boundingBox !== null) { 14589 if (_ray$3.intersectsBox(geometry.boundingBox) === false) return; 14590 } 14591 this._computeIntersections(raycaster, intersects2, _ray$3); 14592 } 14593 _computeIntersections(raycaster, intersects2, rayLocalSpace) { 14594 let intersection; 14595 const geometry = this.geometry; 14596 const material = this.material; 14597 const index = geometry.index; 14598 const position = geometry.attributes.position; 14599 const uv = geometry.attributes.uv; 14600 const uv1 = geometry.attributes.uv1; 14601 const normal = geometry.attributes.normal; 14602 const groups = geometry.groups; 14603 const drawRange = geometry.drawRange; 14604 if (index !== null) { 14605 if (Array.isArray(material)) { 14606 for (let i = 0, il = groups.length; i < il; i++) { 14607 const group = groups[i]; 14608 const groupMaterial = material[group.materialIndex]; 14609 const start = Math.max(group.start, drawRange.start); 14610 const end = Math.min(index.count, Math.min(group.start + group.count, drawRange.start + drawRange.count)); 14611 for (let j = start, jl = end; j < jl; j += 3) { 14612 const a = index.getX(j); 14613 const b = index.getX(j + 1); 14614 const c = index.getX(j + 2); 14615 intersection = checkGeometryIntersection(this, groupMaterial, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c); 14616 if (intersection) { 14617 intersection.faceIndex = Math.floor(j / 3); 14618 intersection.face.materialIndex = group.materialIndex; 14619 intersects2.push(intersection); 14620 } 14621 } 14622 } 14623 } else { 14624 const start = Math.max(0, drawRange.start); 14625 const end = Math.min(index.count, drawRange.start + drawRange.count); 14626 for (let i = start, il = end; i < il; i += 3) { 14627 const a = index.getX(i); 14628 const b = index.getX(i + 1); 14629 const c = index.getX(i + 2); 14630 intersection = checkGeometryIntersection(this, material, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c); 14631 if (intersection) { 14632 intersection.faceIndex = Math.floor(i / 3); 14633 intersects2.push(intersection); 14634 } 14635 } 14636 } 14637 } else if (position !== void 0) { 14638 if (Array.isArray(material)) { 14639 for (let i = 0, il = groups.length; i < il; i++) { 14640 const group = groups[i]; 14641 const groupMaterial = material[group.materialIndex]; 14642 const start = Math.max(group.start, drawRange.start); 14643 const end = Math.min(position.count, Math.min(group.start + group.count, drawRange.start + drawRange.count)); 14644 for (let j = start, jl = end; j < jl; j += 3) { 14645 const a = j; 14646 const b = j + 1; 14647 const c = j + 2; 14648 intersection = checkGeometryIntersection(this, groupMaterial, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c); 14649 if (intersection) { 14650 intersection.faceIndex = Math.floor(j / 3); 14651 intersection.face.materialIndex = group.materialIndex; 14652 intersects2.push(intersection); 14653 } 14654 } 14655 } 14656 } else { 14657 const start = Math.max(0, drawRange.start); 14658 const end = Math.min(position.count, drawRange.start + drawRange.count); 14659 for (let i = start, il = end; i < il; i += 3) { 14660 const a = i; 14661 const b = i + 1; 14662 const c = i + 2; 14663 intersection = checkGeometryIntersection(this, material, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c); 14664 if (intersection) { 14665 intersection.faceIndex = Math.floor(i / 3); 14666 intersects2.push(intersection); 14667 } 14668 } 14669 } 14670 } 14671 } 14672}; 14673function checkIntersection$1(object, material, raycaster, ray, pA, pB, pC, point) { 14674 let intersect2; 14675 if (material.side === BackSide) { 14676 intersect2 = ray.intersectTriangle(pC, pB, pA, true, point); 14677 } else { 14678 intersect2 = ray.intersectTriangle(pA, pB, pC, material.side === FrontSide, point); 14679 } 14680 if (intersect2 === null) return null; 14681 _intersectionPointWorld.copy(point); 14682 _intersectionPointWorld.applyMatrix4(object.matrixWorld); 14683 const distance = raycaster.ray.origin.distanceTo(_intersectionPointWorld); 14684 if (distance < raycaster.near || distance > raycaster.far) return null; 14685 return { 14686 distance, 14687 point: _intersectionPointWorld.clone(), 14688 object 14689 }; 14690} 14691function checkGeometryIntersection(object, material, raycaster, ray, uv, uv1, normal, a, b, c) { 14692 object.getVertexPosition(a, _vA); 14693 object.getVertexPosition(b, _vB); 14694 object.getVertexPosition(c, _vC); 14695 const intersection = checkIntersection$1(object, material, raycaster, ray, _vA, _vB, _vC, _intersectionPoint); 14696 if (intersection) { 14697 const barycoord = new Vector3(); 14698 Triangle.getBarycoord(_intersectionPoint, _vA, _vB, _vC, barycoord); 14699 if (uv) { 14700 intersection.uv = Triangle.getInterpolatedAttribute(uv, a, b, c, barycoord, new Vector2()); 14701 } 14702 if (uv1) { 14703 intersection.uv1 = Triangle.getInterpolatedAttribute(uv1, a, b, c, barycoord, new Vector2()); 14704 } 14705 if (normal) { 14706 intersection.normal = Triangle.getInterpolatedAttribute(normal, a, b, c, barycoord, new Vector3()); 14707 if (intersection.normal.dot(ray.direction) > 0) { 14708 intersection.normal.multiplyScalar(-1); 14709 } 14710 } 14711 const face = { 14712 a, 14713 b, 14714 c, 14715 normal: new Vector3(), 14716 materialIndex: 0 14717 }; 14718 Triangle.getNormal(_vA, _vB, _vC, face.normal); 14719 intersection.face = face; 14720 intersection.barycoord = barycoord; 14721 } 14722 return intersection; 14723} 14724var _baseVector = /* @__PURE__ */ new Vector4(); 14725var _skinIndex = /* @__PURE__ */ new Vector4(); 14726var _skinWeight = /* @__PURE__ */ new Vector4(); 14727var _vector4 = /* @__PURE__ */ new Vector4(); 14728var _matrix4 = /* @__PURE__ */ new Matrix4(); 14729var _vertex = /* @__PURE__ */ new Vector3(); 14730var _sphere$5 = /* @__PURE__ */ new Sphere(); 14731var _inverseMatrix$2 = /* @__PURE__ */ new Matrix4(); 14732var _ray$2 = /* @__PURE__ */ new Ray(); 14733var SkinnedMesh = class extends Mesh { 14734 /** 14735 * Constructs a new skinned mesh. 14736 * 14737 * @param {BufferGeometry} [geometry] - The mesh geometry. 14738 * @param {Material|Array<Material>} [material] - The mesh material. 14739 */ 14740 constructor(geometry, material) { 14741 super(geometry, material); 14742 this.isSkinnedMesh = true; 14743 this.type = "SkinnedMesh"; 14744 this.bindMode = AttachedBindMode; 14745 this.bindMatrix = new Matrix4(); 14746 this.bindMatrixInverse = new Matrix4(); 14747 this.boundingBox = null; 14748 this.boundingSphere = null; 14749 } 14750 /** 14751 * Computes the bounding box of the skinned mesh, and updates {@link SkinnedMesh#boundingBox}. 14752 * The bounding box is not automatically computed by the engine; this method must be called by your app. 14753 * If the skinned mesh is animated, the bounding box should be recomputed per frame in order to reflect 14754 * the current animation state. 14755 */ 14756 computeBoundingBox() { 14757 const geometry = this.geometry; 14758 if (this.boundingBox === null) { 14759 this.boundingBox = new Box3(); 14760 } 14761 this.boundingBox.makeEmpty(); 14762 const positionAttribute = geometry.getAttribute("position"); 14763 for (let i = 0; i < positionAttribute.count; i++) { 14764 this.getVertexPosition(i, _vertex); 14765 this.boundingBox.expandByPoint(_vertex); 14766 } 14767 } 14768 /** 14769 * Computes the bounding sphere of the skinned mesh, and updates {@link SkinnedMesh#boundingSphere}. 14770 * The bounding sphere is automatically computed by the engine once when it is needed, e.g., for ray casting 14771 * and view frustum culling. If the skinned mesh is animated, the bounding sphere should be recomputed 14772 * per frame in order to reflect the current animation state. 14773 */ 14774 computeBoundingSphere() { 14775 const geometry = this.geometry; 14776 if (this.boundingSphere === null) { 14777 this.boundingSphere = new Sphere(); 14778 } 14779 this.boundingSphere.makeEmpty(); 14780 const positionAttribute = geometry.getAttribute("position"); 14781 for (let i = 0; i < positionAttribute.count; i++) { 14782 this.getVertexPosition(i, _vertex); 14783 this.boundingSphere.expandByPoint(_vertex); 14784 } 14785 } 14786 copy(source, recursive) { 14787 super.copy(source, recursive); 14788 this.bindMode = source.bindMode; 14789 this.bindMatrix.copy(source.bindMatrix); 14790 this.bindMatrixInverse.copy(source.bindMatrixInverse); 14791 this.skeleton = source.skeleton; 14792 if (source.boundingBox !== null) this.boundingBox = source.boundingBox.clone(); 14793 if (source.boundingSphere !== null) this.boundingSphere = source.boundingSphere.clone(); 14794 return this; 14795 } 14796 raycast(raycaster, intersects2) { 14797 const material = this.material; 14798 const matrixWorld = this.matrixWorld; 14799 if (material === void 0) return; 14800 if (this.boundingSphere === null) this.computeBoundingSphere(); 14801 _sphere$5.copy(this.boundingSphere); 14802 _sphere$5.applyMatrix4(matrixWorld); 14803 if (raycaster.ray.intersectsSphere(_sphere$5) === false) return; 14804 _inverseMatrix$2.copy(matrixWorld).invert(); 14805 _ray$2.copy(raycaster.ray).applyMatrix4(_inverseMatrix$2); 14806 if (this.boundingBox !== null) { 14807 if (_ray$2.intersectsBox(this.boundingBox) === false) return; 14808 } 14809 this._computeIntersections(raycaster, intersects2, _ray$2); 14810 } 14811 getVertexPosition(index, target) { 14812 super.getVertexPosition(index, target); 14813 this.applyBoneTransform(index, target); 14814 return target; 14815 } 14816 /** 14817 * Binds the given skeleton to the skinned mesh. 14818 * 14819 * @param {Skeleton} skeleton - The skeleton to bind. 14820 * @param {Matrix4} [bindMatrix] - The bind matrix. If no bind matrix is provided, 14821 * the skinned mesh's world matrix will be used instead. 14822 */ 14823 bind(skeleton, bindMatrix) { 14824 this.skeleton = skeleton; 14825 if (bindMatrix === void 0) { 14826 this.updateMatrixWorld(true); 14827 this.skeleton.calculateInverses(); 14828 bindMatrix = this.matrixWorld; 14829 } 14830 this.bindMatrix.copy(bindMatrix); 14831 this.bindMatrixInverse.copy(bindMatrix).invert(); 14832 } 14833 /** 14834 * This method sets the skinned mesh in the rest pose). 14835 */ 14836 pose() { 14837 this.skeleton.pose(); 14838 } 14839 /** 14840 * Normalizes the skin weights which are defined as a buffer attribute 14841 * in the skinned mesh's geometry. 14842 */ 14843 normalizeSkinWeights() { 14844 const vector = new Vector4(); 14845 const skinWeight = this.geometry.attributes.skinWeight; 14846 for (let i = 0, l = skinWeight.count; i < l; i++) { 14847 vector.fromBufferAttribute(skinWeight, i); 14848 const scale = 1 / vector.manhattanLength(); 14849 if (scale !== Infinity) { 14850 vector.multiplyScalar(scale); 14851 } else { 14852 vector.set(1, 0, 0, 0); 14853 } 14854 skinWeight.setXYZW(i, vector.x, vector.y, vector.z, vector.w); 14855 } 14856 } 14857 updateMatrixWorld(force) { 14858 super.updateMatrixWorld(force); 14859 if (this.bindMode === AttachedBindMode) { 14860 this.bindMatrixInverse.copy(this.matrixWorld).invert(); 14861 } else if (this.bindMode === DetachedBindMode) { 14862 this.bindMatrixInverse.copy(this.bindMatrix).invert(); 14863 } else { 14864 warn("SkinnedMesh: Unrecognized bindMode: " + this.bindMode); 14865 } 14866 } 14867 /** 14868 * Applies the bone transform associated with the given index to the given 14869 * vector. Can be used to transform positions or direction vectors by providing 14870 * a Vector4 with 1 or 0 in the w component respectively. Returns the updated vector. 14871 * 14872 * @param {number} index - The vertex index. 14873 * @param {Vector3|Vector4} target - The target object that is used to store the method's result. 14874 * @return {Vector3|Vector4} The updated vertex attribute data. 14875 */ 14876 applyBoneTransform(index, target) { 14877 const skeleton = this.skeleton; 14878 const geometry = this.geometry; 14879 _skinIndex.fromBufferAttribute(geometry.attributes.skinIndex, index); 14880 _skinWeight.fromBufferAttribute(geometry.attributes.skinWeight, index); 14881 if (target.isVector4) { 14882 _baseVector.copy(target); 14883 target.set(0, 0, 0, 0); 14884 } else { 14885 _baseVector.set(...target, 1); 14886 target.set(0, 0, 0); 14887 } 14888 _baseVector.applyMatrix4(this.bindMatrix); 14889 for (let i = 0; i < 4; i++) { 14890 const weight = _skinWeight.getComponent(i); 14891 if (weight !== 0) { 14892 const boneIndex = _skinIndex.getComponent(i); 14893 _matrix4.multiplyMatrices(skeleton.bones[boneIndex].matrixWorld, skeleton.boneInverses[boneIndex]); 14894 target.addScaledVector(_vector4.copy(_baseVector).applyMatrix4(_matrix4), weight); 14895 } 14896 } 14897 if (target.isVector4) { 14898 target.w = _baseVector.w; 14899 } 14900 return target.applyMatrix4(this.bindMatrixInverse); 14901 } 14902}; 14903var Bone = class extends Object3D { 14904 /** 14905 * Constructs a new bone. 14906 */ 14907 constructor() { 14908 super(); 14909 this.isBone = true; 14910 this.type = "Bone"; 14911 } 14912}; 14913var DataTexture = class extends Texture { 14914 /** 14915 * Constructs a new data texture. 14916 * 14917 * @param {?TypedArray} [data=null] - The buffer data. 14918 * @param {number} [width=1] - The width of the texture. 14919 * @param {number} [height=1] - The height of the texture. 14920 * @param {number} [format=RGBAFormat] - The texture format. 14921 * @param {number} [type=UnsignedByteType] - The texture type. 14922 * @param {number} [mapping=Texture.DEFAULT_MAPPING] - The texture mapping. 14923 * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value. 14924 * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value. 14925 * @param {number} [magFilter=NearestFilter] - The mag filter value. 14926 * @param {number} [minFilter=NearestFilter] - The min filter value. 14927 * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value. 14928 * @param {string} [colorSpace=NoColorSpace] - The color space. 14929 */ 14930 constructor(data = null, width = 1, height = 1, format, type, mapping, wrapS, wrapT, magFilter = NearestFilter, minFilter = NearestFilter, anisotropy, colorSpace) { 14931 super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace); 14932 this.isDataTexture = true; 14933 this.image = { data, width, height }; 14934 this.generateMipmaps = false; 14935 this.flipY = false; 14936 this.unpackAlignment = 1; 14937 } 14938}; 14939var _offsetMatrix = /* @__PURE__ */ new Matrix4(); 14940var _identityMatrix = /* @__PURE__ */ new Matrix4(); 14941var Skeleton = class _Skeleton { 14942 /** 14943 * Constructs a new skeleton. 14944 * 14945 * @param {Array<Bone>} [bones] - An array of bones. 14946 * @param {Array<Matrix4>} [boneInverses] - An array of bone inverse matrices. 14947 * If not provided, these matrices will be computed automatically via {@link Skeleton#calculateInverses}. 14948 */ 14949 constructor(bones = [], boneInverses = []) { 14950 this.uuid = generateUUID(); 14951 this.bones = bones.slice(0); 14952 this.boneInverses = boneInverses; 14953 this.boneMatrices = null; 14954 this.previousBoneMatrices = null; 14955 this.boneTexture = null; 14956 this.init(); 14957 } 14958 /** 14959 * Initializes the skeleton. This method gets automatically called by the constructor 14960 * but depending on how the skeleton is created it might be necessary to call this method 14961 * manually. 14962 */ 14963 init() { 14964 const bones = this.bones; 14965 const boneInverses = this.boneInverses; 14966 this.boneMatrices = new Float32Array(bones.length * 16); 14967 if (boneInverses.length === 0) { 14968 this.calculateInverses(); 14969 } else { 14970 if (bones.length !== boneInverses.length) { 14971 warn("Skeleton: Number of inverse bone matrices does not match amount of bones."); 14972 this.boneInverses = []; 14973 for (let i = 0, il = this.bones.length; i < il; i++) { 14974 this.boneInverses.push(new Matrix4()); 14975 } 14976 } 14977 } 14978 } 14979 /** 14980 * Computes the bone inverse matrices. This method resets {@link Skeleton#boneInverses} 14981 * and fills it with new matrices. 14982 */ 14983 calculateInverses() { 14984 this.boneInverses.length = 0; 14985 for (let i = 0, il = this.bones.length; i < il; i++) { 14986 const inverse = new Matrix4(); 14987 if (this.bones[i]) { 14988 inverse.copy(this.bones[i].matrixWorld).invert(); 14989 } 14990 this.boneInverses.push(inverse); 14991 } 14992 } 14993 /** 14994 * Resets the skeleton to the base pose. 14995 */ 14996 pose() { 14997 for (let i = 0, il = this.bones.length; i < il; i++) { 14998 const bone = this.bones[i]; 14999 if (bone) { 15000 bone.matrixWorld.copy(this.boneInverses[i]).invert(); 15001 } 15002 } 15003 for (let i = 0, il = this.bones.length; i < il; i++) { 15004 const bone = this.bones[i]; 15005 if (bone) { 15006 if (bone.parent && bone.parent.isBone) { 15007 bone.matrix.copy(bone.parent.matrixWorld).invert(); 15008 bone.matrix.multiply(bone.matrixWorld); 15009 } else { 15010 bone.matrix.copy(bone.matrixWorld); 15011 } 15012 bone.matrix.decompose(bone.position, bone.quaternion, bone.scale); 15013 } 15014 } 15015 } 15016 /** 15017 * Resets the skeleton to the base pose. 15018 */ 15019 update() { 15020 const bones = this.bones; 15021 const boneInverses = this.boneInverses; 15022 const boneMatrices = this.boneMatrices; 15023 const boneTexture = this.boneTexture; 15024 for (let i = 0, il = bones.length; i < il; i++) { 15025 const matrix = bones[i] ? bones[i].matrixWorld : _identityMatrix; 15026 _offsetMatrix.multiplyMatrices(matrix, boneInverses[i]); 15027 _offsetMatrix.toArray(boneMatrices, i * 16); 15028 } 15029 if (boneTexture !== null) { 15030 boneTexture.needsUpdate = true; 15031 } 15032 } 15033 /** 15034 * Returns a new skeleton with copied values from this instance. 15035 * 15036 * @return {Skeleton} A clone of this instance. 15037 */ 15038 clone() { 15039 return new _Skeleton(this.bones, this.boneInverses); 15040 } 15041 /** 15042 * Computes a data texture for passing bone data to the vertex shader. 15043 * 15044 * @return {Skeleton} A reference of this instance. 15045 */ 15046 computeBoneTexture() { 15047 let size = Math.sqrt(this.bones.length * 4); 15048 size = Math.ceil(size / 4) * 4; 15049 size = Math.max(size, 4); 15050 const boneMatrices = new Float32Array(size * size * 4); 15051 boneMatrices.set(this.boneMatrices); 15052 const boneTexture = new DataTexture(boneMatrices, size, size, RGBAFormat, FloatType); 15053 boneTexture.needsUpdate = true; 15054 this.boneMatrices = boneMatrices; 15055 this.boneTexture = boneTexture; 15056 return this; 15057 } 15058 /** 15059 * Searches through the skeleton's bone array and returns the first with a 15060 * matching name. 15061 * 15062 * @param {string} name - The name of the bone. 15063 * @return {Bone|undefined} The found bone. `undefined` if no bone has been found. 15064 */ 15065 getBoneByName(name) { 15066 for (let i = 0, il = this.bones.length; i < il; i++) { 15067 const bone = this.bones[i]; 15068 if (bone.name === name) { 15069 return bone; 15070 } 15071 } 15072 return void 0; 15073 } 15074 /** 15075 * Frees the GPU-related resources allocated by this instance. Call this 15076 * method whenever this instance is no longer used in your app. 15077 */ 15078 dispose() { 15079 if (this.boneTexture !== null) { 15080 this.boneTexture.dispose(); 15081 this.boneTexture = null; 15082 } 15083 } 15084 /** 15085 * Setups the skeleton by the given JSON and bones. 15086 * 15087 * @param {Object} json - The skeleton as serialized JSON. 15088 * @param {Object<string, Bone>} bones - An array of bones. 15089 * @return {Skeleton} A reference of this instance. 15090 */ 15091 fromJSON(json, bones) { 15092 this.uuid = json.uuid; 15093 for (let i = 0, l = json.bones.length; i < l; i++) { 15094 const uuid = json.bones[i]; 15095 let bone = bones[uuid]; 15096 if (bone === void 0) { 15097 warn("Skeleton: No bone found with UUID:", uuid); 15098 bone = new Bone(); 15099 } 15100 this.bones.push(bone); 15101 this.boneInverses.push(new Matrix4().fromArray(json.boneInverses[i])); 15102 } 15103 this.init(); 15104 return this; 15105 } 15106 /** 15107 * Serializes the skeleton into JSON. 15108 * 15109 * @return {Object} A JSON object representing the serialized skeleton. 15110 * @see {@link ObjectLoader#parse} 15111 */ 15112 toJSON() { 15113 const data = { 15114 metadata: { 15115 version: 4.7, 15116 type: "Skeleton", 15117 generator: "Skeleton.toJSON" 15118 }, 15119 bones: [], 15120 boneInverses: [] 15121 }; 15122 data.uuid = this.uuid; 15123 const bones = this.bones; 15124 const boneInverses = this.boneInverses; 15125 for (let i = 0, l = bones.length; i < l; i++) { 15126 const bone = bones[i]; 15127 data.bones.push(bone.uuid); 15128 const boneInverse = boneInverses[i]; 15129 data.boneInverses.push(boneInverse.toArray()); 15130 } 15131 return data; 15132 } 15133}; 15134var InstancedBufferAttribute = class extends BufferAttribute { 15135 /** 15136 * Constructs a new instanced buffer attribute. 15137 * 15138 * @param {TypedArray} array - The array holding the attribute data. 15139 * @param {number} itemSize - The item size. 15140 * @param {boolean} [normalized=false] - Whether the data are normalized or not. 15141 * @param {number} [meshPerAttribute=1] - How often a value of this buffer attribute should be repeated. 15142 */ 15143 constructor(array, itemSize, normalized, meshPerAttribute = 1) { 15144 super(array, itemSize, normalized); 15145 this.isInstancedBufferAttribute = true; 15146 this.meshPerAttribute = meshPerAttribute; 15147 } 15148 copy(source) { 15149 super.copy(source); 15150 this.meshPerAttribute = source.meshPerAttribute; 15151 return this; 15152 } 15153 toJSON() { 15154 const data = super.toJSON(); 15155 data.meshPerAttribute = this.meshPerAttribute; 15156 data.isInstancedBufferAttribute = true; 15157 return data; 15158 } 15159}; 15160var _instanceLocalMatrix = /* @__PURE__ */ new Matrix4(); 15161var _instanceWorldMatrix = /* @__PURE__ */ new Matrix4(); 15162var _instanceIntersects = []; 15163var _box3 = /* @__PURE__ */ new Box3(); 15164var _identity = /* @__PURE__ */ new Matrix4(); 15165var _mesh$1 = /* @__PURE__ */ new Mesh(); 15166var _sphere$4 = /* @__PURE__ */ new Sphere(); 15167var InstancedMesh = class extends Mesh { 15168 /** 15169 * Constructs a new instanced mesh. 15170 * 15171 * @param {BufferGeometry} [geometry] - The mesh geometry. 15172 * @param {Material|Array<Material>} [material] - The mesh material. 15173 * @param {number} count - The number of instances. 15174 */ 15175 constructor(geometry, material, count) { 15176 super(geometry, material); 15177 this.isInstancedMesh = true; 15178 this.instanceMatrix = new InstancedBufferAttribute(new Float32Array(count * 16), 16); 15179 this.previousInstanceMatrix = null; 15180 this.instanceColor = null; 15181 this.morphTexture = null; 15182 this.count = count; 15183 this.boundingBox = null; 15184 this.boundingSphere = null; 15185 for (let i = 0; i < count; i++) { 15186 this.setMatrixAt(i, _identity); 15187 } 15188 } 15189 /** 15190 * Computes the bounding box of the instanced mesh, and updates {@link InstancedMesh#boundingBox}. 15191 * The bounding box is not automatically computed by the engine; this method must be called by your app. 15192 * You may need to recompute the bounding box if an instance is transformed via {@link InstancedMesh#setMatrixAt}. 15193 */ 15194 computeBoundingBox() { 15195 const geometry = this.geometry; 15196 const count = this.count; 15197 if (this.boundingBox === null) { 15198 this.boundingBox = new Box3(); 15199 } 15200 if (geometry.boundingBox === null) { 15201 geometry.computeBoundingBox(); 15202 } 15203 this.boundingBox.makeEmpty(); 15204 for (let i = 0; i < count; i++) { 15205 this.getMatrixAt(i, _instanceLocalMatrix); 15206 _box3.copy(geometry.boundingBox).applyMatrix4(_instanceLocalMatrix); 15207 this.boundingBox.union(_box3); 15208 } 15209 } 15210 /** 15211 * Computes the bounding sphere of the instanced mesh, and updates {@link InstancedMesh#boundingSphere} 15212 * The engine automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling. 15213 * You may need to recompute the bounding sphere if an instance is transformed via {@link InstancedMesh#setMatrixAt}. 15214 */ 15215 computeBoundingSphere() { 15216 const geometry = this.geometry; 15217 const count = this.count; 15218 if (this.boundingSphere === null) { 15219 this.boundingSphere = new Sphere(); 15220 } 15221 if (geometry.boundingSphere === null) { 15222 geometry.computeBoundingSphere(); 15223 } 15224 this.boundingSphere.makeEmpty(); 15225 for (let i = 0; i < count; i++) { 15226 this.getMatrixAt(i, _instanceLocalMatrix); 15227 _sphere$4.copy(geometry.boundingSphere).applyMatrix4(_instanceLocalMatrix); 15228 this.boundingSphere.union(_sphere$4); 15229 } 15230 } 15231 copy(source, recursive) { 15232 super.copy(source, recursive); 15233 this.instanceMatrix.copy(source.instanceMatrix); 15234 if (source.previousInstanceMatrix !== null) this.previousInstanceMatrix = source.previousInstanceMatrix.clone(); 15235 if (source.morphTexture !== null) this.morphTexture = source.morphTexture.clone(); 15236 if (source.instanceColor !== null) this.instanceColor = source.instanceColor.clone(); 15237 this.count = source.count; 15238 if (source.boundingBox !== null) this.boundingBox = source.boundingBox.clone(); 15239 if (source.boundingSphere !== null) this.boundingSphere = source.boundingSphere.clone(); 15240 return this; 15241 } 15242 /** 15243 * Gets the color of the defined instance. 15244 * 15245 * @param {number} index - The instance index. 15246 * @param {Color} color - The target object that is used to store the method's result. 15247 * @return {Color} A reference to the target color. 15248 */ 15249 getColorAt(index, color) { 15250 if (this.instanceColor === null) { 15251 return color.setRGB(1, 1, 1); 15252 } else { 15253 return color.fromArray(this.instanceColor.array, index * 3); 15254 } 15255 } 15256 /** 15257 * Gets the local transformation matrix of the defined instance. 15258 * 15259 * @param {number} index - The instance index. 15260 * @param {Matrix4} matrix - The target object that is used to store the method's result. 15261 * @return {Matrix4} A reference to the target matrix. 15262 */ 15263 getMatrixAt(index, matrix) { 15264 return matrix.fromArray(this.instanceMatrix.array, index * 16); 15265 } 15266 /** 15267 * Gets the morph target weights of the defined instance. 15268 * 15269 * @param {number} index - The instance index. 15270 * @param {Mesh} object - The target object that is used to store the method's result. 15271 */ 15272 getMorphAt(index, object) { 15273 const objectInfluences = object.morphTargetInfluences; 15274 const array = this.morphTexture.source.data.data; 15275 const len = objectInfluences.length + 1; 15276 const dataIndex = index * len + 1; 15277 for (let i = 0; i < objectInfluences.length; i++) { 15278 objectInfluences[i] = array[dataIndex + i]; 15279 } 15280 } 15281 raycast(raycaster, intersects2) { 15282 const matrixWorld = this.matrixWorld; 15283 const raycastTimes = this.count; 15284 _mesh$1.geometry = this.geometry; 15285 _mesh$1.material = this.material; 15286 if (_mesh$1.material === void 0) return; 15287 if (this.boundingSphere === null) this.computeBoundingSphere(); 15288 _sphere$4.copy(this.boundingSphere); 15289 _sphere$4.applyMatrix4(matrixWorld); 15290 if (raycaster.ray.intersectsSphere(_sphere$4) === false) return; 15291 for (let instanceId = 0; instanceId < raycastTimes; instanceId++) { 15292 this.getMatrixAt(instanceId, _instanceLocalMatrix); 15293 _instanceWorldMatrix.multiplyMatrices(matrixWorld, _instanceLocalMatrix); 15294 _mesh$1.matrixWorld = _instanceWorldMatrix; 15295 _mesh$1.raycast(raycaster, _instanceIntersects); 15296 for (let i = 0, l = _instanceIntersects.length; i < l; i++) { 15297 const intersect2 = _instanceIntersects[i]; 15298 intersect2.instanceId = instanceId; 15299 intersect2.object = this; 15300 intersects2.push(intersect2); 15301 } 15302 _instanceIntersects.length = 0; 15303 } 15304 } 15305 /** 15306 * Sets the given color to the defined instance. Make sure you set the `needsUpdate` flag of 15307 * {@link InstancedMesh#instanceColor} to `true` after updating all the colors. 15308 * 15309 * @param {number} index - The instance index. 15310 * @param {Color} color - The instance color. 15311 * @return {InstancedMesh} A reference to this instanced mesh. 15312 */ 15313 setColorAt(index, color) { 15314 if (this.instanceColor === null) { 15315 this.instanceColor = new InstancedBufferAttribute(new Float32Array(this.instanceMatrix.count * 3).fill(1), 3); 15316 } 15317 color.toArray(this.instanceColor.array, index * 3); 15318 return this; 15319 } 15320 /** 15321 * Sets the given local transformation matrix to the defined instance. Make sure you set the `needsUpdate` flag of 15322 * {@link InstancedMesh#instanceMatrix} to `true` after updating all the matrices. 15323 * 15324 * @param {number} index - The instance index. 15325 * @param {Matrix4} matrix - The local transformation. 15326 * @return {InstancedMesh} A reference to this instanced mesh. 15327 */ 15328 setMatrixAt(index, matrix) { 15329 matrix.toArray(this.instanceMatrix.array, index * 16); 15330 return this; 15331 } 15332 /** 15333 * Sets the morph target weights to the defined instance. Make sure you set the `needsUpdate` flag of 15334 * {@link InstancedMesh#morphTexture} to `true` after updating all the influences. 15335 * 15336 * @param {number} index - The instance index. 15337 * @param {Mesh} object - A mesh which `morphTargetInfluences` property containing the morph target weights 15338 * of a single instance. 15339 * @return {InstancedMesh} A reference to this instanced mesh. 15340 */ 15341 setMorphAt(index, object) { 15342 const objectInfluences = object.morphTargetInfluences; 15343 const len = objectInfluences.length + 1; 15344 if (this.morphTexture === null) { 15345 this.morphTexture = new DataTexture(new Float32Array(len * this.count), len, this.count, RedFormat, FloatType); 15346 } 15347 const array = this.morphTexture.source.data.data; 15348 let morphInfluencesSum = 0; 15349 for (let i = 0; i < objectInfluences.length; i++) { 15350 morphInfluencesSum += objectInfluences[i]; 15351 } 15352 const morphBaseInfluence = this.geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; 15353 const dataIndex = len * index; 15354 array[dataIndex] = morphBaseInfluence; 15355 array.set(objectInfluences, dataIndex + 1); 15356 return this; 15357 } 15358 updateMorphTargets() { 15359 } 15360 /** 15361 * Frees the GPU-related resources allocated by this instance. Call this 15362 * method whenever this instance is no longer used in your app. 15363 */ 15364 dispose() { 15365 this.dispatchEvent({ type: "dispose" }); 15366 if (this.morphTexture !== null) { 15367 this.morphTexture.dispose(); 15368 this.morphTexture = null; 15369 } 15370 } 15371}; 15372var _vector1 = /* @__PURE__ */ new Vector3(); 15373var _vector2 = /* @__PURE__ */ new Vector3(); 15374var _normalMatrix = /* @__PURE__ */ new Matrix3(); 15375var Plane = class { 15376 /** 15377 * Constructs a new plane. 15378 * 15379 * @param {Vector3} [normal=(1,0,0)] - A unit length vector defining the normal of the plane. 15380 * @param {number} [constant=0] - The signed distance from the origin to the plane. 15381 */ 15382 constructor(normal = new Vector3(1, 0, 0), constant = 0) { 15383 this.isPlane = true; 15384 this.normal = normal; 15385 this.constant = constant; 15386 } 15387 /** 15388 * Sets the plane components by copying the given values. 15389 * 15390 * @param {Vector3} normal - The normal. 15391 * @param {number} constant - The constant. 15392 * @return {Plane} A reference to this plane. 15393 */ 15394 set(normal, constant) { 15395 this.normal.copy(normal); 15396 this.constant = constant; 15397 return this; 15398 } 15399 /** 15400 * Sets the plane components by defining `x`, `y`, `z` as the 15401 * plane normal and `w` as the constant. 15402 * 15403 * @param {number} x - The value for the normal's x component. 15404 * @param {number} y - The value for the normal's y component. 15405 * @param {number} z - The value for the normal's z component. 15406 * @param {number} w - The constant value. 15407 * @return {Plane} A reference to this plane. 15408 */ 15409 setComponents(x, y, z, w) { 15410 this.normal.set(x, y, z); 15411 this.constant = w; 15412 return this; 15413 } 15414 /** 15415 * Sets the plane from the given normal and coplanar point (that is a point 15416 * that lies onto the plane). 15417 * 15418 * @param {Vector3} normal - The normal. 15419 * @param {Vector3} point - A coplanar point. 15420 * @return {Plane} A reference to this plane. 15421 */ 15422 setFromNormalAndCoplanarPoint(normal, point) { 15423 this.normal.copy(normal); 15424 this.constant = -point.dot(this.normal); 15425 return this; 15426 } 15427 /** 15428 * Sets the plane from three coplanar points. The winding order is 15429 * assumed to be counter-clockwise, and determines the direction of 15430 * the plane normal. 15431 * 15432 * @param {Vector3} a - The first coplanar point. 15433 * @param {Vector3} b - The second coplanar point. 15434 * @param {Vector3} c - The third coplanar point. 15435 * @return {Plane} A reference to this plane. 15436 */ 15437 setFromCoplanarPoints(a, b, c) { 15438 const normal = _vector1.subVectors(c, b).cross(_vector2.subVectors(a, b)).normalize(); 15439 this.setFromNormalAndCoplanarPoint(normal, a); 15440 return this; 15441 } 15442 /** 15443 * Copies the values of the given plane to this instance. 15444 * 15445 * @param {Plane} plane - The plane to copy. 15446 * @return {Plane} A reference to this plane. 15447 */ 15448 copy(plane) { 15449 this.normal.copy(plane.normal); 15450 this.constant = plane.constant; 15451 return this; 15452 } 15453 /** 15454 * Normalizes the plane normal and adjusts the constant accordingly. 15455 * 15456 * @return {Plane} A reference to this plane. 15457 */ 15458 normalize() { 15459 const inverseNormalLength = 1 / this.normal.length(); 15460 this.normal.multiplyScalar(inverseNormalLength); 15461 this.constant *= inverseNormalLength; 15462 return this; 15463 } 15464 /** 15465 * Negates both the plane normal and the constant. 15466 * 15467 * @return {Plane} A reference to this plane. 15468 */ 15469 negate() { 15470 this.constant *= -1; 15471 this.normal.negate(); 15472 return this; 15473 } 15474 /** 15475 * Returns the signed distance from the given point to this plane. 15476 * 15477 * @param {Vector3} point - The point to compute the distance for. 15478 * @return {number} The signed distance. 15479 */ 15480 distanceToPoint(point) { 15481 return this.normal.dot(point) + this.constant; 15482 } 15483 /** 15484 * Returns the signed distance from the given sphere to this plane. 15485 * 15486 * @param {Sphere} sphere - The sphere to compute the distance for. 15487 * @return {number} The signed distance. 15488 */ 15489 distanceToSphere(sphere) { 15490 return this.distanceToPoint(sphere.center) - sphere.radius; 15491 } 15492 /** 15493 * Projects a the given point onto the plane. 15494 * 15495 * @param {Vector3} point - The point to project. 15496 * @param {Vector3} target - The target vector that is used to store the method's result. 15497 * @return {Vector3} The projected point on the plane. 15498 */ 15499 projectPoint(point, target) { 15500 return target.copy(point).addScaledVector(this.normal, -this.distanceToPoint(point)); 15501 } 15502 /** 15503 * Returns the intersection point of the passed line and the plane. Returns 15504 * `null` if the line does not intersect. Returns the line's starting point if 15505 * the line is coplanar with the plane. 15506 * 15507 * @param {Line3} line - The line to compute the intersection for. 15508 * @param {Vector3} target - The target vector that is used to store the method's result. 15509 * @param {boolean} [clampToLine=true] - Whether to clamp the intersection to the line segment. 15510 * @return {?Vector3} The intersection point. Returns `null` if no intersection is detected. 15511 */ 15512 intersectLine(line, target, clampToLine = true) { 15513 const direction = line.delta(_vector1); 15514 const denominator = this.normal.dot(direction); 15515 if (denominator === 0) { 15516 if (this.distanceToPoint(line.start) === 0) { 15517 return target.copy(line.start); 15518 } 15519 return null; 15520 } 15521 const t = -(line.start.dot(this.normal) + this.constant) / denominator; 15522 if (clampToLine === true && (t < 0 || t > 1)) { 15523 return null; 15524 } 15525 return target.copy(line.start).addScaledVector(direction, t); 15526 } 15527 /** 15528 * Returns `true` if the given line segment intersects with (passes through) the plane. 15529 * 15530 * @param {Line3} line - The line to test. 15531 * @return {boolean} Whether the given line segment intersects with the plane or not. 15532 */ 15533 intersectsLine(line) { 15534 const startSign = this.distanceToPoint(line.start); 15535 const endSign = this.distanceToPoint(line.end); 15536 return startSign < 0 && endSign > 0 || endSign < 0 && startSign > 0; 15537 } 15538 /** 15539 * Returns `true` if the given bounding box intersects with the plane. 15540 * 15541 * @param {Box3} box - The bounding box to test. 15542 * @return {boolean} Whether the given bounding box intersects with the plane or not. 15543 */ 15544 intersectsBox(box) { 15545 return box.intersectsPlane(this); 15546 } 15547 /** 15548 * Returns `true` if the given bounding sphere intersects with the plane. 15549 * 15550 * @param {Sphere} sphere - The bounding sphere to test. 15551 * @return {boolean} Whether the given bounding sphere intersects with the plane or not. 15552 */ 15553 intersectsSphere(sphere) { 15554 return sphere.intersectsPlane(this); 15555 } 15556 /** 15557 * Returns a coplanar vector to the plane, by calculating the 15558 * projection of the normal at the origin onto the plane. 15559 * 15560 * @param {Vector3} target - The target vector that is used to store the method's result. 15561 * @return {Vector3} The coplanar point. 15562 */ 15563 coplanarPoint(target) { 15564 return target.copy(this.normal).multiplyScalar(-this.constant); 15565 } 15566 /** 15567 * Apply a 4x4 matrix to the plane. The matrix must be an affine, homogeneous transform. 15568 * 15569 * The optional normal matrix can be pre-computed like so: 15570 * ```js 15571 * const optionalNormalMatrix = new THREE.Matrix3().getNormalMatrix( matrix ); 15572 * ``` 15573 * 15574 * @param {Matrix4} matrix - The transformation matrix. 15575 * @param {Matrix4} [optionalNormalMatrix] - A pre-computed normal matrix. 15576 * @return {Plane} A reference to this plane. 15577 */ 15578 applyMatrix4(matrix, optionalNormalMatrix) { 15579 const normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix(matrix); 15580 const referencePoint = this.coplanarPoint(_vector1).applyMatrix4(matrix); 15581 const normal = this.normal.applyMatrix3(normalMatrix).normalize(); 15582 this.constant = -referencePoint.dot(normal); 15583 return this; 15584 } 15585 /** 15586 * Translates the plane by the distance defined by the given offset vector. 15587 * Note that this only affects the plane constant and will not affect the normal vector. 15588 * 15589 * @param {Vector3} offset - The offset vector. 15590 * @return {Plane} A reference to this plane. 15591 */ 15592 translate(offset) { 15593 this.constant -= offset.dot(this.normal); 15594 return this; 15595 } 15596 /** 15597 * Returns `true` if this plane is equal with the given one. 15598 * 15599 * @param {Plane} plane - The plane to test for equality. 15600 * @return {boolean} Whether this plane is equal with the given one. 15601 */ 15602 equals(plane) { 15603 return plane.normal.equals(this.normal) && plane.constant === this.constant; 15604 } 15605 /** 15606 * Returns a new plane with copied values from this instance. 15607 * 15608 * @return {Plane} A clone of this instance. 15609 */ 15610 clone() { 15611 return new this.constructor().copy(this); 15612 } 15613}; 15614var _sphere$3 = /* @__PURE__ */ new Sphere(); 15615var _defaultSpriteCenter = /* @__PURE__ */ new Vector2(0.5, 0.5); 15616var _vector$6 = /* @__PURE__ */ new Vector3(); 15617var Frustum = class { 15618 /** 15619 * Constructs a new frustum. 15620 * 15621 * @param {Plane} [p0] - The first plane that encloses the frustum. 15622 * @param {Plane} [p1] - The second plane that encloses the frustum. 15623 * @param {Plane} [p2] - The third plane that encloses the frustum. 15624 * @param {Plane} [p3] - The fourth plane that encloses the frustum. 15625 * @param {Plane} [p4] - The fifth plane that encloses the frustum. 15626 * @param {Plane} [p5] - The sixth plane that encloses the frustum. 15627 */ 15628 constructor(p0 = new Plane(), p1 = new Plane(), p2 = new Plane(), p3 = new Plane(), p4 = new Plane(), p5 = new Plane()) { 15629 this.planes = [p0, p1, p2, p3, p4, p5]; 15630 } 15631 /** 15632 * Sets the frustum planes by copying the given planes. 15633 * 15634 * @param {Plane} [p0] - The first plane that encloses the frustum. 15635 * @param {Plane} [p1] - The second plane that encloses the frustum. 15636 * @param {Plane} [p2] - The third plane that encloses the frustum. 15637 * @param {Plane} [p3] - The fourth plane that encloses the frustum. 15638 * @param {Plane} [p4] - The fifth plane that encloses the frustum. 15639 * @param {Plane} [p5] - The sixth plane that encloses the frustum. 15640 * @return {Frustum} A reference to this frustum. 15641 */ 15642 set(p0, p1, p2, p3, p4, p5) { 15643 const planes = this.planes; 15644 planes[0].copy(p0); 15645 planes[1].copy(p1); 15646 planes[2].copy(p2); 15647 planes[3].copy(p3); 15648 planes[4].copy(p4); 15649 planes[5].copy(p5); 15650 return this; 15651 } 15652 /** 15653 * Copies the values of the given frustum to this instance. 15654 * 15655 * @param {Frustum} frustum - The frustum to copy. 15656 * @return {Frustum} A reference to this frustum. 15657 */ 15658 copy(frustum) { 15659 const planes = this.planes; 15660 for (let i = 0; i < 6; i++) { 15661 planes[i].copy(frustum.planes[i]); 15662 } 15663 return this; 15664 } 15665 /** 15666 * Sets the frustum planes from the given projection matrix. 15667 * 15668 * @param {Matrix4} m - The projection matrix. 15669 * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} coordinateSystem - The coordinate system. 15670 * @param {boolean} [reversedDepth=false] - Whether to use a reversed depth. 15671 * @return {Frustum} A reference to this frustum. 15672 */ 15673 setFromProjectionMatrix(m, coordinateSystem = WebGLCoordinateSystem, reversedDepth = false) { 15674 const planes = this.planes; 15675 const me = m.elements; 15676 const me0 = me[0], me1 = me[1], me2 = me[2], me3 = me[3]; 15677 const me4 = me[4], me5 = me[5], me6 = me[6], me7 = me[7]; 15678 const me8 = me[8], me9 = me[9], me10 = me[10], me11 = me[11]; 15679 const me12 = me[12], me13 = me[13], me14 = me[14], me15 = me[15]; 15680 planes[0].setComponents(me3 - me0, me7 - me4, me11 - me8, me15 - me12).normalize(); 15681 planes[1].setComponents(me3 + me0, me7 + me4, me11 + me8, me15 + me12).normalize(); 15682 planes[2].setComponents(me3 + me1, me7 + me5, me11 + me9, me15 + me13).normalize(); 15683 planes[3].setComponents(me3 - me1, me7 - me5, me11 - me9, me15 - me13).normalize(); 15684 if (reversedDepth) { 15685 planes[4].setComponents(me2, me6, me10, me14).normalize(); 15686 planes[5].setComponents(me3 - me2, me7 - me6, me11 - me10, me15 - me14).normalize(); 15687 } else { 15688 planes[4].setComponents(me3 - me2, me7 - me6, me11 - me10, me15 - me14).normalize(); 15689 if (coordinateSystem === WebGLCoordinateSystem) { 15690 planes[5].setComponents(me3 + me2, me7 + me6, me11 + me10, me15 + me14).normalize(); 15691 } else if (coordinateSystem === WebGPUCoordinateSystem) { 15692 planes[5].setComponents(me2, me6, me10, me14).normalize(); 15693 } else { 15694 throw new Error("THREE.Frustum.setFromProjectionMatrix(): Invalid coordinate system: " + coordinateSystem); 15695 } 15696 } 15697 return this; 15698 } 15699 /** 15700 * Returns `true` if the 3D object's bounding sphere is intersecting this frustum. 15701 * 15702 * Note that the 3D object must have a geometry so that the bounding sphere can be calculated. 15703 * 15704 * @param {Object3D} object - The 3D object to test. 15705 * @return {boolean} Whether the 3D object's bounding sphere is intersecting this frustum or not. 15706 */ 15707 intersectsObject(object) { 15708 if (object.boundingSphere !== void 0) { 15709 if (object.boundingSphere === null) object.computeBoundingSphere(); 15710 _sphere$3.copy(object.boundingSphere).applyMatrix4(object.matrixWorld); 15711 } else { 15712 const geometry = object.geometry; 15713 if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); 15714 _sphere$3.copy(geometry.boundingSphere).applyMatrix4(object.matrixWorld); 15715 } 15716 return this.intersectsSphere(_sphere$3); 15717 } 15718 /** 15719 * Returns `true` if the given sprite is intersecting this frustum. 15720 * 15721 * @param {Sprite} sprite - The sprite to test. 15722 * @return {boolean} Whether the sprite is intersecting this frustum or not. 15723 */ 15724 intersectsSprite(sprite) { 15725 _sphere$3.center.set(0, 0, 0); 15726 const offset = _defaultSpriteCenter.distanceTo(sprite.center); 15727 _sphere$3.radius = 0.7071067811865476 + offset; 15728 _sphere$3.applyMatrix4(sprite.matrixWorld); 15729 return this.intersectsSphere(_sphere$3); 15730 } 15731 /** 15732 * Returns `true` if the given bounding sphere is intersecting this frustum. 15733 * 15734 * @param {Sphere} sphere - The bounding sphere to test. 15735 * @return {boolean} Whether the bounding sphere is intersecting this frustum or not. 15736 */ 15737 intersectsSphere(sphere) { 15738 const planes = this.planes; 15739 const center = sphere.center; 15740 const negRadius = -sphere.radius; 15741 for (let i = 0; i < 6; i++) { 15742 const distance = planes[i].distanceToPoint(center); 15743 if (distance < negRadius) { 15744 return false; 15745 } 15746 } 15747 return true; 15748 } 15749 /** 15750 * Returns `true` if the given bounding box is intersecting this frustum. 15751 * 15752 * @param {Box3} box - The bounding box to test. 15753 * @return {boolean} Whether the bounding box is intersecting this frustum or not. 15754 */ 15755 intersectsBox(box) { 15756 const planes = this.planes; 15757 for (let i = 0; i < 6; i++) { 15758 const plane = planes[i]; 15759 _vector$6.x = plane.normal.x > 0 ? box.max.x : box.min.x; 15760 _vector$6.y = plane.normal.y > 0 ? box.max.y : box.min.y; 15761 _vector$6.z = plane.normal.z > 0 ? box.max.z : box.min.z; 15762 if (plane.distanceToPoint(_vector$6) < 0) { 15763 return false; 15764 } 15765 } 15766 return true; 15767 } 15768 /** 15769 * Returns `true` if the given point lies within the frustum. 15770 * 15771 * @param {Vector3} point - The point to test. 15772 * @return {boolean} Whether the point lies within this frustum or not. 15773 */ 15774 containsPoint(point) { 15775 const planes = this.planes; 15776 for (let i = 0; i < 6; i++) { 15777 if (planes[i].distanceToPoint(point) < 0) { 15778 return false; 15779 } 15780 } 15781 return true; 15782 } 15783 /** 15784 * Returns a new frustum with copied values from this instance. 15785 * 15786 * @return {Frustum} A clone of this instance. 15787 */ 15788 clone() { 15789 return new this.constructor().copy(this); 15790 } 15791}; 15792var _projScreenMatrix$1 = /* @__PURE__ */ new Matrix4(); 15793var _frustum$1 = /* @__PURE__ */ new Frustum(); 15794var FrustumArray = class _FrustumArray { 15795 /** 15796 * Constructs a new frustum array. 15797 * 15798 */ 15799 constructor() { 15800 this.coordinateSystem = WebGLCoordinateSystem; 15801 } 15802 /** 15803 * Returns `true` if the 3D object's bounding sphere is intersecting any frustum 15804 * from the camera array. 15805 * 15806 * @param {Object3D} object - The 3D object to test. 15807 * @param {Object} cameraArray - An object with a cameras property containing an array of cameras. 15808 * @return {boolean} Whether the 3D object is visible in any camera. 15809 */ 15810 intersectsObject(object, cameraArray) { 15811 if (!cameraArray.isArrayCamera || cameraArray.cameras.length === 0) { 15812 return false; 15813 } 15814 for (let i = 0; i < cameraArray.cameras.length; i++) { 15815 const camera = cameraArray.cameras[i]; 15816 _projScreenMatrix$1.multiplyMatrices( 15817 camera.projectionMatrix, 15818 camera.matrixWorldInverse 15819 ); 15820 _frustum$1.setFromProjectionMatrix( 15821 _projScreenMatrix$1, 15822 camera.coordinateSystem, 15823 camera.reversedDepth 15824 ); 15825 if (_frustum$1.intersectsObject(object)) { 15826 return true; 15827 } 15828 } 15829 return false; 15830 } 15831 /** 15832 * Returns `true` if the given sprite is intersecting any frustum 15833 * from the camera array. 15834 * 15835 * @param {Sprite} sprite - The sprite to test. 15836 * @param {Object} cameraArray - An object with a cameras property containing an array of cameras. 15837 * @return {boolean} Whether the sprite is visible in any camera. 15838 */ 15839 intersectsSprite(sprite, cameraArray) { 15840 if (!cameraArray || !cameraArray.cameras || cameraArray.cameras.length === 0) { 15841 return false; 15842 } 15843 for (let i = 0; i < cameraArray.cameras.length; i++) { 15844 const camera = cameraArray.cameras[i]; 15845 _projScreenMatrix$1.multiplyMatrices( 15846 camera.projectionMatrix, 15847 camera.matrixWorldInverse 15848 ); 15849 _frustum$1.setFromProjectionMatrix( 15850 _projScreenMatrix$1, 15851 camera.coordinateSystem, 15852 camera.reversedDepth 15853 ); 15854 if (_frustum$1.intersectsSprite(sprite)) { 15855 return true; 15856 } 15857 } 15858 return false; 15859 } 15860 /** 15861 * Returns `true` if the given bounding sphere is intersecting any frustum 15862 * from the camera array. 15863 * 15864 * @param {Sphere} sphere - The bounding sphere to test. 15865 * @param {Object} cameraArray - An object with a cameras property containing an array of cameras. 15866 * @return {boolean} Whether the sphere is visible in any camera. 15867 */ 15868 intersectsSphere(sphere, cameraArray) { 15869 if (!cameraArray || !cameraArray.cameras || cameraArray.cameras.length === 0) { 15870 return false; 15871 } 15872 for (let i = 0; i < cameraArray.cameras.length; i++) { 15873 const camera = cameraArray.cameras[i]; 15874 _projScreenMatrix$1.multiplyMatrices( 15875 camera.projectionMatrix, 15876 camera.matrixWorldInverse 15877 ); 15878 _frustum$1.setFromProjectionMatrix( 15879 _projScreenMatrix$1, 15880 camera.coordinateSystem, 15881 camera.reversedDepth 15882 ); 15883 if (_frustum$1.intersectsSphere(sphere)) { 15884 return true; 15885 } 15886 } 15887 return false; 15888 } 15889 /** 15890 * Returns `true` if the given bounding box is intersecting any frustum 15891 * from the camera array. 15892 * 15893 * @param {Box3} box - The bounding box to test. 15894 * @param {Object} cameraArray - An object with a cameras property containing an array of cameras. 15895 * @return {boolean} Whether the box is visible in any camera. 15896 */ 15897 intersectsBox(box, cameraArray) { 15898 if (!cameraArray || !cameraArray.cameras || cameraArray.cameras.length === 0) { 15899 return false; 15900 } 15901 for (let i = 0; i < cameraArray.cameras.length; i++) { 15902 const camera = cameraArray.cameras[i]; 15903 _projScreenMatrix$1.multiplyMatrices( 15904 camera.projectionMatrix, 15905 camera.matrixWorldInverse 15906 ); 15907 _frustum$1.setFromProjectionMatrix( 15908 _projScreenMatrix$1, 15909 camera.coordinateSystem, 15910 camera.reversedDepth 15911 ); 15912 if (_frustum$1.intersectsBox(box)) { 15913 return true; 15914 } 15915 } 15916 return false; 15917 } 15918 /** 15919 * Returns `true` if the given point lies within any frustum 15920 * from the camera array. 15921 * 15922 * @param {Vector3} point - The point to test. 15923 * @param {Object} cameraArray - An object with a cameras property containing an array of cameras. 15924 * @return {boolean} Whether the point is visible in any camera. 15925 */ 15926 containsPoint(point, cameraArray) { 15927 if (!cameraArray || !cameraArray.cameras || cameraArray.cameras.length === 0) { 15928 return false; 15929 } 15930 for (let i = 0; i < cameraArray.cameras.length; i++) { 15931 const camera = cameraArray.cameras[i]; 15932 _projScreenMatrix$1.multiplyMatrices( 15933 camera.projectionMatrix, 15934 camera.matrixWorldInverse 15935 ); 15936 _frustum$1.setFromProjectionMatrix( 15937 _projScreenMatrix$1, 15938 camera.coordinateSystem, 15939 camera.reversedDepth 15940 ); 15941 if (_frustum$1.containsPoint(point)) { 15942 return true; 15943 } 15944 } 15945 return false; 15946 } 15947 /** 15948 * Returns a new frustum array with copied values from this instance. 15949 * 15950 * @return {FrustumArray} A clone of this instance. 15951 */ 15952 clone() { 15953 return new _FrustumArray(); 15954 } 15955}; 15956var LineBasicMaterial = class extends Material { 15957 /** 15958 * Constructs a new line basic material. 15959 * 15960 * @param {Object} [parameters] - An object with one or more properties 15961 * defining the material's appearance. Any property of the material 15962 * (including any property from inherited materials) can be passed 15963 * in here. Color values can be passed any type of value accepted 15964 * by {@link Color#set}. 15965 */ 15966 constructor(parameters) { 15967 super(); 15968 this.isLineBasicMaterial = true; 15969 this.type = "LineBasicMaterial"; 15970 this.color = new Color(16777215); 15971 this.map = null; 15972 this.linewidth = 1; 15973 this.linecap = "round"; 15974 this.linejoin = "round"; 15975 this.fog = true; 15976 this.setValues(parameters); 15977 } 15978 copy(source) { 15979 super.copy(source); 15980 this.color.copy(source.color); 15981 this.map = source.map; 15982 this.linewidth = source.linewidth; 15983 this.linecap = source.linecap; 15984 this.linejoin = source.linejoin; 15985 this.fog = source.fog; 15986 return this; 15987 } 15988}; 15989var _vStart = /* @__PURE__ */ new Vector3(); 15990var _vEnd = /* @__PURE__ */ new Vector3(); 15991var _inverseMatrix$1 = /* @__PURE__ */ new Matrix4(); 15992var _ray$1 = /* @__PURE__ */ new Ray(); 15993var _sphere$1 = /* @__PURE__ */ new Sphere(); 15994var _intersectPointOnRay = /* @__PURE__ */ new Vector3(); 15995var _intersectPointOnSegment = /* @__PURE__ */ new Vector3(); 15996var Line = class extends Object3D { 15997 /** 15998 * Constructs a new line. 15999 * 16000 * @param {BufferGeometry} [geometry] - The line geometry. 16001 * @param {Material|Array<Material>} [material] - The line material. 16002 */ 16003 constructor(geometry = new BufferGeometry(), material = new LineBasicMaterial()) { 16004 super(); 16005 this.isLine = true; 16006 this.type = "Line"; 16007 this.geometry = geometry; 16008 this.material = material; 16009 this.morphTargetDictionary = void 0; 16010 this.morphTargetInfluences = void 0; 16011 this.updateMorphTargets(); 16012 } 16013 copy(source, recursive) { 16014 super.copy(source, recursive); 16015 this.material = Array.isArray(source.material) ? source.material.slice() : source.material; 16016 this.geometry = source.geometry; 16017 return this; 16018 } 16019 /** 16020 * Computes an array of distance values which are necessary for rendering dashed lines. 16021 * For each vertex in the geometry, the method calculates the cumulative length from the 16022 * current point to the very beginning of the line. 16023 * 16024 * @return {Line} A reference to this line. 16025 */ 16026 computeLineDistances() { 16027 const geometry = this.geometry; 16028 if (geometry.index === null) { 16029 const positionAttribute = geometry.attributes.position; 16030 const lineDistances = [0]; 16031 for (let i = 1, l = positionAttribute.count; i < l; i++) { 16032 _vStart.fromBufferAttribute(positionAttribute, i - 1); 16033 _vEnd.fromBufferAttribute(positionAttribute, i); 16034 lineDistances[i] = lineDistances[i - 1]; 16035 lineDistances[i] += _vStart.distanceTo(_vEnd); 16036 } 16037 geometry.setAttribute("lineDistance", new Float32BufferAttribute(lineDistances, 1)); 16038 } else { 16039 warn("Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry."); 16040 } 16041 return this; 16042 } 16043 /** 16044 * Computes intersection points between a casted ray and this line. 16045 * 16046 * @param {Raycaster} raycaster - The raycaster. 16047 * @param {Array<Object>} intersects - The target array that holds the intersection points. 16048 */ 16049 raycast(raycaster, intersects2) { 16050 const geometry = this.geometry; 16051 const matrixWorld = this.matrixWorld; 16052 const threshold = raycaster.params.Line.threshold; 16053 const drawRange = geometry.drawRange; 16054 if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); 16055 _sphere$1.copy(geometry.boundingSphere); 16056 _sphere$1.applyMatrix4(matrixWorld); 16057 _sphere$1.radius += threshold; 16058 if (raycaster.ray.intersectsSphere(_sphere$1) === false) return; 16059 _inverseMatrix$1.copy(matrixWorld).invert(); 16060 _ray$1.copy(raycaster.ray).applyMatrix4(_inverseMatrix$1); 16061 const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3); 16062 const localThresholdSq = localThreshold * localThreshold; 16063 const step = this.isLineSegments ? 2 : 1; 16064 const index = geometry.index; 16065 const attributes = geometry.attributes; 16066 const positionAttribute = attributes.position; 16067 if (index !== null) { 16068 const start = Math.max(0, drawRange.start); 16069 const end = Math.min(index.count, drawRange.start + drawRange.count); 16070 for (let i = start, l = end - 1; i < l; i += step) { 16071 const a = index.getX(i); 16072 const b = index.getX(i + 1); 16073 const intersect2 = checkIntersection(this, raycaster, _ray$1, localThresholdSq, a, b, i); 16074 if (intersect2) { 16075 intersects2.push(intersect2); 16076 } 16077 } 16078 if (this.isLineLoop) { 16079 const a = index.getX(end - 1); 16080 const b = index.getX(start); 16081 const intersect2 = checkIntersection(this, raycaster, _ray$1, localThresholdSq, a, b, end - 1); 16082 if (intersect2) { 16083 intersects2.push(intersect2); 16084 } 16085 } 16086 } else { 16087 const start = Math.max(0, drawRange.start); 16088 const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count); 16089 for (let i = start, l = end - 1; i < l; i += step) { 16090 const intersect2 = checkIntersection(this, raycaster, _ray$1, localThresholdSq, i, i + 1, i); 16091 if (intersect2) { 16092 intersects2.push(intersect2); 16093 } 16094 } 16095 if (this.isLineLoop) { 16096 const intersect2 = checkIntersection(this, raycaster, _ray$1, localThresholdSq, end - 1, start, end - 1); 16097 if (intersect2) { 16098 intersects2.push(intersect2); 16099 } 16100 } 16101 } 16102 } 16103 /** 16104 * Sets the values of {@link Line#morphTargetDictionary} and {@link Line#morphTargetInfluences} 16105 * to make sure existing morph targets can influence this 3D object. 16106 */ 16107 updateMorphTargets() { 16108 const geometry = this.geometry; 16109 const morphAttributes = geometry.morphAttributes; 16110 const keys = Object.keys(morphAttributes); 16111 if (keys.length > 0) { 16112 const morphAttribute = morphAttributes[keys[0]]; 16113 if (morphAttribute !== void 0) { 16114 this.morphTargetInfluences = []; 16115 this.morphTargetDictionary = {}; 16116 for (let m = 0, ml = morphAttribute.length; m < ml; m++) { 16117 const name = morphAttribute[m].name || String(m); 16118 this.morphTargetInfluences.push(0); 16119 this.morphTargetDictionary[name] = m; 16120 } 16121 } 16122 } 16123 } 16124}; 16125function checkIntersection(object, raycaster, ray, thresholdSq, a, b, i) { 16126 const positionAttribute = object.geometry.attributes.position; 16127 _vStart.fromBufferAttribute(positionAttribute, a); 16128 _vEnd.fromBufferAttribute(positionAttribute, b); 16129 const distSq = ray.distanceSqToSegment(_vStart, _vEnd, _intersectPointOnRay, _intersectPointOnSegment); 16130 if (distSq > thresholdSq) return; 16131 _intersectPointOnRay.applyMatrix4(object.matrixWorld); 16132 const distance = raycaster.ray.origin.distanceTo(_intersectPointOnRay); 16133 if (distance < raycaster.near || distance > raycaster.far) return; 16134 return { 16135 distance, 16136 // What do we want? intersection point on the ray or on the segment?? 16137 // point: raycaster.ray.at( distance ), 16138 point: _intersectPointOnSegment.clone().applyMatrix4(object.matrixWorld), 16139 index: i, 16140 face: null, 16141 faceIndex: null, 16142 barycoord: null, 16143 object 16144 }; 16145} 16146var _start = /* @__PURE__ */ new Vector3(); 16147var _end = /* @__PURE__ */ new Vector3(); 16148var LineSegments = class extends Line { 16149 /** 16150 * Constructs a new line segments. 16151 * 16152 * @param {BufferGeometry} [geometry] - The line geometry. 16153 * @param {Material|Array<Material>} [material] - The line material. 16154 */ 16155 constructor(geometry, material) { 16156 super(geometry, material); 16157 this.isLineSegments = true; 16158 this.type = "LineSegments"; 16159 } 16160 computeLineDistances() { 16161 const geometry = this.geometry; 16162 if (geometry.index === null) { 16163 const positionAttribute = geometry.attributes.position; 16164 const lineDistances = []; 16165 for (let i = 0, l = positionAttribute.count; i < l; i += 2) { 16166 _start.fromBufferAttribute(positionAttribute, i); 16167 _end.fromBufferAttribute(positionAttribute, i + 1); 16168 lineDistances[i] = i === 0 ? 0 : lineDistances[i - 1]; 16169 lineDistances[i + 1] = lineDistances[i] + _start.distanceTo(_end); 16170 } 16171 geometry.setAttribute("lineDistance", new Float32BufferAttribute(lineDistances, 1)); 16172 } else { 16173 warn("LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry."); 16174 } 16175 return this; 16176 } 16177}; 16178var LineLoop = class extends Line { 16179 /** 16180 * Constructs a new line loop. 16181 * 16182 * @param {BufferGeometry} [geometry] - The line geometry. 16183 * @param {Material|Array<Material>} [material] - The line material. 16184 */ 16185 constructor(geometry, material) { 16186 super(geometry, material); 16187 this.isLineLoop = true; 16188 this.type = "LineLoop"; 16189 } 16190}; 16191var PointsMaterial = class extends Material { 16192 /** 16193 * Constructs a new points material. 16194 * 16195 * @param {Object} [parameters] - An object with one or more properties 16196 * defining the material's appearance. Any property of the material 16197 * (including any property from inherited materials) can be passed 16198 * in here. Color values can be passed any type of value accepted 16199 * by {@link Color#set}. 16200 */ 16201 constructor(parameters) { 16202 super(); 16203 this.isPointsMaterial = true; 16204 this.type = "PointsMaterial"; 16205 this.color = new Color(16777215); 16206 this.map = null; 16207 this.alphaMap = null; 16208 this.size = 1; 16209 this.sizeAttenuation = true; 16210 this.fog = true; 16211 this.setValues(parameters); 16212 } 16213 copy(source) { 16214 super.copy(source); 16215 this.color.copy(source.color); 16216 this.map = source.map; 16217 this.alphaMap = source.alphaMap; 16218 this.size = source.size; 16219 this.sizeAttenuation = source.sizeAttenuation; 16220 this.fog = source.fog; 16221 return this; 16222 } 16223}; 16224var _inverseMatrix = /* @__PURE__ */ new Matrix4(); 16225var _ray = /* @__PURE__ */ new Ray(); 16226var _sphere = /* @__PURE__ */ new Sphere(); 16227var _position$3 = /* @__PURE__ */ new Vector3(); 16228var Points = class extends Object3D { 16229 /** 16230 * Constructs a new point cloud. 16231 * 16232 * @param {BufferGeometry} [geometry] - The points geometry. 16233 * @param {Material|Array<Material>} [material] - The points material. 16234 */ 16235 constructor(geometry = new BufferGeometry(), material = new PointsMaterial()) { 16236 super(); 16237 this.isPoints = true; 16238 this.type = "Points"; 16239 this.geometry = geometry; 16240 this.material = material; 16241 this.morphTargetDictionary = void 0; 16242 this.morphTargetInfluences = void 0; 16243 this.updateMorphTargets(); 16244 } 16245 copy(source, recursive) { 16246 super.copy(source, recursive); 16247 this.material = Array.isArray(source.material) ? source.material.slice() : source.material; 16248 this.geometry = source.geometry; 16249 return this; 16250 } 16251 /** 16252 * Computes intersection points between a casted ray and this point cloud. 16253 * 16254 * @param {Raycaster} raycaster - The raycaster. 16255 * @param {Array<Object>} intersects - The target array that holds the intersection points. 16256 */ 16257 raycast(raycaster, intersects2) { 16258 const geometry = this.geometry; 16259 const matrixWorld = this.matrixWorld; 16260 const threshold = raycaster.params.Points.threshold; 16261 const drawRange = geometry.drawRange; 16262 if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); 16263 _sphere.copy(geometry.boundingSphere); 16264 _sphere.applyMatrix4(matrixWorld); 16265 _sphere.radius += threshold; 16266 if (raycaster.ray.intersectsSphere(_sphere) === false) return; 16267 _inverseMatrix.copy(matrixWorld).invert(); 16268 _ray.copy(raycaster.ray).applyMatrix4(_inverseMatrix); 16269 const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3); 16270 const localThresholdSq = localThreshold * localThreshold; 16271 const index = geometry.index; 16272 const attributes = geometry.attributes; 16273 const positionAttribute = attributes.position; 16274 if (index !== null) { 16275 const start = Math.max(0, drawRange.start); 16276 const end = Math.min(index.count, drawRange.start + drawRange.count); 16277 for (let i = start, il = end; i < il; i++) { 16278 const a = index.getX(i); 16279 _position$3.fromBufferAttribute(positionAttribute, a); 16280 testPoint(_position$3, a, localThresholdSq, matrixWorld, raycaster, intersects2, this); 16281 } 16282 } else { 16283 const start = Math.max(0, drawRange.start); 16284 const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count); 16285 for (let i = start, l = end; i < l; i++) { 16286 _position$3.fromBufferAttribute(positionAttribute, i); 16287 testPoint(_position$3, i, localThresholdSq, matrixWorld, raycaster, intersects2, this); 16288 } 16289 } 16290 } 16291 /** 16292 * Sets the values of {@link Points#morphTargetDictionary} and {@link Points#morphTargetInfluences} 16293 * to make sure existing morph targets can influence this 3D object. 16294 */ 16295 updateMorphTargets() { 16296 const geometry = this.geometry; 16297 const morphAttributes = geometry.morphAttributes; 16298 const keys = Object.keys(morphAttributes); 16299 if (keys.length > 0) { 16300 const morphAttribute = morphAttributes[keys[0]]; 16301 if (morphAttribute !== void 0) { 16302 this.morphTargetInfluences = []; 16303 this.morphTargetDictionary = {}; 16304 for (let m = 0, ml = morphAttribute.length; m < ml; m++) { 16305 const name = morphAttribute[m].name || String(m); 16306 this.morphTargetInfluences.push(0); 16307 this.morphTargetDictionary[name] = m; 16308 } 16309 } 16310 } 16311 } 16312}; 16313function testPoint(point, index, localThresholdSq, matrixWorld, raycaster, intersects2, object) { 16314 const rayPointDistanceSq = _ray.distanceSqToPoint(point); 16315 if (rayPointDistanceSq < localThresholdSq) { 16316 const intersectPoint = new Vector3(); 16317 _ray.closestPointToPoint(point, intersectPoint); 16318 intersectPoint.applyMatrix4(matrixWorld); 16319 const distance = raycaster.ray.origin.distanceTo(intersectPoint); 16320 if (distance < raycaster.near || distance > raycaster.far) return; 16321 intersects2.push({ 16322 distance, 16323 distanceToRay: Math.sqrt(rayPointDistanceSq), 16324 point: intersectPoint, 16325 index, 16326 face: null, 16327 faceIndex: null, 16328 barycoord: null, 16329 object 16330 }); 16331 } 16332} 16333var FramebufferTexture = class extends Texture { 16334 /** 16335 * Constructs a new framebuffer texture. 16336 * 16337 * @param {number} [width] - The width of the texture. 16338 * @param {number} [height] - The height of the texture. 16339 */ 16340 constructor(width, height) { 16341 super({ width, height }); 16342 this.isFramebufferTexture = true; 16343 this.magFilter = NearestFilter; 16344 this.minFilter = NearestFilter; 16345 this.generateMipmaps = false; 16346 this.needsUpdate = true; 16347 } 16348}; 16349var CompressedTexture = class extends Texture { 16350 /** 16351 * Constructs a new compressed texture. 16352 * 16353 * @param {Array<Object>} mipmaps - This array holds for all mipmaps (including the bases mip) 16354 * the data and dimensions. 16355 * @param {number} width - The width of the texture. 16356 * @param {number} height - The height of the texture. 16357 * @param {number} [format=RGBAFormat] - The texture format. 16358 * @param {number} [type=UnsignedByteType] - The texture type. 16359 * @param {number} [mapping=Texture.DEFAULT_MAPPING] - The texture mapping. 16360 * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value. 16361 * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value. 16362 * @param {number} [magFilter=LinearFilter] - The mag filter value. 16363 * @param {number} [minFilter=LinearMipmapLinearFilter] - The min filter value. 16364 * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value. 16365 * @param {string} [colorSpace=NoColorSpace] - The color space. 16366 */ 16367 constructor(mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, colorSpace) { 16368 super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace); 16369 this.isCompressedTexture = true; 16370 this.image = { width, height }; 16371 this.mipmaps = mipmaps; 16372 this.flipY = false; 16373 this.generateMipmaps = false; 16374 } 16375}; 16376var CubeTexture = class extends Texture { 16377 /** 16378 * Constructs a new cube texture. 16379 * 16380 * @param {Array<Image>} [images=[]] - An array holding a image for each side of a cube. 16381 * @param {number} [mapping=CubeReflectionMapping] - The texture mapping. 16382 * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value. 16383 * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value. 16384 * @param {number} [magFilter=LinearFilter] - The mag filter value. 16385 * @param {number} [minFilter=LinearMipmapLinearFilter] - The min filter value. 16386 * @param {number} [format=RGBAFormat] - The texture format. 16387 * @param {number} [type=UnsignedByteType] - The texture type. 16388 * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value. 16389 * @param {string} [colorSpace=NoColorSpace] - The color space value. 16390 */ 16391 constructor(images = [], mapping = CubeReflectionMapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace) { 16392 super(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace); 16393 this.isCubeTexture = true; 16394 this.flipY = false; 16395 } 16396 /** 16397 * Alias for {@link CubeTexture#image}. 16398 * 16399 * @type {Array<Image>} 16400 */ 16401 get images() { 16402 return this.image; 16403 } 16404 set images(value) { 16405 this.image = value; 16406 } 16407}; 16408var DepthTexture = class extends Texture { 16409 /** 16410 * Constructs a new depth texture. 16411 * 16412 * @param {number} width - The width of the texture. 16413 * @param {number} height - The height of the texture. 16414 * @param {number} [type=UnsignedIntType] - The texture type. 16415 * @param {number} [mapping=Texture.DEFAULT_MAPPING] - The texture mapping. 16416 * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value. 16417 * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value. 16418 * @param {number} [magFilter=LinearFilter] - The mag filter value. 16419 * @param {number} [minFilter=LinearFilter] - The min filter value. 16420 * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value. 16421 * @param {number} [format=DepthFormat] - The texture format. 16422 * @param {number} [depth=1] - The depth of the texture. 16423 */ 16424 constructor(width, height, type = UnsignedIntType, mapping, wrapS, wrapT, magFilter = NearestFilter, minFilter = NearestFilter, anisotropy, format = DepthFormat, depth = 1) { 16425 if (format !== DepthFormat && format !== DepthStencilFormat) { 16426 throw new Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat"); 16427 } 16428 const image = { width, height, depth }; 16429 super(image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); 16430 this.isDepthTexture = true; 16431 this.flipY = false; 16432 this.generateMipmaps = false; 16433 this.compareFunction = null; 16434 } 16435 copy(source) { 16436 super.copy(source); 16437 this.source = new Source(Object.assign({}, source.image)); 16438 this.compareFunction = source.compareFunction; 16439 return this; 16440 } 16441 toJSON(meta) { 16442 const data = super.toJSON(meta); 16443 if (this.compareFunction !== null) data.compareFunction = this.compareFunction; 16444 return data; 16445 } 16446}; 16447var CubeDepthTexture = class extends DepthTexture { 16448 /** 16449 * Constructs a new cube depth texture. 16450 * 16451 * @param {number} size - The size (width and height) of each cube face. 16452 * @param {number} [type=UnsignedIntType] - The texture type. 16453 * @param {number} [mapping=CubeReflectionMapping] - The texture mapping. 16454 * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value. 16455 * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value. 16456 * @param {number} [magFilter=NearestFilter] - The mag filter value. 16457 * @param {number} [minFilter=NearestFilter] - The min filter value. 16458 * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value. 16459 * @param {number} [format=DepthFormat] - The texture format. 16460 */ 16461 constructor(size, type = UnsignedIntType, mapping = CubeReflectionMapping, wrapS, wrapT, magFilter = NearestFilter, minFilter = NearestFilter, anisotropy, format = DepthFormat) { 16462 const image = { width: size, height: size, depth: 1 }; 16463 const images = [image, image, image, image, image, image]; 16464 super(size, size, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format); 16465 this.image = images; 16466 this.isCubeDepthTexture = true; 16467 this.isCubeTexture = true; 16468 } 16469 /** 16470 * Alias for {@link CubeDepthTexture#image}. 16471 * 16472 * @type {Array<Image>} 16473 */ 16474 get images() { 16475 return this.image; 16476 } 16477 set images(value) { 16478 this.image = value; 16479 } 16480}; 16481var ExternalTexture = class extends Texture { 16482 /** 16483 * Creates a new raw texture. 16484 * 16485 * @param {?(WebGLTexture|GPUTexture)} [sourceTexture=null] - The external texture. 16486 */ 16487 constructor(sourceTexture = null) { 16488 super(); 16489 this.sourceTexture = sourceTexture; 16490 this.isExternalTexture = true; 16491 } 16492 copy(source) { 16493 super.copy(source); 16494 this.sourceTexture = source.sourceTexture; 16495 return this; 16496 } 16497}; 16498var BoxGeometry = class _BoxGeometry extends BufferGeometry { 16499 /** 16500 * Constructs a new box geometry. 16501 * 16502 * @param {number} [width=1] - The width. That is, the length of the edges parallel to the X axis. 16503 * @param {number} [height=1] - The height. That is, the length of the edges parallel to the Y axis. 16504 * @param {number} [depth=1] - The depth. That is, the length of the edges parallel to the Z axis. 16505 * @param {number} [widthSegments=1] - Number of segmented rectangular faces along the width of the sides. 16506 * @param {number} [heightSegments=1] - Number of segmented rectangular faces along the height of the sides. 16507 * @param {number} [depthSegments=1] - Number of segmented rectangular faces along the depth of the sides. 16508 */ 16509 constructor(width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1) { 16510 super(); 16511 this.type = "BoxGeometry"; 16512 this.parameters = { 16513 width, 16514 height, 16515 depth, 16516 widthSegments, 16517 heightSegments, 16518 depthSegments 16519 }; 16520 const scope = this; 16521 widthSegments = Math.floor(widthSegments); 16522 heightSegments = Math.floor(heightSegments); 16523 depthSegments = Math.floor(depthSegments); 16524 const indices = []; 16525 const vertices = []; 16526 const normals = []; 16527 const uvs = []; 16528 let numberOfVertices = 0; 16529 let groupStart = 0; 16530 buildPlane("z", "y", "x", -1, -1, depth, height, width, depthSegments, heightSegments, 0); 16531 buildPlane("z", "y", "x", 1, -1, depth, height, -width, depthSegments, heightSegments, 1); 16532 buildPlane("x", "z", "y", 1, 1, width, depth, height, widthSegments, depthSegments, 2); 16533 buildPlane("x", "z", "y", 1, -1, width, depth, -height, widthSegments, depthSegments, 3); 16534 buildPlane("x", "y", "z", 1, -1, width, height, depth, widthSegments, heightSegments, 4); 16535 buildPlane("x", "y", "z", -1, -1, width, height, -depth, widthSegments, heightSegments, 5); 16536 this.setIndex(indices); 16537 this.setAttribute("position", new Float32BufferAttribute(vertices, 3)); 16538 this.setAttribute("normal", new Float32BufferAttribute(normals, 3)); 16539 this.setAttribute("uv", new Float32BufferAttribute(uvs, 2)); 16540 function buildPlane(u, v, w, udir, vdir, width2, height2, depth2, gridX, gridY, materialIndex) { 16541 const segmentWidth = width2 / gridX; 16542 const segmentHeight = height2 / gridY; 16543 const widthHalf = width2 / 2; 16544 const heightHalf = height2 / 2; 16545 const depthHalf = depth2 / 2; 16546 const gridX1 = gridX + 1; 16547 const gridY1 = gridY + 1; 16548 let vertexCounter = 0; 16549 let groupCount = 0; 16550 const vector = new Vector3(); 16551 for (let iy = 0; iy < gridY1; iy++) { 16552 const y = iy * segmentHeight - heightHalf; 16553 for (let ix = 0; ix < gridX1; ix++) { 16554 const x = ix * segmentWidth - widthHalf; 16555 vector[u] = x * udir; 16556 vector[v] = y * vdir; 16557 vector[w] = depthHalf; 16558 vertices.push(vector.x, vector.y, vector.z); 16559 vector[u] = 0; 16560 vector[v] = 0; 16561 vector[w] = depth2 > 0 ? 1 : -1; 16562 normals.push(vector.x, vector.y, vector.z); 16563 uvs.push(ix / gridX); 16564 uvs.push(1 - iy / gridY); 16565 vertexCounter += 1; 16566 } 16567 } 16568 for (let iy = 0; iy < gridY; iy++) { 16569 for (let ix = 0; ix < gridX; ix++) { 16570 const a = numberOfVertices + ix + gridX1 * iy; 16571 const b = numberOfVertices + ix + gridX1 * (iy + 1); 16572 const c = numberOfVertices + (ix + 1) + gridX1 * (iy + 1); 16573 const d = numberOfVertices + (ix + 1) + gridX1 * iy; 16574 indices.push(a, b, d); 16575 indices.push(b, c, d); 16576 groupCount += 6; 16577 } 16578 } 16579 scope.addGroup(groupStart, groupCount, materialIndex); 16580 groupStart += groupCount; 16581 numberOfVertices += vertexCounter; 16582 } 16583 } 16584 copy(source) { 16585 super.copy(source); 16586 this.parameters = Object.assign({}, source.parameters); 16587 return this; 16588 } 16589 /** 16590 * Factory method for creating an instance of this class from the given 16591 * JSON object. 16592 * 16593 * @param {Object} data - A JSON object representing the serialized geometry. 16594 * @return {BoxGeometry} A new instance. 16595 */ 16596 static fromJSON(data) { 16597 return new _BoxGeometry(data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments); 16598 } 16599}; 16600var CylinderGeometry = class _CylinderGeometry extends BufferGeometry { 16601 /** 16602 * Constructs a new cylinder geometry. 16603 * 16604 * @param {number} [radiusTop=1] - Radius of the cylinder at the top. 16605 * @param {number} [radiusBottom=1] - Radius of the cylinder at the bottom. 16606 * @param {number} [height=1] - Height of the cylinder. 16607 * @param {number} [radialSegments=32] - Number of segmented faces around the circumference of the cylinder. 16608 * @param {number} [heightSegments=1] - Number of rows of faces along the height of the cylinder. 16609 * @param {boolean} [openEnded=false] - Whether the base of the cylinder is open or capped. 16610 * @param {number} [thetaStart=0] - Start angle for first segment, in radians. 16611 * @param {number} [thetaLength=Math.PI*2] - The central angle, often called theta, of the circular sector, in radians. 16612 * The default value results in a complete cylinder. 16613 */ 16614 constructor(radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) { 16615 super(); 16616 this.type = "CylinderGeometry"; 16617 this.parameters = { 16618 radiusTop, 16619 radiusBottom, 16620 height, 16621 radialSegments, 16622 heightSegments, 16623 openEnded, 16624 thetaStart, 16625 thetaLength 16626 }; 16627 const scope = this; 16628 radialSegments = Math.floor(radialSegments); 16629 heightSegments = Math.floor(heightSegments); 16630 const indices = []; 16631 const vertices = []; 16632 const normals = []; 16633 const uvs = []; 16634 let index = 0; 16635 const indexArray = []; 16636 const halfHeight = height / 2; 16637 let groupStart = 0; 16638 generateTorso(); 16639 if (openEnded === false) { 16640 if (radiusTop > 0) generateCap(true); 16641 if (radiusBottom > 0) generateCap(false); 16642 } 16643 this.setIndex(indices); 16644 this.setAttribute("position", new Float32BufferAttribute(vertices, 3)); 16645 this.setAttribute("normal", new Float32BufferAttribute(normals, 3)); 16646 this.setAttribute("uv", new Float32BufferAttribute(uvs, 2)); 16647 function generateTorso() { 16648 const normal = new Vector3(); 16649 const vertex2 = new Vector3(); 16650 let groupCount = 0; 16651 const slope = (radiusBottom - radiusTop) / height; 16652 for (let y = 0; y <= heightSegments; y++) { 16653 const indexRow = []; 16654 const v = y / heightSegments; 16655 const radius = v * (radiusBottom - radiusTop) + radiusTop; 16656 for (let x = 0; x <= radialSegments; x++) { 16657 const u = x / radialSegments; 16658 const theta = u * thetaLength + thetaStart; 16659 const sinTheta = Math.sin(theta); 16660 const cosTheta = Math.cos(theta); 16661 vertex2.x = radius * sinTheta; 16662 vertex2.y = -v * height + halfHeight; 16663 vertex2.z = radius * cosTheta; 16664 vertices.push(vertex2.x, vertex2.y, vertex2.z); 16665 normal.set(sinTheta, slope, cosTheta).normalize(); 16666 normals.push(normal.x, normal.y, normal.z); 16667 uvs.push(u, 1 - v); 16668 indexRow.push(index++); 16669 } 16670 indexArray.push(indexRow); 16671 } 16672 for (let x = 0; x < radialSegments; x++) { 16673 for (let y = 0; y < heightSegments; y++) { 16674 const a = indexArray[y][x]; 16675 const b = indexArray[y + 1][x]; 16676 const c = indexArray[y + 1][x + 1]; 16677 const d = indexArray[y][x + 1]; 16678 if (radiusTop > 0 || y !== 0) { 16679 indices.push(a, b, d); 16680 groupCount += 3; 16681 } 16682 if (radiusBottom > 0 || y !== heightSegments - 1) { 16683 indices.push(b, c, d); 16684 groupCount += 3; 16685 } 16686 } 16687 } 16688 scope.addGroup(groupStart, groupCount, 0); 16689 groupStart += groupCount; 16690 } 16691 function generateCap(top) { 16692 const centerIndexStart = index; 16693 const uv = new Vector2(); 16694 const vertex2 = new Vector3(); 16695 let groupCount = 0; 16696 const radius = top === true ? radiusTop : radiusBottom; 16697 const sign2 = top === true ? 1 : -1; 16698 for (let x = 1; x <= radialSegments; x++) { 16699 vertices.push(0, halfHeight * sign2, 0); 16700 normals.push(0, sign2, 0); 16701 uvs.push(0.5, 0.5); 16702 index++; 16703 } 16704 const centerIndexEnd = index; 16705 for (let x = 0; x <= radialSegments; x++) { 16706 const u = x / radialSegments; 16707 const theta = u * thetaLength + thetaStart; 16708 const cosTheta = Math.cos(theta); 16709 const sinTheta = Math.sin(theta); 16710 vertex2.x = radius * sinTheta; 16711 vertex2.y = halfHeight * sign2; 16712 vertex2.z = radius * cosTheta; 16713 vertices.push(vertex2.x, vertex2.y, vertex2.z); 16714 normals.push(0, sign2, 0); 16715 uv.x = cosTheta * 0.5 + 0.5; 16716 uv.y = sinTheta * 0.5 * sign2 + 0.5; 16717 uvs.push(uv.x, uv.y); 16718 index++; 16719 } 16720 for (let x = 0; x < radialSegments; x++) { 16721 const c = centerIndexStart + x; 16722 const i = centerIndexEnd + x; 16723 if (top === true) { 16724 indices.push(i, i + 1, c); 16725 } else { 16726 indices.push(i + 1, i, c); 16727 } 16728 groupCount += 3; 16729 } 16730 scope.addGroup(groupStart, groupCount, top === true ? 1 : 2); 16731 groupStart += groupCount; 16732 } 16733 } 16734 copy(source) { 16735 super.copy(source); 16736 this.parameters = Object.assign({}, source.parameters); 16737 return this; 16738 } 16739 /** 16740 * Factory method for creating an instance of this class from the given 16741 * JSON object. 16742 * 16743 * @param {Object} data - A JSON object representing the serialized geometry. 16744 * @return {CylinderGeometry} A new instance. 16745 */ 16746 static fromJSON(data) { 16747 return new _CylinderGeometry(data.radiusTop, data.radiusBottom, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); 16748 } 16749}; 16750var ConeGeometry = class _ConeGeometry extends CylinderGeometry { 16751 /** 16752 * Constructs a new cone geometry. 16753 * 16754 * @param {number} [radius=1] - Radius of the cone base. 16755 * @param {number} [height=1] - Height of the cone. 16756 * @param {number} [radialSegments=32] - Number of segmented faces around the circumference of the cone. 16757 * @param {number} [heightSegments=1] - Number of rows of faces along the height of the cone. 16758 * @param {boolean} [openEnded=false] - Whether the base of the cone is open or capped. 16759 * @param {number} [thetaStart=0] - Start angle for first segment, in radians. 16760 * @param {number} [thetaLength=Math.PI*2] - The central angle, often called theta, of the circular sector, in radians. 16761 * The default value results in a complete cone. 16762 */ 16763 constructor(radius = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) { 16764 super(0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength); 16765 this.type = "ConeGeometry"; 16766 this.parameters = { 16767 radius, 16768 height, 16769 radialSegments, 16770 heightSegments, 16771 openEnded, 16772 thetaStart, 16773 thetaLength 16774 }; 16775 } 16776 /** 16777 * Factory method for creating an instance of this class from the given 16778 * JSON object. 16779 * 16780 * @param {Object} data - A JSON object representing the serialized geometry. 16781 * @return {ConeGeometry} A new instance. 16782 */ 16783 static fromJSON(data) { 16784 return new _ConeGeometry(data.radius, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); 16785 } 16786}; 16787function earcut(data, holeIndices, dim = 2) { 16788 const hasHoles = holeIndices && holeIndices.length; 16789 const outerLen = hasHoles ? holeIndices[0] * dim : data.length; 16790 let outerNode = linkedList(data, 0, outerLen, dim, true); 16791 const triangles = []; 16792 if (!outerNode || outerNode.next === outerNode.prev) return triangles; 16793 let minX, minY, invSize; 16794 if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); 16795 if (data.length > 80 * dim) { 16796 minX = data[0]; 16797 minY = data[1]; 16798 let maxX = minX; 16799 let maxY = minY; 16800 for (let i = dim; i < outerLen; i += dim) { 16801 const x = data[i]; 16802 const y = data[i + 1]; 16803 if (x < minX) minX = x; 16804 if (y < minY) minY = y; 16805 if (x > maxX) maxX = x; 16806 if (y > maxY) maxY = y; 16807 } 16808 invSize = Math.max(maxX - minX, maxY - minY); 16809 invSize = invSize !== 0 ? 32767 / invSize : 0; 16810 } 16811 earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0); 16812 return triangles; 16813} 16814function linkedList(data, start, end, dim, clockwise) { 16815 let last; 16816 if (clockwise === signedArea(data, start, end, dim) > 0) { 16817 for (let i = start; i < end; i += dim) last = insertNode(i / dim | 0, data[i], data[i + 1], last); 16818 } else { 16819 for (let i = end - dim; i >= start; i -= dim) last = insertNode(i / dim | 0, data[i], data[i + 1], last); 16820 } 16821 if (last && equals(last, last.next)) { 16822 removeNode(last); 16823 last = last.next; 16824 } 16825 return last; 16826} 16827function filterPoints(start, end) { 16828 if (!start) return start; 16829 if (!end) end = start; 16830 let p = start, again; 16831 do { 16832 again = false; 16833 if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { 16834 removeNode(p); 16835 p = end = p.prev; 16836 if (p === p.next) break; 16837 again = true; 16838 } else { 16839 p = p.next; 16840 } 16841 } while (again || p !== end); 16842 return end; 16843} 16844function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { 16845 if (!ear) return; 16846 if (!pass && invSize) indexCurve(ear, minX, minY, invSize); 16847 let stop = ear; 16848 while (ear.prev !== ear.next) { 16849 const prev = ear.prev; 16850 const next = ear.next; 16851 if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) { 16852 triangles.push(prev.i, ear.i, next.i); 16853 removeNode(ear); 16854 ear = next.next; 16855 stop = next.next; 16856 continue; 16857 } 16858 ear = next; 16859 if (ear === stop) { 16860 if (!pass) { 16861 earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); 16862 } else if (pass === 1) { 16863 ear = cureLocalIntersections(filterPoints(ear), triangles); 16864 earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); 16865 } else if (pass === 2) { 16866 splitEarcut(ear, triangles, dim, minX, minY, invSize); 16867 } 16868 break; 16869 } 16870 } 16871} 16872function isEar(ear) { 16873 const a = ear.prev, b = ear, c = ear.next; 16874 if (area(a, b, c) >= 0) return false; 16875 const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y; 16876 const x0 = Math.min(ax, bx, cx), y0 = Math.min(ay, by, cy), x1 = Math.max(ax, bx, cx), y1 = Math.max(ay, by, cy); 16877 let p = c.next; 16878 while (p !== a) { 16879 if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; 16880 p = p.next; 16881 } 16882 return true; 16883} 16884function isEarHashed(ear, minX, minY, invSize) { 16885 const a = ear.prev, b = ear, c = ear.next; 16886 if (area(a, b, c) >= 0) return false; 16887 const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y; 16888 const x0 = Math.min(ax, bx, cx), y0 = Math.min(ay, by, cy), x1 = Math.max(ax, bx, cx), y1 = Math.max(ay, by, cy); 16889 const minZ = zOrder(x0, y0, minX, minY, invSize), maxZ = zOrder(x1, y1, minX, minY, invSize); 16890 let p = ear.prevZ, n = ear.nextZ; 16891 while (p && p.z >= minZ && n && n.z <= maxZ) { 16892 if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; 16893 p = p.prevZ; 16894 if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; 16895 n = n.nextZ; 16896 } 16897 while (p && p.z >= minZ) { 16898 if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; 16899 p = p.prevZ; 16900 } 16901 while (n && n.z <= maxZ) { 16902 if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; 16903 n = n.nextZ; 16904 } 16905 return true; 16906} 16907function cureLocalIntersections(start, triangles) { 16908 let p = start; 16909 do { 16910 const a = p.prev, b = p.next.next; 16911 if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { 16912 triangles.push(a.i, p.i, b.i); 16913 removeNode(p); 16914 removeNode(p.next); 16915 p = start = b; 16916 } 16917 p = p.next; 16918 } while (p !== start); 16919 return filterPoints(p); 16920} 16921function splitEarcut(start, triangles, dim, minX, minY, invSize) { 16922 let a = start; 16923 do { 16924 let b = a.next.next; 16925 while (b !== a.prev) { 16926 if (a.i !== b.i && isValidDiagonal(a, b)) { 16927 let c = splitPolygon(a, b); 16928 a = filterPoints(a, a.next); 16929 c = filterPoints(c, c.next); 16930 earcutLinked(a, triangles, dim, minX, minY, invSize, 0); 16931 earcutLinked(c, triangles, dim, minX, minY, invSize, 0); 16932 return; 16933 } 16934 b = b.next; 16935 } 16936 a = a.next; 16937 } while (a !== start); 16938} 16939function eliminateHoles(data, holeIndices, outerNode, dim) { 16940 const queue = []; 16941 for (let i = 0, len = holeIndices.length; i < len; i++) { 16942 const start = holeIndices[i] * dim; 16943 const end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; 16944 const list = linkedList(data, start, end, dim, false); 16945 if (list === list.next) list.steiner = true; 16946 queue.push(getLeftmost(list)); 16947 } 16948 queue.sort(compareXYSlope); 16949 for (let i = 0; i < queue.length; i++) { 16950 outerNode = eliminateHole(queue[i], outerNode); 16951 } 16952 return outerNode; 16953} 16954function compareXYSlope(a, b) { 16955 let result = a.x - b.x; 16956 if (result === 0) { 16957 result = a.y - b.y; 16958 if (result === 0) { 16959 const aSlope = (a.next.y - a.y) / (a.next.x - a.x); 16960 const bSlope = (b.next.y - b.y) / (b.next.x - b.x); 16961 result = aSlope - bSlope; 16962 } 16963 } 16964 return result; 16965} 16966function eliminateHole(hole, outerNode) { 16967 const bridge = findHoleBridge(hole, outerNode); 16968 if (!bridge) { 16969 return outerNode; 16970 } 16971 const bridgeReverse = splitPolygon(bridge, hole); 16972 filterPoints(bridgeReverse, bridgeReverse.next); 16973 return filterPoints(bridge, bridge.next); 16974} 16975function findHoleBridge(hole, outerNode) { 16976 let p = outerNode; 16977 const hx = hole.x; 16978 const hy = hole.y; 16979 let qx = -Infinity; 16980 let m; 16981 if (equals(hole, p)) return p; 16982 do { 16983 if (equals(hole, p.next)) return p.next; 16984 else if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { 16985 const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); 16986 if (x <= hx && x > qx) { 16987 qx = x; 16988 m = p.x < p.next.x ? p : p.next; 16989 if (x === hx) return m; 16990 } 16991 } 16992 p = p.next; 16993 } while (p !== outerNode); 16994 if (!m) return null; 16995 const stop = m; 16996 const mx = m.x; 16997 const my = m.y; 16998 let tanMin = Infinity; 16999 p = m; 17000 do { 17001 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)) { 17002 const tan = Math.abs(hy - p.y) / (hx - p.x); 17003 if (locallyInside(p, hole) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) { 17004 m = p; 17005 tanMin = tan; 17006 } 17007 } 17008 p = p.next; 17009 } while (p !== stop); 17010 return m; 17011} 17012function sectorContainsSector(m, p) { 17013 return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0; 17014} 17015function indexCurve(start, minX, minY, invSize) { 17016 let p = start; 17017 do { 17018 if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize); 17019 p.prevZ = p.prev; 17020 p.nextZ = p.next; 17021 p = p.next; 17022 } while (p !== start); 17023 p.prevZ.nextZ = null; 17024 p.prevZ = null; 17025 sortLinked(p); 17026} 17027function sortLinked(list) { 17028 let numMerges; 17029 let inSize = 1; 17030 do { 17031 let p = list; 17032 let e; 17033 list = null; 17034 let tail = null; 17035 numMerges = 0; 17036 while (p) { 17037 numMerges++; 17038 let q = p; 17039 let pSize = 0; 17040 for (let i = 0; i < inSize; i++) { 17041 pSize++; 17042 q = q.nextZ; 17043 if (!q) break; 17044 } 17045 let qSize = inSize; 17046 while (pSize > 0 || qSize > 0 && q) { 17047 if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { 17048 e = p; 17049 p = p.nextZ; 17050 pSize--; 17051 } else { 17052 e = q; 17053 q = q.nextZ; 17054 qSize--; 17055 } 17056 if (tail) tail.nextZ = e; 17057 else list = e; 17058 e.prevZ = tail; 17059 tail = e; 17060 } 17061 p = q; 17062 } 17063 tail.nextZ = null; 17064 inSize *= 2; 17065 } while (numMerges > 1); 17066 return list; 17067} 17068function zOrder(x, y, minX, minY, invSize) { 17069 x = (x - minX) * invSize | 0; 17070 y = (y - minY) * invSize | 0; 17071 x = (x | x << 8) & 16711935; 17072 x = (x | x << 4) & 252645135; 17073 x = (x | x << 2) & 858993459; 17074 x = (x | x << 1) & 1431655765; 17075 y = (y | y << 8) & 16711935; 17076 y = (y | y << 4) & 252645135; 17077 y = (y | y << 2) & 858993459; 17078 y = (y | y << 1) & 1431655765; 17079 return x | y << 1; 17080} 17081function getLeftmost(start) { 17082 let p = start, leftmost = start; 17083 do { 17084 if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y) leftmost = p; 17085 p = p.next; 17086 } while (p !== start); 17087 return leftmost; 17088} 17089function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { 17090 return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py); 17091} 17092function pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, px, py) { 17093 return !(ax === px && ay === py) && pointInTriangle(ax, ay, bx, by, cx, cy, px, py); 17094} 17095function isValidDiagonal(a, b) { 17096 return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // doesn't intersect other edges 17097 (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible 17098 (area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors 17099 equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); 17100} 17101function area(p, q, r) { 17102 return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); 17103} 17104function equals(p1, p2) { 17105 return p1.x === p2.x && p1.y === p2.y; 17106} 17107function intersects(p1, q1, p2, q2) { 17108 const o1 = sign(area(p1, q1, p2)); 17109 const o2 = sign(area(p1, q1, q2)); 17110 const o3 = sign(area(p2, q2, p1)); 17111 const o4 = sign(area(p2, q2, q1)); 17112 if (o1 !== o2 && o3 !== o4) return true; 17113 if (o1 === 0 && onSegment(p1, p2, q1)) return true; 17114 if (o2 === 0 && onSegment(p1, q2, q1)) return true; 17115 if (o3 === 0 && onSegment(p2, p1, q2)) return true; 17116 if (o4 === 0 && onSegment(p2, q1, q2)) return true; 17117 return false; 17118} 17119function onSegment(p, q, r) { 17120 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); 17121} 17122function sign(num) { 17123 return num > 0 ? 1 : num < 0 ? -1 : 0; 17124} 17125function intersectsPolygon(a, b) { 17126 let p = a; 17127 do { 17128 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; 17129 p = p.next; 17130 } while (p !== a); 17131 return false; 17132} 17133function locallyInside(a, b) { 17134 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; 17135} 17136function middleInside(a, b) { 17137 let p = a; 17138 let inside = false; 17139 const px = (a.x + b.x) / 2; 17140 const py = (a.y + b.y) / 2; 17141 do { 17142 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) 17143 inside = !inside; 17144 p = p.next; 17145 } while (p !== a); 17146 return inside; 17147} 17148function splitPolygon(a, b) { 17149 const a2 = createNode(a.i, a.x, a.y), b2 = createNode(b.i, b.x, b.y), an = a.next, bp = b.prev; 17150 a.next = b; 17151 b.prev = a; 17152 a2.next = an; 17153 an.prev = a2; 17154 b2.next = a2; 17155 a2.prev = b2; 17156 bp.next = b2; 17157 b2.prev = bp; 17158 return b2; 17159} 17160function insertNode(i, x, y, last) { 17161 const p = createNode(i, x, y); 17162 if (!last) { 17163 p.prev = p; 17164 p.next = p; 17165 } else { 17166 p.next = last.next; 17167 p.prev = last; 17168 last.next.prev = p; 17169 last.next = p; 17170 } 17171 return p; 17172} 17173function removeNode(p) { 17174 p.next.prev = p.prev; 17175 p.prev.next = p.next; 17176 if (p.prevZ) p.prevZ.nextZ = p.nextZ; 17177 if (p.nextZ) p.nextZ.prevZ = p.prevZ; 17178} 17179function createNode(i, x, y) { 17180 return { 17181 i, 17182 // vertex index in coordinates array 17183 x, 17184 y, 17185 // vertex coordinates 17186 prev: null, 17187 // previous and next vertex nodes in a polygon ring 17188 next: null, 17189 z: 0, 17190 // z-order curve value 17191 prevZ: null, 17192 // previous and next nodes in z-order 17193 nextZ: null, 17194 steiner: false 17195 // indicates whether this is a steiner point 17196 }; 17197} 17198function signedArea(data, start, end, dim) { 17199 let sum = 0; 17200 for (let i = start, j = end - dim; i < end; i += dim) { 17201 sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); 17202 j = i; 17203 } 17204 return sum; 17205} 17206var Earcut = class { 17207 /** 17208 * Triangulates the given shape definition by returning an array of triangles. 17209 * 17210 * @param {Array<number>} data - An array with 2D points. 17211 * @param {Array<number>} holeIndices - An array with indices defining holes. 17212 * @param {number} [dim=2] - The number of coordinates per vertex in the input array. 17213 * @return {Array<number>} An array representing the triangulated faces. Each face is defined by three consecutive numbers 17214 * representing vertex indices. 17215 */ 17216 static triangulate(data, holeIndices, dim = 2) { 17217 return earcut(data, holeIndices, dim); 17218 } 17219}; 17220var ShapeUtils = class _ShapeUtils { 17221 /** 17222 * Calculate area of a ( 2D ) contour polygon. 17223 * 17224 * @param {Array<Vector2>} contour - An array of 2D points. 17225 * @return {number} The area. 17226 */ 17227 static area(contour) { 17228 const n = contour.length; 17229 let a = 0; 17230 for (let p = n - 1, q = 0; q < n; p = q++) { 17231 a += contour[p].x * contour[q].y - contour[q].x * contour[p].y; 17232 } 17233 return a * 0.5; 17234 } 17235 /** 17236 * Returns `true` if the given contour uses a clockwise winding order. 17237 * 17238 * @param {Array<Vector2>} pts - An array of 2D points defining a polygon. 17239 * @return {boolean} Whether the given contour uses a clockwise winding order or not. 17240 */ 17241 static isClockWise(pts) { 17242 return _ShapeUtils.area(pts) < 0; 17243 } 17244 /** 17245 * Triangulates the given shape definition. 17246 * 17247 * @param {Array<Vector2>} contour - An array of 2D points defining the contour. 17248 * @param {Array<Array<Vector2>>} holes - An array that holds arrays of 2D points defining the holes. 17249 * @return {Array<Array<number>>} An array that holds for each face definition an array with three indices. 17250 */ 17251 static triangulateShape(contour, holes) { 17252 const vertices = []; 17253 const holeIndices = []; 17254 const faces = []; 17255 removeDupEndPts(contour); 17256 addContour(vertices, contour); 17257 let holeIndex = contour.length; 17258 holes.forEach(removeDupEndPts); 17259 for (let i = 0; i < holes.length; i++) { 17260 holeIndices.push(holeIndex); 17261 holeIndex += holes[i].length; 17262 addContour(vertices, holes[i]); 17263 } 17264 const triangles = Earcut.triangulate(vertices, holeIndices); 17265 for (let i = 0; i < triangles.length; i += 3) { 17266 faces.push(triangles.slice(i, i + 3)); 17267 } 17268 return faces; 17269 } 17270}; 17271function removeDupEndPts(points) { 17272 const l = points.length; 17273 if (l > 2 && points[l - 1].equals(points[0])) { 17274 points.pop(); 17275 } 17276} 17277function addContour(vertices, contour) { 17278 for (let i = 0; i < contour.length; i++) { 17279 vertices.push(contour[i].x); 17280 vertices.push(contour[i].y); 17281 } 17282} 17283var PlaneGeometry = class _PlaneGeometry extends BufferGeometry { 17284 /** 17285 * Constructs a new plane geometry. 17286 * 17287 * @param {number} [width=1] - The width along the X axis. 17288 * @param {number} [height=1] - The height along the Y axis 17289 * @param {number} [widthSegments=1] - The number of segments along the X axis. 17290 * @param {number} [heightSegments=1] - The number of segments along the Y axis. 17291 */ 17292 constructor(width = 1, height = 1, widthSegments = 1, heightSegments = 1) { 17293 super(); 17294 this.type = "PlaneGeometry"; 17295 this.parameters = { 17296 width, 17297 height, 17298 widthSegments, 17299 heightSegments 17300 }; 17301 const width_half = width / 2; 17302 const height_half = height / 2; 17303 const gridX = Math.floor(widthSegments); 17304 const gridY = Math.floor(heightSegments); 17305 const gridX1 = gridX + 1; 17306 const gridY1 = gridY + 1; 17307 const segment_width = width / gridX; 17308 const segment_height = height / gridY; 17309 const indices = []; 17310 const vertices = []; 17311 const normals = []; 17312 const uvs = []; 17313 for (let iy = 0; iy < gridY1; iy++) { 17314 const y = iy * segment_height - height_half; 17315 for (let ix = 0; ix < gridX1; ix++) { 17316 const x = ix * segment_width - width_half; 17317 vertices.push(x, -y, 0); 17318 normals.push(0, 0, 1); 17319 uvs.push(ix / gridX); 17320 uvs.push(1 - iy / gridY); 17321 } 17322 } 17323 for (let iy = 0; iy < gridY; iy++) { 17324 for (let ix = 0; ix < gridX; ix++) { 17325 const a = ix + gridX1 * iy; 17326 const b = ix + gridX1 * (iy + 1); 17327 const c = ix + 1 + gridX1 * (iy + 1); 17328 const d = ix + 1 + gridX1 * iy; 17329 indices.push(a, b, d); 17330 indices.push(b, c, d); 17331 } 17332 } 17333 this.setIndex(indices); 17334 this.setAttribute("position", new Float32BufferAttribute(vertices, 3)); 17335 this.setAttribute("normal", new Float32BufferAttribute(normals, 3)); 17336 this.setAttribute("uv", new Float32BufferAttribute(uvs, 2)); 17337 } 17338 copy(source) { 17339 super.copy(source); 17340 this.parameters = Object.assign({}, source.parameters); 17341 return this; 17342 } 17343 /** 17344 * Factory method for creating an instance of this class from the given 17345 * JSON object. 17346 * 17347 * @param {Object} data - A JSON object representing the serialized geometry. 17348 * @return {PlaneGeometry} A new instance. 17349 */ 17350 static fromJSON(data) { 17351 return new _PlaneGeometry(data.width, data.height, data.widthSegments, data.heightSegments); 17352 } 17353}; 17354var SphereGeometry = class _SphereGeometry extends BufferGeometry { 17355 /** 17356 * Constructs a new sphere geometry. 17357 * 17358 * @param {number} [radius=1] - The sphere radius. 17359 * @param {number} [widthSegments=32] - The number of horizontal segments. Minimum value is `3`. 17360 * @param {number} [heightSegments=16] - The number of vertical segments. Minimum value is `2`. 17361 * @param {number} [phiStart=0] - The horizontal starting angle in radians. 17362 * @param {number} [phiLength=Math.PI*2] - The horizontal sweep angle size. 17363 * @param {number} [thetaStart=0] - The vertical starting angle in radians. 17364 * @param {number} [thetaLength=Math.PI] - The vertical sweep angle size. 17365 */ 17366 constructor(radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI) { 17367 super(); 17368 this.type = "SphereGeometry"; 17369 this.parameters = { 17370 radius, 17371 widthSegments, 17372 heightSegments, 17373 phiStart, 17374 phiLength, 17375 thetaStart, 17376 thetaLength 17377 }; 17378 widthSegments = Math.max(3, Math.floor(widthSegments)); 17379 heightSegments = Math.max(2, Math.floor(heightSegments)); 17380 const thetaEnd = Math.min(thetaStart + thetaLength, Math.PI); 17381 let index = 0; 17382 const grid = []; 17383 const vertex2 = new Vector3(); 17384 const normal = new Vector3(); 17385 const indices = []; 17386 const vertices = []; 17387 const normals = []; 17388 const uvs = []; 17389 for (let iy = 0; iy <= heightSegments; iy++) { 17390 const verticesRow = []; 17391 const v = iy / heightSegments; 17392 let uOffset = 0; 17393 if (iy === 0 && thetaStart === 0) { 17394 uOffset = 0.5 / widthSegments; 17395 } else if (iy === heightSegments && thetaEnd === Math.PI) { 17396 uOffset = -0.5 / widthSegments; 17397 } 17398 for (let ix = 0; ix <= widthSegments; ix++) { 17399 const u = ix / widthSegments; 17400 vertex2.x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength); 17401 vertex2.y = radius * Math.cos(thetaStart + v * thetaLength); 17402 vertex2.z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength); 17403 vertices.push(vertex2.x, vertex2.y, vertex2.z); 17404 normal.copy(vertex2).normalize(); 17405 normals.push(normal.x, normal.y, normal.z); 17406 uvs.push(u + uOffset, 1 - v); 17407 verticesRow.push(index++); 17408 } 17409 grid.push(verticesRow); 17410 } 17411 for (let iy = 0; iy < heightSegments; iy++) { 17412 for (let ix = 0; ix < widthSegments; ix++) { 17413 const a = grid[iy][ix + 1]; 17414 const b = grid[iy][ix]; 17415 const c = grid[iy + 1][ix]; 17416 const d = grid[iy + 1][ix + 1]; 17417 if (iy !== 0 || thetaStart > 0) indices.push(a, b, d); 17418 if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c, d); 17419 } 17420 } 17421 this.setIndex(indices); 17422 this.setAttribute("position", new Float32BufferAttribute(vertices, 3)); 17423 this.setAttribute("normal", new Float32BufferAttribute(normals, 3)); 17424 this.setAttribute("uv", new Float32BufferAttribute(uvs, 2)); 17425 } 17426 copy(source) { 17427 super.copy(source); 17428 this.parameters = Object.assign({}, source.parameters); 17429 return this; 17430 } 17431 /** 17432 * Factory method for creating an instance of this class from the given 17433 * JSON object. 17434 * 17435 * @param {Object} data - A JSON object representing the serialized geometry. 17436 * @return {SphereGeometry} A new instance. 17437 */ 17438 static fromJSON(data) { 17439 return new _SphereGeometry(data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength); 17440 } 17441}; 17442var TorusGeometry = class _TorusGeometry extends BufferGeometry { 17443 /** 17444 * Constructs a new torus geometry. 17445 * 17446 * @param {number} [radius=1] - Radius of the torus, from the center of the torus to the center of the tube. 17447 * @param {number} [tube=0.4] - Radius of the tube. Must be smaller than `radius`. 17448 * @param {number} [radialSegments=12] - The number of radial segments. 17449 * @param {number} [tubularSegments=48] - The number of tubular segments. 17450 * @param {number} [arc=Math.PI*2] - Central angle in radians. 17451 * @param {number} [thetaStart=0] - Start of the tubular sweep in radians. 17452 * @param {number} [thetaLength=Math.PI*2] - Length of the tubular sweep in radians. 17453 */ 17454 constructor(radius = 1, tube = 0.4, radialSegments = 12, tubularSegments = 48, arc = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI * 2) { 17455 super(); 17456 this.type = "TorusGeometry"; 17457 this.parameters = { 17458 radius, 17459 tube, 17460 radialSegments, 17461 tubularSegments, 17462 arc, 17463 thetaStart, 17464 thetaLength 17465 }; 17466 radialSegments = Math.floor(radialSegments); 17467 tubularSegments = Math.floor(tubularSegments); 17468 const indices = []; 17469 const vertices = []; 17470 const normals = []; 17471 const uvs = []; 17472 const center = new Vector3(); 17473 const vertex2 = new Vector3(); 17474 const normal = new Vector3(); 17475 for (let j = 0; j <= radialSegments; j++) { 17476 const v = thetaStart + j / radialSegments * thetaLength; 17477 for (let i = 0; i <= tubularSegments; i++) { 17478 const u = i / tubularSegments * arc; 17479 vertex2.x = (radius + tube * Math.cos(v)) * Math.cos(u); 17480 vertex2.y = (radius + tube * Math.cos(v)) * Math.sin(u); 17481 vertex2.z = tube * Math.sin(v); 17482 vertices.push(vertex2.x, vertex2.y, vertex2.z); 17483 center.x = radius * Math.cos(u); 17484 center.y = radius * Math.sin(u); 17485 normal.subVectors(vertex2, center).normalize(); 17486 normals.push(normal.x, normal.y, normal.z); 17487 uvs.push(i / tubularSegments); 17488 uvs.push(j / radialSegments); 17489 } 17490 } 17491 for (let j = 1; j <= radialSegments; j++) { 17492 for (let i = 1; i <= tubularSegments; i++) { 17493 const a = (tubularSegments + 1) * j + i - 1; 17494 const b = (tubularSegments + 1) * (j - 1) + i - 1; 17495 const c = (tubularSegments + 1) * (j - 1) + i; 17496 const d = (tubularSegments + 1) * j + i; 17497 indices.push(a, b, d); 17498 indices.push(b, c, d); 17499 } 17500 } 17501 this.setIndex(indices); 17502 this.setAttribute("position", new Float32BufferAttribute(vertices, 3)); 17503 this.setAttribute("normal", new Float32BufferAttribute(normals, 3)); 17504 this.setAttribute("uv", new Float32BufferAttribute(uvs, 2)); 17505 } 17506 copy(source) { 17507 super.copy(source); 17508 this.parameters = Object.assign({}, source.parameters); 17509 return this; 17510 } 17511 /** 17512 * Factory method for creating an instance of this class from the given 17513 * JSON object. 17514 * 17515 * @param {Object} data - A JSON object representing the serialized geometry. 17516 * @return {TorusGeometry} A new instance. 17517 */ 17518 static fromJSON(data) { 17519 return new _TorusGeometry(data.radius, data.tube, data.radialSegments, data.tubularSegments, data.arc); 17520 } 17521}; 17522var ShadowMaterial = class extends Material { 17523 /** 17524 * Constructs a new shadow material. 17525 * 17526 * @param {Object} [parameters] - An object with one or more properties 17527 * defining the material's appearance. Any property of the material 17528 * (including any property from inherited materials) can be passed 17529 * in here. Color values can be passed any type of value accepted 17530 * by {@link Color#set}. 17531 */ 17532 constructor(parameters) { 17533 super(); 17534 this.isShadowMaterial = true; 17535 this.type = "ShadowMaterial"; 17536 this.color = new Color(0); 17537 this.transparent = true; 17538 this.fog = true; 17539 this.setValues(parameters); 17540 } 17541 copy(source) { 17542 super.copy(source); 17543 this.color.copy(source.color); 17544 this.fog = source.fog; 17545 return this; 17546 } 17547}; 17548function cloneUniforms(src) { 17549 const dst = {}; 17550 for (const u in src) { 17551 dst[u] = {}; 17552 for (const p in src[u]) { 17553 const property = src[u][p]; 17554 if (isThreeObject(property)) { 17555 if (property.isRenderTargetTexture) { 17556 warn("UniformsUtils: Textures of render targets cannot be cloned via cloneUniforms() or mergeUniforms()."); 17557 dst[u][p] = null; 17558 } else { 17559 dst[u][p] = property.clone(); 17560 } 17561 } else if (Array.isArray(property)) { 17562 if (isThreeObject(property[0])) { 17563 const clonedProperty = []; 17564 for (let i = 0, l = property.length; i < l; i++) { 17565 clonedProperty[i] = property[i].clone(); 17566 } 17567 dst[u][p] = clonedProperty; 17568 } else { 17569 dst[u][p] = property.slice(); 17570 } 17571 } else { 17572 dst[u][p] = property; 17573 } 17574 } 17575 } 17576 return dst; 17577} 17578function mergeUniforms(uniforms) { 17579 const merged = {}; 17580 for (let u = 0; u < uniforms.length; u++) { 17581 const tmp = cloneUniforms(uniforms[u]); 17582 for (const p in tmp) { 17583 merged[p] = tmp[p]; 17584 } 17585 } 17586 return merged; 17587} 17588function isThreeObject(property) { 17589 return property && (property.isColor || property.isMatrix3 || property.isMatrix4 || property.isVector2 || property.isVector3 || property.isVector4 || property.isTexture || property.isQuaternion); 17590} 17591function cloneUniformsGroups(src) { 17592 const dst = []; 17593 for (let u = 0; u < src.length; u++) { 17594 dst.push(src[u].clone()); 17595 } 17596 return dst; 17597} 17598function getUnlitUniformColorSpace(renderer) { 17599 const currentRenderTarget = renderer.getRenderTarget(); 17600 if (currentRenderTarget === null) { 17601 return renderer.outputColorSpace; 17602 } 17603 if (currentRenderTarget.isXRRenderTarget === true) { 17604 return currentRenderTarget.texture.colorSpace; 17605 } 17606 return ColorManagement.workingColorSpace; 17607} 17608var UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms }; 17609var default_vertex = "void main() {\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; 17610var default_fragment = "void main() {\n gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; 17611var ShaderMaterial = class extends Material { 17612 /** 17613 * Constructs a new shader material. 17614 * 17615 * @param {Object} [parameters] - An object with one or more properties 17616 * defining the material's appearance. Any property of the material 17617 * (including any property from inherited materials) can be passed 17618 * in here. Color values can be passed any type of value accepted 17619 * by {@link Color#set}. 17620 */ 17621 constructor(parameters) { 17622 super(); 17623 this.isShaderMaterial = true; 17624 this.type = "ShaderMaterial"; 17625 this.defines = {}; 17626 this.uniforms = {}; 17627 this.uniformsGroups = []; 17628 this.vertexShader = default_vertex; 17629 this.fragmentShader = default_fragment; 17630 this.linewidth = 1; 17631 this.wireframe = false; 17632 this.wireframeLinewidth = 1; 17633 this.fog = false; 17634 this.lights = false; 17635 this.clipping = false; 17636 this.forceSinglePass = true; 17637 this.extensions = { 17638 clipCullDistance: false, 17639 // set to use vertex shader clipping 17640 multiDraw: false 17641 // set to use vertex shader multi_draw / enable gl_DrawID 17642 }; 17643 this.defaultAttributeValues = { 17644 "color": [1, 1, 1], 17645 "uv": [0, 0], 17646 "uv1": [0, 0] 17647 }; 17648 this.index0AttributeName = void 0; 17649 this.uniformsNeedUpdate = false; 17650 this.glslVersion = null; 17651 if (parameters !== void 0) { 17652 this.setValues(parameters); 17653 } 17654 } 17655 copy(source) { 17656 super.copy(source); 17657 this.fragmentShader = source.fragmentShader; 17658 this.vertexShader = source.vertexShader; 17659 this.uniforms = cloneUniforms(source.uniforms); 17660 this.uniformsGroups = cloneUniformsGroups(source.uniformsGroups); 17661 this.defines = Object.assign({}, source.defines); 17662 this.wireframe = source.wireframe; 17663 this.wireframeLinewidth = source.wireframeLinewidth; 17664 this.fog = source.fog; 17665 this.lights = source.lights; 17666 this.clipping = source.clipping; 17667 this.extensions = Object.assign({}, source.extensions); 17668 this.glslVersion = source.glslVersion; 17669 this.defaultAttributeValues = Object.assign({}, source.defaultAttributeValues); 17670 this.index0AttributeName = source.index0AttributeName; 17671 this.uniformsNeedUpdate = source.uniformsNeedUpdate; 17672 return this; 17673 } 17674 toJSON(meta) { 17675 const data = super.toJSON(meta); 17676 data.glslVersion = this.glslVersion; 17677 data.uniforms = {}; 17678 for (const name in this.uniforms) { 17679 const uniform = this.uniforms[name]; 17680 const value = uniform.value; 17681 if (value && value.isTexture) { 17682 data.uniforms[name] = { 17683 type: "t", 17684 value: value.toJSON(meta).uuid 17685 }; 17686 } else if (value && value.isColor) { 17687 data.uniforms[name] = { 17688 type: "c", 17689 value: value.getHex() 17690 }; 17691 } else if (value && value.isVector2) { 17692 data.uniforms[name] = { 17693 type: "v2", 17694 value: value.toArray() 17695 }; 17696 } else if (value && value.isVector3) { 17697 data.uniforms[name] = { 17698 type: "v3", 17699 value: value.toArray() 17700 }; 17701 } else if (value && value.isVector4) { 17702 data.uniforms[name] = { 17703 type: "v4", 17704 value: value.toArray() 17705 }; 17706 } else if (value && value.isMatrix3) { 17707 data.uniforms[name] = { 17708 type: "m3", 17709 value: value.toArray() 17710 }; 17711 } else if (value && value.isMatrix4) { 17712 data.uniforms[name] = { 17713 type: "m4", 17714 value: value.toArray() 17715 }; 17716 } else { 17717 data.uniforms[name] = { 17718 value 17719 }; 17720 } 17721 } 17722 if (Object.keys(this.defines).length > 0) data.defines = this.defines; 17723 data.vertexShader = this.vertexShader; 17724 data.fragmentShader = this.fragmentShader; 17725 data.lights = this.lights; 17726 data.clipping = this.clipping; 17727 const extensions = {}; 17728 for (const key in this.extensions) { 17729 if (this.extensions[key] === true) extensions[key] = true; 17730 } 17731 if (Object.keys(extensions).length > 0) data.extensions = extensions; 17732 return data; 17733 } 17734}; 17735var RawShaderMaterial = class extends ShaderMaterial { 17736 /** 17737 * Constructs a new raw shader material. 17738 * 17739 * @param {Object} [parameters] - An object with one or more properties 17740 * defining the material's appearance. Any property of the material 17741 * (including any property from inherited materials) can be passed 17742 * in here. Color values can be passed any type of value accepted 17743 * by {@link Color#set}. 17744 */ 17745 constructor(parameters) { 17746 super(parameters); 17747 this.isRawShaderMaterial = true; 17748 this.type = "RawShaderMaterial"; 17749 } 17750}; 17751var MeshStandardMaterial = class extends Material { 17752 /** 17753 * Constructs a new mesh standard material. 17754 * 17755 * @param {Object} [parameters] - An object with one or more properties 17756 * defining the material's appearance. Any property of the material 17757 * (including any property from inherited materials) can be passed 17758 * in here. Color values can be passed any type of value accepted 17759 * by {@link Color#set}. 17760 */ 17761 constructor(parameters) { 17762 super(); 17763 this.isMeshStandardMaterial = true; 17764 this.type = "MeshStandardMaterial"; 17765 this.defines = { "STANDARD": "" }; 17766 this.color = new Color(16777215); 17767 this.roughness = 1; 17768 this.metalness = 0; 17769 this.map = null; 17770 this.lightMap = null; 17771 this.lightMapIntensity = 1; 17772 this.aoMap = null; 17773 this.aoMapIntensity = 1; 17774 this.emissive = new Color(0); 17775 this.emissiveIntensity = 1; 17776 this.emissiveMap = null; 17777 this.bumpMap = null; 17778 this.bumpScale = 1; 17779 this.normalMap = null; 17780 this.normalMapType = TangentSpaceNormalMap; 17781 this.normalScale = new Vector2(1, 1); 17782 this.displacementMap = null; 17783 this.displacementScale = 1; 17784 this.displacementBias = 0; 17785 this.roughnessMap = null; 17786 this.metalnessMap = null; 17787 this.alphaMap = null; 17788 this.envMap = null; 17789 this.envMapRotation = new Euler(); 17790 this.envMapIntensity = 1; 17791 this.wireframe = false; 17792 this.wireframeLinewidth = 1; 17793 this.wireframeLinecap = "round"; 17794 this.wireframeLinejoin = "round"; 17795 this.flatShading = false; 17796 this.fog = true; 17797 this.setValues(parameters); 17798 } 17799 copy(source) { 17800 super.copy(source); 17801 this.defines = { "STANDARD": "" }; 17802 this.color.copy(source.color); 17803 this.roughness = source.roughness; 17804 this.metalness = source.metalness; 17805 this.map = source.map; 17806 this.lightMap = source.lightMap; 17807 this.lightMapIntensity = source.lightMapIntensity; 17808 this.aoMap = source.aoMap; 17809 this.aoMapIntensity = source.aoMapIntensity; 17810 this.emissive.copy(source.emissive); 17811 this.emissiveMap = source.emissiveMap; 17812 this.emissiveIntensity = source.emissiveIntensity; 17813 this.bumpMap = source.bumpMap; 17814 this.bumpScale = source.bumpScale; 17815 this.normalMap = source.normalMap; 17816 this.normalMapType = source.normalMapType; 17817 this.normalScale.copy(source.normalScale); 17818 this.displacementMap = source.displacementMap; 17819 this.displacementScale = source.displacementScale; 17820 this.displacementBias = source.displacementBias; 17821 this.roughnessMap = source.roughnessMap; 17822 this.metalnessMap = source.metalnessMap; 17823 this.alphaMap = source.alphaMap; 17824 this.envMap = source.envMap; 17825 this.envMapRotation.copy(source.envMapRotation); 17826 this.envMapIntensity = source.envMapIntensity; 17827 this.wireframe = source.wireframe; 17828 this.wireframeLinewidth = source.wireframeLinewidth; 17829 this.wireframeLinecap = source.wireframeLinecap; 17830 this.wireframeLinejoin = source.wireframeLinejoin; 17831 this.flatShading = source.flatShading; 17832 this.fog = source.fog; 17833 return this; 17834 } 17835}; 17836var MeshPhysicalMaterial = class extends MeshStandardMaterial { 17837 /** 17838 * Constructs a new mesh physical material. 17839 * 17840 * @param {Object} [parameters] - An object with one or more properties 17841 * defining the material's appearance. Any property of the material 17842 * (including any property from inherited materials) can be passed 17843 * in here. Color values can be passed any type of value accepted 17844 * by {@link Color#set}. 17845 */ 17846 constructor(parameters) { 17847 super(); 17848 this.isMeshPhysicalMaterial = true; 17849 this.defines = { 17850 "STANDARD": "", 17851 "PHYSICAL": "" 17852 }; 17853 this.type = "MeshPhysicalMaterial"; 17854 this.anisotropyRotation = 0; 17855 this.anisotropyMap = null; 17856 this.clearcoatMap = null; 17857 this.clearcoatRoughness = 0; 17858 this.clearcoatRoughnessMap = null; 17859 this.clearcoatNormalScale = new Vector2(1, 1); 17860 this.clearcoatNormalMap = null; 17861 this.ior = 1.5; 17862 Object.defineProperty(this, "reflectivity", { 17863 get: function() { 17864 return clamp(2.5 * (this.ior - 1) / (this.ior + 1), 0, 1); 17865 }, 17866 set: function(reflectivity) { 17867 this.ior = (1 + 0.4 * reflectivity) / (1 - 0.4 * reflectivity); 17868 } 17869 }); 17870 this.iridescenceMap = null; 17871 this.iridescenceIOR = 1.3; 17872 this.iridescenceThicknessRange = [100, 400]; 17873 this.iridescenceThicknessMap = null; 17874 this.sheenColor = new Color(0); 17875 this.sheenColorMap = null; 17876 this.sheenRoughness = 1; 17877 this.sheenRoughnessMap = null; 17878 this.transmissionMap = null; 17879 this.thickness = 0; 17880 this.thicknessMap = null; 17881 this.attenuationDistance = Infinity; 17882 this.attenuationColor = new Color(1, 1, 1); 17883 this.specularIntensity = 1; 17884 this.specularIntensityMap = null; 17885 this.specularColor = new Color(1, 1, 1); 17886 this.specularColorMap = null; 17887 this._anisotropy = 0; 17888 this._clearcoat = 0; 17889 this._dispersion = 0; 17890 this._iridescence = 0; 17891 this._sheen = 0; 17892 this._transmission = 0; 17893 this.setValues(parameters); 17894 } 17895 /** 17896 * The anisotropy strength, from `0.0` to `1.0`. 17897 * 17898 * @type {number} 17899 * @default 0 17900 */ 17901 get anisotropy() { 17902 return this._anisotropy; 17903 } 17904 set anisotropy(value) { 17905 if (this._anisotropy > 0 !== value > 0) { 17906 this.version++; 17907 } 17908 this._anisotropy = value; 17909 } 17910 /** 17911 * Represents the intensity of the clear coat layer, from `0.0` to `1.0`. Use 17912 * clear coat related properties to enable multilayer materials that have a 17913 * thin translucent layer over the base layer. 17914 * 17915 * @type {number} 17916 * @default 0 17917 */ 17918 get clearcoat() { 17919 return this._clearcoat; 17920 } 17921 set clearcoat(value) { 17922 if (this._clearcoat > 0 !== value > 0) { 17923 this.version++; 17924 } 17925 this._clearcoat = value; 17926 } 17927 /** 17928 * The intensity of the iridescence layer, simulating RGB color shift based on the angle between 17929 * the surface and the viewer, from `0.0` to `1.0`. 17930 * 17931 * @type {number} 17932 * @default 0 17933 */ 17934 get iridescence() { 17935 return this._iridescence; 17936 } 17937 set iridescence(value) { 17938 if (this._iridescence > 0 !== value > 0) { 17939 this.version++; 17940 } 17941 this._iridescence = value; 17942 } 17943 /** 17944 * Defines the strength of the angular separation of colors (chromatic aberration) transmitting 17945 * through a relatively clear volume. Any value zero or larger is valid, the typical range of 17946 * realistic values is `[0, 1]`. This property can be only be used with transmissive objects. 17947 * 17948 * @type {number} 17949 * @default 0 17950 */ 17951 get dispersion() { 17952 return this._dispersion; 17953 } 17954 set dispersion(value) { 17955 if (this._dispersion > 0 !== value > 0) { 17956 this.version++; 17957 } 17958 this._dispersion = value; 17959 } 17960 /** 17961 * The intensity of the sheen layer, from `0.0` to `1.0`. 17962 * 17963 * @type {number} 17964 * @default 0 17965 */ 17966 get sheen() { 17967 return this._sheen; 17968 } 17969 set sheen(value) { 17970 if (this._sheen > 0 !== value > 0) { 17971 this.version++; 17972 } 17973 this._sheen = value; 17974 } 17975 /** 17976 * Degree of transmission (or optical transparency), from `0.0` to `1.0`. 17977 * 17978 * Thin, transparent or semitransparent, plastic or glass materials remain 17979 * largely reflective even if they are fully transmissive. The transmission 17980 * property can be used to model these materials. 17981 * 17982 * When transmission is non-zero, `opacity` should be set to `1`. 17983 * 17984 * @type {number} 17985 * @default 0 17986 */ 17987 get transmission() { 17988 return this._transmission; 17989 } 17990 set transmission(value) { 17991 if (this._transmission > 0 !== value > 0) { 17992 this.version++; 17993 } 17994 this._transmission = value; 17995 } 17996 copy(source) { 17997 super.copy(source); 17998 this.defines = { 17999 "STANDARD": "", 18000 "PHYSICAL": "" 18001 }; 18002 this.anisotropy = source.anisotropy; 18003 this.anisotropyRotation = source.anisotropyRotation; 18004 this.anisotropyMap = source.anisotropyMap; 18005 this.clearcoat = source.clearcoat; 18006 this.clearcoatMap = source.clearcoatMap; 18007 this.clearcoatRoughness = source.clearcoatRoughness; 18008 this.clearcoatRoughnessMap = source.clearcoatRoughnessMap; 18009 this.clearcoatNormalMap = source.clearcoatNormalMap; 18010 this.clearcoatNormalScale.copy(source.clearcoatNormalScale); 18011 this.dispersion = source.dispersion; 18012 this.ior = source.ior; 18013 this.iridescence = source.iridescence; 18014 this.iridescenceMap = source.iridescenceMap; 18015 this.iridescenceIOR = source.iridescenceIOR; 18016 this.iridescenceThicknessRange = [...source.iridescenceThicknessRange]; 18017 this.iridescenceThicknessMap = source.iridescenceThicknessMap; 18018 this.sheen = source.sheen; 18019 this.sheenColor.copy(source.sheenColor); 18020 this.sheenColorMap = source.sheenColorMap; 18021 this.sheenRoughness = source.sheenRoughness; 18022 this.sheenRoughnessMap = source.sheenRoughnessMap; 18023 this.transmission = source.transmission; 18024 this.transmissionMap = source.transmissionMap; 18025 this.thickness = source.thickness; 18026 this.thicknessMap = source.thicknessMap; 18027 this.attenuationDistance = source.attenuationDistance; 18028 this.attenuationColor.copy(source.attenuationColor); 18029 this.specularIntensity = source.specularIntensity; 18030 this.specularIntensityMap = source.specularIntensityMap; 18031 this.specularColor.copy(source.specularColor); 18032 this.specularColorMap = source.specularColorMap; 18033 return this; 18034 } 18035}; 18036var MeshPhongMaterial = class extends Material { 18037 /** 18038 * Constructs a new mesh phong material. 18039 * 18040 * @param {Object} [parameters] - An object with one or more properties 18041 * defining the material's appearance. Any property of the material 18042 * (including any property from inherited materials) can be passed 18043 * in here. Color values can be passed any type of value accepted 18044 * by {@link Color#set}. 18045 */ 18046 constructor(parameters) { 18047 super(); 18048 this.isMeshPhongMaterial = true; 18049 this.type = "MeshPhongMaterial"; 18050 this.color = new Color(16777215); 18051 this.specular = new Color(1118481); 18052 this.shininess = 30; 18053 this.map = null; 18054 this.lightMap = null; 18055 this.lightMapIntensity = 1; 18056 this.aoMap = null; 18057 this.aoMapIntensity = 1; 18058 this.emissive = new Color(0); 18059 this.emissiveIntensity = 1; 18060 this.emissiveMap = null; 18061 this.bumpMap = null; 18062 this.bumpScale = 1; 18063 this.normalMap = null; 18064 this.normalMapType = TangentSpaceNormalMap; 18065 this.normalScale = new Vector2(1, 1); 18066 this.displacementMap = null; 18067 this.displacementScale = 1; 18068 this.displacementBias = 0; 18069 this.specularMap = null; 18070 this.alphaMap = null; 18071 this.envMap = null; 18072 this.envMapRotation = new Euler(); 18073 this.combine = MultiplyOperation; 18074 this.reflectivity = 1; 18075 this.envMapIntensity = 1; 18076 this.refractionRatio = 0.98; 18077 this.wireframe = false; 18078 this.wireframeLinewidth = 1; 18079 this.wireframeLinecap = "round"; 18080 this.wireframeLinejoin = "round"; 18081 this.flatShading = false; 18082 this.fog = true; 18083 this.setValues(parameters); 18084 } 18085 copy(source) { 18086 super.copy(source); 18087 this.color.copy(source.color); 18088 this.specular.copy(source.specular); 18089 this.shininess = source.shininess; 18090 this.map = source.map; 18091 this.lightMap = source.lightMap; 18092 this.lightMapIntensity = source.lightMapIntensity; 18093 this.aoMap = source.aoMap; 18094 this.aoMapIntensity = source.aoMapIntensity; 18095 this.emissive.copy(source.emissive); 18096 this.emissiveMap = source.emissiveMap; 18097 this.emissiveIntensity = source.emissiveIntensity; 18098 this.bumpMap = source.bumpMap; 18099 this.bumpScale = source.bumpScale; 18100 this.normalMap = source.normalMap; 18101 this.normalMapType = source.normalMapType; 18102 this.normalScale.copy(source.normalScale); 18103 this.displacementMap = source.displacementMap; 18104 this.displacementScale = source.displacementScale; 18105 this.displacementBias = source.displacementBias; 18106 this.specularMap = source.specularMap; 18107 this.alphaMap = source.alphaMap; 18108 this.envMap = source.envMap; 18109 this.envMapRotation.copy(source.envMapRotation); 18110 this.combine = source.combine; 18111 this.reflectivity = source.reflectivity; 18112 this.envMapIntensity = source.envMapIntensity; 18113 this.refractionRatio = source.refractionRatio; 18114 this.wireframe = source.wireframe; 18115 this.wireframeLinewidth = source.wireframeLinewidth; 18116 this.wireframeLinecap = source.wireframeLinecap; 18117 this.wireframeLinejoin = source.wireframeLinejoin; 18118 this.flatShading = source.flatShading; 18119 this.fog = source.fog; 18120 return this; 18121 } 18122}; 18123var MeshToonMaterial = class extends Material { 18124 /** 18125 * Constructs a new mesh toon material. 18126 * 18127 * @param {Object} [parameters] - An object with one or more properties 18128 * defining the material's appearance. Any property of the material 18129 * (including any property from inherited materials) can be passed 18130 * in here. Color values can be passed any type of value accepted 18131 * by {@link Color#set}. 18132 */ 18133 constructor(parameters) { 18134 super(); 18135 this.isMeshToonMaterial = true; 18136 this.defines = { "TOON": "" }; 18137 this.type = "MeshToonMaterial"; 18138 this.color = new Color(16777215); 18139 this.map = null; 18140 this.gradientMap = null; 18141 this.lightMap = null; 18142 this.lightMapIntensity = 1; 18143 this.aoMap = null; 18144 this.aoMapIntensity = 1; 18145 this.emissive = new Color(0); 18146 this.emissiveIntensity = 1; 18147 this.emissiveMap = null; 18148 this.bumpMap = null; 18149 this.bumpScale = 1; 18150 this.normalMap = null; 18151 this.normalMapType = TangentSpaceNormalMap; 18152 this.normalScale = new Vector2(1, 1); 18153 this.displacementMap = null; 18154 this.displacementScale = 1; 18155 this.displacementBias = 0; 18156 this.alphaMap = null; 18157 this.wireframe = false; 18158 this.wireframeLinewidth = 1; 18159 this.wireframeLinecap = "round"; 18160 this.wireframeLinejoin = "round"; 18161 this.fog = true; 18162 this.setValues(parameters); 18163 } 18164 copy(source) { 18165 super.copy(source); 18166 this.color.copy(source.color); 18167 this.map = source.map; 18168 this.gradientMap = source.gradientMap; 18169 this.lightMap = source.lightMap; 18170 this.lightMapIntensity = source.lightMapIntensity; 18171 this.aoMap = source.aoMap; 18172 this.aoMapIntensity = source.aoMapIntensity; 18173 this.emissive.copy(source.emissive); 18174 this.emissiveMap = source.emissiveMap; 18175 this.emissiveIntensity = source.emissiveIntensity; 18176 this.bumpMap = source.bumpMap; 18177 this.bumpScale = source.bumpScale; 18178 this.normalMap = source.normalMap; 18179 this.normalMapType = source.normalMapType; 18180 this.normalScale.copy(source.normalScale); 18181 this.displacementMap = source.displacementMap; 18182 this.displacementScale = source.displacementScale; 18183 this.displacementBias = source.displacementBias; 18184 this.alphaMap = source.alphaMap; 18185 this.wireframe = source.wireframe; 18186 this.wireframeLinewidth = source.wireframeLinewidth; 18187 this.wireframeLinecap = source.wireframeLinecap; 18188 this.wireframeLinejoin = source.wireframeLinejoin; 18189 this.fog = source.fog; 18190 return this; 18191 } 18192}; 18193var MeshNormalMaterial = class extends Material { 18194 /** 18195 * Constructs a new mesh normal material. 18196 * 18197 * @param {Object} [parameters] - An object with one or more properties 18198 * defining the material's appearance. Any property of the material 18199 * (including any property from inherited materials) can be passed 18200 * in here. Color values can be passed any type of value accepted 18201 * by {@link Color#set}. 18202 */ 18203 constructor(parameters) { 18204 super(); 18205 this.isMeshNormalMaterial = true; 18206 this.type = "MeshNormalMaterial"; 18207 this.bumpMap = null; 18208 this.bumpScale = 1; 18209 this.normalMap = null; 18210 this.normalMapType = TangentSpaceNormalMap; 18211 this.normalScale = new Vector2(1, 1); 18212 this.displacementMap = null; 18213 this.displacementScale = 1; 18214 this.displacementBias = 0; 18215 this.wireframe = false; 18216 this.wireframeLinewidth = 1; 18217 this.flatShading = false; 18218 this.setValues(parameters); 18219 } 18220 copy(source) { 18221 super.copy(source); 18222 this.bumpMap = source.bumpMap; 18223 this.bumpScale = source.bumpScale; 18224 this.normalMap = source.normalMap; 18225 this.normalMapType = source.normalMapType; 18226 this.normalScale.copy(source.normalScale); 18227 this.displacementMap = source.displacementMap; 18228 this.displacementScale = source.displacementScale; 18229 this.displacementBias = source.displacementBias; 18230 this.wireframe = source.wireframe; 18231 this.wireframeLinewidth = source.wireframeLinewidth; 18232 this.flatShading = source.flatShading; 18233 return this; 18234 } 18235}; 18236var MeshLambertMaterial = class extends Material { 18237 /** 18238 * Constructs a new mesh lambert material. 18239 * 18240 * @param {Object} [parameters] - An object with one or more properties 18241 * defining the material's appearance. Any property of the material 18242 * (including any property from inherited materials) can be passed 18243 * in here. Color values can be passed any type of value accepted 18244 * by {@link Color#set}. 18245 */ 18246 constructor(parameters) { 18247 super(); 18248 this.isMeshLambertMaterial = true; 18249 this.type = "MeshLambertMaterial"; 18250 this.color = new Color(16777215); 18251 this.map = null; 18252 this.lightMap = null; 18253 this.lightMapIntensity = 1; 18254 this.aoMap = null; 18255 this.aoMapIntensity = 1; 18256 this.emissive = new Color(0); 18257 this.emissiveIntensity = 1; 18258 this.emissiveMap = null; 18259 this.bumpMap = null; 18260 this.bumpScale = 1; 18261 this.normalMap = null; 18262 this.normalMapType = TangentSpaceNormalMap; 18263 this.normalScale = new Vector2(1, 1); 18264 this.displacementMap = null; 18265 this.displacementScale = 1; 18266 this.displacementBias = 0; 18267 this.specularMap = null; 18268 this.alphaMap = null; 18269 this.envMap = null; 18270 this.envMapRotation = new Euler(); 18271 this.combine = MultiplyOperation; 18272 this.reflectivity = 1; 18273 this.envMapIntensity = 1; 18274 this.refractionRatio = 0.98; 18275 this.wireframe = false; 18276 this.wireframeLinewidth = 1; 18277 this.wireframeLinecap = "round"; 18278 this.wireframeLinejoin = "round"; 18279 this.flatShading = false; 18280 this.fog = true; 18281 this.setValues(parameters); 18282 } 18283 copy(source) { 18284 super.copy(source); 18285 this.color.copy(source.color); 18286 this.map = source.map; 18287 this.lightMap = source.lightMap; 18288 this.lightMapIntensity = source.lightMapIntensity; 18289 this.aoMap = source.aoMap; 18290 this.aoMapIntensity = source.aoMapIntensity; 18291 this.emissive.copy(source.emissive); 18292 this.emissiveMap = source.emissiveMap; 18293 this.emissiveIntensity = source.emissiveIntensity; 18294 this.bumpMap = source.bumpMap; 18295 this.bumpScale = source.bumpScale; 18296 this.normalMap = source.normalMap; 18297 this.normalMapType = source.normalMapType; 18298 this.normalScale.copy(source.normalScale); 18299 this.displacementMap = source.displacementMap; 18300 this.displacementScale = source.displacementScale; 18301 this.displacementBias = source.displacementBias; 18302 this.specularMap = source.specularMap; 18303 this.alphaMap = source.alphaMap; 18304 this.envMap = source.envMap; 18305 this.envMapRotation.copy(source.envMapRotation); 18306 this.combine = source.combine; 18307 this.reflectivity = source.reflectivity; 18308 this.envMapIntensity = source.envMapIntensity; 18309 this.refractionRatio = source.refractionRatio; 18310 this.wireframe = source.wireframe; 18311 this.wireframeLinewidth = source.wireframeLinewidth; 18312 this.wireframeLinecap = source.wireframeLinecap; 18313 this.wireframeLinejoin = source.wireframeLinejoin; 18314 this.flatShading = source.flatShading; 18315 this.fog = source.fog; 18316 return this; 18317 } 18318}; 18319var MeshDepthMaterial = class extends Material { 18320 /** 18321 * Constructs a new mesh depth material. 18322 * 18323 * @param {Object} [parameters] - An object with one or more properties 18324 * defining the material's appearance. Any property of the material 18325 * (including any property from inherited materials) can be passed 18326 * in here. Color values can be passed any type of value accepted 18327 * by {@link Color#set}. 18328 */ 18329 constructor(parameters) { 18330 super(); 18331 this.isMeshDepthMaterial = true; 18332 this.type = "MeshDepthMaterial"; 18333 this.depthPacking = BasicDepthPacking; 18334 this.map = null; 18335 this.alphaMap = null; 18336 this.displacementMap = null; 18337 this.displacementScale = 1; 18338 this.displacementBias = 0; 18339 this.wireframe = false; 18340 this.wireframeLinewidth = 1; 18341 this.setValues(parameters); 18342 } 18343 copy(source) { 18344 super.copy(source); 18345 this.depthPacking = source.depthPacking; 18346 this.map = source.map; 18347 this.alphaMap = source.alphaMap; 18348 this.displacementMap = source.displacementMap; 18349 this.displacementScale = source.displacementScale; 18350 this.displacementBias = source.displacementBias; 18351 this.wireframe = source.wireframe; 18352 this.wireframeLinewidth = source.wireframeLinewidth; 18353 return this; 18354 } 18355}; 18356var MeshDistanceMaterial = class extends Material { 18357 /** 18358 * Constructs a new mesh distance material. 18359 * 18360 * @param {Object} [parameters] - An object with one or more properties 18361 * defining the material's appearance. Any property of the material 18362 * (including any property from inherited materials) can be passed 18363 * in here. Color values can be passed any type of value accepted 18364 * by {@link Color#set}. 18365 */ 18366 constructor(parameters) { 18367 super(); 18368 this.isMeshDistanceMaterial = true; 18369 this.type = "MeshDistanceMaterial"; 18370 this.map = null; 18371 this.alphaMap = null; 18372 this.displacementMap = null; 18373 this.displacementScale = 1; 18374 this.displacementBias = 0; 18375 this.setValues(parameters); 18376 } 18377 copy(source) { 18378 super.copy(source); 18379 this.map = source.map; 18380 this.alphaMap = source.alphaMap; 18381 this.displacementMap = source.displacementMap; 18382 this.displacementScale = source.displacementScale; 18383 this.displacementBias = source.displacementBias; 18384 return this; 18385 } 18386}; 18387var MeshMatcapMaterial = class extends Material { 18388 /** 18389 * Constructs a new mesh matcap material. 18390 * 18391 * @param {Object} [parameters] - An object with one or more properties 18392 * defining the material's appearance. Any property of the material 18393 * (including any property from inherited materials) can be passed 18394 * in here. Color values can be passed any type of value accepted 18395 * by {@link Color#set}. 18396 */ 18397 constructor(parameters) { 18398 super(); 18399 this.isMeshMatcapMaterial = true; 18400 this.defines = { "MATCAP": "" }; 18401 this.type = "MeshMatcapMaterial"; 18402 this.color = new Color(16777215); 18403 this.matcap = null; 18404 this.map = null; 18405 this.bumpMap = null; 18406 this.bumpScale = 1; 18407 this.normalMap = null; 18408 this.normalMapType = TangentSpaceNormalMap; 18409 this.normalScale = new Vector2(1, 1); 18410 this.displacementMap = null; 18411 this.displacementScale = 1; 18412 this.displacementBias = 0; 18413 this.alphaMap = null; 18414 this.wireframe = false; 18415 this.wireframeLinewidth = 1; 18416 this.flatShading = false; 18417 this.fog = true; 18418 this.setValues(parameters); 18419 } 18420 copy(source) { 18421 super.copy(source); 18422 this.defines = { "MATCAP": "" }; 18423 this.color.copy(source.color); 18424 this.matcap = source.matcap; 18425 this.map = source.map; 18426 this.bumpMap = source.bumpMap; 18427 this.bumpScale = source.bumpScale; 18428 this.normalMap = source.normalMap; 18429 this.normalMapType = source.normalMapType; 18430 this.normalScale.copy(source.normalScale); 18431 this.displacementMap = source.displacementMap; 18432 this.displacementScale = source.displacementScale; 18433 this.displacementBias = source.displacementBias; 18434 this.alphaMap = source.alphaMap; 18435 this.wireframe = source.wireframe; 18436 this.wireframeLinewidth = source.wireframeLinewidth; 18437 this.flatShading = source.flatShading; 18438 this.fog = source.fog; 18439 return this; 18440 } 18441}; 18442var LineDashedMaterial = class extends LineBasicMaterial { 18443 /** 18444 * Constructs a new line dashed material. 18445 * 18446 * @param {Object} [parameters] - An object with one or more properties 18447 * defining the material's appearance. Any property of the material 18448 * (including any property from inherited materials) can be passed 18449 * in here. Color values can be passed any type of value accepted 18450 * by {@link Color#set}. 18451 */ 18452 constructor(parameters) { 18453 super(); 18454 this.isLineDashedMaterial = true; 18455 this.type = "LineDashedMaterial"; 18456 this.scale = 1; 18457 this.dashSize = 3; 18458 this.gapSize = 1; 18459 this.setValues(parameters); 18460 } 18461 copy(source) { 18462 super.copy(source); 18463 this.scale = source.scale; 18464 this.dashSize = source.dashSize; 18465 this.gapSize = source.gapSize; 18466 return this; 18467 } 18468}; 18469function convertArray(array, type) { 18470 if (!array || array.constructor === type) return array; 18471 if (typeof type.BYTES_PER_ELEMENT === "number") { 18472 return new type(array); 18473 } 18474 return Array.prototype.slice.call(array); 18475} 18476function getKeyframeOrder(times) { 18477 function compareTime(i, j) { 18478 return times[i] - times[j]; 18479 } 18480 const n = times.length; 18481 const result = new Array(n); 18482 for (let i = 0; i !== n; ++i) result[i] = i; 18483 result.sort(compareTime); 18484 return result; 18485} 18486function sortedArray(values, stride, order) { 18487 const nValues = values.length; 18488 const result = new values.constructor(nValues); 18489 for (let i = 0, dstOffset = 0; dstOffset !== nValues; ++i) { 18490 const srcOffset = order[i] * stride; 18491 for (let j = 0; j !== stride; ++j) { 18492 result[dstOffset++] = values[srcOffset + j]; 18493 } 18494 } 18495 return result; 18496} 18497function flattenJSON(jsonKeys, times, values, valuePropertyName) { 18498 let i = 1, key = jsonKeys[0]; 18499 while (key !== void 0 && key[valuePropertyName] === void 0) { 18500 key = jsonKeys[i++]; 18501 } 18502 if (key === void 0) return; 18503 let value = key[valuePropertyName]; 18504 if (value === void 0) return; 18505 if (Array.isArray(value)) { 18506 do { 18507 value = key[valuePropertyName]; 18508 if (value !== void 0) { 18509 times.push(key.time); 18510 values.push(...value); 18511 } 18512 key = jsonKeys[i++]; 18513 } while (key !== void 0); 18514 } else if (value.toArray !== void 0) { 18515 do { 18516 value = key[valuePropertyName]; 18517 if (value !== void 0) { 18518 times.push(key.time); 18519 value.toArray(values, values.length); 18520 } 18521 key = jsonKeys[i++]; 18522 } while (key !== void 0); 18523 } else { 18524 do { 18525 value = key[valuePropertyName]; 18526 if (value !== void 0) { 18527 times.push(key.time); 18528 values.push(value); 18529 } 18530 key = jsonKeys[i++]; 18531 } while (key !== void 0); 18532 } 18533} 18534var Interpolant = class { 18535 /** 18536 * Constructs a new interpolant. 18537 * 18538 * @param {TypedArray} parameterPositions - The parameter positions hold the interpolation factors. 18539 * @param {TypedArray} sampleValues - The sample values. 18540 * @param {number} sampleSize - The sample size 18541 * @param {TypedArray} [resultBuffer] - The result buffer. 18542 */ 18543 constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { 18544 this.parameterPositions = parameterPositions; 18545 this._cachedIndex = 0; 18546 this.resultBuffer = resultBuffer !== void 0 ? resultBuffer : new sampleValues.constructor(sampleSize); 18547 this.sampleValues = sampleValues; 18548 this.valueSize = sampleSize; 18549 this.settings = null; 18550 this.DefaultSettings_ = {}; 18551 } 18552 /** 18553 * Evaluate the interpolant at position `t`. 18554 * 18555 * @param {number} t - The interpolation factor. 18556 * @return {TypedArray} The result buffer. 18557 */ 18558 evaluate(t) { 18559 const pp = this.parameterPositions; 18560 let i1 = this._cachedIndex, t1 = pp[i1], t0 = pp[i1 - 1]; 18561 validate_interval: { 18562 seek: { 18563 let right; 18564 linear_scan: { 18565 forward_scan: if (!(t < t1)) { 18566 for (let giveUpAt = i1 + 2; ; ) { 18567 if (t1 === void 0) { 18568 if (t < t0) break forward_scan; 18569 i1 = pp.length; 18570 this._cachedIndex = i1; 18571 return this.copySampleValue_(i1 - 1); 18572 } 18573 if (i1 === giveUpAt) break; 18574 t0 = t1; 18575 t1 = pp[++i1]; 18576 if (t < t1) { 18577 break seek; 18578 } 18579 } 18580 right = pp.length; 18581 break linear_scan; 18582 } 18583 if (!(t >= t0)) { 18584 const t1global = pp[1]; 18585 if (t < t1global) { 18586 i1 = 2; 18587 t0 = t1global; 18588 } 18589 for (let giveUpAt = i1 - 2; ; ) { 18590 if (t0 === void 0) { 18591 this._cachedIndex = 0; 18592 return this.copySampleValue_(0); 18593 } 18594 if (i1 === giveUpAt) break; 18595 t1 = t0; 18596 t0 = pp[--i1 - 1]; 18597 if (t >= t0) { 18598 break seek; 18599 } 18600 } 18601 right = i1; 18602 i1 = 0; 18603 break linear_scan; 18604 } 18605 break validate_interval; 18606 } 18607 while (i1 < right) { 18608 const mid = i1 + right >>> 1; 18609 if (t < pp[mid]) { 18610 right = mid; 18611 } else { 18612 i1 = mid + 1; 18613 } 18614 } 18615 t1 = pp[i1]; 18616 t0 = pp[i1 - 1]; 18617 if (t0 === void 0) { 18618 this._cachedIndex = 0; 18619 return this.copySampleValue_(0); 18620 } 18621 if (t1 === void 0) { 18622 i1 = pp.length; 18623 this._cachedIndex = i1; 18624 return this.copySampleValue_(i1 - 1); 18625 } 18626 } 18627 this._cachedIndex = i1; 18628 this.intervalChanged_(i1, t0, t1); 18629 } 18630 return this.interpolate_(i1, t0, t, t1); 18631 } 18632 /** 18633 * Returns the interpolation settings. 18634 * 18635 * @return {Object} The interpolation settings. 18636 */ 18637 getSettings_() { 18638 return this.settings || this.DefaultSettings_; 18639 } 18640 /** 18641 * Copies a sample value to the result buffer. 18642 * 18643 * @param {number} index - An index into the sample value buffer. 18644 * @return {TypedArray} The result buffer. 18645 */ 18646 copySampleValue_(index) { 18647 const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, offset = index * stride; 18648 for (let i = 0; i !== stride; ++i) { 18649 result[i] = values[offset + i]; 18650 } 18651 return result; 18652 } 18653 /** 18654 * Copies a sample value to the result buffer. 18655 * 18656 * @abstract 18657 * @param {number} i1 - An index into the sample value buffer. 18658 * @param {number} t0 - The previous interpolation factor. 18659 * @param {number} t - The current interpolation factor. 18660 * @param {number} t1 - The next interpolation factor. 18661 * @return {TypedArray} The result buffer. 18662 */ 18663 interpolate_() { 18664 throw new Error("call to abstract method"); 18665 } 18666 /** 18667 * Optional method that is executed when the interval has changed. 18668 * 18669 * @param {number} i1 - An index into the sample value buffer. 18670 * @param {number} t0 - The previous interpolation factor. 18671 * @param {number} t - The current interpolation factor. 18672 */ 18673 intervalChanged_() { 18674 } 18675}; 18676var CubicInterpolant = class extends Interpolant { 18677 /** 18678 * Constructs a new cubic interpolant. 18679 * 18680 * @param {TypedArray} parameterPositions - The parameter positions hold the interpolation factors. 18681 * @param {TypedArray} sampleValues - The sample values. 18682 * @param {number} sampleSize - The sample size 18683 * @param {TypedArray} [resultBuffer] - The result buffer. 18684 */ 18685 constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { 18686 super(parameterPositions, sampleValues, sampleSize, resultBuffer); 18687 this._weightPrev = -0; 18688 this._offsetPrev = -0; 18689 this._weightNext = -0; 18690 this._offsetNext = -0; 18691 this.DefaultSettings_ = { 18692 endingStart: ZeroCurvatureEnding, 18693 endingEnd: ZeroCurvatureEnding 18694 }; 18695 } 18696 intervalChanged_(i1, t0, t1) { 18697 const pp = this.parameterPositions; 18698 let iPrev = i1 - 2, iNext = i1 + 1, tPrev = pp[iPrev], tNext = pp[iNext]; 18699 if (tPrev === void 0) { 18700 switch (this.getSettings_().endingStart) { 18701 case ZeroSlopeEnding: 18702 iPrev = i1; 18703 tPrev = 2 * t0 - t1; 18704 break; 18705 case WrapAroundEnding: 18706 iPrev = pp.length - 2; 18707 tPrev = t0 + pp[iPrev] - pp[iPrev + 1]; 18708 break; 18709 default: 18710 iPrev = i1; 18711 tPrev = t1; 18712 } 18713 } 18714 if (tNext === void 0) { 18715 switch (this.getSettings_().endingEnd) { 18716 case ZeroSlopeEnding: 18717 iNext = i1; 18718 tNext = 2 * t1 - t0; 18719 break; 18720 case WrapAroundEnding: 18721 iNext = 1; 18722 tNext = t1 + pp[1] - pp[0]; 18723 break; 18724 default: 18725 iNext = i1 - 1; 18726 tNext = t0; 18727 } 18728 } 18729 const halfDt = (t1 - t0) * 0.5, stride = this.valueSize; 18730 this._weightPrev = halfDt / (t0 - tPrev); 18731 this._weightNext = halfDt / (tNext - t1); 18732 this._offsetPrev = iPrev * stride; 18733 this._offsetNext = iNext * stride; 18734 } 18735 interpolate_(i1, t0, t, t1) { 18736 const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, o1 = i1 * stride, o0 = o1 - stride, oP = this._offsetPrev, oN = this._offsetNext, wP = this._weightPrev, wN = this._weightNext, p = (t - t0) / (t1 - t0), pp = p * p, ppp = pp * p; 18737 const sP = -wP * ppp + 2 * wP * pp - wP * p; 18738 const s0 = (1 + wP) * ppp + (-1.5 - 2 * wP) * pp + (-0.5 + wP) * p + 1; 18739 const s1 = (-1 - wN) * ppp + (1.5 + wN) * pp + 0.5 * p; 18740 const sN = wN * ppp - wN * pp; 18741 for (let i = 0; i !== stride; ++i) { 18742 result[i] = sP * values[oP + i] + s0 * values[o0 + i] + s1 * values[o1 + i] + sN * values[oN + i]; 18743 } 18744 return result; 18745 } 18746}; 18747var LinearInterpolant = class extends Interpolant { 18748 /** 18749 * Constructs a new linear interpolant. 18750 * 18751 * @param {TypedArray} parameterPositions - The parameter positions hold the interpolation factors. 18752 * @param {TypedArray} sampleValues - The sample values. 18753 * @param {number} sampleSize - The sample size 18754 * @param {TypedArray} [resultBuffer] - The result buffer. 18755 */ 18756 constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { 18757 super(parameterPositions, sampleValues, sampleSize, resultBuffer); 18758 } 18759 interpolate_(i1, t0, t, t1) { 18760 const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, offset1 = i1 * stride, offset0 = offset1 - stride, weight1 = (t - t0) / (t1 - t0), weight0 = 1 - weight1; 18761 for (let i = 0; i !== stride; ++i) { 18762 result[i] = values[offset0 + i] * weight0 + values[offset1 + i] * weight1; 18763 } 18764 return result; 18765 } 18766}; 18767var DiscreteInterpolant = class extends Interpolant { 18768 /** 18769 * Constructs a new discrete interpolant. 18770 * 18771 * @param {TypedArray} parameterPositions - The parameter positions hold the interpolation factors. 18772 * @param {TypedArray} sampleValues - The sample values. 18773 * @param {number} sampleSize - The sample size 18774 * @param {TypedArray} [resultBuffer] - The result buffer. 18775 */ 18776 constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { 18777 super(parameterPositions, sampleValues, sampleSize, resultBuffer); 18778 } 18779 interpolate_(i1) { 18780 return this.copySampleValue_(i1 - 1); 18781 } 18782}; 18783var BezierInterpolant = class extends Interpolant { 18784 interpolate_(i1, t0, t, t1) { 18785 const result = this.resultBuffer; 18786 const values = this.sampleValues; 18787 const stride = this.valueSize; 18788 const offset1 = i1 * stride; 18789 const offset0 = offset1 - stride; 18790 const settings = this.settings || this.DefaultSettings_; 18791 const inTangents = settings.inTangents; 18792 const outTangents = settings.outTangents; 18793 if (!inTangents || !outTangents) { 18794 const weight1 = (t - t0) / (t1 - t0); 18795 const weight0 = 1 - weight1; 18796 for (let i = 0; i !== stride; ++i) { 18797 result[i] = values[offset0 + i] * weight0 + values[offset1 + i] * weight1; 18798 } 18799 return result; 18800 } 18801 const tangentStride = stride * 2; 18802 const i0 = i1 - 1; 18803 for (let i = 0; i !== stride; ++i) { 18804 const v0 = values[offset0 + i]; 18805 const v1 = values[offset1 + i]; 18806 const outTangentOffset = i0 * tangentStride + i * 2; 18807 const c0x = outTangents[outTangentOffset]; 18808 const c0y = outTangents[outTangentOffset + 1]; 18809 const inTangentOffset = i1 * tangentStride + i * 2; 18810 const c1x = inTangents[inTangentOffset]; 18811 const c1y = inTangents[inTangentOffset + 1]; 18812 let s = (t - t0) / (t1 - t0); 18813 let s2, s3, oneMinusS, oneMinusS2, oneMinusS3; 18814 for (let iter = 0; iter < 8; iter++) { 18815 s2 = s * s; 18816 s3 = s2 * s; 18817 oneMinusS = 1 - s; 18818 oneMinusS2 = oneMinusS * oneMinusS; 18819 oneMinusS3 = oneMinusS2 * oneMinusS; 18820 const bx = oneMinusS3 * t0 + 3 * oneMinusS2 * s * c0x + 3 * oneMinusS * s2 * c1x + s3 * t1; 18821 const error2 = bx - t; 18822 if (Math.abs(error2) < 1e-10) break; 18823 const dbx = 3 * oneMinusS2 * (c0x - t0) + 6 * oneMinusS * s * (c1x - c0x) + 3 * s2 * (t1 - c1x); 18824 if (Math.abs(dbx) < 1e-10) break; 18825 s = s - error2 / dbx; 18826 s = Math.max(0, Math.min(1, s)); 18827 } 18828 result[i] = oneMinusS3 * v0 + 3 * oneMinusS2 * s * c0y + 3 * oneMinusS * s2 * c1y + s3 * v1; 18829 } 18830 return result; 18831 } 18832}; 18833var KeyframeTrack = class { 18834 /** 18835 * Constructs a new keyframe track. 18836 * 18837 * @param {string} name - The keyframe track's name. 18838 * @param {Array<number>} times - A list of keyframe times. 18839 * @param {Array<number|string|boolean>} values - A list of keyframe values. 18840 * @param {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth|InterpolateBezier)} [interpolation] - The interpolation type. 18841 */ 18842 constructor(name, times, values, interpolation) { 18843 if (name === void 0) throw new Error("THREE.KeyframeTrack: track name is undefined"); 18844 if (times === void 0 || times.length === 0) throw new Error("THREE.KeyframeTrack: no keyframes in track named " + name); 18845 this.name = name; 18846 this.times = convertArray(times, this.TimeBufferType); 18847 this.values = convertArray(values, this.ValueBufferType); 18848 this.setInterpolation(interpolation || this.DefaultInterpolation); 18849 } 18850 /** 18851 * Converts the keyframe track to JSON. 18852 * 18853 * @static 18854 * @param {KeyframeTrack} track - The keyframe track to serialize. 18855 * @return {Object} The serialized keyframe track as JSON. 18856 */ 18857 static toJSON(track) { 18858 const trackType = track.constructor; 18859 let json; 18860 if (trackType.toJSON !== this.toJSON) { 18861 json = trackType.toJSON(track); 18862 } else { 18863 json = { 18864 "name": track.name, 18865 "times": convertArray(track.times, Array), 18866 "values": convertArray(track.values, Array) 18867 }; 18868 const interpolation = track.getInterpolation(); 18869 if (interpolation !== track.DefaultInterpolation) { 18870 json.interpolation = interpolation; 18871 } 18872 } 18873 json.type = track.ValueTypeName; 18874 return json; 18875 } 18876 /** 18877 * Factory method for creating a new discrete interpolant. 18878 * 18879 * @static 18880 * @param {TypedArray} [result] - The result buffer. 18881 * @return {DiscreteInterpolant} The new interpolant. 18882 */ 18883 InterpolantFactoryMethodDiscrete(result) { 18884 return new DiscreteInterpolant(this.times, this.values, this.getValueSize(), result); 18885 } 18886 /** 18887 * Factory method for creating a new linear interpolant. 18888 * 18889 * @static 18890 * @param {TypedArray} [result] - The result buffer. 18891 * @return {LinearInterpolant} The new interpolant. 18892 */ 18893 InterpolantFactoryMethodLinear(result) { 18894 return new LinearInterpolant(this.times, this.values, this.getValueSize(), result); 18895 } 18896 /** 18897 * Factory method for creating a new smooth interpolant. 18898 * 18899 * @static 18900 * @param {TypedArray} [result] - The result buffer. 18901 * @return {CubicInterpolant} The new interpolant. 18902 */ 18903 InterpolantFactoryMethodSmooth(result) { 18904 return new CubicInterpolant(this.times, this.values, this.getValueSize(), result); 18905 } 18906 /** 18907 * Factory method for creating a new Bezier interpolant. 18908 * 18909 * The Bezier interpolant requires tangent data to be set via the `settings` property 18910 * on the track before creating the interpolant. The settings should contain: 18911 * - `inTangents`: Float32Array with [time, value] pairs per keyframe per component 18912 * - `outTangents`: Float32Array with [time, value] pairs per keyframe per component 18913 * 18914 * @static 18915 * @param {TypedArray} [result] - The result buffer. 18916 * @return {BezierInterpolant} The new interpolant. 18917 */ 18918 InterpolantFactoryMethodBezier(result) { 18919 const interpolant = new BezierInterpolant(this.times, this.values, this.getValueSize(), result); 18920 if (this.settings) { 18921 interpolant.settings = this.settings; 18922 } 18923 return interpolant; 18924 } 18925 /** 18926 * Defines the interpolation factor method for this keyframe track. 18927 * 18928 * @param {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth|InterpolateBezier)} interpolation - The interpolation type. 18929 * @return {KeyframeTrack} A reference to this keyframe track. 18930 */ 18931 setInterpolation(interpolation) { 18932 let factoryMethod; 18933 switch (interpolation) { 18934 case InterpolateDiscrete: 18935 factoryMethod = this.InterpolantFactoryMethodDiscrete; 18936 break; 18937 case InterpolateLinear: 18938 factoryMethod = this.InterpolantFactoryMethodLinear; 18939 break; 18940 case InterpolateSmooth: 18941 factoryMethod = this.InterpolantFactoryMethodSmooth; 18942 break; 18943 case InterpolateBezier: 18944 factoryMethod = this.InterpolantFactoryMethodBezier; 18945 break; 18946 } 18947 if (factoryMethod === void 0) { 18948 const message = "unsupported interpolation for " + this.ValueTypeName + " keyframe track named " + this.name; 18949 if (this.createInterpolant === void 0) { 18950 if (interpolation !== this.DefaultInterpolation) { 18951 this.setInterpolation(this.DefaultInterpolation); 18952 } else { 18953 throw new Error(message); 18954 } 18955 } 18956 warn("KeyframeTrack:", message); 18957 return this; 18958 } 18959 this.createInterpolant = factoryMethod; 18960 return this; 18961 } 18962 /** 18963 * Returns the current interpolation type. 18964 * 18965 * @return {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth|InterpolateBezier)} The interpolation type. 18966 */ 18967 getInterpolation() { 18968 switch (this.createInterpolant) { 18969 case this.InterpolantFactoryMethodDiscrete: 18970 return InterpolateDiscrete; 18971 case this.InterpolantFactoryMethodLinear: 18972 return InterpolateLinear; 18973 case this.InterpolantFactoryMethodSmooth: 18974 return InterpolateSmooth; 18975 case this.InterpolantFactoryMethodBezier: 18976 return InterpolateBezier; 18977 } 18978 } 18979 /** 18980 * Returns the value size. 18981 * 18982 * @return {number} The value size. 18983 */ 18984 getValueSize() { 18985 return this.values.length / this.times.length; 18986 } 18987 /** 18988 * Moves all keyframes either forward or backward in time. 18989 * 18990 * @param {number} timeOffset - The offset to move the time values. 18991 * @return {KeyframeTrack} A reference to this keyframe track. 18992 */ 18993 shift(timeOffset) { 18994 if (timeOffset !== 0) { 18995 const times = this.times; 18996 for (let i = 0, n = times.length; i !== n; ++i) { 18997 times[i] += timeOffset; 18998 } 18999 } 19000 return this; 19001 } 19002 /** 19003 * Scale all keyframe times by a factor (useful for frame - seconds conversions). 19004 * 19005 * @param {number} timeScale - The time scale. 19006 * @return {KeyframeTrack} A reference to this keyframe track. 19007 */ 19008 scale(timeScale) { 19009 if (timeScale !== 1) { 19010 const times = this.times; 19011 for (let i = 0, n = times.length; i !== n; ++i) { 19012 times[i] *= timeScale; 19013 } 19014 } 19015 return this; 19016 } 19017 /** 19018 * Removes keyframes before and after animation without changing any values within the defined time range. 19019 * 19020 * Note: The method does not shift around keys to the start of the track time, because for interpolated 19021 * keys this will change their values 19022 * 19023 * @param {number} startTime - The start time. 19024 * @param {number} endTime - The end time. 19025 * @return {KeyframeTrack} A reference to this keyframe track. 19026 */ 19027 trim(startTime, endTime) { 19028 const times = this.times, nKeys = times.length; 19029 let from = 0, to = nKeys - 1; 19030 while (from !== nKeys && times[from] < startTime) { 19031 ++from; 19032 } 19033 while (to !== -1 && times[to] > endTime) { 19034 --to; 19035 } 19036 ++to; 19037 if (from !== 0 || to !== nKeys) { 19038 if (from >= to) { 19039 to = Math.max(to, 1); 19040 from = to - 1; 19041 } 19042 const stride = this.getValueSize(); 19043 this.times = times.slice(from, to); 19044 this.values = this.values.slice(from * stride, to * stride); 19045 } 19046 return this; 19047 } 19048 /** 19049 * Performs minimal validation on the keyframe track. Returns `true` if the values 19050 * are valid. 19051 * 19052 * @return {boolean} Whether the keyframes are valid or not. 19053 */ 19054 validate() { 19055 let valid = true; 19056 const valueSize = this.getValueSize(); 19057 if (valueSize - Math.floor(valueSize) !== 0) { 19058 error("KeyframeTrack: Invalid value size in track.", this); 19059 valid = false; 19060 } 19061 const times = this.times, values = this.values, nKeys = times.length; 19062 if (nKeys === 0) { 19063 error("KeyframeTrack: Track is empty.", this); 19064 valid = false; 19065 } 19066 let prevTime = null; 19067 for (let i = 0; i !== nKeys; i++) { 19068 const currTime = times[i]; 19069 if (typeof currTime === "number" && isNaN(currTime)) { 19070 error("KeyframeTrack: Time is not a valid number.", this, i, currTime); 19071 valid = false; 19072 break; 19073 } 19074 if (prevTime !== null && prevTime > currTime) { 19075 error("KeyframeTrack: Out of order keys.", this, i, currTime, prevTime); 19076 valid = false; 19077 break; 19078 } 19079 prevTime = currTime; 19080 } 19081 if (values !== void 0) { 19082 if (isTypedArray(values)) { 19083 for (let i = 0, n = values.length; i !== n; ++i) { 19084 const value = values[i]; 19085 if (isNaN(value)) { 19086 error("KeyframeTrack: Value is not a valid number.", this, i, value); 19087 valid = false; 19088 break; 19089 } 19090 } 19091 } 19092 } 19093 return valid; 19094 } 19095 /** 19096 * Optimizes this keyframe track by removing equivalent sequential keys (which are 19097 * common in morph target sequences). 19098 * 19099 * @return {KeyframeTrack} A reference to this keyframe track. 19100 */ 19101 optimize() { 19102 const times = this.times.slice(), values = this.values.slice(), stride = this.getValueSize(), smoothInterpolation = this.getInterpolation() === InterpolateSmooth, lastIndex = times.length - 1; 19103 let writeIndex = 1; 19104 for (let i = 1; i < lastIndex; ++i) { 19105 let keep = false; 19106 const time = times[i]; 19107 const timeNext = times[i + 1]; 19108 if (time !== timeNext && (i !== 1 || time !== times[0])) { 19109 if (!smoothInterpolation) { 19110 const offset = i * stride, offsetP = offset - stride, offsetN = offset + stride; 19111 for (let j = 0; j !== stride; ++j) { 19112 const value = values[offset + j]; 19113 if (value !== values[offsetP + j] || value !== values[offsetN + j]) { 19114 keep = true; 19115 break; 19116 } 19117 } 19118 } else { 19119 keep = true; 19120 } 19121 } 19122 if (keep) { 19123 if (i !== writeIndex) { 19124 times[writeIndex] = times[i]; 19125 const readOffset = i * stride, writeOffset = writeIndex * stride; 19126 for (let j = 0; j !== stride; ++j) { 19127 values[writeOffset + j] = values[readOffset + j]; 19128 } 19129 } 19130 ++writeIndex; 19131 } 19132 } 19133 if (lastIndex > 0) { 19134 times[writeIndex] = times[lastIndex]; 19135 for (let readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++j) { 19136 values[writeOffset + j] = values[readOffset + j]; 19137 } 19138 ++writeIndex; 19139 } 19140 if (writeIndex !== times.length) { 19141 this.times = times.slice(0, writeIndex); 19142 this.values = values.slice(0, writeIndex * stride); 19143 } else { 19144 this.times = times; 19145 this.values = values; 19146 } 19147 return this; 19148 } 19149 /** 19150 * Returns a new keyframe track with copied values from this instance. 19151 * 19152 * @return {KeyframeTrack} A clone of this instance. 19153 */ 19154 clone() { 19155 const times = this.times.slice(); 19156 const values = this.values.slice(); 19157 const TypedKeyframeTrack = this.constructor; 19158 const track = new TypedKeyframeTrack(this.name, times, values); 19159 track.createInterpolant = this.createInterpolant; 19160 return track; 19161 } 19162}; 19163KeyframeTrack.prototype.ValueTypeName = ""; 19164KeyframeTrack.prototype.TimeBufferType = Float32Array; 19165KeyframeTrack.prototype.ValueBufferType = Float32Array; 19166KeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear; 19167var BooleanKeyframeTrack = class extends KeyframeTrack { 19168 /** 19169 * Constructs a new boolean keyframe track. 19170 * 19171 * This keyframe track type has no `interpolation` parameter because the 19172 * interpolation is always discrete. 19173 * 19174 * @param {string} name - The keyframe track's name. 19175 * @param {Array<number>} times - A list of keyframe times. 19176 * @param {Array<boolean>} values - A list of keyframe values. 19177 */ 19178 constructor(name, times, values) { 19179 super(name, times, values); 19180 } 19181}; 19182BooleanKeyframeTrack.prototype.ValueTypeName = "bool"; 19183BooleanKeyframeTrack.prototype.ValueBufferType = Array; 19184BooleanKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete; 19185BooleanKeyframeTrack.prototype.InterpolantFactoryMethodLinear = void 0; 19186BooleanKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = void 0; 19187var ColorKeyframeTrack = class extends KeyframeTrack { 19188 /** 19189 * Constructs a new color keyframe track. 19190 * 19191 * @param {string} name - The keyframe track's name. 19192 * @param {Array<number>} times - A list of keyframe times. 19193 * @param {Array<number>} values - A list of keyframe values. 19194 * @param {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth)} [interpolation] - The interpolation type. 19195 */ 19196 constructor(name, times, values, interpolation) { 19197 super(name, times, values, interpolation); 19198 } 19199}; 19200ColorKeyframeTrack.prototype.ValueTypeName = "color"; 19201var NumberKeyframeTrack = class extends KeyframeTrack { 19202 /** 19203 * Constructs a new number keyframe track. 19204 * 19205 * @param {string} name - The keyframe track's name. 19206 * @param {Array<number>} times - A list of keyframe times. 19207 * @param {Array<number>} values - A list of keyframe values. 19208 * @param {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth)} [interpolation] - The interpolation type. 19209 */ 19210 constructor(name, times, values, interpolation) { 19211 super(name, times, values, interpolation); 19212 } 19213}; 19214NumberKeyframeTrack.prototype.ValueTypeName = "number"; 19215var QuaternionLinearInterpolant = class extends Interpolant { 19216 /** 19217 * Constructs a new SLERP interpolant. 19218 * 19219 * @param {TypedArray} parameterPositions - The parameter positions hold the interpolation factors. 19220 * @param {TypedArray} sampleValues - The sample values. 19221 * @param {number} sampleSize - The sample size 19222 * @param {TypedArray} [resultBuffer] - The result buffer. 19223 */ 19224 constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { 19225 super(parameterPositions, sampleValues, sampleSize, resultBuffer); 19226 } 19227 interpolate_(i1, t0, t, t1) { 19228 const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, alpha = (t - t0) / (t1 - t0); 19229 let offset = i1 * stride; 19230 for (let end = offset + stride; offset !== end; offset += 4) { 19231 Quaternion.slerpFlat(result, 0, values, offset - stride, values, offset, alpha); 19232 } 19233 return result; 19234 } 19235}; 19236var QuaternionKeyframeTrack = class extends KeyframeTrack { 19237 /** 19238 * Constructs a new Quaternion keyframe track. 19239 * 19240 * @param {string} name - The keyframe track's name. 19241 * @param {Array<number>} times - A list of keyframe times. 19242 * @param {Array<number>} values - A list of keyframe values. 19243 * @param {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth)} [interpolation] - The interpolation type. 19244 */ 19245 constructor(name, times, values, interpolation) { 19246 super(name, times, values, interpolation); 19247 } 19248 /** 19249 * Overwritten so the method returns Quaternion based interpolant. 19250 * 19251 * @static 19252 * @param {TypedArray} [result] - The result buffer. 19253 * @return {QuaternionLinearInterpolant} The new interpolant. 19254 */ 19255 InterpolantFactoryMethodLinear(result) { 19256 return new QuaternionLinearInterpolant(this.times, this.values, this.getValueSize(), result); 19257 } 19258}; 19259QuaternionKeyframeTrack.prototype.ValueTypeName = "quaternion"; 19260QuaternionKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = void 0; 19261var StringKeyframeTrack = class extends KeyframeTrack { 19262 /** 19263 * Constructs a new string keyframe track. 19264 * 19265 * This keyframe track type has no `interpolation` parameter because the 19266 * interpolation is always discrete. 19267 * 19268 * @param {string} name - The keyframe track's name. 19269 * @param {Array<number>} times - A list of keyframe times. 19270 * @param {Array<string>} values - A list of keyframe values. 19271 */ 19272 constructor(name, times, values) { 19273 super(name, times, values); 19274 } 19275}; 19276StringKeyframeTrack.prototype.ValueTypeName = "string"; 19277StringKeyframeTrack.prototype.ValueBufferType = Array; 19278StringKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete; 19279StringKeyframeTrack.prototype.InterpolantFactoryMethodLinear = void 0; 19280StringKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = void 0; 19281var VectorKeyframeTrack = class extends KeyframeTrack { 19282 /** 19283 * Constructs a new vector keyframe track. 19284 * 19285 * @param {string} name - The keyframe track's name. 19286 * @param {Array<number>} times - A list of keyframe times. 19287 * @param {Array<number>} values - A list of keyframe values. 19288 * @param {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth)} [interpolation] - The interpolation type. 19289 */ 19290 constructor(name, times, values, interpolation) { 19291 super(name, times, values, interpolation); 19292 } 19293}; 19294VectorKeyframeTrack.prototype.ValueTypeName = "vector"; 19295var AnimationClip = class { 19296 /** 19297 * Constructs a new animation clip. 19298 * 19299 * Note: Instead of instantiating an AnimationClip directly with the constructor, you can 19300 * use the static interface of this class for creating clips. In most cases though, animation clips 19301 * will automatically be created by loaders when importing animated 3D assets. 19302 * 19303 * @param {string} [name=''] - The clip's name. 19304 * @param {number} [duration=-1] - The clip's duration in seconds. If a negative value is passed, 19305 * the duration will be calculated from the passed keyframes. 19306 * @param {Array<KeyframeTrack>} tracks - An array of keyframe tracks. 19307 * @param {(NormalAnimationBlendMode|AdditiveAnimationBlendMode)} [blendMode=NormalAnimationBlendMode] - Defines how the animation 19308 * is blended/combined when two or more animations are simultaneously played. 19309 */ 19310 constructor(name = "", duration = -1, tracks = [], blendMode = NormalAnimationBlendMode) { 19311 this.name = name; 19312 this.tracks = tracks; 19313 this.duration = duration; 19314 this.blendMode = blendMode; 19315 this.uuid = generateUUID(); 19316 this.userData = {}; 19317 if (this.duration < 0) { 19318 this.resetDuration(); 19319 } 19320 } 19321 /** 19322 * Factory method for creating an animation clip from the given JSON. 19323 * 19324 * @static 19325 * @param {Object} json - The serialized animation clip. 19326 * @return {AnimationClip} The new animation clip. 19327 */ 19328 static parse(json) { 19329 const tracks = [], jsonTracks = json.tracks, frameTime = 1 / (json.fps || 1); 19330 for (let i = 0, n = jsonTracks.length; i !== n; ++i) { 19331 tracks.push(parseKeyframeTrack(jsonTracks[i]).scale(frameTime)); 19332 } 19333 const clip = new this(json.name, json.duration, tracks, json.blendMode); 19334 clip.uuid = json.uuid; 19335 clip.userData = JSON.parse(json.userData || "{}"); 19336 return clip; 19337 } 19338 /** 19339 * Serializes the given animation clip into JSON. 19340 * 19341 * @static 19342 * @param {AnimationClip} clip - The animation clip to serialize. 19343 * @return {Object} The JSON object. 19344 */ 19345 static toJSON(clip) { 19346 const tracks = [], clipTracks = clip.tracks; 19347 const json = { 19348 "name": clip.name, 19349 "duration": clip.duration, 19350 "tracks": tracks, 19351 "uuid": clip.uuid, 19352 "blendMode": clip.blendMode, 19353 "userData": JSON.stringify(clip.userData) 19354 }; 19355 for (let i = 0, n = clipTracks.length; i !== n; ++i) { 19356 tracks.push(KeyframeTrack.toJSON(clipTracks[i])); 19357 } 19358 return json; 19359 } 19360 /** 19361 * Returns a new animation clip from the passed morph targets array of a 19362 * geometry, taking a name and the number of frames per second. 19363 * 19364 * Note: The fps parameter is required, but the animation speed can be 19365 * overridden via {@link AnimationAction#setDuration}. 19366 * 19367 * @static 19368 * @param {string} name - The name of the animation clip. 19369 * @param {Array<Object>} morphTargetSequence - A sequence of morph targets. 19370 * @param {number} fps - The Frames-Per-Second value. 19371 * @param {boolean} noLoop - Whether the clip should be no loop or not. 19372 * @return {AnimationClip} The new animation clip. 19373 */ 19374 static CreateFromMorphTargetSequence(name, morphTargetSequence, fps, noLoop) { 19375 const numMorphTargets = morphTargetSequence.length; 19376 const tracks = []; 19377 for (let i = 0; i < numMorphTargets; i++) { 19378 let times = []; 19379 let values = []; 19380 times.push( 19381 (i + numMorphTargets - 1) % numMorphTargets, 19382 i, 19383 (i + 1) % numMorphTargets 19384 ); 19385 values.push(0, 1, 0); 19386 const order = getKeyframeOrder(times); 19387 times = sortedArray(times, 1, order); 19388 values = sortedArray(values, 1, order); 19389 if (!noLoop && times[0] === 0) { 19390 times.push(numMorphTargets); 19391 values.push(values[0]); 19392 } 19393 tracks.push( 19394 new NumberKeyframeTrack( 19395 ".morphTargetInfluences[" + morphTargetSequence[i].name + "]", 19396 times, 19397 values 19398 ).scale(1 / fps) 19399 ); 19400 } 19401 return new this(name, -1, tracks); 19402 } 19403 /** 19404 * Searches for an animation clip by name, taking as its first parameter 19405 * either an array of clips, or a mesh or geometry that contains an 19406 * array named "animations" property. 19407 * 19408 * @static 19409 * @param {(Array<AnimationClip>|Object3D)} objectOrClipArray - The array or object to search through. 19410 * @param {string} name - The name to search for. 19411 * @return {?AnimationClip} The found animation clip. Returns `null` if no clip has been found. 19412 */ 19413 static findByName(objectOrClipArray, name) { 19414 let clipArray = objectOrClipArray; 19415 if (!Array.isArray(objectOrClipArray)) { 19416 const o = objectOrClipArray; 19417 clipArray = o.geometry && o.geometry.animations || o.animations; 19418 } 19419 for (let i = 0; i < clipArray.length; i++) { 19420 if (clipArray[i].name === name) { 19421 return clipArray[i]; 19422 } 19423 } 19424 return null; 19425 } 19426 /** 19427 * Returns an array of new AnimationClips created from the morph target 19428 * sequences of a geometry, trying to sort morph target names into 19429 * animation-group-based patterns like "Walk_001, Walk_002, Run_001, Run_002...". 19430 * 19431 * See {@link MD2Loader#parse} as an example for how the method should be used. 19432 * 19433 * @static 19434 * @param {Array<Object>} morphTargets - A sequence of morph targets. 19435 * @param {number} fps - The Frames-Per-Second value. 19436 * @param {boolean} noLoop - Whether the clip should be no loop or not. 19437 * @return {Array<AnimationClip>} An array of new animation clips. 19438 */ 19439 static CreateClipsFromMorphTargetSequences(morphTargets, fps, noLoop) { 19440 const animationToMorphTargets = {}; 19441 const pattern = /^([\w-]*?)([\d]+)$/; 19442 for (let i = 0, il = morphTargets.length; i < il; i++) { 19443 const morphTarget = morphTargets[i]; 19444 const parts = morphTarget.name.match(pattern); 19445 if (parts && parts.length > 1) { 19446 const name = parts[1]; 19447 let animationMorphTargets = animationToMorphTargets[name]; 19448 if (!animationMorphTargets) { 19449 animationToMorphTargets[name] = animationMorphTargets = []; 19450 } 19451 animationMorphTargets.push(morphTarget); 19452 } 19453 } 19454 const clips = []; 19455 for (const name in animationToMorphTargets) { 19456 clips.push(this.CreateFromMorphTargetSequence(name, animationToMorphTargets[name], fps, noLoop)); 19457 } 19458 return clips; 19459 } 19460 /** 19461 * Parses the `animation.hierarchy` format and returns a new animation clip. 19462 * 19463 * @static 19464 * @deprecated since r175. 19465 * @param {Object} animation - A serialized animation clip as JSON. 19466 * @param {Array<Bone>} bones - An array of bones. 19467 * @return {?AnimationClip} The new animation clip. 19468 */ 19469 static parseAnimation(animation, bones) { 19470 warn("AnimationClip: parseAnimation() is deprecated and will be removed with r185"); 19471 if (!animation) { 19472 error("AnimationClip: No animation in JSONLoader data."); 19473 return null; 19474 } 19475 const addNonemptyTrack = function(trackType, trackName, animationKeys, propertyName, destTracks) { 19476 if (animationKeys.length !== 0) { 19477 const times = []; 19478 const values = []; 19479 flattenJSON(animationKeys, times, values, propertyName); 19480 if (times.length !== 0) { 19481 destTracks.push(new trackType(trackName, times, values)); 19482 } 19483 } 19484 }; 19485 const tracks = []; 19486 const clipName = animation.name || "default"; 19487 const fps = animation.fps || 30; 19488 const blendMode = animation.blendMode; 19489 let duration = animation.length || -1; 19490 const hierarchyTracks = animation.hierarchy || []; 19491 for (let h = 0; h < hierarchyTracks.length; h++) { 19492 const animationKeys = hierarchyTracks[h].keys; 19493 if (!animationKeys || animationKeys.length === 0) continue; 19494 if (animationKeys[0].morphTargets) { 19495 const morphTargetNames = {}; 19496 let k; 19497 for (k = 0; k < animationKeys.length; k++) { 19498 if (animationKeys[k].morphTargets) { 19499 for (let m = 0; m < animationKeys[k].morphTargets.length; m++) { 19500 morphTargetNames[animationKeys[k].morphTargets[m]] = -1; 19501 } 19502 } 19503 } 19504 for (const morphTargetName in morphTargetNames) { 19505 const times = []; 19506 const values = []; 19507 for (let m = 0; m !== animationKeys[k].morphTargets.length; ++m) { 19508 const animationKey = animationKeys[k]; 19509 times.push(animationKey.time); 19510 values.push(animationKey.morphTarget === morphTargetName ? 1 : 0); 19511 } 19512 tracks.push(new NumberKeyframeTrack(".morphTargetInfluence[" + morphTargetName + "]", times, values)); 19513 } 19514 duration = morphTargetNames.length * fps; 19515 } else { 19516 const boneName = ".bones[" + bones[h].name + "]"; 19517 addNonemptyTrack( 19518 VectorKeyframeTrack, 19519 boneName + ".position", 19520 animationKeys, 19521 "pos", 19522 tracks 19523 ); 19524 addNonemptyTrack( 19525 QuaternionKeyframeTrack, 19526 boneName + ".quaternion", 19527 animationKeys, 19528 "rot", 19529 tracks 19530 ); 19531 addNonemptyTrack( 19532 VectorKeyframeTrack, 19533 boneName + ".scale", 19534 animationKeys, 19535 "scl", 19536 tracks 19537 ); 19538 } 19539 } 19540 if (tracks.length === 0) { 19541 return null; 19542 } 19543 const clip = new this(clipName, duration, tracks, blendMode); 19544 return clip; 19545 } 19546 /** 19547 * Sets the duration of this clip to the duration of its longest keyframe track. 19548 * 19549 * @return {AnimationClip} A reference to this animation clip. 19550 */ 19551 resetDuration() { 19552 const tracks = this.tracks; 19553 let duration = 0; 19554 for (let i = 0, n = tracks.length; i !== n; ++i) { 19555 const track = this.tracks[i]; 19556 duration = Math.max(duration, track.times[track.times.length - 1]); 19557 } 19558 this.duration = duration; 19559 return this; 19560 } 19561 /** 19562 * Trims all tracks to the clip's duration. 19563 * 19564 * @return {AnimationClip} A reference to this animation clip. 19565 */ 19566 trim() { 19567 for (let i = 0; i < this.tracks.length; i++) { 19568 this.tracks[i].trim(0, this.duration); 19569 } 19570 return this; 19571 } 19572 /** 19573 * Performs minimal validation on each track in the clip. Returns `true` if all 19574 * tracks are valid. 19575 * 19576 * @return {boolean} Whether the clip's keyframes are valid or not. 19577 */ 19578 validate() { 19579 let valid = true; 19580 for (let i = 0; i < this.tracks.length; i++) { 19581 valid = valid && this.tracks[i].validate(); 19582 } 19583 return valid; 19584 } 19585 /** 19586 * Optimizes each track by removing equivalent sequential keys (which are 19587 * common in morph target sequences). 19588 * 19589 * @return {AnimationClip} A reference to this animation clip. 19590 */ 19591 optimize() { 19592 for (let i = 0; i < this.tracks.length; i++) { 19593 this.tracks[i].optimize(); 19594 } 19595 return this; 19596 } 19597 /** 19598 * Returns a new animation clip with copied values from this instance. 19599 * 19600 * @return {AnimationClip} A clone of this instance. 19601 */ 19602 clone() { 19603 const tracks = []; 19604 for (let i = 0; i < this.tracks.length; i++) { 19605 tracks.push(this.tracks[i].clone()); 19606 } 19607 const clip = new this.constructor(this.name, this.duration, tracks, this.blendMode); 19608 clip.userData = JSON.parse(JSON.stringify(this.userData)); 19609 return clip; 19610 } 19611 /** 19612 * Serializes this animation clip into JSON. 19613 * 19614 * @return {Object} The JSON object. 19615 */ 19616 toJSON() { 19617 return this.constructor.toJSON(this); 19618 } 19619}; 19620function getTrackTypeForValueTypeName(typeName) { 19621 switch (typeName.toLowerCase()) { 19622 case "scalar": 19623 case "double": 19624 case "float": 19625 case "number": 19626 case "integer": 19627 return NumberKeyframeTrack; 19628 case "vector": 19629 case "vector2": 19630 case "vector3": 19631 case "vector4": 19632 return VectorKeyframeTrack; 19633 case "color": 19634 return ColorKeyframeTrack; 19635 case "quaternion": 19636 return QuaternionKeyframeTrack; 19637 case "bool": 19638 case "boolean": 19639 return BooleanKeyframeTrack; 19640 case "string": 19641 return StringKeyframeTrack; 19642 } 19643 throw new Error("THREE.KeyframeTrack: Unsupported typeName: " + typeName); 19644} 19645function parseKeyframeTrack(json) { 19646 if (json.type === void 0) { 19647 throw new Error("THREE.KeyframeTrack: track type undefined, can not parse"); 19648 } 19649 const trackType = getTrackTypeForValueTypeName(json.type); 19650 if (json.times === void 0) { 19651 const times = [], values = []; 19652 flattenJSON(json.keys, times, values, "value"); 19653 json.times = times; 19654 json.values = values; 19655 } 19656 if (trackType.parse !== void 0) { 19657 return trackType.parse(json); 19658 } else { 19659 return new trackType(json.name, json.times, json.values, json.interpolation); 19660 } 19661} 19662var Cache = { 19663 /** 19664 * Whether caching is enabled or not. 19665 * 19666 * @static 19667 * @type {boolean} 19668 * @default false 19669 */ 19670 enabled: false, 19671 /** 19672 * A dictionary that holds cached files. 19673 * 19674 * @static 19675 * @type {Object<string,Object>} 19676 */ 19677 files: {}, 19678 /** 19679 * Adds a cache entry with a key to reference the file. If this key already 19680 * holds a file, it is overwritten. 19681 * 19682 * @static 19683 * @param {string} key - The key to reference the cached file. 19684 * @param {Object} file - The file to be cached. 19685 */ 19686 add: function(key, file) { 19687 if (this.enabled === false) return; 19688 if (isBlobURL(key)) return; 19689 this.files[key] = file; 19690 }, 19691 /** 19692 * Gets the cached value for the given key. 19693 * 19694 * @static 19695 * @param {string} key - The key to reference the cached file. 19696 * @return {Object|undefined} The cached file. If the key does not exist `undefined` is returned. 19697 */ 19698 get: function(key) { 19699 if (this.enabled === false) return; 19700 if (isBlobURL(key)) return; 19701 return this.files[key]; 19702 }, 19703 /** 19704 * Removes the cached file associated with the given key. 19705 * 19706 * @static 19707 * @param {string} key - The key to reference the cached file. 19708 */ 19709 remove: function(key) { 19710 delete this.files[key]; 19711 }, 19712 /** 19713 * Remove all values from the cache. 19714 * 19715 * @static 19716 */ 19717 clear: function() { 19718 this.files = {}; 19719 } 19720}; 19721function isBlobURL(key) { 19722 try { 19723 const urlString = key.slice(key.indexOf(":") + 1); 19724 const url = new URL(urlString); 19725 return url.protocol === "blob:"; 19726 } catch (e) { 19727 return false; 19728 } 19729} 19730var LoadingManager = class { 19731 /** 19732 * Constructs a new loading manager. 19733 * 19734 * @param {Function} [onLoad] - Executes when all items have been loaded. 19735 * @param {Function} [onProgress] - Executes when single items have been loaded. 19736 * @param {Function} [onError] - Executes when an error occurs. 19737 */ 19738 constructor(onLoad, onProgress, onError) { 19739 const scope = this; 19740 let isLoading = false; 19741 let itemsLoaded = 0; 19742 let itemsTotal = 0; 19743 let urlModifier = void 0; 19744 const handlers = []; 19745 this.onStart = void 0; 19746 this.onLoad = onLoad; 19747 this.onProgress = onProgress; 19748 this.onError = onError; 19749 this._abortController = null; 19750 this.itemStart = function(url) { 19751 itemsTotal++; 19752 if (isLoading === false) { 19753 if (scope.onStart !== void 0) { 19754 scope.onStart(url, itemsLoaded, itemsTotal); 19755 } 19756 } 19757 isLoading = true; 19758 }; 19759 this.itemEnd = function(url) { 19760 itemsLoaded++; 19761 if (scope.onProgress !== void 0) { 19762 scope.onProgress(url, itemsLoaded, itemsTotal); 19763 } 19764 if (itemsLoaded === itemsTotal) { 19765 isLoading = false; 19766 if (scope.onLoad !== void 0) { 19767 scope.onLoad(); 19768 } 19769 } 19770 }; 19771 this.itemError = function(url) { 19772 if (scope.onError !== void 0) { 19773 scope.onError(url); 19774 } 19775 }; 19776 this.resolveURL = function(url) { 19777 if (urlModifier) { 19778 return urlModifier(url); 19779 } 19780 return url; 19781 }; 19782 this.setURLModifier = function(transform) { 19783 urlModifier = transform; 19784 return this; 19785 }; 19786 this.addHandler = function(regex, loader) { 19787 handlers.push(regex, loader); 19788 return this; 19789 }; 19790 this.removeHandler = function(regex) { 19791 const index = handlers.indexOf(regex); 19792 if (index !== -1) { 19793 handlers.splice(index, 2); 19794 } 19795 return this; 19796 }; 19797 this.getHandler = function(file) { 19798 for (let i = 0, l = handlers.length; i < l; i += 2) { 19799 const regex = handlers[i]; 19800 const loader = handlers[i + 1]; 19801 if (regex.global) regex.lastIndex = 0; 19802 if (regex.test(file)) { 19803 return loader; 19804 } 19805 } 19806 return null; 19807 }; 19808 this.abort = function() { 19809 this.abortController.abort(); 19810 this._abortController = null; 19811 return this; 19812 }; 19813 } 19814 // TODO: Revert this back to a single member variable once this issue has been fixed 19815 // https://github.com/cloudflare/workerd/issues/3657 19816 /** 19817 * Used for aborting ongoing requests in loaders using this manager. 19818 * 19819 * @type {AbortController} 19820 */ 19821 get abortController() { 19822 if (!this._abortController) { 19823 this._abortController = new AbortController(); 19824 } 19825 return this._abortController; 19826 } 19827}; 19828var DefaultLoadingManager = /* @__PURE__ */ new LoadingManager(); 19829var Loader = class { 19830 /** 19831 * Constructs a new loader. 19832 * 19833 * @param {LoadingManager} [manager] - The loading manager. 19834 */ 19835 constructor(manager) { 19836 this.manager = manager !== void 0 ? manager : DefaultLoadingManager; 19837 this.crossOrigin = "anonymous"; 19838 this.withCredentials = false; 19839 this.path = ""; 19840 this.resourcePath = ""; 19841 this.requestHeader = {}; 19842 if (typeof __THREE_DEVTOOLS__ !== "undefined") { 19843 __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe", { detail: this })); 19844 } 19845 } 19846 /** 19847 * This method needs to be implemented by all concrete loaders. It holds the 19848 * logic for loading assets from the backend. 19849 * 19850 * @abstract 19851 * @param {string} url - The path/URL of the file to be loaded. 19852 * @param {Function} onLoad - Executed when the loading process has been finished. 19853 * @param {onProgressCallback} [onProgress] - Executed while the loading is in progress. 19854 * @param {onErrorCallback} [onError] - Executed when errors occur. 19855 */ 19856 load() { 19857 } 19858 /** 19859 * A async version of {@link Loader#load}. 19860 * 19861 * @param {string} url - The path/URL of the file to be loaded. 19862 * @param {onProgressCallback} [onProgress] - Executed while the loading is in progress. 19863 * @return {Promise} A Promise that resolves when the asset has been loaded. 19864 */ 19865 loadAsync(url, onProgress) { 19866 const scope = this; 19867 return new Promise(function(resolve, reject) { 19868 scope.load(url, resolve, onProgress, reject); 19869 }); 19870 } 19871 /** 19872 * This method needs to be implemented by all concrete loaders. It holds the 19873 * logic for parsing the asset into three.js entities. 19874 * 19875 * @abstract 19876 * @param {any} data - The data to parse. 19877 */ 19878 parse() { 19879 } 19880 /** 19881 * Sets the `crossOrigin` String to implement CORS for loading the URL 19882 * from a different domain that allows CORS. 19883 * 19884 * @param {string} crossOrigin - The `crossOrigin` value. 19885 * @return {Loader} A reference to this instance. 19886 */ 19887 setCrossOrigin(crossOrigin) { 19888 this.crossOrigin = crossOrigin; 19889 return this; 19890 } 19891 /** 19892 * Whether the XMLHttpRequest uses credentials such as cookies, authorization 19893 * headers or TLS client certificates, see [XMLHttpRequest.withCredentials](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials). 19894 * 19895 * Note: This setting has no effect if you are loading files locally or from the same domain. 19896 * 19897 * @param {boolean} value - The `withCredentials` value. 19898 * @return {Loader} A reference to this instance. 19899 */ 19900 setWithCredentials(value) { 19901 this.withCredentials = value; 19902 return this; 19903 } 19904 /** 19905 * Sets the base path for the asset. 19906 * 19907 * @param {string} path - The base path. 19908 * @return {Loader} A reference to this instance. 19909 */ 19910 setPath(path) { 19911 this.path = path; 19912 return this; 19913 } 19914 /** 19915 * Sets the base path for dependent resources like textures. 19916 * 19917 * @param {string} resourcePath - The resource path. 19918 * @return {Loader} A reference to this instance. 19919 */ 19920 setResourcePath(resourcePath) { 19921 this.resourcePath = resourcePath; 19922 return this; 19923 } 19924 /** 19925 * Sets the given request header. 19926 * 19927 * @param {Object} requestHeader - A [request header](https://developer.mozilla.org/en-US/docs/Glossary/Request_header) 19928 * for configuring the HTTP request. 19929 * @return {Loader} A reference to this instance. 19930 */ 19931 setRequestHeader(requestHeader) { 19932 this.requestHeader = requestHeader; 19933 return this; 19934 } 19935 /** 19936 * This method can be implemented in loaders for aborting ongoing requests. 19937 * 19938 * @abstract 19939 * @return {Loader} A reference to this instance. 19940 */ 19941 abort() { 19942 return this; 19943 } 19944}; 19945Loader.DEFAULT_MATERIAL_NAME = "__DEFAULT"; 19946var loading = {}; 19947var HttpError = class extends Error { 19948 constructor(message, response) { 19949 super(message); 19950 this.response = response; 19951 } 19952}; 19953var FileLoader = class extends Loader { 19954 /** 19955 * Constructs a new file loader. 19956 * 19957 * @param {LoadingManager} [manager] - The loading manager. 19958 */ 19959 constructor(manager) { 19960 super(manager); 19961 this.mimeType = ""; 19962 this.responseType = ""; 19963 this._abortController = new AbortController(); 19964 } 19965 /** 19966 * Starts loading from the given URL and pass the loaded response to the `onLoad()` callback. 19967 * 19968 * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI. 19969 * @param {function(any)} onLoad - Executed when the loading process has been finished. 19970 * @param {onProgressCallback} [onProgress] - Executed while the loading is in progress. 19971 * @param {onErrorCallback} [onError] - Executed when errors occur. 19972 */ 19973 load(url, onLoad, onProgress, onError) { 19974 if (url === void 0) url = ""; 19975 if (this.path !== void 0) url = this.path + url; 19976 url = this.manager.resolveURL(url); 19977 const cached = Cache.get(`file:${url}`); 19978 if (cached !== void 0) { 19979 this.manager.itemStart(url); 19980 setTimeout(() => { 19981 if (onLoad) onLoad(cached); 19982 this.manager.itemEnd(url); 19983 }, 0); 19984 return; 19985 } 19986 if (loading[url] !== void 0) { 19987 loading[url].push({ 19988 onLoad, 19989 onProgress, 19990 onError 19991 }); 19992 return; 19993 } 19994 loading[url] = []; 19995 loading[url].push({ 19996 onLoad, 19997 onProgress, 19998 onError 19999 }); 20000 const req = new Request(url, { 20001 headers: new Headers(this.requestHeader), 20002 credentials: this.withCredentials ? "include" : "same-origin", 20003 signal: typeof AbortSignal.any === "function" ? AbortSignal.any([this._abortController.signal, this.manager.abortController.signal]) : this._abortController.signal 20004 }); 20005 const mimeType = this.mimeType; 20006 const responseType = this.responseType; 20007 fetch(req).then((response) => { 20008 if (response.status === 200 || response.status === 0) { 20009 if (response.status === 0) { 20010 warn("FileLoader: HTTP Status 0 received."); 20011 } 20012 if (typeof ReadableStream === "undefined" || response.body === void 0 || response.body.getReader === void 0) { 20013 return response; 20014 } 20015 const callbacks = loading[url]; 20016 const reader = response.body.getReader(); 20017 const contentLength = response.headers.get("X-File-Size") || response.headers.get("Content-Length"); 20018 const total = contentLength ? parseInt(contentLength) : 0; 20019 const lengthComputable = total !== 0; 20020 let loaded = 0; 20021 const stream = new ReadableStream({ 20022 start(controller) { 20023 readData(); 20024 function readData() { 20025 reader.read().then(({ done, value }) => { 20026 if (done) { 20027 controller.close(); 20028 } else { 20029 loaded += value.byteLength; 20030 const event = new ProgressEvent("progress", { lengthComputable, loaded, total }); 20031 for (let i = 0, il = callbacks.length; i < il; i++) { 20032 const callback = callbacks[i]; 20033 if (callback.onProgress) callback.onProgress(event); 20034 } 20035 controller.enqueue(value); 20036 readData(); 20037 } 20038 }, (e) => { 20039 controller.error(e); 20040 }); 20041 } 20042 } 20043 }); 20044 return new Response(stream); 20045 } else { 20046 throw new HttpError(`fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`, response); 20047 } 20048 }).then((response) => { 20049 switch (responseType) { 20050 case "arraybuffer": 20051 return response.arrayBuffer(); 20052 case "blob": 20053 return response.blob(); 20054 case "document": 20055 return response.text().then((text) => { 20056 const parser = new DOMParser(); 20057 return parser.parseFromString(text, mimeType); 20058 }); 20059 case "json": 20060 return response.json(); 20061 default: 20062 if (mimeType === "") { 20063 return response.text(); 20064 } else { 20065 const re = /charset="?([^;"\s]*)"?/i; 20066 const exec = re.exec(mimeType); 20067 const label = exec && exec[1] ? exec[1].toLowerCase() : void 0; 20068 const decoder = new TextDecoder(label); 20069 return response.arrayBuffer().then((ab) => decoder.decode(ab)); 20070 } 20071 } 20072 }).then((data) => { 20073 Cache.add(`file:${url}`, data); 20074 const callbacks = loading[url]; 20075 delete loading[url]; 20076 for (let i = 0, il = callbacks.length; i < il; i++) { 20077 const callback = callbacks[i]; 20078 if (callback.onLoad) callback.onLoad(data); 20079 } 20080 }).catch((err) => { 20081 const callbacks = loading[url]; 20082 if (callbacks === void 0) { 20083 this.manager.itemError(url); 20084 throw err; 20085 } 20086 delete loading[url]; 20087 for (let i = 0, il = callbacks.length; i < il; i++) { 20088 const callback = callbacks[i]; 20089 if (callback.onError) callback.onError(err); 20090 } 20091 this.manager.itemError(url); 20092 }).finally(() => { 20093 this.manager.itemEnd(url); 20094 }); 20095 this.manager.itemStart(url); 20096 } 20097 /** 20098 * Sets the expected response type. 20099 * 20100 * @param {('arraybuffer'|'blob'|'document'|'json'|'')} value - The response type. 20101 * @return {FileLoader} A reference to this file loader. 20102 */ 20103 setResponseType(value) { 20104 this.responseType = value; 20105 return this; 20106 } 20107 /** 20108 * Sets the expected mime type of the loaded file. 20109 * 20110 * @param {string} value - The mime type. 20111 * @return {FileLoader} A reference to this file loader. 20112 */ 20113 setMimeType(value) { 20114 this.mimeType = value; 20115 return this; 20116 } 20117 /** 20118 * Aborts ongoing fetch requests. 20119 * 20120 * @return {FileLoader} A reference to this instance. 20121 */ 20122 abort() { 20123 this._abortController.abort(); 20124 this._abortController = new AbortController(); 20125 return this; 20126 } 20127}; 20128var _loading = /* @__PURE__ */ new WeakMap(); 20129var ImageLoader = class extends Loader { 20130 /** 20131 * Constructs a new image loader. 20132 * 20133 * @param {LoadingManager} [manager] - The loading manager. 20134 */ 20135 constructor(manager) { 20136 super(manager); 20137 } 20138 /** 20139 * Starts loading from the given URL and passes the loaded image 20140 * to the `onLoad()` callback. The method also returns a new `Image` object which can 20141 * directly be used for texture creation. If you do it this way, the texture 20142 * may pop up in your scene once the respective loading process is finished. 20143 * 20144 * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI. 20145 * @param {function(Image)} onLoad - Executed when the loading process has been finished. 20146 * @param {onProgressCallback} onProgress - Unsupported in this loader. 20147 * @param {onErrorCallback} onError - Executed when errors occur. 20148 * @return {Image} The image. 20149 */ 20150 load(url, onLoad, onProgress, onError) { 20151 if (this.path !== void 0) url = this.path + url; 20152 url = this.manager.resolveURL(url); 20153 const scope = this; 20154 const cached = Cache.get(`image:${url}`); 20155 if (cached !== void 0) { 20156 if (cached.complete === true) { 20157 scope.manager.itemStart(url); 20158 setTimeout(function() { 20159 if (onLoad) onLoad(cached); 20160 scope.manager.itemEnd(url); 20161 }, 0); 20162 } else { 20163 let arr = _loading.get(cached); 20164 if (arr === void 0) { 20165 arr = []; 20166 _loading.set(cached, arr); 20167 } 20168 arr.push({ onLoad, onError }); 20169 } 20170 return cached; 20171 } 20172 const image = createElementNS("img"); 20173 function onImageLoad() { 20174 removeEventListeners(); 20175 if (onLoad) onLoad(this); 20176 const callbacks = _loading.get(this) || []; 20177 for (let i = 0; i < callbacks.length; i++) { 20178 const callback = callbacks[i]; 20179 if (callback.onLoad) callback.onLoad(this); 20180 } 20181 _loading.delete(this); 20182 scope.manager.itemEnd(url); 20183 } 20184 function onImageError(event) { 20185 removeEventListeners(); 20186 if (onError) onError(event); 20187 Cache.remove(`image:${url}`); 20188 const callbacks = _loading.get(this) || []; 20189 for (let i = 0; i < callbacks.length; i++) { 20190 const callback = callbacks[i]; 20191 if (callback.onError) callback.onError(event); 20192 } 20193 _loading.delete(this); 20194 scope.manager.itemError(url); 20195 scope.manager.itemEnd(url); 20196 } 20197 function removeEventListeners() { 20198 image.removeEventListener("load", onImageLoad, false); 20199 image.removeEventListener("error", onImageError, false); 20200 } 20201 image.addEventListener("load", onImageLoad, false); 20202 image.addEventListener("error", onImageError, false); 20203 if (url.slice(0, 5) !== "data:") { 20204 if (this.crossOrigin !== void 0) image.crossOrigin = this.crossOrigin; 20205 } 20206 Cache.add(`image:${url}`, image); 20207 scope.manager.itemStart(url); 20208 image.src = url; 20209 return image; 20210 } 20211}; 20212var TextureLoader = class extends Loader { 20213 /** 20214 * Constructs a new texture loader. 20215 * 20216 * @param {LoadingManager} [manager] - The loading manager. 20217 */ 20218 constructor(manager) { 20219 super(manager); 20220 } 20221 /** 20222 * Starts loading from the given URL and pass the fully loaded texture 20223 * to the `onLoad()` callback. The method also returns a new texture object which can 20224 * directly be used for material creation. If you do it this way, the texture 20225 * may pop up in your scene once the respective loading process is finished. 20226 * 20227 * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI. 20228 * @param {function(Texture)} onLoad - Executed when the loading process has been finished. 20229 * @param {onProgressCallback} onProgress - Unsupported in this loader. 20230 * @param {onErrorCallback} onError - Executed when errors occur. 20231 * @return {Texture} The texture. 20232 */ 20233 load(url, onLoad, onProgress, onError) { 20234 const texture = new Texture(); 20235 const loader = new ImageLoader(this.manager); 20236 loader.setCrossOrigin(this.crossOrigin); 20237 loader.setPath(this.path); 20238 loader.load(url, function(image) { 20239 texture.image = image; 20240 texture.needsUpdate = true; 20241 if (onLoad !== void 0) { 20242 onLoad(texture); 20243 } 20244 }, onProgress, onError); 20245 return texture; 20246 } 20247}; 20248var Light = class extends Object3D { 20249 /** 20250 * Constructs a new light. 20251 * 20252 * @param {(number|Color|string)} [color=0xffffff] - The light's color. 20253 * @param {number} [intensity=1] - The light's strength/intensity. 20254 */ 20255 constructor(color, intensity = 1) { 20256 super(); 20257 this.isLight = true; 20258 this.type = "Light"; 20259 this.color = new Color(color); 20260 this.intensity = intensity; 20261 } 20262 /** 20263 * Frees the GPU-related resources allocated by this instance. Call this 20264 * method whenever this instance is no longer used in your app. 20265 */ 20266 dispose() { 20267 this.dispatchEvent({ type: "dispose" }); 20268 } 20269 copy(source, recursive) { 20270 super.copy(source, recursive); 20271 this.color.copy(source.color); 20272 this.intensity = source.intensity; 20273 return this; 20274 } 20275 toJSON(meta) { 20276 const data = super.toJSON(meta); 20277 data.object.color = this.color.getHex(); 20278 data.object.intensity = this.intensity; 20279 return data; 20280 } 20281}; 20282var HemisphereLight = class extends Light { 20283 /** 20284 * Constructs a new hemisphere light. 20285 * 20286 * @param {(number|Color|string)} [skyColor=0xffffff] - The light's sky color. 20287 * @param {(number|Color|string)} [groundColor=0xffffff] - The light's ground color. 20288 * @param {number} [intensity=1] - The light's strength/intensity. 20289 */ 20290 constructor(skyColor, groundColor, intensity) { 20291 super(skyColor, intensity); 20292 this.isHemisphereLight = true; 20293 this.type = "HemisphereLight"; 20294 this.position.copy(Object3D.DEFAULT_UP); 20295 this.updateMatrix(); 20296 this.groundColor = new Color(groundColor); 20297 } 20298 copy(source, recursive) { 20299 super.copy(source, recursive); 20300 this.groundColor.copy(source.groundColor); 20301 return this; 20302 } 20303 toJSON(meta) { 20304 const data = super.toJSON(meta); 20305 data.object.groundColor = this.groundColor.getHex(); 20306 return data; 20307 } 20308}; 20309var _projScreenMatrix = /* @__PURE__ */ new Matrix4(); 20310var _lightPositionWorld = /* @__PURE__ */ new Vector3(); 20311var _lookTarget = /* @__PURE__ */ new Vector3(); 20312var LightShadow = class { 20313 /** 20314 * Constructs a new light shadow. 20315 * 20316 * @param {Camera} camera - The light's view of the world. 20317 */ 20318 constructor(camera) { 20319 this.camera = camera; 20320 this.intensity = 1; 20321 this.bias = 0; 20322 this.biasNode = null; 20323 this.normalBias = 0; 20324 this.radius = 1; 20325 this.blurSamples = 8; 20326 this.mapSize = new Vector2(512, 512); 20327 this.mapType = UnsignedByteType; 20328 this.map = null; 20329 this.mapPass = null; 20330 this.matrix = new Matrix4(); 20331 this.autoUpdate = true; 20332 this.needsUpdate = false; 20333 this._frustum = new Frustum(); 20334 this._frameExtents = new Vector2(1, 1); 20335 this._viewportCount = 1; 20336 this._viewports = [ 20337 new Vector4(0, 0, 1, 1) 20338 ]; 20339 } 20340 /** 20341 * Used internally by the renderer to get the number of viewports that need 20342 * to be rendered for this shadow. 20343 * 20344 * @return {number} The viewport count. 20345 */ 20346 getViewportCount() { 20347 return this._viewportCount; 20348 } 20349 /** 20350 * Gets the shadow cameras frustum. Used internally by the renderer to cull objects. 20351 * 20352 * @return {Frustum} The shadow camera frustum. 20353 */ 20354 getFrustum() { 20355 return this._frustum; 20356 } 20357 /** 20358 * Update the matrices for the camera and shadow, used internally by the renderer. 20359 * 20360 * @param {Light} light - The light for which the shadow is being rendered. 20361 */ 20362 updateMatrices(light) { 20363 const shadowCamera = this.camera; 20364 const shadowMatrix = this.matrix; 20365 _lightPositionWorld.setFromMatrixPosition(light.matrixWorld); 20366 shadowCamera.position.copy(_lightPositionWorld); 20367 _lookTarget.setFromMatrixPosition(light.target.matrixWorld); 20368 shadowCamera.lookAt(_lookTarget); 20369 shadowCamera.updateMatrixWorld(); 20370 _projScreenMatrix.multiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse); 20371 this._frustum.setFromProjectionMatrix(_projScreenMatrix, shadowCamera.coordinateSystem, shadowCamera.reversedDepth); 20372 if (shadowCamera.coordinateSystem === WebGPUCoordinateSystem || shadowCamera.reversedDepth) { 20373 shadowMatrix.set( 20374 0.5, 20375 0, 20376 0, 20377 0.5, 20378 0, 20379 0.5, 20380 0, 20381 0.5, 20382 0, 20383 0, 20384 1, 20385 0, 20386 // Identity Z (preserving the correct [0, 1] range from the projection matrix) 20387 0, 20388 0, 20389 0, 20390 1 20391 ); 20392 } else { 20393 shadowMatrix.set( 20394 0.5, 20395 0, 20396 0, 20397 0.5, 20398 0, 20399 0.5, 20400 0, 20401 0.5, 20402 0, 20403 0, 20404 0.5, 20405 0.5, 20406 0, 20407 0, 20408 0, 20409 1 20410 ); 20411 } 20412 shadowMatrix.multiply(_projScreenMatrix); 20413 } 20414 /** 20415 * Returns a viewport definition for the given viewport index. 20416 * 20417 * @param {number} viewportIndex - The viewport index. 20418 * @return {Vector4} The viewport. 20419 */ 20420 getViewport(viewportIndex) { 20421 return this._viewports[viewportIndex]; 20422 } 20423 /** 20424 * Returns the frame extends. 20425 * 20426 * @return {Vector2} The frame extends. 20427 */ 20428 getFrameExtents() { 20429 return this._frameExtents; 20430 } 20431 /** 20432 * Frees the GPU-related resources allocated by this instance. Call this 20433 * method whenever this instance is no longer used in your app. 20434 */ 20435 dispose() { 20436 if (this.map) { 20437 this.map.dispose(); 20438 } 20439 if (this.mapPass) { 20440 this.mapPass.dispose(); 20441 } 20442 } 20443 /** 20444 * Copies the values of the given light shadow instance to this instance. 20445 * 20446 * @param {LightShadow} source - The light shadow to copy. 20447 * @return {LightShadow} A reference to this light shadow instance. 20448 */ 20449 copy(source) { 20450 this.camera = source.camera.clone(); 20451 this.intensity = source.intensity; 20452 this.bias = source.bias; 20453 this.radius = source.radius; 20454 this.autoUpdate = source.autoUpdate; 20455 this.needsUpdate = source.needsUpdate; 20456 this.normalBias = source.normalBias; 20457 this.blurSamples = source.blurSamples; 20458 this.mapSize.copy(source.mapSize); 20459 this.biasNode = source.biasNode; 20460 return this; 20461 } 20462 /** 20463 * Returns a new light shadow instance with copied values from this instance. 20464 * 20465 * @return {LightShadow} A clone of this instance. 20466 */ 20467 clone() { 20468 return new this.constructor().copy(this); 20469 } 20470 /** 20471 * Serializes the light shadow into JSON. 20472 * 20473 * @return {Object} A JSON object representing the serialized light shadow. 20474 * @see {@link ObjectLoader#parse} 20475 */ 20476 toJSON() { 20477 const object = {}; 20478 if (this.intensity !== 1) object.intensity = this.intensity; 20479 if (this.bias !== 0) object.bias = this.bias; 20480 if (this.normalBias !== 0) object.normalBias = this.normalBias; 20481 if (this.radius !== 1) object.radius = this.radius; 20482 if (this.mapSize.x !== 512 || this.mapSize.y !== 512) object.mapSize = this.mapSize.toArray(); 20483 object.camera = this.camera.toJSON(false).object; 20484 delete object.camera.matrix; 20485 return object; 20486 } 20487}; 20488var _position$2 = /* @__PURE__ */ new Vector3(); 20489var _quaternion$2 = /* @__PURE__ */ new Quaternion(); 20490var _scale$2 = /* @__PURE__ */ new Vector3(); 20491var Camera = class extends Object3D { 20492 /** 20493 * Constructs a new camera. 20494 */ 20495 constructor() { 20496 super(); 20497 this.isCamera = true; 20498 this.type = "Camera"; 20499 this.matrixWorldInverse = new Matrix4(); 20500 this.projectionMatrix = new Matrix4(); 20501 this.projectionMatrixInverse = new Matrix4(); 20502 this.coordinateSystem = WebGLCoordinateSystem; 20503 this._reversedDepth = false; 20504 } 20505 /** 20506 * The flag that indicates whether the camera uses a reversed depth buffer. 20507 * 20508 * @type {boolean} 20509 * @default false 20510 */ 20511 get reversedDepth() { 20512 return this._reversedDepth; 20513 } 20514 copy(source, recursive) { 20515 super.copy(source, recursive); 20516 this.matrixWorldInverse.copy(source.matrixWorldInverse); 20517 this.projectionMatrix.copy(source.projectionMatrix); 20518 this.projectionMatrixInverse.copy(source.projectionMatrixInverse); 20519 this.coordinateSystem = source.coordinateSystem; 20520 return this; 20521 } 20522 /** 20523 * Returns a vector representing the ("look") direction of the 3D object in world space. 20524 * 20525 * This method is overwritten since cameras have a different forward vector compared to other 20526 * 3D objects. A camera looks down its local, negative z-axis by default. 20527 * 20528 * @param {Vector3} target - The target vector the result is stored to. 20529 * @return {Vector3} The 3D object's direction in world space. 20530 */ 20531 getWorldDirection(target) { 20532 return super.getWorldDirection(target).negate(); 20533 } 20534 updateMatrixWorld(force) { 20535 super.updateMatrixWorld(force); 20536 this.matrixWorld.decompose(_position$2, _quaternion$2, _scale$2); 20537 if (_scale$2.x === 1 && _scale$2.y === 1 && _scale$2.z === 1) { 20538 this.matrixWorldInverse.copy(this.matrixWorld).invert(); 20539 } else { 20540 this.matrixWorldInverse.compose(_position$2, _quaternion$2, _scale$2.set(1, 1, 1)).invert(); 20541 } 20542 } 20543 updateWorldMatrix(updateParents, updateChildren) { 20544 super.updateWorldMatrix(updateParents, updateChildren); 20545 this.matrixWorld.decompose(_position$2, _quaternion$2, _scale$2); 20546 if (_scale$2.x === 1 && _scale$2.y === 1 && _scale$2.z === 1) { 20547 this.matrixWorldInverse.copy(this.matrixWorld).invert(); 20548 } else { 20549 this.matrixWorldInverse.compose(_position$2, _quaternion$2, _scale$2.set(1, 1, 1)).invert(); 20550 } 20551 } 20552 clone() { 20553 return new this.constructor().copy(this); 20554 } 20555}; 20556var _v3$1 = /* @__PURE__ */ new Vector3(); 20557var _minTarget = /* @__PURE__ */ new Vector2(); 20558var _maxTarget = /* @__PURE__ */ new Vector2(); 20559var PerspectiveCamera = class extends Camera { 20560 /** 20561 * Constructs a new perspective camera. 20562 * 20563 * @param {number} [fov=50] - The vertical field of view. 20564 * @param {number} [aspect=1] - The aspect ratio. 20565 * @param {number} [near=0.1] - The camera's near plane. 20566 * @param {number} [far=2000] - The camera's far plane. 20567 */ 20568 constructor(fov2 = 50, aspect2 = 1, near = 0.1, far = 2e3) { 20569 super(); 20570 this.isPerspectiveCamera = true; 20571 this.type = "PerspectiveCamera"; 20572 this.fov = fov2; 20573 this.zoom = 1; 20574 this.near = near; 20575 this.far = far; 20576 this.focus = 10; 20577 this.aspect = aspect2; 20578 this.view = null; 20579 this.filmGauge = 35; 20580 this.filmOffset = 0; 20581 this.updateProjectionMatrix(); 20582 } 20583 copy(source, recursive) { 20584 super.copy(source, recursive); 20585 this.fov = source.fov; 20586 this.zoom = source.zoom; 20587 this.near = source.near; 20588 this.far = source.far; 20589 this.focus = source.focus; 20590 this.aspect = source.aspect; 20591 this.view = source.view === null ? null : Object.assign({}, source.view); 20592 this.filmGauge = source.filmGauge; 20593 this.filmOffset = source.filmOffset; 20594 return this; 20595 } 20596 /** 20597 * Sets the FOV by focal length in respect to the current {@link PerspectiveCamera#filmGauge}. 20598 * 20599 * The default film gauge is 35, so that the focal length can be specified for 20600 * a 35mm (full frame) camera. 20601 * 20602 * @param {number} focalLength - Values for focal length and film gauge must have the same unit. 20603 */ 20604 setFocalLength(focalLength) { 20605 const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; 20606 this.fov = RAD2DEG * 2 * Math.atan(vExtentSlope); 20607 this.updateProjectionMatrix(); 20608 } 20609 /** 20610 * Returns the focal length from the current {@link PerspectiveCamera#fov} and 20611 * {@link PerspectiveCamera#filmGauge}. 20612 * 20613 * @return {number} The computed focal length. 20614 */ 20615 getFocalLength() { 20616 const vExtentSlope = Math.tan(DEG2RAD * 0.5 * this.fov); 20617 return 0.5 * this.getFilmHeight() / vExtentSlope; 20618 } 20619 /** 20620 * Returns the current vertical field of view angle in degrees considering {@link PerspectiveCamera#zoom}. 20621 * 20622 * @return {number} The effective FOV. 20623 */ 20624 getEffectiveFOV() { 20625 return RAD2DEG * 2 * Math.atan( 20626 Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom 20627 ); 20628 } 20629 /** 20630 * Returns the width of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or 20631 * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}. 20632 * 20633 * @return {number} The film width. 20634 */ 20635 getFilmWidth() { 20636 return this.filmGauge * Math.min(this.aspect, 1); 20637 } 20638 /** 20639 * Returns the height of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or 20640 * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}. 20641 * 20642 * @return {number} The film width. 20643 */ 20644 getFilmHeight() { 20645 return this.filmGauge / Math.max(this.aspect, 1); 20646 } 20647 /** 20648 * Computes the 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction. 20649 * Sets `minTarget` and `maxTarget` to the coordinates of the lower-left and upper-right corners of the view rectangle. 20650 * 20651 * @param {number} distance - The viewing distance. 20652 * @param {Vector2} minTarget - The lower-left corner of the view rectangle is written into this vector. 20653 * @param {Vector2} maxTarget - The upper-right corner of the view rectangle is written into this vector. 20654 */ 20655 getViewBounds(distance, minTarget, maxTarget) { 20656 _v3$1.set(-1, -1, 0.5).applyMatrix4(this.projectionMatrixInverse); 20657 minTarget.set(_v3$1.x, _v3$1.y).multiplyScalar(-distance / _v3$1.z); 20658 _v3$1.set(1, 1, 0.5).applyMatrix4(this.projectionMatrixInverse); 20659 maxTarget.set(_v3$1.x, _v3$1.y).multiplyScalar(-distance / _v3$1.z); 20660 } 20661 /** 20662 * Computes the width and height of the camera's viewable rectangle at a given distance along the viewing direction. 20663 * 20664 * @param {number} distance - The viewing distance. 20665 * @param {Vector2} target - The target vector that is used to store result where x is width and y is height. 20666 * @returns {Vector2} The view size. 20667 */ 20668 getViewSize(distance, target) { 20669 this.getViewBounds(distance, _minTarget, _maxTarget); 20670 return target.subVectors(_maxTarget, _minTarget); 20671 } 20672 /** 20673 * Sets an offset in a larger frustum. This is useful for multi-window or 20674 * multi-monitor/multi-machine setups. 20675 * 20676 * For example, if you have 3x2 monitors and each monitor is 1920x1080 and 20677 * the monitors are in grid like this 20678 *``` 20679 * +---+---+---+ 20680 * | A | B | C | 20681 * +---+---+---+ 20682 * | D | E | F | 20683 * +---+---+---+ 20684 *``` 20685 * then for each monitor you would call it like this: 20686 *```js 20687 * const w = 1920; 20688 * const h = 1080; 20689 * const fullWidth = w * 3; 20690 * const fullHeight = h * 2; 20691 * 20692 * // --A-- 20693 * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); 20694 * // --B-- 20695 * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); 20696 * // --C-- 20697 * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); 20698 * // --D-- 20699 * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); 20700 * // --E-- 20701 * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); 20702 * // --F-- 20703 * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); 20704 * ``` 20705 * 20706 * Note there is no reason monitors have to be the same size or in a grid. 20707 * 20708 * @param {number} fullWidth - The full width of multiview setup. 20709 * @param {number} fullHeight - The full height of multiview setup. 20710 * @param {number} x - The horizontal offset of the subcamera. 20711 * @param {number} y - The vertical offset of the subcamera. 20712 * @param {number} width - The width of subcamera. 20713 * @param {number} height - The height of subcamera. 20714 */ 20715 setViewOffset(fullWidth, fullHeight, x, y, width, height) { 20716 this.aspect = fullWidth / fullHeight; 20717 if (this.view === null) { 20718 this.view = { 20719 enabled: true, 20720 fullWidth: 1, 20721 fullHeight: 1, 20722 offsetX: 0, 20723 offsetY: 0, 20724 width: 1, 20725 height: 1 20726 }; 20727 } 20728 this.view.enabled = true; 20729 this.view.fullWidth = fullWidth; 20730 this.view.fullHeight = fullHeight; 20731 this.view.offsetX = x; 20732 this.view.offsetY = y; 20733 this.view.width = width; 20734 this.view.height = height; 20735 this.updateProjectionMatrix(); 20736 } 20737 /** 20738 * Removes the view offset from the projection matrix. 20739 */ 20740 clearViewOffset() { 20741 if (this.view !== null) { 20742 this.view.enabled = false; 20743 } 20744 this.updateProjectionMatrix(); 20745 } 20746 /** 20747 * Updates the camera's projection matrix. Must be called after any change of 20748 * camera properties. 20749 */ 20750 updateProjectionMatrix() { 20751 const near = this.near; 20752 let top = near * Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom; 20753 let height = 2 * top; 20754 let width = this.aspect * height; 20755 let left = -0.5 * width; 20756 const view = this.view; 20757 if (this.view !== null && this.view.enabled) { 20758 const fullWidth = view.fullWidth, fullHeight = view.fullHeight; 20759 left += view.offsetX * width / fullWidth; 20760 top -= view.offsetY * height / fullHeight; 20761 width *= view.width / fullWidth; 20762 height *= view.height / fullHeight; 20763 } 20764 const skew = this.filmOffset; 20765 if (skew !== 0) left += near * skew / this.getFilmWidth(); 20766 this.projectionMatrix.makePerspective(left, left + width, top, top - height, near, this.far, this.coordinateSystem, this.reversedDepth); 20767 this.projectionMatrixInverse.copy(this.projectionMatrix).invert(); 20768 } 20769 toJSON(meta) { 20770 const data = super.toJSON(meta); 20771 data.object.fov = this.fov; 20772 data.object.zoom = this.zoom; 20773 data.object.near = this.near; 20774 data.object.far = this.far; 20775 data.object.focus = this.focus; 20776 data.object.aspect = this.aspect; 20777 if (this.view !== null) data.object.view = Object.assign({}, this.view); 20778 data.object.filmGauge = this.filmGauge; 20779 data.object.filmOffset = this.filmOffset; 20780 return data; 20781 } 20782}; 20783var SpotLightShadow = class extends LightShadow { 20784 /** 20785 * Constructs a new spot light shadow. 20786 */ 20787 constructor() { 20788 super(new PerspectiveCamera(50, 1, 0.5, 500)); 20789 this.isSpotLightShadow = true; 20790 this.focus = 1; 20791 this.aspect = 1; 20792 } 20793 updateMatrices(light) { 20794 const camera = this.camera; 20795 const fov2 = RAD2DEG * 2 * light.angle * this.focus; 20796 const aspect2 = this.mapSize.width / this.mapSize.height * this.aspect; 20797 const far = light.distance || camera.far; 20798 if (fov2 !== camera.fov || aspect2 !== camera.aspect || far !== camera.far) { 20799 camera.fov = fov2; 20800 camera.aspect = aspect2; 20801 camera.far = far; 20802 camera.updateProjectionMatrix(); 20803 } 20804 super.updateMatrices(light); 20805 } 20806 copy(source) { 20807 super.copy(source); 20808 this.focus = source.focus; 20809 return this; 20810 } 20811}; 20812var SpotLight = class extends Light { 20813 /** 20814 * Constructs a new spot light. 20815 * 20816 * @param {(number|Color|string)} [color=0xffffff] - The light's color. 20817 * @param {number} [intensity=1] - The light's strength/intensity measured in candela (cd). 20818 * @param {number} [distance=0] - Maximum range of the light. `0` means no limit. 20819 * @param {number} [angle=Math.PI/3] - Maximum angle of light dispersion from its direction whose upper bound is `Math.PI/2`. 20820 * @param {number} [penumbra=0] - Percent of the spotlight cone that is attenuated due to penumbra. Value range is `[0,1]`. 20821 * @param {number} [decay=2] - The amount the light dims along the distance of the light. 20822 */ 20823 constructor(color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 2) { 20824 super(color, intensity); 20825 this.isSpotLight = true; 20826 this.type = "SpotLight"; 20827 this.position.copy(Object3D.DEFAULT_UP); 20828 this.updateMatrix(); 20829 this.target = new Object3D(); 20830 this.distance = distance; 20831 this.angle = angle; 20832 this.penumbra = penumbra; 20833 this.decay = decay; 20834 this.map = null; 20835 this.shadow = new SpotLightShadow(); 20836 } 20837 /** 20838 * The light's power. Power is the luminous power of the light measured in lumens (lm). 20839 * Changing the power will also change the light's intensity. 20840 * 20841 * @type {number} 20842 */ 20843 get power() { 20844 return this.intensity * Math.PI; 20845 } 20846 set power(power) { 20847 this.intensity = power / Math.PI; 20848 } 20849 dispose() { 20850 super.dispose(); 20851 this.shadow.dispose(); 20852 } 20853 copy(source, recursive) { 20854 super.copy(source, recursive); 20855 this.distance = source.distance; 20856 this.angle = source.angle; 20857 this.penumbra = source.penumbra; 20858 this.decay = source.decay; 20859 this.target = source.target.clone(); 20860 this.map = source.map; 20861 this.shadow = source.shadow.clone(); 20862 return this; 20863 } 20864 toJSON(meta) { 20865 const data = super.toJSON(meta); 20866 data.object.distance = this.distance; 20867 data.object.angle = this.angle; 20868 data.object.decay = this.decay; 20869 data.object.penumbra = this.penumbra; 20870 data.object.target = this.target.uuid; 20871 if (this.map && this.map.isTexture) data.object.map = this.map.toJSON(meta).uuid; 20872 data.object.shadow = this.shadow.toJSON(); 20873 return data; 20874 } 20875}; 20876var PointLightShadow = class extends LightShadow { 20877 /** 20878 * Constructs a new point light shadow. 20879 */ 20880 constructor() { 20881 super(new PerspectiveCamera(90, 1, 0.5, 500)); 20882 this.isPointLightShadow = true; 20883 } 20884}; 20885var PointLight = class extends Light { 20886 /** 20887 * Constructs a new point light. 20888 * 20889 * @param {(number|Color|string)} [color=0xffffff] - The light's color. 20890 * @param {number} [intensity=1] - The light's strength/intensity measured in candela (cd). 20891 * @param {number} [distance=0] - Maximum range of the light. `0` means no limit. 20892 * @param {number} [decay=2] - The amount the light dims along the distance of the light. 20893 */ 20894 constructor(color, intensity, distance = 0, decay = 2) { 20895 super(color, intensity); 20896 this.isPointLight = true; 20897 this.type = "PointLight"; 20898 this.distance = distance; 20899 this.decay = decay; 20900 this.shadow = new PointLightShadow(); 20901 } 20902 /** 20903 * The light's power. Power is the luminous power of the light measured in lumens (lm). 20904 * Changing the power will also change the light's intensity. 20905 * 20906 * @type {number} 20907 */ 20908 get power() { 20909 return this.intensity * 4 * Math.PI; 20910 } 20911 set power(power) { 20912 this.intensity = power / (4 * Math.PI); 20913 } 20914 dispose() { 20915 super.dispose(); 20916 this.shadow.dispose(); 20917 } 20918 copy(source, recursive) { 20919 super.copy(source, recursive); 20920 this.distance = source.distance; 20921 this.decay = source.decay; 20922 this.shadow = source.shadow.clone(); 20923 return this; 20924 } 20925 toJSON(meta) { 20926 const data = super.toJSON(meta); 20927 data.object.distance = this.distance; 20928 data.object.decay = this.decay; 20929 data.object.shadow = this.shadow.toJSON(); 20930 return data; 20931 } 20932}; 20933var OrthographicCamera = class extends Camera { 20934 /** 20935 * Constructs a new orthographic camera. 20936 * 20937 * @param {number} [left=-1] - The left plane of the camera's frustum. 20938 * @param {number} [right=1] - The right plane of the camera's frustum. 20939 * @param {number} [top=1] - The top plane of the camera's frustum. 20940 * @param {number} [bottom=-1] - The bottom plane of the camera's frustum. 20941 * @param {number} [near=0.1] - The camera's near plane. 20942 * @param {number} [far=2000] - The camera's far plane. 20943 */ 20944 constructor(left = -1, right = 1, top = 1, bottom = -1, near = 0.1, far = 2e3) { 20945 super(); 20946 this.isOrthographicCamera = true; 20947 this.type = "OrthographicCamera"; 20948 this.zoom = 1; 20949 this.view = null; 20950 this.left = left; 20951 this.right = right; 20952 this.top = top; 20953 this.bottom = bottom; 20954 this.near = near; 20955 this.far = far; 20956 this.updateProjectionMatrix(); 20957 } 20958 copy(source, recursive) { 20959 super.copy(source, recursive); 20960 this.left = source.left; 20961 this.right = source.right; 20962 this.top = source.top; 20963 this.bottom = source.bottom; 20964 this.near = source.near; 20965 this.far = source.far; 20966 this.zoom = source.zoom; 20967 this.view = source.view === null ? null : Object.assign({}, source.view); 20968 return this; 20969 } 20970 /** 20971 * Sets an offset in a larger frustum. This is useful for multi-window or 20972 * multi-monitor/multi-machine setups. 20973 * 20974 * @param {number} fullWidth - The full width of multiview setup. 20975 * @param {number} fullHeight - The full height of multiview setup. 20976 * @param {number} x - The horizontal offset of the subcamera. 20977 * @param {number} y - The vertical offset of the subcamera. 20978 * @param {number} width - The width of subcamera. 20979 * @param {number} height - The height of subcamera. 20980 * @see {@link PerspectiveCamera#setViewOffset} 20981 */ 20982 setViewOffset(fullWidth, fullHeight, x, y, width, height) { 20983 if (this.view === null) { 20984 this.view = { 20985 enabled: true, 20986 fullWidth: 1, 20987 fullHeight: 1, 20988 offsetX: 0, 20989 offsetY: 0, 20990 width: 1, 20991 height: 1 20992 }; 20993 } 20994 this.view.enabled = true; 20995 this.view.fullWidth = fullWidth; 20996 this.view.fullHeight = fullHeight; 20997 this.view.offsetX = x; 20998 this.view.offsetY = y; 20999 this.view.width = width; 21000 this.view.height = height; 21001 this.updateProjectionMatrix(); 21002 } 21003 /** 21004 * Removes the view offset from the projection matrix. 21005 */ 21006 clearViewOffset() { 21007 if (this.view !== null) { 21008 this.view.enabled = false; 21009 } 21010 this.updateProjectionMatrix(); 21011 } 21012 /** 21013 * Updates the camera's projection matrix. Must be called after any change of 21014 * camera properties. 21015 */ 21016 updateProjectionMatrix() { 21017 const dx = (this.right - this.left) / (2 * this.zoom); 21018 const dy = (this.top - this.bottom) / (2 * this.zoom); 21019 const cx = (this.right + this.left) / 2; 21020 const cy = (this.top + this.bottom) / 2; 21021 let left = cx - dx; 21022 let right = cx + dx; 21023 let top = cy + dy; 21024 let bottom = cy - dy; 21025 if (this.view !== null && this.view.enabled) { 21026 const scaleW = (this.right - this.left) / this.view.fullWidth / this.zoom; 21027 const scaleH = (this.top - this.bottom) / this.view.fullHeight / this.zoom; 21028 left += scaleW * this.view.offsetX; 21029 right = left + scaleW * this.view.width; 21030 top -= scaleH * this.view.offsetY; 21031 bottom = top - scaleH * this.view.height; 21032 } 21033 this.projectionMatrix.makeOrthographic(left, right, top, bottom, this.near, this.far, this.coordinateSystem, this.reversedDepth); 21034 this.projectionMatrixInverse.copy(this.projectionMatrix).invert(); 21035 } 21036 toJSON(meta) { 21037 const data = super.toJSON(meta); 21038 data.object.zoom = this.zoom; 21039 data.object.left = this.left; 21040 data.object.right = this.right; 21041 data.object.top = this.top; 21042 data.object.bottom = this.bottom; 21043 data.object.near = this.near; 21044 data.object.far = this.far; 21045 if (this.view !== null) data.object.view = Object.assign({}, this.view); 21046 return data; 21047 } 21048}; 21049var DirectionalLightShadow = class extends LightShadow { 21050 /** 21051 * Constructs a new directional light shadow. 21052 */ 21053 constructor() { 21054 super(new OrthographicCamera(-5, 5, 5, -5, 0.5, 500)); 21055 this.isDirectionalLightShadow = true; 21056 } 21057}; 21058var DirectionalLight = class extends Light { 21059 /** 21060 * Constructs a new directional light. 21061 * 21062 * @param {(number|Color|string)} [color=0xffffff] - The light's color. 21063 * @param {number} [intensity=1] - The light's strength/intensity. 21064 */ 21065 constructor(color, intensity) { 21066 super(color, intensity); 21067 this.isDirectionalLight = true; 21068 this.type = "DirectionalLight"; 21069 this.position.copy(Object3D.DEFAULT_UP); 21070 this.updateMatrix(); 21071 this.target = new Object3D(); 21072 this.shadow = new DirectionalLightShadow(); 21073 } 21074 dispose() { 21075 super.dispose(); 21076 this.shadow.dispose(); 21077 } 21078 copy(source) { 21079 super.copy(source); 21080 this.target = source.target.clone(); 21081 this.shadow = source.shadow.clone(); 21082 return this; 21083 } 21084 toJSON(meta) { 21085 const data = super.toJSON(meta); 21086 data.object.shadow = this.shadow.toJSON(); 21087 data.object.target = this.target.uuid; 21088 return data; 21089 } 21090}; 21091var AmbientLight = class extends Light { 21092 /** 21093 * Constructs a new ambient light. 21094 * 21095 * @param {(number|Color|string)} [color=0xffffff] - The light's color. 21096 * @param {number} [intensity=1] - The light's strength/intensity. 21097 */ 21098 constructor(color, intensity) { 21099 super(color, intensity); 21100 this.isAmbientLight = true; 21101 this.type = "AmbientLight"; 21102 } 21103}; 21104var RectAreaLight = class extends Light { 21105 /** 21106 * Constructs a new area light. 21107 * 21108 * @param {(number|Color|string)} [color=0xffffff] - The light's color. 21109 * @param {number} [intensity=1] - The light's strength/intensity. 21110 * @param {number} [width=10] - The width of the light. 21111 * @param {number} [height=10] - The height of the light. 21112 */ 21113 constructor(color, intensity, width = 10, height = 10) { 21114 super(color, intensity); 21115 this.isRectAreaLight = true; 21116 this.type = "RectAreaLight"; 21117 this.width = width; 21118 this.height = height; 21119 } 21120 /** 21121 * The light's power. Power is the luminous power of the light measured in lumens (lm). 21122 * Changing the power will also change the light's intensity. 21123 * 21124 * @type {number} 21125 */ 21126 get power() { 21127 return this.intensity * this.width * this.height * Math.PI; 21128 } 21129 set power(power) { 21130 this.intensity = power / (this.width * this.height * Math.PI); 21131 } 21132 copy(source) { 21133 super.copy(source); 21134 this.width = source.width; 21135 this.height = source.height; 21136 return this; 21137 } 21138 toJSON(meta) { 21139 const data = super.toJSON(meta); 21140 data.object.width = this.width; 21141 data.object.height = this.height; 21142 return data; 21143 } 21144}; 21145var SphericalHarmonics3 = class { 21146 /** 21147 * Constructs a new spherical harmonics. 21148 */ 21149 constructor() { 21150 this.isSphericalHarmonics3 = true; 21151 this.coefficients = []; 21152 for (let i = 0; i < 9; i++) { 21153 this.coefficients.push(new Vector3()); 21154 } 21155 } 21156 /** 21157 * Sets the given SH coefficients to this instance by copying 21158 * the values. 21159 * 21160 * @param {Array<Vector3>} coefficients - The SH coefficients. 21161 * @return {SphericalHarmonics3} A reference to this spherical harmonics. 21162 */ 21163 set(coefficients) { 21164 for (let i = 0; i < 9; i++) { 21165 this.coefficients[i].copy(coefficients[i]); 21166 } 21167 return this; 21168 } 21169 /** 21170 * Sets all SH coefficients to `0`. 21171 * 21172 * @return {SphericalHarmonics3} A reference to this spherical harmonics. 21173 */ 21174 zero() { 21175 for (let i = 0; i < 9; i++) { 21176 this.coefficients[i].set(0, 0, 0); 21177 } 21178 return this; 21179 } 21180 /** 21181 * Returns the radiance in the direction of the given normal. 21182 * 21183 * @param {Vector3} normal - The normal vector (assumed to be unit length) 21184 * @param {Vector3} target - The target vector that is used to store the method's result. 21185 * @return {Vector3} The radiance. 21186 */ 21187 getAt(normal, target) { 21188 const x = normal.x, y = normal.y, z = normal.z; 21189 const coeff = this.coefficients; 21190 target.copy(coeff[0]).multiplyScalar(0.282095); 21191 target.addScaledVector(coeff[1], 0.488603 * y); 21192 target.addScaledVector(coeff[2], 0.488603 * z); 21193 target.addScaledVector(coeff[3], 0.488603 * x); 21194 target.addScaledVector(coeff[4], 1.092548 * (x * y)); 21195 target.addScaledVector(coeff[5], 1.092548 * (y * z)); 21196 target.addScaledVector(coeff[6], 0.315392 * (3 * z * z - 1)); 21197 target.addScaledVector(coeff[7], 1.092548 * (x * z)); 21198 target.addScaledVector(coeff[8], 0.546274 * (x * x - y * y)); 21199 return target; 21200 } 21201 /** 21202 * Returns the irradiance (radiance convolved with cosine lobe) in the 21203 * direction of the given normal. 21204 * 21205 * @param {Vector3} normal - The normal vector (assumed to be unit length) 21206 * @param {Vector3} target - The target vector that is used to store the method's result. 21207 * @return {Vector3} The irradiance. 21208 */ 21209 getIrradianceAt(normal, target) { 21210 const x = normal.x, y = normal.y, z = normal.z; 21211 const coeff = this.coefficients; 21212 target.copy(coeff[0]).multiplyScalar(0.886227); 21213 target.addScaledVector(coeff[1], 2 * 0.511664 * y); 21214 target.addScaledVector(coeff[2], 2 * 0.511664 * z); 21215 target.addScaledVector(coeff[3], 2 * 0.511664 * x); 21216 target.addScaledVector(coeff[4], 2 * 0.429043 * x * y); 21217 target.addScaledVector(coeff[5], 2 * 0.429043 * y * z); 21218 target.addScaledVector(coeff[6], 0.743125 * z * z - 0.247708); 21219 target.addScaledVector(coeff[7], 2 * 0.429043 * x * z); 21220 target.addScaledVector(coeff[8], 0.429043 * (x * x - y * y)); 21221 return target; 21222 } 21223 /** 21224 * Adds the given SH to this instance. 21225 * 21226 * @param {SphericalHarmonics3} sh - The SH to add. 21227 * @return {SphericalHarmonics3} A reference to this spherical harmonics. 21228 */ 21229 add(sh) { 21230 for (let i = 0; i < 9; i++) { 21231 this.coefficients[i].add(sh.coefficients[i]); 21232 } 21233 return this; 21234 } 21235 /** 21236 * A convenience method for performing {@link SphericalHarmonics3#add} and 21237 * {@link SphericalHarmonics3#scale} at once. 21238 * 21239 * @param {SphericalHarmonics3} sh - The SH to add. 21240 * @param {number} s - The scale factor. 21241 * @return {SphericalHarmonics3} A reference to this spherical harmonics. 21242 */ 21243 addScaledSH(sh, s) { 21244 for (let i = 0; i < 9; i++) { 21245 this.coefficients[i].addScaledVector(sh.coefficients[i], s); 21246 } 21247 return this; 21248 } 21249 /** 21250 * Scales this SH by the given scale factor. 21251 * 21252 * @param {number} s - The scale factor. 21253 * @return {SphericalHarmonics3} A reference to this spherical harmonics. 21254 */ 21255 scale(s) { 21256 for (let i = 0; i < 9; i++) { 21257 this.coefficients[i].multiplyScalar(s); 21258 } 21259 return this; 21260 } 21261 /** 21262 * Linear interpolates between the given SH and this instance by the given 21263 * alpha factor. 21264 * 21265 * @param {SphericalHarmonics3} sh - The SH to interpolate with. 21266 * @param {number} alpha - The alpha factor. 21267 * @return {SphericalHarmonics3} A reference to this spherical harmonics. 21268 */ 21269 lerp(sh, alpha) { 21270 for (let i = 0; i < 9; i++) { 21271 this.coefficients[i].lerp(sh.coefficients[i], alpha); 21272 } 21273 return this; 21274 } 21275 /** 21276 * Returns `true` if this spherical harmonics is equal with the given one. 21277 * 21278 * @param {SphericalHarmonics3} sh - The spherical harmonics to test for equality. 21279 * @return {boolean} Whether this spherical harmonics is equal with the given one. 21280 */ 21281 equals(sh) { 21282 for (let i = 0; i < 9; i++) { 21283 if (!this.coefficients[i].equals(sh.coefficients[i])) { 21284 return false; 21285 } 21286 } 21287 return true; 21288 } 21289 /** 21290 * Copies the values of the given spherical harmonics to this instance. 21291 * 21292 * @param {SphericalHarmonics3} sh - The spherical harmonics to copy. 21293 * @return {SphericalHarmonics3} A reference to this spherical harmonics. 21294 */ 21295 copy(sh) { 21296 return this.set(sh.coefficients); 21297 } 21298 /** 21299 * Returns a new spherical harmonics with copied values from this instance. 21300 * 21301 * @return {SphericalHarmonics3} A clone of this instance. 21302 */ 21303 clone() { 21304 return new this.constructor().copy(this); 21305 } 21306 /** 21307 * Sets the SH coefficients of this instance from the given array. 21308 * 21309 * @param {Array<number>} array - An array holding the SH coefficients. 21310 * @param {number} [offset=0] - The array offset where to start copying. 21311 * @return {SphericalHarmonics3} A clone of this instance. 21312 */ 21313 fromArray(array, offset = 0) { 21314 const coefficients = this.coefficients; 21315 for (let i = 0; i < 9; i++) { 21316 coefficients[i].fromArray(array, offset + i * 3); 21317 } 21318 return this; 21319 } 21320 /** 21321 * Returns an array with the SH coefficients, or copies them into the provided 21322 * array. The coefficients are represented as numbers. 21323 * 21324 * @param {Array<number>} [array=[]] - The target array. 21325 * @param {number} [offset=0] - The array offset where to start copying. 21326 * @return {Array<number>} An array with flat SH coefficients. 21327 */ 21328 toArray(array = [], offset = 0) { 21329 const coefficients = this.coefficients; 21330 for (let i = 0; i < 9; i++) { 21331 coefficients[i].toArray(array, offset + i * 3); 21332 } 21333 return array; 21334 } 21335 /** 21336 * Computes the SH basis for the given normal vector. 21337 * 21338 * @param {Vector3} normal - The normal. 21339 * @param {Array<number>} shBasis - The target array holding the SH basis. 21340 */ 21341 static getBasisAt(normal, shBasis) { 21342 const x = normal.x, y = normal.y, z = normal.z; 21343 shBasis[0] = 0.282095; 21344 shBasis[1] = 0.488603 * y; 21345 shBasis[2] = 0.488603 * z; 21346 shBasis[3] = 0.488603 * x; 21347 shBasis[4] = 1.092548 * x * y; 21348 shBasis[5] = 1.092548 * y * z; 21349 shBasis[6] = 0.315392 * (3 * z * z - 1); 21350 shBasis[7] = 1.092548 * x * z; 21351 shBasis[8] = 0.546274 * (x * x - y * y); 21352 } 21353}; 21354var LightProbe = class extends Light { 21355 /** 21356 * Constructs a new light probe. 21357 * 21358 * @param {SphericalHarmonics3} sh - The spherical harmonics which represents encoded lighting information. 21359 * @param {number} [intensity=1] - The light's strength/intensity. 21360 */ 21361 constructor(sh = new SphericalHarmonics3(), intensity = 1) { 21362 super(void 0, intensity); 21363 this.isLightProbe = true; 21364 this.sh = sh; 21365 } 21366 copy(source) { 21367 super.copy(source); 21368 this.sh.copy(source.sh); 21369 return this; 21370 } 21371 toJSON(meta) { 21372 const data = super.toJSON(meta); 21373 data.object.sh = this.sh.toArray(); 21374 return data; 21375 } 21376}; 21377var LoaderUtils = class { 21378 /** 21379 * Extracts the base URL from the given URL. 21380 * 21381 * @param {string} url -The URL to extract the base URL from. 21382 * @return {string} The extracted base URL. 21383 */ 21384 static extractUrlBase(url) { 21385 const index = url.lastIndexOf("/"); 21386 if (index === -1) return "./"; 21387 return url.slice(0, index + 1); 21388 } 21389 /** 21390 * Resolves relative URLs against the given path. Absolute paths, data urls, 21391 * and blob URLs will be returned as is. Invalid URLs will return an empty 21392 * string. 21393 * 21394 * @param {string} url -The URL to resolve. 21395 * @param {string} path - The base path for relative URLs to be resolved against. 21396 * @return {string} The resolved URL. 21397 */ 21398 static resolveURL(url, path) { 21399 if (typeof url !== "string" || url === "") return ""; 21400 if (/^https?:\/\//i.test(path) && /^\//.test(url)) { 21401 path = path.replace(/(^https?:\/\/[^\/]+).*/i, "$1"); 21402 } 21403 if (/^(https?:)?\/\//i.test(url)) return url; 21404 if (/^data:.*,.*$/i.test(url)) return url; 21405 if (/^blob:.*$/i.test(url)) return url; 21406 return path + url; 21407 } 21408}; 21409var _errorMap = /* @__PURE__ */ new WeakMap(); 21410var ImageBitmapLoader = class extends Loader { 21411 /** 21412 * Constructs a new image bitmap loader. 21413 * 21414 * @param {LoadingManager} [manager] - The loading manager. 21415 */ 21416 constructor(manager) { 21417 super(manager); 21418 this.isImageBitmapLoader = true; 21419 if (typeof createImageBitmap === "undefined") { 21420 warn("ImageBitmapLoader: createImageBitmap() not supported."); 21421 } 21422 if (typeof fetch === "undefined") { 21423 warn("ImageBitmapLoader: fetch() not supported."); 21424 } 21425 this.options = { premultiplyAlpha: "none" }; 21426 this._abortController = new AbortController(); 21427 } 21428 /** 21429 * Sets the given loader options. The structure of the object must match the `options` parameter of 21430 * [createImageBitmap](https://developer.mozilla.org/en-US/docs/Web/API/Window/createImageBitmap). 21431 * 21432 * Note: When caching is enabled, the cache key is based on the URL only. Loading the same URL with 21433 * different options will return the cached result of the first request. 21434 * 21435 * @param {Object} options - The loader options to set. 21436 * @return {ImageBitmapLoader} A reference to this image bitmap loader. 21437 */ 21438 setOptions(options) { 21439 this.options = options; 21440 return this; 21441 } 21442 /** 21443 * Starts loading from the given URL and pass the loaded image bitmap to the `onLoad()` callback. 21444 * 21445 * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI. 21446 * @param {function(ImageBitmap)} onLoad - Executed when the loading process has been finished. 21447 * @param {onProgressCallback} onProgress - Unsupported in this loader. 21448 * @param {onErrorCallback} onError - Executed when errors occur. 21449 */ 21450 load(url, onLoad, onProgress, onError) { 21451 if (url === void 0) url = ""; 21452 if (this.path !== void 0) url = this.path + url; 21453 url = this.manager.resolveURL(url); 21454 const scope = this; 21455 const cached = Cache.get(`image-bitmap:${url}`); 21456 if (cached !== void 0) { 21457 scope.manager.itemStart(url); 21458 if (cached.then) { 21459 cached.then((imageBitmap) => { 21460 if (_errorMap.has(cached) === true) { 21461 if (onError) onError(_errorMap.get(cached)); 21462 scope.manager.itemError(url); 21463 scope.manager.itemEnd(url); 21464 } else { 21465 if (onLoad) onLoad(imageBitmap); 21466 scope.manager.itemEnd(url); 21467 } 21468 }); 21469 return; 21470 } 21471 setTimeout(function() { 21472 if (onLoad) onLoad(cached); 21473 scope.manager.itemEnd(url); 21474 }, 0); 21475 return; 21476 } 21477 const fetchOptions = {}; 21478 fetchOptions.credentials = this.crossOrigin === "anonymous" ? "same-origin" : "include"; 21479 fetchOptions.headers = this.requestHeader; 21480 fetchOptions.signal = typeof AbortSignal.any === "function" ? AbortSignal.any([this._abortController.signal, this.manager.abortController.signal]) : this._abortController.signal; 21481 const promise = fetch(url, fetchOptions).then(function(res) { 21482 return res.blob(); 21483 }).then(function(blob) { 21484 return createImageBitmap(blob, Object.assign(scope.options, { colorSpaceConversion: "none" })); 21485 }).then(function(imageBitmap) { 21486 Cache.add(`image-bitmap:${url}`, imageBitmap); 21487 if (onLoad) onLoad(imageBitmap); 21488 scope.manager.itemEnd(url); 21489 }).catch(function(e) { 21490 if (onError) onError(e); 21491 _errorMap.set(promise, e); 21492 Cache.remove(`image-bitmap:${url}`); 21493 scope.manager.itemError(url); 21494 scope.manager.itemEnd(url); 21495 }); 21496 Cache.add(`image-bitmap:${url}`, promise); 21497 scope.manager.itemStart(url); 21498 } 21499 /** 21500 * Aborts ongoing fetch requests. 21501 * 21502 * @return {ImageBitmapLoader} A reference to this instance. 21503 */ 21504 abort() { 21505 this._abortController.abort(); 21506 this._abortController = new AbortController(); 21507 return this; 21508 } 21509}; 21510var fov = -90; 21511var aspect = 1; 21512var CubeCamera = class extends Object3D { 21513 /** 21514 * Constructs a new cube camera. 21515 * 21516 * @param {number} near - The camera's near plane. 21517 * @param {number} far - The camera's far plane. 21518 * @param {WebGLCubeRenderTarget} renderTarget - The cube render target. 21519 */ 21520 constructor(near, far, renderTarget) { 21521 super(); 21522 this.type = "CubeCamera"; 21523 this.renderTarget = renderTarget; 21524 this.coordinateSystem = null; 21525 this.activeMipmapLevel = 0; 21526 const cameraPX = new PerspectiveCamera(fov, aspect, near, far); 21527 cameraPX.layers = this.layers; 21528 this.add(cameraPX); 21529 const cameraNX = new PerspectiveCamera(fov, aspect, near, far); 21530 cameraNX.layers = this.layers; 21531 this.add(cameraNX); 21532 const cameraPY = new PerspectiveCamera(fov, aspect, near, far); 21533 cameraPY.layers = this.layers; 21534 this.add(cameraPY); 21535 const cameraNY = new PerspectiveCamera(fov, aspect, near, far); 21536 cameraNY.layers = this.layers; 21537 this.add(cameraNY); 21538 const cameraPZ = new PerspectiveCamera(fov, aspect, near, far); 21539 cameraPZ.layers = this.layers; 21540 this.add(cameraPZ); 21541 const cameraNZ = new PerspectiveCamera(fov, aspect, near, far); 21542 cameraNZ.layers = this.layers; 21543 this.add(cameraNZ); 21544 } 21545 /** 21546 * Must be called when the coordinate system of the cube camera is changed. 21547 */ 21548 updateCoordinateSystem() { 21549 const coordinateSystem = this.coordinateSystem; 21550 const cameras = this.children.concat(); 21551 const [cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ] = cameras; 21552 for (const camera of cameras) this.remove(camera); 21553 if (coordinateSystem === WebGLCoordinateSystem) { 21554 cameraPX.up.set(0, 1, 0); 21555 cameraPX.lookAt(1, 0, 0); 21556 cameraNX.up.set(0, 1, 0); 21557 cameraNX.lookAt(-1, 0, 0); 21558 cameraPY.up.set(0, 0, -1); 21559 cameraPY.lookAt(0, 1, 0); 21560 cameraNY.up.set(0, 0, 1); 21561 cameraNY.lookAt(0, -1, 0); 21562 cameraPZ.up.set(0, 1, 0); 21563 cameraPZ.lookAt(0, 0, 1); 21564 cameraNZ.up.set(0, 1, 0); 21565 cameraNZ.lookAt(0, 0, -1); 21566 } else if (coordinateSystem === WebGPUCoordinateSystem) { 21567 cameraPX.up.set(0, -1, 0); 21568 cameraPX.lookAt(-1, 0, 0); 21569 cameraNX.up.set(0, -1, 0); 21570 cameraNX.lookAt(1, 0, 0); 21571 cameraPY.up.set(0, 0, 1); 21572 cameraPY.lookAt(0, 1, 0); 21573 cameraNY.up.set(0, 0, -1); 21574 cameraNY.lookAt(0, -1, 0); 21575 cameraPZ.up.set(0, -1, 0); 21576 cameraPZ.lookAt(0, 0, 1); 21577 cameraNZ.up.set(0, -1, 0); 21578 cameraNZ.lookAt(0, 0, -1); 21579 } else { 21580 throw new Error("THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: " + coordinateSystem); 21581 } 21582 for (const camera of cameras) { 21583 this.add(camera); 21584 camera.updateMatrixWorld(); 21585 } 21586 } 21587 /** 21588 * Calling this method will render the given scene with the given renderer 21589 * into the cube render target of the camera. 21590 * 21591 * @param {(Renderer|WebGLRenderer)} renderer - The renderer. 21592 * @param {Scene} scene - The scene to render. 21593 */ 21594 update(renderer, scene) { 21595 if (this.parent === null) this.updateMatrixWorld(); 21596 const { renderTarget, activeMipmapLevel } = this; 21597 if (this.coordinateSystem !== renderer.coordinateSystem) { 21598 this.coordinateSystem = renderer.coordinateSystem; 21599 this.updateCoordinateSystem(); 21600 } 21601 const [cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ] = this.children; 21602 const currentRenderTarget = renderer.getRenderTarget(); 21603 const currentActiveCubeFace = renderer.getActiveCubeFace(); 21604 const currentActiveMipmapLevel = renderer.getActiveMipmapLevel(); 21605 const currentXrEnabled = renderer.xr.enabled; 21606 renderer.xr.enabled = false; 21607 const generateMipmaps = renderTarget.texture.generateMipmaps; 21608 renderTarget.texture.generateMipmaps = false; 21609 let reversedDepthBuffer = false; 21610 if (renderer.isWebGLRenderer === true) { 21611 reversedDepthBuffer = renderer.state.buffers.depth.getReversed(); 21612 } else { 21613 reversedDepthBuffer = renderer.reversedDepthBuffer; 21614 } 21615 renderer.setRenderTarget(renderTarget, 0, activeMipmapLevel); 21616 if (reversedDepthBuffer && renderer.autoClear === false) renderer.clearDepth(); 21617 renderer.render(scene, cameraPX); 21618 renderer.setRenderTarget(renderTarget, 1, activeMipmapLevel); 21619 if (reversedDepthBuffer && renderer.autoClear === false) renderer.clearDepth(); 21620 renderer.render(scene, cameraNX); 21621 renderer.setRenderTarget(renderTarget, 2, activeMipmapLevel); 21622 if (reversedDepthBuffer && renderer.autoClear === false) renderer.clearDepth(); 21623 renderer.render(scene, cameraPY); 21624 renderer.setRenderTarget(renderTarget, 3, activeMipmapLevel); 21625 if (reversedDepthBuffer && renderer.autoClear === false) renderer.clearDepth(); 21626 renderer.render(scene, cameraNY); 21627 renderer.setRenderTarget(renderTarget, 4, activeMipmapLevel); 21628 if (reversedDepthBuffer && renderer.autoClear === false) renderer.clearDepth(); 21629 renderer.render(scene, cameraPZ); 21630 renderTarget.texture.generateMipmaps = generateMipmaps; 21631 renderer.setRenderTarget(renderTarget, 5, activeMipmapLevel); 21632 if (reversedDepthBuffer && renderer.autoClear === false) renderer.clearDepth(); 21633 renderer.render(scene, cameraNZ); 21634 renderer.setRenderTarget(currentRenderTarget, currentActiveCubeFace, currentActiveMipmapLevel); 21635 renderer.xr.enabled = currentXrEnabled; 21636 renderTarget.texture.needsPMREMUpdate = true; 21637 } 21638}; 21639var ArrayCamera = class extends PerspectiveCamera { 21640 /** 21641 * Constructs a new array camera. 21642 * 21643 * @param {Array<PerspectiveCamera>} [array=[]] - An array of perspective sub cameras. 21644 */ 21645 constructor(array = []) { 21646 super(); 21647 this.isArrayCamera = true; 21648 this.isMultiViewCamera = false; 21649 this.cameras = array; 21650 } 21651}; 21652var _RESERVED_CHARS_RE = "\\[\\]\\.:\\/"; 21653var _reservedRe = new RegExp("[" + _RESERVED_CHARS_RE + "]", "g"); 21654var _wordChar = "[^" + _RESERVED_CHARS_RE + "]"; 21655var _wordCharOrDot = "[^" + _RESERVED_CHARS_RE.replace("\\.", "") + "]"; 21656var _directoryRe = /* @__PURE__ */ /((?:WC+[\/:])*)/.source.replace("WC", _wordChar); 21657var _nodeRe = /* @__PURE__ */ /(WCOD+)?/.source.replace("WCOD", _wordCharOrDot); 21658var _objectRe = /* @__PURE__ */ /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC", _wordChar); 21659var _propertyRe = /* @__PURE__ */ /\.(WC+)(?:\[(.+)\])?/.source.replace("WC", _wordChar); 21660var _trackRe = new RegExp( 21661 "^" + _directoryRe + _nodeRe + _objectRe + _propertyRe + "$" 21662); 21663var _supportedObjectNames = ["material", "materials", "bones", "map"]; 21664var Composite = class { 21665 constructor(targetGroup, path, optionalParsedPath) { 21666 const parsedPath = optionalParsedPath || PropertyBinding.parseTrackName(path); 21667 this._targetGroup = targetGroup; 21668 this._bindings = targetGroup.subscribe_(path, parsedPath); 21669 } 21670 getValue(array, offset) { 21671 this.bind(); 21672 const firstValidIndex = this._targetGroup.nCachedObjects_, binding = this._bindings[firstValidIndex]; 21673 if (binding !== void 0) binding.getValue(array, offset); 21674 } 21675 setValue(array, offset) { 21676 const bindings = this._bindings; 21677 for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { 21678 bindings[i].setValue(array, offset); 21679 } 21680 } 21681 bind() { 21682 const bindings = this._bindings; 21683 for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { 21684 bindings[i].bind(); 21685 } 21686 } 21687 unbind() { 21688 const bindings = this._bindings; 21689 for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { 21690 bindings[i].unbind(); 21691 } 21692 } 21693}; 21694var PropertyBinding = class _PropertyBinding { 21695 /** 21696 * Constructs a new property binding. 21697 * 21698 * @param {Object} rootNode - The root node. 21699 * @param {string} path - The path. 21700 * @param {?Object} [parsedPath] - The parsed path. 21701 */ 21702 constructor(rootNode, path, parsedPath) { 21703 this.path = path; 21704 this.parsedPath = parsedPath || _PropertyBinding.parseTrackName(path); 21705 this.node = _PropertyBinding.findNode(rootNode, this.parsedPath.nodeName); 21706 this.rootNode = rootNode; 21707 this.getValue = this._getValue_unbound; 21708 this.setValue = this._setValue_unbound; 21709 } 21710 /** 21711 * Factory method for creating a property binding from the given parameters. 21712 * 21713 * @static 21714 * @param {Object} root - The root node. 21715 * @param {string} path - The path. 21716 * @param {?Object} [parsedPath] - The parsed path. 21717 * @return {PropertyBinding|Composite} The created property binding or composite. 21718 */ 21719 static create(root, path, parsedPath) { 21720 if (!(root && root.isAnimationObjectGroup)) { 21721 return new _PropertyBinding(root, path, parsedPath); 21722 } else { 21723 return new _PropertyBinding.Composite(root, path, parsedPath); 21724 } 21725 } 21726 /** 21727 * Replaces spaces with underscores and removes unsupported characters from 21728 * node names, to ensure compatibility with parseTrackName(). 21729 * 21730 * @param {string} name - Node name to be sanitized. 21731 * @return {string} The sanitized node name. 21732 */ 21733 static sanitizeNodeName(name) { 21734 return name.replace(/\s/g, "_").replace(_reservedRe, ""); 21735 } 21736 /** 21737 * Parses the given track name (an object path to an animated property) and 21738 * returns an object with information about the path. Matches strings in the following forms: 21739 * 21740 * - nodeName.property 21741 * - nodeName.property[accessor] 21742 * - nodeName.material.property[accessor] 21743 * - uuid.property[accessor] 21744 * - uuid.objectName[objectIndex].propertyName[propertyIndex] 21745 * - parentName/nodeName.property 21746 * - parentName/parentName/nodeName.property[index] 21747 * - .bone[Armature.DEF_cog].position 21748 * - scene:helium_balloon_model:helium_balloon_model.position 21749 * 21750 * @static 21751 * @param {string} trackName - The track name to parse. 21752 * @return {Object} The parsed track name as an object. 21753 */ 21754 static parseTrackName(trackName) { 21755 const matches = _trackRe.exec(trackName); 21756 if (matches === null) { 21757 throw new Error("PropertyBinding: Cannot parse trackName: " + trackName); 21758 } 21759 const results = { 21760 // directoryName: matches[ 1 ], // (tschw) currently unused 21761 nodeName: matches[2], 21762 objectName: matches[3], 21763 objectIndex: matches[4], 21764 propertyName: matches[5], 21765 // required 21766 propertyIndex: matches[6] 21767 }; 21768 const lastDot = results.nodeName && results.nodeName.lastIndexOf("."); 21769 if (lastDot !== void 0 && lastDot !== -1) { 21770 const objectName = results.nodeName.substring(lastDot + 1); 21771 if (_supportedObjectNames.indexOf(objectName) !== -1) { 21772 results.nodeName = results.nodeName.substring(0, lastDot); 21773 results.objectName = objectName; 21774 } 21775 } 21776 if (results.propertyName === null || results.propertyName.length === 0) { 21777 throw new Error("PropertyBinding: can not parse propertyName from trackName: " + trackName); 21778 } 21779 return results; 21780 } 21781 /** 21782 * Searches for a node in the hierarchy of the given root object by the given 21783 * node name. 21784 * 21785 * @static 21786 * @param {Object} root - The root object. 21787 * @param {string|number} nodeName - The name of the node. 21788 * @return {?Object} The found node. Returns `null` if no object was found. 21789 */ 21790 static findNode(root, nodeName) { 21791 if (nodeName === void 0 || nodeName === "" || nodeName === "." || nodeName === -1 || nodeName === root.name || nodeName === root.uuid) { 21792 return root; 21793 } 21794 if (root.skeleton) { 21795 const bone = root.skeleton.getBoneByName(nodeName); 21796 if (bone !== void 0) { 21797 return bone; 21798 } 21799 } 21800 if (root.children) { 21801 const searchNodeSubtree = function(children2) { 21802 for (let i = 0; i < children2.length; i++) { 21803 const childNode = children2[i]; 21804 if (childNode.name === nodeName || childNode.uuid === nodeName) { 21805 return childNode; 21806 } 21807 const result = searchNodeSubtree(childNode.children); 21808 if (result) return result; 21809 } 21810 return null; 21811 }; 21812 const subTreeNode = searchNodeSubtree(root.children); 21813 if (subTreeNode) { 21814 return subTreeNode; 21815 } 21816 } 21817 return null; 21818 } 21819 // these are used to "bind" a nonexistent property 21820 _getValue_unavailable() { 21821 } 21822 _setValue_unavailable() { 21823 } 21824 // Getters 21825 _getValue_direct(buffer, offset) { 21826 buffer[offset] = this.targetObject[this.propertyName]; 21827 } 21828 _getValue_array(buffer, offset) { 21829 const source = this.resolvedProperty; 21830 for (let i = 0, n = source.length; i !== n; ++i) { 21831 buffer[offset++] = source[i]; 21832 } 21833 } 21834 _getValue_arrayElement(buffer, offset) { 21835 buffer[offset] = this.resolvedProperty[this.propertyIndex]; 21836 } 21837 _getValue_toArray(buffer, offset) { 21838 this.resolvedProperty.toArray(buffer, offset); 21839 } 21840 // Direct 21841 _setValue_direct(buffer, offset) { 21842 this.targetObject[this.propertyName] = buffer[offset]; 21843 } 21844 _setValue_direct_setNeedsUpdate(buffer, offset) { 21845 this.targetObject[this.propertyName] = buffer[offset]; 21846 this.targetObject.needsUpdate = true; 21847 } 21848 _setValue_direct_setMatrixWorldNeedsUpdate(buffer, offset) { 21849 this.targetObject[this.propertyName] = buffer[offset]; 21850 this.targetObject.matrixWorldNeedsUpdate = true; 21851 } 21852 // EntireArray 21853 _setValue_array(buffer, offset) { 21854 const dest = this.resolvedProperty; 21855 for (let i = 0, n = dest.length; i !== n; ++i) { 21856 dest[i] = buffer[offset++]; 21857 } 21858 } 21859 _setValue_array_setNeedsUpdate(buffer, offset) { 21860 const dest = this.resolvedProperty; 21861 for (let i = 0, n = dest.length; i !== n; ++i) { 21862 dest[i] = buffer[offset++]; 21863 } 21864 this.targetObject.needsUpdate = true; 21865 } 21866 _setValue_array_setMatrixWorldNeedsUpdate(buffer, offset) { 21867 const dest = this.resolvedProperty; 21868 for (let i = 0, n = dest.length; i !== n; ++i) { 21869 dest[i] = buffer[offset++]; 21870 } 21871 this.targetObject.matrixWorldNeedsUpdate = true; 21872 } 21873 // ArrayElement 21874 _setValue_arrayElement(buffer, offset) { 21875 this.resolvedProperty[this.propertyIndex] = buffer[offset]; 21876 } 21877 _setValue_arrayElement_setNeedsUpdate(buffer, offset) { 21878 this.resolvedProperty[this.propertyIndex] = buffer[offset]; 21879 this.targetObject.needsUpdate = true; 21880 } 21881 _setValue_arrayElement_setMatrixWorldNeedsUpdate(buffer, offset) { 21882 this.resolvedProperty[this.propertyIndex] = buffer[offset]; 21883 this.targetObject.matrixWorldNeedsUpdate = true; 21884 } 21885 // HasToFromArray 21886 _setValue_fromArray(buffer, offset) { 21887 this.resolvedProperty.fromArray(buffer, offset); 21888 } 21889 _setValue_fromArray_setNeedsUpdate(buffer, offset) { 21890 this.resolvedProperty.fromArray(buffer, offset); 21891 this.targetObject.needsUpdate = true; 21892 } 21893 _setValue_fromArray_setMatrixWorldNeedsUpdate(buffer, offset) { 21894 this.resolvedProperty.fromArray(buffer, offset); 21895 this.targetObject.matrixWorldNeedsUpdate = true; 21896 } 21897 _getValue_unbound(targetArray, offset) { 21898 this.bind(); 21899 this.getValue(targetArray, offset); 21900 } 21901 _setValue_unbound(sourceArray, offset) { 21902 this.bind(); 21903 this.setValue(sourceArray, offset); 21904 } 21905 /** 21906 * Creates a getter / setter pair for the property tracked by this binding. 21907 */ 21908 bind() { 21909 let targetObject = this.node; 21910 const parsedPath = this.parsedPath; 21911 const objectName = parsedPath.objectName; 21912 const propertyName = parsedPath.propertyName; 21913 let propertyIndex = parsedPath.propertyIndex; 21914 if (!targetObject) { 21915 targetObject = _PropertyBinding.findNode(this.rootNode, parsedPath.nodeName); 21916 this.node = targetObject; 21917 } 21918 this.getValue = this._getValue_unavailable; 21919 this.setValue = this._setValue_unavailable; 21920 if (!targetObject) { 21921 warn("PropertyBinding: No target node found for track: " + this.path + "."); 21922 return; 21923 } 21924 if (objectName) { 21925 let objectIndex = parsedPath.objectIndex; 21926 switch (objectName) { 21927 case "materials": 21928 if (!targetObject.material) { 21929 error("PropertyBinding: Can not bind to material as node does not have a material.", this); 21930 return; 21931 } 21932 if (!targetObject.material.materials) { 21933 error("PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.", this); 21934 return; 21935 } 21936 targetObject = targetObject.material.materials; 21937 break; 21938 case "bones": 21939 if (!targetObject.skeleton) { 21940 error("PropertyBinding: Can not bind to bones as node does not have a skeleton.", this); 21941 return; 21942 } 21943 targetObject = targetObject.skeleton.bones; 21944 for (let i = 0; i < targetObject.length; i++) { 21945 if (targetObject[i].name === objectIndex) { 21946 objectIndex = i; 21947 break; 21948 } 21949 } 21950 break; 21951 case "map": 21952 if ("map" in targetObject) { 21953 targetObject = targetObject.map; 21954 break; 21955 } 21956 if (!targetObject.material) { 21957 error("PropertyBinding: Can not bind to material as node does not have a material.", this); 21958 return; 21959 } 21960 if (!targetObject.material.map) { 21961 error("PropertyBinding: Can not bind to material.map as node.material does not have a map.", this); 21962 return; 21963 } 21964 targetObject = targetObject.material.map; 21965 break; 21966 default: 21967 if (targetObject[objectName] === void 0) { 21968 error("PropertyBinding: Can not bind to objectName of node undefined.", this); 21969 return; 21970 } 21971 targetObject = targetObject[objectName]; 21972 } 21973 if (objectIndex !== void 0) { 21974 if (targetObject[objectIndex] === void 0) { 21975 error("PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.", this, targetObject); 21976 return; 21977 } 21978 targetObject = targetObject[objectIndex]; 21979 } 21980 } 21981 const nodeProperty = targetObject[propertyName]; 21982 if (nodeProperty === void 0) { 21983 const nodeName = parsedPath.nodeName; 21984 error("PropertyBinding: Trying to update property for track: " + nodeName + "." + propertyName + " but it wasn't found.", targetObject); 21985 return; 21986 } 21987 let versioning = this.Versioning.None; 21988 this.targetObject = targetObject; 21989 if (targetObject.isMaterial === true) { 21990 versioning = this.Versioning.NeedsUpdate; 21991 } else if (targetObject.isObject3D === true) { 21992 versioning = this.Versioning.MatrixWorldNeedsUpdate; 21993 } 21994 let bindingType = this.BindingType.Direct; 21995 if (propertyIndex !== void 0) { 21996 if (propertyName === "morphTargetInfluences") { 21997 if (!targetObject.geometry) { 21998 error("PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.", this); 21999 return; 22000 } 22001 if (!targetObject.geometry.morphAttributes) { 22002 error("PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.", this); 22003 return; 22004 } 22005 if (targetObject.morphTargetDictionary[propertyIndex] !== void 0) { 22006 propertyIndex = targetObject.morphTargetDictionary[propertyIndex]; 22007 } 22008 } 22009 bindingType = this.BindingType.ArrayElement; 22010 this.resolvedProperty = nodeProperty; 22011 this.propertyIndex = propertyIndex; 22012 } else if (nodeProperty.fromArray !== void 0 && nodeProperty.toArray !== void 0) { 22013 bindingType = this.BindingType.HasFromToArray; 22014 this.resolvedProperty = nodeProperty; 22015 } else if (Array.isArray(nodeProperty)) { 22016 bindingType = this.BindingType.EntireArray; 22017 this.resolvedProperty = nodeProperty; 22018 } else { 22019 this.propertyName = propertyName; 22020 } 22021 this.getValue = this.GetterByBindingType[bindingType]; 22022 this.setValue = this.SetterByBindingTypeAndVersioning[bindingType][versioning]; 22023 } 22024 /** 22025 * Unbinds the property. 22026 */ 22027 unbind() { 22028 this.node = null; 22029 this.getValue = this._getValue_unbound; 22030 this.setValue = this._setValue_unbound; 22031 } 22032}; 22033PropertyBinding.Composite = Composite; 22034PropertyBinding.prototype.BindingType = { 22035 Direct: 0, 22036 EntireArray: 1, 22037 ArrayElement: 2, 22038 HasFromToArray: 3 22039}; 22040PropertyBinding.prototype.Versioning = { 22041 None: 0, 22042 NeedsUpdate: 1, 22043 MatrixWorldNeedsUpdate: 2 22044}; 22045PropertyBinding.prototype.GetterByBindingType = [ 22046 PropertyBinding.prototype._getValue_direct, 22047 PropertyBinding.prototype._getValue_array, 22048 PropertyBinding.prototype._getValue_arrayElement, 22049 PropertyBinding.prototype._getValue_toArray 22050]; 22051PropertyBinding.prototype.SetterByBindingTypeAndVersioning = [ 22052 [ 22053 // Direct 22054 PropertyBinding.prototype._setValue_direct, 22055 PropertyBinding.prototype._setValue_direct_setNeedsUpdate, 22056 PropertyBinding.prototype._setValue_direct_setMatrixWorldNeedsUpdate 22057 ], 22058 [ 22059 // EntireArray 22060 PropertyBinding.prototype._setValue_array, 22061 PropertyBinding.prototype._setValue_array_setNeedsUpdate, 22062 PropertyBinding.prototype._setValue_array_setMatrixWorldNeedsUpdate 22063 ], 22064 [ 22065 // ArrayElement 22066 PropertyBinding.prototype._setValue_arrayElement, 22067 PropertyBinding.prototype._setValue_arrayElement_setNeedsUpdate, 22068 PropertyBinding.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate 22069 ], 22070 [ 22071 // HasToFromArray 22072 PropertyBinding.prototype._setValue_fromArray, 22073 PropertyBinding.prototype._setValue_fromArray_setNeedsUpdate, 22074 PropertyBinding.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate 22075 ] 22076]; 22077var _controlInterpolantsResultBuffer = new Float32Array(1); 22078var Uniform = class _Uniform { 22079 /** 22080 * Constructs a new uniform. 22081 * 22082 * @param {any} value - The uniform value. 22083 */ 22084 constructor(value) { 22085 this.value = value; 22086 } 22087 /** 22088 * Returns a new uniform with copied values from this instance. 22089 * If the value has a `clone()` method, the value is cloned as well. 22090 * 22091 * @return {Uniform} A clone of this instance. 22092 */ 22093 clone() { 22094 return new _Uniform(this.value.clone === void 0 ? this.value : this.value.clone()); 22095 } 22096}; 22097var InstancedInterleavedBuffer = class extends InterleavedBuffer { 22098 /** 22099 * Constructs a new instanced interleaved buffer. 22100 * 22101 * @param {TypedArray} array - A typed array with a shared buffer storing attribute data. 22102 * @param {number} stride - The number of typed-array elements per vertex. 22103 * @param {number} [meshPerAttribute=1] - Defines how often a value of this interleaved buffer should be repeated. 22104 */ 22105 constructor(array, stride, meshPerAttribute = 1) { 22106 super(array, stride); 22107 this.isInstancedInterleavedBuffer = true; 22108 this.meshPerAttribute = meshPerAttribute; 22109 } 22110 copy(source) { 22111 super.copy(source); 22112 this.meshPerAttribute = source.meshPerAttribute; 22113 return this; 22114 } 22115 clone(data) { 22116 const ib = super.clone(data); 22117 ib.meshPerAttribute = this.meshPerAttribute; 22118 return ib; 22119 } 22120 toJSON(data) { 22121 const json = super.toJSON(data); 22122 json.isInstancedInterleavedBuffer = true; 22123 json.meshPerAttribute = this.meshPerAttribute; 22124 return json; 22125 } 22126}; 22127var _matrix = /* @__PURE__ */ new Matrix4(); 22128var Raycaster = class { 22129 /** 22130 * Constructs a new raycaster. 22131 * 22132 * @param {Vector3} origin - The origin vector where the ray casts from. 22133 * @param {Vector3} direction - The (normalized) direction vector that gives direction to the ray. 22134 * @param {number} [near=0] - All results returned are further away than near. Near can't be negative. 22135 * @param {number} [far=Infinity] - All results returned are closer than far. Far can't be lower than near. 22136 */ 22137 constructor(origin, direction, near = 0, far = Infinity) { 22138 this.ray = new Ray(origin, direction); 22139 this.near = near; 22140 this.far = far; 22141 this.camera = null; 22142 this.layers = new Layers(); 22143 this.params = { 22144 Mesh: {}, 22145 Line: { threshold: 1 }, 22146 LOD: {}, 22147 Points: { threshold: 1 }, 22148 Sprite: {} 22149 }; 22150 } 22151 /** 22152 * Updates the ray with a new origin and direction by copying the values from the arguments. 22153 * 22154 * @param {Vector3} origin - The origin vector where the ray casts from. 22155 * @param {Vector3} direction - The (normalized) direction vector that gives direction to the ray. 22156 */ 22157 set(origin, direction) { 22158 this.ray.set(origin, direction); 22159 } 22160 /** 22161 * Uses the given coordinates and camera to compute a new origin and direction for the internal ray. 22162 * 22163 * @param {Vector2} coords - 2D coordinates of the mouse, in normalized device coordinates (NDC). 22164 * X and Y components should be between `-1` and `1`. 22165 * @param {Camera} camera - The camera from which the ray should originate. 22166 */ 22167 setFromCamera(coords, camera) { 22168 if (camera.isPerspectiveCamera) { 22169 this.ray.origin.setFromMatrixPosition(camera.matrixWorld); 22170 this.ray.direction.set(coords.x, coords.y, 0.5).unproject(camera).sub(this.ray.origin).normalize(); 22171 this.camera = camera; 22172 } else if (camera.isOrthographicCamera) { 22173 this.ray.origin.set(coords.x, coords.y, (camera.near + camera.far) / (camera.near - camera.far)).unproject(camera); 22174 this.ray.direction.set(0, 0, -1).transformDirection(camera.matrixWorld); 22175 this.camera = camera; 22176 } else { 22177 error("Raycaster: Unsupported camera type: " + camera.type); 22178 } 22179 } 22180 /** 22181 * Uses the given WebXR controller to compute a new origin and direction for the internal ray. 22182 * 22183 * @param {WebXRController} controller - The controller to copy the position and direction from. 22184 * @return {Raycaster} A reference to this raycaster. 22185 */ 22186 setFromXRController(controller) { 22187 _matrix.identity().extractRotation(controller.matrixWorld); 22188 this.ray.origin.setFromMatrixPosition(controller.matrixWorld); 22189 this.ray.direction.set(0, 0, -1).applyMatrix4(_matrix); 22190 return this; 22191 } 22192 /** 22193 * The intersection point of a raycaster intersection test. 22194 * @typedef {Object} Raycaster~Intersection 22195 * @property {number} distance - The distance from the ray's origin to the intersection point. 22196 * @property {number} distanceToRay - Some 3D objects e.g. {@link Points} provide the distance of the 22197 * intersection to the nearest point on the ray. For other objects it will be `undefined`. 22198 * @property {Vector3} point - The intersection point, in world coordinates. 22199 * @property {Object} face - The face that has been intersected. 22200 * @property {number} faceIndex - The face index. 22201 * @property {Object3D} object - The 3D object that has been intersected. 22202 * @property {Vector2} uv - U,V coordinates at point of intersection. 22203 * @property {Vector2} uv1 - Second set of U,V coordinates at point of intersection. 22204 * @property {Vector3} normal - Interpolated normal vector at point of intersection. 22205 * @property {number} instanceId - The index number of the instance where the ray 22206 * intersects the {@link InstancedMesh}. 22207 */ 22208 /** 22209 * Checks all intersection between the ray and the object with or without the 22210 * descendants. Intersections are returned sorted by distance, closest first. 22211 * 22212 * `Raycaster` delegates to the `raycast()` method of the passed 3D object, when 22213 * evaluating whether the ray intersects the object or not. This allows meshes to respond 22214 * differently to ray casting than lines or points. 22215 * 22216 * Note that for meshes, faces must be pointed towards the origin of the ray in order 22217 * to be detected; intersections of the ray passing through the back of a face will not 22218 * be detected. To raycast against both faces of an object, you'll want to set {@link Material#side} 22219 * to `THREE.DoubleSide`. 22220 * 22221 * @param {Object3D} object - The 3D object to check for intersection with the ray. 22222 * @param {boolean} [recursive=true] - If set to `true`, it also checks all descendants. 22223 * Otherwise it only checks intersection with the object. 22224 * @param {Array<Raycaster~Intersection>} [intersects=[]] The target array that holds the result of the method. 22225 * @return {Array<Raycaster~Intersection>} An array holding the intersection points. 22226 */ 22227 intersectObject(object, recursive = true, intersects2 = []) { 22228 intersect(object, this, intersects2, recursive); 22229 intersects2.sort(ascSort); 22230 return intersects2; 22231 } 22232 /** 22233 * Checks all intersection between the ray and the objects with or without 22234 * the descendants. Intersections are returned sorted by distance, closest first. 22235 * 22236 * @param {Array<Object3D>} objects - The 3D objects to check for intersection with the ray. 22237 * @param {boolean} [recursive=true] - If set to `true`, it also checks all descendants. 22238 * Otherwise it only checks intersection with the object. 22239 * @param {Array<Raycaster~Intersection>} [intersects=[]] The target array that holds the result of the method. 22240 * @return {Array<Raycaster~Intersection>} An array holding the intersection points. 22241 */ 22242 intersectObjects(objects, recursive = true, intersects2 = []) { 22243 for (let i = 0, l = objects.length; i < l; i++) { 22244 intersect(objects[i], this, intersects2, recursive); 22245 } 22246 intersects2.sort(ascSort); 22247 return intersects2; 22248 } 22249}; 22250function ascSort(a, b) { 22251 return a.distance - b.distance; 22252} 22253function intersect(object, raycaster, intersects2, recursive) { 22254 let propagate = true; 22255 if (object.layers.test(raycaster.layers)) { 22256 const result = object.raycast(raycaster, intersects2); 22257 if (result === false) propagate = false; 22258 } 22259 if (propagate === true && recursive === true) { 22260 const children2 = object.children; 22261 for (let i = 0, l = children2.length; i < l; i++) { 22262 intersect(children2[i], raycaster, intersects2, true); 22263 } 22264 } 22265} 22266var Clock = class { 22267 /** 22268 * Constructs a new clock. 22269 * 22270 * @deprecated since 183. 22271 * @param {boolean} [autoStart=true] - Whether to automatically start the clock when 22272 * `getDelta()` is called for the first time. 22273 */ 22274 constructor(autoStart = true) { 22275 this.autoStart = autoStart; 22276 this.startTime = 0; 22277 this.oldTime = 0; 22278 this.elapsedTime = 0; 22279 this.running = false; 22280 warn("Clock: This module has been deprecated. Please use THREE.Timer instead."); 22281 } 22282 /** 22283 * Starts the clock. When `autoStart` is set to `true`, the method is automatically 22284 * called by the class. 22285 */ 22286 start() { 22287 this.startTime = performance.now(); 22288 this.oldTime = this.startTime; 22289 this.elapsedTime = 0; 22290 this.running = true; 22291 } 22292 /** 22293 * Stops the clock. 22294 */ 22295 stop() { 22296 this.getElapsedTime(); 22297 this.running = false; 22298 this.autoStart = false; 22299 } 22300 /** 22301 * Returns the elapsed time in seconds. 22302 * 22303 * @return {number} The elapsed time. 22304 */ 22305 getElapsedTime() { 22306 this.getDelta(); 22307 return this.elapsedTime; 22308 } 22309 /** 22310 * Returns the delta time in seconds. 22311 * 22312 * @return {number} The delta time. 22313 */ 22314 getDelta() { 22315 let diff = 0; 22316 if (this.autoStart && !this.running) { 22317 this.start(); 22318 return 0; 22319 } 22320 if (this.running) { 22321 const newTime = performance.now(); 22322 diff = (newTime - this.oldTime) / 1e3; 22323 this.oldTime = newTime; 22324 this.elapsedTime += diff; 22325 } 22326 return diff; 22327 } 22328}; 22329var Matrix2 = class _Matrix2 { 22330 static { 22331 _Matrix2.prototype.isMatrix2 = true; 22332 } 22333 /** 22334 * Constructs a new 2x2 matrix. The arguments are supposed to be 22335 * in row-major order. If no arguments are provided, the constructor 22336 * initializes the matrix as an identity matrix. 22337 * 22338 * @param {number} [n11] - 1-1 matrix element. 22339 * @param {number} [n12] - 1-2 matrix element. 22340 * @param {number} [n21] - 2-1 matrix element. 22341 * @param {number} [n22] - 2-2 matrix element. 22342 */ 22343 constructor(n11, n12, n21, n22) { 22344 this.elements = [ 22345 1, 22346 0, 22347 0, 22348 1 22349 ]; 22350 if (n11 !== void 0) { 22351 this.set(n11, n12, n21, n22); 22352 } 22353 } 22354 /** 22355 * Sets this matrix to the 2x2 identity matrix. 22356 * 22357 * @return {Matrix2} A reference to this matrix. 22358 */ 22359 identity() { 22360 this.set( 22361 1, 22362 0, 22363 0, 22364 1 22365 ); 22366 return this; 22367 } 22368 /** 22369 * Sets the elements of the matrix from the given array. 22370 * 22371 * @param {Array<number>} array - The matrix elements in column-major order. 22372 * @param {number} [offset=0] - Index of the first element in the array. 22373 * @return {Matrix2} A reference to this matrix. 22374 */ 22375 fromArray(array, offset = 0) { 22376 for (let i = 0; i < 4; i++) { 22377 this.elements[i] = array[i + offset]; 22378 } 22379 return this; 22380 } 22381 /** 22382 * Sets the elements of the matrix.The arguments are supposed to be 22383 * in row-major order. 22384 * 22385 * @param {number} n11 - 1-1 matrix element. 22386 * @param {number} n12 - 1-2 matrix element. 22387 * @param {number} n21 - 2-1 matrix element. 22388 * @param {number} n22 - 2-2 matrix element. 22389 * @return {Matrix2} A reference to this matrix. 22390 */ 22391 set(n11, n12, n21, n22) { 22392 const te = this.elements; 22393 te[0] = n11; 22394 te[2] = n12; 22395 te[1] = n21; 22396 te[3] = n22; 22397 return this; 22398 } 22399}; 22400function getByteLength(width, height, format, type) { 22401 const typeByteLength = getTextureTypeByteLength(type); 22402 switch (format) { 22403 // https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glTexImage2D.xhtml 22404 case AlphaFormat: 22405 return width * height; 22406 case RedFormat: 22407 return width * height / typeByteLength.components * typeByteLength.byteLength; 22408 case RedIntegerFormat: 22409 return width * height / typeByteLength.components * typeByteLength.byteLength; 22410 case RGFormat: 22411 return width * height * 2 / typeByteLength.components * typeByteLength.byteLength; 22412 case RGIntegerFormat: 22413 return width * height * 2 / typeByteLength.components * typeByteLength.byteLength; 22414 case RGBFormat: 22415 return width * height * 3 / typeByteLength.components * typeByteLength.byteLength; 22416 case RGBAFormat: 22417 return width * height * 4 / typeByteLength.components * typeByteLength.byteLength; 22418 case RGBAIntegerFormat: 22419 return width * height * 4 / typeByteLength.components * typeByteLength.byteLength; 22420 // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_s3tc_srgb/ 22421 case RGB_S3TC_DXT1_Format: 22422 case RGBA_S3TC_DXT1_Format: 22423 return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 8; 22424 case RGBA_S3TC_DXT3_Format: 22425 case RGBA_S3TC_DXT5_Format: 22426 return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 16; 22427 // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_pvrtc/ 22428 case RGB_PVRTC_2BPPV1_Format: 22429 case RGBA_PVRTC_2BPPV1_Format: 22430 return Math.max(width, 16) * Math.max(height, 8) / 4; 22431 case RGB_PVRTC_4BPPV1_Format: 22432 case RGBA_PVRTC_4BPPV1_Format: 22433 return Math.max(width, 8) * Math.max(height, 8) / 2; 22434 // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_etc/ 22435 case RGB_ETC1_Format: 22436 case RGB_ETC2_Format: 22437 case R11_EAC_Format: 22438 case SIGNED_R11_EAC_Format: 22439 return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 8; 22440 case RGBA_ETC2_EAC_Format: 22441 case RG11_EAC_Format: 22442 case SIGNED_RG11_EAC_Format: 22443 return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 16; 22444 // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/ 22445 case RGBA_ASTC_4x4_Format: 22446 return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 16; 22447 case RGBA_ASTC_5x4_Format: 22448 return Math.floor((width + 4) / 5) * Math.floor((height + 3) / 4) * 16; 22449 case RGBA_ASTC_5x5_Format: 22450 return Math.floor((width + 4) / 5) * Math.floor((height + 4) / 5) * 16; 22451 case RGBA_ASTC_6x5_Format: 22452 return Math.floor((width + 5) / 6) * Math.floor((height + 4) / 5) * 16; 22453 case RGBA_ASTC_6x6_Format: 22454 return Math.floor((width + 5) / 6) * Math.floor((height + 5) / 6) * 16; 22455 case RGBA_ASTC_8x5_Format: 22456 return Math.floor((width + 7) / 8) * Math.floor((height + 4) / 5) * 16; 22457 case RGBA_ASTC_8x6_Format: 22458 return Math.floor((width + 7) / 8) * Math.floor((height + 5) / 6) * 16; 22459 case RGBA_ASTC_8x8_Format: 22460 return Math.floor((width + 7) / 8) * Math.floor((height + 7) / 8) * 16; 22461 case RGBA_ASTC_10x5_Format: 22462 return Math.floor((width + 9) / 10) * Math.floor((height + 4) / 5) * 16; 22463 case RGBA_ASTC_10x6_Format: 22464 return Math.floor((width + 9) / 10) * Math.floor((height + 5) / 6) * 16; 22465 case RGBA_ASTC_10x8_Format: 22466 return Math.floor((width + 9) / 10) * Math.floor((height + 7) / 8) * 16; 22467 case RGBA_ASTC_10x10_Format: 22468 return Math.floor((width + 9) / 10) * Math.floor((height + 9) / 10) * 16; 22469 case RGBA_ASTC_12x10_Format: 22470 return Math.floor((width + 11) / 12) * Math.floor((height + 9) / 10) * 16; 22471 case RGBA_ASTC_12x12_Format: 22472 return Math.floor((width + 11) / 12) * Math.floor((height + 11) / 12) * 16; 22473 // https://registry.khronos.org/webgl/extensions/EXT_texture_compression_bptc/ 22474 case RGBA_BPTC_Format: 22475 case RGB_BPTC_SIGNED_Format: 22476 case RGB_BPTC_UNSIGNED_Format: 22477 return Math.ceil(width / 4) * Math.ceil(height / 4) * 16; 22478 // https://registry.khronos.org/webgl/extensions/EXT_texture_compression_rgtc/ 22479 case RED_RGTC1_Format: 22480 case SIGNED_RED_RGTC1_Format: 22481 return Math.ceil(width / 4) * Math.ceil(height / 4) * 8; 22482 case RED_GREEN_RGTC2_Format: 22483 case SIGNED_RED_GREEN_RGTC2_Format: 22484 return Math.ceil(width / 4) * Math.ceil(height / 4) * 16; 22485 } 22486 throw new Error( 22487 `Unable to determine texture byte length for ${format} format.` 22488 ); 22489} 22490function getTextureTypeByteLength(type) { 22491 switch (type) { 22492 case UnsignedByteType: 22493 case ByteType: 22494 return { byteLength: 1, components: 1 }; 22495 case UnsignedShortType: 22496 case ShortType: 22497 case HalfFloatType: 22498 return { byteLength: 2, components: 1 }; 22499 case UnsignedShort4444Type: 22500 case UnsignedShort5551Type: 22501 return { byteLength: 2, components: 4 }; 22502 case UnsignedIntType: 22503 case IntType: 22504 case FloatType: 22505 return { byteLength: 4, components: 1 }; 22506 case UnsignedInt5999Type: 22507 case UnsignedInt101111Type: 22508 return { byteLength: 4, components: 3 }; 22509 } 22510 throw new Error(`Unknown texture type ${type}.`); 22511} 22512if (typeof __THREE_DEVTOOLS__ !== "undefined") { 22513 __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("register", { detail: { 22514 revision: REVISION 22515 } })); 22516} 22517if (typeof window !== "undefined") { 22518 if (window.__THREE__) { 22519 warn("WARNING: Multiple instances of Three.js being imported."); 22520 } else { 22521 window.__THREE__ = REVISION; 22522 } 22523} 22524
vendor: 591,998 bytes, lines 22525-34292
22525// node_modules/three/build/three.module.js 22526function WebGLAnimation() { 22527 let context = null; 22528 let isAnimating = false; 22529 let animationLoop = null; 22530 let requestId = null; 22531 function onAnimationFrame(time, frame) { 22532 animationLoop(time, frame); 22533 requestId = context.requestAnimationFrame(onAnimationFrame); 22534 } 22535 return { 22536 start: function() { 22537 if (isAnimating === true) return; 22538 if (animationLoop === null) return; 22539 if (context === null) return; 22540 requestId = context.requestAnimationFrame(onAnimationFrame); 22541 isAnimating = true; 22542 }, 22543 stop: function() { 22544 if (context !== null) context.cancelAnimationFrame(requestId); 22545 isAnimating = false; 22546 }, 22547 setAnimationLoop: function(callback) { 22548 animationLoop = callback; 22549 }, 22550 setContext: function(value) { 22551 context = value; 22552 } 22553 }; 22554} 22555function WebGLAttributes(gl) { 22556 const buffers = /* @__PURE__ */ new WeakMap(); 22557 function createBuffer(attribute, bufferType) { 22558 const array = attribute.array; 22559 const usage = attribute.usage; 22560 const size = array.byteLength; 22561 const buffer = gl.createBuffer(); 22562 gl.bindBuffer(bufferType, buffer); 22563 gl.bufferData(bufferType, array, usage); 22564 attribute.onUploadCallback(); 22565 let type; 22566 if (array instanceof Float32Array) { 22567 type = gl.FLOAT; 22568 } else if (typeof Float16Array !== "undefined" && array instanceof Float16Array) { 22569 type = gl.HALF_FLOAT; 22570 } else if (array instanceof Uint16Array) { 22571 if (attribute.isFloat16BufferAttribute) { 22572 type = gl.HALF_FLOAT; 22573 } else { 22574 type = gl.UNSIGNED_SHORT; 22575 } 22576 } else if (array instanceof Int16Array) { 22577 type = gl.SHORT; 22578 } else if (array instanceof Uint32Array) { 22579 type = gl.UNSIGNED_INT; 22580 } else if (array instanceof Int32Array) { 22581 type = gl.INT; 22582 } else if (array instanceof Int8Array) { 22583 type = gl.BYTE; 22584 } else if (array instanceof Uint8Array) { 22585 type = gl.UNSIGNED_BYTE; 22586 } else if (array instanceof Uint8ClampedArray) { 22587 type = gl.UNSIGNED_BYTE; 22588 } else { 22589 throw new Error("THREE.WebGLAttributes: Unsupported buffer data format: " + array); 22590 } 22591 return { 22592 buffer, 22593 type, 22594 bytesPerElement: array.BYTES_PER_ELEMENT, 22595 version: attribute.version, 22596 size 22597 }; 22598 } 22599 function updateBuffer(buffer, attribute, bufferType) { 22600 const array = attribute.array; 22601 const updateRanges = attribute.updateRanges; 22602 gl.bindBuffer(bufferType, buffer); 22603 if (updateRanges.length === 0) { 22604 gl.bufferSubData(bufferType, 0, array); 22605 } else { 22606 updateRanges.sort((a, b) => a.start - b.start); 22607 let mergeIndex = 0; 22608 for (let i = 1; i < updateRanges.length; i++) { 22609 const previousRange = updateRanges[mergeIndex]; 22610 const range = updateRanges[i]; 22611 if (range.start <= previousRange.start + previousRange.count + 1) { 22612 previousRange.count = Math.max( 22613 previousRange.count, 22614 range.start + range.count - previousRange.start 22615 ); 22616 } else { 22617 ++mergeIndex; 22618 updateRanges[mergeIndex] = range; 22619 } 22620 } 22621 updateRanges.length = mergeIndex + 1; 22622 for (let i = 0, l = updateRanges.length; i < l; i++) { 22623 const range = updateRanges[i]; 22624 gl.bufferSubData( 22625 bufferType, 22626 range.start * array.BYTES_PER_ELEMENT, 22627 array, 22628 range.start, 22629 range.count 22630 ); 22631 } 22632 attribute.clearUpdateRanges(); 22633 } 22634 attribute.onUploadCallback(); 22635 } 22636 function get(attribute) { 22637 if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; 22638 return buffers.get(attribute); 22639 } 22640 function remove(attribute) { 22641 if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; 22642 const data = buffers.get(attribute); 22643 if (data) { 22644 gl.deleteBuffer(data.buffer); 22645 buffers.delete(attribute); 22646 } 22647 } 22648 function update(attribute, bufferType) { 22649 if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; 22650 if (attribute.isGLBufferAttribute) { 22651 const cached = buffers.get(attribute); 22652 if (!cached || cached.version < attribute.version) { 22653 buffers.set(attribute, { 22654 buffer: attribute.buffer, 22655 type: attribute.type, 22656 bytesPerElement: attribute.elementSize, 22657 version: attribute.version 22658 }); 22659 } 22660 return; 22661 } 22662 const data = buffers.get(attribute); 22663 if (data === void 0) { 22664 buffers.set(attribute, createBuffer(attribute, bufferType)); 22665 } else if (data.version < attribute.version) { 22666 if (data.size !== attribute.array.byteLength) { 22667 throw new Error("THREE.WebGLAttributes: The size of the buffer attribute's array buffer does not match the original size. Resizing buffer attributes is not supported."); 22668 } 22669 updateBuffer(data.buffer, attribute, bufferType); 22670 data.version = attribute.version; 22671 } 22672 } 22673 return { 22674 get, 22675 remove, 22676 update 22677 }; 22678} 22679var alphahash_fragment = "#ifdef USE_ALPHAHASH\n if ( diffuseColor.a < getAlphaHashThreshold( vPosition ) ) discard;\n#endif"; 22680var alphahash_pars_fragment = "#ifdef USE_ALPHAHASH\n const float ALPHA_HASH_SCALE = 0.05;\n float hash2D( vec2 value ) {\n return fract( 1.0e4 * sin( 17.0 * value.x + 0.1 * value.y ) * ( 0.1 + abs( sin( 13.0 * value.y + value.x ) ) ) );\n }\n float hash3D( vec3 value ) {\n return hash2D( vec2( hash2D( value.xy ), value.z ) );\n }\n float getAlphaHashThreshold( vec3 position ) {\n float maxDeriv = max(\n length( dFdx( position.xyz ) ),\n length( dFdy( position.xyz ) )\n );\n float pixScale = 1.0 / ( ALPHA_HASH_SCALE * maxDeriv );\n vec2 pixScales = vec2(\n exp2( floor( log2( pixScale ) ) ),\n exp2( ceil( log2( pixScale ) ) )\n );\n vec2 alpha = vec2(\n hash3D( floor( pixScales.x * position.xyz ) ),\n hash3D( floor( pixScales.y * position.xyz ) )\n );\n float lerpFactor = fract( log2( pixScale ) );\n float x = ( 1.0 - lerpFactor ) * alpha.x + lerpFactor * alpha.y;\n float a = min( lerpFactor, 1.0 - lerpFactor );\n vec3 cases = vec3(\n x * x / ( 2.0 * a * ( 1.0 - a ) ),\n ( x - 0.5 * a ) / ( 1.0 - a ),\n 1.0 - ( ( 1.0 - x ) * ( 1.0 - x ) / ( 2.0 * a * ( 1.0 - a ) ) )\n );\n float threshold = ( x < ( 1.0 - a ) )\n ? ( ( x < a ) ? cases.x : cases.y )\n : cases.z;\n return clamp( threshold , 1.0e-6, 1.0 );\n }\n#endif"; 22681var alphamap_fragment = "#ifdef USE_ALPHAMAP\n diffuseColor.a *= texture2D( alphaMap, vAlphaMapUv ).g;\n#endif"; 22682var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n uniform sampler2D alphaMap;\n#endif"; 22683var alphatest_fragment = "#ifdef USE_ALPHATEST\n #ifdef ALPHA_TO_COVERAGE\n diffuseColor.a = smoothstep( alphaTest, alphaTest + fwidth( diffuseColor.a ), diffuseColor.a );\n if ( diffuseColor.a == 0.0 ) discard;\n #else\n if ( diffuseColor.a < alphaTest ) discard;\n #endif\n#endif"; 22684var alphatest_pars_fragment = "#ifdef USE_ALPHATEST\n uniform float alphaTest;\n#endif"; 22685var aomap_fragment = "#ifdef USE_AOMAP\n float ambientOcclusion = ( texture2D( aoMap, vAoMapUv ).r - 1.0 ) * aoMapIntensity + 1.0;\n reflectedLight.indirectDiffuse *= ambientOcclusion;\n #if defined( USE_CLEARCOAT ) \n clearcoatSpecularIndirect *= ambientOcclusion;\n #endif\n #if defined( USE_SHEEN ) \n sheenSpecularIndirect *= ambientOcclusion;\n #endif\n #if defined( USE_ENVMAP ) && defined( STANDARD )\n float dotNV = saturate( dot( geometryNormal, geometryViewDir ) );\n reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n #endif\n#endif"; 22686var aomap_pars_fragment = "#ifdef USE_AOMAP\n uniform sampler2D aoMap;\n uniform float aoMapIntensity;\n#endif"; 22687var batching_pars_vertex = "#ifdef USE_BATCHING\n #if ! defined( GL_ANGLE_multi_draw )\n #define gl_DrawID _gl_DrawID\n uniform int _gl_DrawID;\n #endif\n uniform highp sampler2D batchingTexture;\n uniform highp usampler2D batchingIdTexture;\n mat4 getBatchingMatrix( const in float i ) {\n int size = textureSize( batchingTexture, 0 ).x;\n int j = int( i ) * 4;\n int x = j % size;\n int y = j / size;\n vec4 v1 = texelFetch( batchingTexture, ivec2( x, y ), 0 );\n vec4 v2 = texelFetch( batchingTexture, ivec2( x + 1, y ), 0 );\n vec4 v3 = texelFetch( batchingTexture, ivec2( x + 2, y ), 0 );\n vec4 v4 = texelFetch( batchingTexture, ivec2( x + 3, y ), 0 );\n return mat4( v1, v2, v3, v4 );\n }\n float getIndirectIndex( const in int i ) {\n int size = textureSize( batchingIdTexture, 0 ).x;\n int x = i % size;\n int y = i / size;\n return float( texelFetch( batchingIdTexture, ivec2( x, y ), 0 ).r );\n }\n#endif\n#ifdef USE_BATCHING_COLOR\n uniform sampler2D batchingColorTexture;\n vec4 getBatchingColor( const in float i ) {\n int size = textureSize( batchingColorTexture, 0 ).x;\n int j = int( i );\n int x = j % size;\n int y = j / size;\n return texelFetch( batchingColorTexture, ivec2( x, y ), 0 );\n }\n#endif"; 22688var batching_vertex = "#ifdef USE_BATCHING\n mat4 batchingMatrix = getBatchingMatrix( getIndirectIndex( gl_DrawID ) );\n#endif"; 22689var begin_vertex = "vec3 transformed = vec3( position );\n#ifdef USE_ALPHAHASH\n vPosition = vec3( position );\n#endif"; 22690var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n vec3 objectTangent = vec3( tangent.xyz );\n#endif"; 22691var bsdfs = "float G_BlinnPhong_Implicit( ) {\n return 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n return 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 vec3 halfDir = normalize( lightDir + viewDir );\n float dotNH = saturate( dot( normal, halfDir ) );\n float dotVH = saturate( dot( viewDir, halfDir ) );\n vec3 F = F_Schlick( specularColor, 1.0, dotVH );\n float G = G_BlinnPhong_Implicit( );\n float D = D_BlinnPhong( shininess, dotNH );\n return F * ( G * D );\n} // validated"; 22692var iridescence_fragment = "#ifdef USE_IRIDESCENCE\n const mat3 XYZ_TO_REC709 = mat3(\n 3.2404542, -0.9692660, 0.0556434,\n -1.5371385, 1.8760108, -0.2040259,\n -0.4985314, 0.0415560, 1.0572252\n );\n vec3 Fresnel0ToIor( vec3 fresnel0 ) {\n vec3 sqrtF0 = sqrt( fresnel0 );\n return ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\n }\n vec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) {\n return pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );\n }\n float IorToFresnel0( float transmittedIor, float incidentIor ) {\n return pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));\n }\n vec3 evalSensitivity( float OPD, vec3 shift ) {\n float phase = 2.0 * PI * OPD * 1.0e-9;\n vec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );\n vec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );\n vec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );\n vec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( - pow2( phase ) * var );\n xyz.x += 9.7470e-14 * sqrt( 2.0 * PI * 4.5282e+09 ) * cos( 2.2399e+06 * phase + shift[ 0 ] ) * exp( - 4.5282e+09 * pow2( phase ) );\n xyz /= 1.0685e-7;\n vec3 rgb = XYZ_TO_REC709 * xyz;\n return rgb;\n }\n vec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {\n vec3 I;\n float iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );\n float sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );\n float cosTheta2Sq = 1.0 - sinTheta2Sq;\n if ( cosTheta2Sq < 0.0 ) {\n return vec3( 1.0 );\n }\n float cosTheta2 = sqrt( cosTheta2Sq );\n float R0 = IorToFresnel0( iridescenceIOR, outsideIOR );\n float R12 = F_Schlick( R0, 1.0, cosTheta1 );\n float T121 = 1.0 - R12;\n float phi12 = 0.0;\n if ( iridescenceIOR < outsideIOR ) phi12 = PI;\n float phi21 = PI - phi12;\n vec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) ); vec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR );\n vec3 R23 = F_Schlick( R1, 1.0, cosTheta2 );\n vec3 phi23 = vec3( 0.0 );\n if ( baseIOR[ 0 ] < iridescenceIOR ) phi23[ 0 ] = PI;\n if ( baseIOR[ 1 ] < iridescenceIOR ) phi23[ 1 ] = PI;\n if ( baseIOR[ 2 ] < iridescenceIOR ) phi23[ 2 ] = PI;\n float OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;\n vec3 phi = vec3( phi21 ) + phi23;\n vec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );\n vec3 r123 = sqrt( R123 );\n vec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );\n vec3 C0 = R12 + Rs;\n I = C0;\n vec3 Cm = Rs - T121;\n for ( int m = 1; m <= 2; ++ m ) {\n Cm *= r123;\n vec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );\n I += Cm * Sm;\n }\n return max( I, vec3( 0.0 ) );\n }\n#endif"; 22693var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n uniform sampler2D bumpMap;\n uniform float bumpScale;\n vec2 dHdxy_fwd() {\n vec2 dSTdx = dFdx( vBumpMapUv );\n vec2 dSTdy = dFdy( vBumpMapUv );\n float Hll = bumpScale * texture2D( bumpMap, vBumpMapUv ).x;\n float dBx = bumpScale * texture2D( bumpMap, vBumpMapUv + dSTdx ).x - Hll;\n float dBy = bumpScale * texture2D( bumpMap, vBumpMapUv + dSTdy ).x - Hll;\n return vec2( dBx, dBy );\n }\n vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {\n vec3 vSigmaX = normalize( dFdx( surf_pos.xyz ) );\n vec3 vSigmaY = normalize( dFdy( surf_pos.xyz ) );\n vec3 vN = surf_norm;\n vec3 R1 = cross( vSigmaY, vN );\n vec3 R2 = cross( vN, vSigmaX );\n float fDet = dot( vSigmaX, R1 ) * faceDirection;\n vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n return normalize( abs( fDet ) * surf_norm - vGrad );\n }\n#endif"; 22694var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n vec4 plane;\n #ifdef ALPHA_TO_COVERAGE\n float distanceToPlane, distanceGradient;\n float clipOpacity = 1.0;\n #pragma unroll_loop_start\n for ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n plane = clippingPlanes[ i ];\n distanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n distanceGradient = fwidth( distanceToPlane ) / 2.0;\n clipOpacity *= smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n if ( clipOpacity == 0.0 ) discard;\n }\n #pragma unroll_loop_end\n #if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n float unionClipOpacity = 1.0;\n #pragma unroll_loop_start\n for ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n plane = clippingPlanes[ i ];\n distanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n distanceGradient = fwidth( distanceToPlane ) / 2.0;\n unionClipOpacity *= 1.0 - smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n }\n #pragma unroll_loop_end\n clipOpacity *= 1.0 - unionClipOpacity;\n #endif\n diffuseColor.a *= clipOpacity;\n if ( diffuseColor.a == 0.0 ) discard;\n #else\n #pragma unroll_loop_start\n for ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n plane = clippingPlanes[ i ];\n if ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n }\n #pragma unroll_loop_end\n #if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n bool clipped = true;\n #pragma unroll_loop_start\n for ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n plane = clippingPlanes[ i ];\n clipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n }\n #pragma unroll_loop_end\n if ( clipped ) discard;\n #endif\n #endif\n#endif"; 22695var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n varying vec3 vClipPosition;\n uniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; 22696var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n varying vec3 vClipPosition;\n#endif"; 22697var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n vClipPosition = - mvPosition.xyz;\n#endif"; 22698var color_fragment = "#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA )\n diffuseColor *= vColor;\n#endif"; 22699var color_pars_fragment = "#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA )\n varying vec4 vColor;\n#endif"; 22700var color_pars_vertex = "#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )\n varying vec4 vColor;\n#endif"; 22701var color_vertex = "#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )\n vColor = vec4( 1.0 );\n#endif\n#ifdef USE_COLOR_ALPHA\n vColor *= color;\n#elif defined( USE_COLOR )\n vColor.rgb *= color;\n#endif\n#ifdef USE_INSTANCING_COLOR\n vColor.rgb *= instanceColor.rgb;\n#endif\n#ifdef USE_BATCHING_COLOR\n vColor *= getBatchingColor( getIndirectIndex( gl_DrawID ) );\n#endif"; 22702var 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; }\nvec3 pow2( const in vec3 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 v ) { return dot( v, vec3( 0.3333333 ) ); }\nhighp float rand( const in vec2 uv ) {\n const highp float a = 12.9898, b = 78.233, c = 43758.5453;\n highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n return fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n float precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n float precisionSafeLength( vec3 v ) {\n float maxComponent = max3( abs( v ) );\n return length( v / maxComponent ) * maxComponent;\n }\n#endif\nstruct IncidentLight {\n vec3 color;\n vec3 direction;\n bool visible;\n};\nstruct ReflectedLight {\n vec3 directDiffuse;\n vec3 directSpecular;\n vec3 indirectDiffuse;\n vec3 indirectSpecular;\n};\n#ifdef USE_ALPHAHASH\n varying vec3 vPosition;\n#endif\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n return m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n float u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n float v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n return vec2( u, v );\n}\nvec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n return RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n float fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n float fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n} // validated"; 22703var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n #define cubeUV_minMipLevel 4.0\n #define cubeUV_minTileSize 16.0\n float getFace( vec3 direction ) {\n vec3 absDirection = abs( direction );\n float face = - 1.0;\n if ( absDirection.x > absDirection.z ) {\n if ( absDirection.x > absDirection.y )\n face = direction.x > 0.0 ? 0.0 : 3.0;\n else\n face = direction.y > 0.0 ? 1.0 : 4.0;\n } else {\n if ( absDirection.z > absDirection.y )\n face = direction.z > 0.0 ? 2.0 : 5.0;\n else\n face = direction.y > 0.0 ? 1.0 : 4.0;\n }\n return face;\n }\n vec2 getUV( vec3 direction, float face ) {\n vec2 uv;\n if ( face == 0.0 ) {\n uv = vec2( direction.z, direction.y ) / abs( direction.x );\n } else if ( face == 1.0 ) {\n uv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n } else if ( face == 2.0 ) {\n uv = vec2( - direction.x, direction.y ) / abs( direction.z );\n } else if ( face == 3.0 ) {\n uv = vec2( - direction.z, direction.y ) / abs( direction.x );\n } else if ( face == 4.0 ) {\n uv = vec2( - direction.x, direction.z ) / abs( direction.y );\n } else {\n uv = vec2( direction.x, direction.y ) / abs( direction.z );\n }\n return 0.5 * ( uv + 1.0 );\n }\n vec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n float face = getFace( direction );\n float filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n mipInt = max( mipInt, cubeUV_minMipLevel );\n float faceSize = exp2( mipInt );\n highp vec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\n if ( face > 2.0 ) {\n uv.y += faceSize;\n face -= 3.0;\n }\n uv.x += face * faceSize;\n uv.x += filterInt * 3.0 * cubeUV_minTileSize;\n uv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n uv.x *= CUBEUV_TEXEL_WIDTH;\n uv.y *= CUBEUV_TEXEL_HEIGHT;\n #ifdef texture2DGradEXT\n return texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n #else\n return texture2D( envMap, uv ).rgb;\n #endif\n }\n #define cubeUV_r0 1.0\n #define cubeUV_m0 - 2.0\n #define cubeUV_r1 0.8\n #define cubeUV_m1 - 1.0\n #define cubeUV_r4 0.4\n #define cubeUV_m4 2.0\n #define cubeUV_r5 0.305\n #define cubeUV_m5 3.0\n #define cubeUV_r6 0.21\n #define cubeUV_m6 4.0\n float roughnessToMip( float roughness ) {\n float mip = 0.0;\n if ( roughness >= cubeUV_r1 ) {\n mip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;\n } else if ( roughness >= cubeUV_r4 ) {\n mip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;\n } else if ( roughness >= cubeUV_r5 ) {\n mip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;\n } else if ( roughness >= cubeUV_r6 ) {\n mip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5;\n } else {\n mip = - 2.0 * log2( 1.16 * roughness ); }\n return mip;\n }\n vec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n float mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP );\n float mipF = fract( mip );\n float mipInt = floor( mip );\n vec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n if ( mipF == 0.0 ) {\n return vec4( color0, 1.0 );\n } else {\n vec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n return vec4( mix( color0, color1, mipF ), 1.0 );\n }\n }\n#endif"; 22704var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_TANGENT\n vec3 transformedTangent = objectTangent;\n#endif\n#ifdef USE_BATCHING\n mat3 bm = mat3( batchingMatrix );\n transformedNormal /= vec3( dot( bm[ 0 ], bm[ 0 ] ), dot( bm[ 1 ], bm[ 1 ] ), dot( bm[ 2 ], bm[ 2 ] ) );\n transformedNormal = bm * transformedNormal;\n #ifdef USE_TANGENT\n transformedTangent = bm * transformedTangent;\n #endif\n#endif\n#ifdef USE_INSTANCING\n mat3 im = mat3( instanceMatrix );\n transformedNormal /= vec3( dot( im[ 0 ], im[ 0 ] ), dot( im[ 1 ], im[ 1 ] ), dot( im[ 2 ], im[ 2 ] ) );\n transformedNormal = im * transformedNormal;\n #ifdef USE_TANGENT\n transformedTangent = im * transformedTangent;\n #endif\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n transformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n transformedTangent = ( modelViewMatrix * vec4( transformedTangent, 0.0 ) ).xyz;\n #ifdef FLIP_SIDED\n transformedTangent = - transformedTangent;\n #endif\n#endif"; 22705var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n uniform sampler2D displacementMap;\n uniform float displacementScale;\n uniform float displacementBias;\n#endif"; 22706var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n transformed += normalize( objectNormal ) * ( texture2D( displacementMap, vDisplacementMapUv ).x * displacementScale + displacementBias );\n#endif"; 22707var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n vec4 emissiveColor = texture2D( emissiveMap, vEmissiveMapUv );\n #ifdef DECODE_VIDEO_TEXTURE_EMISSIVE\n emissiveColor = sRGBTransferEOTF( emissiveColor );\n #endif\n totalEmissiveRadiance *= emissiveColor.rgb;\n#endif"; 22708var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n uniform sampler2D emissiveMap;\n#endif"; 22709var colorspace_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; 22710var colorspace_pars_fragment = "vec4 LinearTransferOETF( in vec4 value ) {\n return value;\n}\nvec4 sRGBTransferEOTF( in vec4 value ) {\n return 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 sRGBTransferOETF( in vec4 value ) {\n return 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}"; 22711var envmap_fragment = "#ifdef USE_ENVMAP\n #ifdef ENV_WORLDPOS\n vec3 cameraToFrag;\n if ( isOrthographic ) {\n cameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n } else {\n cameraToFrag = normalize( vWorldPosition - cameraPosition );\n }\n vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n #ifdef ENVMAP_MODE_REFLECTION\n vec3 reflectVec = reflect( cameraToFrag, worldNormal );\n #else\n vec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n #endif\n #else\n vec3 reflectVec = vReflect;\n #endif\n #ifdef ENVMAP_TYPE_CUBE\n vec4 envColor = textureCube( envMap, envMapRotation * reflectVec );\n #ifdef ENVMAP_BLENDING_MULTIPLY\n outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n #elif defined( ENVMAP_BLENDING_MIX )\n outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n #elif defined( ENVMAP_BLENDING_ADD )\n outgoingLight += envColor.xyz * specularStrength * reflectivity;\n #endif\n #endif\n#endif"; 22712var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n uniform float envMapIntensity;\n uniform mat3 envMapRotation;\n #ifdef ENVMAP_TYPE_CUBE\n uniform samplerCube envMap;\n #else\n uniform sampler2D envMap;\n #endif\n#endif"; 22713var envmap_pars_fragment = "#ifdef USE_ENVMAP\n uniform float reflectivity;\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\n #define ENV_WORLDPOS\n #endif\n #ifdef ENV_WORLDPOS\n varying vec3 vWorldPosition;\n uniform float refractionRatio;\n #else\n varying vec3 vReflect;\n #endif\n#endif"; 22714var envmap_pars_vertex = "#ifdef USE_ENVMAP\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\n #define ENV_WORLDPOS\n #endif\n #ifdef ENV_WORLDPOS\n \n varying vec3 vWorldPosition;\n #else\n varying vec3 vReflect;\n uniform float refractionRatio;\n #endif\n#endif"; 22715var envmap_vertex = "#ifdef USE_ENVMAP\n #ifdef ENV_WORLDPOS\n vWorldPosition = worldPosition.xyz;\n #else\n vec3 cameraToVertex;\n if ( isOrthographic ) {\n cameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n } else {\n cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n }\n vec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n #ifdef ENVMAP_MODE_REFLECTION\n vReflect = reflect( cameraToVertex, worldNormal );\n #else\n vReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n #endif\n #endif\n#endif"; 22716var fog_vertex = "#ifdef USE_FOG\n vFogDepth = - mvPosition.z;\n#endif"; 22717var fog_pars_vertex = "#ifdef USE_FOG\n varying float vFogDepth;\n#endif"; 22718var fog_fragment = "#ifdef USE_FOG\n #ifdef FOG_EXP2\n float fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n #else\n float fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n #endif\n gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif"; 22719var fog_pars_fragment = "#ifdef USE_FOG\n uniform vec3 fogColor;\n varying float vFogDepth;\n #ifdef FOG_EXP2\n uniform float fogDensity;\n #else\n uniform float fogNear;\n uniform float fogFar;\n #endif\n#endif"; 22720var gradientmap_pars_fragment = "#ifdef USE_GRADIENTMAP\n uniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n float dotNL = dot( normal, lightDirection );\n vec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n #ifdef USE_GRADIENTMAP\n return vec3( texture2D( gradientMap, coord ).r );\n #else\n vec2 fw = fwidth( coord ) * 0.5;\n return mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) );\n #endif\n}"; 22721var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n uniform sampler2D lightMap;\n uniform float lightMapIntensity;\n#endif"; 22722var lights_lambert_fragment = "LambertMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularStrength = specularStrength;"; 22723var lights_lambert_pars_fragment = "varying vec3 vViewPosition;\nstruct LambertMaterial {\n vec3 diffuseColor;\n float specularStrength;\n};\nvoid RE_Direct_Lambert( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n vec3 irradiance = dotNL * directLight.color;\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct RE_Direct_Lambert\n#define RE_IndirectDiffuse RE_IndirectDiffuse_Lambert"; 22724var lights_pars_begin = "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\n#if defined( USE_LIGHT_PROBES )\n uniform vec3 lightProbe[ 9 ];\n#endif\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n float x = normal.x, y = normal.y, z = normal.z;\n vec3 result = shCoefficients[ 0 ] * 0.886227;\n result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n return result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {\n vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n vec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n return irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n vec3 irradiance = ambientLightColor;\n return irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n if ( cutoffDistance > 0.0 ) {\n distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n }\n return distanceFalloff;\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n return smoothstep( coneCosine, penumbraCosine, angleCosine );\n}\n#if NUM_DIR_LIGHTS > 0\n struct DirectionalLight {\n vec3 direction;\n vec3 color;\n };\n uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n void getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) {\n light.color = directionalLight.color;\n light.direction = directionalLight.direction;\n light.visible = true;\n }\n#endif\n#if NUM_POINT_LIGHTS > 0\n struct PointLight {\n vec3 position;\n vec3 color;\n float distance;\n float decay;\n };\n uniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n void getPointLightInfo( const in PointLight pointLight, const in vec3 geometryPosition, out IncidentLight light ) {\n vec3 lVector = pointLight.position - geometryPosition;\n light.direction = normalize( lVector );\n float lightDistance = length( lVector );\n light.color = pointLight.color;\n light.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n light.visible = ( light.color != vec3( 0.0 ) );\n }\n#endif\n#if NUM_SPOT_LIGHTS > 0\n struct SpotLight {\n vec3 position;\n vec3 direction;\n vec3 color;\n float distance;\n float decay;\n float coneCos;\n float penumbraCos;\n };\n uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n void getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) {\n vec3 lVector = spotLight.position - geometryPosition;\n light.direction = normalize( lVector );\n float angleCos = dot( light.direction, spotLight.direction );\n float spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n if ( spotAttenuation > 0.0 ) {\n float lightDistance = length( lVector );\n light.color = spotLight.color * spotAttenuation;\n light.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n light.visible = ( light.color != vec3( 0.0 ) );\n } else {\n light.color = vec3( 0.0 );\n light.visible = false;\n }\n }\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n struct RectAreaLight {\n vec3 color;\n vec3 position;\n vec3 halfWidth;\n vec3 halfHeight;\n };\n uniform sampler2D ltc_1; uniform sampler2D ltc_2;\n uniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n struct HemisphereLight {\n vec3 direction;\n vec3 skyColor;\n vec3 groundColor;\n };\n uniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {\n float dotNL = dot( normal, hemiLight.direction );\n float hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n vec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n return irradiance;\n }\n#endif\n#include <lightprobes_pars_fragment>"; 22725var envmap_physical_pars_fragment = "#ifdef USE_ENVMAP\n vec3 getIBLIrradiance( const in vec3 normal ) {\n #ifdef ENVMAP_TYPE_CUBE_UV\n vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n vec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 );\n return PI * envMapColor.rgb * envMapIntensity;\n #else\n return vec3( 0.0 );\n #endif\n }\n vec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n #ifdef ENVMAP_TYPE_CUBE_UV\n vec3 reflectVec = reflect( - viewDir, normal );\n reflectVec = normalize( mix( reflectVec, normal, pow4( roughness ) ) );\n reflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n vec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness );\n return envMapColor.rgb * envMapIntensity;\n #else\n return vec3( 0.0 );\n #endif\n }\n #ifdef USE_ANISOTROPY\n vec3 getIBLAnisotropyRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) {\n #ifdef ENVMAP_TYPE_CUBE_UV\n vec3 bentNormal = cross( bitangent, viewDir );\n bentNormal = normalize( cross( bentNormal, bitangent ) );\n bentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) );\n return getIBLRadiance( viewDir, bentNormal, roughness );\n #else\n return vec3( 0.0 );\n #endif\n }\n #endif\n#endif"; 22726var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;"; 22727var lights_toon_pars_fragment = "varying vec3 vViewPosition;\nstruct ToonMaterial {\n vec3 diffuseColor;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n vec3 irradiance = getGradientIrradiance( geometryNormal, directLight.direction ) * directLight.color;\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct RE_Direct_Toon\n#define RE_IndirectDiffuse RE_IndirectDiffuse_Toon"; 22728var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; 22729var lights_phong_pars_fragment = "varying vec3 vViewPosition;\nstruct BlinnPhongMaterial {\n vec3 diffuseColor;\n vec3 specularColor;\n float specularShininess;\n float specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n vec3 irradiance = dotNL * directLight.color;\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n reflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct RE_Direct_BlinnPhong\n#define RE_IndirectDiffuse RE_IndirectDiffuse_BlinnPhong"; 22730var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.diffuseContribution = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.metalness = metalnessFactor;\nvec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) );\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 material.ior = ior;\n #ifdef USE_SPECULAR\n float specularIntensityFactor = specularIntensity;\n vec3 specularColorFactor = specularColor;\n #ifdef USE_SPECULAR_COLORMAP\n specularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;\n #endif\n #ifdef USE_SPECULAR_INTENSITYMAP\n specularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;\n #endif\n material.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n #else\n float specularIntensityFactor = 1.0;\n vec3 specularColorFactor = vec3( 1.0 );\n material.specularF90 = 1.0;\n #endif\n material.specularColor = min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor;\n material.specularColorBlended = mix( material.specularColor, diffuseColor.rgb, metalnessFactor );\n#else\n material.specularColor = vec3( 0.04 );\n material.specularColorBlended = mix( material.specularColor, diffuseColor.rgb, metalnessFactor );\n material.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n material.clearcoat = clearcoat;\n material.clearcoatRoughness = clearcoatRoughness;\n material.clearcoatF0 = vec3( 0.04 );\n material.clearcoatF90 = 1.0;\n #ifdef USE_CLEARCOATMAP\n material.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x;\n #endif\n #ifdef USE_CLEARCOAT_ROUGHNESSMAP\n material.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y;\n #endif\n material.clearcoat = saturate( material.clearcoat ); material.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n material.clearcoatRoughness += geometryRoughness;\n material.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_DISPERSION\n material.dispersion = dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n material.iridescence = iridescence;\n material.iridescenceIOR = iridescenceIOR;\n #ifdef USE_IRIDESCENCEMAP\n material.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;\n #endif\n #ifdef USE_IRIDESCENCE_THICKNESSMAP\n material.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;\n #else\n material.iridescenceThickness = iridescenceThicknessMaximum;\n #endif\n#endif\n#ifdef USE_SHEEN\n material.sheenColor = sheenColor;\n #ifdef USE_SHEEN_COLORMAP\n material.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;\n #endif\n material.sheenRoughness = clamp( sheenRoughness, 0.0001, 1.0 );\n #ifdef USE_SHEEN_ROUGHNESSMAP\n material.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;\n #endif\n#endif\n#ifdef USE_ANISOTROPY\n #ifdef USE_ANISOTROPYMAP\n mat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );\n vec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;\n vec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;\n #else\n vec2 anisotropyV = anisotropyVector;\n #endif\n material.anisotropy = length( anisotropyV );\n if( material.anisotropy == 0.0 ) {\n anisotropyV = vec2( 1.0, 0.0 );\n } else {\n anisotropyV /= material.anisotropy;\n material.anisotropy = saturate( material.anisotropy );\n }\n material.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );\n material.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y;\n material.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y;\n#endif"; 22731var lights_physical_pars_fragment = "uniform sampler2D dfgLUT;\nstruct PhysicalMaterial {\n vec3 diffuseColor;\n vec3 diffuseContribution;\n vec3 specularColor;\n vec3 specularColorBlended;\n float roughness;\n float metalness;\n float specularF90;\n float dispersion;\n #ifdef USE_CLEARCOAT\n float clearcoat;\n float clearcoatRoughness;\n vec3 clearcoatF0;\n float clearcoatF90;\n #endif\n #ifdef USE_IRIDESCENCE\n float iridescence;\n float iridescenceIOR;\n float iridescenceThickness;\n vec3 iridescenceFresnel;\n vec3 iridescenceF0;\n vec3 iridescenceFresnelDielectric;\n vec3 iridescenceFresnelMetallic;\n #endif\n #ifdef USE_SHEEN\n vec3 sheenColor;\n float sheenRoughness;\n #endif\n #ifdef IOR\n float ior;\n #endif\n #ifdef USE_TRANSMISSION\n float transmission;\n float transmissionAlpha;\n float thickness;\n float attenuationDistance;\n vec3 attenuationColor;\n #endif\n #ifdef USE_ANISOTROPY\n float anisotropy;\n float alphaT;\n vec3 anisotropyT;\n vec3 anisotropyB;\n #endif\n};\nvec3 clearcoatSpecularDirect = vec3( 0.0 );\nvec3 clearcoatSpecularIndirect = vec3( 0.0 );\nvec3 sheenSpecularDirect = vec3( 0.0 );\nvec3 sheenSpecularIndirect = vec3(0.0 );\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n float a2 = pow2( alpha );\n float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n return 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n float a2 = pow2( alpha );\n float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n return RECIPROCAL_PI * a2 / pow2( denom );\n}\n#ifdef USE_ANISOTROPY\n float V_GGX_SmithCorrelated_Anisotropic( const in float alphaT, const in float alphaB, const in float dotTV, const in float dotBV, const in float dotTL, const in float dotBL, const in float dotNV, const in float dotNL ) {\n float gv = dotNL * length( vec3( alphaT * dotTV, alphaB * dotBV, dotNV ) );\n float gl = dotNV * length( vec3( alphaT * dotTL, alphaB * dotBL, dotNL ) );\n return 0.5 / max( gv + gl, EPSILON );\n }\n float D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) {\n float a2 = alphaT * alphaB;\n highp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH );\n highp float v2 = dot( v, v );\n float w2 = a2 / v2;\n return RECIPROCAL_PI * a2 * pow2 ( w2 );\n }\n#endif\n#ifdef USE_CLEARCOAT\n vec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) {\n vec3 f0 = material.clearcoatF0;\n float f90 = material.clearcoatF90;\n float roughness = material.clearcoatRoughness;\n float alpha = pow2( roughness );\n vec3 halfDir = normalize( lightDir + viewDir );\n float dotNL = saturate( dot( normal, lightDir ) );\n float dotNV = saturate( dot( normal, viewDir ) );\n float dotNH = saturate( dot( normal, halfDir ) );\n float dotVH = saturate( dot( viewDir, halfDir ) );\n vec3 F = F_Schlick( f0, f90, dotVH );\n float V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n float D = D_GGX( alpha, dotNH );\n return F * ( V * D );\n }\n#endif\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n vec3 f0 = material.specularColorBlended;\n float f90 = material.specularF90;\n float roughness = material.roughness;\n float alpha = pow2( roughness );\n vec3 halfDir = normalize( lightDir + viewDir );\n float dotNL = saturate( dot( normal, lightDir ) );\n float dotNV = saturate( dot( normal, viewDir ) );\n float dotNH = saturate( dot( normal, halfDir ) );\n float dotVH = saturate( dot( viewDir, halfDir ) );\n vec3 F = F_Schlick( f0, f90, dotVH );\n #ifdef USE_IRIDESCENCE\n F = mix( F, material.iridescenceFresnel, material.iridescence );\n #endif\n #ifdef USE_ANISOTROPY\n float dotTL = dot( material.anisotropyT, lightDir );\n float dotTV = dot( material.anisotropyT, viewDir );\n float dotTH = dot( material.anisotropyT, halfDir );\n float dotBL = dot( material.anisotropyB, lightDir );\n float dotBV = dot( material.anisotropyB, viewDir );\n float dotBH = dot( material.anisotropyB, halfDir );\n float V = V_GGX_SmithCorrelated_Anisotropic( material.alphaT, alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL );\n float D = D_GGX_Anisotropic( material.alphaT, alpha, dotNH, dotTH, dotBH );\n #else\n float V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n float D = D_GGX( alpha, dotNH );\n #endif\n return F * ( V * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n const float LUT_SIZE = 64.0;\n const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n const float LUT_BIAS = 0.5 / LUT_SIZE;\n float dotNV = saturate( dot( N, V ) );\n vec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n uv = uv * LUT_SCALE + LUT_BIAS;\n return uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n float l = length( f );\n return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n float x = dot( v1, v2 );\n float y = abs( x );\n float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n float b = 3.4175940 + ( 4.1616724 + y ) * y;\n float v = a / b;\n float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n return 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 vec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n vec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n vec3 lightNormal = cross( v1, v2 );\n if( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n vec3 T1, T2;\n T1 = normalize( V - N * dot( V, N ) );\n T2 = - cross( N, T1 );\n mat3 mat = mInv * transpose( mat3( T1, T2, N ) );\n vec3 coords[ 4 ];\n coords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n coords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n coords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n coords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n coords[ 0 ] = normalize( coords[ 0 ] );\n coords[ 1 ] = normalize( coords[ 1 ] );\n coords[ 2 ] = normalize( coords[ 2 ] );\n coords[ 3 ] = normalize( coords[ 3 ] );\n vec3 vectorFormFactor = vec3( 0.0 );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n float result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n return vec3( result );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n float alpha = pow2( roughness );\n float invAlpha = 1.0 / alpha;\n float cos2h = dotNH * dotNH;\n float sin2h = max( 1.0 - cos2h, 0.0078125 );\n return ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n return 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 vec3 halfDir = normalize( lightDir + viewDir );\n float dotNL = saturate( dot( normal, lightDir ) );\n float dotNV = saturate( dot( normal, viewDir ) );\n float dotNH = saturate( dot( normal, halfDir ) );\n float D = D_Charlie( sheenRoughness, dotNH );\n float V = V_Neubelt( dotNV, dotNL );\n return sheenColor * ( D * V );\n}\n#endif\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n float dotNV = saturate( dot( normal, viewDir ) );\n float r2 = roughness * roughness;\n float rInv = 1.0 / ( roughness + 0.1 );\n float a = -1.9362 + 1.0678 * roughness + 0.4573 * r2 - 0.8469 * rInv;\n float b = -0.6014 + 0.5538 * roughness - 0.4670 * r2 - 0.1255 * rInv;\n float DG = exp( a * dotNV + b );\n return saturate( DG );\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n float dotNV = saturate( dot( normal, viewDir ) );\n vec2 fab = texture2D( dfgLUT, vec2( roughness, dotNV ) ).rg;\n return specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\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#endif\n float dotNV = saturate( dot( normal, viewDir ) );\n vec2 fab = texture2D( dfgLUT, vec2( roughness, dotNV ) ).rg;\n #ifdef USE_IRIDESCENCE\n vec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n #else\n vec3 Fr = specularColor;\n #endif\n vec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n float Ess = fab.x + fab.y;\n float Ems = 1.0 - Ess;\n vec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619; vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n singleScatter += FssEss;\n multiScatter += Fms * Ems;\n}\nvec3 BRDF_GGX_Multiscatter( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n vec3 singleScatter = BRDF_GGX( lightDir, viewDir, normal, material );\n float dotNL = saturate( dot( normal, lightDir ) );\n float dotNV = saturate( dot( normal, viewDir ) );\n vec2 dfgV = texture2D( dfgLUT, vec2( material.roughness, dotNV ) ).rg;\n vec2 dfgL = texture2D( dfgLUT, vec2( material.roughness, dotNL ) ).rg;\n vec3 FssEss_V = material.specularColorBlended * dfgV.x + material.specularF90 * dfgV.y;\n vec3 FssEss_L = material.specularColorBlended * dfgL.x + material.specularF90 * dfgL.y;\n float Ess_V = dfgV.x + dfgV.y;\n float Ess_L = dfgL.x + dfgL.y;\n float Ems_V = 1.0 - Ess_V;\n float Ems_L = 1.0 - Ess_L;\n vec3 Favg = material.specularColorBlended + ( 1.0 - material.specularColorBlended ) * 0.047619;\n vec3 Fms = FssEss_V * FssEss_L * Favg / ( 1.0 - Ems_V * Ems_L * Favg + EPSILON );\n float compensationFactor = Ems_V * Ems_L;\n vec3 multiScatter = Fms * compensationFactor;\n return singleScatter + multiScatter;\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n void RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n vec3 normal = geometryNormal;\n vec3 viewDir = geometryViewDir;\n vec3 position = geometryPosition;\n vec3 lightPos = rectAreaLight.position;\n vec3 halfWidth = rectAreaLight.halfWidth;\n vec3 halfHeight = rectAreaLight.halfHeight;\n vec3 lightColor = rectAreaLight.color;\n float roughness = material.roughness;\n vec3 rectCoords[ 4 ];\n rectCoords[ 0 ] = lightPos + halfWidth - halfHeight; rectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n rectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n rectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n vec2 uv = LTC_Uv( normal, viewDir, roughness );\n vec4 t1 = texture2D( ltc_1, uv );\n vec4 t2 = texture2D( ltc_2, uv );\n mat3 mInv = mat3(\n vec3( t1.x, 0, t1.y ),\n vec3( 0, 1, 0 ),\n vec3( t1.z, 0, t1.w )\n );\n vec3 fresnel = ( material.specularColorBlended * t2.x + ( material.specularF90 - material.specularColorBlended ) * t2.y );\n reflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n reflectedLight.directDiffuse += lightColor * material.diffuseContribution * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n #ifdef USE_CLEARCOAT\n vec3 Ncc = geometryClearcoatNormal;\n vec2 uvClearcoat = LTC_Uv( Ncc, viewDir, material.clearcoatRoughness );\n vec4 t1Clearcoat = texture2D( ltc_1, uvClearcoat );\n vec4 t2Clearcoat = texture2D( ltc_2, uvClearcoat );\n mat3 mInvClearcoat = mat3(\n vec3( t1Clearcoat.x, 0, t1Clearcoat.y ),\n vec3( 0, 1, 0 ),\n vec3( t1Clearcoat.z, 0, t1Clearcoat.w )\n );\n vec3 fresnelClearcoat = material.clearcoatF0 * t2Clearcoat.x + ( material.clearcoatF90 - material.clearcoatF0 ) * t2Clearcoat.y;\n clearcoatSpecularDirect += lightColor * fresnelClearcoat * LTC_Evaluate( Ncc, viewDir, position, mInvClearcoat, rectCoords );\n #endif\n }\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n vec3 irradiance = dotNL * directLight.color;\n #ifdef USE_CLEARCOAT\n float dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) );\n vec3 ccIrradiance = dotNLcc * directLight.color;\n clearcoatSpecularDirect += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material );\n #endif\n #ifdef USE_SHEEN\n \n sheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );\n \n float sheenAlbedoV = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n float sheenAlbedoL = IBLSheenBRDF( geometryNormal, directLight.direction, material.sheenRoughness );\n \n float sheenEnergyComp = 1.0 - max3( material.sheenColor ) * max( sheenAlbedoV, sheenAlbedoL );\n \n irradiance *= sheenEnergyComp;\n \n #endif\n reflectedLight.directSpecular += irradiance * BRDF_GGX_Multiscatter( directLight.direction, geometryViewDir, geometryNormal, material );\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseContribution );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n vec3 diffuse = irradiance * BRDF_Lambert( material.diffuseContribution );\n #ifdef USE_SHEEN\n float sheenAlbedo = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n float sheenEnergyComp = 1.0 - max3( material.sheenColor ) * sheenAlbedo;\n diffuse *= sheenEnergyComp;\n #endif\n reflectedLight.indirectDiffuse += diffuse;\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n #ifdef USE_CLEARCOAT\n clearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n #endif\n #ifdef USE_SHEEN\n sheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness ) * RECIPROCAL_PI;\n #endif\n vec3 singleScatteringDielectric = vec3( 0.0 );\n vec3 multiScatteringDielectric = vec3( 0.0 );\n vec3 singleScatteringMetallic = vec3( 0.0 );\n vec3 multiScatteringMetallic = vec3( 0.0 );\n #ifdef USE_IRIDESCENCE\n computeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnelDielectric, material.roughness, singleScatteringDielectric, multiScatteringDielectric );\n computeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.diffuseColor, material.specularF90, material.iridescence, material.iridescenceFresnelMetallic, material.roughness, singleScatteringMetallic, multiScatteringMetallic );\n #else\n computeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScatteringDielectric, multiScatteringDielectric );\n computeMultiscattering( geometryNormal, geometryViewDir, material.diffuseColor, material.specularF90, material.roughness, singleScatteringMetallic, multiScatteringMetallic );\n #endif\n vec3 singleScattering = mix( singleScatteringDielectric, singleScatteringMetallic, material.metalness );\n vec3 multiScattering = mix( multiScatteringDielectric, multiScatteringMetallic, material.metalness );\n vec3 totalScatteringDielectric = singleScatteringDielectric + multiScatteringDielectric;\n vec3 diffuse = material.diffuseContribution * ( 1.0 - totalScatteringDielectric );\n vec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n vec3 indirectSpecular = radiance * singleScattering;\n indirectSpecular += multiScattering * cosineWeightedIrradiance;\n vec3 indirectDiffuse = diffuse * cosineWeightedIrradiance;\n #ifdef USE_SHEEN\n float sheenAlbedo = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n float sheenEnergyComp = 1.0 - max3( material.sheenColor ) * sheenAlbedo;\n indirectSpecular *= sheenEnergyComp;\n indirectDiffuse *= sheenEnergyComp;\n #endif\n reflectedLight.indirectSpecular += indirectSpecular;\n reflectedLight.indirectDiffuse += indirectDiffuse;\n}\n#define RE_Direct RE_Direct_Physical\n#define RE_Direct_RectArea RE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse RE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular RE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}"; 22732var lights_fragment_begin = "\nvec3 geometryPosition = - vViewPosition;\nvec3 geometryNormal = normal;\nvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\nvec3 geometryClearcoatNormal = vec3( 0.0 );\n#ifdef USE_CLEARCOAT\n geometryClearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n float dotNVi = saturate( dot( normal, geometryViewDir ) );\n if ( material.iridescenceThickness == 0.0 ) {\n material.iridescence = 0.0;\n } else {\n material.iridescence = saturate( material.iridescence );\n }\n if ( material.iridescence > 0.0 ) {\n material.iridescenceFresnelDielectric = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n material.iridescenceFresnelMetallic = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.diffuseColor );\n material.iridescenceFresnel = mix( material.iridescenceFresnelDielectric, material.iridescenceFresnelMetallic, material.metalness );\n material.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n }\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n PointLight pointLight;\n #if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n PointLightShadow pointLightShadow;\n #endif\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n pointLight = pointLights[ i ];\n getPointLightInfo( pointLight, geometryPosition, directLight );\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS ) && ( defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_BASIC ) )\n pointLightShadow = pointLightShadows[ i ];\n directLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n #endif\n RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n SpotLight spotLight;\n vec4 spotColor;\n vec3 spotLightCoord;\n bool inSpotLightMap;\n #if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n SpotLightShadow spotLightShadow;\n #endif\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n spotLight = spotLights[ i ];\n getSpotLightInfo( spotLight, geometryPosition, directLight );\n #if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n #define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n #elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n #define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n #else\n #define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n #endif\n #if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n spotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n inSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n spotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n directLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n #endif\n #undef SPOT_LIGHT_MAP_INDEX\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n spotLightShadow = spotLightShadows[ i ];\n directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n DirectionalLight directionalLight;\n #if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n DirectionalLightShadow directionalLightShadow;\n #endif\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n directionalLight = directionalLights[ i ];\n getDirectionalLightInfo( directionalLight, directLight );\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n directionalLightShadow = directionalLightShadows[ i ];\n directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n RectAreaLight rectAreaLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n rectAreaLight = rectAreaLights[ i ];\n RE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n vec3 iblIrradiance = vec3( 0.0 );\n vec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n #if defined( USE_LIGHT_PROBES )\n irradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n #endif\n #if ( NUM_HEMI_LIGHTS > 0 )\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );\n }\n #pragma unroll_loop_end\n #endif\n #ifdef USE_LIGHT_PROBES_GRID\n vec3 probeWorldPos = ( ( vec4( geometryPosition, 1.0 ) - viewMatrix[ 3 ] ) * viewMatrix ).xyz;\n vec3 probeWorldNormal = inverseTransformDirection( geometryNormal, viewMatrix );\n irradiance += getLightProbeGridIrradiance( probeWorldPos, probeWorldNormal );\n #endif\n#endif\n#if defined( RE_IndirectSpecular )\n vec3 radiance = vec3( 0.0 );\n vec3 clearcoatRadiance = vec3( 0.0 );\n#endif"; 22733var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n #ifdef USE_LIGHTMAP\n vec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n vec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n irradiance += lightMapIrradiance;\n #endif\n #if defined( USE_ENVMAP ) && defined( ENVMAP_TYPE_CUBE_UV )\n #if defined( STANDARD ) || defined( LAMBERT ) || defined( PHONG )\n iblIrradiance += getIBLIrradiance( geometryNormal );\n #endif\n #endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n #ifdef USE_ANISOTROPY\n radiance += getIBLAnisotropyRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy );\n #else\n radiance += getIBLRadiance( geometryViewDir, geometryNormal, material.roughness );\n #endif\n #ifdef USE_CLEARCOAT\n clearcoatRadiance += getIBLRadiance( geometryViewDir, geometryClearcoatNormal, material.clearcoatRoughness );\n #endif\n#endif"; 22734var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n #if defined( LAMBERT ) || defined( PHONG )\n irradiance += iblIrradiance;\n #endif\n RE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n RE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif"; 22735var lightprobes_pars_fragment = "#ifdef USE_LIGHT_PROBES_GRID\nuniform highp sampler3D probesSH;\nuniform vec3 probesMin;\nuniform vec3 probesMax;\nuniform vec3 probesResolution;\nvec3 getLightProbeGridIrradiance( vec3 worldPos, vec3 worldNormal ) {\n vec3 res = probesResolution;\n vec3 gridRange = probesMax - probesMin;\n vec3 resMinusOne = res - 1.0;\n vec3 probeSpacing = gridRange / resMinusOne;\n vec3 samplePos = worldPos + worldNormal * probeSpacing * 0.5;\n vec3 uvw = clamp( ( samplePos - probesMin ) / gridRange, 0.0, 1.0 );\n uvw = uvw * resMinusOne / res + 0.5 / res;\n float nz = res.z;\n float paddedSlices = nz + 2.0;\n float atlasDepth = 7.0 * paddedSlices;\n float uvZBase = uvw.z * nz + 1.0;\n vec4 s0 = texture( probesSH, vec3( uvw.xy, ( uvZBase ) / atlasDepth ) );\n vec4 s1 = texture( probesSH, vec3( uvw.xy, ( uvZBase + paddedSlices ) / atlasDepth ) );\n vec4 s2 = texture( probesSH, vec3( uvw.xy, ( uvZBase + 2.0 * paddedSlices ) / atlasDepth ) );\n vec4 s3 = texture( probesSH, vec3( uvw.xy, ( uvZBase + 3.0 * paddedSlices ) / atlasDepth ) );\n vec4 s4 = texture( probesSH, vec3( uvw.xy, ( uvZBase + 4.0 * paddedSlices ) / atlasDepth ) );\n vec4 s5 = texture( probesSH, vec3( uvw.xy, ( uvZBase + 5.0 * paddedSlices ) / atlasDepth ) );\n vec4 s6 = texture( probesSH, vec3( uvw.xy, ( uvZBase + 6.0 * paddedSlices ) / atlasDepth ) );\n vec3 c0 = s0.xyz;\n vec3 c1 = vec3( s0.w, s1.xy );\n vec3 c2 = vec3( s1.zw, s2.x );\n vec3 c3 = s2.yzw;\n vec3 c4 = s3.xyz;\n vec3 c5 = vec3( s3.w, s4.xy );\n vec3 c6 = vec3( s4.zw, s5.x );\n vec3 c7 = s5.yzw;\n vec3 c8 = s6.xyz;\n float x = worldNormal.x, y = worldNormal.y, z = worldNormal.z;\n vec3 result = c0 * 0.886227;\n result += c1 * 2.0 * 0.511664 * y;\n result += c2 * 2.0 * 0.511664 * z;\n result += c3 * 2.0 * 0.511664 * x;\n result += c4 * 2.0 * 0.429043 * x * y;\n result += c5 * 2.0 * 0.429043 * y * z;\n result += c6 * ( 0.743125 * z * z - 0.247708 );\n result += c7 * 2.0 * 0.429043 * x * z;\n result += c8 * 0.429043 * ( x * x - y * y );\n return max( result, vec3( 0.0 ) );\n}\n#endif"; 22736var logdepthbuf_fragment = "#if defined( USE_LOGARITHMIC_DEPTH_BUFFER )\n gl_FragDepth = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; 22737var logdepthbuf_pars_fragment = "#if defined( USE_LOGARITHMIC_DEPTH_BUFFER )\n uniform float logDepthBufFC;\n varying float vFragDepth;\n varying float vIsPerspective;\n#endif"; 22738var logdepthbuf_pars_vertex = "#ifdef USE_LOGARITHMIC_DEPTH_BUFFER\n varying float vFragDepth;\n varying float vIsPerspective;\n#endif"; 22739var logdepthbuf_vertex = "#ifdef USE_LOGARITHMIC_DEPTH_BUFFER\n vFragDepth = 1.0 + gl_Position.w;\n vIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n#endif"; 22740var map_fragment = "#ifdef USE_MAP\n vec4 sampledDiffuseColor = texture2D( map, vMapUv );\n #ifdef DECODE_VIDEO_TEXTURE\n sampledDiffuseColor = sRGBTransferEOTF( sampledDiffuseColor );\n #endif\n diffuseColor *= sampledDiffuseColor;\n#endif"; 22741var map_pars_fragment = "#ifdef USE_MAP\n uniform sampler2D map;\n#endif"; 22742var map_particle_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n #if defined( USE_POINTS_UV )\n vec2 uv = vUv;\n #else\n vec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n #endif\n#endif\n#ifdef USE_MAP\n diffuseColor *= texture2D( map, uv );\n#endif\n#ifdef USE_ALPHAMAP\n diffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif"; 22743var map_particle_pars_fragment = "#if defined( USE_POINTS_UV )\n varying vec2 vUv;\n#else\n #if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n uniform mat3 uvTransform;\n #endif\n#endif\n#ifdef USE_MAP\n uniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n uniform sampler2D alphaMap;\n#endif"; 22744var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n vec4 texelMetalness = texture2D( metalnessMap, vMetalnessMapUv );\n metalnessFactor *= texelMetalness.b;\n#endif"; 22745var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n uniform sampler2D metalnessMap;\n#endif"; 22746var morphinstance_vertex = "#ifdef USE_INSTANCING_MORPH\n float morphTargetInfluences[ MORPHTARGETS_COUNT ];\n float morphTargetBaseInfluence = texelFetch( morphTexture, ivec2( 0, gl_InstanceID ), 0 ).r;\n for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n morphTargetInfluences[i] = texelFetch( morphTexture, ivec2( i + 1, gl_InstanceID ), 0 ).r;\n }\n#endif"; 22747var morphcolor_vertex = "#if defined( USE_MORPHCOLORS )\n vColor *= morphTargetBaseInfluence;\n for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n #if defined( USE_COLOR_ALPHA )\n if ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ];\n #elif defined( USE_COLOR )\n if ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ];\n #endif\n }\n#endif"; 22748var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n objectNormal *= morphTargetBaseInfluence;\n for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n if ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ];\n }\n#endif"; 22749var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n #ifndef USE_INSTANCING_MORPH\n uniform float morphTargetBaseInfluence;\n uniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];\n #endif\n uniform sampler2DArray morphTargetsTexture;\n uniform ivec2 morphTargetsTextureSize;\n vec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) {\n int texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset;\n int y = texelIndex / morphTargetsTextureSize.x;\n int x = texelIndex - y * morphTargetsTextureSize.x;\n ivec3 morphUV = ivec3( x, y, morphTargetIndex );\n return texelFetch( morphTargetsTexture, morphUV, 0 );\n }\n#endif"; 22750var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n transformed *= morphTargetBaseInfluence;\n for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n if ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\n }\n#endif"; 22751var normal_fragment_begin = "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n vec3 fdx = dFdx( vViewPosition );\n vec3 fdy = dFdy( vViewPosition );\n vec3 normal = normalize( cross( fdx, fdy ) );\n#else\n vec3 normal = normalize( vNormal );\n #ifdef DOUBLE_SIDED\n normal *= faceDirection;\n #endif\n#endif\n#if defined( USE_NORMALMAP_TANGENTSPACE ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY )\n #ifdef USE_TANGENT\n mat3 tbn = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n #else\n mat3 tbn = getTangentFrame( - vViewPosition, normal,\n #if defined( USE_NORMALMAP )\n vNormalMapUv\n #elif defined( USE_CLEARCOAT_NORMALMAP )\n vClearcoatNormalMapUv\n #else\n vUv\n #endif\n );\n #endif\n #if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n tbn[0] *= faceDirection;\n tbn[1] *= faceDirection;\n #endif\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n #ifdef USE_TANGENT\n mat3 tbn2 = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n #else\n mat3 tbn2 = getTangentFrame( - vViewPosition, normal, vClearcoatNormalMapUv );\n #endif\n #if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n tbn2[0] *= faceDirection;\n tbn2[1] *= faceDirection;\n #endif\n#endif\nvec3 nonPerturbedNormal = normal;"; 22752var normal_fragment_maps = "#ifdef USE_NORMALMAP_OBJECTSPACE\n normal = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n #ifdef FLIP_SIDED\n normal = - normal;\n #endif\n #ifdef DOUBLE_SIDED\n normal = normal * faceDirection;\n #endif\n normal = normalize( normalMatrix * normal );\n#elif defined( USE_NORMALMAP_TANGENTSPACE )\n vec3 mapN = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n #if defined( USE_PACKED_NORMALMAP )\n mapN = vec3( mapN.xy, sqrt( saturate( 1.0 - dot( mapN.xy, mapN.xy ) ) ) );\n #endif\n mapN.xy *= normalScale;\n normal = normalize( tbn * mapN );\n#elif defined( USE_BUMPMAP )\n normal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif"; 22753var normal_pars_fragment = "#ifndef FLAT_SHADED\n varying vec3 vNormal;\n #ifdef USE_TANGENT\n varying vec3 vTangent;\n varying vec3 vBitangent;\n #endif\n#endif"; 22754var normal_pars_vertex = "#ifndef FLAT_SHADED\n varying vec3 vNormal;\n #ifdef USE_TANGENT\n varying vec3 vTangent;\n varying vec3 vBitangent;\n #endif\n#endif"; 22755var normal_vertex = "#ifndef FLAT_SHADED\n vNormal = normalize( transformedNormal );\n #ifdef USE_TANGENT\n vTangent = normalize( transformedTangent );\n vBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n #endif\n#endif"; 22756var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n uniform sampler2D normalMap;\n uniform vec2 normalScale;\n#endif\n#ifdef USE_NORMALMAP_OBJECTSPACE\n uniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( USE_NORMALMAP_TANGENTSPACE ) || defined ( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY ) )\n mat3 getTangentFrame( vec3 eye_pos, vec3 surf_norm, vec2 uv ) {\n vec3 q0 = dFdx( eye_pos.xyz );\n vec3 q1 = dFdy( eye_pos.xyz );\n vec2 st0 = dFdx( uv.st );\n vec2 st1 = dFdy( uv.st );\n vec3 N = surf_norm;\n vec3 q1perp = cross( q1, N );\n vec3 q0perp = cross( N, q0 );\n vec3 T = q1perp * st0.x + q0perp * st1.x;\n vec3 B = q1perp * st0.y + q0perp * st1.y;\n float det = max( dot( T, T ), dot( B, B ) );\n float scale = ( det == 0.0 ) ? 0.0 : inversesqrt( det );\n return mat3( T * scale, B * scale, N );\n }\n#endif"; 22757var clearcoat_normal_fragment_begin = "#ifdef USE_CLEARCOAT\n vec3 clearcoatNormal = nonPerturbedNormal;\n#endif"; 22758var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n vec3 clearcoatMapN = texture2D( clearcoatNormalMap, vClearcoatNormalMapUv ).xyz * 2.0 - 1.0;\n clearcoatMapN.xy *= clearcoatNormalScale;\n clearcoatNormal = normalize( tbn2 * clearcoatMapN );\n#endif"; 22759var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n uniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n uniform sampler2D clearcoatNormalMap;\n uniform vec2 clearcoatNormalScale;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n uniform sampler2D clearcoatRoughnessMap;\n#endif"; 22760var iridescence_pars_fragment = "#ifdef USE_IRIDESCENCEMAP\n uniform sampler2D iridescenceMap;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n uniform sampler2D iridescenceThicknessMap;\n#endif"; 22761var opaque_fragment = "#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= material.transmissionAlpha;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );"; 22762var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n return normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n return 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;const float ShiftRight8 = 1. / 256.;\nconst float Inv255 = 1. / 255.;\nconst vec4 PackFactors = vec4( 1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0 );\nconst vec2 UnpackFactors2 = vec2( UnpackDownscale, 1.0 / PackFactors.g );\nconst vec3 UnpackFactors3 = vec3( UnpackDownscale / PackFactors.rg, 1.0 / PackFactors.b );\nconst vec4 UnpackFactors4 = vec4( UnpackDownscale / PackFactors.rgb, 1.0 / PackFactors.a );\nvec4 packDepthToRGBA( const in float v ) {\n if( v <= 0.0 )\n return vec4( 0., 0., 0., 0. );\n if( v >= 1.0 )\n return vec4( 1., 1., 1., 1. );\n float vuf;\n float af = modf( v * PackFactors.a, vuf );\n float bf = modf( vuf * ShiftRight8, vuf );\n float gf = modf( vuf * ShiftRight8, vuf );\n return vec4( vuf * Inv255, gf * PackUpscale, bf * PackUpscale, af );\n}\nvec3 packDepthToRGB( const in float v ) {\n if( v <= 0.0 )\n return vec3( 0., 0., 0. );\n if( v >= 1.0 )\n return vec3( 1., 1., 1. );\n float vuf;\n float bf = modf( v * PackFactors.b, vuf );\n float gf = modf( vuf * ShiftRight8, vuf );\n return vec3( vuf * Inv255, gf * PackUpscale, bf );\n}\nvec2 packDepthToRG( const in float v ) {\n if( v <= 0.0 )\n return vec2( 0., 0. );\n if( v >= 1.0 )\n return vec2( 1., 1. );\n float vuf;\n float gf = modf( v * 256., vuf );\n return vec2( vuf * Inv255, gf );\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n return dot( v, UnpackFactors4 );\n}\nfloat unpackRGBToDepth( const in vec3 v ) {\n return dot( v, UnpackFactors3 );\n}\nfloat unpackRGToDepth( const in vec2 v ) {\n return v.r * UnpackFactors2.r + v.g * UnpackFactors2.g;\n}\nvec4 pack2HalfToRGBA( const in vec2 v ) {\n vec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) );\n return vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );\n}\nvec2 unpackRGBATo2Half( const in vec4 v ) {\n return 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 return ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float depth, const in float near, const in float far ) {\n #ifdef USE_REVERSED_DEPTH_BUFFER\n \n return depth * ( far - near ) - far;\n #else\n return depth * ( near - far ) - near;\n #endif\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n return ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float depth, const in float near, const in float far ) {\n \n #ifdef USE_REVERSED_DEPTH_BUFFER\n return ( near * far ) / ( ( near - far ) * depth - near );\n #else\n return ( near * far ) / ( ( far - near ) * depth - far );\n #endif\n}"; 22763var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n gl_FragColor.rgb *= gl_FragColor.a;\n#endif"; 22764var project_vertex = "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_BATCHING\n mvPosition = batchingMatrix * mvPosition;\n#endif\n#ifdef USE_INSTANCING\n mvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;"; 22765var dithering_fragment = "#ifdef DITHERING\n gl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; 22766var dithering_pars_fragment = "#ifdef DITHERING\n vec3 dithering( vec3 color ) {\n float grid_position = rand( gl_FragCoord.xy );\n vec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n dither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n return color + dither_shift_RGB;\n }\n#endif"; 22767var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n vec4 texelRoughness = texture2D( roughnessMap, vRoughnessMapUv );\n roughnessFactor *= texelRoughness.g;\n#endif"; 22768var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n uniform sampler2D roughnessMap;\n#endif"; 22769var shadowmap_pars_fragment = "#if NUM_SPOT_LIGHT_COORDS > 0\n varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#if NUM_SPOT_LIGHT_MAPS > 0\n uniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ];\n#endif\n#ifdef USE_SHADOWMAP\n #if NUM_DIR_LIGHT_SHADOWS > 0\n #if defined( SHADOWMAP_TYPE_PCF )\n uniform sampler2DShadow directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n #else\n uniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n #endif\n varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n struct DirectionalLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n #endif\n #if NUM_SPOT_LIGHT_SHADOWS > 0\n #if defined( SHADOWMAP_TYPE_PCF )\n uniform sampler2DShadow spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n #else\n uniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n #endif\n struct SpotLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n #if defined( SHADOWMAP_TYPE_PCF )\n uniform samplerCubeShadow pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n #elif defined( SHADOWMAP_TYPE_BASIC )\n uniform samplerCube pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n #endif\n varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n struct PointLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n float shadowCameraNear;\n float shadowCameraFar;\n };\n uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n #endif\n #if defined( SHADOWMAP_TYPE_PCF )\n float interleavedGradientNoise( vec2 position ) {\n return fract( 52.9829189 * fract( dot( position, vec2( 0.06711056, 0.00583715 ) ) ) );\n }\n vec2 vogelDiskSample( int sampleIndex, int samplesCount, float phi ) {\n const float goldenAngle = 2.399963229728653;\n float r = sqrt( ( float( sampleIndex ) + 0.5 ) / float( samplesCount ) );\n float theta = float( sampleIndex ) * goldenAngle + phi;\n return vec2( cos( theta ), sin( theta ) ) * r;\n }\n #endif\n #if defined( SHADOWMAP_TYPE_PCF )\n float getShadow( sampler2DShadow shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n float shadow = 1.0;\n shadowCoord.xyz /= shadowCoord.w;\n shadowCoord.z += shadowBias;\n bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n bool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n if ( frustumTest ) {\n vec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n float radius = shadowRadius * texelSize.x;\n float phi = interleavedGradientNoise( gl_FragCoord.xy ) * PI2;\n shadow = (\n texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 0, 5, phi ) * radius, shadowCoord.z ) ) +\n texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 1, 5, phi ) * radius, shadowCoord.z ) ) +\n texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 2, 5, phi ) * radius, shadowCoord.z ) ) +\n texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 3, 5, phi ) * radius, shadowCoord.z ) ) +\n texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 4, 5, phi ) * radius, shadowCoord.z ) )\n ) * 0.2;\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n #elif defined( SHADOWMAP_TYPE_VSM )\n float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n float shadow = 1.0;\n shadowCoord.xyz /= shadowCoord.w;\n #ifdef USE_REVERSED_DEPTH_BUFFER\n shadowCoord.z -= shadowBias;\n #else\n shadowCoord.z += shadowBias;\n #endif\n bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n bool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n if ( frustumTest ) {\n vec2 distribution = texture2D( shadowMap, shadowCoord.xy ).rg;\n float mean = distribution.x;\n float variance = distribution.y * distribution.y;\n #ifdef USE_REVERSED_DEPTH_BUFFER\n float hard_shadow = step( mean, shadowCoord.z );\n #else\n float hard_shadow = step( shadowCoord.z, mean );\n #endif\n \n if ( hard_shadow == 1.0 ) {\n shadow = 1.0;\n } else {\n variance = max( variance, 0.0000001 );\n float d = shadowCoord.z - mean;\n float p_max = variance / ( variance + d * d );\n p_max = clamp( ( p_max - 0.3 ) / 0.65, 0.0, 1.0 );\n shadow = max( hard_shadow, p_max );\n }\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n #else\n float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n float shadow = 1.0;\n shadowCoord.xyz /= shadowCoord.w;\n #ifdef USE_REVERSED_DEPTH_BUFFER\n shadowCoord.z -= shadowBias;\n #else\n shadowCoord.z += shadowBias;\n #endif\n bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n bool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n if ( frustumTest ) {\n float depth = texture2D( shadowMap, shadowCoord.xy ).r;\n #ifdef USE_REVERSED_DEPTH_BUFFER\n shadow = step( depth, shadowCoord.z );\n #else\n shadow = step( shadowCoord.z, depth );\n #endif\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n #if defined( SHADOWMAP_TYPE_PCF )\n float getPointShadow( samplerCubeShadow shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n float shadow = 1.0;\n vec3 lightToPosition = shadowCoord.xyz;\n vec3 bd3D = normalize( lightToPosition );\n vec3 absVec = abs( lightToPosition );\n float viewSpaceZ = max( max( absVec.x, absVec.y ), absVec.z );\n if ( viewSpaceZ - shadowCameraFar <= 0.0 && viewSpaceZ - shadowCameraNear >= 0.0 ) {\n #ifdef USE_REVERSED_DEPTH_BUFFER\n float dp = ( shadowCameraNear * ( shadowCameraFar - viewSpaceZ ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );\n dp -= shadowBias;\n #else\n float dp = ( shadowCameraFar * ( viewSpaceZ - shadowCameraNear ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );\n dp += shadowBias;\n #endif\n float texelSize = shadowRadius / shadowMapSize.x;\n vec3 absDir = abs( bd3D );\n vec3 tangent = absDir.x > absDir.z ? vec3( 0.0, 1.0, 0.0 ) : vec3( 1.0, 0.0, 0.0 );\n tangent = normalize( cross( bd3D, tangent ) );\n vec3 bitangent = cross( bd3D, tangent );\n float phi = interleavedGradientNoise( gl_FragCoord.xy ) * PI2;\n vec2 sample0 = vogelDiskSample( 0, 5, phi );\n vec2 sample1 = vogelDiskSample( 1, 5, phi );\n vec2 sample2 = vogelDiskSample( 2, 5, phi );\n vec2 sample3 = vogelDiskSample( 3, 5, phi );\n vec2 sample4 = vogelDiskSample( 4, 5, phi );\n shadow = (\n texture( shadowMap, vec4( bd3D + ( tangent * sample0.x + bitangent * sample0.y ) * texelSize, dp ) ) +\n texture( shadowMap, vec4( bd3D + ( tangent * sample1.x + bitangent * sample1.y ) * texelSize, dp ) ) +\n texture( shadowMap, vec4( bd3D + ( tangent * sample2.x + bitangent * sample2.y ) * texelSize, dp ) ) +\n texture( shadowMap, vec4( bd3D + ( tangent * sample3.x + bitangent * sample3.y ) * texelSize, dp ) ) +\n texture( shadowMap, vec4( bd3D + ( tangent * sample4.x + bitangent * sample4.y ) * texelSize, dp ) )\n ) * 0.2;\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n #elif defined( SHADOWMAP_TYPE_BASIC )\n float getPointShadow( samplerCube shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n float shadow = 1.0;\n vec3 lightToPosition = shadowCoord.xyz;\n vec3 absVec = abs( lightToPosition );\n float viewSpaceZ = max( max( absVec.x, absVec.y ), absVec.z );\n if ( viewSpaceZ - shadowCameraFar <= 0.0 && viewSpaceZ - shadowCameraNear >= 0.0 ) {\n float dp = ( shadowCameraFar * ( viewSpaceZ - shadowCameraNear ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );\n dp += shadowBias;\n vec3 bd3D = normalize( lightToPosition );\n float depth = textureCube( shadowMap, bd3D ).r;\n #ifdef USE_REVERSED_DEPTH_BUFFER\n depth = 1.0 - depth;\n #endif\n shadow = step( dp, depth );\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n #endif\n #endif\n#endif"; 22770var shadowmap_pars_vertex = "#if NUM_SPOT_LIGHT_COORDS > 0\n uniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#ifdef USE_SHADOWMAP\n #if NUM_DIR_LIGHT_SHADOWS > 0\n uniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n struct DirectionalLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n #endif\n #if NUM_SPOT_LIGHT_SHADOWS > 0\n struct SpotLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n uniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n struct PointLightShadow {\n float shadowIntensity;\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n float shadowCameraNear;\n float shadowCameraFar;\n };\n uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n #endif\n#endif"; 22771var shadowmap_vertex = "#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n #ifdef HAS_NORMAL\n vec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n #else\n vec3 shadowWorldNormal = vec3( 0.0 );\n #endif\n vec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\n #if NUM_DIR_LIGHT_SHADOWS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n vDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n }\n #pragma unroll_loop_end\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n vPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n }\n #pragma unroll_loop_end\n #endif\n#endif\n#if NUM_SPOT_LIGHT_COORDS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n shadowWorldPosition = worldPosition;\n #if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n shadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n #endif\n vSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition;\n }\n #pragma unroll_loop_end\n#endif"; 22772var shadowmask_pars_fragment = "float getShadowMask() {\n float shadow = 1.0;\n #ifdef USE_SHADOWMAP\n #if NUM_DIR_LIGHT_SHADOWS > 0\n DirectionalLightShadow directionalLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n directionalLight = directionalLightShadows[ i ];\n shadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowIntensity, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n }\n #pragma unroll_loop_end\n #endif\n #if NUM_SPOT_LIGHT_SHADOWS > 0\n SpotLightShadow spotLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n spotLight = spotLightShadows[ i ];\n shadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowIntensity, spotLight.shadowBias, spotLight.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n }\n #pragma unroll_loop_end\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0 && ( defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_BASIC ) )\n PointLightShadow pointLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n pointLight = pointLightShadows[ i ];\n shadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowIntensity, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n }\n #pragma unroll_loop_end\n #endif\n #endif\n return shadow;\n}"; 22773var skinbase_vertex = "#ifdef USE_SKINNING\n mat4 boneMatX = getBoneMatrix( skinIndex.x );\n mat4 boneMatY = getBoneMatrix( skinIndex.y );\n mat4 boneMatZ = getBoneMatrix( skinIndex.z );\n mat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif"; 22774var skinning_pars_vertex = "#ifdef USE_SKINNING\n uniform mat4 bindMatrix;\n uniform mat4 bindMatrixInverse;\n uniform highp sampler2D boneTexture;\n mat4 getBoneMatrix( const in float i ) {\n int size = textureSize( boneTexture, 0 ).x;\n int j = int( i ) * 4;\n int x = j % size;\n int y = j / size;\n vec4 v1 = texelFetch( boneTexture, ivec2( x, y ), 0 );\n vec4 v2 = texelFetch( boneTexture, ivec2( x + 1, y ), 0 );\n vec4 v3 = texelFetch( boneTexture, ivec2( x + 2, y ), 0 );\n vec4 v4 = texelFetch( boneTexture, ivec2( x + 3, y ), 0 );\n return mat4( v1, v2, v3, v4 );\n }\n#endif"; 22775var skinning_vertex = "#ifdef USE_SKINNING\n vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n vec4 skinned = vec4( 0.0 );\n skinned += boneMatX * skinVertex * skinWeight.x;\n skinned += boneMatY * skinVertex * skinWeight.y;\n skinned += boneMatZ * skinVertex * skinWeight.z;\n skinned += boneMatW * skinVertex * skinWeight.w;\n transformed = ( bindMatrixInverse * skinned ).xyz;\n#endif"; 22776var skinnormal_vertex = "#ifdef USE_SKINNING\n mat4 skinMatrix = mat4( 0.0 );\n skinMatrix += skinWeight.x * boneMatX;\n skinMatrix += skinWeight.y * boneMatY;\n skinMatrix += skinWeight.z * boneMatZ;\n skinMatrix += skinWeight.w * boneMatW;\n skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n #ifdef USE_TANGENT\n objectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n #endif\n#endif"; 22777var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n vec4 texelSpecular = texture2D( specularMap, vSpecularMapUv );\n specularStrength = texelSpecular.r;\n#else\n specularStrength = 1.0;\n#endif"; 22778var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n uniform sampler2D specularMap;\n#endif"; 22779var tonemapping_fragment = "#if defined( TONE_MAPPING )\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif"; 22780var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n return saturate( toneMappingExposure * color );\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n color *= toneMappingExposure;\n return saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 CineonToneMapping( vec3 color ) {\n color *= toneMappingExposure;\n color = max( vec3( 0.0 ), color - 0.004 );\n return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n vec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n return a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n const mat3 ACESInputMat = mat3(\n vec3( 0.59719, 0.07600, 0.02840 ), vec3( 0.35458, 0.90834, 0.13383 ),\n vec3( 0.04823, 0.01566, 0.83777 )\n );\n const mat3 ACESOutputMat = mat3(\n vec3( 1.60475, -0.10208, -0.00327 ), vec3( -0.53108, 1.10813, -0.07276 ),\n vec3( -0.07367, -0.00605, 1.07602 )\n );\n color *= toneMappingExposure / 0.6;\n color = ACESInputMat * color;\n color = RRTAndODTFit( color );\n color = ACESOutputMat * color;\n return saturate( color );\n}\nconst mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(\n vec3( 1.6605, - 0.1246, - 0.0182 ),\n vec3( - 0.5876, 1.1329, - 0.1006 ),\n vec3( - 0.0728, - 0.0083, 1.1187 )\n);\nconst mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(\n vec3( 0.6274, 0.0691, 0.0164 ),\n vec3( 0.3293, 0.9195, 0.0880 ),\n vec3( 0.0433, 0.0113, 0.8956 )\n);\nvec3 agxDefaultContrastApprox( vec3 x ) {\n vec3 x2 = x * x;\n vec3 x4 = x2 * x2;\n return + 15.5 * x4 * x2\n - 40.14 * x4 * x\n + 31.96 * x4\n - 6.868 * x2 * x\n + 0.4298 * x2\n + 0.1191 * x\n - 0.00232;\n}\nvec3 AgXToneMapping( vec3 color ) {\n const mat3 AgXInsetMatrix = mat3(\n vec3( 0.856627153315983, 0.137318972929847, 0.11189821299995 ),\n vec3( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ),\n vec3( 0.0482516061458583, 0.101439036467562, 0.811302368396859 )\n );\n const mat3 AgXOutsetMatrix = mat3(\n vec3( 1.1271005818144368, - 0.1413297634984383, - 0.14132976349843826 ),\n vec3( - 0.11060664309660323, 1.157823702216272, - 0.11060664309660294 ),\n vec3( - 0.016493938717834573, - 0.016493938717834257, 1.2519364065950405 )\n );\n const float AgxMinEv = - 12.47393; const float AgxMaxEv = 4.026069;\n color *= toneMappingExposure;\n color = LINEAR_SRGB_TO_LINEAR_REC2020 * color;\n color = AgXInsetMatrix * color;\n color = max( color, 1e-10 ); color = log2( color );\n color = ( color - AgxMinEv ) / ( AgxMaxEv - AgxMinEv );\n color = clamp( color, 0.0, 1.0 );\n color = agxDefaultContrastApprox( color );\n color = AgXOutsetMatrix * color;\n color = pow( max( vec3( 0.0 ), color ), vec3( 2.2 ) );\n color = LINEAR_REC2020_TO_LINEAR_SRGB * color;\n color = clamp( color, 0.0, 1.0 );\n return color;\n}\nvec3 NeutralToneMapping( vec3 color ) {\n const float StartCompression = 0.8 - 0.04;\n const float Desaturation = 0.15;\n color *= toneMappingExposure;\n float x = min( color.r, min( color.g, color.b ) );\n float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;\n color -= offset;\n float peak = max( color.r, max( color.g, color.b ) );\n if ( peak < StartCompression ) return color;\n float d = 1. - StartCompression;\n float newPeak = 1. - d * d / ( peak + d - StartCompression );\n color *= newPeak / peak;\n float g = 1. - 1. / ( Desaturation * ( peak - newPeak ) + 1. );\n return mix( color, vec3( newPeak ), g );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }"; 22781var transmission_fragment = "#ifdef USE_TRANSMISSION\n material.transmission = transmission;\n material.transmissionAlpha = 1.0;\n material.thickness = thickness;\n material.attenuationDistance = attenuationDistance;\n material.attenuationColor = attenuationColor;\n #ifdef USE_TRANSMISSIONMAP\n material.transmission *= texture2D( transmissionMap, vTransmissionMapUv ).r;\n #endif\n #ifdef USE_THICKNESSMAP\n material.thickness *= texture2D( thicknessMap, vThicknessMapUv ).g;\n #endif\n vec3 pos = vWorldPosition;\n vec3 v = normalize( cameraPosition - pos );\n vec3 n = inverseTransformDirection( normal, viewMatrix );\n vec4 transmitted = getIBLVolumeRefraction(\n n, v, material.roughness, material.diffuseContribution, material.specularColorBlended, material.specularF90,\n pos, modelMatrix, viewMatrix, projectionMatrix, material.dispersion, material.ior, material.thickness,\n material.attenuationColor, material.attenuationDistance );\n material.transmissionAlpha = mix( material.transmissionAlpha, transmitted.a, material.transmission );\n totalDiffuse = mix( totalDiffuse, transmitted.rgb, material.transmission );\n#endif"; 22782var transmission_pars_fragment = "#ifdef USE_TRANSMISSION\n uniform float transmission;\n uniform float thickness;\n uniform float attenuationDistance;\n uniform vec3 attenuationColor;\n #ifdef USE_TRANSMISSIONMAP\n uniform sampler2D transmissionMap;\n #endif\n #ifdef USE_THICKNESSMAP\n uniform sampler2D thicknessMap;\n #endif\n uniform vec2 transmissionSamplerSize;\n uniform sampler2D transmissionSamplerMap;\n uniform mat4 modelMatrix;\n uniform mat4 projectionMatrix;\n varying vec3 vWorldPosition;\n float w0( float a ) {\n return ( 1.0 / 6.0 ) * ( a * ( a * ( - a + 3.0 ) - 3.0 ) + 1.0 );\n }\n float w1( float a ) {\n return ( 1.0 / 6.0 ) * ( a * a * ( 3.0 * a - 6.0 ) + 4.0 );\n }\n float w2( float a ){\n return ( 1.0 / 6.0 ) * ( a * ( a * ( - 3.0 * a + 3.0 ) + 3.0 ) + 1.0 );\n }\n float w3( float a ) {\n return ( 1.0 / 6.0 ) * ( a * a * a );\n }\n float g0( float a ) {\n return w0( a ) + w1( a );\n }\n float g1( float a ) {\n return w2( a ) + w3( a );\n }\n float h0( float a ) {\n return - 1.0 + w1( a ) / ( w0( a ) + w1( a ) );\n }\n float h1( float a ) {\n return 1.0 + w3( a ) / ( w2( a ) + w3( a ) );\n }\n vec4 bicubic( sampler2D tex, vec2 uv, vec4 texelSize, float lod ) {\n uv = uv * texelSize.zw + 0.5;\n vec2 iuv = floor( uv );\n vec2 fuv = fract( uv );\n float g0x = g0( fuv.x );\n float g1x = g1( fuv.x );\n float h0x = h0( fuv.x );\n float h1x = h1( fuv.x );\n float h0y = h0( fuv.y );\n float h1y = h1( fuv.y );\n vec2 p0 = ( vec2( iuv.x + h0x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n vec2 p1 = ( vec2( iuv.x + h1x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n vec2 p2 = ( vec2( iuv.x + h0x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n vec2 p3 = ( vec2( iuv.x + h1x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n return g0( fuv.y ) * ( g0x * textureLod( tex, p0, lod ) + g1x * textureLod( tex, p1, lod ) ) +\n g1( fuv.y ) * ( g0x * textureLod( tex, p2, lod ) + g1x * textureLod( tex, p3, lod ) );\n }\n vec4 textureBicubic( sampler2D sampler, vec2 uv, float lod ) {\n vec2 fLodSize = vec2( textureSize( sampler, int( lod ) ) );\n vec2 cLodSize = vec2( textureSize( sampler, int( lod + 1.0 ) ) );\n vec2 fLodSizeInv = 1.0 / fLodSize;\n vec2 cLodSizeInv = 1.0 / cLodSize;\n vec4 fSample = bicubic( sampler, uv, vec4( fLodSizeInv, fLodSize ), floor( lod ) );\n vec4 cSample = bicubic( sampler, uv, vec4( cLodSizeInv, cLodSize ), ceil( lod ) );\n return mix( fSample, cSample, fract( lod ) );\n }\n vec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n vec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n vec3 modelScale;\n modelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n modelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n modelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n return normalize( refractionVector ) * thickness * modelScale;\n }\n float applyIorToRoughness( const in float roughness, const in float ior ) {\n return roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n }\n vec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n float lod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n return textureBicubic( transmissionSamplerMap, fragCoord.xy, lod );\n }\n vec3 volumeAttenuation( const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n if ( isinf( attenuationDistance ) ) {\n return vec3( 1.0 );\n } else {\n vec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n vec3 transmittance = exp( - attenuationCoefficient * transmissionDistance ); return transmittance;\n }\n }\n vec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n const in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n const in mat4 viewMatrix, const in mat4 projMatrix, const in float dispersion, const in float ior, const in float thickness,\n const in vec3 attenuationColor, const in float attenuationDistance ) {\n vec4 transmittedLight;\n vec3 transmittance;\n #ifdef USE_DISPERSION\n float halfSpread = ( ior - 1.0 ) * 0.025 * dispersion;\n vec3 iors = vec3( ior - halfSpread, ior, ior + halfSpread );\n for ( int i = 0; i < 3; i ++ ) {\n vec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, iors[ i ], modelMatrix );\n vec3 refractedRayExit = position + transmissionRay;\n vec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n vec2 refractionCoords = ndcPos.xy / ndcPos.w;\n refractionCoords += 1.0;\n refractionCoords /= 2.0;\n vec4 transmissionSample = getTransmissionSample( refractionCoords, roughness, iors[ i ] );\n transmittedLight[ i ] = transmissionSample[ i ];\n transmittedLight.a += transmissionSample.a;\n transmittance[ i ] = diffuseColor[ i ] * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance )[ i ];\n }\n transmittedLight.a /= 3.0;\n #else\n vec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n vec3 refractedRayExit = position + transmissionRay;\n vec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n vec2 refractionCoords = ndcPos.xy / ndcPos.w;\n refractionCoords += 1.0;\n refractionCoords /= 2.0;\n transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n transmittance = diffuseColor * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance );\n #endif\n vec3 attenuatedColor = transmittance * transmittedLight.rgb;\n vec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n float transmittanceFactor = ( transmittance.r + transmittance.g + transmittance.b ) / 3.0;\n return vec4( ( 1.0 - F ) * attenuatedColor, 1.0 - ( 1.0 - transmittedLight.a ) * transmittanceFactor );\n }\n#endif"; 22783var uv_pars_fragment = "#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n varying vec2 vUv;\n#endif\n#ifdef USE_MAP\n varying vec2 vMapUv;\n#endif\n#ifdef USE_ALPHAMAP\n varying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n varying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n varying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n varying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n varying vec2 vNormalMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n varying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n varying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n varying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n varying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n varying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n varying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n varying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n varying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n varying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n varying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n varying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n varying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n varying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n varying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n uniform mat3 transmissionMapTransform;\n varying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n uniform mat3 thicknessMapTransform;\n varying vec2 vThicknessMapUv;\n#endif"; 22784var uv_pars_vertex = "#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n varying vec2 vUv;\n#endif\n#ifdef USE_MAP\n uniform mat3 mapTransform;\n varying vec2 vMapUv;\n#endif\n#ifdef USE_ALPHAMAP\n uniform mat3 alphaMapTransform;\n varying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n uniform mat3 lightMapTransform;\n varying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n uniform mat3 aoMapTransform;\n varying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n uniform mat3 bumpMapTransform;\n varying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n uniform mat3 normalMapTransform;\n varying vec2 vNormalMapUv;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n uniform mat3 displacementMapTransform;\n varying vec2 vDisplacementMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n uniform mat3 emissiveMapTransform;\n varying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n uniform mat3 metalnessMapTransform;\n varying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n uniform mat3 roughnessMapTransform;\n varying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n uniform mat3 anisotropyMapTransform;\n varying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n uniform mat3 clearcoatMapTransform;\n varying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n uniform mat3 clearcoatNormalMapTransform;\n varying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n uniform mat3 clearcoatRoughnessMapTransform;\n varying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n uniform mat3 sheenColorMapTransform;\n varying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n uniform mat3 sheenRoughnessMapTransform;\n varying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n uniform mat3 iridescenceMapTransform;\n varying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n uniform mat3 iridescenceThicknessMapTransform;\n varying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n uniform mat3 specularMapTransform;\n varying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n uniform mat3 specularColorMapTransform;\n varying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n uniform mat3 specularIntensityMapTransform;\n varying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n uniform mat3 transmissionMapTransform;\n varying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n uniform mat3 thicknessMapTransform;\n varying vec2 vThicknessMapUv;\n#endif"; 22785var uv_vertex = "#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n vUv = vec3( uv, 1 ).xy;\n#endif\n#ifdef USE_MAP\n vMapUv = ( mapTransform * vec3( MAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ALPHAMAP\n vAlphaMapUv = ( alphaMapTransform * vec3( ALPHAMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_LIGHTMAP\n vLightMapUv = ( lightMapTransform * vec3( LIGHTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_AOMAP\n vAoMapUv = ( aoMapTransform * vec3( AOMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_BUMPMAP\n vBumpMapUv = ( bumpMapTransform * vec3( BUMPMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_NORMALMAP\n vNormalMapUv = ( normalMapTransform * vec3( NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n vDisplacementMapUv = ( displacementMapTransform * vec3( DISPLACEMENTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_EMISSIVEMAP\n vEmissiveMapUv = ( emissiveMapTransform * vec3( EMISSIVEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_METALNESSMAP\n vMetalnessMapUv = ( metalnessMapTransform * vec3( METALNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ROUGHNESSMAP\n vRoughnessMapUv = ( roughnessMapTransform * vec3( ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ANISOTROPYMAP\n vAnisotropyMapUv = ( anisotropyMapTransform * vec3( ANISOTROPYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOATMAP\n vClearcoatMapUv = ( clearcoatMapTransform * vec3( CLEARCOATMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n vClearcoatNormalMapUv = ( clearcoatNormalMapTransform * vec3( CLEARCOAT_NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n vClearcoatRoughnessMapUv = ( clearcoatRoughnessMapTransform * vec3( CLEARCOAT_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n vIridescenceMapUv = ( iridescenceMapTransform * vec3( IRIDESCENCEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n vIridescenceThicknessMapUv = ( iridescenceThicknessMapTransform * vec3( IRIDESCENCE_THICKNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n vSheenColorMapUv = ( sheenColorMapTransform * vec3( SHEEN_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n vSheenRoughnessMapUv = ( sheenRoughnessMapTransform * vec3( SHEEN_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULARMAP\n vSpecularMapUv = ( specularMapTransform * vec3( SPECULARMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n vSpecularColorMapUv = ( specularColorMapTransform * vec3( SPECULAR_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n vSpecularIntensityMapUv = ( specularIntensityMapTransform * vec3( SPECULAR_INTENSITYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n vTransmissionMapUv = ( transmissionMapTransform * vec3( TRANSMISSIONMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_THICKNESSMAP\n vThicknessMapUv = ( thicknessMapTransform * vec3( THICKNESSMAP_UV, 1 ) ).xy;\n#endif"; 22786var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0\n vec4 worldPosition = vec4( transformed, 1.0 );\n #ifdef USE_BATCHING\n worldPosition = batchingMatrix * worldPosition;\n #endif\n #ifdef USE_INSTANCING\n worldPosition = instanceMatrix * worldPosition;\n #endif\n worldPosition = modelMatrix * worldPosition;\n#endif"; 22787var vertex$h = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n vUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n gl_Position = vec4( position.xy, 1.0, 1.0 );\n}"; 22788var fragment$h = "uniform sampler2D t2D;\nuniform float backgroundIntensity;\nvarying vec2 vUv;\nvoid main() {\n vec4 texColor = texture2D( t2D, vUv );\n #ifdef DECODE_VIDEO_TEXTURE\n texColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w );\n #endif\n texColor.rgb *= backgroundIntensity;\n gl_FragColor = texColor;\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}"; 22789var vertex$g = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n vWorldDirection = transformDirection( position, modelMatrix );\n #include <begin_vertex>\n #include <project_vertex>\n gl_Position.z = gl_Position.w;\n}"; 22790var fragment$g = "#ifdef ENVMAP_TYPE_CUBE\n uniform samplerCube envMap;\n#elif defined( ENVMAP_TYPE_CUBE_UV )\n uniform sampler2D envMap;\n#endif\nuniform float backgroundBlurriness;\nuniform float backgroundIntensity;\nuniform mat3 backgroundRotation;\nvarying vec3 vWorldDirection;\n#include <cube_uv_reflection_fragment>\nvoid main() {\n #ifdef ENVMAP_TYPE_CUBE\n vec4 texColor = textureCube( envMap, backgroundRotation * vWorldDirection );\n #elif defined( ENVMAP_TYPE_CUBE_UV )\n vec4 texColor = textureCubeUV( envMap, backgroundRotation * vWorldDirection, backgroundBlurriness );\n #else\n vec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n #endif\n texColor.rgb *= backgroundIntensity;\n gl_FragColor = texColor;\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}"; 22791var vertex$f = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n vWorldDirection = transformDirection( position, modelMatrix );\n #include <begin_vertex>\n #include <project_vertex>\n gl_Position.z = gl_Position.w;\n}"; 22792var fragment$f = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n vec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n gl_FragColor = texColor;\n gl_FragColor.a *= opacity;\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}"; 22793var vertex$e = "#include <common>\n#include <batching_pars_vertex>\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 #include <uv_vertex>\n #include <batching_vertex>\n #include <skinbase_vertex>\n #include <morphinstance_vertex>\n #ifdef USE_DISPLACEMENTMAP\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinnormal_vertex>\n #endif\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n vHighPrecisionZW = gl_Position.zw;\n}"; 22794var fragment$e = "#if DEPTH_PACKING == 3200\n uniform 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 <alphahash_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n vec4 diffuseColor = vec4( 1.0 );\n #include <clipping_planes_fragment>\n #if DEPTH_PACKING == 3200\n diffuseColor.a = opacity;\n #endif\n #include <map_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <logdepthbuf_fragment>\n #ifdef USE_REVERSED_DEPTH_BUFFER\n float fragCoordZ = vHighPrecisionZW[ 0 ] / vHighPrecisionZW[ 1 ];\n #else\n float fragCoordZ = 0.5 * vHighPrecisionZW[ 0 ] / vHighPrecisionZW[ 1 ] + 0.5;\n #endif\n #if DEPTH_PACKING == 3200\n gl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n #elif DEPTH_PACKING == 3201\n gl_FragColor = packDepthToRGBA( fragCoordZ );\n #elif DEPTH_PACKING == 3202\n gl_FragColor = vec4( packDepthToRGB( fragCoordZ ), 1.0 );\n #elif DEPTH_PACKING == 3203\n gl_FragColor = vec4( packDepthToRG( fragCoordZ ), 0.0, 1.0 );\n #endif\n}"; 22795var vertex$d = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <batching_pars_vertex>\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 #include <uv_vertex>\n #include <batching_vertex>\n #include <skinbase_vertex>\n #include <morphinstance_vertex>\n #ifdef USE_DISPLACEMENTMAP\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinnormal_vertex>\n #endif\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <worldpos_vertex>\n #include <clipping_planes_vertex>\n vWorldPosition = worldPosition.xyz;\n}"; 22796var fragment$d = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\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 <alphahash_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n vec4 diffuseColor = vec4( 1.0 );\n #include <clipping_planes_fragment>\n #include <map_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n float dist = length( vWorldPosition - referencePosition );\n dist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n dist = saturate( dist );\n gl_FragColor = vec4( dist, 0.0, 0.0, 1.0 );\n}"; 22797var vertex$c = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n vWorldDirection = transformDirection( position, modelMatrix );\n #include <begin_vertex>\n #include <project_vertex>\n}"; 22798var fragment$c = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n vec3 direction = normalize( vWorldDirection );\n vec2 sampleUV = equirectUv( direction );\n gl_FragColor = texture2D( tEquirect, sampleUV );\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}"; 22799var vertex$b = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <uv_pars_vertex>\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 vLineDistance = scale * lineDistance;\n #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n #include <fog_vertex>\n}"; 22800var 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 <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n if ( mod( vLineDistance, totalSize ) > dashSize ) {\n discard;\n }\n vec3 outgoingLight = vec3( 0.0 );\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n outgoingLight = diffuseColor.rgb;\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n}"; 22801var vertex$a = "#include <common>\n#include <batching_pars_vertex>\n#include <uv_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 #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n #if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #endif\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n #include <worldpos_vertex>\n #include <envmap_vertex>\n #include <fog_vertex>\n}"; 22802var fragment$a = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n varying vec3 vNormal;\n#endif\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_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 <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <specularmap_fragment>\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n #ifdef USE_LIGHTMAP\n vec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n reflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\n #else\n reflectedLight.indirectDiffuse += vec3( 1.0 );\n #endif\n #include <aomap_fragment>\n reflectedLight.indirectDiffuse *= diffuseColor.rgb;\n vec3 outgoingLight = reflectedLight.indirectDiffuse;\n #include <envmap_fragment>\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}"; 22803var vertex$9 = "#define LAMBERT\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_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 #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <normal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n vViewPosition = - mvPosition.xyz;\n #include <worldpos_vertex>\n #include <envmap_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n}"; 22804var fragment$9 = "#define LAMBERT\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\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 <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_lambert_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 vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <specularmap_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n #include <emissivemap_fragment>\n #include <lights_lambert_fragment>\n #include <lights_fragment_begin>\n #include <lights_fragment_maps>\n #include <lights_fragment_end>\n #include <aomap_fragment>\n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n #include <envmap_fragment>\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}"; 22805var vertex$8 = "#define MATCAP\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\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 #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <normal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n #include <fog_vertex>\n vViewPosition = - mvPosition.xyz;\n}"; 22806var 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 <alphahash_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 vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n vec3 viewDir = normalize( vViewPosition );\n vec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n vec3 y = cross( viewDir, x );\n vec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n #ifdef USE_MATCAP\n vec4 matcapColor = texture2D( matcap, uv );\n #else\n vec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );\n #endif\n vec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}"; 22807var vertex$7 = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n varying vec3 vViewPosition;\n#endif\n#include <common>\n#include <batching_pars_vertex>\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 #include <uv_vertex>\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphinstance_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <normal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n vViewPosition = - mvPosition.xyz;\n#endif\n}"; 22808var fragment$7 = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n varying vec3 vViewPosition;\n#endif\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 vec4 diffuseColor = vec4( 0.0, 0.0, 0.0, opacity );\n #include <clipping_planes_fragment>\n #include <logdepthbuf_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n gl_FragColor = vec4( normalize( normal ) * 0.5 + 0.5, diffuseColor.a );\n #ifdef OPAQUE\n gl_FragColor.a = 1.0;\n #endif\n}"; 22809var vertex$6 = "#define PHONG\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_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 #include <uv_vertex>\n #include <color_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphinstance_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <normal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n vViewPosition = - mvPosition.xyz;\n #include <worldpos_vertex>\n #include <envmap_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n}"; 22810var fragment$6 = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\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 <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <envmap_physical_pars_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 vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <specularmap_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n #include <emissivemap_fragment>\n #include <lights_phong_fragment>\n #include <lights_fragment_begin>\n #include <lights_fragment_maps>\n #include <lights_fragment_end>\n #include <aomap_fragment>\n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n #include <envmap_fragment>\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}"; 22811var vertex$5 = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n varying vec3 vWorldPosition;\n#endif\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_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 #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <normal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n vViewPosition = - mvPosition.xyz;\n #include <worldpos_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n#ifdef USE_TRANSMISSION\n vWorldPosition = worldPosition.xyz;\n#endif\n}"; 22812var fragment$5 = "#define STANDARD\n#ifdef PHYSICAL\n #define IOR\n #define USE_SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n uniform float ior;\n#endif\n#ifdef USE_SPECULAR\n uniform float specularIntensity;\n uniform vec3 specularColor;\n #ifdef USE_SPECULAR_COLORMAP\n uniform sampler2D specularColorMap;\n #endif\n #ifdef USE_SPECULAR_INTENSITYMAP\n uniform sampler2D specularIntensityMap;\n #endif\n#endif\n#ifdef USE_CLEARCOAT\n uniform float clearcoat;\n uniform float clearcoatRoughness;\n#endif\n#ifdef USE_DISPERSION\n uniform float dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n uniform float iridescence;\n uniform float iridescenceIOR;\n uniform float iridescenceThicknessMinimum;\n uniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n uniform vec3 sheenColor;\n uniform float sheenRoughness;\n #ifdef USE_SHEEN_COLORMAP\n uniform sampler2D sheenColorMap;\n #endif\n #ifdef USE_SHEEN_ROUGHNESSMAP\n uniform sampler2D sheenRoughnessMap;\n #endif\n#endif\n#ifdef USE_ANISOTROPY\n uniform vec2 anisotropyVector;\n #ifdef USE_ANISOTROPYMAP\n uniform sampler2D anisotropyMap;\n #endif\n#endif\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 <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <iridescence_fragment>\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 <iridescence_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 vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <roughnessmap_fragment>\n #include <metalnessmap_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n #include <clearcoat_normal_fragment_begin>\n #include <clearcoat_normal_fragment_maps>\n #include <emissivemap_fragment>\n #include <lights_physical_fragment>\n #include <lights_fragment_begin>\n #include <lights_fragment_maps>\n #include <lights_fragment_end>\n #include <aomap_fragment>\n vec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n vec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n #include <transmission_fragment>\n vec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n #ifdef USE_SHEEN\n \n outgoingLight = outgoingLight + sheenSpecularDirect + sheenSpecularIndirect;\n \n #endif\n #ifdef USE_CLEARCOAT\n float dotNVcc = saturate( dot( geometryClearcoatNormal, geometryViewDir ) );\n vec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n outgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + ( clearcoatSpecularDirect + clearcoatSpecularIndirect ) * material.clearcoat;\n #endif\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}"; 22813var vertex$4 = "#define TOON\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_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 #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <normal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n vViewPosition = - mvPosition.xyz;\n #include <worldpos_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n}"; 22814var fragment$4 = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\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 <alphahash_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 vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n #include <emissivemap_fragment>\n #include <lights_toon_fragment>\n #include <lights_fragment_begin>\n #include <lights_fragment_maps>\n #include <lights_fragment_end>\n #include <aomap_fragment>\n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}"; 22815var 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>\n#ifdef USE_POINTS_UV\n varying vec2 vUv;\n uniform mat3 uvTransform;\n#endif\nvoid main() {\n #ifdef USE_POINTS_UV\n vUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n #endif\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <project_vertex>\n gl_PointSize = size;\n #ifdef USE_SIZEATTENUATION\n bool isPerspective = isPerspectiveMatrix( projectionMatrix );\n if ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n #endif\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n #include <worldpos_vertex>\n #include <fog_vertex>\n}"; 22816var 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 <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n vec3 outgoingLight = vec3( 0.0 );\n #include <logdepthbuf_fragment>\n #include <map_particle_fragment>\n #include <color_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n outgoingLight = diffuseColor.rgb;\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n}"; 22817var vertex$2 = "#include <common>\n#include <batching_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <shadowmap_pars_vertex>\nvoid main() {\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphinstance_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <worldpos_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n}"; 22818var fragment$2 = "uniform vec3 color;\nuniform float opacity;\n#include <common>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <logdepthbuf_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n #include <logdepthbuf_fragment>\n gl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n}"; 22819var 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 #include <uv_vertex>\n vec4 mvPosition = modelViewMatrix[ 3 ];\n vec2 scale = vec2( length( modelMatrix[ 0 ].xyz ), length( modelMatrix[ 1 ].xyz ) );\n #ifndef USE_SIZEATTENUATION\n bool isPerspective = isPerspectiveMatrix( projectionMatrix );\n if ( isPerspective ) scale *= - mvPosition.z;\n #endif\n vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n vec2 rotatedPosition;\n rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n mvPosition.xy += rotatedPosition;\n gl_Position = projectionMatrix * mvPosition;\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n #include <fog_vertex>\n}"; 22820var 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 <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n vec3 outgoingLight = vec3( 0.0 );\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n outgoingLight = diffuseColor.rgb;\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n}"; 22821var ShaderChunk = { 22822 alphahash_fragment, 22823 alphahash_pars_fragment, 22824 alphamap_fragment, 22825 alphamap_pars_fragment, 22826 alphatest_fragment, 22827 alphatest_pars_fragment, 22828 aomap_fragment, 22829 aomap_pars_fragment, 22830 batching_pars_vertex, 22831 batching_vertex, 22832 begin_vertex, 22833 beginnormal_vertex, 22834 bsdfs, 22835 iridescence_fragment, 22836 bumpmap_pars_fragment, 22837 clipping_planes_fragment, 22838 clipping_planes_pars_fragment, 22839 clipping_planes_pars_vertex, 22840 clipping_planes_vertex, 22841 color_fragment, 22842 color_pars_fragment, 22843 color_pars_vertex, 22844 color_vertex, 22845 common, 22846 cube_uv_reflection_fragment, 22847 defaultnormal_vertex, 22848 displacementmap_pars_vertex, 22849 displacementmap_vertex, 22850 emissivemap_fragment, 22851 emissivemap_pars_fragment, 22852 colorspace_fragment, 22853 colorspace_pars_fragment, 22854 envmap_fragment, 22855 envmap_common_pars_fragment, 22856 envmap_pars_fragment, 22857 envmap_pars_vertex, 22858 envmap_physical_pars_fragment, 22859 envmap_vertex, 22860 fog_vertex, 22861 fog_pars_vertex, 22862 fog_fragment, 22863 fog_pars_fragment, 22864 gradientmap_pars_fragment, 22865 lightmap_pars_fragment, 22866 lights_lambert_fragment, 22867 lights_lambert_pars_fragment, 22868 lights_pars_begin, 22869 lights_toon_fragment, 22870 lights_toon_pars_fragment, 22871 lights_phong_fragment, 22872 lights_phong_pars_fragment, 22873 lights_physical_fragment, 22874 lights_physical_pars_fragment, 22875 lights_fragment_begin, 22876 lights_fragment_maps, 22877 lights_fragment_end, 22878 lightprobes_pars_fragment, 22879 logdepthbuf_fragment, 22880 logdepthbuf_pars_fragment, 22881 logdepthbuf_pars_vertex, 22882 logdepthbuf_vertex, 22883 map_fragment, 22884 map_pars_fragment, 22885 map_particle_fragment, 22886 map_particle_pars_fragment, 22887 metalnessmap_fragment, 22888 metalnessmap_pars_fragment, 22889 morphinstance_vertex, 22890 morphcolor_vertex, 22891 morphnormal_vertex, 22892 morphtarget_pars_vertex, 22893 morphtarget_vertex, 22894 normal_fragment_begin, 22895 normal_fragment_maps, 22896 normal_pars_fragment, 22897 normal_pars_vertex, 22898 normal_vertex, 22899 normalmap_pars_fragment, 22900 clearcoat_normal_fragment_begin, 22901 clearcoat_normal_fragment_maps, 22902 clearcoat_pars_fragment, 22903 iridescence_pars_fragment, 22904 opaque_fragment, 22905 packing, 22906 premultiplied_alpha_fragment, 22907 project_vertex, 22908 dithering_fragment, 22909 dithering_pars_fragment, 22910 roughnessmap_fragment, 22911 roughnessmap_pars_fragment, 22912 shadowmap_pars_fragment, 22913 shadowmap_pars_vertex, 22914 shadowmap_vertex, 22915 shadowmask_pars_fragment, 22916 skinbase_vertex, 22917 skinning_pars_vertex, 22918 skinning_vertex, 22919 skinnormal_vertex, 22920 specularmap_fragment, 22921 specularmap_pars_fragment, 22922 tonemapping_fragment, 22923 tonemapping_pars_fragment, 22924 transmission_fragment, 22925 transmission_pars_fragment, 22926 uv_pars_fragment, 22927 uv_pars_vertex, 22928 uv_vertex, 22929 worldpos_vertex, 22930 background_vert: vertex$h, 22931 background_frag: fragment$h, 22932 backgroundCube_vert: vertex$g, 22933 backgroundCube_frag: fragment$g, 22934 cube_vert: vertex$f, 22935 cube_frag: fragment$f, 22936 depth_vert: vertex$e, 22937 depth_frag: fragment$e, 22938 distance_vert: vertex$d, 22939 distance_frag: fragment$d, 22940 equirect_vert: vertex$c, 22941 equirect_frag: fragment$c, 22942 linedashed_vert: vertex$b, 22943 linedashed_frag: fragment$b, 22944 meshbasic_vert: vertex$a, 22945 meshbasic_frag: fragment$a, 22946 meshlambert_vert: vertex$9, 22947 meshlambert_frag: fragment$9, 22948 meshmatcap_vert: vertex$8, 22949 meshmatcap_frag: fragment$8, 22950 meshnormal_vert: vertex$7, 22951 meshnormal_frag: fragment$7, 22952 meshphong_vert: vertex$6, 22953 meshphong_frag: fragment$6, 22954 meshphysical_vert: vertex$5, 22955 meshphysical_frag: fragment$5, 22956 meshtoon_vert: vertex$4, 22957 meshtoon_frag: fragment$4, 22958 points_vert: vertex$3, 22959 points_frag: fragment$3, 22960 shadow_vert: vertex$2, 22961 shadow_frag: fragment$2, 22962 sprite_vert: vertex$1, 22963 sprite_frag: fragment$1 22964}; 22965var UniformsLib = { 22966 common: { 22967 diffuse: { value: /* @__PURE__ */ new Color(16777215) }, 22968 opacity: { value: 1 }, 22969 map: { value: null }, 22970 mapTransform: { value: /* @__PURE__ */ new Matrix3() }, 22971 alphaMap: { value: null }, 22972 alphaMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 22973 alphaTest: { value: 0 } 22974 }, 22975 specularmap: { 22976 specularMap: { value: null }, 22977 specularMapTransform: { value: /* @__PURE__ */ new Matrix3() } 22978 }, 22979 envmap: { 22980 envMap: { value: null }, 22981 envMapRotation: { value: /* @__PURE__ */ new Matrix3() }, 22982 reflectivity: { value: 1 }, 22983 // basic, lambert, phong 22984 ior: { value: 1.5 }, 22985 // physical 22986 refractionRatio: { value: 0.98 }, 22987 // basic, lambert, phong 22988 dfgLUT: { value: null } 22989 // DFG LUT for physically-based rendering 22990 }, 22991 aomap: { 22992 aoMap: { value: null }, 22993 aoMapIntensity: { value: 1 }, 22994 aoMapTransform: { value: /* @__PURE__ */ new Matrix3() } 22995 }, 22996 lightmap: { 22997 lightMap: { value: null }, 22998 lightMapIntensity: { value: 1 }, 22999 lightMapTransform: { value: /* @__PURE__ */ new Matrix3() } 23000 }, 23001 bumpmap: { 23002 bumpMap: { value: null }, 23003 bumpMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23004 bumpScale: { value: 1 } 23005 }, 23006 normalmap: { 23007 normalMap: { value: null }, 23008 normalMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23009 normalScale: { value: /* @__PURE__ */ new Vector2(1, 1) } 23010 }, 23011 displacementmap: { 23012 displacementMap: { value: null }, 23013 displacementMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23014 displacementScale: { value: 1 }, 23015 displacementBias: { value: 0 } 23016 }, 23017 emissivemap: { 23018 emissiveMap: { value: null }, 23019 emissiveMapTransform: { value: /* @__PURE__ */ new Matrix3() } 23020 }, 23021 metalnessmap: { 23022 metalnessMap: { value: null }, 23023 metalnessMapTransform: { value: /* @__PURE__ */ new Matrix3() } 23024 }, 23025 roughnessmap: { 23026 roughnessMap: { value: null }, 23027 roughnessMapTransform: { value: /* @__PURE__ */ new Matrix3() } 23028 }, 23029 gradientmap: { 23030 gradientMap: { value: null } 23031 }, 23032 fog: { 23033 fogDensity: { value: 25e-5 }, 23034 fogNear: { value: 1 }, 23035 fogFar: { value: 2e3 }, 23036 fogColor: { value: /* @__PURE__ */ new Color(16777215) } 23037 }, 23038 lights: { 23039 ambientLightColor: { value: [] }, 23040 lightProbe: { value: [] }, 23041 directionalLights: { value: [], properties: { 23042 direction: {}, 23043 color: {} 23044 } }, 23045 directionalLightShadows: { value: [], properties: { 23046 shadowIntensity: 1, 23047 shadowBias: {}, 23048 shadowNormalBias: {}, 23049 shadowRadius: {}, 23050 shadowMapSize: {} 23051 } }, 23052 directionalShadowMatrix: { value: [] }, 23053 spotLights: { value: [], properties: { 23054 color: {}, 23055 position: {}, 23056 direction: {}, 23057 distance: {}, 23058 coneCos: {}, 23059 penumbraCos: {}, 23060 decay: {} 23061 } }, 23062 spotLightShadows: { value: [], properties: { 23063 shadowIntensity: 1, 23064 shadowBias: {}, 23065 shadowNormalBias: {}, 23066 shadowRadius: {}, 23067 shadowMapSize: {} 23068 } }, 23069 spotLightMap: { value: [] }, 23070 spotLightMatrix: { value: [] }, 23071 pointLights: { value: [], properties: { 23072 color: {}, 23073 position: {}, 23074 decay: {}, 23075 distance: {} 23076 } }, 23077 pointLightShadows: { value: [], properties: { 23078 shadowIntensity: 1, 23079 shadowBias: {}, 23080 shadowNormalBias: {}, 23081 shadowRadius: {}, 23082 shadowMapSize: {}, 23083 shadowCameraNear: {}, 23084 shadowCameraFar: {} 23085 } }, 23086 pointShadowMatrix: { value: [] }, 23087 hemisphereLights: { value: [], properties: { 23088 direction: {}, 23089 skyColor: {}, 23090 groundColor: {} 23091 } }, 23092 // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src 23093 rectAreaLights: { value: [], properties: { 23094 color: {}, 23095 position: {}, 23096 width: {}, 23097 height: {} 23098 } }, 23099 ltc_1: { value: null }, 23100 ltc_2: { value: null }, 23101 probesSH: { value: null }, 23102 probesMin: { value: /* @__PURE__ */ new Vector3() }, 23103 probesMax: { value: /* @__PURE__ */ new Vector3() }, 23104 probesResolution: { value: /* @__PURE__ */ new Vector3() } 23105 }, 23106 points: { 23107 diffuse: { value: /* @__PURE__ */ new Color(16777215) }, 23108 opacity: { value: 1 }, 23109 size: { value: 1 }, 23110 scale: { value: 1 }, 23111 map: { value: null }, 23112 alphaMap: { value: null }, 23113 alphaMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23114 alphaTest: { value: 0 }, 23115 uvTransform: { value: /* @__PURE__ */ new Matrix3() } 23116 }, 23117 sprite: { 23118 diffuse: { value: /* @__PURE__ */ new Color(16777215) }, 23119 opacity: { value: 1 }, 23120 center: { value: /* @__PURE__ */ new Vector2(0.5, 0.5) }, 23121 rotation: { value: 0 }, 23122 map: { value: null }, 23123 mapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23124 alphaMap: { value: null }, 23125 alphaMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23126 alphaTest: { value: 0 } 23127 } 23128}; 23129var ShaderLib = { 23130 basic: { 23131 uniforms: /* @__PURE__ */ mergeUniforms([ 23132 UniformsLib.common, 23133 UniformsLib.specularmap, 23134 UniformsLib.envmap, 23135 UniformsLib.aomap, 23136 UniformsLib.lightmap, 23137 UniformsLib.fog 23138 ]), 23139 vertexShader: ShaderChunk.meshbasic_vert, 23140 fragmentShader: ShaderChunk.meshbasic_frag 23141 }, 23142 lambert: { 23143 uniforms: /* @__PURE__ */ mergeUniforms([ 23144 UniformsLib.common, 23145 UniformsLib.specularmap, 23146 UniformsLib.envmap, 23147 UniformsLib.aomap, 23148 UniformsLib.lightmap, 23149 UniformsLib.emissivemap, 23150 UniformsLib.bumpmap, 23151 UniformsLib.normalmap, 23152 UniformsLib.displacementmap, 23153 UniformsLib.fog, 23154 UniformsLib.lights, 23155 { 23156 emissive: { value: /* @__PURE__ */ new Color(0) }, 23157 envMapIntensity: { value: 1 } 23158 } 23159 ]), 23160 vertexShader: ShaderChunk.meshlambert_vert, 23161 fragmentShader: ShaderChunk.meshlambert_frag 23162 }, 23163 phong: { 23164 uniforms: /* @__PURE__ */ mergeUniforms([ 23165 UniformsLib.common, 23166 UniformsLib.specularmap, 23167 UniformsLib.envmap, 23168 UniformsLib.aomap, 23169 UniformsLib.lightmap, 23170 UniformsLib.emissivemap, 23171 UniformsLib.bumpmap, 23172 UniformsLib.normalmap, 23173 UniformsLib.displacementmap, 23174 UniformsLib.fog, 23175 UniformsLib.lights, 23176 { 23177 emissive: { value: /* @__PURE__ */ new Color(0) }, 23178 specular: { value: /* @__PURE__ */ new Color(1118481) }, 23179 shininess: { value: 30 }, 23180 envMapIntensity: { value: 1 } 23181 } 23182 ]), 23183 vertexShader: ShaderChunk.meshphong_vert, 23184 fragmentShader: ShaderChunk.meshphong_frag 23185 }, 23186 standard: { 23187 uniforms: /* @__PURE__ */ mergeUniforms([ 23188 UniformsLib.common, 23189 UniformsLib.envmap, 23190 UniformsLib.aomap, 23191 UniformsLib.lightmap, 23192 UniformsLib.emissivemap, 23193 UniformsLib.bumpmap, 23194 UniformsLib.normalmap, 23195 UniformsLib.displacementmap, 23196 UniformsLib.roughnessmap, 23197 UniformsLib.metalnessmap, 23198 UniformsLib.fog, 23199 UniformsLib.lights, 23200 { 23201 emissive: { value: /* @__PURE__ */ new Color(0) }, 23202 roughness: { value: 1 }, 23203 metalness: { value: 0 }, 23204 envMapIntensity: { value: 1 } 23205 } 23206 ]), 23207 vertexShader: ShaderChunk.meshphysical_vert, 23208 fragmentShader: ShaderChunk.meshphysical_frag 23209 }, 23210 toon: { 23211 uniforms: /* @__PURE__ */ mergeUniforms([ 23212 UniformsLib.common, 23213 UniformsLib.aomap, 23214 UniformsLib.lightmap, 23215 UniformsLib.emissivemap, 23216 UniformsLib.bumpmap, 23217 UniformsLib.normalmap, 23218 UniformsLib.displacementmap, 23219 UniformsLib.gradientmap, 23220 UniformsLib.fog, 23221 UniformsLib.lights, 23222 { 23223 emissive: { value: /* @__PURE__ */ new Color(0) } 23224 } 23225 ]), 23226 vertexShader: ShaderChunk.meshtoon_vert, 23227 fragmentShader: ShaderChunk.meshtoon_frag 23228 }, 23229 matcap: { 23230 uniforms: /* @__PURE__ */ mergeUniforms([ 23231 UniformsLib.common, 23232 UniformsLib.bumpmap, 23233 UniformsLib.normalmap, 23234 UniformsLib.displacementmap, 23235 UniformsLib.fog, 23236 { 23237 matcap: { value: null } 23238 } 23239 ]), 23240 vertexShader: ShaderChunk.meshmatcap_vert, 23241 fragmentShader: ShaderChunk.meshmatcap_frag 23242 }, 23243 points: { 23244 uniforms: /* @__PURE__ */ mergeUniforms([ 23245 UniformsLib.points, 23246 UniformsLib.fog 23247 ]), 23248 vertexShader: ShaderChunk.points_vert, 23249 fragmentShader: ShaderChunk.points_frag 23250 }, 23251 dashed: { 23252 uniforms: /* @__PURE__ */ mergeUniforms([ 23253 UniformsLib.common, 23254 UniformsLib.fog, 23255 { 23256 scale: { value: 1 }, 23257 dashSize: { value: 1 }, 23258 totalSize: { value: 2 } 23259 } 23260 ]), 23261 vertexShader: ShaderChunk.linedashed_vert, 23262 fragmentShader: ShaderChunk.linedashed_frag 23263 }, 23264 depth: { 23265 uniforms: /* @__PURE__ */ mergeUniforms([ 23266 UniformsLib.common, 23267 UniformsLib.displacementmap 23268 ]), 23269 vertexShader: ShaderChunk.depth_vert, 23270 fragmentShader: ShaderChunk.depth_frag 23271 }, 23272 normal: { 23273 uniforms: /* @__PURE__ */ mergeUniforms([ 23274 UniformsLib.common, 23275 UniformsLib.bumpmap, 23276 UniformsLib.normalmap, 23277 UniformsLib.displacementmap, 23278 { 23279 opacity: { value: 1 } 23280 } 23281 ]), 23282 vertexShader: ShaderChunk.meshnormal_vert, 23283 fragmentShader: ShaderChunk.meshnormal_frag 23284 }, 23285 sprite: { 23286 uniforms: /* @__PURE__ */ mergeUniforms([ 23287 UniformsLib.sprite, 23288 UniformsLib.fog 23289 ]), 23290 vertexShader: ShaderChunk.sprite_vert, 23291 fragmentShader: ShaderChunk.sprite_frag 23292 }, 23293 background: { 23294 uniforms: { 23295 uvTransform: { value: /* @__PURE__ */ new Matrix3() }, 23296 t2D: { value: null }, 23297 backgroundIntensity: { value: 1 } 23298 }, 23299 vertexShader: ShaderChunk.background_vert, 23300 fragmentShader: ShaderChunk.background_frag 23301 }, 23302 backgroundCube: { 23303 uniforms: { 23304 envMap: { value: null }, 23305 backgroundBlurriness: { value: 0 }, 23306 backgroundIntensity: { value: 1 }, 23307 backgroundRotation: { value: /* @__PURE__ */ new Matrix3() } 23308 }, 23309 vertexShader: ShaderChunk.backgroundCube_vert, 23310 fragmentShader: ShaderChunk.backgroundCube_frag 23311 }, 23312 cube: { 23313 uniforms: { 23314 tCube: { value: null }, 23315 tFlip: { value: -1 }, 23316 opacity: { value: 1 } 23317 }, 23318 vertexShader: ShaderChunk.cube_vert, 23319 fragmentShader: ShaderChunk.cube_frag 23320 }, 23321 equirect: { 23322 uniforms: { 23323 tEquirect: { value: null } 23324 }, 23325 vertexShader: ShaderChunk.equirect_vert, 23326 fragmentShader: ShaderChunk.equirect_frag 23327 }, 23328 distance: { 23329 uniforms: /* @__PURE__ */ mergeUniforms([ 23330 UniformsLib.common, 23331 UniformsLib.displacementmap, 23332 { 23333 referencePosition: { value: /* @__PURE__ */ new Vector3() }, 23334 nearDistance: { value: 1 }, 23335 farDistance: { value: 1e3 } 23336 } 23337 ]), 23338 vertexShader: ShaderChunk.distance_vert, 23339 fragmentShader: ShaderChunk.distance_frag 23340 }, 23341 shadow: { 23342 uniforms: /* @__PURE__ */ mergeUniforms([ 23343 UniformsLib.lights, 23344 UniformsLib.fog, 23345 { 23346 color: { value: /* @__PURE__ */ new Color(0) }, 23347 opacity: { value: 1 } 23348 } 23349 ]), 23350 vertexShader: ShaderChunk.shadow_vert, 23351 fragmentShader: ShaderChunk.shadow_frag 23352 } 23353}; 23354ShaderLib.physical = { 23355 uniforms: /* @__PURE__ */ mergeUniforms([ 23356 ShaderLib.standard.uniforms, 23357 { 23358 clearcoat: { value: 0 }, 23359 clearcoatMap: { value: null }, 23360 clearcoatMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23361 clearcoatNormalMap: { value: null }, 23362 clearcoatNormalMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23363 clearcoatNormalScale: { value: /* @__PURE__ */ new Vector2(1, 1) }, 23364 clearcoatRoughness: { value: 0 }, 23365 clearcoatRoughnessMap: { value: null }, 23366 clearcoatRoughnessMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23367 dispersion: { value: 0 }, 23368 iridescence: { value: 0 }, 23369 iridescenceMap: { value: null }, 23370 iridescenceMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23371 iridescenceIOR: { value: 1.3 }, 23372 iridescenceThicknessMinimum: { value: 100 }, 23373 iridescenceThicknessMaximum: { value: 400 }, 23374 iridescenceThicknessMap: { value: null }, 23375 iridescenceThicknessMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23376 sheen: { value: 0 }, 23377 sheenColor: { value: /* @__PURE__ */ new Color(0) }, 23378 sheenColorMap: { value: null }, 23379 sheenColorMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23380 sheenRoughness: { value: 1 }, 23381 sheenRoughnessMap: { value: null }, 23382 sheenRoughnessMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23383 transmission: { value: 0 }, 23384 transmissionMap: { value: null }, 23385 transmissionMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23386 transmissionSamplerSize: { value: /* @__PURE__ */ new Vector2() }, 23387 transmissionSamplerMap: { value: null }, 23388 thickness: { value: 0 }, 23389 thicknessMap: { value: null }, 23390 thicknessMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23391 attenuationDistance: { value: 0 }, 23392 attenuationColor: { value: /* @__PURE__ */ new Color(0) }, 23393 specularColor: { value: /* @__PURE__ */ new Color(1, 1, 1) }, 23394 specularColorMap: { value: null }, 23395 specularColorMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23396 specularIntensity: { value: 1 }, 23397 specularIntensityMap: { value: null }, 23398 specularIntensityMapTransform: { value: /* @__PURE__ */ new Matrix3() }, 23399 anisotropyVector: { value: /* @__PURE__ */ new Vector2() }, 23400 anisotropyMap: { value: null }, 23401 anisotropyMapTransform: { value: /* @__PURE__ */ new Matrix3() } 23402 } 23403 ]), 23404 vertexShader: ShaderChunk.meshphysical_vert, 23405 fragmentShader: ShaderChunk.meshphysical_frag 23406}; 23407var _rgb = { r: 0, b: 0, g: 0 }; 23408var _m1$12 = /* @__PURE__ */ new Matrix4(); 23409var _m$1 = /* @__PURE__ */ new Matrix3(); 23410_m$1.set(-1, 0, 0, 0, 1, 0, 0, 0, 1); 23411function WebGLBackground(renderer, environments, state, objects, alpha, premultipliedAlpha) { 23412 const clearColor = new Color(0); 23413 let clearAlpha = alpha === true ? 0 : 1; 23414 let planeMesh; 23415 let boxMesh; 23416 let currentBackground = null; 23417 let currentBackgroundVersion = 0; 23418 let currentTonemapping = null; 23419 function getBackground(scene) { 23420 let background = scene.isScene === true ? scene.background : null; 23421 if (background && background.isTexture) { 23422 const usePMREM = scene.backgroundBlurriness > 0; 23423 background = environments.get(background, usePMREM); 23424 } 23425 return background; 23426 } 23427 function render2(scene) { 23428 let forceClear = false; 23429 const background = getBackground(scene); 23430 if (background === null) { 23431 setClear(clearColor, clearAlpha); 23432 } else if (background && background.isColor) { 23433 setClear(background, 1); 23434 forceClear = true; 23435 } 23436 const environmentBlendMode = renderer.xr.getEnvironmentBlendMode(); 23437 if (environmentBlendMode === "additive") { 23438 state.buffers.color.setClear(0, 0, 0, 1, premultipliedAlpha); 23439 } else if (environmentBlendMode === "alpha-blend") { 23440 state.buffers.color.setClear(0, 0, 0, 0, premultipliedAlpha); 23441 } 23442 if (renderer.autoClear || forceClear) { 23443 state.buffers.depth.setTest(true); 23444 state.buffers.depth.setMask(true); 23445 state.buffers.color.setMask(true); 23446 renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil); 23447 } 23448 } 23449 function addToRenderList(renderList, scene) { 23450 const background = getBackground(scene); 23451 if (background && (background.isCubeTexture || background.mapping === CubeUVReflectionMapping)) { 23452 if (boxMesh === void 0) { 23453 boxMesh = new Mesh( 23454 new BoxGeometry(1, 1, 1), 23455 new ShaderMaterial({ 23456 name: "BackgroundCubeMaterial", 23457 uniforms: cloneUniforms(ShaderLib.backgroundCube.uniforms), 23458 vertexShader: ShaderLib.backgroundCube.vertexShader, 23459 fragmentShader: ShaderLib.backgroundCube.fragmentShader, 23460 side: BackSide, 23461 depthTest: false, 23462 depthWrite: false, 23463 fog: false, 23464 allowOverride: false 23465 }) 23466 ); 23467 boxMesh.geometry.deleteAttribute("normal"); 23468 boxMesh.geometry.deleteAttribute("uv"); 23469 boxMesh.onBeforeRender = function(renderer2, scene2, camera) { 23470 this.matrixWorld.copyPosition(camera.matrixWorld); 23471 }; 23472 Object.defineProperty(boxMesh.material, "envMap", { 23473 get: function() { 23474 return this.uniforms.envMap.value; 23475 } 23476 }); 23477 objects.update(boxMesh); 23478 } 23479 boxMesh.material.uniforms.envMap.value = background; 23480 boxMesh.material.uniforms.backgroundBlurriness.value = scene.backgroundBlurriness; 23481 boxMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity; 23482 boxMesh.material.uniforms.backgroundRotation.value.setFromMatrix4(_m1$12.makeRotationFromEuler(scene.backgroundRotation)).transpose(); 23483 if (background.isCubeTexture && background.isRenderTargetTexture === false) { 23484 boxMesh.material.uniforms.backgroundRotation.value.premultiply(_m$1); 23485 } 23486 boxMesh.material.toneMapped = ColorManagement.getTransfer(background.colorSpace) !== SRGBTransfer; 23487 if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) { 23488 boxMesh.material.needsUpdate = true; 23489 currentBackground = background; 23490 currentBackgroundVersion = background.version; 23491 currentTonemapping = renderer.toneMapping; 23492 } 23493 boxMesh.layers.enableAll(); 23494 renderList.unshift(boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null); 23495 } else if (background && background.isTexture) { 23496 if (planeMesh === void 0) { 23497 planeMesh = new Mesh( 23498 new PlaneGeometry(2, 2), 23499 new ShaderMaterial({ 23500 name: "BackgroundMaterial", 23501 uniforms: cloneUniforms(ShaderLib.background.uniforms), 23502 vertexShader: ShaderLib.background.vertexShader, 23503 fragmentShader: ShaderLib.background.fragmentShader, 23504 side: FrontSide, 23505 depthTest: false, 23506 depthWrite: false, 23507 fog: false, 23508 allowOverride: false 23509 }) 23510 ); 23511 planeMesh.geometry.deleteAttribute("normal"); 23512 Object.defineProperty(planeMesh.material, "map", { 23513 get: function() { 23514 return this.uniforms.t2D.value; 23515 } 23516 }); 23517 objects.update(planeMesh); 23518 } 23519 planeMesh.material.uniforms.t2D.value = background; 23520 planeMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity; 23521 planeMesh.material.toneMapped = ColorManagement.getTransfer(background.colorSpace) !== SRGBTransfer; 23522 if (background.matrixAutoUpdate === true) { 23523 background.updateMatrix(); 23524 } 23525 planeMesh.material.uniforms.uvTransform.value.copy(background.matrix); 23526 if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) { 23527 planeMesh.material.needsUpdate = true; 23528 currentBackground = background; 23529 currentBackgroundVersion = background.version; 23530 currentTonemapping = renderer.toneMapping; 23531 } 23532 planeMesh.layers.enableAll(); 23533 renderList.unshift(planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null); 23534 } 23535 } 23536 function setClear(color, alpha2) { 23537 color.getRGB(_rgb, getUnlitUniformColorSpace(renderer)); 23538 state.buffers.color.setClear(_rgb.r, _rgb.g, _rgb.b, alpha2, premultipliedAlpha); 23539 } 23540 function dispose2() { 23541 if (boxMesh !== void 0) { 23542 boxMesh.geometry.dispose(); 23543 boxMesh.material.dispose(); 23544 boxMesh = void 0; 23545 } 23546 if (planeMesh !== void 0) { 23547 planeMesh.geometry.dispose(); 23548 planeMesh.material.dispose(); 23549 planeMesh = void 0; 23550 } 23551 } 23552 return { 23553 getClearColor: function() { 23554 return clearColor; 23555 }, 23556 setClearColor: function(color, alpha2 = 1) { 23557 clearColor.set(color); 23558 clearAlpha = alpha2; 23559 setClear(clearColor, clearAlpha); 23560 }, 23561 getClearAlpha: function() { 23562 return clearAlpha; 23563 }, 23564 setClearAlpha: function(alpha2) { 23565 clearAlpha = alpha2; 23566 setClear(clearColor, clearAlpha); 23567 }, 23568 render: render2, 23569 addToRenderList, 23570 dispose: dispose2 23571 }; 23572} 23573function WebGLBindingStates(gl, attributes) { 23574 const maxVertexAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); 23575 const bindingStates = {}; 23576 const defaultState = createBindingState(null); 23577 let currentState = defaultState; 23578 let forceUpdate = false; 23579 function setup(object, material, program, geometry, index) { 23580 let updateBuffers = false; 23581 const state = getBindingState(object, geometry, program, material); 23582 if (currentState !== state) { 23583 currentState = state; 23584 bindVertexArrayObject(currentState.object); 23585 } 23586 updateBuffers = needsUpdate(object, geometry, program, index); 23587 if (updateBuffers) saveCache(object, geometry, program, index); 23588 if (index !== null) { 23589 attributes.update(index, gl.ELEMENT_ARRAY_BUFFER); 23590 } 23591 if (updateBuffers || forceUpdate) { 23592 forceUpdate = false; 23593 setupVertexAttributes(object, material, program, geometry); 23594 if (index !== null) { 23595 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, attributes.get(index).buffer); 23596 } 23597 } 23598 } 23599 function createVertexArrayObject() { 23600 return gl.createVertexArray(); 23601 } 23602 function bindVertexArrayObject(vao) { 23603 return gl.bindVertexArray(vao); 23604 } 23605 function deleteVertexArrayObject(vao) { 23606 return gl.deleteVertexArray(vao); 23607 } 23608 function getBindingState(object, geometry, program, material) { 23609 const wireframe = material.wireframe === true; 23610 let objectMap = bindingStates[geometry.id]; 23611 if (objectMap === void 0) { 23612 objectMap = {}; 23613 bindingStates[geometry.id] = objectMap; 23614 } 23615 const objectId = object.isInstancedMesh === true ? object.id : 0; 23616 let programMap = objectMap[objectId]; 23617 if (programMap === void 0) { 23618 programMap = {}; 23619 objectMap[objectId] = programMap; 23620 } 23621 let stateMap = programMap[program.id]; 23622 if (stateMap === void 0) { 23623 stateMap = {}; 23624 programMap[program.id] = stateMap; 23625 } 23626 let state = stateMap[wireframe]; 23627 if (state === void 0) { 23628 state = createBindingState(createVertexArrayObject()); 23629 stateMap[wireframe] = state; 23630 } 23631 return state; 23632 } 23633 function createBindingState(vao) { 23634 const newAttributes = []; 23635 const enabledAttributes = []; 23636 const attributeDivisors = []; 23637 for (let i = 0; i < maxVertexAttributes; i++) { 23638 newAttributes[i] = 0; 23639 enabledAttributes[i] = 0; 23640 attributeDivisors[i] = 0; 23641 } 23642 return { 23643 // for backward compatibility on non-VAO support browser 23644 geometry: null, 23645 program: null, 23646 wireframe: false, 23647 newAttributes, 23648 enabledAttributes, 23649 attributeDivisors, 23650 object: vao, 23651 attributes: {}, 23652 index: null 23653 }; 23654 } 23655 function needsUpdate(object, geometry, program, index) { 23656 const cachedAttributes = currentState.attributes; 23657 const geometryAttributes = geometry.attributes; 23658 let attributesNum = 0; 23659 const programAttributes = program.getAttributes(); 23660 for (const name in programAttributes) { 23661 const programAttribute = programAttributes[name]; 23662 if (programAttribute.location >= 0) { 23663 const cachedAttribute = cachedAttributes[name]; 23664 let geometryAttribute = geometryAttributes[name]; 23665 if (geometryAttribute === void 0) { 23666 if (name === "instanceMatrix" && object.instanceMatrix) geometryAttribute = object.instanceMatrix; 23667 if (name === "instanceColor" && object.instanceColor) geometryAttribute = object.instanceColor; 23668 } 23669 if (cachedAttribute === void 0) return true; 23670 if (cachedAttribute.attribute !== geometryAttribute) return true; 23671 if (geometryAttribute && cachedAttribute.data !== geometryAttribute.data) return true; 23672 attributesNum++; 23673 } 23674 } 23675 if (currentState.attributesNum !== attributesNum) return true; 23676 if (currentState.index !== index) return true; 23677 return false; 23678 } 23679 function saveCache(object, geometry, program, index) { 23680 const cache = {}; 23681 const attributes2 = geometry.attributes; 23682 let attributesNum = 0; 23683 const programAttributes = program.getAttributes(); 23684 for (const name in programAttributes) { 23685 const programAttribute = programAttributes[name]; 23686 if (programAttribute.location >= 0) { 23687 let attribute = attributes2[name]; 23688 if (attribute === void 0) { 23689 if (name === "instanceMatrix" && object.instanceMatrix) attribute = object.instanceMatrix; 23690 if (name === "instanceColor" && object.instanceColor) attribute = object.instanceColor; 23691 } 23692 const data = {}; 23693 data.attribute = attribute; 23694 if (attribute && attribute.data) { 23695 data.data = attribute.data; 23696 } 23697 cache[name] = data; 23698 attributesNum++; 23699 } 23700 } 23701 currentState.attributes = cache; 23702 currentState.attributesNum = attributesNum; 23703 currentState.index = index; 23704 } 23705 function initAttributes() { 23706 const newAttributes = currentState.newAttributes; 23707 for (let i = 0, il = newAttributes.length; i < il; i++) { 23708 newAttributes[i] = 0; 23709 } 23710 } 23711 function enableAttribute(attribute) { 23712 enableAttributeAndDivisor(attribute, 0); 23713 } 23714 function enableAttributeAndDivisor(attribute, meshPerAttribute) { 23715 const newAttributes = currentState.newAttributes; 23716 const enabledAttributes = currentState.enabledAttributes; 23717 const attributeDivisors = currentState.attributeDivisors; 23718 newAttributes[attribute] = 1; 23719 if (enabledAttributes[attribute] === 0) { 23720 gl.enableVertexAttribArray(attribute); 23721 enabledAttributes[attribute] = 1; 23722 } 23723 if (attributeDivisors[attribute] !== meshPerAttribute) { 23724 gl.vertexAttribDivisor(attribute, meshPerAttribute); 23725 attributeDivisors[attribute] = meshPerAttribute; 23726 } 23727 } 23728 function disableUnusedAttributes() { 23729 const newAttributes = currentState.newAttributes; 23730 const enabledAttributes = currentState.enabledAttributes; 23731 for (let i = 0, il = enabledAttributes.length; i < il; i++) { 23732 if (enabledAttributes[i] !== newAttributes[i]) { 23733 gl.disableVertexAttribArray(i); 23734 enabledAttributes[i] = 0; 23735 } 23736 } 23737 } 23738 function vertexAttribPointer(index, size, type, normalized, stride, offset, integer) { 23739 if (integer === true) { 23740 gl.vertexAttribIPointer(index, size, type, stride, offset); 23741 } else { 23742 gl.vertexAttribPointer(index, size, type, normalized, stride, offset); 23743 } 23744 } 23745 function setupVertexAttributes(object, material, program, geometry) { 23746 initAttributes(); 23747 const geometryAttributes = geometry.attributes; 23748 const programAttributes = program.getAttributes(); 23749 const materialDefaultAttributeValues = material.defaultAttributeValues; 23750 for (const name in programAttributes) { 23751 const programAttribute = programAttributes[name]; 23752 if (programAttribute.location >= 0) { 23753 let geometryAttribute = geometryAttributes[name]; 23754 if (geometryAttribute === void 0) { 23755 if (name === "instanceMatrix" && object.instanceMatrix) geometryAttribute = object.instanceMatrix; 23756 if (name === "instanceColor" && object.instanceColor) geometryAttribute = object.instanceColor; 23757 } 23758 if (geometryAttribute !== void 0) { 23759 const normalized = geometryAttribute.normalized; 23760 const size = geometryAttribute.itemSize; 23761 const attribute = attributes.get(geometryAttribute); 23762 if (attribute === void 0) continue; 23763 const buffer = attribute.buffer; 23764 const type = attribute.type; 23765 const bytesPerElement = attribute.bytesPerElement; 23766 const integer = type === gl.INT || type === gl.UNSIGNED_INT || geometryAttribute.gpuType === IntType; 23767 if (geometryAttribute.isInterleavedBufferAttribute) { 23768 const data = geometryAttribute.data; 23769 const stride = data.stride; 23770 const offset = geometryAttribute.offset; 23771 if (data.isInstancedInterleavedBuffer) { 23772 for (let i = 0; i < programAttribute.locationSize; i++) { 23773 enableAttributeAndDivisor(programAttribute.location + i, data.meshPerAttribute); 23774 } 23775 if (object.isInstancedMesh !== true && geometry._maxInstanceCount === void 0) { 23776 geometry._maxInstanceCount = data.meshPerAttribute * data.count; 23777 } 23778 } else { 23779 for (let i = 0; i < programAttribute.locationSize; i++) { 23780 enableAttribute(programAttribute.location + i); 23781 } 23782 } 23783 gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 23784 for (let i = 0; i < programAttribute.locationSize; i++) { 23785 vertexAttribPointer( 23786 programAttribute.location + i, 23787 size / programAttribute.locationSize, 23788 type, 23789 normalized, 23790 stride * bytesPerElement, 23791 (offset + size / programAttribute.locationSize * i) * bytesPerElement, 23792 integer 23793 ); 23794 } 23795 } else { 23796 if (geometryAttribute.isInstancedBufferAttribute) { 23797 for (let i = 0; i < programAttribute.locationSize; i++) { 23798 enableAttributeAndDivisor(programAttribute.location + i, geometryAttribute.meshPerAttribute); 23799 } 23800 if (object.isInstancedMesh !== true && geometry._maxInstanceCount === void 0) { 23801 geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count; 23802 } 23803 } else { 23804 for (let i = 0; i < programAttribute.locationSize; i++) { 23805 enableAttribute(programAttribute.location + i); 23806 } 23807 } 23808 gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 23809 for (let i = 0; i < programAttribute.locationSize; i++) { 23810 vertexAttribPointer( 23811 programAttribute.location + i, 23812 size / programAttribute.locationSize, 23813 type, 23814 normalized, 23815 size * bytesPerElement, 23816 size / programAttribute.locationSize * i * bytesPerElement, 23817 integer 23818 ); 23819 } 23820 } 23821 } else if (materialDefaultAttributeValues !== void 0) { 23822 const value = materialDefaultAttributeValues[name]; 23823 if (value !== void 0) { 23824 switch (value.length) { 23825 case 2: 23826 gl.vertexAttrib2fv(programAttribute.location, value); 23827 break; 23828 case 3: 23829 gl.vertexAttrib3fv(programAttribute.location, value); 23830 break; 23831 case 4: 23832 gl.vertexAttrib4fv(programAttribute.location, value); 23833 break; 23834 default: 23835 gl.vertexAttrib1fv(programAttribute.location, value); 23836 } 23837 } 23838 } 23839 } 23840 } 23841 disableUnusedAttributes(); 23842 } 23843 function dispose2() { 23844 reset2(); 23845 for (const geometryId in bindingStates) { 23846 const objectMap = bindingStates[geometryId]; 23847 for (const objectId in objectMap) { 23848 const programMap = objectMap[objectId]; 23849 for (const programId in programMap) { 23850 const stateMap = programMap[programId]; 23851 for (const wireframe in stateMap) { 23852 deleteVertexArrayObject(stateMap[wireframe].object); 23853 delete stateMap[wireframe]; 23854 } 23855 delete programMap[programId]; 23856 } 23857 } 23858 delete bindingStates[geometryId]; 23859 } 23860 } 23861 function releaseStatesOfGeometry(geometry) { 23862 if (bindingStates[geometry.id] === void 0) return; 23863 const objectMap = bindingStates[geometry.id]; 23864 for (const objectId in objectMap) { 23865 const programMap = objectMap[objectId]; 23866 for (const programId in programMap) { 23867 const stateMap = programMap[programId]; 23868 for (const wireframe in stateMap) { 23869 deleteVertexArrayObject(stateMap[wireframe].object); 23870 delete stateMap[wireframe]; 23871 } 23872 delete programMap[programId]; 23873 } 23874 } 23875 delete bindingStates[geometry.id]; 23876 } 23877 function releaseStatesOfProgram(program) { 23878 for (const geometryId in bindingStates) { 23879 const objectMap = bindingStates[geometryId]; 23880 for (const objectId in objectMap) { 23881 const programMap = objectMap[objectId]; 23882 if (programMap[program.id] === void 0) continue; 23883 const stateMap = programMap[program.id]; 23884 for (const wireframe in stateMap) { 23885 deleteVertexArrayObject(stateMap[wireframe].object); 23886 delete stateMap[wireframe]; 23887 } 23888 delete programMap[program.id]; 23889 } 23890 } 23891 } 23892 function releaseStatesOfObject(object) { 23893 for (const geometryId in bindingStates) { 23894 const objectMap = bindingStates[geometryId]; 23895 const objectId = object.isInstancedMesh === true ? object.id : 0; 23896 const programMap = objectMap[objectId]; 23897 if (programMap === void 0) continue; 23898 for (const programId in programMap) { 23899 const stateMap = programMap[programId]; 23900 for (const wireframe in stateMap) { 23901 deleteVertexArrayObject(stateMap[wireframe].object); 23902 delete stateMap[wireframe]; 23903 } 23904 delete programMap[programId]; 23905 } 23906 delete objectMap[objectId]; 23907 if (Object.keys(objectMap).length === 0) { 23908 delete bindingStates[geometryId]; 23909 } 23910 } 23911 } 23912 function reset2() { 23913 resetDefaultState(); 23914 forceUpdate = true; 23915 if (currentState === defaultState) return; 23916 currentState = defaultState; 23917 bindVertexArrayObject(currentState.object); 23918 } 23919 function resetDefaultState() { 23920 defaultState.geometry = null; 23921 defaultState.program = null; 23922 defaultState.wireframe = false; 23923 } 23924 return { 23925 setup, 23926 reset: reset2, 23927 resetDefaultState, 23928 dispose: dispose2, 23929 releaseStatesOfGeometry, 23930 releaseStatesOfObject, 23931 releaseStatesOfProgram, 23932 initAttributes, 23933 enableAttribute, 23934 disableUnusedAttributes 23935 }; 23936} 23937function WebGLBufferRenderer(gl, extensions, info) { 23938 let mode; 23939 function setMode(value) { 23940 mode = value; 23941 } 23942 function render2(start, count) { 23943 gl.drawArrays(mode, start, count); 23944 info.update(count, mode, 1); 23945 } 23946 function renderInstances(start, count, primcount) { 23947 if (primcount === 0) return; 23948 gl.drawArraysInstanced(mode, start, count, primcount); 23949 info.update(count, mode, primcount); 23950 } 23951 function renderMultiDraw(starts, counts, drawCount) { 23952 if (drawCount === 0) return; 23953 const extension = extensions.get("WEBGL_multi_draw"); 23954 extension.multiDrawArraysWEBGL(mode, starts, 0, counts, 0, drawCount); 23955 let elementCount = 0; 23956 for (let i = 0; i < drawCount; i++) { 23957 elementCount += counts[i]; 23958 } 23959 info.update(elementCount, mode, 1); 23960 } 23961 this.setMode = setMode; 23962 this.render = render2; 23963 this.renderInstances = renderInstances; 23964 this.renderMultiDraw = renderMultiDraw; 23965} 23966function WebGLCapabilities(gl, extensions, parameters, utils) { 23967 let maxAnisotropy; 23968 function getMaxAnisotropy() { 23969 if (maxAnisotropy !== void 0) return maxAnisotropy; 23970 if (extensions.has("EXT_texture_filter_anisotropic") === true) { 23971 const extension = extensions.get("EXT_texture_filter_anisotropic"); 23972 maxAnisotropy = gl.getParameter(extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT); 23973 } else { 23974 maxAnisotropy = 0; 23975 } 23976 return maxAnisotropy; 23977 } 23978 function textureFormatReadable(textureFormat) { 23979 if (textureFormat !== RGBAFormat && utils.convert(textureFormat) !== gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT)) { 23980 return false; 23981 } 23982 return true; 23983 } 23984 function textureTypeReadable(textureType) { 23985 const halfFloatSupportedByExt = textureType === HalfFloatType && (extensions.has("EXT_color_buffer_half_float") || extensions.has("EXT_color_buffer_float")); 23986 if (textureType !== UnsignedByteType && utils.convert(textureType) !== gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE) && // Edge and Chrome Mac < 52 (#9513) 23987 textureType !== FloatType && !halfFloatSupportedByExt) { 23988 return false; 23989 } 23990 return true; 23991 } 23992 function getMaxPrecision(precision2) { 23993 if (precision2 === "highp") { 23994 if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision > 0) { 23995 return "highp"; 23996 } 23997 precision2 = "mediump"; 23998 } 23999 if (precision2 === "mediump") { 24000 if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT).precision > 0) { 24001 return "mediump"; 24002 } 24003 } 24004 return "lowp"; 24005 } 24006 let precision = parameters.precision !== void 0 ? parameters.precision : "highp"; 24007 const maxPrecision = getMaxPrecision(precision); 24008 if (maxPrecision !== precision) { 24009 warn("WebGLRenderer:", precision, "not supported, using", maxPrecision, "instead."); 24010 precision = maxPrecision; 24011 } 24012 const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; 24013 const reversedDepthBuffer = parameters.reversedDepthBuffer === true && extensions.has("EXT_clip_control"); 24014 if (parameters.reversedDepthBuffer === true && reversedDepthBuffer === false) { 24015 warn("WebGLRenderer: Unable to use reversed depth buffer due to missing EXT_clip_control extension. Fallback to default depth buffer."); 24016 } 24017 const maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); 24018 const maxVertexTextures = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS); 24019 const maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); 24020 const maxCubemapSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); 24021 const maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); 24022 const maxVertexUniforms = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS); 24023 const maxVaryings = gl.getParameter(gl.MAX_VARYING_VECTORS); 24024 const maxFragmentUniforms = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS); 24025 const maxSamples = gl.getParameter(gl.MAX_SAMPLES); 24026 const samples = gl.getParameter(gl.SAMPLES); 24027 return { 24028 isWebGL2: true, 24029 // keeping this for backwards compatibility 24030 getMaxAnisotropy, 24031 getMaxPrecision, 24032 textureFormatReadable, 24033 textureTypeReadable, 24034 precision, 24035 logarithmicDepthBuffer, 24036 reversedDepthBuffer, 24037 maxTextures, 24038 maxVertexTextures, 24039 maxTextureSize, 24040 maxCubemapSize, 24041 maxAttributes, 24042 maxVertexUniforms, 24043 maxVaryings, 24044 maxFragmentUniforms, 24045 maxSamples, 24046 samples 24047 }; 24048} 24049function WebGLClipping(properties) { 24050 const scope = this; 24051 let globalState = null, numGlobalPlanes = 0, localClippingEnabled = false, renderingShadows = false; 24052 const plane = new Plane(), viewNormalMatrix = new Matrix3(), uniform = { value: null, needsUpdate: false }; 24053 this.uniform = uniform; 24054 this.numPlanes = 0; 24055 this.numIntersection = 0; 24056 this.init = function(planes, enableLocalClipping) { 24057 const enabled = planes.length !== 0 || enableLocalClipping || // enable state of previous frame - the clipping code has to 24058 // run another frame in order to reset the state: 24059 numGlobalPlanes !== 0 || localClippingEnabled; 24060 localClippingEnabled = enableLocalClipping; 24061 numGlobalPlanes = planes.length; 24062 return enabled; 24063 }; 24064 this.beginShadows = function() { 24065 renderingShadows = true; 24066 projectPlanes(null); 24067 }; 24068 this.endShadows = function() { 24069 renderingShadows = false; 24070 }; 24071 this.setGlobalState = function(planes, camera) { 24072 globalState = projectPlanes(planes, camera, 0); 24073 }; 24074 this.setState = function(material, camera, useCache) { 24075 const planes = material.clippingPlanes, clipIntersection = material.clipIntersection, clipShadows = material.clipShadows; 24076 const materialProperties = properties.get(material); 24077 if (!localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && !clipShadows) { 24078 if (renderingShadows) { 24079 projectPlanes(null); 24080 } else { 24081 resetGlobalState(); 24082 } 24083 } else { 24084 const nGlobal = renderingShadows ? 0 : numGlobalPlanes, lGlobal = nGlobal * 4; 24085 let dstArray = materialProperties.clippingState || null; 24086 uniform.value = dstArray; 24087 dstArray = projectPlanes(planes, camera, lGlobal, useCache); 24088 for (let i = 0; i !== lGlobal; ++i) { 24089 dstArray[i] = globalState[i]; 24090 } 24091 materialProperties.clippingState = dstArray; 24092 this.numIntersection = clipIntersection ? this.numPlanes : 0; 24093 this.numPlanes += nGlobal; 24094 } 24095 }; 24096 function resetGlobalState() { 24097 if (uniform.value !== globalState) { 24098 uniform.value = globalState; 24099 uniform.needsUpdate = numGlobalPlanes > 0; 24100 } 24101 scope.numPlanes = numGlobalPlanes; 24102 scope.numIntersection = 0; 24103 } 24104 function projectPlanes(planes, camera, dstOffset, skipTransform) { 24105 const nPlanes = planes !== null ? planes.length : 0; 24106 let dstArray = null; 24107 if (nPlanes !== 0) { 24108 dstArray = uniform.value; 24109 if (skipTransform !== true || dstArray === null) { 24110 const flatSize = dstOffset + nPlanes * 4, viewMatrix = camera.matrixWorldInverse; 24111 viewNormalMatrix.getNormalMatrix(viewMatrix); 24112 if (dstArray === null || dstArray.length < flatSize) { 24113 dstArray = new Float32Array(flatSize); 24114 } 24115 for (let i = 0, i4 = dstOffset; i !== nPlanes; ++i, i4 += 4) { 24116 plane.copy(planes[i]).applyMatrix4(viewMatrix, viewNormalMatrix); 24117 plane.normal.toArray(dstArray, i4); 24118 dstArray[i4 + 3] = plane.constant; 24119 } 24120 } 24121 uniform.value = dstArray; 24122 uniform.needsUpdate = true; 24123 } 24124 scope.numPlanes = nPlanes; 24125 scope.numIntersection = 0; 24126 return dstArray; 24127 } 24128} 24129var LOD_MIN = 4; 24130var EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; 24131var MAX_SAMPLES = 20; 24132var GGX_SAMPLES = 256; 24133var _flatCamera = /* @__PURE__ */ new OrthographicCamera(); 24134var _clearColor = /* @__PURE__ */ new Color(); 24135var _oldTarget = null; 24136var _oldActiveCubeFace = 0; 24137var _oldActiveMipmapLevel = 0; 24138var _oldXrEnabled = false; 24139var _origin = /* @__PURE__ */ new Vector3(); 24140var PMREMGenerator = class { 24141 /** 24142 * Constructs a new PMREM generator. 24143 * 24144 * @param {WebGLRenderer} renderer - The renderer. 24145 */ 24146 constructor(renderer) { 24147 this._renderer = renderer; 24148 this._pingPongRenderTarget = null; 24149 this._lodMax = 0; 24150 this._cubeSize = 0; 24151 this._sizeLods = []; 24152 this._sigmas = []; 24153 this._lodMeshes = []; 24154 this._backgroundBox = null; 24155 this._cubemapMaterial = null; 24156 this._equirectMaterial = null; 24157 this._blurMaterial = null; 24158 this._ggxMaterial = null; 24159 } 24160 /** 24161 * Generates a PMREM from a supplied Scene, which can be faster than using an 24162 * image if networking bandwidth is low. Optional sigma specifies a blur radius 24163 * in radians to be applied to the scene before PMREM generation. Optional near 24164 * and far planes ensure the scene is rendered in its entirety. 24165 * 24166 * @param {Scene} scene - The scene to be captured. 24167 * @param {number} [sigma=0] - The blur radius in radians. 24168 * @param {number} [near=0.1] - The near plane distance. 24169 * @param {number} [far=100] - The far plane distance. 24170 * @param {Object} [options={}] - The configuration options. 24171 * @param {number} [options.size=256] - The texture size of the PMREM. 24172 * @param {Vector3} [options.position=origin] - The position of the internal cube camera that renders the scene. 24173 * @return {WebGLRenderTarget} The resulting PMREM. 24174 */ 24175 fromScene(scene, sigma = 0, near = 0.1, far = 100, options = {}) { 24176 const { 24177 size = 256, 24178 position = _origin 24179 } = options; 24180 _oldTarget = this._renderer.getRenderTarget(); 24181 _oldActiveCubeFace = this._renderer.getActiveCubeFace(); 24182 _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); 24183 _oldXrEnabled = this._renderer.xr.enabled; 24184 this._renderer.xr.enabled = false; 24185 this._setSize(size); 24186 const cubeUVRenderTarget = this._allocateTargets(); 24187 cubeUVRenderTarget.depthBuffer = true; 24188 this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget, position); 24189 if (sigma > 0) { 24190 this._blur(cubeUVRenderTarget, 0, 0, sigma); 24191 } 24192 this._applyPMREM(cubeUVRenderTarget); 24193 this._cleanup(cubeUVRenderTarget); 24194 return cubeUVRenderTarget; 24195 } 24196 /** 24197 * Generates a PMREM from an equirectangular texture, which can be either LDR 24198 * or HDR. The ideal input image size is 1k (1024 x 512), 24199 * as this matches best with the 256 x 256 cubemap output. 24200 * 24201 * @param {Texture} equirectangular - The equirectangular texture to be converted. 24202 * @param {?WebGLRenderTarget} [renderTarget=null] - The render target to use. 24203 * @return {WebGLRenderTarget} The resulting PMREM. 24204 */ 24205 fromEquirectangular(equirectangular, renderTarget = null) { 24206 return this._fromTexture(equirectangular, renderTarget); 24207 } 24208 /** 24209 * Generates a PMREM from an cubemap texture, which can be either LDR 24210 * or HDR. The ideal input cube size is 256 x 256, 24211 * as this matches best with the 256 x 256 cubemap output. 24212 * 24213 * @param {Texture} cubemap - The cubemap texture to be converted. 24214 * @param {?WebGLRenderTarget} [renderTarget=null] - The render target to use. 24215 * @return {WebGLRenderTarget} The resulting PMREM. 24216 */ 24217 fromCubemap(cubemap, renderTarget = null) { 24218 return this._fromTexture(cubemap, renderTarget); 24219 } 24220 /** 24221 * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during 24222 * your texture's network fetch for increased concurrency. 24223 */ 24224 compileCubemapShader() { 24225 if (this._cubemapMaterial === null) { 24226 this._cubemapMaterial = _getCubemapMaterial(); 24227 this._compileMaterial(this._cubemapMaterial); 24228 } 24229 } 24230 /** 24231 * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during 24232 * your texture's network fetch for increased concurrency. 24233 */ 24234 compileEquirectangularShader() { 24235 if (this._equirectMaterial === null) { 24236 this._equirectMaterial = _getEquirectMaterial(); 24237 this._compileMaterial(this._equirectMaterial); 24238 } 24239 } 24240 /** 24241 * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, 24242 * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on 24243 * one of them will cause any others to also become unusable. 24244 */ 24245 dispose() { 24246 this._dispose(); 24247 if (this._cubemapMaterial !== null) this._cubemapMaterial.dispose(); 24248 if (this._equirectMaterial !== null) this._equirectMaterial.dispose(); 24249 if (this._backgroundBox !== null) { 24250 this._backgroundBox.geometry.dispose(); 24251 this._backgroundBox.material.dispose(); 24252 } 24253 } 24254 // private interface 24255 _setSize(cubeSize) { 24256 this._lodMax = Math.floor(Math.log2(cubeSize)); 24257 this._cubeSize = Math.pow(2, this._lodMax); 24258 } 24259 _dispose() { 24260 if (this._blurMaterial !== null) this._blurMaterial.dispose(); 24261 if (this._ggxMaterial !== null) this._ggxMaterial.dispose(); 24262 if (this._pingPongRenderTarget !== null) this._pingPongRenderTarget.dispose(); 24263 for (let i = 0; i < this._lodMeshes.length; i++) { 24264 this._lodMeshes[i].geometry.dispose(); 24265 } 24266 } 24267 _cleanup(outputTarget) { 24268 this._renderer.setRenderTarget(_oldTarget, _oldActiveCubeFace, _oldActiveMipmapLevel); 24269 this._renderer.xr.enabled = _oldXrEnabled; 24270 outputTarget.scissorTest = false; 24271 _setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height); 24272 } 24273 _fromTexture(texture, renderTarget) { 24274 if (texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping) { 24275 this._setSize(texture.image.length === 0 ? 16 : texture.image[0].width || texture.image[0].image.width); 24276 } else { 24277 this._setSize(texture.image.width / 4); 24278 } 24279 _oldTarget = this._renderer.getRenderTarget(); 24280 _oldActiveCubeFace = this._renderer.getActiveCubeFace(); 24281 _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); 24282 _oldXrEnabled = this._renderer.xr.enabled; 24283 this._renderer.xr.enabled = false; 24284 const cubeUVRenderTarget = renderTarget || this._allocateTargets(); 24285 this._textureToCubeUV(texture, cubeUVRenderTarget); 24286 this._applyPMREM(cubeUVRenderTarget); 24287 this._cleanup(cubeUVRenderTarget); 24288 return cubeUVRenderTarget; 24289 } 24290 _allocateTargets() { 24291 const width = 3 * Math.max(this._cubeSize, 16 * 7); 24292 const height = 4 * this._cubeSize; 24293 const params = { 24294 magFilter: LinearFilter, 24295 minFilter: LinearFilter, 24296 generateMipmaps: false, 24297 type: HalfFloatType, 24298 format: RGBAFormat, 24299 colorSpace: LinearSRGBColorSpace, 24300 depthBuffer: false 24301 }; 24302 const cubeUVRenderTarget = _createRenderTarget(width, height, params); 24303 if (this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== width || this._pingPongRenderTarget.height !== height) { 24304 if (this._pingPongRenderTarget !== null) { 24305 this._dispose(); 24306 } 24307 this._pingPongRenderTarget = _createRenderTarget(width, height, params); 24308 const { _lodMax } = this; 24309 ({ lodMeshes: this._lodMeshes, sizeLods: this._sizeLods, sigmas: this._sigmas } = _createPlanes(_lodMax)); 24310 this._blurMaterial = _getBlurShader(_lodMax, width, height); 24311 this._ggxMaterial = _getGGXShader(_lodMax, width, height); 24312 } 24313 return cubeUVRenderTarget; 24314 } 24315 _compileMaterial(material) { 24316 const mesh = new Mesh(new BufferGeometry(), material); 24317 this._renderer.compile(mesh, _flatCamera); 24318 } 24319 _sceneToCubeUV(scene, near, far, cubeUVRenderTarget, position) { 24320 const fov2 = 90; 24321 const aspect2 = 1; 24322 const cubeCamera = new PerspectiveCamera(fov2, aspect2, near, far); 24323 const upSign = [1, -1, 1, 1, 1, 1]; 24324 const forwardSign = [1, 1, 1, -1, -1, -1]; 24325 const renderer = this._renderer; 24326 const originalAutoClear = renderer.autoClear; 24327 const toneMapping = renderer.toneMapping; 24328 renderer.getClearColor(_clearColor); 24329 renderer.toneMapping = NoToneMapping; 24330 renderer.autoClear = false; 24331 const reversedDepthBuffer = renderer.state.buffers.depth.getReversed(); 24332 if (reversedDepthBuffer) { 24333 renderer.setRenderTarget(cubeUVRenderTarget); 24334 renderer.clearDepth(); 24335 renderer.setRenderTarget(null); 24336 } 24337 if (this._backgroundBox === null) { 24338 this._backgroundBox = new Mesh( 24339 new BoxGeometry(), 24340 new MeshBasicMaterial({ 24341 name: "PMREM.Background", 24342 side: BackSide, 24343 depthWrite: false, 24344 depthTest: false 24345 }) 24346 ); 24347 } 24348 const backgroundBox = this._backgroundBox; 24349 const backgroundMaterial = backgroundBox.material; 24350 let useSolidColor = false; 24351 const background = scene.background; 24352 if (background) { 24353 if (background.isColor) { 24354 backgroundMaterial.color.copy(background); 24355 scene.background = null; 24356 useSolidColor = true; 24357 } 24358 } else { 24359 backgroundMaterial.color.copy(_clearColor); 24360 useSolidColor = true; 24361 } 24362 for (let i = 0; i < 6; i++) { 24363 const col = i % 3; 24364 if (col === 0) { 24365 cubeCamera.up.set(0, upSign[i], 0); 24366 cubeCamera.position.set(position.x, position.y, position.z); 24367 cubeCamera.lookAt(position.x + forwardSign[i], position.y, position.z); 24368 } else if (col === 1) { 24369 cubeCamera.up.set(0, 0, upSign[i]); 24370 cubeCamera.position.set(position.x, position.y, position.z); 24371 cubeCamera.lookAt(position.x, position.y + forwardSign[i], position.z); 24372 } else { 24373 cubeCamera.up.set(0, upSign[i], 0); 24374 cubeCamera.position.set(position.x, position.y, position.z); 24375 cubeCamera.lookAt(position.x, position.y, position.z + forwardSign[i]); 24376 } 24377 const size = this._cubeSize; 24378 _setViewport(cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size); 24379 renderer.setRenderTarget(cubeUVRenderTarget); 24380 if (useSolidColor) { 24381 renderer.render(backgroundBox, cubeCamera); 24382 } 24383 renderer.render(scene, cubeCamera); 24384 } 24385 renderer.toneMapping = toneMapping; 24386 renderer.autoClear = originalAutoClear; 24387 scene.background = background; 24388 } 24389 _textureToCubeUV(texture, cubeUVRenderTarget) { 24390 const renderer = this._renderer; 24391 const isCubeTexture = texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping; 24392 if (isCubeTexture) { 24393 if (this._cubemapMaterial === null) { 24394 this._cubemapMaterial = _getCubemapMaterial(); 24395 } 24396 this._cubemapMaterial.uniforms.flipEnvMap.value = texture.isRenderTargetTexture === false ? -1 : 1; 24397 } else { 24398 if (this._equirectMaterial === null) { 24399 this._equirectMaterial = _getEquirectMaterial(); 24400 } 24401 } 24402 const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial; 24403 const mesh = this._lodMeshes[0]; 24404 mesh.material = material; 24405 const uniforms = material.uniforms; 24406 uniforms["envMap"].value = texture; 24407 const size = this._cubeSize; 24408 _setViewport(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size); 24409 renderer.setRenderTarget(cubeUVRenderTarget); 24410 renderer.render(mesh, _flatCamera); 24411 } 24412 _applyPMREM(cubeUVRenderTarget) { 24413 const renderer = this._renderer; 24414 const autoClear = renderer.autoClear; 24415 renderer.autoClear = false; 24416 const n = this._lodMeshes.length; 24417 for (let i = 1; i < n; i++) { 24418 this._applyGGXFilter(cubeUVRenderTarget, i - 1, i); 24419 } 24420 renderer.autoClear = autoClear; 24421 } 24422 /** 24423 * Applies GGX VNDF importance sampling filter to generate a prefiltered environment map. 24424 * Uses Monte Carlo integration with VNDF importance sampling to accurately represent the 24425 * GGX BRDF for physically-based rendering. Reads from the previous LOD level and 24426 * applies incremental roughness filtering to avoid over-blurring. 24427 * 24428 * @private 24429 * @param {WebGLRenderTarget} cubeUVRenderTarget 24430 * @param {number} lodIn - Source LOD level to read from 24431 * @param {number} lodOut - Target LOD level to write to 24432 */ 24433 _applyGGXFilter(cubeUVRenderTarget, lodIn, lodOut) { 24434 const renderer = this._renderer; 24435 const pingPongRenderTarget = this._pingPongRenderTarget; 24436 const ggxMaterial = this._ggxMaterial; 24437 const ggxMesh = this._lodMeshes[lodOut]; 24438 ggxMesh.material = ggxMaterial; 24439 const ggxUniforms = ggxMaterial.uniforms; 24440 const targetRoughness = lodOut / (this._lodMeshes.length - 1); 24441 const sourceRoughness = lodIn / (this._lodMeshes.length - 1); 24442 const incrementalRoughness = Math.sqrt(targetRoughness * targetRoughness - sourceRoughness * sourceRoughness); 24443 const blurStrength = 0 + targetRoughness * 1.25; 24444 const adjustedRoughness = incrementalRoughness * blurStrength; 24445 const { _lodMax } = this; 24446 const outputSize = this._sizeLods[lodOut]; 24447 const x = 3 * outputSize * (lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0); 24448 const y = 4 * (this._cubeSize - outputSize); 24449 ggxUniforms["envMap"].value = cubeUVRenderTarget.texture; 24450 ggxUniforms["roughness"].value = adjustedRoughness; 24451 ggxUniforms["mipInt"].value = _lodMax - lodIn; 24452 _setViewport(pingPongRenderTarget, x, y, 3 * outputSize, 2 * outputSize); 24453 renderer.setRenderTarget(pingPongRenderTarget); 24454 renderer.render(ggxMesh, _flatCamera); 24455 ggxUniforms["envMap"].value = pingPongRenderTarget.texture; 24456 ggxUniforms["roughness"].value = 0; 24457 ggxUniforms["mipInt"].value = _lodMax - lodOut; 24458 _setViewport(cubeUVRenderTarget, x, y, 3 * outputSize, 2 * outputSize); 24459 renderer.setRenderTarget(cubeUVRenderTarget); 24460 renderer.render(ggxMesh, _flatCamera); 24461 } 24462 /** 24463 * This is a two-pass Gaussian blur for a cubemap. Normally this is done 24464 * vertically and horizontally, but this breaks down on a cube. Here we apply 24465 * the blur latitudinally (around the poles), and then longitudinally (towards 24466 * the poles) to approximate the orthogonally-separable blur. It is least 24467 * accurate at the poles, but still does a decent job. 24468 * 24469 * Used for initial scene blur in fromScene() method when sigma > 0. 24470 * 24471 * @private 24472 * @param {WebGLRenderTarget} cubeUVRenderTarget 24473 * @param {number} lodIn 24474 * @param {number} lodOut 24475 * @param {number} sigma 24476 * @param {Vector3} [poleAxis] 24477 */ 24478 _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) { 24479 const pingPongRenderTarget = this._pingPongRenderTarget; 24480 this._halfBlur( 24481 cubeUVRenderTarget, 24482 pingPongRenderTarget, 24483 lodIn, 24484 lodOut, 24485 sigma, 24486 "latitudinal", 24487 poleAxis 24488 ); 24489 this._halfBlur( 24490 pingPongRenderTarget, 24491 cubeUVRenderTarget, 24492 lodOut, 24493 lodOut, 24494 sigma, 24495 "longitudinal", 24496 poleAxis 24497 ); 24498 } 24499 _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) { 24500 const renderer = this._renderer; 24501 const blurMaterial = this._blurMaterial; 24502 if (direction !== "latitudinal" && direction !== "longitudinal") { 24503 error( 24504 "blur direction must be either latitudinal or longitudinal!" 24505 ); 24506 } 24507 const STANDARD_DEVIATIONS = 3; 24508 const blurMesh = this._lodMeshes[lodOut]; 24509 blurMesh.material = blurMaterial; 24510 const blurUniforms = blurMaterial.uniforms; 24511 const pixels = this._sizeLods[lodIn] - 1; 24512 const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : 2 * Math.PI / (2 * MAX_SAMPLES - 1); 24513 const sigmaPixels = sigmaRadians / radiansPerPixel; 24514 const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES; 24515 if (samples > MAX_SAMPLES) { 24516 warn(`sigmaRadians, ${sigmaRadians}, is too large and will clip, as it requested ${samples} samples when the maximum is set to ${MAX_SAMPLES}`); 24517 } 24518 const weights = []; 24519 let sum = 0; 24520 for (let i = 0; i < MAX_SAMPLES; ++i) { 24521 const x2 = i / sigmaPixels; 24522 const weight = Math.exp(-x2 * x2 / 2); 24523 weights.push(weight); 24524 if (i === 0) { 24525 sum += weight; 24526 } else if (i < samples) { 24527 sum += 2 * weight; 24528 } 24529 } 24530 for (let i = 0; i < weights.length; i++) { 24531 weights[i] = weights[i] / sum; 24532 } 24533 blurUniforms["envMap"].value = targetIn.texture; 24534 blurUniforms["samples"].value = samples; 24535 blurUniforms["weights"].value = weights; 24536 blurUniforms["latitudinal"].value = direction === "latitudinal"; 24537 if (poleAxis) { 24538 blurUniforms["poleAxis"].value = poleAxis; 24539 } 24540 const { _lodMax } = this; 24541 blurUniforms["dTheta"].value = radiansPerPixel; 24542 blurUniforms["mipInt"].value = _lodMax - lodIn; 24543 const outputSize = this._sizeLods[lodOut]; 24544 const x = 3 * outputSize * (lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0); 24545 const y = 4 * (this._cubeSize - outputSize); 24546 _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize); 24547 renderer.setRenderTarget(targetOut); 24548 renderer.render(blurMesh, _flatCamera); 24549 } 24550}; 24551function _createPlanes(lodMax) { 24552 const sizeLods = []; 24553 const sigmas = []; 24554 const lodMeshes = []; 24555 let lod = lodMax; 24556 const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; 24557 for (let i = 0; i < totalLods; i++) { 24558 const sizeLod = Math.pow(2, lod); 24559 sizeLods.push(sizeLod); 24560 let sigma = 1 / sizeLod; 24561 if (i > lodMax - LOD_MIN) { 24562 sigma = EXTRA_LOD_SIGMA[i - lodMax + LOD_MIN - 1]; 24563 } else if (i === 0) { 24564 sigma = 0; 24565 } 24566 sigmas.push(sigma); 24567 const texelSize = 1 / (sizeLod - 2); 24568 const min = -texelSize; 24569 const max = 1 + texelSize; 24570 const uv1 = [min, min, max, min, max, max, min, min, max, max, min, max]; 24571 const cubeFaces = 6; 24572 const vertices = 6; 24573 const positionSize = 3; 24574 const uvSize = 2; 24575 const faceIndexSize = 1; 24576 const position = new Float32Array(positionSize * vertices * cubeFaces); 24577 const uv = new Float32Array(uvSize * vertices * cubeFaces); 24578 const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces); 24579 for (let face = 0; face < cubeFaces; face++) { 24580 const x = face % 3 * 2 / 3 - 1; 24581 const y = face > 2 ? 0 : -1; 24582 const coordinates = [ 24583 x, 24584 y, 24585 0, 24586 x + 2 / 3, 24587 y, 24588 0, 24589 x + 2 / 3, 24590 y + 1, 24591 0, 24592 x, 24593 y, 24594 0, 24595 x + 2 / 3, 24596 y + 1, 24597 0, 24598 x, 24599 y + 1, 24600 0 24601 ]; 24602 position.set(coordinates, positionSize * vertices * face); 24603 uv.set(uv1, uvSize * vertices * face); 24604 const fill = [face, face, face, face, face, face]; 24605 faceIndex.set(fill, faceIndexSize * vertices * face); 24606 } 24607 const planes = new BufferGeometry(); 24608 planes.setAttribute("position", new BufferAttribute(position, positionSize)); 24609 planes.setAttribute("uv", new BufferAttribute(uv, uvSize)); 24610 planes.setAttribute("faceIndex", new BufferAttribute(faceIndex, faceIndexSize)); 24611 lodMeshes.push(new Mesh(planes, null)); 24612 if (lod > LOD_MIN) { 24613 lod--; 24614 } 24615 } 24616 return { lodMeshes, sizeLods, sigmas }; 24617} 24618function _createRenderTarget(width, height, params) { 24619 const cubeUVRenderTarget = new WebGLRenderTarget(width, height, params); 24620 cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; 24621 cubeUVRenderTarget.texture.name = "PMREM.cubeUv"; 24622 cubeUVRenderTarget.scissorTest = true; 24623 return cubeUVRenderTarget; 24624} 24625function _setViewport(target, x, y, width, height) { 24626 target.viewport.set(x, y, width, height); 24627 target.scissor.set(x, y, width, height); 24628} 24629function _getGGXShader(lodMax, width, height) { 24630 const shaderMaterial = new ShaderMaterial({ 24631 name: "PMREMGGXConvolution", 24632 defines: { 24633 "GGX_SAMPLES": GGX_SAMPLES, 24634 "CUBEUV_TEXEL_WIDTH": 1 / width, 24635 "CUBEUV_TEXEL_HEIGHT": 1 / height, 24636 "CUBEUV_MAX_MIP": `${lodMax}.0` 24637 }, 24638 uniforms: { 24639 "envMap": { value: null }, 24640 "roughness": { value: 0 }, 24641 "mipInt": { value: 0 } 24642 }, 24643 vertexShader: _getCommonVertexShader(), 24644 fragmentShader: ( 24645 /* glsl */ 24646 ` 24647 24648 precision highp float; 24649 precision highp int; 24650 24651 varying vec3 vOutputDirection; 24652 24653 uniform sampler2D envMap; 24654 uniform float roughness; 24655 uniform float mipInt; 24656 24657 #define ENVMAP_TYPE_CUBE_UV 24658 #include <cube_uv_reflection_fragment> 24659 24660 #define PI 3.14159265359 24661 24662 // Van der Corput radical inverse 24663 float radicalInverse_VdC(uint bits) { 24664 bits = (bits << 16u) | (bits >> 16u); 24665 bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); 24666 bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); 24667 bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); 24668 bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); 24669 return float(bits) * 2.3283064365386963e-10; // / 0x100000000 24670 } 24671 24672 // Hammersley sequence 24673 vec2 hammersley(uint i, uint N) { 24674 return vec2(float(i) / float(N), radicalInverse_VdC(i)); 24675 } 24676 24677 // GGX VNDF importance sampling (Eric Heitz 2018) 24678 // "Sampling the GGX Distribution of Visible Normals" 24679 // https://jcgt.org/published/0007/04/01/ 24680 vec3 importanceSampleGGX_VNDF(vec2 Xi, vec3 V, float roughness) { 24681 float alpha = roughness * roughness; 24682 24683 // Section 4.1: Orthonormal basis 24684 vec3 T1 = vec3(1.0, 0.0, 0.0); 24685 vec3 T2 = cross(V, T1); 24686 24687 // Section 4.2: Parameterization of projected area 24688 float r = sqrt(Xi.x); 24689 float phi = 2.0 * PI * Xi.y; 24690 float t1 = r * cos(phi); 24691 float t2 = r * sin(phi); 24692 float s = 0.5 * (1.0 + V.z); 24693 t2 = (1.0 - s) * sqrt(1.0 - t1 * t1) + s * t2; 24694 24695 // Section 4.3: Reprojection onto hemisphere 24696 vec3 Nh = t1 * T1 + t2 * T2 + sqrt(max(0.0, 1.0 - t1 * t1 - t2 * t2)) * V; 24697 24698 // Section 3.4: Transform back to ellipsoid configuration 24699 return normalize(vec3(alpha * Nh.x, alpha * Nh.y, max(0.0, Nh.z))); 24700 } 24701 24702 void main() { 24703 vec3 N = normalize(vOutputDirection); 24704 vec3 V = N; // Assume view direction equals normal for pre-filtering 24705 24706 vec3 prefilteredColor = vec3(0.0); 24707 float totalWeight = 0.0; 24708 24709 // For very low roughness, just sample the environment directly 24710 if (roughness < 0.001) { 24711 gl_FragColor = vec4(bilinearCubeUV(envMap, N, mipInt), 1.0); 24712 return; 24713 } 24714 24715 // Tangent space basis for VNDF sampling 24716 vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); 24717 vec3 tangent = normalize(cross(up, N)); 24718 vec3 bitangent = cross(N, tangent); 24719 24720 for(uint i = 0u; i < uint(GGX_SAMPLES); i++) { 24721 vec2 Xi = hammersley(i, uint(GGX_SAMPLES)); 24722 24723 // For PMREM, V = N, so in tangent space V is always (0, 0, 1) 24724 vec3 H_tangent = importanceSampleGGX_VNDF(Xi, vec3(0.0, 0.0, 1.0), roughness); 24725 24726 // Transform H back to world space 24727 vec3 H = normalize(tangent * H_tangent.x + bitangent * H_tangent.y + N * H_tangent.z); 24728 vec3 L = normalize(2.0 * dot(V, H) * H - V); 24729 24730 float NdotL = max(dot(N, L), 0.0); 24731 24732 if(NdotL > 0.0) { 24733 // Sample environment at fixed mip level 24734 // VNDF importance sampling handles the distribution filtering 24735 vec3 sampleColor = bilinearCubeUV(envMap, L, mipInt); 24736 24737 // Weight by NdotL for the split-sum approximation 24738 // VNDF PDF naturally accounts for the visible microfacet distribution 24739 prefilteredColor += sampleColor * NdotL; 24740 totalWeight += NdotL; 24741 } 24742 } 24743 24744 if (totalWeight > 0.0) { 24745 prefilteredColor = prefilteredColor / totalWeight; 24746 } 24747 24748 gl_FragColor = vec4(prefilteredColor, 1.0); 24749 } 24750 ` 24751 ), 24752 blending: NoBlending, 24753 depthTest: false, 24754 depthWrite: false 24755 }); 24756 return shaderMaterial; 24757} 24758function _getBlurShader(lodMax, width, height) { 24759 const weights = new Float32Array(MAX_SAMPLES); 24760 const poleAxis = new Vector3(0, 1, 0); 24761 const shaderMaterial = new ShaderMaterial({ 24762 name: "SphericalGaussianBlur", 24763 defines: { 24764 "n": MAX_SAMPLES, 24765 "CUBEUV_TEXEL_WIDTH": 1 / width, 24766 "CUBEUV_TEXEL_HEIGHT": 1 / height, 24767 "CUBEUV_MAX_MIP": `${lodMax}.0` 24768 }, 24769 uniforms: { 24770 "envMap": { value: null }, 24771 "samples": { value: 1 }, 24772 "weights": { value: weights }, 24773 "latitudinal": { value: false }, 24774 "dTheta": { value: 0 }, 24775 "mipInt": { value: 0 }, 24776 "poleAxis": { value: poleAxis } 24777 }, 24778 vertexShader: _getCommonVertexShader(), 24779 fragmentShader: ( 24780 /* glsl */ 24781 ` 24782 24783 precision mediump float; 24784 precision mediump int; 24785 24786 varying vec3 vOutputDirection; 24787 24788 uniform sampler2D envMap; 24789 uniform int samples; 24790 uniform float weights[ n ]; 24791 uniform bool latitudinal; 24792 uniform float dTheta; 24793 uniform float mipInt; 24794 uniform vec3 poleAxis; 24795 24796 #define ENVMAP_TYPE_CUBE_UV 24797 #include <cube_uv_reflection_fragment> 24798 24799 vec3 getSample( float theta, vec3 axis ) { 24800 24801 float cosTheta = cos( theta ); 24802 // Rodrigues' axis-angle rotation 24803 vec3 sampleDirection = vOutputDirection * cosTheta 24804 + cross( axis, vOutputDirection ) * sin( theta ) 24805 + axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta ); 24806 24807 return bilinearCubeUV( envMap, sampleDirection, mipInt ); 24808 24809 } 24810 24811 void main() { 24812 24813 vec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection ); 24814 24815 if ( all( equal( axis, vec3( 0.0 ) ) ) ) { 24816 24817 axis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x ); 24818 24819 } 24820 24821 axis = normalize( axis ); 24822 24823 gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 ); 24824 gl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis ); 24825 24826 for ( int i = 1; i < n; i++ ) { 24827 24828 if ( i >= samples ) { 24829 24830 break; 24831 24832 } 24833 24834 float theta = dTheta * float( i ); 24835 gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis ); 24836 gl_FragColor.rgb += weights[ i ] * getSample( theta, axis ); 24837 24838 } 24839 24840 } 24841 ` 24842 ), 24843 blending: NoBlending, 24844 depthTest: false, 24845 depthWrite: false 24846 }); 24847 return shaderMaterial; 24848} 24849function _getEquirectMaterial() { 24850 return new ShaderMaterial({ 24851 name: "EquirectangularToCubeUV", 24852 uniforms: { 24853 "envMap": { value: null } 24854 }, 24855 vertexShader: _getCommonVertexShader(), 24856 fragmentShader: ( 24857 /* glsl */ 24858 ` 24859 24860 precision mediump float; 24861 precision mediump int; 24862 24863 varying vec3 vOutputDirection; 24864 24865 uniform sampler2D envMap; 24866 24867 #include <common> 24868 24869 void main() { 24870 24871 vec3 outputDirection = normalize( vOutputDirection ); 24872 vec2 uv = equirectUv( outputDirection ); 24873 24874 gl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 ); 24875 24876 } 24877 ` 24878 ), 24879 blending: NoBlending, 24880 depthTest: false, 24881 depthWrite: false 24882 }); 24883} 24884function _getCubemapMaterial() { 24885 return new ShaderMaterial({ 24886 name: "CubemapToCubeUV", 24887 uniforms: { 24888 "envMap": { value: null }, 24889 "flipEnvMap": { value: -1 } 24890 }, 24891 vertexShader: _getCommonVertexShader(), 24892 fragmentShader: ( 24893 /* glsl */ 24894 ` 24895 24896 precision mediump float; 24897 precision mediump int; 24898 24899 uniform float flipEnvMap; 24900 24901 varying vec3 vOutputDirection; 24902 24903 uniform samplerCube envMap; 24904 24905 void main() { 24906 24907 gl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) ); 24908 24909 } 24910 ` 24911 ), 24912 blending: NoBlending, 24913 depthTest: false, 24914 depthWrite: false 24915 }); 24916} 24917function _getCommonVertexShader() { 24918 return ( 24919 /* glsl */ 24920 ` 24921 24922 precision mediump float; 24923 precision mediump int; 24924 24925 attribute float faceIndex; 24926 24927 varying vec3 vOutputDirection; 24928 24929 // RH coordinate system; PMREM face-indexing convention 24930 vec3 getDirection( vec2 uv, float face ) { 24931 24932 uv = 2.0 * uv - 1.0; 24933 24934 vec3 direction = vec3( uv, 1.0 ); 24935 24936 if ( face == 0.0 ) { 24937 24938 direction = direction.zyx; // ( 1, v, u ) pos x 24939 24940 } else if ( face == 1.0 ) { 24941 24942 direction = direction.xzy; 24943 direction.xz *= -1.0; // ( -u, 1, -v ) pos y 24944 24945 } else if ( face == 2.0 ) { 24946 24947 direction.x *= -1.0; // ( -u, v, 1 ) pos z 24948 24949 } else if ( face == 3.0 ) { 24950 24951 direction = direction.zyx; 24952 direction.xz *= -1.0; // ( -1, v, -u ) neg x 24953 24954 } else if ( face == 4.0 ) { 24955 24956 direction = direction.xzy; 24957 direction.xy *= -1.0; // ( -u, -1, v ) neg y 24958 24959 } else if ( face == 5.0 ) { 24960 24961 direction.z *= -1.0; // ( u, v, -1 ) neg z 24962 24963 } 24964 24965 return direction; 24966 24967 } 24968 24969 void main() { 24970 24971 vOutputDirection = getDirection( uv, faceIndex ); 24972 gl_Position = vec4( position, 1.0 ); 24973 24974 } 24975 ` 24976 ); 24977} 24978var WebGLCubeRenderTarget = class extends WebGLRenderTarget { 24979 /** 24980 * Constructs a new cube render target. 24981 * 24982 * @param {number} [size=1] - The size of the render target. 24983 * @param {RenderTarget~Options} [options] - The configuration object. 24984 */ 24985 constructor(size = 1, options = {}) { 24986 super(size, size, options); 24987 this.isWebGLCubeRenderTarget = true; 24988 const image = { width: size, height: size, depth: 1 }; 24989 const images = [image, image, image, image, image, image]; 24990 this.texture = new CubeTexture(images); 24991 this._setTextureOptions(options); 24992 this.texture.isRenderTargetTexture = true; 24993 } 24994 /** 24995 * Converts the given equirectangular texture to a cube map. 24996 * 24997 * @param {WebGLRenderer} renderer - The renderer. 24998 * @param {Texture} texture - The equirectangular texture. 24999 * @return {WebGLCubeRenderTarget} A reference to this cube render target. 25000 */ 25001 fromEquirectangularTexture(renderer, texture) { 25002 this.texture.type = texture.type; 25003 this.texture.colorSpace = texture.colorSpace; 25004 this.texture.generateMipmaps = texture.generateMipmaps; 25005 this.texture.minFilter = texture.minFilter; 25006 this.texture.magFilter = texture.magFilter; 25007 const shader = { 25008 uniforms: { 25009 tEquirect: { value: null } 25010 }, 25011 vertexShader: ( 25012 /* glsl */ 25013 ` 25014 25015 varying vec3 vWorldDirection; 25016 25017 vec3 transformDirection( in vec3 dir, in mat4 matrix ) { 25018 25019 return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); 25020 25021 } 25022 25023 void main() { 25024 25025 vWorldDirection = transformDirection( position, modelMatrix ); 25026 25027 #include <begin_vertex> 25028 #include <project_vertex> 25029 25030 } 25031 ` 25032 ), 25033 fragmentShader: ( 25034 /* glsl */ 25035 ` 25036 25037 uniform sampler2D tEquirect; 25038 25039 varying vec3 vWorldDirection; 25040 25041 #include <common> 25042 25043 void main() { 25044 25045 vec3 direction = normalize( vWorldDirection ); 25046 25047 vec2 sampleUV = equirectUv( direction ); 25048 25049 gl_FragColor = texture2D( tEquirect, sampleUV ); 25050 25051 } 25052 ` 25053 ) 25054 }; 25055 const geometry = new BoxGeometry(5, 5, 5); 25056 const material = new ShaderMaterial({ 25057 name: "CubemapFromEquirect", 25058 uniforms: cloneUniforms(shader.uniforms), 25059 vertexShader: shader.vertexShader, 25060 fragmentShader: shader.fragmentShader, 25061 side: BackSide, 25062 blending: NoBlending 25063 }); 25064 material.uniforms.tEquirect.value = texture; 25065 const mesh = new Mesh(geometry, material); 25066 const currentMinFilter = texture.minFilter; 25067 if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter; 25068 const camera = new CubeCamera(1, 10, this); 25069 camera.update(renderer, mesh); 25070 texture.minFilter = currentMinFilter; 25071 mesh.geometry.dispose(); 25072 mesh.material.dispose(); 25073 return this; 25074 } 25075 /** 25076 * Clears this cube render target. 25077 * 25078 * @param {WebGLRenderer} renderer - The renderer. 25079 * @param {boolean} [color=true] - Whether the color buffer should be cleared or not. 25080 * @param {boolean} [depth=true] - Whether the depth buffer should be cleared or not. 25081 * @param {boolean} [stencil=true] - Whether the stencil buffer should be cleared or not. 25082 */ 25083 clear(renderer, color = true, depth = true, stencil = true) { 25084 const currentRenderTarget = renderer.getRenderTarget(); 25085 for (let i = 0; i < 6; i++) { 25086 renderer.setRenderTarget(this, i); 25087 renderer.clear(color, depth, stencil); 25088 } 25089 renderer.setRenderTarget(currentRenderTarget); 25090 } 25091}; 25092function WebGLEnvironments(renderer) { 25093 let cubeMaps = /* @__PURE__ */ new WeakMap(); 25094 let pmremMaps = /* @__PURE__ */ new WeakMap(); 25095 let pmremGenerator = null; 25096 function get(texture, usePMREM = false) { 25097 if (texture === null || texture === void 0) return null; 25098 if (usePMREM) { 25099 return getPMREM(texture); 25100 } 25101 return getCube(texture); 25102 } 25103 function getCube(texture) { 25104 if (texture && texture.isTexture) { 25105 const mapping = texture.mapping; 25106 if (mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping) { 25107 if (cubeMaps.has(texture)) { 25108 const cubemap = cubeMaps.get(texture).texture; 25109 return mapTextureMapping(cubemap, texture.mapping); 25110 } else { 25111 const image = texture.image; 25112 if (image && image.height > 0) { 25113 const renderTarget = new WebGLCubeRenderTarget(image.height); 25114 renderTarget.fromEquirectangularTexture(renderer, texture); 25115 cubeMaps.set(texture, renderTarget); 25116 texture.addEventListener("dispose", onCubemapDispose); 25117 return mapTextureMapping(renderTarget.texture, texture.mapping); 25118 } else { 25119 return null; 25120 } 25121 } 25122 } 25123 } 25124 return texture; 25125 } 25126 function getPMREM(texture) { 25127 if (texture && texture.isTexture) { 25128 const mapping = texture.mapping; 25129 const isEquirectMap = mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping; 25130 const isCubeMap = mapping === CubeReflectionMapping || mapping === CubeRefractionMapping; 25131 if (isEquirectMap || isCubeMap) { 25132 let renderTarget = pmremMaps.get(texture); 25133 const currentPMREMVersion = renderTarget !== void 0 ? renderTarget.texture.pmremVersion : 0; 25134 if (texture.isRenderTargetTexture && texture.pmremVersion !== currentPMREMVersion) { 25135 if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer); 25136 renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture, renderTarget) : pmremGenerator.fromCubemap(texture, renderTarget); 25137 renderTarget.texture.pmremVersion = texture.pmremVersion; 25138 pmremMaps.set(texture, renderTarget); 25139 return renderTarget.texture; 25140 } else { 25141 if (renderTarget !== void 0) { 25142 return renderTarget.texture; 25143 } else { 25144 const image = texture.image; 25145 if (isEquirectMap && image && image.height > 0 || isCubeMap && image && isCubeTextureComplete(image)) { 25146 if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer); 25147 renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture) : pmremGenerator.fromCubemap(texture); 25148 renderTarget.texture.pmremVersion = texture.pmremVersion; 25149 pmremMaps.set(texture, renderTarget); 25150 texture.addEventListener("dispose", onPMREMDispose); 25151 return renderTarget.texture; 25152 } else { 25153 return null; 25154 } 25155 } 25156 } 25157 } 25158 } 25159 return texture; 25160 } 25161 function mapTextureMapping(texture, mapping) { 25162 if (mapping === EquirectangularReflectionMapping) { 25163 texture.mapping = CubeReflectionMapping; 25164 } else if (mapping === EquirectangularRefractionMapping) { 25165 texture.mapping = CubeRefractionMapping; 25166 } 25167 return texture; 25168 } 25169 function isCubeTextureComplete(image) { 25170 let count = 0; 25171 const length = 6; 25172 for (let i = 0; i < length; i++) { 25173 if (image[i] !== void 0) count++; 25174 } 25175 return count === length; 25176 } 25177 function onCubemapDispose(event) { 25178 const texture = event.target; 25179 texture.removeEventListener("dispose", onCubemapDispose); 25180 const cubemap = cubeMaps.get(texture); 25181 if (cubemap !== void 0) { 25182 cubeMaps.delete(texture); 25183 cubemap.dispose(); 25184 } 25185 } 25186 function onPMREMDispose(event) { 25187 const texture = event.target; 25188 texture.removeEventListener("dispose", onPMREMDispose); 25189 const pmrem = pmremMaps.get(texture); 25190 if (pmrem !== void 0) { 25191 pmremMaps.delete(texture); 25192 pmrem.dispose(); 25193 } 25194 } 25195 function dispose2() { 25196 cubeMaps = /* @__PURE__ */ new WeakMap(); 25197 pmremMaps = /* @__PURE__ */ new WeakMap(); 25198 if (pmremGenerator !== null) { 25199 pmremGenerator.dispose(); 25200 pmremGenerator = null; 25201 } 25202 } 25203 return { 25204 get, 25205 dispose: dispose2 25206 }; 25207} 25208function WebGLExtensions(gl) { 25209 const extensions = {}; 25210 function getExtension(name) { 25211 if (extensions[name] !== void 0) { 25212 return extensions[name]; 25213 } 25214 const extension = gl.getExtension(name); 25215 extensions[name] = extension; 25216 return extension; 25217 } 25218 return { 25219 has: function(name) { 25220 return getExtension(name) !== null; 25221 }, 25222 init: function() { 25223 getExtension("EXT_color_buffer_float"); 25224 getExtension("WEBGL_clip_cull_distance"); 25225 getExtension("OES_texture_float_linear"); 25226 getExtension("EXT_color_buffer_half_float"); 25227 getExtension("WEBGL_multisampled_render_to_texture"); 25228 getExtension("WEBGL_render_shared_exponent"); 25229 }, 25230 get: function(name) { 25231 const extension = getExtension(name); 25232 if (extension === null) { 25233 warnOnce("WebGLRenderer: " + name + " extension not supported."); 25234 } 25235 return extension; 25236 } 25237 }; 25238} 25239function WebGLGeometries(gl, attributes, info, bindingStates) { 25240 const geometries = {}; 25241 const wireframeAttributes = /* @__PURE__ */ new WeakMap(); 25242 function onGeometryDispose(event) { 25243 const geometry = event.target; 25244 if (geometry.index !== null) { 25245 attributes.remove(geometry.index); 25246 } 25247 for (const name in geometry.attributes) { 25248 attributes.remove(geometry.attributes[name]); 25249 } 25250 geometry.removeEventListener("dispose", onGeometryDispose); 25251 delete geometries[geometry.id]; 25252 const attribute = wireframeAttributes.get(geometry); 25253 if (attribute) { 25254 attributes.remove(attribute); 25255 wireframeAttributes.delete(geometry); 25256 } 25257 bindingStates.releaseStatesOfGeometry(geometry); 25258 if (geometry.isInstancedBufferGeometry === true) { 25259 delete geometry._maxInstanceCount; 25260 } 25261 info.memory.geometries--; 25262 } 25263 function get(object, geometry) { 25264 if (geometries[geometry.id] === true) return geometry; 25265 geometry.addEventListener("dispose", onGeometryDispose); 25266 geometries[geometry.id] = true; 25267 info.memory.geometries++; 25268 return geometry; 25269 } 25270 function update(geometry) { 25271 const geometryAttributes = geometry.attributes; 25272 for (const name in geometryAttributes) { 25273 attributes.update(geometryAttributes[name], gl.ARRAY_BUFFER); 25274 } 25275 } 25276 function updateWireframeAttribute(geometry) { 25277 const indices = []; 25278 const geometryIndex = geometry.index; 25279 const geometryPosition = geometry.attributes.position; 25280 let version = 0; 25281 if (geometryPosition === void 0) { 25282 return; 25283 } 25284 if (geometryIndex !== null) { 25285 const array = geometryIndex.array; 25286 version = geometryIndex.version; 25287 for (let i = 0, l = array.length; i < l; i += 3) { 25288 const a = array[i + 0]; 25289 const b = array[i + 1]; 25290 const c = array[i + 2]; 25291 indices.push(a, b, b, c, c, a); 25292 } 25293 } else { 25294 const array = geometryPosition.array; 25295 version = geometryPosition.version; 25296 for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) { 25297 const a = i + 0; 25298 const b = i + 1; 25299 const c = i + 2; 25300 indices.push(a, b, b, c, c, a); 25301 } 25302 } 25303 const attribute = new (geometryPosition.count >= 65535 ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1); 25304 attribute.version = version; 25305 const previousAttribute = wireframeAttributes.get(geometry); 25306 if (previousAttribute) attributes.remove(previousAttribute); 25307 wireframeAttributes.set(geometry, attribute); 25308 } 25309 function getWireframeAttribute(geometry) { 25310 const currentAttribute = wireframeAttributes.get(geometry); 25311 if (currentAttribute) { 25312 const geometryIndex = geometry.index; 25313 if (geometryIndex !== null) { 25314 if (currentAttribute.version < geometryIndex.version) { 25315 updateWireframeAttribute(geometry); 25316 } 25317 } 25318 } else { 25319 updateWireframeAttribute(geometry); 25320 } 25321 return wireframeAttributes.get(geometry); 25322 } 25323 return { 25324 get, 25325 update, 25326 getWireframeAttribute 25327 }; 25328} 25329function WebGLIndexedBufferRenderer(gl, extensions, info) { 25330 let mode; 25331 function setMode(value) { 25332 mode = value; 25333 } 25334 let type, bytesPerElement; 25335 function setIndex(value) { 25336 type = value.type; 25337 bytesPerElement = value.bytesPerElement; 25338 } 25339 function render2(start, count) { 25340 gl.drawElements(mode, count, type, start * bytesPerElement); 25341 info.update(count, mode, 1); 25342 } 25343 function renderInstances(start, count, primcount) { 25344 if (primcount === 0) return; 25345 gl.drawElementsInstanced(mode, count, type, start * bytesPerElement, primcount); 25346 info.update(count, mode, primcount); 25347 } 25348 function renderMultiDraw(starts, counts, drawCount) { 25349 if (drawCount === 0) return; 25350 const extension = extensions.get("WEBGL_multi_draw"); 25351 extension.multiDrawElementsWEBGL(mode, counts, 0, type, starts, 0, drawCount); 25352 let elementCount = 0; 25353 for (let i = 0; i < drawCount; i++) { 25354 elementCount += counts[i]; 25355 } 25356 info.update(elementCount, mode, 1); 25357 } 25358 this.setMode = setMode; 25359 this.setIndex = setIndex; 25360 this.render = render2; 25361 this.renderInstances = renderInstances; 25362 this.renderMultiDraw = renderMultiDraw; 25363} 25364function WebGLInfo(gl) { 25365 const memory = { 25366 geometries: 0, 25367 textures: 0 25368 }; 25369 const render2 = { 25370 frame: 0, 25371 calls: 0, 25372 triangles: 0, 25373 points: 0, 25374 lines: 0 25375 }; 25376 function update(count, mode, instanceCount) { 25377 render2.calls++; 25378 switch (mode) { 25379 case gl.TRIANGLES: 25380 render2.triangles += instanceCount * (count / 3); 25381 break; 25382 case gl.LINES: 25383 render2.lines += instanceCount * (count / 2); 25384 break; 25385 case gl.LINE_STRIP: 25386 render2.lines += instanceCount * (count - 1); 25387 break; 25388 case gl.LINE_LOOP: 25389 render2.lines += instanceCount * count; 25390 break; 25391 case gl.POINTS: 25392 render2.points += instanceCount * count; 25393 break; 25394 default: 25395 error("WebGLInfo: Unknown draw mode:", mode); 25396 break; 25397 } 25398 } 25399 function reset2() { 25400 render2.calls = 0; 25401 render2.triangles = 0; 25402 render2.points = 0; 25403 render2.lines = 0; 25404 } 25405 return { 25406 memory, 25407 render: render2, 25408 programs: null, 25409 autoReset: true, 25410 reset: reset2, 25411 update 25412 }; 25413} 25414function WebGLMorphtargets(gl, capabilities, textures) { 25415 const morphTextures = /* @__PURE__ */ new WeakMap(); 25416 const morph = new Vector4(); 25417 function update(object, geometry, program) { 25418 const objectInfluences = object.morphTargetInfluences; 25419 const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; 25420 const morphTargetsCount = morphAttribute !== void 0 ? morphAttribute.length : 0; 25421 let entry = morphTextures.get(geometry); 25422 if (entry === void 0 || entry.count !== morphTargetsCount) { 25423 let disposeTexture = function() { 25424 texture.dispose(); 25425 morphTextures.delete(geometry); 25426 geometry.removeEventListener("dispose", disposeTexture); 25427 }; 25428 if (entry !== void 0) entry.texture.dispose(); 25429 const hasMorphPosition = geometry.morphAttributes.position !== void 0; 25430 const hasMorphNormals = geometry.morphAttributes.normal !== void 0; 25431 const hasMorphColors = geometry.morphAttributes.color !== void 0; 25432 const morphTargets = geometry.morphAttributes.position || []; 25433 const morphNormals = geometry.morphAttributes.normal || []; 25434 const morphColors = geometry.morphAttributes.color || []; 25435 let vertexDataCount = 0; 25436 if (hasMorphPosition === true) vertexDataCount = 1; 25437 if (hasMorphNormals === true) vertexDataCount = 2; 25438 if (hasMorphColors === true) vertexDataCount = 3; 25439 let width = geometry.attributes.position.count * vertexDataCount; 25440 let height = 1; 25441 if (width > capabilities.maxTextureSize) { 25442 height = Math.ceil(width / capabilities.maxTextureSize); 25443 width = capabilities.maxTextureSize; 25444 } 25445 const buffer = new Float32Array(width * height * 4 * morphTargetsCount); 25446 const texture = new DataArrayTexture(buffer, width, height, morphTargetsCount); 25447 texture.type = FloatType; 25448 texture.needsUpdate = true; 25449 const vertexDataStride = vertexDataCount * 4; 25450 for (let i = 0; i < morphTargetsCount; i++) { 25451 const morphTarget = morphTargets[i]; 25452 const morphNormal = morphNormals[i]; 25453 const morphColor = morphColors[i]; 25454 const offset = width * height * 4 * i; 25455 for (let j = 0; j < morphTarget.count; j++) { 25456 const stride = j * vertexDataStride; 25457 if (hasMorphPosition === true) { 25458 morph.fromBufferAttribute(morphTarget, j); 25459 buffer[offset + stride + 0] = morph.x; 25460 buffer[offset + stride + 1] = morph.y; 25461 buffer[offset + stride + 2] = morph.z; 25462 buffer[offset + stride + 3] = 0; 25463 } 25464 if (hasMorphNormals === true) { 25465 morph.fromBufferAttribute(morphNormal, j); 25466 buffer[offset + stride + 4] = morph.x; 25467 buffer[offset + stride + 5] = morph.y; 25468 buffer[offset + stride + 6] = morph.z; 25469 buffer[offset + stride + 7] = 0; 25470 } 25471 if (hasMorphColors === true) { 25472 morph.fromBufferAttribute(morphColor, j); 25473 buffer[offset + stride + 8] = morph.x; 25474 buffer[offset + stride + 9] = morph.y; 25475 buffer[offset + stride + 10] = morph.z; 25476 buffer[offset + stride + 11] = morphColor.itemSize === 4 ? morph.w : 1; 25477 } 25478 } 25479 } 25480 entry = { 25481 count: morphTargetsCount, 25482 texture, 25483 size: new Vector2(width, height) 25484 }; 25485 morphTextures.set(geometry, entry); 25486 geometry.addEventListener("dispose", disposeTexture); 25487 } 25488 if (object.isInstancedMesh === true && object.morphTexture !== null) { 25489 program.getUniforms().setValue(gl, "morphTexture", object.morphTexture, textures); 25490 } else { 25491 let morphInfluencesSum = 0; 25492 for (let i = 0; i < objectInfluences.length; i++) { 25493 morphInfluencesSum += objectInfluences[i]; 25494 } 25495 const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; 25496 program.getUniforms().setValue(gl, "morphTargetBaseInfluence", morphBaseInfluence); 25497 program.getUniforms().setValue(gl, "morphTargetInfluences", objectInfluences); 25498 } 25499 program.getUniforms().setValue(gl, "morphTargetsTexture", entry.texture, textures); 25500 program.getUniforms().setValue(gl, "morphTargetsTextureSize", entry.size); 25501 } 25502 return { 25503 update 25504 }; 25505} 25506function WebGLObjects(gl, geometries, attributes, bindingStates, info) { 25507 let updateMap = /* @__PURE__ */ new WeakMap(); 25508 function update(object) { 25509 const frame = info.render.frame; 25510 const geometry = object.geometry; 25511 const buffergeometry = geometries.get(object, geometry); 25512 if (updateMap.get(buffergeometry) !== frame) { 25513 geometries.update(buffergeometry); 25514 updateMap.set(buffergeometry, frame); 25515 } 25516 if (object.isInstancedMesh) { 25517 if (object.hasEventListener("dispose", onInstancedMeshDispose) === false) { 25518 object.addEventListener("dispose", onInstancedMeshDispose); 25519 } 25520 if (updateMap.get(object) !== frame) { 25521 attributes.update(object.instanceMatrix, gl.ARRAY_BUFFER); 25522 if (object.instanceColor !== null) { 25523 attributes.update(object.instanceColor, gl.ARRAY_BUFFER); 25524 } 25525 updateMap.set(object, frame); 25526 } 25527 } 25528 if (object.isSkinnedMesh) { 25529 const skeleton = object.skeleton; 25530 if (updateMap.get(skeleton) !== frame) { 25531 skeleton.update(); 25532 updateMap.set(skeleton, frame); 25533 } 25534 } 25535 return buffergeometry; 25536 } 25537 function dispose2() { 25538 updateMap = /* @__PURE__ */ new WeakMap(); 25539 } 25540 function onInstancedMeshDispose(event) { 25541 const instancedMesh = event.target; 25542 instancedMesh.removeEventListener("dispose", onInstancedMeshDispose); 25543 bindingStates.releaseStatesOfObject(instancedMesh); 25544 attributes.remove(instancedMesh.instanceMatrix); 25545 if (instancedMesh.instanceColor !== null) attributes.remove(instancedMesh.instanceColor); 25546 } 25547 return { 25548 update, 25549 dispose: dispose2 25550 }; 25551} 25552var toneMappingMap = { 25553 [LinearToneMapping]: "LINEAR_TONE_MAPPING", 25554 [ReinhardToneMapping]: "REINHARD_TONE_MAPPING", 25555 [CineonToneMapping]: "CINEON_TONE_MAPPING", 25556 [ACESFilmicToneMapping]: "ACES_FILMIC_TONE_MAPPING", 25557 [AgXToneMapping]: "AGX_TONE_MAPPING", 25558 [NeutralToneMapping]: "NEUTRAL_TONE_MAPPING", 25559 [CustomToneMapping]: "CUSTOM_TONE_MAPPING" 25560}; 25561function WebGLOutput(type, width, height, depth, stencil) { 25562 const targetA = new WebGLRenderTarget(width, height, { 25563 type, 25564 depthBuffer: depth, 25565 stencilBuffer: stencil, 25566 depthTexture: depth ? new DepthTexture(width, height) : void 0 25567 }); 25568 const targetB = new WebGLRenderTarget(width, height, { 25569 type: HalfFloatType, 25570 depthBuffer: false, 25571 stencilBuffer: false 25572 }); 25573 const geometry = new BufferGeometry(); 25574 geometry.setAttribute("position", new Float32BufferAttribute([-1, 3, 0, -1, -1, 0, 3, -1, 0], 3)); 25575 geometry.setAttribute("uv", new Float32BufferAttribute([0, 2, 0, 0, 2, 0], 2)); 25576 const material = new RawShaderMaterial({ 25577 uniforms: { 25578 tDiffuse: { value: null } 25579 }, 25580 vertexShader: ( 25581 /* glsl */ 25582 ` 25583 precision highp float; 25584 25585 uniform mat4 modelViewMatrix; 25586 uniform mat4 projectionMatrix; 25587 25588 attribute vec3 position; 25589 attribute vec2 uv; 25590 25591 varying vec2 vUv; 25592 25593 void main() { 25594 vUv = uv; 25595 gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 25596 }` 25597 ), 25598 fragmentShader: ( 25599 /* glsl */ 25600 ` 25601 precision highp float; 25602 25603 uniform sampler2D tDiffuse; 25604 25605 varying vec2 vUv; 25606 25607 #include <tonemapping_pars_fragment> 25608 #include <colorspace_pars_fragment> 25609 25610 void main() { 25611 gl_FragColor = texture2D( tDiffuse, vUv ); 25612 25613 #ifdef LINEAR_TONE_MAPPING 25614 gl_FragColor.rgb = LinearToneMapping( gl_FragColor.rgb ); 25615 #elif defined( REINHARD_TONE_MAPPING ) 25616 gl_FragColor.rgb = ReinhardToneMapping( gl_FragColor.rgb ); 25617 #elif defined( CINEON_TONE_MAPPING ) 25618 gl_FragColor.rgb = CineonToneMapping( gl_FragColor.rgb ); 25619 #elif defined( ACES_FILMIC_TONE_MAPPING ) 25620 gl_FragColor.rgb = ACESFilmicToneMapping( gl_FragColor.rgb ); 25621 #elif defined( AGX_TONE_MAPPING ) 25622 gl_FragColor.rgb = AgXToneMapping( gl_FragColor.rgb ); 25623 #elif defined( NEUTRAL_TONE_MAPPING ) 25624 gl_FragColor.rgb = NeutralToneMapping( gl_FragColor.rgb ); 25625 #elif defined( CUSTOM_TONE_MAPPING ) 25626 gl_FragColor.rgb = CustomToneMapping( gl_FragColor.rgb ); 25627 #endif 25628 25629 #ifdef SRGB_TRANSFER 25630 gl_FragColor = sRGBTransferOETF( gl_FragColor ); 25631 #endif 25632 }` 25633 ), 25634 depthTest: false, 25635 depthWrite: false 25636 }); 25637 const mesh = new Mesh(geometry, material); 25638 const camera = new OrthographicCamera(-1, 1, 1, -1, 0, 1); 25639 let _outputColorSpace = null; 25640 let _outputToneMapping = null; 25641 let _isCompositing = false; 25642 let _savedToneMapping; 25643 let _savedRenderTarget = null; 25644 let _effects = []; 25645 let _hasRenderPass = false; 25646 this.setSize = function(width2, height2) { 25647 targetA.setSize(width2, height2); 25648 targetB.setSize(width2, height2); 25649 for (let i = 0; i < _effects.length; i++) { 25650 const effect = _effects[i]; 25651 if (effect.setSize) effect.setSize(width2, height2); 25652 } 25653 }; 25654 this.setEffects = function(effects) { 25655 _effects = effects; 25656 _hasRenderPass = _effects.length > 0 && _effects[0].isRenderPass === true; 25657 const width2 = targetA.width; 25658 const height2 = targetA.height; 25659 for (let i = 0; i < _effects.length; i++) { 25660 const effect = _effects[i]; 25661 if (effect.setSize) effect.setSize(width2, height2); 25662 } 25663 }; 25664 this.begin = function(renderer, renderTarget) { 25665 if (_isCompositing) return false; 25666 if (renderer.toneMapping === NoToneMapping && _effects.length === 0) return false; 25667 _savedRenderTarget = renderTarget; 25668 if (renderTarget !== null) { 25669 const width2 = renderTarget.width; 25670 const height2 = renderTarget.height; 25671 if (targetA.width !== width2 || targetA.height !== height2) { 25672 this.setSize(width2, height2); 25673 } 25674 } 25675 if (_hasRenderPass === false) { 25676 renderer.setRenderTarget(targetA); 25677 } 25678 _savedToneMapping = renderer.toneMapping; 25679 renderer.toneMapping = NoToneMapping; 25680 return true; 25681 }; 25682 this.hasRenderPass = function() { 25683 return _hasRenderPass; 25684 }; 25685 this.end = function(renderer, deltaTime) { 25686 renderer.toneMapping = _savedToneMapping; 25687 _isCompositing = true; 25688 let readBuffer = targetA; 25689 let writeBuffer = targetB; 25690 for (let i = 0; i < _effects.length; i++) { 25691 const effect = _effects[i]; 25692 if (effect.enabled === false) continue; 25693 effect.render(renderer, writeBuffer, readBuffer, deltaTime); 25694 if (effect.needsSwap !== false) { 25695 const temp = readBuffer; 25696 readBuffer = writeBuffer; 25697 writeBuffer = temp; 25698 } 25699 } 25700 if (_outputColorSpace !== renderer.outputColorSpace || _outputToneMapping !== renderer.toneMapping) { 25701 _outputColorSpace = renderer.outputColorSpace; 25702 _outputToneMapping = renderer.toneMapping; 25703 material.defines = {}; 25704 if (ColorManagement.getTransfer(_outputColorSpace) === SRGBTransfer) material.defines.SRGB_TRANSFER = ""; 25705 const toneMapping = toneMappingMap[_outputToneMapping]; 25706 if (toneMapping) material.defines[toneMapping] = ""; 25707 material.needsUpdate = true; 25708 } 25709 material.uniforms.tDiffuse.value = readBuffer.texture; 25710 renderer.setRenderTarget(_savedRenderTarget); 25711 renderer.render(mesh, camera); 25712 _savedRenderTarget = null; 25713 _isCompositing = false; 25714 }; 25715 this.isCompositing = function() { 25716 return _isCompositing; 25717 }; 25718 this.dispose = function() { 25719 if (targetA.depthTexture) targetA.depthTexture.dispose(); 25720 targetA.dispose(); 25721 targetB.dispose(); 25722 geometry.dispose(); 25723 material.dispose(); 25724 }; 25725} 25726var emptyTexture = /* @__PURE__ */ new Texture(); 25727var emptyShadowTexture = /* @__PURE__ */ new DepthTexture(1, 1); 25728var emptyArrayTexture = /* @__PURE__ */ new DataArrayTexture(); 25729var empty3dTexture = /* @__PURE__ */ new Data3DTexture(); 25730var emptyCubeTexture = /* @__PURE__ */ new CubeTexture(); 25731var arrayCacheF32 = []; 25732var arrayCacheI32 = []; 25733var mat4array = new Float32Array(16); 25734var mat3array = new Float32Array(9); 25735var mat2array = new Float32Array(4); 25736function flatten(array, nBlocks, blockSize) { 25737 const firstElem = array[0]; 25738 if (firstElem <= 0 || firstElem > 0) return array; 25739 const n = nBlocks * blockSize; 25740 let r = arrayCacheF32[n]; 25741 if (r === void 0) { 25742 r = new Float32Array(n); 25743 arrayCacheF32[n] = r; 25744 } 25745 if (nBlocks !== 0) { 25746 firstElem.toArray(r, 0); 25747 for (let i = 1, offset = 0; i !== nBlocks; ++i) { 25748 offset += blockSize; 25749 array[i].toArray(r, offset); 25750 } 25751 } 25752 return r; 25753} 25754function arraysEqual(a, b) { 25755 if (a.length !== b.length) return false; 25756 for (let i = 0, l = a.length; i < l; i++) { 25757 if (a[i] !== b[i]) return false; 25758 } 25759 return true; 25760} 25761function copyArray(a, b) { 25762 for (let i = 0, l = b.length; i < l; i++) { 25763 a[i] = b[i]; 25764 } 25765} 25766function allocTexUnits(textures, n) { 25767 let r = arrayCacheI32[n]; 25768 if (r === void 0) { 25769 r = new Int32Array(n); 25770 arrayCacheI32[n] = r; 25771 } 25772 for (let i = 0; i !== n; ++i) { 25773 r[i] = textures.allocateTextureUnit(); 25774 } 25775 return r; 25776} 25777function setValueV1f(gl, v) { 25778 const cache = this.cache; 25779 if (cache[0] === v) return; 25780 gl.uniform1f(this.addr, v); 25781 cache[0] = v; 25782} 25783function setValueV2f(gl, v) { 25784 const cache = this.cache; 25785 if (v.x !== void 0) { 25786 if (cache[0] !== v.x || cache[1] !== v.y) { 25787 gl.uniform2f(this.addr, v.x, v.y); 25788 cache[0] = v.x; 25789 cache[1] = v.y; 25790 } 25791 } else { 25792 if (arraysEqual(cache, v)) return; 25793 gl.uniform2fv(this.addr, v); 25794 copyArray(cache, v); 25795 } 25796} 25797function setValueV3f(gl, v) { 25798 const cache = this.cache; 25799 if (v.x !== void 0) { 25800 if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) { 25801 gl.uniform3f(this.addr, v.x, v.y, v.z); 25802 cache[0] = v.x; 25803 cache[1] = v.y; 25804 cache[2] = v.z; 25805 } 25806 } else if (v.r !== void 0) { 25807 if (cache[0] !== v.r || cache[1] !== v.g || cache[2] !== v.b) { 25808 gl.uniform3f(this.addr, v.r, v.g, v.b); 25809 cache[0] = v.r; 25810 cache[1] = v.g; 25811 cache[2] = v.b; 25812 } 25813 } else { 25814 if (arraysEqual(cache, v)) return; 25815 gl.uniform3fv(this.addr, v); 25816 copyArray(cache, v); 25817 } 25818} 25819function setValueV4f(gl, v) { 25820 const cache = this.cache; 25821 if (v.x !== void 0) { 25822 if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z || cache[3] !== v.w) { 25823 gl.uniform4f(this.addr, v.x, v.y, v.z, v.w); 25824 cache[0] = v.x; 25825 cache[1] = v.y; 25826 cache[2] = v.z; 25827 cache[3] = v.w; 25828 } 25829 } else { 25830 if (arraysEqual(cache, v)) return; 25831 gl.uniform4fv(this.addr, v); 25832 copyArray(cache, v); 25833 } 25834} 25835function setValueM2(gl, v) { 25836 const cache = this.cache; 25837 const elements = v.elements; 25838 if (elements === void 0) { 25839 if (arraysEqual(cache, v)) return; 25840 gl.uniformMatrix2fv(this.addr, false, v); 25841 copyArray(cache, v); 25842 } else { 25843 if (arraysEqual(cache, elements)) return; 25844 mat2array.set(elements); 25845 gl.uniformMatrix2fv(this.addr, false, mat2array); 25846 copyArray(cache, elements); 25847 } 25848} 25849function setValueM3(gl, v) { 25850 const cache = this.cache; 25851 const elements = v.elements; 25852 if (elements === void 0) { 25853 if (arraysEqual(cache, v)) return; 25854 gl.uniformMatrix3fv(this.addr, false, v); 25855 copyArray(cache, v); 25856 } else { 25857 if (arraysEqual(cache, elements)) return; 25858 mat3array.set(elements); 25859 gl.uniformMatrix3fv(this.addr, false, mat3array); 25860 copyArray(cache, elements); 25861 } 25862} 25863function setValueM4(gl, v) { 25864 const cache = this.cache; 25865 const elements = v.elements; 25866 if (elements === void 0) { 25867 if (arraysEqual(cache, v)) return; 25868 gl.uniformMatrix4fv(this.addr, false, v); 25869 copyArray(cache, v); 25870 } else { 25871 if (arraysEqual(cache, elements)) return; 25872 mat4array.set(elements); 25873 gl.uniformMatrix4fv(this.addr, false, mat4array); 25874 copyArray(cache, elements); 25875 } 25876} 25877function setValueV1i(gl, v) { 25878 const cache = this.cache; 25879 if (cache[0] === v) return; 25880 gl.uniform1i(this.addr, v); 25881 cache[0] = v; 25882} 25883function setValueV2i(gl, v) { 25884 const cache = this.cache; 25885 if (v.x !== void 0) { 25886 if (cache[0] !== v.x || cache[1] !== v.y) { 25887 gl.uniform2i(this.addr, v.x, v.y); 25888 cache[0] = v.x; 25889 cache[1] = v.y; 25890 } 25891 } else { 25892 if (arraysEqual(cache, v)) return; 25893 gl.uniform2iv(this.addr, v); 25894 copyArray(cache, v); 25895 } 25896} 25897function setValueV3i(gl, v) { 25898 const cache = this.cache; 25899 if (v.x !== void 0) { 25900 if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) { 25901 gl.uniform3i(this.addr, v.x, v.y, v.z); 25902 cache[0] = v.x; 25903 cache[1] = v.y; 25904 cache[2] = v.z; 25905 } 25906 } else { 25907 if (arraysEqual(cache, v)) return; 25908 gl.uniform3iv(this.addr, v); 25909 copyArray(cache, v); 25910 } 25911} 25912function setValueV4i(gl, v) { 25913 const cache = this.cache; 25914 if (v.x !== void 0) { 25915 if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z || cache[3] !== v.w) { 25916 gl.uniform4i(this.addr, v.x, v.y, v.z, v.w); 25917 cache[0] = v.x; 25918 cache[1] = v.y; 25919 cache[2] = v.z; 25920 cache[3] = v.w; 25921 } 25922 } else { 25923 if (arraysEqual(cache, v)) return; 25924 gl.uniform4iv(this.addr, v); 25925 copyArray(cache, v); 25926 } 25927} 25928function setValueV1ui(gl, v) { 25929 const cache = this.cache; 25930 if (cache[0] === v) return; 25931 gl.uniform1ui(this.addr, v); 25932 cache[0] = v; 25933} 25934function setValueV2ui(gl, v) { 25935 const cache = this.cache; 25936 if (v.x !== void 0) { 25937 if (cache[0] !== v.x || cache[1] !== v.y) { 25938 gl.uniform2ui(this.addr, v.x, v.y); 25939 cache[0] = v.x; 25940 cache[1] = v.y; 25941 } 25942 } else { 25943 if (arraysEqual(cache, v)) return; 25944 gl.uniform2uiv(this.addr, v); 25945 copyArray(cache, v); 25946 } 25947} 25948function setValueV3ui(gl, v) { 25949 const cache = this.cache; 25950 if (v.x !== void 0) { 25951 if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) { 25952 gl.uniform3ui(this.addr, v.x, v.y, v.z); 25953 cache[0] = v.x; 25954 cache[1] = v.y; 25955 cache[2] = v.z; 25956 } 25957 } else { 25958 if (arraysEqual(cache, v)) return; 25959 gl.uniform3uiv(this.addr, v); 25960 copyArray(cache, v); 25961 } 25962} 25963function setValueV4ui(gl, v) { 25964 const cache = this.cache; 25965 if (v.x !== void 0) { 25966 if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z || cache[3] !== v.w) { 25967 gl.uniform4ui(this.addr, v.x, v.y, v.z, v.w); 25968 cache[0] = v.x; 25969 cache[1] = v.y; 25970 cache[2] = v.z; 25971 cache[3] = v.w; 25972 } 25973 } else { 25974 if (arraysEqual(cache, v)) return; 25975 gl.uniform4uiv(this.addr, v); 25976 copyArray(cache, v); 25977 } 25978} 25979function setValueT1(gl, v, textures) { 25980 const cache = this.cache; 25981 const unit = textures.allocateTextureUnit(); 25982 if (cache[0] !== unit) { 25983 gl.uniform1i(this.addr, unit); 25984 cache[0] = unit; 25985 } 25986 let emptyTexture2D; 25987 if (this.type === gl.SAMPLER_2D_SHADOW) { 25988 emptyShadowTexture.compareFunction = textures.isReversedDepthBuffer() ? GreaterEqualCompare : LessEqualCompare; 25989 emptyTexture2D = emptyShadowTexture; 25990 } else { 25991 emptyTexture2D = emptyTexture; 25992 } 25993 textures.setTexture2D(v || emptyTexture2D, unit); 25994} 25995function setValueT3D1(gl, v, textures) { 25996 const cache = this.cache; 25997 const unit = textures.allocateTextureUnit(); 25998 if (cache[0] !== unit) { 25999 gl.uniform1i(this.addr, unit); 26000 cache[0] = unit; 26001 } 26002 textures.setTexture3D(v || empty3dTexture, unit); 26003} 26004function setValueT6(gl, v, textures) { 26005 const cache = this.cache; 26006 const unit = textures.allocateTextureUnit(); 26007 if (cache[0] !== unit) { 26008 gl.uniform1i(this.addr, unit); 26009 cache[0] = unit; 26010 } 26011 textures.setTextureCube(v || emptyCubeTexture, unit); 26012} 26013function setValueT2DArray1(gl, v, textures) { 26014 const cache = this.cache; 26015 const unit = textures.allocateTextureUnit(); 26016 if (cache[0] !== unit) { 26017 gl.uniform1i(this.addr, unit); 26018 cache[0] = unit; 26019 } 26020 textures.setTexture2DArray(v || emptyArrayTexture, unit); 26021} 26022function getSingularSetter(type) { 26023 switch (type) { 26024 case 5126: 26025 return setValueV1f; 26026 // FLOAT 26027 case 35664: 26028 return setValueV2f; 26029 // _VEC2 26030 case 35665: 26031 return setValueV3f; 26032 // _VEC3 26033 case 35666: 26034 return setValueV4f; 26035 // _VEC4 26036 case 35674: 26037 return setValueM2; 26038 // _MAT2 26039 case 35675: 26040 return setValueM3; 26041 // _MAT3 26042 case 35676: 26043 return setValueM4; 26044 // _MAT4 26045 case 5124: 26046 case 35670: 26047 return setValueV1i; 26048 // INT, BOOL 26049 case 35667: 26050 case 35671: 26051 return setValueV2i; 26052 // _VEC2 26053 case 35668: 26054 case 35672: 26055 return setValueV3i; 26056 // _VEC3 26057 case 35669: 26058 case 35673: 26059 return setValueV4i; 26060 // _VEC4 26061 case 5125: 26062 return setValueV1ui; 26063 // UINT 26064 case 36294: 26065 return setValueV2ui; 26066 // _VEC2 26067 case 36295: 26068 return setValueV3ui; 26069 // _VEC3 26070 case 36296: 26071 return setValueV4ui; 26072 // _VEC4 26073 case 35678: 26074 // SAMPLER_2D 26075 case 36198: 26076 // SAMPLER_EXTERNAL_OES 26077 case 36298: 26078 // INT_SAMPLER_2D 26079 case 36306: 26080 // UNSIGNED_INT_SAMPLER_2D 26081 case 35682: 26082 return setValueT1; 26083 case 35679: 26084 // SAMPLER_3D 26085 case 36299: 26086 // INT_SAMPLER_3D 26087 case 36307: 26088 return setValueT3D1; 26089 case 35680: 26090 // SAMPLER_CUBE 26091 case 36300: 26092 // INT_SAMPLER_CUBE 26093 case 36308: 26094 // UNSIGNED_INT_SAMPLER_CUBE 26095 case 36293: 26096 return setValueT6; 26097 case 36289: 26098 // SAMPLER_2D_ARRAY 26099 case 36303: 26100 // INT_SAMPLER_2D_ARRAY 26101 case 36311: 26102 // UNSIGNED_INT_SAMPLER_2D_ARRAY 26103 case 36292: 26104 return setValueT2DArray1; 26105 } 26106} 26107function setValueV1fArray(gl, v) { 26108 gl.uniform1fv(this.addr, v); 26109} 26110function setValueV2fArray(gl, v) { 26111 const data = flatten(v, this.size, 2); 26112 gl.uniform2fv(this.addr, data); 26113} 26114function setValueV3fArray(gl, v) { 26115 const data = flatten(v, this.size, 3); 26116 gl.uniform3fv(this.addr, data); 26117} 26118function setValueV4fArray(gl, v) { 26119 const data = flatten(v, this.size, 4); 26120 gl.uniform4fv(this.addr, data); 26121} 26122function setValueM2Array(gl, v) { 26123 const data = flatten(v, this.size, 4); 26124 gl.uniformMatrix2fv(this.addr, false, data); 26125} 26126function setValueM3Array(gl, v) { 26127 const data = flatten(v, this.size, 9); 26128 gl.uniformMatrix3fv(this.addr, false, data); 26129} 26130function setValueM4Array(gl, v) { 26131 const data = flatten(v, this.size, 16); 26132 gl.uniformMatrix4fv(this.addr, false, data); 26133} 26134function setValueV1iArray(gl, v) { 26135 gl.uniform1iv(this.addr, v); 26136} 26137function setValueV2iArray(gl, v) { 26138 gl.uniform2iv(this.addr, v); 26139} 26140function setValueV3iArray(gl, v) { 26141 gl.uniform3iv(this.addr, v); 26142} 26143function setValueV4iArray(gl, v) { 26144 gl.uniform4iv(this.addr, v); 26145} 26146function setValueV1uiArray(gl, v) { 26147 gl.uniform1uiv(this.addr, v); 26148} 26149function setValueV2uiArray(gl, v) { 26150 gl.uniform2uiv(this.addr, v); 26151} 26152function setValueV3uiArray(gl, v) { 26153 gl.uniform3uiv(this.addr, v); 26154} 26155function setValueV4uiArray(gl, v) { 26156 gl.uniform4uiv(this.addr, v); 26157} 26158function setValueT1Array(gl, v, textures) { 26159 const cache = this.cache; 26160 const n = v.length; 26161 const units = allocTexUnits(textures, n); 26162 if (!arraysEqual(cache, units)) { 26163 gl.uniform1iv(this.addr, units); 26164 copyArray(cache, units); 26165 } 26166 let emptyTexture2D; 26167 if (this.type === gl.SAMPLER_2D_SHADOW) { 26168 emptyTexture2D = emptyShadowTexture; 26169 } else { 26170 emptyTexture2D = emptyTexture; 26171 } 26172 for (let i = 0; i !== n; ++i) { 26173 textures.setTexture2D(v[i] || emptyTexture2D, units[i]); 26174 } 26175} 26176function setValueT3DArray(gl, v, textures) { 26177 const cache = this.cache; 26178 const n = v.length; 26179 const units = allocTexUnits(textures, n); 26180 if (!arraysEqual(cache, units)) { 26181 gl.uniform1iv(this.addr, units); 26182 copyArray(cache, units); 26183 } 26184 for (let i = 0; i !== n; ++i) { 26185 textures.setTexture3D(v[i] || empty3dTexture, units[i]); 26186 } 26187} 26188function setValueT6Array(gl, v, textures) { 26189 const cache = this.cache; 26190 const n = v.length; 26191 const units = allocTexUnits(textures, n); 26192 if (!arraysEqual(cache, units)) { 26193 gl.uniform1iv(this.addr, units); 26194 copyArray(cache, units); 26195 } 26196 for (let i = 0; i !== n; ++i) { 26197 textures.setTextureCube(v[i] || emptyCubeTexture, units[i]); 26198 } 26199} 26200function setValueT2DArrayArray(gl, v, textures) { 26201 const cache = this.cache; 26202 const n = v.length; 26203 const units = allocTexUnits(textures, n); 26204 if (!arraysEqual(cache, units)) { 26205 gl.uniform1iv(this.addr, units); 26206 copyArray(cache, units); 26207 } 26208 for (let i = 0; i !== n; ++i) { 26209 textures.setTexture2DArray(v[i] || emptyArrayTexture, units[i]); 26210 } 26211} 26212function getPureArraySetter(type) { 26213 switch (type) { 26214 case 5126: 26215 return setValueV1fArray; 26216 // FLOAT 26217 case 35664: 26218 return setValueV2fArray; 26219 // _VEC2 26220 case 35665: 26221 return setValueV3fArray; 26222 // _VEC3 26223 case 35666: 26224 return setValueV4fArray; 26225 // _VEC4 26226 case 35674: 26227 return setValueM2Array; 26228 // _MAT2 26229 case 35675: 26230 return setValueM3Array; 26231 // _MAT3 26232 case 35676: 26233 return setValueM4Array; 26234 // _MAT4 26235 case 5124: 26236 case 35670: 26237 return setValueV1iArray; 26238 // INT, BOOL 26239 case 35667: 26240 case 35671: 26241 return setValueV2iArray; 26242 // _VEC2 26243 case 35668: 26244 case 35672: 26245 return setValueV3iArray; 26246 // _VEC3 26247 case 35669: 26248 case 35673: 26249 return setValueV4iArray; 26250 // _VEC4 26251 case 5125: 26252 return setValueV1uiArray; 26253 // UINT 26254 case 36294: 26255 return setValueV2uiArray; 26256 // _VEC2 26257 case 36295: 26258 return setValueV3uiArray; 26259 // _VEC3 26260 case 36296: 26261 return setValueV4uiArray; 26262 // _VEC4 26263 case 35678: 26264 // SAMPLER_2D 26265 case 36198: 26266 // SAMPLER_EXTERNAL_OES 26267 case 36298: 26268 // INT_SAMPLER_2D 26269 case 36306: 26270 // UNSIGNED_INT_SAMPLER_2D 26271 case 35682: 26272 return setValueT1Array; 26273 case 35679: 26274 // SAMPLER_3D 26275 case 36299: 26276 // INT_SAMPLER_3D 26277 case 36307: 26278 return setValueT3DArray; 26279 case 35680: 26280 // SAMPLER_CUBE 26281 case 36300: 26282 // INT_SAMPLER_CUBE 26283 case 36308: 26284 // UNSIGNED_INT_SAMPLER_CUBE 26285 case 36293: 26286 return setValueT6Array; 26287 case 36289: 26288 // SAMPLER_2D_ARRAY 26289 case 36303: 26290 // INT_SAMPLER_2D_ARRAY 26291 case 36311: 26292 // UNSIGNED_INT_SAMPLER_2D_ARRAY 26293 case 36292: 26294 return setValueT2DArrayArray; 26295 } 26296} 26297var SingleUniform = class { 26298 constructor(id, activeInfo, addr) { 26299 this.id = id; 26300 this.addr = addr; 26301 this.cache = []; 26302 this.type = activeInfo.type; 26303 this.setValue = getSingularSetter(activeInfo.type); 26304 } 26305}; 26306var PureArrayUniform = class { 26307 constructor(id, activeInfo, addr) { 26308 this.id = id; 26309 this.addr = addr; 26310 this.cache = []; 26311 this.type = activeInfo.type; 26312 this.size = activeInfo.size; 26313 this.setValue = getPureArraySetter(activeInfo.type); 26314 } 26315}; 26316var StructuredUniform = class { 26317 constructor(id) { 26318 this.id = id; 26319 this.seq = []; 26320 this.map = {}; 26321 } 26322 setValue(gl, value, textures) { 26323 const seq = this.seq; 26324 for (let i = 0, n = seq.length; i !== n; ++i) { 26325 const u = seq[i]; 26326 u.setValue(gl, value[u.id], textures); 26327 } 26328 } 26329}; 26330var RePathPart = /(\w+)(\])?(\[|\.)?/g; 26331function addUniform(container, uniformObject) { 26332 container.seq.push(uniformObject); 26333 container.map[uniformObject.id] = uniformObject; 26334} 26335function parseUniform(activeInfo, addr, container) { 26336 const path = activeInfo.name, pathLength = path.length; 26337 RePathPart.lastIndex = 0; 26338 while (true) { 26339 const match = RePathPart.exec(path), matchEnd = RePathPart.lastIndex; 26340 let id = match[1]; 26341 const idIsIndex = match[2] === "]", subscript = match[3]; 26342 if (idIsIndex) id = id | 0; 26343 if (subscript === void 0 || subscript === "[" && matchEnd + 2 === pathLength) { 26344 addUniform(container, subscript === void 0 ? new SingleUniform(id, activeInfo, addr) : new PureArrayUniform(id, activeInfo, addr)); 26345 break; 26346 } else { 26347 const map = container.map; 26348 let next = map[id]; 26349 if (next === void 0) { 26350 next = new StructuredUniform(id); 26351 addUniform(container, next); 26352 } 26353 container = next; 26354 } 26355 } 26356} 26357var WebGLUniforms = class { 26358 constructor(gl, program) { 26359 this.seq = []; 26360 this.map = {}; 26361 const n = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); 26362 for (let i = 0; i < n; ++i) { 26363 const info = gl.getActiveUniform(program, i), addr = gl.getUniformLocation(program, info.name); 26364 parseUniform(info, addr, this); 26365 } 26366 const shadowSamplers = []; 26367 const otherUniforms = []; 26368 for (const u of this.seq) { 26369 if (u.type === gl.SAMPLER_2D_SHADOW || u.type === gl.SAMPLER_CUBE_SHADOW || u.type === gl.SAMPLER_2D_ARRAY_SHADOW) { 26370 shadowSamplers.push(u); 26371 } else { 26372 otherUniforms.push(u); 26373 } 26374 } 26375 if (shadowSamplers.length > 0) { 26376 this.seq = shadowSamplers.concat(otherUniforms); 26377 } 26378 } 26379 setValue(gl, name, value, textures) { 26380 const u = this.map[name]; 26381 if (u !== void 0) u.setValue(gl, value, textures); 26382 } 26383 setOptional(gl, object, name) { 26384 const v = object[name]; 26385 if (v !== void 0) this.setValue(gl, name, v); 26386 } 26387 static upload(gl, seq, values, textures) { 26388 for (let i = 0, n = seq.length; i !== n; ++i) { 26389 const u = seq[i], v = values[u.id]; 26390 if (v.needsUpdate !== false) { 26391 u.setValue(gl, v.value, textures); 26392 } 26393 } 26394 } 26395 static seqWithValue(seq, values) { 26396 const r = []; 26397 for (let i = 0, n = seq.length; i !== n; ++i) { 26398 const u = seq[i]; 26399 if (u.id in values) r.push(u); 26400 } 26401 return r; 26402 } 26403}; 26404function WebGLShader(gl, type, string) { 26405 const shader = gl.createShader(type); 26406 gl.shaderSource(shader, string); 26407 gl.compileShader(shader); 26408 return shader; 26409} 26410var COMPLETION_STATUS_KHR = 37297; 26411var programIdCount = 0; 26412function handleSource(string, errorLine) { 26413 const lines = string.split("\n"); 26414 const lines2 = []; 26415 const from = Math.max(errorLine - 6, 0); 26416 const to = Math.min(errorLine + 6, lines.length); 26417 for (let i = from; i < to; i++) { 26418 const line = i + 1; 26419 lines2.push(`${line === errorLine ? ">" : " "} ${line}: ${lines[i]}`); 26420 } 26421 return lines2.join("\n"); 26422} 26423var _m0 = /* @__PURE__ */ new Matrix3(); 26424function getEncodingComponents(colorSpace) { 26425 ColorManagement._getMatrix(_m0, ColorManagement.workingColorSpace, colorSpace); 26426 const encodingMatrix = `mat3( ${_m0.elements.map((v) => v.toFixed(4))} )`; 26427 switch (ColorManagement.getTransfer(colorSpace)) { 26428 case LinearTransfer: 26429 return [encodingMatrix, "LinearTransferOETF"]; 26430 case SRGBTransfer: 26431 return [encodingMatrix, "sRGBTransferOETF"]; 26432 default: 26433 warn("WebGLProgram: Unsupported color space: ", colorSpace); 26434 return [encodingMatrix, "LinearTransferOETF"]; 26435 } 26436} 26437function getShaderErrors(gl, shader, type) { 26438 const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS); 26439 const shaderInfoLog = gl.getShaderInfoLog(shader) || ""; 26440 const errors = shaderInfoLog.trim(); 26441 if (status && errors === "") return ""; 26442 const errorMatches = /ERROR: 0:(\d+)/.exec(errors); 26443 if (errorMatches) { 26444 const errorLine = parseInt(errorMatches[1]); 26445 return type.toUpperCase() + "\n\n" + errors + "\n\n" + handleSource(gl.getShaderSource(shader), errorLine); 26446 } else { 26447 return errors; 26448 } 26449} 26450function getTexelEncodingFunction(functionName, colorSpace) { 26451 const components = getEncodingComponents(colorSpace); 26452 return [ 26453 `vec4 ${functionName}( vec4 value ) {`, 26454 ` return ${components[1]}( vec4( value.rgb * ${components[0]}, value.a ) );`, 26455 "}" 26456 ].join("\n"); 26457} 26458var toneMappingFunctions = { 26459 [LinearToneMapping]: "Linear", 26460 [ReinhardToneMapping]: "Reinhard", 26461 [CineonToneMapping]: "Cineon", 26462 [ACESFilmicToneMapping]: "ACESFilmic", 26463 [AgXToneMapping]: "AgX", 26464 [NeutralToneMapping]: "Neutral", 26465 [CustomToneMapping]: "Custom" 26466}; 26467function getToneMappingFunction(functionName, toneMapping) { 26468 const toneMappingName = toneMappingFunctions[toneMapping]; 26469 if (toneMappingName === void 0) { 26470 warn("WebGLProgram: Unsupported toneMapping:", toneMapping); 26471 return "vec3 " + functionName + "( vec3 color ) { return LinearToneMapping( color ); }"; 26472 } 26473 return "vec3 " + functionName + "( vec3 color ) { return " + toneMappingName + "ToneMapping( color ); }"; 26474} 26475var _v0 = /* @__PURE__ */ new Vector3(); 26476function getLuminanceFunction() { 26477 ColorManagement.getLuminanceCoefficients(_v0); 26478 const r = _v0.x.toFixed(4); 26479 const g = _v0.y.toFixed(4); 26480 const b = _v0.z.toFixed(4); 26481 return [ 26482 "float luminance( const in vec3 rgb ) {", 26483 ` const vec3 weights = vec3( ${r}, ${g}, ${b} );`, 26484 " return dot( weights, rgb );", 26485 "}" 26486 ].join("\n"); 26487} 26488function generateVertexExtensions(parameters) { 26489 const chunks = [ 26490 parameters.extensionClipCullDistance ? "#extension GL_ANGLE_clip_cull_distance : require" : "", 26491 parameters.extensionMultiDraw ? "#extension GL_ANGLE_multi_draw : require" : "" 26492 ]; 26493 return chunks.filter(filterEmptyLine).join("\n"); 26494} 26495function generateDefines(defines) { 26496 const chunks = []; 26497 for (const name in defines) { 26498 const value = defines[name]; 26499 if (value === false) continue; 26500 chunks.push("#define " + name + " " + value); 26501 } 26502 return chunks.join("\n"); 26503} 26504function fetchAttributeLocations(gl, program) { 26505 const attributes = {}; 26506 const n = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); 26507 for (let i = 0; i < n; i++) { 26508 const info = gl.getActiveAttrib(program, i); 26509 const name = info.name; 26510 let locationSize = 1; 26511 if (info.type === gl.FLOAT_MAT2) locationSize = 2; 26512 if (info.type === gl.FLOAT_MAT3) locationSize = 3; 26513 if (info.type === gl.FLOAT_MAT4) locationSize = 4; 26514 attributes[name] = { 26515 type: info.type, 26516 location: gl.getAttribLocation(program, name), 26517 locationSize 26518 }; 26519 } 26520 return attributes; 26521} 26522function filterEmptyLine(string) { 26523 return string !== ""; 26524} 26525function replaceLightNums(string, parameters) { 26526 const numSpotLightCoords = parameters.numSpotLightShadows + parameters.numSpotLightMaps - parameters.numSpotLightShadowsWithMaps; 26527 return string.replace(/NUM_DIR_LIGHTS/g, parameters.numDirLights).replace(/NUM_SPOT_LIGHTS/g, parameters.numSpotLights).replace(/NUM_SPOT_LIGHT_MAPS/g, parameters.numSpotLightMaps).replace(/NUM_SPOT_LIGHT_COORDS/g, numSpotLightCoords).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_WITH_MAPS/g, parameters.numSpotLightShadowsWithMaps).replace(/NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows); 26528} 26529function replaceClippingPlaneNums(string, parameters) { 26530 return string.replace(/NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g, parameters.numClippingPlanes - parameters.numClipIntersection); 26531} 26532var includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm; 26533function resolveIncludes(string) { 26534 return string.replace(includePattern, includeReplacer); 26535} 26536var shaderChunkMap = /* @__PURE__ */ new Map(); 26537function includeReplacer(match, include) { 26538 let string = ShaderChunk[include]; 26539 if (string === void 0) { 26540 const newInclude = shaderChunkMap.get(include); 26541 if (newInclude !== void 0) { 26542 string = ShaderChunk[newInclude]; 26543 warn('WebGLRenderer: Shader chunk "%s" has been deprecated. Use "%s" instead.', include, newInclude); 26544 } else { 26545 throw new Error("Can not resolve #include <" + include + ">"); 26546 } 26547 } 26548 return resolveIncludes(string); 26549} 26550var 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; 26551function unrollLoops(string) { 26552 return string.replace(unrollLoopPattern, loopReplacer); 26553} 26554function loopReplacer(match, start, end, snippet) { 26555 let string = ""; 26556 for (let i = parseInt(start); i < parseInt(end); i++) { 26557 string += snippet.replace(/\[\s*i\s*\]/g, "[ " + i + " ]").replace(/UNROLLED_LOOP_INDEX/g, i); 26558 } 26559 return string; 26560} 26561function generatePrecision(parameters) { 26562 let precisionstring = `precision ${parameters.precision} float; 26563 precision ${parameters.precision} int; 26564 precision ${parameters.precision} sampler2D; 26565 precision ${parameters.precision} samplerCube; 26566 precision ${parameters.precision} sampler3D; 26567 precision ${parameters.precision} sampler2DArray; 26568 precision ${parameters.precision} sampler2DShadow; 26569 precision ${parameters.precision} samplerCubeShadow; 26570 precision ${parameters.precision} sampler2DArrayShadow; 26571 precision ${parameters.precision} isampler2D; 26572 precision ${parameters.precision} isampler3D; 26573 precision ${parameters.precision} isamplerCube; 26574 precision ${parameters.precision} isampler2DArray; 26575 precision ${parameters.precision} usampler2D; 26576 precision ${parameters.precision} usampler3D; 26577 precision ${parameters.precision} usamplerCube; 26578 precision ${parameters.precision} usampler2DArray; 26579 `; 26580 if (parameters.precision === "highp") { 26581 precisionstring += "\n#define HIGH_PRECISION"; 26582 } else if (parameters.precision === "mediump") { 26583 precisionstring += "\n#define MEDIUM_PRECISION"; 26584 } else if (parameters.precision === "lowp") { 26585 precisionstring += "\n#define LOW_PRECISION"; 26586 } 26587 return precisionstring; 26588} 26589var shadowMapTypeDefines = { 26590 [PCFShadowMap]: "SHADOWMAP_TYPE_PCF", 26591 [VSMShadowMap]: "SHADOWMAP_TYPE_VSM" 26592}; 26593function generateShadowMapTypeDefine(parameters) { 26594 return shadowMapTypeDefines[parameters.shadowMapType] || "SHADOWMAP_TYPE_BASIC"; 26595} 26596var envMapTypeDefines = { 26597 [CubeReflectionMapping]: "ENVMAP_TYPE_CUBE", 26598 [CubeRefractionMapping]: "ENVMAP_TYPE_CUBE", 26599 [CubeUVReflectionMapping]: "ENVMAP_TYPE_CUBE_UV" 26600}; 26601function generateEnvMapTypeDefine(parameters) { 26602 if (parameters.envMap === false) return "ENVMAP_TYPE_CUBE"; 26603 return envMapTypeDefines[parameters.envMapMode] || "ENVMAP_TYPE_CUBE"; 26604} 26605var envMapModeDefines = { 26606 [CubeRefractionMapping]: "ENVMAP_MODE_REFRACTION" 26607}; 26608function generateEnvMapModeDefine(parameters) { 26609 if (parameters.envMap === false) return "ENVMAP_MODE_REFLECTION"; 26610 return envMapModeDefines[parameters.envMapMode] || "ENVMAP_MODE_REFLECTION"; 26611} 26612var envMapBlendingDefines = { 26613 [MultiplyOperation]: "ENVMAP_BLENDING_MULTIPLY", 26614 [MixOperation]: "ENVMAP_BLENDING_MIX", 26615 [AddOperation]: "ENVMAP_BLENDING_ADD" 26616}; 26617function generateEnvMapBlendingDefine(parameters) { 26618 if (parameters.envMap === false) return "ENVMAP_BLENDING_NONE"; 26619 return envMapBlendingDefines[parameters.combine] || "ENVMAP_BLENDING_NONE"; 26620} 26621function generateCubeUVSize(parameters) { 26622 const imageHeight = parameters.envMapCubeUVHeight; 26623 if (imageHeight === null) return null; 26624 const maxMip = Math.log2(imageHeight) - 2; 26625 const texelHeight = 1 / imageHeight; 26626 const texelWidth = 1 / (3 * Math.max(Math.pow(2, maxMip), 7 * 16)); 26627 return { texelWidth, texelHeight, maxMip }; 26628} 26629function WebGLProgram(renderer, cacheKey, parameters, bindingStates) { 26630 const gl = renderer.getContext(); 26631 const defines = parameters.defines; 26632 let vertexShader = parameters.vertexShader; 26633 let fragmentShader = parameters.fragmentShader; 26634 const shadowMapTypeDefine = generateShadowMapTypeDefine(parameters); 26635 const envMapTypeDefine = generateEnvMapTypeDefine(parameters); 26636 const envMapModeDefine = generateEnvMapModeDefine(parameters); 26637 const envMapBlendingDefine = generateEnvMapBlendingDefine(parameters); 26638 const envMapCubeUVSize = generateCubeUVSize(parameters); 26639 const customVertexExtensions = generateVertexExtensions(parameters); 26640 const customDefines = generateDefines(defines); 26641 const program = gl.createProgram(); 26642 let prefixVertex, prefixFragment; 26643 let versionString = parameters.glslVersion ? "#version " + parameters.glslVersion + "\n" : ""; 26644 if (parameters.isRawShaderMaterial) { 26645 prefixVertex = [ 26646 "#define SHADER_TYPE " + parameters.shaderType, 26647 "#define SHADER_NAME " + parameters.shaderName, 26648 customDefines 26649 ].filter(filterEmptyLine).join("\n"); 26650 if (prefixVertex.length > 0) { 26651 prefixVertex += "\n"; 26652 } 26653 prefixFragment = [ 26654 "#define SHADER_TYPE " + parameters.shaderType, 26655 "#define SHADER_NAME " + parameters.shaderName, 26656 customDefines 26657 ].filter(filterEmptyLine).join("\n"); 26658 if (prefixFragment.length > 0) { 26659 prefixFragment += "\n"; 26660 } 26661 } else { 26662 prefixVertex = [ 26663 generatePrecision(parameters), 26664 "#define SHADER_TYPE " + parameters.shaderType, 26665 "#define SHADER_NAME " + parameters.shaderName, 26666 customDefines, 26667 parameters.extensionClipCullDistance ? "#define USE_CLIP_DISTANCE" : "", 26668 parameters.batching ? "#define USE_BATCHING" : "", 26669 parameters.batchingColor ? "#define USE_BATCHING_COLOR" : "", 26670 parameters.instancing ? "#define USE_INSTANCING" : "", 26671 parameters.instancingColor ? "#define USE_INSTANCING_COLOR" : "", 26672 parameters.instancingMorph ? "#define USE_INSTANCING_MORPH" : "", 26673 parameters.useFog && parameters.fog ? "#define USE_FOG" : "", 26674 parameters.useFog && parameters.fogExp2 ? "#define FOG_EXP2" : "", 26675 parameters.map ? "#define USE_MAP" : "", 26676 parameters.envMap ? "#define USE_ENVMAP" : "", 26677 parameters.envMap ? "#define " + envMapModeDefine : "", 26678 parameters.lightMap ? "#define USE_LIGHTMAP" : "", 26679 parameters.aoMap ? "#define USE_AOMAP" : "", 26680 parameters.bumpMap ? "#define USE_BUMPMAP" : "", 26681 parameters.normalMap ? "#define USE_NORMALMAP" : "", 26682 parameters.normalMapObjectSpace ? "#define USE_NORMALMAP_OBJECTSPACE" : "", 26683 parameters.normalMapTangentSpace ? "#define USE_NORMALMAP_TANGENTSPACE" : "", 26684 parameters.displacementMap ? "#define USE_DISPLACEMENTMAP" : "", 26685 parameters.emissiveMap ? "#define USE_EMISSIVEMAP" : "", 26686 parameters.anisotropy ? "#define USE_ANISOTROPY" : "", 26687 parameters.anisotropyMap ? "#define USE_ANISOTROPYMAP" : "", 26688 parameters.clearcoatMap ? "#define USE_CLEARCOATMAP" : "", 26689 parameters.clearcoatRoughnessMap ? "#define USE_CLEARCOAT_ROUGHNESSMAP" : "", 26690 parameters.clearcoatNormalMap ? "#define USE_CLEARCOAT_NORMALMAP" : "", 26691 parameters.iridescenceMap ? "#define USE_IRIDESCENCEMAP" : "", 26692 parameters.iridescenceThicknessMap ? "#define USE_IRIDESCENCE_THICKNESSMAP" : "", 26693 parameters.specularMap ? "#define USE_SPECULARMAP" : "", 26694 parameters.specularColorMap ? "#define USE_SPECULAR_COLORMAP" : "", 26695 parameters.specularIntensityMap ? "#define USE_SPECULAR_INTENSITYMAP" : "", 26696 parameters.roughnessMap ? "#define USE_ROUGHNESSMAP" : "", 26697 parameters.metalnessMap ? "#define USE_METALNESSMAP" : "", 26698 parameters.alphaMap ? "#define USE_ALPHAMAP" : "", 26699 parameters.alphaHash ? "#define USE_ALPHAHASH" : "", 26700 parameters.transmission ? "#define USE_TRANSMISSION" : "", 26701 parameters.transmissionMap ? "#define USE_TRANSMISSIONMAP" : "", 26702 parameters.thicknessMap ? "#define USE_THICKNESSMAP" : "", 26703 parameters.sheenColorMap ? "#define USE_SHEEN_COLORMAP" : "", 26704 parameters.sheenRoughnessMap ? "#define USE_SHEEN_ROUGHNESSMAP" : "", 26705 // 26706 parameters.mapUv ? "#define MAP_UV " + parameters.mapUv : "", 26707 parameters.alphaMapUv ? "#define ALPHAMAP_UV " + parameters.alphaMapUv : "", 26708 parameters.lightMapUv ? "#define LIGHTMAP_UV " + parameters.lightMapUv : "", 26709 parameters.aoMapUv ? "#define AOMAP_UV " + parameters.aoMapUv : "", 26710 parameters.emissiveMapUv ? "#define EMISSIVEMAP_UV " + parameters.emissiveMapUv : "", 26711 parameters.bumpMapUv ? "#define BUMPMAP_UV " + parameters.bumpMapUv : "", 26712 parameters.normalMapUv ? "#define NORMALMAP_UV " + parameters.normalMapUv : "", 26713 parameters.displacementMapUv ? "#define DISPLACEMENTMAP_UV " + parameters.displacementMapUv : "", 26714 parameters.metalnessMapUv ? "#define METALNESSMAP_UV " + parameters.metalnessMapUv : "", 26715 parameters.roughnessMapUv ? "#define ROUGHNESSMAP_UV " + parameters.roughnessMapUv : "", 26716 parameters.anisotropyMapUv ? "#define ANISOTROPYMAP_UV " + parameters.anisotropyMapUv : "", 26717 parameters.clearcoatMapUv ? "#define CLEARCOATMAP_UV " + parameters.clearcoatMapUv : "", 26718 parameters.clearcoatNormalMapUv ? "#define CLEARCOAT_NORMALMAP_UV " + parameters.clearcoatNormalMapUv : "", 26719 parameters.clearcoatRoughnessMapUv ? "#define CLEARCOAT_ROUGHNESSMAP_UV " + parameters.clearcoatRoughnessMapUv : "", 26720 parameters.iridescenceMapUv ? "#define IRIDESCENCEMAP_UV " + parameters.iridescenceMapUv : "", 26721 parameters.iridescenceThicknessMapUv ? "#define IRIDESCENCE_THICKNESSMAP_UV " + parameters.iridescenceThicknessMapUv : "", 26722 parameters.sheenColorMapUv ? "#define SHEEN_COLORMAP_UV " + parameters.sheenColorMapUv : "", 26723 parameters.sheenRoughnessMapUv ? "#define SHEEN_ROUGHNESSMAP_UV " + parameters.sheenRoughnessMapUv : "", 26724 parameters.specularMapUv ? "#define SPECULARMAP_UV " + parameters.specularMapUv : "", 26725 parameters.specularColorMapUv ? "#define SPECULAR_COLORMAP_UV " + parameters.specularColorMapUv : "", 26726 parameters.specularIntensityMapUv ? "#define SPECULAR_INTENSITYMAP_UV " + parameters.specularIntensityMapUv : "", 26727 parameters.transmissionMapUv ? "#define TRANSMISSIONMAP_UV " + parameters.transmissionMapUv : "", 26728 parameters.thicknessMapUv ? "#define THICKNESSMAP_UV " + parameters.thicknessMapUv : "", 26729 // 26730 parameters.vertexTangents && parameters.flatShading === false ? "#define USE_TANGENT" : "", 26731 parameters.vertexNormals ? "#define HAS_NORMAL" : "", 26732 parameters.vertexColors ? "#define USE_COLOR" : "", 26733 parameters.vertexAlphas ? "#define USE_COLOR_ALPHA" : "", 26734 parameters.vertexUv1s ? "#define USE_UV1" : "", 26735 parameters.vertexUv2s ? "#define USE_UV2" : "", 26736 parameters.vertexUv3s ? "#define USE_UV3" : "", 26737 parameters.pointsUvs ? "#define USE_POINTS_UV" : "", 26738 parameters.flatShading ? "#define FLAT_SHADED" : "", 26739 parameters.skinning ? "#define USE_SKINNING" : "", 26740 parameters.morphTargets ? "#define USE_MORPHTARGETS" : "", 26741 parameters.morphNormals && parameters.flatShading === false ? "#define USE_MORPHNORMALS" : "", 26742 parameters.morphColors ? "#define USE_MORPHCOLORS" : "", 26743 parameters.morphTargetsCount > 0 ? "#define MORPHTARGETS_TEXTURE_STRIDE " + parameters.morphTextureStride : "", 26744 parameters.morphTargetsCount > 0 ? "#define MORPHTARGETS_COUNT " + parameters.morphTargetsCount : "", 26745 parameters.doubleSided ? "#define DOUBLE_SIDED" : "", 26746 parameters.flipSided ? "#define FLIP_SIDED" : "", 26747 parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "", 26748 parameters.shadowMapEnabled ? "#define " + shadowMapTypeDefine : "", 26749 parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "", 26750 parameters.numLightProbes > 0 ? "#define USE_LIGHT_PROBES" : "", 26751 parameters.logarithmicDepthBuffer ? "#define USE_LOGARITHMIC_DEPTH_BUFFER" : "", 26752 parameters.reversedDepthBuffer ? "#define USE_REVERSED_DEPTH_BUFFER" : "", 26753 "uniform mat4 modelMatrix;", 26754 "uniform mat4 modelViewMatrix;", 26755 "uniform mat4 projectionMatrix;", 26756 "uniform mat4 viewMatrix;", 26757 "uniform mat3 normalMatrix;", 26758 "uniform vec3 cameraPosition;", 26759 "uniform bool isOrthographic;", 26760 "#ifdef USE_INSTANCING", 26761 " attribute mat4 instanceMatrix;", 26762 "#endif", 26763 "#ifdef USE_INSTANCING_COLOR", 26764 " attribute vec3 instanceColor;", 26765 "#endif", 26766 "#ifdef USE_INSTANCING_MORPH", 26767 " uniform sampler2D morphTexture;", 26768 "#endif", 26769 "attribute vec3 position;", 26770 "attribute vec3 normal;", 26771 "attribute vec2 uv;", 26772 "#ifdef USE_UV1", 26773 " attribute vec2 uv1;", 26774 "#endif", 26775 "#ifdef USE_UV2", 26776 " attribute vec2 uv2;", 26777 "#endif", 26778 "#ifdef USE_UV3", 26779 " attribute vec2 uv3;", 26780 "#endif", 26781 "#ifdef USE_TANGENT", 26782 " attribute vec4 tangent;", 26783 "#endif", 26784 "#if defined( USE_COLOR_ALPHA )", 26785 " attribute vec4 color;", 26786 "#elif defined( USE_COLOR )", 26787 " attribute vec3 color;", 26788 "#endif", 26789 "#ifdef USE_SKINNING", 26790 " attribute vec4 skinIndex;", 26791 " attribute vec4 skinWeight;", 26792 "#endif", 26793 "\n" 26794 ].filter(filterEmptyLine).join("\n"); 26795 prefixFragment = [ 26796 generatePrecision(parameters), 26797 "#define SHADER_TYPE " + parameters.shaderType, 26798 "#define SHADER_NAME " + parameters.shaderName, 26799 customDefines, 26800 parameters.useFog && parameters.fog ? "#define USE_FOG" : "", 26801 parameters.useFog && parameters.fogExp2 ? "#define FOG_EXP2" : "", 26802 parameters.alphaToCoverage ? "#define ALPHA_TO_COVERAGE" : "", 26803 parameters.map ? "#define USE_MAP" : "", 26804 parameters.matcap ? "#define USE_MATCAP" : "", 26805 parameters.envMap ? "#define USE_ENVMAP" : "", 26806 parameters.envMap ? "#define " + envMapTypeDefine : "", 26807 parameters.envMap ? "#define " + envMapModeDefine : "", 26808 parameters.envMap ? "#define " + envMapBlendingDefine : "", 26809 envMapCubeUVSize ? "#define CUBEUV_TEXEL_WIDTH " + envMapCubeUVSize.texelWidth : "", 26810 envMapCubeUVSize ? "#define CUBEUV_TEXEL_HEIGHT " + envMapCubeUVSize.texelHeight : "", 26811 envMapCubeUVSize ? "#define CUBEUV_MAX_MIP " + envMapCubeUVSize.maxMip + ".0" : "", 26812 parameters.lightMap ? "#define USE_LIGHTMAP" : "", 26813 parameters.aoMap ? "#define USE_AOMAP" : "", 26814 parameters.bumpMap ? "#define USE_BUMPMAP" : "", 26815 parameters.normalMap ? "#define USE_NORMALMAP" : "", 26816 parameters.normalMapObjectSpace ? "#define USE_NORMALMAP_OBJECTSPACE" : "", 26817 parameters.normalMapTangentSpace ? "#define USE_NORMALMAP_TANGENTSPACE" : "", 26818 parameters.packedNormalMap ? "#define USE_PACKED_NORMALMAP" : "", 26819 parameters.emissiveMap ? "#define USE_EMISSIVEMAP" : "", 26820 parameters.anisotropy ? "#define USE_ANISOTROPY" : "", 26821 parameters.anisotropyMap ? "#define USE_ANISOTROPYMAP" : "", 26822 parameters.clearcoat ? "#define USE_CLEARCOAT" : "", 26823 parameters.clearcoatMap ? "#define USE_CLEARCOATMAP" : "", 26824 parameters.clearcoatRoughnessMap ? "#define USE_CLEARCOAT_ROUGHNESSMAP" : "", 26825 parameters.clearcoatNormalMap ? "#define USE_CLEARCOAT_NORMALMAP" : "", 26826 parameters.dispersion ? "#define USE_DISPERSION" : "", 26827 parameters.iridescence ? "#define USE_IRIDESCENCE" : "", 26828 parameters.iridescenceMap ? "#define USE_IRIDESCENCEMAP" : "", 26829 parameters.iridescenceThicknessMap ? "#define USE_IRIDESCENCE_THICKNESSMAP" : "", 26830 parameters.specularMap ? "#define USE_SPECULARMAP" : "", 26831 parameters.specularColorMap ? "#define USE_SPECULAR_COLORMAP" : "", 26832 parameters.specularIntensityMap ? "#define USE_SPECULAR_INTENSITYMAP" : "", 26833 parameters.roughnessMap ? "#define USE_ROUGHNESSMAP" : "", 26834 parameters.metalnessMap ? "#define USE_METALNESSMAP" : "", 26835 parameters.alphaMap ? "#define USE_ALPHAMAP" : "", 26836 parameters.alphaTest ? "#define USE_ALPHATEST" : "", 26837 parameters.alphaHash ? "#define USE_ALPHAHASH" : "", 26838 parameters.sheen ? "#define USE_SHEEN" : "", 26839 parameters.sheenColorMap ? "#define USE_SHEEN_COLORMAP" : "", 26840 parameters.sheenRoughnessMap ? "#define USE_SHEEN_ROUGHNESSMAP" : "", 26841 parameters.transmission ? "#define USE_TRANSMISSION" : "", 26842 parameters.transmissionMap ? "#define USE_TRANSMISSIONMAP" : "", 26843 parameters.thicknessMap ? "#define USE_THICKNESSMAP" : "", 26844 parameters.vertexTangents && parameters.flatShading === false ? "#define USE_TANGENT" : "", 26845 parameters.vertexColors || parameters.instancingColor ? "#define USE_COLOR" : "", 26846 parameters.vertexAlphas || parameters.batchingColor ? "#define USE_COLOR_ALPHA" : "", 26847 parameters.vertexUv1s ? "#define USE_UV1" : "", 26848 parameters.vertexUv2s ? "#define USE_UV2" : "", 26849 parameters.vertexUv3s ? "#define USE_UV3" : "", 26850 parameters.pointsUvs ? "#define USE_POINTS_UV" : "", 26851 parameters.gradientMap ? "#define USE_GRADIENTMAP" : "", 26852 parameters.flatShading ? "#define FLAT_SHADED" : "", 26853 parameters.doubleSided ? "#define DOUBLE_SIDED" : "", 26854 parameters.flipSided ? "#define FLIP_SIDED" : "", 26855 parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "", 26856 parameters.shadowMapEnabled ? "#define " + shadowMapTypeDefine : "", 26857 parameters.premultipliedAlpha ? "#define PREMULTIPLIED_ALPHA" : "", 26858 parameters.numLightProbes > 0 ? "#define USE_LIGHT_PROBES" : "", 26859 parameters.numLightProbeGrids > 0 ? "#define USE_LIGHT_PROBES_GRID" : "", 26860 parameters.decodeVideoTexture ? "#define DECODE_VIDEO_TEXTURE" : "", 26861 parameters.decodeVideoTextureEmissive ? "#define DECODE_VIDEO_TEXTURE_EMISSIVE" : "", 26862 parameters.logarithmicDepthBuffer ? "#define USE_LOGARITHMIC_DEPTH_BUFFER" : "", 26863 parameters.reversedDepthBuffer ? "#define USE_REVERSED_DEPTH_BUFFER" : "", 26864 "uniform mat4 viewMatrix;", 26865 "uniform vec3 cameraPosition;", 26866 "uniform bool isOrthographic;", 26867 parameters.toneMapping !== NoToneMapping ? "#define TONE_MAPPING" : "", 26868 parameters.toneMapping !== NoToneMapping ? ShaderChunk["tonemapping_pars_fragment"] : "", 26869 // this code is required here because it is used by the toneMapping() function defined below 26870 parameters.toneMapping !== NoToneMapping ? getToneMappingFunction("toneMapping", parameters.toneMapping) : "", 26871 parameters.dithering ? "#define DITHERING" : "", 26872 parameters.opaque ? "#define OPAQUE" : "", 26873 ShaderChunk["colorspace_pars_fragment"], 26874 // this code is required here because it is used by the various encoding/decoding function defined below 26875 getTexelEncodingFunction("linearToOutputTexel", parameters.outputColorSpace), 26876 getLuminanceFunction(), 26877 parameters.useDepthPacking ? "#define DEPTH_PACKING " + parameters.depthPacking : "", 26878 "\n" 26879 ].filter(filterEmptyLine).join("\n"); 26880 } 26881 vertexShader = resolveIncludes(vertexShader); 26882 vertexShader = replaceLightNums(vertexShader, parameters); 26883 vertexShader = replaceClippingPlaneNums(vertexShader, parameters); 26884 fragmentShader = resolveIncludes(fragmentShader); 26885 fragmentShader = replaceLightNums(fragmentShader, parameters); 26886 fragmentShader = replaceClippingPlaneNums(fragmentShader, parameters); 26887 vertexShader = unrollLoops(vertexShader); 26888 fragmentShader = unrollLoops(fragmentShader); 26889 if (parameters.isRawShaderMaterial !== true) { 26890 versionString = "#version 300 es\n"; 26891 prefixVertex = [ 26892 customVertexExtensions, 26893 "#define attribute in", 26894 "#define varying out", 26895 "#define texture2D texture" 26896 ].join("\n") + "\n" + prefixVertex; 26897 prefixFragment = [ 26898 "#define varying in", 26899 parameters.glslVersion === GLSL3 ? "" : "layout(location = 0) out highp vec4 pc_fragColor;", 26900 parameters.glslVersion === GLSL3 ? "" : "#define gl_FragColor pc_fragColor", 26901 "#define gl_FragDepthEXT gl_FragDepth", 26902 "#define texture2D texture", 26903 "#define textureCube texture", 26904 "#define texture2DProj textureProj", 26905 "#define texture2DLodEXT textureLod", 26906 "#define texture2DProjLodEXT textureProjLod", 26907 "#define textureCubeLodEXT textureLod", 26908 "#define texture2DGradEXT textureGrad", 26909 "#define texture2DProjGradEXT textureProjGrad", 26910 "#define textureCubeGradEXT textureGrad" 26911 ].join("\n") + "\n" + prefixFragment; 26912 } 26913 const vertexGlsl = versionString + prefixVertex + vertexShader; 26914 const fragmentGlsl = versionString + prefixFragment + fragmentShader; 26915 const glVertexShader = WebGLShader(gl, gl.VERTEX_SHADER, vertexGlsl); 26916 const glFragmentShader = WebGLShader(gl, gl.FRAGMENT_SHADER, fragmentGlsl); 26917 gl.attachShader(program, glVertexShader); 26918 gl.attachShader(program, glFragmentShader); 26919 if (parameters.index0AttributeName !== void 0) { 26920 gl.bindAttribLocation(program, 0, parameters.index0AttributeName); 26921 } else if (parameters.morphTargets === true) { 26922 gl.bindAttribLocation(program, 0, "position"); 26923 } 26924 gl.linkProgram(program); 26925 function onFirstUse(self2) { 26926 if (renderer.debug.checkShaderErrors) { 26927 const programInfoLog = gl.getProgramInfoLog(program) || ""; 26928 const vertexShaderInfoLog = gl.getShaderInfoLog(glVertexShader) || ""; 26929 const fragmentShaderInfoLog = gl.getShaderInfoLog(glFragmentShader) || ""; 26930 const programLog = programInfoLog.trim(); 26931 const vertexLog = vertexShaderInfoLog.trim(); 26932 const fragmentLog = fragmentShaderInfoLog.trim(); 26933 let runnable = true; 26934 let haveDiagnostics = true; 26935 if (gl.getProgramParameter(program, gl.LINK_STATUS) === false) { 26936 runnable = false; 26937 if (typeof renderer.debug.onShaderError === "function") { 26938 renderer.debug.onShaderError(gl, program, glVertexShader, glFragmentShader); 26939 } else { 26940 const vertexErrors = getShaderErrors(gl, glVertexShader, "vertex"); 26941 const fragmentErrors = getShaderErrors(gl, glFragmentShader, "fragment"); 26942 error( 26943 "THREE.WebGLProgram: Shader Error " + gl.getError() + " - VALIDATE_STATUS " + gl.getProgramParameter(program, gl.VALIDATE_STATUS) + "\n\nMaterial Name: " + self2.name + "\nMaterial Type: " + self2.type + "\n\nProgram Info Log: " + programLog + "\n" + vertexErrors + "\n" + fragmentErrors 26944 ); 26945 } 26946 } else if (programLog !== "") { 26947 warn("WebGLProgram: Program Info Log:", programLog); 26948 } else if (vertexLog === "" || fragmentLog === "") { 26949 haveDiagnostics = false; 26950 } 26951 if (haveDiagnostics) { 26952 self2.diagnostics = { 26953 runnable, 26954 programLog, 26955 vertexShader: { 26956 log: vertexLog, 26957 prefix: prefixVertex 26958 }, 26959 fragmentShader: { 26960 log: fragmentLog, 26961 prefix: prefixFragment 26962 } 26963 }; 26964 } 26965 } 26966 gl.deleteShader(glVertexShader); 26967 gl.deleteShader(glFragmentShader); 26968 cachedUniforms = new WebGLUniforms(gl, program); 26969 cachedAttributes = fetchAttributeLocations(gl, program); 26970 } 26971 let cachedUniforms; 26972 this.getUniforms = function() { 26973 if (cachedUniforms === void 0) { 26974 onFirstUse(this); 26975 } 26976 return cachedUniforms; 26977 }; 26978 let cachedAttributes; 26979 this.getAttributes = function() { 26980 if (cachedAttributes === void 0) { 26981 onFirstUse(this); 26982 } 26983 return cachedAttributes; 26984 }; 26985 let programReady = parameters.rendererExtensionParallelShaderCompile === false; 26986 this.isReady = function() { 26987 if (programReady === false) { 26988 programReady = gl.getProgramParameter(program, COMPLETION_STATUS_KHR); 26989 } 26990 return programReady; 26991 }; 26992 this.destroy = function() { 26993 bindingStates.releaseStatesOfProgram(this); 26994 gl.deleteProgram(program); 26995 this.program = void 0; 26996 }; 26997 this.type = parameters.shaderType; 26998 this.name = parameters.shaderName; 26999 this.id = programIdCount++; 27000 this.cacheKey = cacheKey; 27001 this.usedTimes = 1; 27002 this.program = program; 27003 this.vertexShader = glVertexShader; 27004 this.fragmentShader = glFragmentShader; 27005 return this; 27006} 27007var _id = 0; 27008var WebGLShaderCache = class { 27009 constructor() { 27010 this.shaderCache = /* @__PURE__ */ new Map(); 27011 this.materialCache = /* @__PURE__ */ new Map(); 27012 } 27013 update(material) { 27014 const vertexShader = material.vertexShader; 27015 const fragmentShader = material.fragmentShader; 27016 const vertexShaderStage = this._getShaderStage(vertexShader); 27017 const fragmentShaderStage = this._getShaderStage(fragmentShader); 27018 const materialShaders = this._getShaderCacheForMaterial(material); 27019 if (materialShaders.has(vertexShaderStage) === false) { 27020 materialShaders.add(vertexShaderStage); 27021 vertexShaderStage.usedTimes++; 27022 } 27023 if (materialShaders.has(fragmentShaderStage) === false) { 27024 materialShaders.add(fragmentShaderStage); 27025 fragmentShaderStage.usedTimes++; 27026 } 27027 return this; 27028 } 27029 remove(material) { 27030 const materialShaders = this.materialCache.get(material); 27031 for (const shaderStage of materialShaders) { 27032 shaderStage.usedTimes--; 27033 if (shaderStage.usedTimes === 0) this.shaderCache.delete(shaderStage.code); 27034 } 27035 this.materialCache.delete(material); 27036 return this; 27037 } 27038 getVertexShaderID(material) { 27039 return this._getShaderStage(material.vertexShader).id; 27040 } 27041 getFragmentShaderID(material) { 27042 return this._getShaderStage(material.fragmentShader).id; 27043 } 27044 dispose() { 27045 this.shaderCache.clear(); 27046 this.materialCache.clear(); 27047 } 27048 _getShaderCacheForMaterial(material) { 27049 const cache = this.materialCache; 27050 let set = cache.get(material); 27051 if (set === void 0) { 27052 set = /* @__PURE__ */ new Set(); 27053 cache.set(material, set); 27054 } 27055 return set; 27056 } 27057 _getShaderStage(code) { 27058 const cache = this.shaderCache; 27059 let stage = cache.get(code); 27060 if (stage === void 0) { 27061 stage = new WebGLShaderStage(code); 27062 cache.set(code, stage); 27063 } 27064 return stage; 27065 } 27066}; 27067var WebGLShaderStage = class { 27068 constructor(code) { 27069 this.id = _id++; 27070 this.code = code; 27071 this.usedTimes = 0; 27072 } 27073}; 27074function isPackedRGFormat(format) { 27075 return format === RGFormat || format === RG11_EAC_Format || format === RED_GREEN_RGTC2_Format; 27076} 27077function WebGLPrograms(renderer, environments, extensions, capabilities, bindingStates, clipping) { 27078 const _programLayers = new Layers(); 27079 const _customShaders = new WebGLShaderCache(); 27080 const _activeChannels = /* @__PURE__ */ new Set(); 27081 const programs = []; 27082 const programsMap = /* @__PURE__ */ new Map(); 27083 const logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer; 27084 let precision = capabilities.precision; 27085 const shaderIDs = { 27086 MeshDepthMaterial: "depth", 27087 MeshDistanceMaterial: "distance", 27088 MeshNormalMaterial: "normal", 27089 MeshBasicMaterial: "basic", 27090 MeshLambertMaterial: "lambert", 27091 MeshPhongMaterial: "phong", 27092 MeshToonMaterial: "toon", 27093 MeshStandardMaterial: "physical", 27094 MeshPhysicalMaterial: "physical", 27095 MeshMatcapMaterial: "matcap", 27096 LineBasicMaterial: "basic", 27097 LineDashedMaterial: "dashed", 27098 PointsMaterial: "points", 27099 ShadowMaterial: "shadow", 27100 SpriteMaterial: "sprite" 27101 }; 27102 function getChannel(value) { 27103 _activeChannels.add(value); 27104 if (value === 0) return "uv"; 27105 return `uv${value}`; 27106 } 27107 function getParameters(material, lights, shadows, scene, object, lightProbeGrids) { 27108 const fog = scene.fog; 27109 const geometry = object.geometry; 27110 const environment = material.isMeshStandardMaterial || material.isMeshLambertMaterial || material.isMeshPhongMaterial ? scene.environment : null; 27111 const usePMREM = material.isMeshStandardMaterial || material.isMeshLambertMaterial && !material.envMap || material.isMeshPhongMaterial && !material.envMap; 27112 const envMap = environments.get(material.envMap || environment, usePMREM); 27113 const envMapCubeUVHeight = !!envMap && envMap.mapping === CubeUVReflectionMapping ? envMap.image.height : null; 27114 const shaderID = shaderIDs[material.type]; 27115 if (material.precision !== null) { 27116 precision = capabilities.getMaxPrecision(material.precision); 27117 if (precision !== material.precision) { 27118 warn("WebGLProgram.getParameters:", material.precision, "not supported, using", precision, "instead."); 27119 } 27120 } 27121 const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; 27122 const morphTargetsCount = morphAttribute !== void 0 ? morphAttribute.length : 0; 27123 let morphTextureStride = 0; 27124 if (geometry.morphAttributes.position !== void 0) morphTextureStride = 1; 27125 if (geometry.morphAttributes.normal !== void 0) morphTextureStride = 2; 27126 if (geometry.morphAttributes.color !== void 0) morphTextureStride = 3; 27127 let vertexShader, fragmentShader; 27128 let customVertexShaderID, customFragmentShaderID; 27129 if (shaderID) { 27130 const shader = ShaderLib[shaderID]; 27131 vertexShader = shader.vertexShader; 27132 fragmentShader = shader.fragmentShader; 27133 } else { 27134 vertexShader = material.vertexShader; 27135 fragmentShader = material.fragmentShader; 27136 _customShaders.update(material); 27137 customVertexShaderID = _customShaders.getVertexShaderID(material); 27138 customFragmentShaderID = _customShaders.getFragmentShaderID(material); 27139 } 27140 const currentRenderTarget = renderer.getRenderTarget(); 27141 const reversedDepthBuffer = renderer.state.buffers.depth.getReversed(); 27142 const IS_INSTANCEDMESH = object.isInstancedMesh === true; 27143 const IS_BATCHEDMESH = object.isBatchedMesh === true; 27144 const HAS_MAP = !!material.map; 27145 const HAS_MATCAP = !!material.matcap; 27146 const HAS_ENVMAP = !!envMap; 27147 const HAS_AOMAP = !!material.aoMap; 27148 const HAS_LIGHTMAP = !!material.lightMap; 27149 const HAS_BUMPMAP = !!material.bumpMap; 27150 const HAS_NORMALMAP = !!material.normalMap; 27151 const HAS_DISPLACEMENTMAP = !!material.displacementMap; 27152 const HAS_EMISSIVEMAP = !!material.emissiveMap; 27153 const HAS_METALNESSMAP = !!material.metalnessMap; 27154 const HAS_ROUGHNESSMAP = !!material.roughnessMap; 27155 const HAS_ANISOTROPY = material.anisotropy > 0; 27156 const HAS_CLEARCOAT = material.clearcoat > 0; 27157 const HAS_DISPERSION = material.dispersion > 0; 27158 const HAS_IRIDESCENCE = material.iridescence > 0; 27159 const HAS_SHEEN = material.sheen > 0; 27160 const HAS_TRANSMISSION = material.transmission > 0; 27161 const HAS_ANISOTROPYMAP = HAS_ANISOTROPY && !!material.anisotropyMap; 27162 const HAS_CLEARCOATMAP = HAS_CLEARCOAT && !!material.clearcoatMap; 27163 const HAS_CLEARCOAT_NORMALMAP = HAS_CLEARCOAT && !!material.clearcoatNormalMap; 27164 const HAS_CLEARCOAT_ROUGHNESSMAP = HAS_CLEARCOAT && !!material.clearcoatRoughnessMap; 27165 const HAS_IRIDESCENCEMAP = HAS_IRIDESCENCE && !!material.iridescenceMap; 27166 const HAS_IRIDESCENCE_THICKNESSMAP = HAS_IRIDESCENCE && !!material.iridescenceThicknessMap; 27167 const HAS_SHEEN_COLORMAP = HAS_SHEEN && !!material.sheenColorMap; 27168 const HAS_SHEEN_ROUGHNESSMAP = HAS_SHEEN && !!material.sheenRoughnessMap; 27169 const HAS_SPECULARMAP = !!material.specularMap; 27170 const HAS_SPECULAR_COLORMAP = !!material.specularColorMap; 27171 const HAS_SPECULAR_INTENSITYMAP = !!material.specularIntensityMap; 27172 const HAS_TRANSMISSIONMAP = HAS_TRANSMISSION && !!material.transmissionMap; 27173 const HAS_THICKNESSMAP = HAS_TRANSMISSION && !!material.thicknessMap; 27174 const HAS_GRADIENTMAP = !!material.gradientMap; 27175 const HAS_ALPHAMAP = !!material.alphaMap; 27176 const HAS_ALPHATEST = material.alphaTest > 0; 27177 const HAS_ALPHAHASH = !!material.alphaHash; 27178 const HAS_EXTENSIONS = !!material.extensions; 27179 let toneMapping = NoToneMapping; 27180 if (material.toneMapped) { 27181 if (currentRenderTarget === null || currentRenderTarget.isXRRenderTarget === true) { 27182 toneMapping = renderer.toneMapping; 27183 } 27184 } 27185 const parameters = { 27186 shaderID, 27187 shaderType: material.type, 27188 shaderName: material.name, 27189 vertexShader, 27190 fragmentShader, 27191 defines: material.defines, 27192 customVertexShaderID, 27193 customFragmentShaderID, 27194 isRawShaderMaterial: material.isRawShaderMaterial === true, 27195 glslVersion: material.glslVersion, 27196 precision, 27197 batching: IS_BATCHEDMESH, 27198 batchingColor: IS_BATCHEDMESH && object._colorsTexture !== null, 27199 instancing: IS_INSTANCEDMESH, 27200 instancingColor: IS_INSTANCEDMESH && object.instanceColor !== null, 27201 instancingMorph: IS_INSTANCEDMESH && object.morphTexture !== null, 27202 outputColorSpace: currentRenderTarget === null ? renderer.outputColorSpace : currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.colorSpace : ColorManagement.workingColorSpace, 27203 alphaToCoverage: !!material.alphaToCoverage, 27204 map: HAS_MAP, 27205 matcap: HAS_MATCAP, 27206 envMap: HAS_ENVMAP, 27207 envMapMode: HAS_ENVMAP && envMap.mapping, 27208 envMapCubeUVHeight, 27209 aoMap: HAS_AOMAP, 27210 lightMap: HAS_LIGHTMAP, 27211 bumpMap: HAS_BUMPMAP, 27212 normalMap: HAS_NORMALMAP, 27213 displacementMap: HAS_DISPLACEMENTMAP, 27214 emissiveMap: HAS_EMISSIVEMAP, 27215 normalMapObjectSpace: HAS_NORMALMAP && material.normalMapType === ObjectSpaceNormalMap, 27216 normalMapTangentSpace: HAS_NORMALMAP && material.normalMapType === TangentSpaceNormalMap, 27217 packedNormalMap: HAS_NORMALMAP && material.normalMapType === TangentSpaceNormalMap && isPackedRGFormat(material.normalMap.format), 27218 metalnessMap: HAS_METALNESSMAP, 27219 roughnessMap: HAS_ROUGHNESSMAP, 27220 anisotropy: HAS_ANISOTROPY, 27221 anisotropyMap: HAS_ANISOTROPYMAP, 27222 clearcoat: HAS_CLEARCOAT, 27223 clearcoatMap: HAS_CLEARCOATMAP, 27224 clearcoatNormalMap: HAS_CLEARCOAT_NORMALMAP, 27225 clearcoatRoughnessMap: HAS_CLEARCOAT_ROUGHNESSMAP, 27226 dispersion: HAS_DISPERSION, 27227 iridescence: HAS_IRIDESCENCE, 27228 iridescenceMap: HAS_IRIDESCENCEMAP, 27229 iridescenceThicknessMap: HAS_IRIDESCENCE_THICKNESSMAP, 27230 sheen: HAS_SHEEN, 27231 sheenColorMap: HAS_SHEEN_COLORMAP, 27232 sheenRoughnessMap: HAS_SHEEN_ROUGHNESSMAP, 27233 specularMap: HAS_SPECULARMAP, 27234 specularColorMap: HAS_SPECULAR_COLORMAP, 27235 specularIntensityMap: HAS_SPECULAR_INTENSITYMAP, 27236 transmission: HAS_TRANSMISSION, 27237 transmissionMap: HAS_TRANSMISSIONMAP, 27238 thicknessMap: HAS_THICKNESSMAP, 27239 gradientMap: HAS_GRADIENTMAP, 27240 opaque: material.transparent === false && material.blending === NormalBlending && material.alphaToCoverage === false, 27241 alphaMap: HAS_ALPHAMAP, 27242 alphaTest: HAS_ALPHATEST, 27243 alphaHash: HAS_ALPHAHASH, 27244 combine: material.combine, 27245 // 27246 mapUv: HAS_MAP && getChannel(material.map.channel), 27247 aoMapUv: HAS_AOMAP && getChannel(material.aoMap.channel), 27248 lightMapUv: HAS_LIGHTMAP && getChannel(material.lightMap.channel), 27249 bumpMapUv: HAS_BUMPMAP && getChannel(material.bumpMap.channel), 27250 normalMapUv: HAS_NORMALMAP && getChannel(material.normalMap.channel), 27251 displacementMapUv: HAS_DISPLACEMENTMAP && getChannel(material.displacementMap.channel), 27252 emissiveMapUv: HAS_EMISSIVEMAP && getChannel(material.emissiveMap.channel), 27253 metalnessMapUv: HAS_METALNESSMAP && getChannel(material.metalnessMap.channel), 27254 roughnessMapUv: HAS_ROUGHNESSMAP && getChannel(material.roughnessMap.channel), 27255 anisotropyMapUv: HAS_ANISOTROPYMAP && getChannel(material.anisotropyMap.channel), 27256 clearcoatMapUv: HAS_CLEARCOATMAP && getChannel(material.clearcoatMap.channel), 27257 clearcoatNormalMapUv: HAS_CLEARCOAT_NORMALMAP && getChannel(material.clearcoatNormalMap.channel), 27258 clearcoatRoughnessMapUv: HAS_CLEARCOAT_ROUGHNESSMAP && getChannel(material.clearcoatRoughnessMap.channel), 27259 iridescenceMapUv: HAS_IRIDESCENCEMAP && getChannel(material.iridescenceMap.channel), 27260 iridescenceThicknessMapUv: HAS_IRIDESCENCE_THICKNESSMAP && getChannel(material.iridescenceThicknessMap.channel), 27261 sheenColorMapUv: HAS_SHEEN_COLORMAP && getChannel(material.sheenColorMap.channel), 27262 sheenRoughnessMapUv: HAS_SHEEN_ROUGHNESSMAP && getChannel(material.sheenRoughnessMap.channel), 27263 specularMapUv: HAS_SPECULARMAP && getChannel(material.specularMap.channel), 27264 specularColorMapUv: HAS_SPECULAR_COLORMAP && getChannel(material.specularColorMap.channel), 27265 specularIntensityMapUv: HAS_SPECULAR_INTENSITYMAP && getChannel(material.specularIntensityMap.channel), 27266 transmissionMapUv: HAS_TRANSMISSIONMAP && getChannel(material.transmissionMap.channel), 27267 thicknessMapUv: HAS_THICKNESSMAP && getChannel(material.thicknessMap.channel), 27268 alphaMapUv: HAS_ALPHAMAP && getChannel(material.alphaMap.channel), 27269 // 27270 vertexTangents: !!geometry.attributes.tangent && (HAS_NORMALMAP || HAS_ANISOTROPY), 27271 vertexNormals: !!geometry.attributes.normal, 27272 vertexColors: material.vertexColors, 27273 vertexAlphas: material.vertexColors === true && !!geometry.attributes.color && geometry.attributes.color.itemSize === 4, 27274 pointsUvs: object.isPoints === true && !!geometry.attributes.uv && (HAS_MAP || HAS_ALPHAMAP), 27275 fog: !!fog, 27276 useFog: material.fog === true, 27277 fogExp2: !!fog && fog.isFogExp2, 27278 flatShading: material.wireframe === false && (material.flatShading === true || geometry.attributes.normal === void 0 && HAS_NORMALMAP === false && (material.isMeshLambertMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial || material.isMeshPhysicalMaterial)), 27279 sizeAttenuation: material.sizeAttenuation === true, 27280 logarithmicDepthBuffer, 27281 reversedDepthBuffer, 27282 skinning: object.isSkinnedMesh === true, 27283 morphTargets: geometry.morphAttributes.position !== void 0, 27284 morphNormals: geometry.morphAttributes.normal !== void 0, 27285 morphColors: geometry.morphAttributes.color !== void 0, 27286 morphTargetsCount, 27287 morphTextureStride, 27288 numDirLights: lights.directional.length, 27289 numPointLights: lights.point.length, 27290 numSpotLights: lights.spot.length, 27291 numSpotLightMaps: lights.spotLightMap.length, 27292 numRectAreaLights: lights.rectArea.length, 27293 numHemiLights: lights.hemi.length, 27294 numDirLightShadows: lights.directionalShadowMap.length, 27295 numPointLightShadows: lights.pointShadowMap.length, 27296 numSpotLightShadows: lights.spotShadowMap.length, 27297 numSpotLightShadowsWithMaps: lights.numSpotLightShadowsWithMaps, 27298 numLightProbes: lights.numLightProbes, 27299 numLightProbeGrids: lightProbeGrids.length, 27300 numClippingPlanes: clipping.numPlanes, 27301 numClipIntersection: clipping.numIntersection, 27302 dithering: material.dithering, 27303 shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0, 27304 shadowMapType: renderer.shadowMap.type, 27305 toneMapping, 27306 decodeVideoTexture: HAS_MAP && material.map.isVideoTexture === true && ColorManagement.getTransfer(material.map.colorSpace) === SRGBTransfer, 27307 decodeVideoTextureEmissive: HAS_EMISSIVEMAP && material.emissiveMap.isVideoTexture === true && ColorManagement.getTransfer(material.emissiveMap.colorSpace) === SRGBTransfer, 27308 premultipliedAlpha: material.premultipliedAlpha, 27309 doubleSided: material.side === DoubleSide, 27310 flipSided: material.side === BackSide, 27311 useDepthPacking: material.depthPacking >= 0, 27312 depthPacking: material.depthPacking || 0, 27313 index0AttributeName: material.index0AttributeName, 27314 extensionClipCullDistance: HAS_EXTENSIONS && material.extensions.clipCullDistance === true && extensions.has("WEBGL_clip_cull_distance"), 27315 extensionMultiDraw: (HAS_EXTENSIONS && material.extensions.multiDraw === true || IS_BATCHEDMESH) && extensions.has("WEBGL_multi_draw"), 27316 rendererExtensionParallelShaderCompile: extensions.has("KHR_parallel_shader_compile"), 27317 customProgramCacheKey: material.customProgramCacheKey() 27318 }; 27319 parameters.vertexUv1s = _activeChannels.has(1); 27320 parameters.vertexUv2s = _activeChannels.has(2); 27321 parameters.vertexUv3s = _activeChannels.has(3); 27322 _activeChannels.clear(); 27323 return parameters; 27324 } 27325 function getProgramCacheKey(parameters) { 27326 const array = []; 27327 if (parameters.shaderID) { 27328 array.push(parameters.shaderID); 27329 } else { 27330 array.push(parameters.customVertexShaderID); 27331 array.push(parameters.customFragmentShaderID); 27332 } 27333 if (parameters.defines !== void 0) { 27334 for (const name in parameters.defines) { 27335 array.push(name); 27336 array.push(parameters.defines[name]); 27337 } 27338 } 27339 if (parameters.isRawShaderMaterial === false) { 27340 getProgramCacheKeyParameters(array, parameters); 27341 getProgramCacheKeyBooleans(array, parameters); 27342 array.push(renderer.outputColorSpace); 27343 } 27344 array.push(parameters.customProgramCacheKey); 27345 return array.join(); 27346 } 27347 function getProgramCacheKeyParameters(array, parameters) { 27348 array.push(parameters.precision); 27349 array.push(parameters.outputColorSpace); 27350 array.push(parameters.envMapMode); 27351 array.push(parameters.envMapCubeUVHeight); 27352 array.push(parameters.mapUv); 27353 array.push(parameters.alphaMapUv); 27354 array.push(parameters.lightMapUv); 27355 array.push(parameters.aoMapUv); 27356 array.push(parameters.bumpMapUv); 27357 array.push(parameters.normalMapUv); 27358 array.push(parameters.displacementMapUv); 27359 array.push(parameters.emissiveMapUv); 27360 array.push(parameters.metalnessMapUv); 27361 array.push(parameters.roughnessMapUv); 27362 array.push(parameters.anisotropyMapUv); 27363 array.push(parameters.clearcoatMapUv); 27364 array.push(parameters.clearcoatNormalMapUv); 27365 array.push(parameters.clearcoatRoughnessMapUv); 27366 array.push(parameters.iridescenceMapUv); 27367 array.push(parameters.iridescenceThicknessMapUv); 27368 array.push(parameters.sheenColorMapUv); 27369 array.push(parameters.sheenRoughnessMapUv); 27370 array.push(parameters.specularMapUv); 27371 array.push(parameters.specularColorMapUv); 27372 array.push(parameters.specularIntensityMapUv); 27373 array.push(parameters.transmissionMapUv); 27374 array.push(parameters.thicknessMapUv); 27375 array.push(parameters.combine); 27376 array.push(parameters.fogExp2); 27377 array.push(parameters.sizeAttenuation); 27378 array.push(parameters.morphTargetsCount); 27379 array.push(parameters.morphAttributeCount); 27380 array.push(parameters.numDirLights); 27381 array.push(parameters.numPointLights); 27382 array.push(parameters.numSpotLights); 27383 array.push(parameters.numSpotLightMaps); 27384 array.push(parameters.numHemiLights); 27385 array.push(parameters.numRectAreaLights); 27386 array.push(parameters.numDirLightShadows); 27387 array.push(parameters.numPointLightShadows); 27388 array.push(parameters.numSpotLightShadows); 27389 array.push(parameters.numSpotLightShadowsWithMaps); 27390 array.push(parameters.numLightProbes); 27391 array.push(parameters.shadowMapType); 27392 array.push(parameters.toneMapping); 27393 array.push(parameters.numClippingPlanes); 27394 array.push(parameters.numClipIntersection); 27395 array.push(parameters.depthPacking); 27396 } 27397 function getProgramCacheKeyBooleans(array, parameters) { 27398 _programLayers.disableAll(); 27399 if (parameters.instancing) 27400 _programLayers.enable(0); 27401 if (parameters.instancingColor) 27402 _programLayers.enable(1); 27403 if (parameters.instancingMorph) 27404 _programLayers.enable(2); 27405 if (parameters.matcap) 27406 _programLayers.enable(3); 27407 if (parameters.envMap) 27408 _programLayers.enable(4); 27409 if (parameters.normalMapObjectSpace) 27410 _programLayers.enable(5); 27411 if (parameters.normalMapTangentSpace) 27412 _programLayers.enable(6); 27413 if (parameters.clearcoat) 27414 _programLayers.enable(7); 27415 if (parameters.iridescence) 27416 _programLayers.enable(8); 27417 if (parameters.alphaTest) 27418 _programLayers.enable(9); 27419 if (parameters.vertexColors) 27420 _programLayers.enable(10); 27421 if (parameters.vertexAlphas) 27422 _programLayers.enable(11); 27423 if (parameters.vertexUv1s) 27424 _programLayers.enable(12); 27425 if (parameters.vertexUv2s) 27426 _programLayers.enable(13); 27427 if (parameters.vertexUv3s) 27428 _programLayers.enable(14); 27429 if (parameters.vertexTangents) 27430 _programLayers.enable(15); 27431 if (parameters.anisotropy) 27432 _programLayers.enable(16); 27433 if (parameters.alphaHash) 27434 _programLayers.enable(17); 27435 if (parameters.batching) 27436 _programLayers.enable(18); 27437 if (parameters.dispersion) 27438 _programLayers.enable(19); 27439 if (parameters.batchingColor) 27440 _programLayers.enable(20); 27441 if (parameters.gradientMap) 27442 _programLayers.enable(21); 27443 if (parameters.packedNormalMap) 27444 _programLayers.enable(22); 27445 if (parameters.vertexNormals) 27446 _programLayers.enable(23); 27447 array.push(_programLayers.mask); 27448 _programLayers.disableAll(); 27449 if (parameters.fog) 27450 _programLayers.enable(0); 27451 if (parameters.useFog) 27452 _programLayers.enable(1); 27453 if (parameters.flatShading) 27454 _programLayers.enable(2); 27455 if (parameters.logarithmicDepthBuffer) 27456 _programLayers.enable(3); 27457 if (parameters.reversedDepthBuffer) 27458 _programLayers.enable(4); 27459 if (parameters.skinning) 27460 _programLayers.enable(5); 27461 if (parameters.morphTargets) 27462 _programLayers.enable(6); 27463 if (parameters.morphNormals) 27464 _programLayers.enable(7); 27465 if (parameters.morphColors) 27466 _programLayers.enable(8); 27467 if (parameters.premultipliedAlpha) 27468 _programLayers.enable(9); 27469 if (parameters.shadowMapEnabled) 27470 _programLayers.enable(10); 27471 if (parameters.doubleSided) 27472 _programLayers.enable(11); 27473 if (parameters.flipSided) 27474 _programLayers.enable(12); 27475 if (parameters.useDepthPacking) 27476 _programLayers.enable(13); 27477 if (parameters.dithering) 27478 _programLayers.enable(14); 27479 if (parameters.transmission) 27480 _programLayers.enable(15); 27481 if (parameters.sheen) 27482 _programLayers.enable(16); 27483 if (parameters.opaque) 27484 _programLayers.enable(17); 27485 if (parameters.pointsUvs) 27486 _programLayers.enable(18); 27487 if (parameters.decodeVideoTexture) 27488 _programLayers.enable(19); 27489 if (parameters.decodeVideoTextureEmissive) 27490 _programLayers.enable(20); 27491 if (parameters.alphaToCoverage) 27492 _programLayers.enable(21); 27493 if (parameters.numLightProbeGrids > 0) 27494 _programLayers.enable(22); 27495 array.push(_programLayers.mask); 27496 } 27497 function getUniforms(material) { 27498 const shaderID = shaderIDs[material.type]; 27499 let uniforms; 27500 if (shaderID) { 27501 const shader = ShaderLib[shaderID]; 27502 uniforms = UniformsUtils.clone(shader.uniforms); 27503 } else { 27504 uniforms = material.uniforms; 27505 } 27506 return uniforms; 27507 } 27508 function acquireProgram(parameters, cacheKey) { 27509 let program = programsMap.get(cacheKey); 27510 if (program !== void 0) { 27511 ++program.usedTimes; 27512 } else { 27513 program = new WebGLProgram(renderer, cacheKey, parameters, bindingStates); 27514 programs.push(program); 27515 programsMap.set(cacheKey, program); 27516 } 27517 return program; 27518 } 27519 function releaseProgram(program) { 27520 if (--program.usedTimes === 0) { 27521 const i = programs.indexOf(program); 27522 programs[i] = programs[programs.length - 1]; 27523 programs.pop(); 27524 programsMap.delete(program.cacheKey); 27525 program.destroy(); 27526 } 27527 } 27528 function releaseShaderCache(material) { 27529 _customShaders.remove(material); 27530 } 27531 function dispose2() { 27532 _customShaders.dispose(); 27533 } 27534 return { 27535 getParameters, 27536 getProgramCacheKey, 27537 getUniforms, 27538 acquireProgram, 27539 releaseProgram, 27540 releaseShaderCache, 27541 // Exposed for resource monitoring & error feedback via renderer.info: 27542 programs, 27543 dispose: dispose2 27544 }; 27545} 27546function WebGLProperties() { 27547 let properties = /* @__PURE__ */ new WeakMap(); 27548 function has(object) { 27549 return properties.has(object); 27550 } 27551 function get(object) { 27552 let map = properties.get(object); 27553 if (map === void 0) { 27554 map = {}; 27555 properties.set(object, map); 27556 } 27557 return map; 27558 } 27559 function remove(object) { 27560 properties.delete(object); 27561 } 27562 function update(object, key, value) { 27563 properties.get(object)[key] = value; 27564 } 27565 function dispose2() { 27566 properties = /* @__PURE__ */ new WeakMap(); 27567 } 27568 return { 27569 has, 27570 get, 27571 remove, 27572 update, 27573 dispose: dispose2 27574 }; 27575} 27576function painterSortStable(a, b) { 27577 if (a.groupOrder !== b.groupOrder) { 27578 return a.groupOrder - b.groupOrder; 27579 } else if (a.renderOrder !== b.renderOrder) { 27580 return a.renderOrder - b.renderOrder; 27581 } else if (a.material.id !== b.material.id) { 27582 return a.material.id - b.material.id; 27583 } else if (a.materialVariant !== b.materialVariant) { 27584 return a.materialVariant - b.materialVariant; 27585 } else if (a.z !== b.z) { 27586 return a.z - b.z; 27587 } else { 27588 return a.id - b.id; 27589 } 27590} 27591function reversePainterSortStable(a, b) { 27592 if (a.groupOrder !== b.groupOrder) { 27593 return a.groupOrder - b.groupOrder; 27594 } else if (a.renderOrder !== b.renderOrder) { 27595 return a.renderOrder - b.renderOrder; 27596 } else if (a.z !== b.z) { 27597 return b.z - a.z; 27598 } else { 27599 return a.id - b.id; 27600 } 27601} 27602function WebGLRenderList() { 27603 const renderItems = []; 27604 let renderItemsIndex = 0; 27605 const opaque = []; 27606 const transmissive = []; 27607 const transparent = []; 27608 function init() { 27609 renderItemsIndex = 0; 27610 opaque.length = 0; 27611 transmissive.length = 0; 27612 transparent.length = 0; 27613 } 27614 function materialVariant(object) { 27615 let variant = 0; 27616 if (object.isInstancedMesh) variant += 2; 27617 if (object.isSkinnedMesh) variant += 1; 27618 return variant; 27619 } 27620 function getNextRenderItem(object, geometry, material, groupOrder, z, group) { 27621 let renderItem = renderItems[renderItemsIndex]; 27622 if (renderItem === void 0) { 27623 renderItem = { 27624 id: object.id, 27625 object, 27626 geometry, 27627 material, 27628 materialVariant: materialVariant(object), 27629 groupOrder, 27630 renderOrder: object.renderOrder, 27631 z, 27632 group 27633 }; 27634 renderItems[renderItemsIndex] = renderItem; 27635 } else { 27636 renderItem.id = object.id; 27637 renderItem.object = object; 27638 renderItem.geometry = geometry; 27639 renderItem.material = material; 27640 renderItem.materialVariant = materialVariant(object); 27641 renderItem.groupOrder = groupOrder; 27642 renderItem.renderOrder = object.renderOrder; 27643 renderItem.z = z; 27644 renderItem.group = group; 27645 } 27646 renderItemsIndex++; 27647 return renderItem; 27648 } 27649 function push(object, geometry, material, groupOrder, z, group) { 27650 const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); 27651 if (material.transmission > 0) { 27652 transmissive.push(renderItem); 27653 } else if (material.transparent === true) { 27654 transparent.push(renderItem); 27655 } else { 27656 opaque.push(renderItem); 27657 } 27658 } 27659 function unshift(object, geometry, material, groupOrder, z, group) { 27660 const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); 27661 if (material.transmission > 0) { 27662 transmissive.unshift(renderItem); 27663 } else if (material.transparent === true) { 27664 transparent.unshift(renderItem); 27665 } else { 27666 opaque.unshift(renderItem); 27667 } 27668 } 27669 function sort(customOpaqueSort, customTransparentSort) { 27670 if (opaque.length > 1) opaque.sort(customOpaqueSort || painterSortStable); 27671 if (transmissive.length > 1) transmissive.sort(customTransparentSort || reversePainterSortStable); 27672 if (transparent.length > 1) transparent.sort(customTransparentSort || reversePainterSortStable); 27673 } 27674 function finish() { 27675 for (let i = renderItemsIndex, il = renderItems.length; i < il; i++) { 27676 const renderItem = renderItems[i]; 27677 if (renderItem.id === null) break; 27678 renderItem.id = null; 27679 renderItem.object = null; 27680 renderItem.geometry = null; 27681 renderItem.material = null; 27682 renderItem.group = null; 27683 } 27684 } 27685 return { 27686 opaque, 27687 transmissive, 27688 transparent, 27689 init, 27690 push, 27691 unshift, 27692 finish, 27693 sort 27694 }; 27695} 27696function WebGLRenderLists() { 27697 let lists = /* @__PURE__ */ new WeakMap(); 27698 function get(scene, renderCallDepth) { 27699 const listArray = lists.get(scene); 27700 let list; 27701 if (listArray === void 0) { 27702 list = new WebGLRenderList(); 27703 lists.set(scene, [list]); 27704 } else { 27705 if (renderCallDepth >= listArray.length) { 27706 list = new WebGLRenderList(); 27707 listArray.push(list); 27708 } else { 27709 list = listArray[renderCallDepth]; 27710 } 27711 } 27712 return list; 27713 } 27714 function dispose2() { 27715 lists = /* @__PURE__ */ new WeakMap(); 27716 } 27717 return { 27718 get, 27719 dispose: dispose2 27720 }; 27721} 27722function UniformsCache() { 27723 const lights = {}; 27724 return { 27725 get: function(light) { 27726 if (lights[light.id] !== void 0) { 27727 return lights[light.id]; 27728 } 27729 let uniforms; 27730 switch (light.type) { 27731 case "DirectionalLight": 27732 uniforms = { 27733 direction: new Vector3(), 27734 color: new Color() 27735 }; 27736 break; 27737 case "SpotLight": 27738 uniforms = { 27739 position: new Vector3(), 27740 direction: new Vector3(), 27741 color: new Color(), 27742 distance: 0, 27743 coneCos: 0, 27744 penumbraCos: 0, 27745 decay: 0 27746 }; 27747 break; 27748 case "PointLight": 27749 uniforms = { 27750 position: new Vector3(), 27751 color: new Color(), 27752 distance: 0, 27753 decay: 0 27754 }; 27755 break; 27756 case "HemisphereLight": 27757 uniforms = { 27758 direction: new Vector3(), 27759 skyColor: new Color(), 27760 groundColor: new Color() 27761 }; 27762 break; 27763 case "RectAreaLight": 27764 uniforms = { 27765 color: new Color(), 27766 position: new Vector3(), 27767 halfWidth: new Vector3(), 27768 halfHeight: new Vector3() 27769 }; 27770 break; 27771 } 27772 lights[light.id] = uniforms; 27773 return uniforms; 27774 } 27775 }; 27776} 27777function ShadowUniformsCache() { 27778 const lights = {}; 27779 return { 27780 get: function(light) { 27781 if (lights[light.id] !== void 0) { 27782 return lights[light.id]; 27783 } 27784 let uniforms; 27785 switch (light.type) { 27786 case "DirectionalLight": 27787 uniforms = { 27788 shadowIntensity: 1, 27789 shadowBias: 0, 27790 shadowNormalBias: 0, 27791 shadowRadius: 1, 27792 shadowMapSize: new Vector2() 27793 }; 27794 break; 27795 case "SpotLight": 27796 uniforms = { 27797 shadowIntensity: 1, 27798 shadowBias: 0, 27799 shadowNormalBias: 0, 27800 shadowRadius: 1, 27801 shadowMapSize: new Vector2() 27802 }; 27803 break; 27804 case "PointLight": 27805 uniforms = { 27806 shadowIntensity: 1, 27807 shadowBias: 0, 27808 shadowNormalBias: 0, 27809 shadowRadius: 1, 27810 shadowMapSize: new Vector2(), 27811 shadowCameraNear: 1, 27812 shadowCameraFar: 1e3 27813 }; 27814 break; 27815 } 27816 lights[light.id] = uniforms; 27817 return uniforms; 27818 } 27819 }; 27820} 27821var nextVersion = 0; 27822function shadowCastingAndTexturingLightsFirst(lightA, lightB) { 27823 return (lightB.castShadow ? 2 : 0) - (lightA.castShadow ? 2 : 0) + (lightB.map ? 1 : 0) - (lightA.map ? 1 : 0); 27824} 27825function WebGLLights(extensions) { 27826 const cache = new UniformsCache(); 27827 const shadowCache = ShadowUniformsCache(); 27828 const state = { 27829 version: 0, 27830 hash: { 27831 directionalLength: -1, 27832 pointLength: -1, 27833 spotLength: -1, 27834 rectAreaLength: -1, 27835 hemiLength: -1, 27836 numDirectionalShadows: -1, 27837 numPointShadows: -1, 27838 numSpotShadows: -1, 27839 numSpotMaps: -1, 27840 numLightProbes: -1 27841 }, 27842 ambient: [0, 0, 0], 27843 probe: [], 27844 directional: [], 27845 directionalShadow: [], 27846 directionalShadowMap: [], 27847 directionalShadowMatrix: [], 27848 spot: [], 27849 spotLightMap: [], 27850 spotShadow: [], 27851 spotShadowMap: [], 27852 spotLightMatrix: [], 27853 rectArea: [], 27854 rectAreaLTC1: null, 27855 rectAreaLTC2: null, 27856 point: [], 27857 pointShadow: [], 27858 pointShadowMap: [], 27859 pointShadowMatrix: [], 27860 hemi: [], 27861 numSpotLightShadowsWithMaps: 0, 27862 numLightProbes: 0 27863 }; 27864 for (let i = 0; i < 9; i++) state.probe.push(new Vector3()); 27865 const vector3 = new Vector3(); 27866 const matrix4 = new Matrix4(); 27867 const matrix42 = new Matrix4(); 27868 function setup(lights) { 27869 let r = 0, g = 0, b = 0; 27870 for (let i = 0; i < 9; i++) state.probe[i].set(0, 0, 0); 27871 let directionalLength = 0; 27872 let pointLength = 0; 27873 let spotLength = 0; 27874 let rectAreaLength = 0; 27875 let hemiLength = 0; 27876 let numDirectionalShadows = 0; 27877 let numPointShadows = 0; 27878 let numSpotShadows = 0; 27879 let numSpotMaps = 0; 27880 let numSpotShadowsWithMaps = 0; 27881 let numLightProbes = 0; 27882 lights.sort(shadowCastingAndTexturingLightsFirst); 27883 for (let i = 0, l = lights.length; i < l; i++) { 27884 const light = lights[i]; 27885 const color = light.color; 27886 const intensity = light.intensity; 27887 const distance = light.distance; 27888 let shadowMap = null; 27889 if (light.shadow && light.shadow.map) { 27890 if (light.shadow.map.texture.format === RGFormat) { 27891 shadowMap = light.shadow.map.texture; 27892 } else { 27893 shadowMap = light.shadow.map.depthTexture || light.shadow.map.texture; 27894 } 27895 } 27896 if (light.isAmbientLight) { 27897 r += color.r * intensity; 27898 g += color.g * intensity; 27899 b += color.b * intensity; 27900 } else if (light.isLightProbe) { 27901 for (let j = 0; j < 9; j++) { 27902 state.probe[j].addScaledVector(light.sh.coefficients[j], intensity); 27903 } 27904 numLightProbes++; 27905 } else if (light.isDirectionalLight) { 27906 const uniforms = cache.get(light); 27907 uniforms.color.copy(light.color).multiplyScalar(light.intensity); 27908 if (light.castShadow) { 27909 const shadow = light.shadow; 27910 const shadowUniforms = shadowCache.get(light); 27911 shadowUniforms.shadowIntensity = shadow.intensity; 27912 shadowUniforms.shadowBias = shadow.bias; 27913 shadowUniforms.shadowNormalBias = shadow.normalBias; 27914 shadowUniforms.shadowRadius = shadow.radius; 27915 shadowUniforms.shadowMapSize = shadow.mapSize; 27916 state.directionalShadow[directionalLength] = shadowUniforms; 27917 state.directionalShadowMap[directionalLength] = shadowMap; 27918 state.directionalShadowMatrix[directionalLength] = light.shadow.matrix; 27919 numDirectionalShadows++; 27920 } 27921 state.directional[directionalLength] = uniforms; 27922 directionalLength++; 27923 } else if (light.isSpotLight) { 27924 const uniforms = cache.get(light); 27925 uniforms.position.setFromMatrixPosition(light.matrixWorld); 27926 uniforms.color.copy(color).multiplyScalar(intensity); 27927 uniforms.distance = distance; 27928 uniforms.coneCos = Math.cos(light.angle); 27929 uniforms.penumbraCos = Math.cos(light.angle * (1 - light.penumbra)); 27930 uniforms.decay = light.decay; 27931 state.spot[spotLength] = uniforms; 27932 const shadow = light.shadow; 27933 if (light.map) { 27934 state.spotLightMap[numSpotMaps] = light.map; 27935 numSpotMaps++; 27936 shadow.updateMatrices(light); 27937 if (light.castShadow) numSpotShadowsWithMaps++; 27938 } 27939 state.spotLightMatrix[spotLength] = shadow.matrix; 27940 if (light.castShadow) { 27941 const shadowUniforms = shadowCache.get(light); 27942 shadowUniforms.shadowIntensity = shadow.intensity; 27943 shadowUniforms.shadowBias = shadow.bias; 27944 shadowUniforms.shadowNormalBias = shadow.normalBias; 27945 shadowUniforms.shadowRadius = shadow.radius; 27946 shadowUniforms.shadowMapSize = shadow.mapSize; 27947 state.spotShadow[spotLength] = shadowUniforms; 27948 state.spotShadowMap[spotLength] = shadowMap; 27949 numSpotShadows++; 27950 } 27951 spotLength++; 27952 } else if (light.isRectAreaLight) { 27953 const uniforms = cache.get(light); 27954 uniforms.color.copy(color).multiplyScalar(intensity); 27955 uniforms.halfWidth.set(light.width * 0.5, 0, 0); 27956 uniforms.halfHeight.set(0, light.height * 0.5, 0); 27957 state.rectArea[rectAreaLength] = uniforms; 27958 rectAreaLength++; 27959 } else if (light.isPointLight) { 27960 const uniforms = cache.get(light); 27961 uniforms.color.copy(light.color).multiplyScalar(light.intensity); 27962 uniforms.distance = light.distance; 27963 uniforms.decay = light.decay; 27964 if (light.castShadow) { 27965 const shadow = light.shadow; 27966 const shadowUniforms = shadowCache.get(light); 27967 shadowUniforms.shadowIntensity = shadow.intensity; 27968 shadowUniforms.shadowBias = shadow.bias; 27969 shadowUniforms.shadowNormalBias = shadow.normalBias; 27970 shadowUniforms.shadowRadius = shadow.radius; 27971 shadowUniforms.shadowMapSize = shadow.mapSize; 27972 shadowUniforms.shadowCameraNear = shadow.camera.near; 27973 shadowUniforms.shadowCameraFar = shadow.camera.far; 27974 state.pointShadow[pointLength] = shadowUniforms; 27975 state.pointShadowMap[pointLength] = shadowMap; 27976 state.pointShadowMatrix[pointLength] = light.shadow.matrix; 27977 numPointShadows++; 27978 } 27979 state.point[pointLength] = uniforms; 27980 pointLength++; 27981 } else if (light.isHemisphereLight) { 27982 const uniforms = cache.get(light); 27983 uniforms.skyColor.copy(light.color).multiplyScalar(intensity); 27984 uniforms.groundColor.copy(light.groundColor).multiplyScalar(intensity); 27985 state.hemi[hemiLength] = uniforms; 27986 hemiLength++; 27987 } 27988 } 27989 if (rectAreaLength > 0) { 27990 if (extensions.has("OES_texture_float_linear") === true) { 27991 state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1; 27992 state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2; 27993 } else { 27994 state.rectAreaLTC1 = UniformsLib.LTC_HALF_1; 27995 state.rectAreaLTC2 = UniformsLib.LTC_HALF_2; 27996 } 27997 } 27998 state.ambient[0] = r; 27999 state.ambient[1] = g; 28000 state.ambient[2] = b; 28001 const hash = state.hash; 28002 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 || hash.numSpotMaps !== numSpotMaps || hash.numLightProbes !== numLightProbes) { 28003 state.directional.length = directionalLength; 28004 state.spot.length = spotLength; 28005 state.rectArea.length = rectAreaLength; 28006 state.point.length = pointLength; 28007 state.hemi.length = hemiLength; 28008 state.directionalShadow.length = numDirectionalShadows; 28009 state.directionalShadowMap.length = numDirectionalShadows; 28010 state.pointShadow.length = numPointShadows; 28011 state.pointShadowMap.length = numPointShadows; 28012 state.spotShadow.length = numSpotShadows; 28013 state.spotShadowMap.length = numSpotShadows; 28014 state.directionalShadowMatrix.length = numDirectionalShadows; 28015 state.pointShadowMatrix.length = numPointShadows; 28016 state.spotLightMatrix.length = numSpotShadows + numSpotMaps - numSpotShadowsWithMaps; 28017 state.spotLightMap.length = numSpotMaps; 28018 state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps; 28019 state.numLightProbes = numLightProbes; 28020 hash.directionalLength = directionalLength; 28021 hash.pointLength = pointLength; 28022 hash.spotLength = spotLength; 28023 hash.rectAreaLength = rectAreaLength; 28024 hash.hemiLength = hemiLength; 28025 hash.numDirectionalShadows = numDirectionalShadows; 28026 hash.numPointShadows = numPointShadows; 28027 hash.numSpotShadows = numSpotShadows; 28028 hash.numSpotMaps = numSpotMaps; 28029 hash.numLightProbes = numLightProbes; 28030 state.version = nextVersion++; 28031 } 28032 } 28033 function setupView(lights, camera) { 28034 let directionalLength = 0; 28035 let pointLength = 0; 28036 let spotLength = 0; 28037 let rectAreaLength = 0; 28038 let hemiLength = 0; 28039 const viewMatrix = camera.matrixWorldInverse; 28040 for (let i = 0, l = lights.length; i < l; i++) { 28041 const light = lights[i]; 28042 if (light.isDirectionalLight) { 28043 const uniforms = state.directional[directionalLength]; 28044 uniforms.direction.setFromMatrixPosition(light.matrixWorld); 28045 vector3.setFromMatrixPosition(light.target.matrixWorld); 28046 uniforms.direction.sub(vector3); 28047 uniforms.direction.transformDirection(viewMatrix); 28048 directionalLength++; 28049 } else if (light.isSpotLight) { 28050 const uniforms = state.spot[spotLength]; 28051 uniforms.position.setFromMatrixPosition(light.matrixWorld); 28052 uniforms.position.applyMatrix4(viewMatrix); 28053 uniforms.direction.setFromMatrixPosition(light.matrixWorld); 28054 vector3.setFromMatrixPosition(light.target.matrixWorld); 28055 uniforms.direction.sub(vector3); 28056 uniforms.direction.transformDirection(viewMatrix); 28057 spotLength++; 28058 } else if (light.isRectAreaLight) { 28059 const uniforms = state.rectArea[rectAreaLength]; 28060 uniforms.position.setFromMatrixPosition(light.matrixWorld); 28061 uniforms.position.applyMatrix4(viewMatrix); 28062 matrix42.identity(); 28063 matrix4.copy(light.matrixWorld); 28064 matrix4.premultiply(viewMatrix); 28065 matrix42.extractRotation(matrix4); 28066 uniforms.halfWidth.set(light.width * 0.5, 0, 0); 28067 uniforms.halfHeight.set(0, light.height * 0.5, 0); 28068 uniforms.halfWidth.applyMatrix4(matrix42); 28069 uniforms.halfHeight.applyMatrix4(matrix42); 28070 rectAreaLength++; 28071 } else if (light.isPointLight) { 28072 const uniforms = state.point[pointLength]; 28073 uniforms.position.setFromMatrixPosition(light.matrixWorld); 28074 uniforms.position.applyMatrix4(viewMatrix); 28075 pointLength++; 28076 } else if (light.isHemisphereLight) { 28077 const uniforms = state.hemi[hemiLength]; 28078 uniforms.direction.setFromMatrixPosition(light.matrixWorld); 28079 uniforms.direction.transformDirection(viewMatrix); 28080 hemiLength++; 28081 } 28082 } 28083 } 28084 return { 28085 setup, 28086 setupView, 28087 state 28088 }; 28089} 28090function WebGLRenderState(extensions) { 28091 const lights = new WebGLLights(extensions); 28092 const lightsArray = []; 28093 const shadowsArray = []; 28094 const lightProbeGridArray = []; 28095 function init(camera) { 28096 state.camera = camera; 28097 lightsArray.length = 0; 28098 shadowsArray.length = 0; 28099 lightProbeGridArray.length = 0; 28100 } 28101 function pushLight(light) { 28102 lightsArray.push(light); 28103 } 28104 function pushShadow(shadowLight) { 28105 shadowsArray.push(shadowLight); 28106 } 28107 function pushLightProbeGrid(volume) { 28108 lightProbeGridArray.push(volume); 28109 } 28110 function setupLights() { 28111 lights.setup(lightsArray); 28112 } 28113 function setupLightsView(camera) { 28114 lights.setupView(lightsArray, camera); 28115 } 28116 const state = { 28117 lightsArray, 28118 shadowsArray, 28119 lightProbeGridArray, 28120 camera: null, 28121 lights, 28122 transmissionRenderTarget: {}, 28123 textureUnits: 0 28124 }; 28125 return { 28126 init, 28127 state, 28128 setupLights, 28129 setupLightsView, 28130 pushLight, 28131 pushShadow, 28132 pushLightProbeGrid 28133 }; 28134} 28135function WebGLRenderStates(extensions) { 28136 let renderStates = /* @__PURE__ */ new WeakMap(); 28137 function get(scene, renderCallDepth = 0) { 28138 const renderStateArray = renderStates.get(scene); 28139 let renderState; 28140 if (renderStateArray === void 0) { 28141 renderState = new WebGLRenderState(extensions); 28142 renderStates.set(scene, [renderState]); 28143 } else { 28144 if (renderCallDepth >= renderStateArray.length) { 28145 renderState = new WebGLRenderState(extensions); 28146 renderStateArray.push(renderState); 28147 } else { 28148 renderState = renderStateArray[renderCallDepth]; 28149 } 28150 } 28151 return renderState; 28152 } 28153 function dispose2() { 28154 renderStates = /* @__PURE__ */ new WeakMap(); 28155 } 28156 return { 28157 get, 28158 dispose: dispose2 28159 }; 28160} 28161var vertex = "void main() {\n gl_Position = vec4( position, 1.0 );\n}"; 28162var fragment = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\nvoid main() {\n const float samples = float( VSM_SAMPLES );\n float mean = 0.0;\n float squared_mean = 0.0;\n float uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 );\n float uvStart = samples <= 1.0 ? 0.0 : - 1.0;\n for ( float i = 0.0; i < samples; i ++ ) {\n float uvOffset = uvStart + i * uvStride;\n #ifdef HORIZONTAL_PASS\n vec2 distribution = texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 0.0 ) * radius ) / resolution ).rg;\n mean += distribution.x;\n squared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n #else\n float depth = texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, uvOffset ) * radius ) / resolution ).r;\n mean += depth;\n squared_mean += depth * depth;\n #endif\n }\n mean = mean / samples;\n squared_mean = squared_mean / samples;\n float std_dev = sqrt( max( 0.0, squared_mean - mean * mean ) );\n gl_FragColor = vec4( mean, std_dev, 0.0, 1.0 );\n}"; 28163var _cubeDirections = [ 28164 /* @__PURE__ */ new Vector3(1, 0, 0), 28165 /* @__PURE__ */ new Vector3(-1, 0, 0), 28166 /* @__PURE__ */ new Vector3(0, 1, 0), 28167 /* @__PURE__ */ new Vector3(0, -1, 0), 28168 /* @__PURE__ */ new Vector3(0, 0, 1), 28169 /* @__PURE__ */ new Vector3(0, 0, -1) 28170]; 28171var _cubeUps = [ 28172 /* @__PURE__ */ new Vector3(0, -1, 0), 28173 /* @__PURE__ */ new Vector3(0, -1, 0), 28174 /* @__PURE__ */ new Vector3(0, 0, 1), 28175 /* @__PURE__ */ new Vector3(0, 0, -1), 28176 /* @__PURE__ */ new Vector3(0, -1, 0), 28177 /* @__PURE__ */ new Vector3(0, -1, 0) 28178]; 28179var _projScreenMatrix2 = /* @__PURE__ */ new Matrix4(); 28180var _lightPositionWorld2 = /* @__PURE__ */ new Vector3(); 28181var _lookTarget2 = /* @__PURE__ */ new Vector3(); 28182function WebGLShadowMap(renderer, objects, capabilities) { 28183 let _frustum = new Frustum(); 28184 const _shadowMapSize = new Vector2(), _viewportSize = new Vector2(), _viewport = new Vector4(), _depthMaterial = new MeshDepthMaterial(), _distanceMaterial = new MeshDistanceMaterial(), _materialCache = {}, _maxTextureSize = capabilities.maxTextureSize; 28185 const shadowSide = { [FrontSide]: BackSide, [BackSide]: FrontSide, [DoubleSide]: DoubleSide }; 28186 const shadowMaterialVertical = new ShaderMaterial({ 28187 defines: { 28188 VSM_SAMPLES: 8 28189 }, 28190 uniforms: { 28191 shadow_pass: { value: null }, 28192 resolution: { value: new Vector2() }, 28193 radius: { value: 4 } 28194 }, 28195 vertexShader: vertex, 28196 fragmentShader: fragment 28197 }); 28198 const shadowMaterialHorizontal = shadowMaterialVertical.clone(); 28199 shadowMaterialHorizontal.defines.HORIZONTAL_PASS = 1; 28200 const fullScreenTri = new BufferGeometry(); 28201 fullScreenTri.setAttribute( 28202 "position", 28203 new BufferAttribute( 28204 new Float32Array([-1, -1, 0.5, 3, -1, 0.5, -1, 3, 0.5]), 28205 3 28206 ) 28207 ); 28208 const fullScreenMesh = new Mesh(fullScreenTri, shadowMaterialVertical); 28209 const scope = this; 28210 this.enabled = false; 28211 this.autoUpdate = true; 28212 this.needsUpdate = false; 28213 this.type = PCFShadowMap; 28214 let _previousType = this.type; 28215 this.render = function(lights, scene, camera) { 28216 if (scope.enabled === false) return; 28217 if (scope.autoUpdate === false && scope.needsUpdate === false) return; 28218 if (lights.length === 0) return; 28219 if (this.type === PCFSoftShadowMap) { 28220 warn("WebGLShadowMap: PCFSoftShadowMap has been deprecated. Using PCFShadowMap instead."); 28221 this.type = PCFShadowMap; 28222 } 28223 const currentRenderTarget = renderer.getRenderTarget(); 28224 const activeCubeFace = renderer.getActiveCubeFace(); 28225 const activeMipmapLevel = renderer.getActiveMipmapLevel(); 28226 const _state = renderer.state; 28227 _state.setBlending(NoBlending); 28228 if (_state.buffers.depth.getReversed() === true) { 28229 _state.buffers.color.setClear(0, 0, 0, 0); 28230 } else { 28231 _state.buffers.color.setClear(1, 1, 1, 1); 28232 } 28233 _state.buffers.depth.setTest(true); 28234 _state.setScissorTest(false); 28235 const typeChanged = _previousType !== this.type; 28236 if (typeChanged) { 28237 scene.traverse(function(object) { 28238 if (object.material) { 28239 if (Array.isArray(object.material)) { 28240 object.material.forEach((mat) => mat.needsUpdate = true); 28241 } else { 28242 object.material.needsUpdate = true; 28243 } 28244 } 28245 }); 28246 } 28247 for (let i = 0, il = lights.length; i < il; i++) { 28248 const light = lights[i]; 28249 const shadow = light.shadow; 28250 if (shadow === void 0) { 28251 warn("WebGLShadowMap:", light, "has no shadow."); 28252 continue; 28253 } 28254 if (shadow.autoUpdate === false && shadow.needsUpdate === false) continue; 28255 _shadowMapSize.copy(shadow.mapSize); 28256 const shadowFrameExtents = shadow.getFrameExtents(); 28257 _shadowMapSize.multiply(shadowFrameExtents); 28258 _viewportSize.copy(shadow.mapSize); 28259 if (_shadowMapSize.x > _maxTextureSize || _shadowMapSize.y > _maxTextureSize) { 28260 if (_shadowMapSize.x > _maxTextureSize) { 28261 _viewportSize.x = Math.floor(_maxTextureSize / shadowFrameExtents.x); 28262 _shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x; 28263 shadow.mapSize.x = _viewportSize.x; 28264 } 28265 if (_shadowMapSize.y > _maxTextureSize) { 28266 _viewportSize.y = Math.floor(_maxTextureSize / shadowFrameExtents.y); 28267 _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y; 28268 shadow.mapSize.y = _viewportSize.y; 28269 } 28270 } 28271 const reversedDepthBuffer = renderer.state.buffers.depth.getReversed(); 28272 shadow.camera._reversedDepth = reversedDepthBuffer; 28273 if (shadow.map === null || typeChanged === true) { 28274 if (shadow.map !== null) { 28275 if (shadow.map.depthTexture !== null) { 28276 shadow.map.depthTexture.dispose(); 28277 shadow.map.depthTexture = null; 28278 } 28279 shadow.map.dispose(); 28280 } 28281 if (this.type === VSMShadowMap) { 28282 if (light.isPointLight) { 28283 warn("WebGLShadowMap: VSM shadow maps are not supported for PointLights. Use PCF or BasicShadowMap instead."); 28284 continue; 28285 } 28286 shadow.map = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, { 28287 format: RGFormat, 28288 type: HalfFloatType, 28289 minFilter: LinearFilter, 28290 magFilter: LinearFilter, 28291 generateMipmaps: false 28292 }); 28293 shadow.map.texture.name = light.name + ".shadowMap"; 28294 shadow.map.depthTexture = new DepthTexture(_shadowMapSize.x, _shadowMapSize.y, FloatType); 28295 shadow.map.depthTexture.name = light.name + ".shadowMapDepth"; 28296 shadow.map.depthTexture.format = DepthFormat; 28297 shadow.map.depthTexture.compareFunction = null; 28298 shadow.map.depthTexture.minFilter = NearestFilter; 28299 shadow.map.depthTexture.magFilter = NearestFilter; 28300 } else { 28301 if (light.isPointLight) { 28302 shadow.map = new WebGLCubeRenderTarget(_shadowMapSize.x); 28303 shadow.map.depthTexture = new CubeDepthTexture(_shadowMapSize.x, UnsignedIntType); 28304 } else { 28305 shadow.map = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y); 28306 shadow.map.depthTexture = new DepthTexture(_shadowMapSize.x, _shadowMapSize.y, UnsignedIntType); 28307 } 28308 shadow.map.depthTexture.name = light.name + ".shadowMap"; 28309 shadow.map.depthTexture.format = DepthFormat; 28310 if (this.type === PCFShadowMap) { 28311 shadow.map.depthTexture.compareFunction = reversedDepthBuffer ? GreaterEqualCompare : LessEqualCompare; 28312 shadow.map.depthTexture.minFilter = LinearFilter; 28313 shadow.map.depthTexture.magFilter = LinearFilter; 28314 } else { 28315 shadow.map.depthTexture.compareFunction = null; 28316 shadow.map.depthTexture.minFilter = NearestFilter; 28317 shadow.map.depthTexture.magFilter = NearestFilter; 28318 } 28319 } 28320 shadow.camera.updateProjectionMatrix(); 28321 } 28322 const faceCount = shadow.map.isWebGLCubeRenderTarget ? 6 : 1; 28323 for (let face = 0; face < faceCount; face++) { 28324 if (shadow.map.isWebGLCubeRenderTarget) { 28325 renderer.setRenderTarget(shadow.map, face); 28326 renderer.clear(); 28327 } else { 28328 if (face === 0) { 28329 renderer.setRenderTarget(shadow.map); 28330 renderer.clear(); 28331 } 28332 const viewport = shadow.getViewport(face); 28333 _viewport.set( 28334 _viewportSize.x * viewport.x, 28335 _viewportSize.y * viewport.y, 28336 _viewportSize.x * viewport.z, 28337 _viewportSize.y * viewport.w 28338 ); 28339 _state.viewport(_viewport); 28340 } 28341 if (light.isPointLight) { 28342 const camera2 = shadow.camera; 28343 const shadowMatrix = shadow.matrix; 28344 const far = light.distance || camera2.far; 28345 if (far !== camera2.far) { 28346 camera2.far = far; 28347 camera2.updateProjectionMatrix(); 28348 } 28349 _lightPositionWorld2.setFromMatrixPosition(light.matrixWorld); 28350 camera2.position.copy(_lightPositionWorld2); 28351 _lookTarget2.copy(camera2.position); 28352 _lookTarget2.add(_cubeDirections[face]); 28353 camera2.up.copy(_cubeUps[face]); 28354 camera2.lookAt(_lookTarget2); 28355 camera2.updateMatrixWorld(); 28356 shadowMatrix.makeTranslation(-_lightPositionWorld2.x, -_lightPositionWorld2.y, -_lightPositionWorld2.z); 28357 _projScreenMatrix2.multiplyMatrices(camera2.projectionMatrix, camera2.matrixWorldInverse); 28358 shadow._frustum.setFromProjectionMatrix(_projScreenMatrix2, camera2.coordinateSystem, camera2.reversedDepth); 28359 } else { 28360 shadow.updateMatrices(light); 28361 } 28362 _frustum = shadow.getFrustum(); 28363 renderObject(scene, camera, shadow.camera, light, this.type); 28364 } 28365 if (shadow.isPointLightShadow !== true && this.type === VSMShadowMap) { 28366 VSMPass(shadow, camera); 28367 } 28368 shadow.needsUpdate = false; 28369 } 28370 _previousType = this.type; 28371 scope.needsUpdate = false; 28372 renderer.setRenderTarget(currentRenderTarget, activeCubeFace, activeMipmapLevel); 28373 }; 28374 function VSMPass(shadow, camera) { 28375 const geometry = objects.update(fullScreenMesh); 28376 if (shadowMaterialVertical.defines.VSM_SAMPLES !== shadow.blurSamples) { 28377 shadowMaterialVertical.defines.VSM_SAMPLES = shadow.blurSamples; 28378 shadowMaterialHorizontal.defines.VSM_SAMPLES = shadow.blurSamples; 28379 shadowMaterialVertical.needsUpdate = true; 28380 shadowMaterialHorizontal.needsUpdate = true; 28381 } 28382 if (shadow.mapPass === null) { 28383 shadow.mapPass = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, { 28384 format: RGFormat, 28385 type: HalfFloatType 28386 }); 28387 } 28388 shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.depthTexture; 28389 shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize; 28390 shadowMaterialVertical.uniforms.radius.value = shadow.radius; 28391 renderer.setRenderTarget(shadow.mapPass); 28392 renderer.clear(); 28393 renderer.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null); 28394 shadowMaterialHorizontal.uniforms.shadow_pass.value = shadow.mapPass.texture; 28395 shadowMaterialHorizontal.uniforms.resolution.value = shadow.mapSize; 28396 shadowMaterialHorizontal.uniforms.radius.value = shadow.radius; 28397 renderer.setRenderTarget(shadow.map); 28398 renderer.clear(); 28399 renderer.renderBufferDirect(camera, null, geometry, shadowMaterialHorizontal, fullScreenMesh, null); 28400 } 28401 function getDepthMaterial(object, material, light, type) { 28402 let result = null; 28403 const customMaterial = light.isPointLight === true ? object.customDistanceMaterial : object.customDepthMaterial; 28404 if (customMaterial !== void 0) { 28405 result = customMaterial; 28406 } else { 28407 result = light.isPointLight === true ? _distanceMaterial : _depthMaterial; 28408 if (renderer.localClippingEnabled && material.clipShadows === true && Array.isArray(material.clippingPlanes) && material.clippingPlanes.length !== 0 || material.displacementMap && material.displacementScale !== 0 || material.alphaMap && material.alphaTest > 0 || material.map && material.alphaTest > 0 || material.alphaToCoverage === true) { 28409 const keyA = result.uuid, keyB = material.uuid; 28410 let materialsForVariant = _materialCache[keyA]; 28411 if (materialsForVariant === void 0) { 28412 materialsForVariant = {}; 28413 _materialCache[keyA] = materialsForVariant; 28414 } 28415 let cachedMaterial = materialsForVariant[keyB]; 28416 if (cachedMaterial === void 0) { 28417 cachedMaterial = result.clone(); 28418 materialsForVariant[keyB] = cachedMaterial; 28419 material.addEventListener("dispose", onMaterialDispose); 28420 } 28421 result = cachedMaterial; 28422 } 28423 } 28424 result.visible = material.visible; 28425 result.wireframe = material.wireframe; 28426 if (type === VSMShadowMap) { 28427 result.side = material.shadowSide !== null ? material.shadowSide : material.side; 28428 } else { 28429 result.side = material.shadowSide !== null ? material.shadowSide : shadowSide[material.side]; 28430 } 28431 result.alphaMap = material.alphaMap; 28432 result.alphaTest = material.alphaToCoverage === true ? 0.5 : material.alphaTest; 28433 result.map = material.map; 28434 result.clipShadows = material.clipShadows; 28435 result.clippingPlanes = material.clippingPlanes; 28436 result.clipIntersection = material.clipIntersection; 28437 result.displacementMap = material.displacementMap; 28438 result.displacementScale = material.displacementScale; 28439 result.displacementBias = material.displacementBias; 28440 result.wireframeLinewidth = material.wireframeLinewidth; 28441 result.linewidth = material.linewidth; 28442 if (light.isPointLight === true && result.isMeshDistanceMaterial === true) { 28443 const materialProperties = renderer.properties.get(result); 28444 materialProperties.light = light; 28445 } 28446 return result; 28447 } 28448 function renderObject(object, camera, shadowCamera, light, type) { 28449 if (object.visible === false) return; 28450 const visible = object.layers.test(camera.layers); 28451 if (visible && (object.isMesh || object.isLine || object.isPoints)) { 28452 if ((object.castShadow || object.receiveShadow && type === VSMShadowMap) && (!object.frustumCulled || _frustum.intersectsObject(object))) { 28453 object.modelViewMatrix.multiplyMatrices(shadowCamera.matrixWorldInverse, object.matrixWorld); 28454 const geometry = objects.update(object); 28455 const material = object.material; 28456 if (Array.isArray(material)) { 28457 const groups = geometry.groups; 28458 for (let k = 0, kl = groups.length; k < kl; k++) { 28459 const group = groups[k]; 28460 const groupMaterial = material[group.materialIndex]; 28461 if (groupMaterial && groupMaterial.visible) { 28462 const depthMaterial = getDepthMaterial(object, groupMaterial, light, type); 28463 object.onBeforeShadow(renderer, object, camera, shadowCamera, geometry, depthMaterial, group); 28464 renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, group); 28465 object.onAfterShadow(renderer, object, camera, shadowCamera, geometry, depthMaterial, group); 28466 } 28467 } 28468 } else if (material.visible) { 28469 const depthMaterial = getDepthMaterial(object, material, light, type); 28470 object.onBeforeShadow(renderer, object, camera, shadowCamera, geometry, depthMaterial, null); 28471 renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, null); 28472 object.onAfterShadow(renderer, object, camera, shadowCamera, geometry, depthMaterial, null); 28473 } 28474 } 28475 } 28476 const children2 = object.children; 28477 for (let i = 0, l = children2.length; i < l; i++) { 28478 renderObject(children2[i], camera, shadowCamera, light, type); 28479 } 28480 } 28481 function onMaterialDispose(event) { 28482 const material = event.target; 28483 material.removeEventListener("dispose", onMaterialDispose); 28484 for (const id in _materialCache) { 28485 const cache = _materialCache[id]; 28486 const uuid = event.target.uuid; 28487 if (uuid in cache) { 28488 const shadowMaterial = cache[uuid]; 28489 shadowMaterial.dispose(); 28490 delete cache[uuid]; 28491 } 28492 } 28493 } 28494} 28495function WebGLState(gl, extensions) { 28496 function ColorBuffer() { 28497 let locked = false; 28498 const color = new Vector4(); 28499 let currentColorMask = null; 28500 const currentColorClear = new Vector4(0, 0, 0, 0); 28501 return { 28502 setMask: function(colorMask) { 28503 if (currentColorMask !== colorMask && !locked) { 28504 gl.colorMask(colorMask, colorMask, colorMask, colorMask); 28505 currentColorMask = colorMask; 28506 } 28507 }, 28508 setLocked: function(lock) { 28509 locked = lock; 28510 }, 28511 setClear: function(r, g, b, a, premultipliedAlpha) { 28512 if (premultipliedAlpha === true) { 28513 r *= a; 28514 g *= a; 28515 b *= a; 28516 } 28517 color.set(r, g, b, a); 28518 if (currentColorClear.equals(color) === false) { 28519 gl.clearColor(r, g, b, a); 28520 currentColorClear.copy(color); 28521 } 28522 }, 28523 reset: function() { 28524 locked = false; 28525 currentColorMask = null; 28526 currentColorClear.set(-1, 0, 0, 0); 28527 } 28528 }; 28529 } 28530 function DepthBuffer() { 28531 let locked = false; 28532 let currentReversed = false; 28533 let currentDepthMask = null; 28534 let currentDepthFunc = null; 28535 let currentDepthClear = null; 28536 return { 28537 setReversed: function(reversed) { 28538 if (currentReversed !== reversed) { 28539 const ext = extensions.get("EXT_clip_control"); 28540 if (reversed) { 28541 ext.clipControlEXT(ext.LOWER_LEFT_EXT, ext.ZERO_TO_ONE_EXT); 28542 } else { 28543 ext.clipControlEXT(ext.LOWER_LEFT_EXT, ext.NEGATIVE_ONE_TO_ONE_EXT); 28544 } 28545 currentReversed = reversed; 28546 const oldDepth = currentDepthClear; 28547 currentDepthClear = null; 28548 this.setClear(oldDepth); 28549 } 28550 }, 28551 getReversed: function() { 28552 return currentReversed; 28553 }, 28554 setTest: function(depthTest) { 28555 if (depthTest) { 28556 enable(gl.DEPTH_TEST); 28557 } else { 28558 disable(gl.DEPTH_TEST); 28559 } 28560 }, 28561 setMask: function(depthMask) { 28562 if (currentDepthMask !== depthMask && !locked) { 28563 gl.depthMask(depthMask); 28564 currentDepthMask = depthMask; 28565 } 28566 }, 28567 setFunc: function(depthFunc) { 28568 if (currentReversed) depthFunc = ReversedDepthFuncs[depthFunc]; 28569 if (currentDepthFunc !== depthFunc) { 28570 switch (depthFunc) { 28571 case NeverDepth: 28572 gl.depthFunc(gl.NEVER); 28573 break; 28574 case AlwaysDepth: 28575 gl.depthFunc(gl.ALWAYS); 28576 break; 28577 case LessDepth: 28578 gl.depthFunc(gl.LESS); 28579 break; 28580 case LessEqualDepth: 28581 gl.depthFunc(gl.LEQUAL); 28582 break; 28583 case EqualDepth: 28584 gl.depthFunc(gl.EQUAL); 28585 break; 28586 case GreaterEqualDepth: 28587 gl.depthFunc(gl.GEQUAL); 28588 break; 28589 case GreaterDepth: 28590 gl.depthFunc(gl.GREATER); 28591 break; 28592 case NotEqualDepth: 28593 gl.depthFunc(gl.NOTEQUAL); 28594 break; 28595 default: 28596 gl.depthFunc(gl.LEQUAL); 28597 } 28598 currentDepthFunc = depthFunc; 28599 } 28600 }, 28601 setLocked: function(lock) { 28602 locked = lock; 28603 }, 28604 setClear: function(depth) { 28605 if (currentDepthClear !== depth) { 28606 currentDepthClear = depth; 28607 if (currentReversed) { 28608 depth = 1 - depth; 28609 } 28610 gl.clearDepth(depth); 28611 } 28612 }, 28613 reset: function() { 28614 locked = false; 28615 currentDepthMask = null; 28616 currentDepthFunc = null; 28617 currentDepthClear = null; 28618 currentReversed = false; 28619 } 28620 }; 28621 } 28622 function StencilBuffer() { 28623 let locked = false; 28624 let currentStencilMask = null; 28625 let currentStencilFunc = null; 28626 let currentStencilRef = null; 28627 let currentStencilFuncMask = null; 28628 let currentStencilFail = null; 28629 let currentStencilZFail = null; 28630 let currentStencilZPass = null; 28631 let currentStencilClear = null; 28632 return { 28633 setTest: function(stencilTest) { 28634 if (!locked) { 28635 if (stencilTest) { 28636 enable(gl.STENCIL_TEST); 28637 } else { 28638 disable(gl.STENCIL_TEST); 28639 } 28640 } 28641 }, 28642 setMask: function(stencilMask) { 28643 if (currentStencilMask !== stencilMask && !locked) { 28644 gl.stencilMask(stencilMask); 28645 currentStencilMask = stencilMask; 28646 } 28647 }, 28648 setFunc: function(stencilFunc, stencilRef, stencilMask) { 28649 if (currentStencilFunc !== stencilFunc || currentStencilRef !== stencilRef || currentStencilFuncMask !== stencilMask) { 28650 gl.stencilFunc(stencilFunc, stencilRef, stencilMask); 28651 currentStencilFunc = stencilFunc; 28652 currentStencilRef = stencilRef; 28653 currentStencilFuncMask = stencilMask; 28654 } 28655 }, 28656 setOp: function(stencilFail, stencilZFail, stencilZPass) { 28657 if (currentStencilFail !== stencilFail || currentStencilZFail !== stencilZFail || currentStencilZPass !== stencilZPass) { 28658 gl.stencilOp(stencilFail, stencilZFail, stencilZPass); 28659 currentStencilFail = stencilFail; 28660 currentStencilZFail = stencilZFail; 28661 currentStencilZPass = stencilZPass; 28662 } 28663 }, 28664 setLocked: function(lock) { 28665 locked = lock; 28666 }, 28667 setClear: function(stencil) { 28668 if (currentStencilClear !== stencil) { 28669 gl.clearStencil(stencil); 28670 currentStencilClear = stencil; 28671 } 28672 }, 28673 reset: function() { 28674 locked = false; 28675 currentStencilMask = null; 28676 currentStencilFunc = null; 28677 currentStencilRef = null; 28678 currentStencilFuncMask = null; 28679 currentStencilFail = null; 28680 currentStencilZFail = null; 28681 currentStencilZPass = null; 28682 currentStencilClear = null; 28683 } 28684 }; 28685 } 28686 const colorBuffer = new ColorBuffer(); 28687 const depthBuffer = new DepthBuffer(); 28688 const stencilBuffer = new StencilBuffer(); 28689 const uboBindings = /* @__PURE__ */ new WeakMap(); 28690 const uboProgramMap = /* @__PURE__ */ new WeakMap(); 28691 let enabledCapabilities = {}; 28692 let parameters = {}; 28693 let currentBoundFramebuffers = {}; 28694 let currentDrawbuffers = /* @__PURE__ */ new WeakMap(); 28695 let defaultDrawbuffers = []; 28696 let currentProgram = null; 28697 let currentBlendingEnabled = false; 28698 let currentBlending = null; 28699 let currentBlendEquation = null; 28700 let currentBlendSrc = null; 28701 let currentBlendDst = null; 28702 let currentBlendEquationAlpha = null; 28703 let currentBlendSrcAlpha = null; 28704 let currentBlendDstAlpha = null; 28705 let currentBlendColor = new Color(0, 0, 0); 28706 let currentBlendAlpha = 0; 28707 let currentPremultipledAlpha = false; 28708 let currentFlipSided = null; 28709 let currentCullFace = null; 28710 let currentLineWidth = null; 28711 let currentPolygonOffsetFactor = null; 28712 let currentPolygonOffsetUnits = null; 28713 const maxTextures = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS); 28714 let lineWidthAvailable = false; 28715 let version = 0; 28716 const glVersion = gl.getParameter(gl.VERSION); 28717 if (glVersion.indexOf("WebGL") !== -1) { 28718 version = parseFloat(/^WebGL (\d)/.exec(glVersion)[1]); 28719 lineWidthAvailable = version >= 1; 28720 } else if (glVersion.indexOf("OpenGL ES") !== -1) { 28721 version = parseFloat(/^OpenGL ES (\d)/.exec(glVersion)[1]); 28722 lineWidthAvailable = version >= 2; 28723 } 28724 let currentTextureSlot = null; 28725 let currentBoundTextures = {}; 28726 const scissorParam = gl.getParameter(gl.SCISSOR_BOX); 28727 const viewportParam = gl.getParameter(gl.VIEWPORT); 28728 const currentScissor = new Vector4().fromArray(scissorParam); 28729 const currentViewport = new Vector4().fromArray(viewportParam); 28730 function createTexture(type, target, count, dimensions) { 28731 const data = new Uint8Array(4); 28732 const texture = gl.createTexture(); 28733 gl.bindTexture(type, texture); 28734 gl.texParameteri(type, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 28735 gl.texParameteri(type, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 28736 for (let i = 0; i < count; i++) { 28737 if (type === gl.TEXTURE_3D || type === gl.TEXTURE_2D_ARRAY) { 28738 gl.texImage3D(target, 0, gl.RGBA, 1, 1, dimensions, 0, gl.RGBA, gl.UNSIGNED_BYTE, data); 28739 } else { 28740 gl.texImage2D(target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data); 28741 } 28742 } 28743 return texture; 28744 } 28745 const emptyTextures = {}; 28746 emptyTextures[gl.TEXTURE_2D] = createTexture(gl.TEXTURE_2D, gl.TEXTURE_2D, 1); 28747 emptyTextures[gl.TEXTURE_CUBE_MAP] = createTexture(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6); 28748 emptyTextures[gl.TEXTURE_2D_ARRAY] = createTexture(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_2D_ARRAY, 1, 1); 28749 emptyTextures[gl.TEXTURE_3D] = createTexture(gl.TEXTURE_3D, gl.TEXTURE_3D, 1, 1); 28750 colorBuffer.setClear(0, 0, 0, 1); 28751 depthBuffer.setClear(1); 28752 stencilBuffer.setClear(0); 28753 enable(gl.DEPTH_TEST); 28754 depthBuffer.setFunc(LessEqualDepth); 28755 setFlipSided(false); 28756 setCullFace(CullFaceBack); 28757 enable(gl.CULL_FACE); 28758 setBlending(NoBlending); 28759 function enable(id) { 28760 if (enabledCapabilities[id] !== true) { 28761 gl.enable(id); 28762 enabledCapabilities[id] = true; 28763 } 28764 } 28765 function disable(id) { 28766 if (enabledCapabilities[id] !== false) { 28767 gl.disable(id); 28768 enabledCapabilities[id] = false; 28769 } 28770 } 28771 function bindFramebuffer(target, framebuffer) { 28772 if (currentBoundFramebuffers[target] !== framebuffer) { 28773 gl.bindFramebuffer(target, framebuffer); 28774 currentBoundFramebuffers[target] = framebuffer; 28775 if (target === gl.DRAW_FRAMEBUFFER) { 28776 currentBoundFramebuffers[gl.FRAMEBUFFER] = framebuffer; 28777 } 28778 if (target === gl.FRAMEBUFFER) { 28779 currentBoundFramebuffers[gl.DRAW_FRAMEBUFFER] = framebuffer; 28780 } 28781 return true; 28782 } 28783 return false; 28784 } 28785 function drawBuffers(renderTarget, framebuffer) { 28786 let drawBuffers2 = defaultDrawbuffers; 28787 let needsUpdate = false; 28788 if (renderTarget) { 28789 drawBuffers2 = currentDrawbuffers.get(framebuffer); 28790 if (drawBuffers2 === void 0) { 28791 drawBuffers2 = []; 28792 currentDrawbuffers.set(framebuffer, drawBuffers2); 28793 } 28794 const textures = renderTarget.textures; 28795 if (drawBuffers2.length !== textures.length || drawBuffers2[0] !== gl.COLOR_ATTACHMENT0) { 28796 for (let i = 0, il = textures.length; i < il; i++) { 28797 drawBuffers2[i] = gl.COLOR_ATTACHMENT0 + i; 28798 } 28799 drawBuffers2.length = textures.length; 28800 needsUpdate = true; 28801 } 28802 } else { 28803 if (drawBuffers2[0] !== gl.BACK) { 28804 drawBuffers2[0] = gl.BACK; 28805 needsUpdate = true; 28806 } 28807 } 28808 if (needsUpdate) { 28809 gl.drawBuffers(drawBuffers2); 28810 } 28811 } 28812 function useProgram(program) { 28813 if (currentProgram !== program) { 28814 gl.useProgram(program); 28815 currentProgram = program; 28816 return true; 28817 } 28818 return false; 28819 } 28820 const equationToGL = { 28821 [AddEquation]: gl.FUNC_ADD, 28822 [SubtractEquation]: gl.FUNC_SUBTRACT, 28823 [ReverseSubtractEquation]: gl.FUNC_REVERSE_SUBTRACT 28824 }; 28825 equationToGL[MinEquation] = gl.MIN; 28826 equationToGL[MaxEquation] = gl.MAX; 28827 const factorToGL = { 28828 [ZeroFactor]: gl.ZERO, 28829 [OneFactor]: gl.ONE, 28830 [SrcColorFactor]: gl.SRC_COLOR, 28831 [SrcAlphaFactor]: gl.SRC_ALPHA, 28832 [SrcAlphaSaturateFactor]: gl.SRC_ALPHA_SATURATE, 28833 [DstColorFactor]: gl.DST_COLOR, 28834 [DstAlphaFactor]: gl.DST_ALPHA, 28835 [OneMinusSrcColorFactor]: gl.ONE_MINUS_SRC_COLOR, 28836 [OneMinusSrcAlphaFactor]: gl.ONE_MINUS_SRC_ALPHA, 28837 [OneMinusDstColorFactor]: gl.ONE_MINUS_DST_COLOR, 28838 [OneMinusDstAlphaFactor]: gl.ONE_MINUS_DST_ALPHA, 28839 [ConstantColorFactor]: gl.CONSTANT_COLOR, 28840 [OneMinusConstantColorFactor]: gl.ONE_MINUS_CONSTANT_COLOR, 28841 [ConstantAlphaFactor]: gl.CONSTANT_ALPHA, 28842 [OneMinusConstantAlphaFactor]: gl.ONE_MINUS_CONSTANT_ALPHA 28843 }; 28844 function setBlending(blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, blendColor, blendAlpha, premultipliedAlpha) { 28845 if (blending === NoBlending) { 28846 if (currentBlendingEnabled === true) { 28847 disable(gl.BLEND); 28848 currentBlendingEnabled = false; 28849 } 28850 return; 28851 } 28852 if (currentBlendingEnabled === false) { 28853 enable(gl.BLEND); 28854 currentBlendingEnabled = true; 28855 } 28856 if (blending !== CustomBlending) { 28857 if (blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha) { 28858 if (currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation) { 28859 gl.blendEquation(gl.FUNC_ADD); 28860 currentBlendEquation = AddEquation; 28861 currentBlendEquationAlpha = AddEquation; 28862 } 28863 if (premultipliedAlpha) { 28864 switch (blending) { 28865 case NormalBlending: 28866 gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); 28867 break; 28868 case AdditiveBlending: 28869 gl.blendFunc(gl.ONE, gl.ONE); 28870 break; 28871 case SubtractiveBlending: 28872 gl.blendFuncSeparate(gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE); 28873 break; 28874 case MultiplyBlending: 28875 gl.blendFuncSeparate(gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ONE); 28876 break; 28877 default: 28878 error("WebGLState: Invalid blending: ", blending); 28879 break; 28880 } 28881 } else { 28882 switch (blending) { 28883 case NormalBlending: 28884 gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); 28885 break; 28886 case AdditiveBlending: 28887 gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE, gl.ONE, gl.ONE); 28888 break; 28889 case SubtractiveBlending: 28890 error("WebGLState: SubtractiveBlending requires material.premultipliedAlpha = true"); 28891 break; 28892 case MultiplyBlending: 28893 error("WebGLState: MultiplyBlending requires material.premultipliedAlpha = true"); 28894 break; 28895 default: 28896 error("WebGLState: Invalid blending: ", blending); 28897 break; 28898 } 28899 } 28900 currentBlendSrc = null; 28901 currentBlendDst = null; 28902 currentBlendSrcAlpha = null; 28903 currentBlendDstAlpha = null; 28904 currentBlendColor.set(0, 0, 0); 28905 currentBlendAlpha = 0; 28906 currentBlending = blending; 28907 currentPremultipledAlpha = premultipliedAlpha; 28908 } 28909 return; 28910 } 28911 blendEquationAlpha = blendEquationAlpha || blendEquation; 28912 blendSrcAlpha = blendSrcAlpha || blendSrc; 28913 blendDstAlpha = blendDstAlpha || blendDst; 28914 if (blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha) { 28915 gl.blendEquationSeparate(equationToGL[blendEquation], equationToGL[blendEquationAlpha]); 28916 currentBlendEquation = blendEquation; 28917 currentBlendEquationAlpha = blendEquationAlpha; 28918 } 28919 if (blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha) { 28920 gl.blendFuncSeparate(factorToGL[blendSrc], factorToGL[blendDst], factorToGL[blendSrcAlpha], factorToGL[blendDstAlpha]); 28921 currentBlendSrc = blendSrc; 28922 currentBlendDst = blendDst; 28923 currentBlendSrcAlpha = blendSrcAlpha; 28924 currentBlendDstAlpha = blendDstAlpha; 28925 } 28926 if (blendColor.equals(currentBlendColor) === false || blendAlpha !== currentBlendAlpha) { 28927 gl.blendColor(blendColor.r, blendColor.g, blendColor.b, blendAlpha); 28928 currentBlendColor.copy(blendColor); 28929 currentBlendAlpha = blendAlpha; 28930 } 28931 currentBlending = blending; 28932 currentPremultipledAlpha = false; 28933 } 28934 function setMaterial(material, frontFaceCW) { 28935 material.side === DoubleSide ? disable(gl.CULL_FACE) : enable(gl.CULL_FACE); 28936 let flipSided = material.side === BackSide; 28937 if (frontFaceCW) flipSided = !flipSided; 28938 setFlipSided(flipSided); 28939 material.blending === NormalBlending && material.transparent === false ? setBlending(NoBlending) : setBlending(material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.blendColor, material.blendAlpha, material.premultipliedAlpha); 28940 depthBuffer.setFunc(material.depthFunc); 28941 depthBuffer.setTest(material.depthTest); 28942 depthBuffer.setMask(material.depthWrite); 28943 colorBuffer.setMask(material.colorWrite); 28944 const stencilWrite = material.stencilWrite; 28945 stencilBuffer.setTest(stencilWrite); 28946 if (stencilWrite) { 28947 stencilBuffer.setMask(material.stencilWriteMask); 28948 stencilBuffer.setFunc(material.stencilFunc, material.stencilRef, material.stencilFuncMask); 28949 stencilBuffer.setOp(material.stencilFail, material.stencilZFail, material.stencilZPass); 28950 } 28951 setPolygonOffset(material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits); 28952 material.alphaToCoverage === true ? enable(gl.SAMPLE_ALPHA_TO_COVERAGE) : disable(gl.SAMPLE_ALPHA_TO_COVERAGE); 28953 } 28954 function setFlipSided(flipSided) { 28955 if (currentFlipSided !== flipSided) { 28956 if (flipSided) { 28957 gl.frontFace(gl.CW); 28958 } else { 28959 gl.frontFace(gl.CCW); 28960 } 28961 currentFlipSided = flipSided; 28962 } 28963 } 28964 function setCullFace(cullFace) { 28965 if (cullFace !== CullFaceNone) { 28966 enable(gl.CULL_FACE); 28967 if (cullFace !== currentCullFace) { 28968 if (cullFace === CullFaceBack) { 28969 gl.cullFace(gl.BACK); 28970 } else if (cullFace === CullFaceFront) { 28971 gl.cullFace(gl.FRONT); 28972 } else { 28973 gl.cullFace(gl.FRONT_AND_BACK); 28974 } 28975 } 28976 } else { 28977 disable(gl.CULL_FACE); 28978 } 28979 currentCullFace = cullFace; 28980 } 28981 function setLineWidth(width) { 28982 if (width !== currentLineWidth) { 28983 if (lineWidthAvailable) gl.lineWidth(width); 28984 currentLineWidth = width; 28985 } 28986 } 28987 function setPolygonOffset(polygonOffset, factor, units) { 28988 if (polygonOffset) { 28989 enable(gl.POLYGON_OFFSET_FILL); 28990 if (currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units) { 28991 currentPolygonOffsetFactor = factor; 28992 currentPolygonOffsetUnits = units; 28993 if (depthBuffer.getReversed()) { 28994 factor = -factor; 28995 } 28996 gl.polygonOffset(factor, units); 28997 } 28998 } else { 28999 disable(gl.POLYGON_OFFSET_FILL); 29000 } 29001 } 29002 function setScissorTest(scissorTest) { 29003 if (scissorTest) { 29004 enable(gl.SCISSOR_TEST); 29005 } else { 29006 disable(gl.SCISSOR_TEST); 29007 } 29008 } 29009 function activeTexture(webglSlot) { 29010 if (webglSlot === void 0) webglSlot = gl.TEXTURE0 + maxTextures - 1; 29011 if (currentTextureSlot !== webglSlot) { 29012 gl.activeTexture(webglSlot); 29013 currentTextureSlot = webglSlot; 29014 } 29015 } 29016 function bindTexture(webglType, webglTexture, webglSlot) { 29017 if (webglSlot === void 0) { 29018 if (currentTextureSlot === null) { 29019 webglSlot = gl.TEXTURE0 + maxTextures - 1; 29020 } else { 29021 webglSlot = currentTextureSlot; 29022 } 29023 } 29024 let boundTexture = currentBoundTextures[webglSlot]; 29025 if (boundTexture === void 0) { 29026 boundTexture = { type: void 0, texture: void 0 }; 29027 currentBoundTextures[webglSlot] = boundTexture; 29028 } 29029 if (boundTexture.type !== webglType || boundTexture.texture !== webglTexture) { 29030 if (currentTextureSlot !== webglSlot) { 29031 gl.activeTexture(webglSlot); 29032 currentTextureSlot = webglSlot; 29033 } 29034 gl.bindTexture(webglType, webglTexture || emptyTextures[webglType]); 29035 boundTexture.type = webglType; 29036 boundTexture.texture = webglTexture; 29037 } 29038 } 29039 function unbindTexture() { 29040 const boundTexture = currentBoundTextures[currentTextureSlot]; 29041 if (boundTexture !== void 0 && boundTexture.type !== void 0) { 29042 gl.bindTexture(boundTexture.type, null); 29043 boundTexture.type = void 0; 29044 boundTexture.texture = void 0; 29045 } 29046 } 29047 function compressedTexImage2D() { 29048 try { 29049 gl.compressedTexImage2D(...arguments); 29050 } catch (e) { 29051 error("WebGLState:", e); 29052 } 29053 } 29054 function compressedTexImage3D() { 29055 try { 29056 gl.compressedTexImage3D(...arguments); 29057 } catch (e) { 29058 error("WebGLState:", e); 29059 } 29060 } 29061 function texSubImage2D() { 29062 try { 29063 gl.texSubImage2D(...arguments); 29064 } catch (e) { 29065 error("WebGLState:", e); 29066 } 29067 } 29068 function texSubImage3D() { 29069 try { 29070 gl.texSubImage3D(...arguments); 29071 } catch (e) { 29072 error("WebGLState:", e); 29073 } 29074 } 29075 function compressedTexSubImage2D() { 29076 try { 29077 gl.compressedTexSubImage2D(...arguments); 29078 } catch (e) { 29079 error("WebGLState:", e); 29080 } 29081 } 29082 function compressedTexSubImage3D() { 29083 try { 29084 gl.compressedTexSubImage3D(...arguments); 29085 } catch (e) { 29086 error("WebGLState:", e); 29087 } 29088 } 29089 function texStorage2D() { 29090 try { 29091 gl.texStorage2D(...arguments); 29092 } catch (e) { 29093 error("WebGLState:", e); 29094 } 29095 } 29096 function texStorage3D() { 29097 try { 29098 gl.texStorage3D(...arguments); 29099 } catch (e) { 29100 error("WebGLState:", e); 29101 } 29102 } 29103 function texImage2D() { 29104 try { 29105 gl.texImage2D(...arguments); 29106 } catch (e) { 29107 error("WebGLState:", e); 29108 } 29109 } 29110 function texImage3D() { 29111 try { 29112 gl.texImage3D(...arguments); 29113 } catch (e) { 29114 error("WebGLState:", e); 29115 } 29116 } 29117 function getParameter(name) { 29118 if (parameters[name] !== void 0) { 29119 return parameters[name]; 29120 } else { 29121 return gl.getParameter(name); 29122 } 29123 } 29124 function pixelStorei(name, value) { 29125 if (parameters[name] !== value) { 29126 gl.pixelStorei(name, value); 29127 parameters[name] = value; 29128 } 29129 } 29130 function scissor(scissor2) { 29131 if (currentScissor.equals(scissor2) === false) { 29132 gl.scissor(scissor2.x, scissor2.y, scissor2.z, scissor2.w); 29133 currentScissor.copy(scissor2); 29134 } 29135 } 29136 function viewport(viewport2) { 29137 if (currentViewport.equals(viewport2) === false) { 29138 gl.viewport(viewport2.x, viewport2.y, viewport2.z, viewport2.w); 29139 currentViewport.copy(viewport2); 29140 } 29141 } 29142 function updateUBOMapping(uniformsGroup, program) { 29143 let mapping = uboProgramMap.get(program); 29144 if (mapping === void 0) { 29145 mapping = /* @__PURE__ */ new WeakMap(); 29146 uboProgramMap.set(program, mapping); 29147 } 29148 let blockIndex = mapping.get(uniformsGroup); 29149 if (blockIndex === void 0) { 29150 blockIndex = gl.getUniformBlockIndex(program, uniformsGroup.name); 29151 mapping.set(uniformsGroup, blockIndex); 29152 } 29153 } 29154 function uniformBlockBinding(uniformsGroup, program) { 29155 const mapping = uboProgramMap.get(program); 29156 const blockIndex = mapping.get(uniformsGroup); 29157 if (uboBindings.get(program) !== blockIndex) { 29158 gl.uniformBlockBinding(program, blockIndex, uniformsGroup.__bindingPointIndex); 29159 uboBindings.set(program, blockIndex); 29160 } 29161 } 29162 function reset2() { 29163 gl.disable(gl.BLEND); 29164 gl.disable(gl.CULL_FACE); 29165 gl.disable(gl.DEPTH_TEST); 29166 gl.disable(gl.POLYGON_OFFSET_FILL); 29167 gl.disable(gl.SCISSOR_TEST); 29168 gl.disable(gl.STENCIL_TEST); 29169 gl.disable(gl.SAMPLE_ALPHA_TO_COVERAGE); 29170 gl.blendEquation(gl.FUNC_ADD); 29171 gl.blendFunc(gl.ONE, gl.ZERO); 29172 gl.blendFuncSeparate(gl.ONE, gl.ZERO, gl.ONE, gl.ZERO); 29173 gl.blendColor(0, 0, 0, 0); 29174 gl.colorMask(true, true, true, true); 29175 gl.clearColor(0, 0, 0, 0); 29176 gl.depthMask(true); 29177 gl.depthFunc(gl.LESS); 29178 depthBuffer.setReversed(false); 29179 gl.clearDepth(1); 29180 gl.stencilMask(4294967295); 29181 gl.stencilFunc(gl.ALWAYS, 0, 4294967295); 29182 gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); 29183 gl.clearStencil(0); 29184 gl.cullFace(gl.BACK); 29185 gl.frontFace(gl.CCW); 29186 gl.polygonOffset(0, 0); 29187 gl.activeTexture(gl.TEXTURE0); 29188 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 29189 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null); 29190 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null); 29191 gl.useProgram(null); 29192 gl.lineWidth(1); 29193 gl.scissor(0, 0, gl.canvas.width, gl.canvas.height); 29194 gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); 29195 gl.pixelStorei(gl.PACK_ALIGNMENT, 4); 29196 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4); 29197 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); 29198 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); 29199 gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.BROWSER_DEFAULT_WEBGL); 29200 gl.pixelStorei(gl.PACK_ROW_LENGTH, 0); 29201 gl.pixelStorei(gl.PACK_SKIP_PIXELS, 0); 29202 gl.pixelStorei(gl.PACK_SKIP_ROWS, 0); 29203 gl.pixelStorei(gl.UNPACK_ROW_LENGTH, 0); 29204 gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, 0); 29205 gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0); 29206 gl.pixelStorei(gl.UNPACK_SKIP_ROWS, 0); 29207 gl.pixelStorei(gl.UNPACK_SKIP_IMAGES, 0); 29208 enabledCapabilities = {}; 29209 parameters = {}; 29210 currentTextureSlot = null; 29211 currentBoundTextures = {}; 29212 currentBoundFramebuffers = {}; 29213 currentDrawbuffers = /* @__PURE__ */ new WeakMap(); 29214 defaultDrawbuffers = []; 29215 currentProgram = null; 29216 currentBlendingEnabled = false; 29217 currentBlending = null; 29218 currentBlendEquation = null; 29219 currentBlendSrc = null; 29220 currentBlendDst = null; 29221 currentBlendEquationAlpha = null; 29222 currentBlendSrcAlpha = null; 29223 currentBlendDstAlpha = null; 29224 currentBlendColor = new Color(0, 0, 0); 29225 currentBlendAlpha = 0; 29226 currentPremultipledAlpha = false; 29227 currentFlipSided = null; 29228 currentCullFace = null; 29229 currentLineWidth = null; 29230 currentPolygonOffsetFactor = null; 29231 currentPolygonOffsetUnits = null; 29232 currentScissor.set(0, 0, gl.canvas.width, gl.canvas.height); 29233 currentViewport.set(0, 0, gl.canvas.width, gl.canvas.height); 29234 colorBuffer.reset(); 29235 depthBuffer.reset(); 29236 stencilBuffer.reset(); 29237 } 29238 return { 29239 buffers: { 29240 color: colorBuffer, 29241 depth: depthBuffer, 29242 stencil: stencilBuffer 29243 }, 29244 enable, 29245 disable, 29246 bindFramebuffer, 29247 drawBuffers, 29248 useProgram, 29249 setBlending, 29250 setMaterial, 29251 setFlipSided, 29252 setCullFace, 29253 setLineWidth, 29254 setPolygonOffset, 29255 setScissorTest, 29256 activeTexture, 29257 bindTexture, 29258 unbindTexture, 29259 compressedTexImage2D, 29260 compressedTexImage3D, 29261 texImage2D, 29262 texImage3D, 29263 pixelStorei, 29264 getParameter, 29265 updateUBOMapping, 29266 uniformBlockBinding, 29267 texStorage2D, 29268 texStorage3D, 29269 texSubImage2D, 29270 texSubImage3D, 29271 compressedTexSubImage2D, 29272 compressedTexSubImage3D, 29273 scissor, 29274 viewport, 29275 reset: reset2 29276 }; 29277} 29278function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info) { 29279 const multisampledRTTExt = extensions.has("WEBGL_multisampled_render_to_texture") ? extensions.get("WEBGL_multisampled_render_to_texture") : null; 29280 const supportsInvalidateFramebuffer = typeof navigator === "undefined" ? false : /OculusBrowser/g.test(navigator.userAgent); 29281 const _imageDimensions = new Vector2(); 29282 const _videoTextures = /* @__PURE__ */ new WeakMap(); 29283 const _htmlTextures = /* @__PURE__ */ new Set(); 29284 let _canvas2; 29285 const _sources = /* @__PURE__ */ new WeakMap(); 29286 let useOffscreenCanvas = false; 29287 try { 29288 useOffscreenCanvas = typeof OffscreenCanvas !== "undefined" && new OffscreenCanvas(1, 1).getContext("2d") !== null; 29289 } catch (err) { 29290 } 29291 function createCanvas(width, height) { 29292 return useOffscreenCanvas ? new OffscreenCanvas(width, height) : createElementNS("canvas"); 29293 } 29294 function resizeImage(image, needsNewCanvas, maxSize) { 29295 let scale = 1; 29296 const dimensions = getDimensions(image); 29297 if (dimensions.width > maxSize || dimensions.height > maxSize) { 29298 scale = maxSize / Math.max(dimensions.width, dimensions.height); 29299 } 29300 if (scale < 1) { 29301 if (typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== "undefined" && image instanceof HTMLCanvasElement || typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap || typeof VideoFrame !== "undefined" && image instanceof VideoFrame) { 29302 const width = Math.floor(scale * dimensions.width); 29303 const height = Math.floor(scale * dimensions.height); 29304 if (_canvas2 === void 0) _canvas2 = createCanvas(width, height); 29305 const canvas = needsNewCanvas ? createCanvas(width, height) : _canvas2; 29306 canvas.width = width; 29307 canvas.height = height; 29308 const context = canvas.getContext("2d"); 29309 context.drawImage(image, 0, 0, width, height); 29310 warn("WebGLRenderer: Texture has been resized from (" + dimensions.width + "x" + dimensions.height + ") to (" + width + "x" + height + ")."); 29311 return canvas; 29312 } else { 29313 if ("data" in image) { 29314 warn("WebGLRenderer: Image in DataTexture is too big (" + dimensions.width + "x" + dimensions.height + ")."); 29315 } 29316 return image; 29317 } 29318 } 29319 return image; 29320 } 29321 function textureNeedsGenerateMipmaps(texture) { 29322 return texture.generateMipmaps; 29323 } 29324 function generateMipmap(target) { 29325 _gl.generateMipmap(target); 29326 } 29327 function getTargetType(texture) { 29328 if (texture.isWebGLCubeRenderTarget) return _gl.TEXTURE_CUBE_MAP; 29329 if (texture.isWebGL3DRenderTarget) return _gl.TEXTURE_3D; 29330 if (texture.isWebGLArrayRenderTarget || texture.isCompressedArrayTexture) return _gl.TEXTURE_2D_ARRAY; 29331 return _gl.TEXTURE_2D; 29332 } 29333 function getInternalFormat(internalFormatName, glFormat, glType, normalized, colorSpace, forceLinearTransfer = false) { 29334 if (internalFormatName !== null) { 29335 if (_gl[internalFormatName] !== void 0) return _gl[internalFormatName]; 29336 warn("WebGLRenderer: Attempt to use non-existing WebGL internal format '" + internalFormatName + "'"); 29337 } 29338 let ext_texture_norm16; 29339 if (normalized) { 29340 ext_texture_norm16 = extensions.get("EXT_texture_norm16"); 29341 if (!ext_texture_norm16) { 29342 warn("WebGLRenderer: Unable to use normalized textures without EXT_texture_norm16 extension"); 29343 } 29344 } 29345 let internalFormat = glFormat; 29346 if (glFormat === _gl.RED) { 29347 if (glType === _gl.FLOAT) internalFormat = _gl.R32F; 29348 if (glType === _gl.HALF_FLOAT) internalFormat = _gl.R16F; 29349 if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.R8; 29350 if (glType === _gl.UNSIGNED_SHORT && ext_texture_norm16) internalFormat = ext_texture_norm16.R16_EXT; 29351 if (glType === _gl.SHORT && ext_texture_norm16) internalFormat = ext_texture_norm16.R16_SNORM_EXT; 29352 } 29353 if (glFormat === _gl.RED_INTEGER) { 29354 if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.R8UI; 29355 if (glType === _gl.UNSIGNED_SHORT) internalFormat = _gl.R16UI; 29356 if (glType === _gl.UNSIGNED_INT) internalFormat = _gl.R32UI; 29357 if (glType === _gl.BYTE) internalFormat = _gl.R8I; 29358 if (glType === _gl.SHORT) internalFormat = _gl.R16I; 29359 if (glType === _gl.INT) internalFormat = _gl.R32I; 29360 } 29361 if (glFormat === _gl.RG) { 29362 if (glType === _gl.FLOAT) internalFormat = _gl.RG32F; 29363 if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RG16F; 29364 if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RG8; 29365 if (glType === _gl.UNSIGNED_SHORT && ext_texture_norm16) internalFormat = ext_texture_norm16.RG16_EXT; 29366 if (glType === _gl.SHORT && ext_texture_norm16) internalFormat = ext_texture_norm16.RG16_SNORM_EXT; 29367 } 29368 if (glFormat === _gl.RG_INTEGER) { 29369 if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RG8UI; 29370 if (glType === _gl.UNSIGNED_SHORT) internalFormat = _gl.RG16UI; 29371 if (glType === _gl.UNSIGNED_INT) internalFormat = _gl.RG32UI; 29372 if (glType === _gl.BYTE) internalFormat = _gl.RG8I; 29373 if (glType === _gl.SHORT) internalFormat = _gl.RG16I; 29374 if (glType === _gl.INT) internalFormat = _gl.RG32I; 29375 } 29376 if (glFormat === _gl.RGB_INTEGER) { 29377 if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RGB8UI; 29378 if (glType === _gl.UNSIGNED_SHORT) internalFormat = _gl.RGB16UI; 29379 if (glType === _gl.UNSIGNED_INT) internalFormat = _gl.RGB32UI; 29380 if (glType === _gl.BYTE) internalFormat = _gl.RGB8I; 29381 if (glType === _gl.SHORT) internalFormat = _gl.RGB16I; 29382 if (glType === _gl.INT) internalFormat = _gl.RGB32I; 29383 } 29384 if (glFormat === _gl.RGBA_INTEGER) { 29385 if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RGBA8UI; 29386 if (glType === _gl.UNSIGNED_SHORT) internalFormat = _gl.RGBA16UI; 29387 if (glType === _gl.UNSIGNED_INT) internalFormat = _gl.RGBA32UI; 29388 if (glType === _gl.BYTE) internalFormat = _gl.RGBA8I; 29389 if (glType === _gl.SHORT) internalFormat = _gl.RGBA16I; 29390 if (glType === _gl.INT) internalFormat = _gl.RGBA32I; 29391 } 29392 if (glFormat === _gl.RGB) { 29393 if (glType === _gl.UNSIGNED_SHORT && ext_texture_norm16) internalFormat = ext_texture_norm16.RGB16_EXT; 29394 if (glType === _gl.SHORT && ext_texture_norm16) internalFormat = ext_texture_norm16.RGB16_SNORM_EXT; 29395 if (glType === _gl.UNSIGNED_INT_5_9_9_9_REV) internalFormat = _gl.RGB9_E5; 29396 if (glType === _gl.UNSIGNED_INT_10F_11F_11F_REV) internalFormat = _gl.R11F_G11F_B10F; 29397 } 29398 if (glFormat === _gl.RGBA) { 29399 const transfer = forceLinearTransfer ? LinearTransfer : ColorManagement.getTransfer(colorSpace); 29400 if (glType === _gl.FLOAT) internalFormat = _gl.RGBA32F; 29401 if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RGBA16F; 29402 if (glType === _gl.UNSIGNED_BYTE) internalFormat = transfer === SRGBTransfer ? _gl.SRGB8_ALPHA8 : _gl.RGBA8; 29403 if (glType === _gl.UNSIGNED_SHORT && ext_texture_norm16) internalFormat = ext_texture_norm16.RGBA16_EXT; 29404 if (glType === _gl.SHORT && ext_texture_norm16) internalFormat = ext_texture_norm16.RGBA16_SNORM_EXT; 29405 if (glType === _gl.UNSIGNED_SHORT_4_4_4_4) internalFormat = _gl.RGBA4; 29406 if (glType === _gl.UNSIGNED_SHORT_5_5_5_1) internalFormat = _gl.RGB5_A1; 29407 } 29408 if (internalFormat === _gl.R16F || internalFormat === _gl.R32F || internalFormat === _gl.RG16F || internalFormat === _gl.RG32F || internalFormat === _gl.RGBA16F || internalFormat === _gl.RGBA32F) { 29409 extensions.get("EXT_color_buffer_float"); 29410 } 29411 return internalFormat; 29412 } 29413 function getInternalDepthFormat(useStencil, depthType) { 29414 let glInternalFormat; 29415 if (useStencil) { 29416 if (depthType === null || depthType === UnsignedIntType || depthType === UnsignedInt248Type) { 29417 glInternalFormat = _gl.DEPTH24_STENCIL8; 29418 } else if (depthType === FloatType) { 29419 glInternalFormat = _gl.DEPTH32F_STENCIL8; 29420 } else if (depthType === UnsignedShortType) { 29421 glInternalFormat = _gl.DEPTH24_STENCIL8; 29422 warn("DepthTexture: 16 bit depth attachment is not supported with stencil. Using 24-bit attachment."); 29423 } 29424 } else { 29425 if (depthType === null || depthType === UnsignedIntType || depthType === UnsignedInt248Type) { 29426 glInternalFormat = _gl.DEPTH_COMPONENT24; 29427 } else if (depthType === FloatType) { 29428 glInternalFormat = _gl.DEPTH_COMPONENT32F; 29429 } else if (depthType === UnsignedShortType) { 29430 glInternalFormat = _gl.DEPTH_COMPONENT16; 29431 } 29432 } 29433 return glInternalFormat; 29434 } 29435 function getMipLevels(texture, image) { 29436 if (textureNeedsGenerateMipmaps(texture) === true || texture.isFramebufferTexture && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter) { 29437 return Math.log2(Math.max(image.width, image.height)) + 1; 29438 } else if (texture.mipmaps !== void 0 && texture.mipmaps.length > 0) { 29439 return texture.mipmaps.length; 29440 } else if (texture.isCompressedTexture && Array.isArray(texture.image)) { 29441 return image.mipmaps.length; 29442 } else { 29443 return 1; 29444 } 29445 } 29446 function onTextureDispose(event) { 29447 const texture = event.target; 29448 texture.removeEventListener("dispose", onTextureDispose); 29449 deallocateTexture(texture); 29450 if (texture.isVideoTexture) { 29451 _videoTextures.delete(texture); 29452 } 29453 if (texture.isHTMLTexture) { 29454 _htmlTextures.delete(texture); 29455 } 29456 } 29457 function onRenderTargetDispose(event) { 29458 const renderTarget = event.target; 29459 renderTarget.removeEventListener("dispose", onRenderTargetDispose); 29460 deallocateRenderTarget(renderTarget); 29461 } 29462 function deallocateTexture(texture) { 29463 const textureProperties = properties.get(texture); 29464 if (textureProperties.__webglInit === void 0) return; 29465 const source = texture.source; 29466 const webglTextures = _sources.get(source); 29467 if (webglTextures) { 29468 const webglTexture = webglTextures[textureProperties.__cacheKey]; 29469 webglTexture.usedTimes--; 29470 if (webglTexture.usedTimes === 0) { 29471 deleteTexture(texture); 29472 } 29473 if (Object.keys(webglTextures).length === 0) { 29474 _sources.delete(source); 29475 } 29476 } 29477 properties.remove(texture); 29478 } 29479 function deleteTexture(texture) { 29480 const textureProperties = properties.get(texture); 29481 _gl.deleteTexture(textureProperties.__webglTexture); 29482 const source = texture.source; 29483 const webglTextures = _sources.get(source); 29484 delete webglTextures[textureProperties.__cacheKey]; 29485 info.memory.textures--; 29486 } 29487 function deallocateRenderTarget(renderTarget) { 29488 const renderTargetProperties = properties.get(renderTarget); 29489 if (renderTarget.depthTexture) { 29490 renderTarget.depthTexture.dispose(); 29491 properties.remove(renderTarget.depthTexture); 29492 } 29493 if (renderTarget.isWebGLCubeRenderTarget) { 29494 for (let i = 0; i < 6; i++) { 29495 if (Array.isArray(renderTargetProperties.__webglFramebuffer[i])) { 29496 for (let level = 0; level < renderTargetProperties.__webglFramebuffer[i].length; level++) _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[i][level]); 29497 } else { 29498 _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[i]); 29499 } 29500 if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer[i]); 29501 } 29502 } else { 29503 if (Array.isArray(renderTargetProperties.__webglFramebuffer)) { 29504 for (let level = 0; level < renderTargetProperties.__webglFramebuffer.length; level++) _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[level]); 29505 } else { 29506 _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer); 29507 } 29508 if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer); 29509 if (renderTargetProperties.__webglMultisampledFramebuffer) _gl.deleteFramebuffer(renderTargetProperties.__webglMultisampledFramebuffer); 29510 if (renderTargetProperties.__webglColorRenderbuffer) { 29511 for (let i = 0; i < renderTargetProperties.__webglColorRenderbuffer.length; i++) { 29512 if (renderTargetProperties.__webglColorRenderbuffer[i]) _gl.deleteRenderbuffer(renderTargetProperties.__webglColorRenderbuffer[i]); 29513 } 29514 } 29515 if (renderTargetProperties.__webglDepthRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthRenderbuffer); 29516 } 29517 const textures = renderTarget.textures; 29518 for (let i = 0, il = textures.length; i < il; i++) { 29519 const attachmentProperties = properties.get(textures[i]); 29520 if (attachmentProperties.__webglTexture) { 29521 _gl.deleteTexture(attachmentProperties.__webglTexture); 29522 info.memory.textures--; 29523 } 29524 properties.remove(textures[i]); 29525 } 29526 properties.remove(renderTarget); 29527 } 29528 let textureUnits = 0; 29529 function resetTextureUnits() { 29530 textureUnits = 0; 29531 } 29532 function getTextureUnits() { 29533 return textureUnits; 29534 } 29535 function setTextureUnits(value) { 29536 textureUnits = value; 29537 } 29538 function allocateTextureUnit() { 29539 const textureUnit = textureUnits; 29540 if (textureUnit >= capabilities.maxTextures) { 29541 warn("WebGLTextures: Trying to use " + textureUnit + " texture units while this GPU supports only " + capabilities.maxTextures); 29542 } 29543 textureUnits += 1; 29544 return textureUnit; 29545 } 29546 function getTextureCacheKey(texture) { 29547 const array = []; 29548 array.push(texture.wrapS); 29549 array.push(texture.wrapT); 29550 array.push(texture.wrapR || 0); 29551 array.push(texture.magFilter); 29552 array.push(texture.minFilter); 29553 array.push(texture.anisotropy); 29554 array.push(texture.internalFormat); 29555 array.push(texture.format); 29556 array.push(texture.type); 29557 array.push(texture.generateMipmaps); 29558 array.push(texture.premultiplyAlpha); 29559 array.push(texture.flipY); 29560 array.push(texture.unpackAlignment); 29561 array.push(texture.colorSpace); 29562 return array.join(); 29563 } 29564 function setTexture2D(texture, slot) { 29565 const textureProperties = properties.get(texture); 29566 if (texture.isVideoTexture) updateVideoTexture(texture); 29567 if (texture.isRenderTargetTexture === false && texture.isExternalTexture !== true && texture.version > 0 && textureProperties.__version !== texture.version) { 29568 const image = texture.image; 29569 if (image === null) { 29570 warn("WebGLRenderer: Texture marked for update but no image data found."); 29571 } else if (image.complete === false) { 29572 warn("WebGLRenderer: Texture marked for update but image is incomplete"); 29573 } else { 29574 uploadTexture(textureProperties, texture, slot); 29575 return; 29576 } 29577 } else if (texture.isExternalTexture) { 29578 textureProperties.__webglTexture = texture.sourceTexture ? texture.sourceTexture : null; 29579 } 29580 state.bindTexture(_gl.TEXTURE_2D, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); 29581 } 29582 function setTexture2DArray(texture, slot) { 29583 const textureProperties = properties.get(texture); 29584 if (texture.isRenderTargetTexture === false && texture.version > 0 && textureProperties.__version !== texture.version) { 29585 uploadTexture(textureProperties, texture, slot); 29586 return; 29587 } else if (texture.isExternalTexture) { 29588 textureProperties.__webglTexture = texture.sourceTexture ? texture.sourceTexture : null; 29589 } 29590 state.bindTexture(_gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); 29591 } 29592 function setTexture3D(texture, slot) { 29593 const textureProperties = properties.get(texture); 29594 if (texture.isRenderTargetTexture === false && texture.version > 0 && textureProperties.__version !== texture.version) { 29595 uploadTexture(textureProperties, texture, slot); 29596 return; 29597 } 29598 state.bindTexture(_gl.TEXTURE_3D, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); 29599 } 29600 function setTextureCube(texture, slot) { 29601 const textureProperties = properties.get(texture); 29602 if (texture.isCubeDepthTexture !== true && texture.version > 0 && textureProperties.__version !== texture.version) { 29603 uploadCubeTexture(textureProperties, texture, slot); 29604 return; 29605 } 29606 state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); 29607 } 29608 const wrappingToGL = { 29609 [RepeatWrapping]: _gl.REPEAT, 29610 [ClampToEdgeWrapping]: _gl.CLAMP_TO_EDGE, 29611 [MirroredRepeatWrapping]: _gl.MIRRORED_REPEAT 29612 }; 29613 const filterToGL = { 29614 [NearestFilter]: _gl.NEAREST, 29615 [NearestMipmapNearestFilter]: _gl.NEAREST_MIPMAP_NEAREST, 29616 [NearestMipmapLinearFilter]: _gl.NEAREST_MIPMAP_LINEAR, 29617 [LinearFilter]: _gl.LINEAR, 29618 [LinearMipmapNearestFilter]: _gl.LINEAR_MIPMAP_NEAREST, 29619 [LinearMipmapLinearFilter]: _gl.LINEAR_MIPMAP_LINEAR 29620 }; 29621 const compareToGL = { 29622 [NeverCompare]: _gl.NEVER, 29623 [AlwaysCompare]: _gl.ALWAYS, 29624 [LessCompare]: _gl.LESS, 29625 [LessEqualCompare]: _gl.LEQUAL, 29626 [EqualCompare]: _gl.EQUAL, 29627 [GreaterEqualCompare]: _gl.GEQUAL, 29628 [GreaterCompare]: _gl.GREATER, 29629 [NotEqualCompare]: _gl.NOTEQUAL 29630 }; 29631 function setTextureParameters(textureType, texture) { 29632 if (texture.type === FloatType && extensions.has("OES_texture_float_linear") === false && (texture.magFilter === LinearFilter || texture.magFilter === LinearMipmapNearestFilter || texture.magFilter === NearestMipmapLinearFilter || texture.magFilter === LinearMipmapLinearFilter || texture.minFilter === LinearFilter || texture.minFilter === LinearMipmapNearestFilter || texture.minFilter === NearestMipmapLinearFilter || texture.minFilter === LinearMipmapLinearFilter)) { 29633 warn("WebGLRenderer: Unable to use linear filtering with floating point textures. OES_texture_float_linear not supported on this device."); 29634 } 29635 _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_S, wrappingToGL[texture.wrapS]); 29636 _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_T, wrappingToGL[texture.wrapT]); 29637 if (textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY) { 29638 _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_R, wrappingToGL[texture.wrapR]); 29639 } 29640 _gl.texParameteri(textureType, _gl.TEXTURE_MAG_FILTER, filterToGL[texture.magFilter]); 29641 _gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterToGL[texture.minFilter]); 29642 if (texture.compareFunction) { 29643 _gl.texParameteri(textureType, _gl.TEXTURE_COMPARE_MODE, _gl.COMPARE_REF_TO_TEXTURE); 29644 _gl.texParameteri(textureType, _gl.TEXTURE_COMPARE_FUNC, compareToGL[texture.compareFunction]); 29645 } 29646 if (extensions.has("EXT_texture_filter_anisotropic") === true) { 29647 if (texture.magFilter === NearestFilter) return; 29648 if (texture.minFilter !== NearestMipmapLinearFilter && texture.minFilter !== LinearMipmapLinearFilter) return; 29649 if (texture.type === FloatType && extensions.has("OES_texture_float_linear") === false) return; 29650 if (texture.anisotropy > 1 || properties.get(texture).__currentAnisotropy) { 29651 const extension = extensions.get("EXT_texture_filter_anisotropic"); 29652 _gl.texParameterf(textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(texture.anisotropy, capabilities.getMaxAnisotropy())); 29653 properties.get(texture).__currentAnisotropy = texture.anisotropy; 29654 } 29655 } 29656 } 29657 function initTexture(textureProperties, texture) { 29658 let forceUpload = false; 29659 if (textureProperties.__webglInit === void 0) { 29660 textureProperties.__webglInit = true; 29661 texture.addEventListener("dispose", onTextureDispose); 29662 } 29663 const source = texture.source; 29664 let webglTextures = _sources.get(source); 29665 if (webglTextures === void 0) { 29666 webglTextures = {}; 29667 _sources.set(source, webglTextures); 29668 } 29669 const textureCacheKey = getTextureCacheKey(texture); 29670 if (textureCacheKey !== textureProperties.__cacheKey) { 29671 if (webglTextures[textureCacheKey] === void 0) { 29672 webglTextures[textureCacheKey] = { 29673 texture: _gl.createTexture(), 29674 usedTimes: 0 29675 }; 29676 info.memory.textures++; 29677 forceUpload = true; 29678 } 29679 webglTextures[textureCacheKey].usedTimes++; 29680 const webglTexture = webglTextures[textureProperties.__cacheKey]; 29681 if (webglTexture !== void 0) { 29682 webglTextures[textureProperties.__cacheKey].usedTimes--; 29683 if (webglTexture.usedTimes === 0) { 29684 deleteTexture(texture); 29685 } 29686 } 29687 textureProperties.__cacheKey = textureCacheKey; 29688 textureProperties.__webglTexture = webglTextures[textureCacheKey].texture; 29689 } 29690 return forceUpload; 29691 } 29692 function getRow(index, rowLength, componentStride) { 29693 return Math.floor(Math.floor(index / componentStride) / rowLength); 29694 } 29695 function updateTexture(texture, image, glFormat, glType) { 29696 const componentStride = 4; 29697 const updateRanges = texture.updateRanges; 29698 if (updateRanges.length === 0) { 29699 state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data); 29700 } else { 29701 updateRanges.sort((a, b) => a.start - b.start); 29702 let mergeIndex = 0; 29703 for (let i = 1; i < updateRanges.length; i++) { 29704 const previousRange = updateRanges[mergeIndex]; 29705 const range = updateRanges[i]; 29706 const previousEnd = previousRange.start + previousRange.count; 29707 const currentRow = getRow(range.start, image.width, componentStride); 29708 const previousRow = getRow(previousRange.start, image.width, componentStride); 29709 if (range.start <= previousEnd + 1 && currentRow === previousRow && getRow(range.start + range.count - 1, image.width, componentStride) === currentRow) { 29710 previousRange.count = Math.max( 29711 previousRange.count, 29712 range.start + range.count - previousRange.start 29713 ); 29714 } else { 29715 ++mergeIndex; 29716 updateRanges[mergeIndex] = range; 29717 } 29718 } 29719 updateRanges.length = mergeIndex + 1; 29720 const currentUnpackRowLen = state.getParameter(_gl.UNPACK_ROW_LENGTH); 29721 const currentUnpackSkipPixels = state.getParameter(_gl.UNPACK_SKIP_PIXELS); 29722 const currentUnpackSkipRows = state.getParameter(_gl.UNPACK_SKIP_ROWS); 29723 state.pixelStorei(_gl.UNPACK_ROW_LENGTH, image.width); 29724 for (let i = 0, l = updateRanges.length; i < l; i++) { 29725 const range = updateRanges[i]; 29726 const pixelStart = Math.floor(range.start / componentStride); 29727 const pixelCount = Math.ceil(range.count / componentStride); 29728 const x = pixelStart % image.width; 29729 const y = Math.floor(pixelStart / image.width); 29730 const width = pixelCount; 29731 const height = 1; 29732 state.pixelStorei(_gl.UNPACK_SKIP_PIXELS, x); 29733 state.pixelStorei(_gl.UNPACK_SKIP_ROWS, y); 29734 state.texSubImage2D(_gl.TEXTURE_2D, 0, x, y, width, height, glFormat, glType, image.data); 29735 } 29736 texture.clearUpdateRanges(); 29737 state.pixelStorei(_gl.UNPACK_ROW_LENGTH, currentUnpackRowLen); 29738 state.pixelStorei(_gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels); 29739 state.pixelStorei(_gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows); 29740 } 29741 } 29742 function uploadTexture(textureProperties, texture, slot) { 29743 let textureType = _gl.TEXTURE_2D; 29744 if (texture.isDataArrayTexture || texture.isCompressedArrayTexture) textureType = _gl.TEXTURE_2D_ARRAY; 29745 if (texture.isData3DTexture) textureType = _gl.TEXTURE_3D; 29746 const forceUpload = initTexture(textureProperties, texture); 29747 const source = texture.source; 29748 state.bindTexture(textureType, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); 29749 const sourceProperties = properties.get(source); 29750 if (source.version !== sourceProperties.__version || forceUpload === true) { 29751 state.activeTexture(_gl.TEXTURE0 + slot); 29752 const isImageBitmap = typeof ImageBitmap !== "undefined" && texture.image instanceof ImageBitmap; 29753 if (isImageBitmap === false) { 29754 const workingPrimaries = ColorManagement.getPrimaries(ColorManagement.workingColorSpace); 29755 const texturePrimaries = texture.colorSpace === NoColorSpace ? null : ColorManagement.getPrimaries(texture.colorSpace); 29756 const unpackConversion = texture.colorSpace === NoColorSpace || workingPrimaries === texturePrimaries ? _gl.NONE : _gl.BROWSER_DEFAULT_WEBGL; 29757 state.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); 29758 state.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha); 29759 state.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion); 29760 } 29761 state.pixelStorei(_gl.UNPACK_ALIGNMENT, texture.unpackAlignment); 29762 let image = resizeImage(texture.image, false, capabilities.maxTextureSize); 29763 image = verifyColorSpace(texture, image); 29764 const glFormat = utils.convert(texture.format, texture.colorSpace); 29765 const glType = utils.convert(texture.type); 29766 let glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.normalized, texture.colorSpace, texture.isVideoTexture); 29767 setTextureParameters(textureType, texture); 29768 let mipmap; 29769 const mipmaps = texture.mipmaps; 29770 const useTexStorage = texture.isVideoTexture !== true; 29771 const allocateMemory = sourceProperties.__version === void 0 || forceUpload === true; 29772 const dataReady = source.dataReady; 29773 const levels = getMipLevels(texture, image); 29774 if (texture.isDepthTexture) { 29775 glInternalFormat = getInternalDepthFormat(texture.format === DepthStencilFormat, texture.type); 29776 if (allocateMemory) { 29777 if (useTexStorage) { 29778 state.texStorage2D(_gl.TEXTURE_2D, 1, glInternalFormat, image.width, image.height); 29779 } else { 29780 state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null); 29781 } 29782 } 29783 } else if (texture.isDataTexture) { 29784 if (mipmaps.length > 0) { 29785 if (useTexStorage && allocateMemory) { 29786 state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); 29787 } 29788 for (let i = 0, il = mipmaps.length; i < il; i++) { 29789 mipmap = mipmaps[i]; 29790 if (useTexStorage) { 29791 if (dataReady) { 29792 state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); 29793 } 29794 } else { 29795 state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); 29796 } 29797 } 29798 texture.generateMipmaps = false; 29799 } else { 29800 if (useTexStorage) { 29801 if (allocateMemory) { 29802 state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); 29803 } 29804 if (dataReady) { 29805 updateTexture(texture, image, glFormat, glType); 29806 } 29807 } else { 29808 state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data); 29809 } 29810 } 29811 } else if (texture.isCompressedTexture) { 29812 if (texture.isCompressedArrayTexture) { 29813 if (useTexStorage && allocateMemory) { 29814 state.texStorage3D(_gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height, image.depth); 29815 } 29816 for (let i = 0, il = mipmaps.length; i < il; i++) { 29817 mipmap = mipmaps[i]; 29818 if (texture.format !== RGBAFormat) { 29819 if (glFormat !== null) { 29820 if (useTexStorage) { 29821 if (dataReady) { 29822 if (texture.layerUpdates.size > 0) { 29823 const layerByteLength = getByteLength(mipmap.width, mipmap.height, texture.format, texture.type); 29824 for (const layerIndex of texture.layerUpdates) { 29825 const layerData = mipmap.data.subarray( 29826 layerIndex * layerByteLength / mipmap.data.BYTES_PER_ELEMENT, 29827 (layerIndex + 1) * layerByteLength / mipmap.data.BYTES_PER_ELEMENT 29828 ); 29829 state.compressedTexSubImage3D(_gl.TEXTURE_2D_ARRAY, i, 0, 0, layerIndex, mipmap.width, mipmap.height, 1, glFormat, layerData); 29830 } 29831 texture.clearLayerUpdates(); 29832 } else { 29833 state.compressedTexSubImage3D(_gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data); 29834 } 29835 } 29836 } else { 29837 state.compressedTexImage3D(_gl.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, mipmap.data, 0, 0); 29838 } 29839 } else { 29840 warn("WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"); 29841 } 29842 } else { 29843 if (useTexStorage) { 29844 if (dataReady) { 29845 state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, glType, mipmap.data); 29846 } 29847 } else { 29848 state.texImage3D(_gl.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, glFormat, glType, mipmap.data); 29849 } 29850 } 29851 } 29852 } else { 29853 if (useTexStorage && allocateMemory) { 29854 state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); 29855 } 29856 for (let i = 0, il = mipmaps.length; i < il; i++) { 29857 mipmap = mipmaps[i]; 29858 if (texture.format !== RGBAFormat) { 29859 if (glFormat !== null) { 29860 if (useTexStorage) { 29861 if (dataReady) { 29862 state.compressedTexSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data); 29863 } 29864 } else { 29865 state.compressedTexImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data); 29866 } 29867 } else { 29868 warn("WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"); 29869 } 29870 } else { 29871 if (useTexStorage) { 29872 if (dataReady) { 29873 state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); 29874 } 29875 } else { 29876 state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); 29877 } 29878 } 29879 } 29880 } 29881 } else if (texture.isDataArrayTexture) { 29882 if (useTexStorage) { 29883 if (allocateMemory) { 29884 state.texStorage3D(_gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, image.width, image.height, image.depth); 29885 } 29886 if (dataReady) { 29887 if (texture.layerUpdates.size > 0) { 29888 const layerByteLength = getByteLength(image.width, image.height, texture.format, texture.type); 29889 for (const layerIndex of texture.layerUpdates) { 29890 const layerData = image.data.subarray( 29891 layerIndex * layerByteLength / image.data.BYTES_PER_ELEMENT, 29892 (layerIndex + 1) * layerByteLength / image.data.BYTES_PER_ELEMENT 29893 ); 29894 state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, 0, 0, 0, layerIndex, image.width, image.height, 1, glFormat, glType, layerData); 29895 } 29896 texture.clearLayerUpdates(); 29897 } else { 29898 state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data); 29899 } 29900 } 29901 } else { 29902 state.texImage3D(_gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data); 29903 } 29904 } else if (texture.isData3DTexture) { 29905 if (useTexStorage) { 29906 if (allocateMemory) { 29907 state.texStorage3D(_gl.TEXTURE_3D, levels, glInternalFormat, image.width, image.height, image.depth); 29908 } 29909 if (dataReady) { 29910 state.texSubImage3D(_gl.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data); 29911 } 29912 } else { 29913 state.texImage3D(_gl.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data); 29914 } 29915 } else if (texture.isFramebufferTexture) { 29916 if (allocateMemory) { 29917 if (useTexStorage) { 29918 state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); 29919 } else { 29920 let width = image.width, height = image.height; 29921 for (let i = 0; i < levels; i++) { 29922 state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, width, height, 0, glFormat, glType, null); 29923 width >>= 1; 29924 height >>= 1; 29925 } 29926 } 29927 } 29928 } else if (texture.isHTMLTexture) { 29929 if ("texElementImage2D" in _gl) { 29930 const canvas = _gl.canvas; 29931 if (!canvas.hasAttribute("layoutsubtree")) { 29932 canvas.setAttribute("layoutsubtree", "true"); 29933 } 29934 if (image.parentNode !== canvas) { 29935 canvas.appendChild(image); 29936 _htmlTextures.add(texture); 29937 canvas.onpaint = (event) => { 29938 const changed = event.changedElements; 29939 for (const t of _htmlTextures) { 29940 if (changed.includes(t.image)) { 29941 t.needsUpdate = true; 29942 } 29943 } 29944 }; 29945 canvas.requestPaint(); 29946 return; 29947 } 29948 const level = 0; 29949 const internalFormat = _gl.RGBA; 29950 const srcFormat = _gl.RGBA; 29951 const srcType = _gl.UNSIGNED_BYTE; 29952 _gl.texElementImage2D(_gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, image); 29953 _gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR); 29954 _gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE); 29955 _gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE); 29956 } 29957 } else { 29958 if (mipmaps.length > 0) { 29959 if (useTexStorage && allocateMemory) { 29960 const dimensions = getDimensions(mipmaps[0]); 29961 state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, dimensions.width, dimensions.height); 29962 } 29963 for (let i = 0, il = mipmaps.length; i < il; i++) { 29964 mipmap = mipmaps[i]; 29965 if (useTexStorage) { 29966 if (dataReady) { 29967 state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap); 29968 } 29969 } else { 29970 state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap); 29971 } 29972 } 29973 texture.generateMipmaps = false; 29974 } else { 29975 if (useTexStorage) { 29976 if (allocateMemory) { 29977 const dimensions = getDimensions(image); 29978 state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, dimensions.width, dimensions.height); 29979 } 29980 if (dataReady) { 29981 state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, glFormat, glType, image); 29982 } 29983 } else { 29984 state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image); 29985 } 29986 } 29987 } 29988 if (textureNeedsGenerateMipmaps(texture)) { 29989 generateMipmap(textureType); 29990 } 29991 sourceProperties.__version = source.version; 29992 if (texture.onUpdate) texture.onUpdate(texture); 29993 } 29994 textureProperties.__version = texture.version; 29995 } 29996 function uploadCubeTexture(textureProperties, texture, slot) { 29997 if (texture.image.length !== 6) return; 29998 const forceUpload = initTexture(textureProperties, texture); 29999 const source = texture.source; 30000 state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); 30001 const sourceProperties = properties.get(source); 30002 if (source.version !== sourceProperties.__version || forceUpload === true) { 30003 state.activeTexture(_gl.TEXTURE0 + slot); 30004 const workingPrimaries = ColorManagement.getPrimaries(ColorManagement.workingColorSpace); 30005 const texturePrimaries = texture.colorSpace === NoColorSpace ? null : ColorManagement.getPrimaries(texture.colorSpace); 30006 const unpackConversion = texture.colorSpace === NoColorSpace || workingPrimaries === texturePrimaries ? _gl.NONE : _gl.BROWSER_DEFAULT_WEBGL; 30007 state.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); 30008 state.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha); 30009 state.pixelStorei(_gl.UNPACK_ALIGNMENT, texture.unpackAlignment); 30010 state.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion); 30011 const isCompressed = texture.isCompressedTexture || texture.image[0].isCompressedTexture; 30012 const isDataTexture = texture.image[0] && texture.image[0].isDataTexture; 30013 const cubeImage = []; 30014 for (let i = 0; i < 6; i++) { 30015 if (!isCompressed && !isDataTexture) { 30016 cubeImage[i] = resizeImage(texture.image[i], true, capabilities.maxCubemapSize); 30017 } else { 30018 cubeImage[i] = isDataTexture ? texture.image[i].image : texture.image[i]; 30019 } 30020 cubeImage[i] = verifyColorSpace(texture, cubeImage[i]); 30021 } 30022 const image = cubeImage[0], glFormat = utils.convert(texture.format, texture.colorSpace), glType = utils.convert(texture.type), glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.normalized, texture.colorSpace); 30023 const useTexStorage = texture.isVideoTexture !== true; 30024 const allocateMemory = sourceProperties.__version === void 0 || forceUpload === true; 30025 const dataReady = source.dataReady; 30026 let levels = getMipLevels(texture, image); 30027 setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture); 30028 let mipmaps; 30029 if (isCompressed) { 30030 if (useTexStorage && allocateMemory) { 30031 state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, image.width, image.height); 30032 } 30033 for (let i = 0; i < 6; i++) { 30034 mipmaps = cubeImage[i].mipmaps; 30035 for (let j = 0; j < mipmaps.length; j++) { 30036 const mipmap = mipmaps[j]; 30037 if (texture.format !== RGBAFormat) { 30038 if (glFormat !== null) { 30039 if (useTexStorage) { 30040 if (dataReady) { 30041 state.compressedTexSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data); 30042 } 30043 } else { 30044 state.compressedTexImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data); 30045 } 30046 } else { 30047 warn("WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()"); 30048 } 30049 } else { 30050 if (useTexStorage) { 30051 if (dataReady) { 30052 state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); 30053 } 30054 } else { 30055 state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); 30056 } 30057 } 30058 } 30059 } 30060 } else { 30061 mipmaps = texture.mipmaps; 30062 if (useTexStorage && allocateMemory) { 30063 if (mipmaps.length > 0) levels++; 30064 const dimensions = getDimensions(cubeImage[0]); 30065 state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, dimensions.width, dimensions.height); 30066 } 30067 for (let i = 0; i < 6; i++) { 30068 if (isDataTexture) { 30069 if (useTexStorage) { 30070 if (dataReady) { 30071 state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, cubeImage[i].width, cubeImage[i].height, glFormat, glType, cubeImage[i].data); 30072 } 30073 } else { 30074 state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[i].width, cubeImage[i].height, 0, glFormat, glType, cubeImage[i].data); 30075 } 30076 for (let j = 0; j < mipmaps.length; j++) { 30077 const mipmap = mipmaps[j]; 30078 const mipmapImage = mipmap.image[i].image; 30079 if (useTexStorage) { 30080 if (dataReady) { 30081 state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width, mipmapImage.height, glFormat, glType, mipmapImage.data); 30082 } 30083 } else { 30084 state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data); 30085 } 30086 } 30087 } else { 30088 if (useTexStorage) { 30089 if (dataReady) { 30090 state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[i]); 30091 } 30092 } else { 30093 state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i]); 30094 } 30095 for (let j = 0; j < mipmaps.length; j++) { 30096 const mipmap = mipmaps[j]; 30097 if (useTexStorage) { 30098 if (dataReady) { 30099 state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[i]); 30100 } 30101 } else { 30102 state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[i]); 30103 } 30104 } 30105 } 30106 } 30107 } 30108 if (textureNeedsGenerateMipmaps(texture)) { 30109 generateMipmap(_gl.TEXTURE_CUBE_MAP); 30110 } 30111 sourceProperties.__version = source.version; 30112 if (texture.onUpdate) texture.onUpdate(texture); 30113 } 30114 textureProperties.__version = texture.version; 30115 } 30116 function setupFrameBufferTexture(framebuffer, renderTarget, texture, attachment, textureTarget, level) { 30117 const glFormat = utils.convert(texture.format, texture.colorSpace); 30118 const glType = utils.convert(texture.type); 30119 const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.normalized, texture.colorSpace); 30120 const renderTargetProperties = properties.get(renderTarget); 30121 const textureProperties = properties.get(texture); 30122 textureProperties.__renderTarget = renderTarget; 30123 if (!renderTargetProperties.__hasExternalTextures) { 30124 const width = Math.max(1, renderTarget.width >> level); 30125 const height = Math.max(1, renderTarget.height >> level); 30126 if (textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY) { 30127 state.texImage3D(textureTarget, level, glInternalFormat, width, height, renderTarget.depth, 0, glFormat, glType, null); 30128 } else { 30129 state.texImage2D(textureTarget, level, glInternalFormat, width, height, 0, glFormat, glType, null); 30130 } 30131 } 30132 state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); 30133 if (useMultisampledRTT(renderTarget)) { 30134 multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, attachment, textureTarget, textureProperties.__webglTexture, 0, getRenderTargetSamples(renderTarget)); 30135 } else if (textureTarget === _gl.TEXTURE_2D || textureTarget >= _gl.TEXTURE_CUBE_MAP_POSITIVE_X && textureTarget <= _gl.TEXTURE_CUBE_MAP_NEGATIVE_Z) { 30136 _gl.framebufferTexture2D(_gl.FRAMEBUFFER, attachment, textureTarget, textureProperties.__webglTexture, level); 30137 } 30138 state.bindFramebuffer(_gl.FRAMEBUFFER, null); 30139 } 30140 function setupRenderBufferStorage(renderbuffer, renderTarget, useMultisample) { 30141 _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer); 30142 if (renderTarget.depthBuffer) { 30143 const depthTexture = renderTarget.depthTexture; 30144 const depthType = depthTexture && depthTexture.isDepthTexture ? depthTexture.type : null; 30145 const glInternalFormat = getInternalDepthFormat(renderTarget.stencilBuffer, depthType); 30146 const glAttachmentType = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; 30147 if (useMultisampledRTT(renderTarget)) { 30148 multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, getRenderTargetSamples(renderTarget), glInternalFormat, renderTarget.width, renderTarget.height); 30149 } else if (useMultisample) { 30150 _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, getRenderTargetSamples(renderTarget), glInternalFormat, renderTarget.width, renderTarget.height); 30151 } else { 30152 _gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height); 30153 } 30154 _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, glAttachmentType, _gl.RENDERBUFFER, renderbuffer); 30155 } else { 30156 const textures = renderTarget.textures; 30157 for (let i = 0; i < textures.length; i++) { 30158 const texture = textures[i]; 30159 const glFormat = utils.convert(texture.format, texture.colorSpace); 30160 const glType = utils.convert(texture.type); 30161 const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.normalized, texture.colorSpace); 30162 if (useMultisampledRTT(renderTarget)) { 30163 multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, getRenderTargetSamples(renderTarget), glInternalFormat, renderTarget.width, renderTarget.height); 30164 } else if (useMultisample) { 30165 _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, getRenderTargetSamples(renderTarget), glInternalFormat, renderTarget.width, renderTarget.height); 30166 } else { 30167 _gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height); 30168 } 30169 } 30170 } 30171 _gl.bindRenderbuffer(_gl.RENDERBUFFER, null); 30172 } 30173 function setupDepthTexture(framebuffer, renderTarget, cubeFace) { 30174 const isCube = renderTarget.isWebGLCubeRenderTarget === true; 30175 state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); 30176 if (!(renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture)) { 30177 throw new Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture"); 30178 } 30179 const textureProperties = properties.get(renderTarget.depthTexture); 30180 textureProperties.__renderTarget = renderTarget; 30181 if (!textureProperties.__webglTexture || renderTarget.depthTexture.image.width !== renderTarget.width || renderTarget.depthTexture.image.height !== renderTarget.height) { 30182 renderTarget.depthTexture.image.width = renderTarget.width; 30183 renderTarget.depthTexture.image.height = renderTarget.height; 30184 renderTarget.depthTexture.needsUpdate = true; 30185 } 30186 if (isCube) { 30187 if (textureProperties.__webglInit === void 0) { 30188 textureProperties.__webglInit = true; 30189 renderTarget.depthTexture.addEventListener("dispose", onTextureDispose); 30190 } 30191 if (textureProperties.__webglTexture === void 0) { 30192 textureProperties.__webglTexture = _gl.createTexture(); 30193 state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture); 30194 setTextureParameters(_gl.TEXTURE_CUBE_MAP, renderTarget.depthTexture); 30195 const glFormat = utils.convert(renderTarget.depthTexture.format); 30196 const glType = utils.convert(renderTarget.depthTexture.type); 30197 let glInternalFormat; 30198 if (renderTarget.depthTexture.format === DepthFormat) { 30199 glInternalFormat = _gl.DEPTH_COMPONENT24; 30200 } else if (renderTarget.depthTexture.format === DepthStencilFormat) { 30201 glInternalFormat = _gl.DEPTH24_STENCIL8; 30202 } 30203 for (let i = 0; i < 6; i++) { 30204 _gl.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null); 30205 } 30206 } 30207 } else { 30208 setTexture2D(renderTarget.depthTexture, 0); 30209 } 30210 const webglDepthTexture = textureProperties.__webglTexture; 30211 const samples = getRenderTargetSamples(renderTarget); 30212 const glTextureType = isCube ? _gl.TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace : _gl.TEXTURE_2D; 30213 const glAttachmentType = renderTarget.depthTexture.format === DepthStencilFormat ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; 30214 if (renderTarget.depthTexture.format === DepthFormat) { 30215 if (useMultisampledRTT(renderTarget)) { 30216 multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, glAttachmentType, glTextureType, webglDepthTexture, 0, samples); 30217 } else { 30218 _gl.framebufferTexture2D(_gl.FRAMEBUFFER, glAttachmentType, glTextureType, webglDepthTexture, 0); 30219 } 30220 } else if (renderTarget.depthTexture.format === DepthStencilFormat) { 30221 if (useMultisampledRTT(renderTarget)) { 30222 multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, glAttachmentType, glTextureType, webglDepthTexture, 0, samples); 30223 } else { 30224 _gl.framebufferTexture2D(_gl.FRAMEBUFFER, glAttachmentType, glTextureType, webglDepthTexture, 0); 30225 } 30226 } else { 30227 throw new Error("Unknown depthTexture format"); 30228 } 30229 } 30230 function setupDepthRenderbuffer(renderTarget) { 30231 const renderTargetProperties = properties.get(renderTarget); 30232 const isCube = renderTarget.isWebGLCubeRenderTarget === true; 30233 if (renderTargetProperties.__boundDepthTexture !== renderTarget.depthTexture) { 30234 const depthTexture = renderTarget.depthTexture; 30235 if (renderTargetProperties.__depthDisposeCallback) { 30236 renderTargetProperties.__depthDisposeCallback(); 30237 } 30238 if (depthTexture) { 30239 const disposeEvent = () => { 30240 delete renderTargetProperties.__boundDepthTexture; 30241 delete renderTargetProperties.__depthDisposeCallback; 30242 depthTexture.removeEventListener("dispose", disposeEvent); 30243 }; 30244 depthTexture.addEventListener("dispose", disposeEvent); 30245 renderTargetProperties.__depthDisposeCallback = disposeEvent; 30246 } 30247 renderTargetProperties.__boundDepthTexture = depthTexture; 30248 } 30249 if (renderTarget.depthTexture && !renderTargetProperties.__autoAllocateDepthBuffer) { 30250 if (isCube) { 30251 for (let i = 0; i < 6; i++) { 30252 setupDepthTexture(renderTargetProperties.__webglFramebuffer[i], renderTarget, i); 30253 } 30254 } else { 30255 const mipmaps = renderTarget.texture.mipmaps; 30256 if (mipmaps && mipmaps.length > 0) { 30257 setupDepthTexture(renderTargetProperties.__webglFramebuffer[0], renderTarget, 0); 30258 } else { 30259 setupDepthTexture(renderTargetProperties.__webglFramebuffer, renderTarget, 0); 30260 } 30261 } 30262 } else { 30263 if (isCube) { 30264 renderTargetProperties.__webglDepthbuffer = []; 30265 for (let i = 0; i < 6; i++) { 30266 state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[i]); 30267 if (renderTargetProperties.__webglDepthbuffer[i] === void 0) { 30268 renderTargetProperties.__webglDepthbuffer[i] = _gl.createRenderbuffer(); 30269 setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer[i], renderTarget, false); 30270 } else { 30271 const glAttachmentType = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; 30272 const renderbuffer = renderTargetProperties.__webglDepthbuffer[i]; 30273 _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer); 30274 _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, glAttachmentType, _gl.RENDERBUFFER, renderbuffer); 30275 } 30276 } 30277 } else { 30278 const mipmaps = renderTarget.texture.mipmaps; 30279 if (mipmaps && mipmaps.length > 0) { 30280 state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[0]); 30281 } else { 30282 state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); 30283 } 30284 if (renderTargetProperties.__webglDepthbuffer === void 0) { 30285 renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); 30286 setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer, renderTarget, false); 30287 } else { 30288 const glAttachmentType = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; 30289 const renderbuffer = renderTargetProperties.__webglDepthbuffer; 30290 _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer); 30291 _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, glAttachmentType, _gl.RENDERBUFFER, renderbuffer); 30292 } 30293 } 30294 } 30295 state.bindFramebuffer(_gl.FRAMEBUFFER, null); 30296 } 30297 function rebindTextures(renderTarget, colorTexture, depthTexture) { 30298 const renderTargetProperties = properties.get(renderTarget); 30299 if (colorTexture !== void 0) { 30300 setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, renderTarget.texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, 0); 30301 } 30302 if (depthTexture !== void 0) { 30303 setupDepthRenderbuffer(renderTarget); 30304 } 30305 } 30306 function setupRenderTarget(renderTarget) { 30307 const texture = renderTarget.texture; 30308 const renderTargetProperties = properties.get(renderTarget); 30309 const textureProperties = properties.get(texture); 30310 renderTarget.addEventListener("dispose", onRenderTargetDispose); 30311 const textures = renderTarget.textures; 30312 const isCube = renderTarget.isWebGLCubeRenderTarget === true; 30313 const isMultipleRenderTargets = textures.length > 1; 30314 if (!isMultipleRenderTargets) { 30315 if (textureProperties.__webglTexture === void 0) { 30316 textureProperties.__webglTexture = _gl.createTexture(); 30317 } 30318 textureProperties.__version = texture.version; 30319 info.memory.textures++; 30320 } 30321 if (isCube) { 30322 renderTargetProperties.__webglFramebuffer = []; 30323 for (let i = 0; i < 6; i++) { 30324 if (texture.mipmaps && texture.mipmaps.length > 0) { 30325 renderTargetProperties.__webglFramebuffer[i] = []; 30326 for (let level = 0; level < texture.mipmaps.length; level++) { 30327 renderTargetProperties.__webglFramebuffer[i][level] = _gl.createFramebuffer(); 30328 } 30329 } else { 30330 renderTargetProperties.__webglFramebuffer[i] = _gl.createFramebuffer(); 30331 } 30332 } 30333 } else { 30334 if (texture.mipmaps && texture.mipmaps.length > 0) { 30335 renderTargetProperties.__webglFramebuffer = []; 30336 for (let level = 0; level < texture.mipmaps.length; level++) { 30337 renderTargetProperties.__webglFramebuffer[level] = _gl.createFramebuffer(); 30338 } 30339 } else { 30340 renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer(); 30341 } 30342 if (isMultipleRenderTargets) { 30343 for (let i = 0, il = textures.length; i < il; i++) { 30344 const attachmentProperties = properties.get(textures[i]); 30345 if (attachmentProperties.__webglTexture === void 0) { 30346 attachmentProperties.__webglTexture = _gl.createTexture(); 30347 info.memory.textures++; 30348 } 30349 } 30350 } 30351 if (renderTarget.samples > 0 && useMultisampledRTT(renderTarget) === false) { 30352 renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer(); 30353 renderTargetProperties.__webglColorRenderbuffer = []; 30354 state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); 30355 for (let i = 0; i < textures.length; i++) { 30356 const texture2 = textures[i]; 30357 renderTargetProperties.__webglColorRenderbuffer[i] = _gl.createRenderbuffer(); 30358 _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); 30359 const glFormat = utils.convert(texture2.format, texture2.colorSpace); 30360 const glType = utils.convert(texture2.type); 30361 const glInternalFormat = getInternalFormat(texture2.internalFormat, glFormat, glType, texture2.normalized, texture2.colorSpace, renderTarget.isXRRenderTarget === true); 30362 const samples = getRenderTargetSamples(renderTarget); 30363 _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); 30364 _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); 30365 } 30366 _gl.bindRenderbuffer(_gl.RENDERBUFFER, null); 30367 if (renderTarget.depthBuffer) { 30368 renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer(); 30369 setupRenderBufferStorage(renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true); 30370 } 30371 state.bindFramebuffer(_gl.FRAMEBUFFER, null); 30372 } 30373 } 30374 if (isCube) { 30375 state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture); 30376 setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture); 30377 for (let i = 0; i < 6; i++) { 30378 if (texture.mipmaps && texture.mipmaps.length > 0) { 30379 for (let level = 0; level < texture.mipmaps.length; level++) { 30380 setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[i][level], renderTarget, texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, level); 30381 } 30382 } else { 30383 setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[i], renderTarget, texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0); 30384 } 30385 } 30386 if (textureNeedsGenerateMipmaps(texture)) { 30387 generateMipmap(_gl.TEXTURE_CUBE_MAP); 30388 } 30389 state.unbindTexture(); 30390 } else if (isMultipleRenderTargets) { 30391 for (let i = 0, il = textures.length; i < il; i++) { 30392 const attachment = textures[i]; 30393 const attachmentProperties = properties.get(attachment); 30394 let glTextureType = _gl.TEXTURE_2D; 30395 if (renderTarget.isWebGL3DRenderTarget || renderTarget.isWebGLArrayRenderTarget) { 30396 glTextureType = renderTarget.isWebGL3DRenderTarget ? _gl.TEXTURE_3D : _gl.TEXTURE_2D_ARRAY; 30397 } 30398 state.bindTexture(glTextureType, attachmentProperties.__webglTexture); 30399 setTextureParameters(glTextureType, attachment); 30400 setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, attachment, _gl.COLOR_ATTACHMENT0 + i, glTextureType, 0); 30401 if (textureNeedsGenerateMipmaps(attachment)) { 30402 generateMipmap(glTextureType); 30403 } 30404 } 30405 state.unbindTexture(); 30406 } else { 30407 let glTextureType = _gl.TEXTURE_2D; 30408 if (renderTarget.isWebGL3DRenderTarget || renderTarget.isWebGLArrayRenderTarget) { 30409 glTextureType = renderTarget.isWebGL3DRenderTarget ? _gl.TEXTURE_3D : _gl.TEXTURE_2D_ARRAY; 30410 } 30411 state.bindTexture(glTextureType, textureProperties.__webglTexture); 30412 setTextureParameters(glTextureType, texture); 30413 if (texture.mipmaps && texture.mipmaps.length > 0) { 30414 for (let level = 0; level < texture.mipmaps.length; level++) { 30415 setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[level], renderTarget, texture, _gl.COLOR_ATTACHMENT0, glTextureType, level); 30416 } 30417 } else { 30418 setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, texture, _gl.COLOR_ATTACHMENT0, glTextureType, 0); 30419 } 30420 if (textureNeedsGenerateMipmaps(texture)) { 30421 generateMipmap(glTextureType); 30422 } 30423 state.unbindTexture(); 30424 } 30425 if (renderTarget.depthBuffer) { 30426 setupDepthRenderbuffer(renderTarget); 30427 } 30428 } 30429 function updateRenderTargetMipmap(renderTarget) { 30430 const textures = renderTarget.textures; 30431 for (let i = 0, il = textures.length; i < il; i++) { 30432 const texture = textures[i]; 30433 if (textureNeedsGenerateMipmaps(texture)) { 30434 const targetType = getTargetType(renderTarget); 30435 const webglTexture = properties.get(texture).__webglTexture; 30436 state.bindTexture(targetType, webglTexture); 30437 generateMipmap(targetType); 30438 state.unbindTexture(); 30439 } 30440 } 30441 } 30442 const invalidationArrayRead = []; 30443 const invalidationArrayDraw = []; 30444 function updateMultisampleRenderTarget(renderTarget) { 30445 if (renderTarget.samples > 0) { 30446 if (useMultisampledRTT(renderTarget) === false) { 30447 const textures = renderTarget.textures; 30448 const width = renderTarget.width; 30449 const height = renderTarget.height; 30450 let mask = _gl.COLOR_BUFFER_BIT; 30451 const depthStyle = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; 30452 const renderTargetProperties = properties.get(renderTarget); 30453 const isMultipleRenderTargets = textures.length > 1; 30454 if (isMultipleRenderTargets) { 30455 for (let i = 0; i < textures.length; i++) { 30456 state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); 30457 _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, null); 30458 state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); 30459 _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D, null, 0); 30460 } 30461 } 30462 state.bindFramebuffer(_gl.READ_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); 30463 const mipmaps = renderTarget.texture.mipmaps; 30464 if (mipmaps && mipmaps.length > 0) { 30465 state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[0]); 30466 } else { 30467 state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); 30468 } 30469 for (let i = 0; i < textures.length; i++) { 30470 if (renderTarget.resolveDepthBuffer) { 30471 if (renderTarget.depthBuffer) mask |= _gl.DEPTH_BUFFER_BIT; 30472 if (renderTarget.stencilBuffer && renderTarget.resolveStencilBuffer) mask |= _gl.STENCIL_BUFFER_BIT; 30473 } 30474 if (isMultipleRenderTargets) { 30475 _gl.framebufferRenderbuffer(_gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); 30476 const webglTexture = properties.get(textures[i]).__webglTexture; 30477 _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, webglTexture, 0); 30478 } 30479 _gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, mask, _gl.NEAREST); 30480 if (supportsInvalidateFramebuffer === true) { 30481 invalidationArrayRead.length = 0; 30482 invalidationArrayDraw.length = 0; 30483 invalidationArrayRead.push(_gl.COLOR_ATTACHMENT0 + i); 30484 if (renderTarget.depthBuffer && renderTarget.resolveDepthBuffer === false) { 30485 invalidationArrayRead.push(depthStyle); 30486 invalidationArrayDraw.push(depthStyle); 30487 _gl.invalidateFramebuffer(_gl.DRAW_FRAMEBUFFER, invalidationArrayDraw); 30488 } 30489 _gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, invalidationArrayRead); 30490 } 30491 } 30492 state.bindFramebuffer(_gl.READ_FRAMEBUFFER, null); 30493 state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, null); 30494 if (isMultipleRenderTargets) { 30495 for (let i = 0; i < textures.length; i++) { 30496 state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); 30497 _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); 30498 const webglTexture = properties.get(textures[i]).__webglTexture; 30499 state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); 30500 _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D, webglTexture, 0); 30501 } 30502 } 30503 state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); 30504 } else { 30505 if (renderTarget.depthBuffer && renderTarget.resolveDepthBuffer === false && supportsInvalidateFramebuffer) { 30506 const depthStyle = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; 30507 _gl.invalidateFramebuffer(_gl.DRAW_FRAMEBUFFER, [depthStyle]); 30508 } 30509 } 30510 } 30511 } 30512 function getRenderTargetSamples(renderTarget) { 30513 return Math.min(capabilities.maxSamples, renderTarget.samples); 30514 } 30515 function useMultisampledRTT(renderTarget) { 30516 const renderTargetProperties = properties.get(renderTarget); 30517 return renderTarget.samples > 0 && extensions.has("WEBGL_multisampled_render_to_texture") === true && renderTargetProperties.__useRenderToTexture !== false; 30518 } 30519 function updateVideoTexture(texture) { 30520 const frame = info.render.frame; 30521 if (_videoTextures.get(texture) !== frame) { 30522 _videoTextures.set(texture, frame); 30523 texture.update(); 30524 } 30525 } 30526 function verifyColorSpace(texture, image) { 30527 const colorSpace = texture.colorSpace; 30528 const format = texture.format; 30529 const type = texture.type; 30530 if (texture.isCompressedTexture === true || texture.isVideoTexture === true) return image; 30531 if (colorSpace !== LinearSRGBColorSpace && colorSpace !== NoColorSpace) { 30532 if (ColorManagement.getTransfer(colorSpace) === SRGBTransfer) { 30533 if (format !== RGBAFormat || type !== UnsignedByteType) { 30534 warn("WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType."); 30535 } 30536 } else { 30537 error("WebGLTextures: Unsupported texture color space:", colorSpace); 30538 } 30539 } 30540 return image; 30541 } 30542 function getDimensions(image) { 30543 if (typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement) { 30544 _imageDimensions.width = image.naturalWidth || image.width; 30545 _imageDimensions.height = image.naturalHeight || image.height; 30546 } else if (typeof VideoFrame !== "undefined" && image instanceof VideoFrame) { 30547 _imageDimensions.width = image.displayWidth; 30548 _imageDimensions.height = image.displayHeight; 30549 } else { 30550 _imageDimensions.width = image.width; 30551 _imageDimensions.height = image.height; 30552 } 30553 return _imageDimensions; 30554 } 30555 this.allocateTextureUnit = allocateTextureUnit; 30556 this.resetTextureUnits = resetTextureUnits; 30557 this.getTextureUnits = getTextureUnits; 30558 this.setTextureUnits = setTextureUnits; 30559 this.setTexture2D = setTexture2D; 30560 this.setTexture2DArray = setTexture2DArray; 30561 this.setTexture3D = setTexture3D; 30562 this.setTextureCube = setTextureCube; 30563 this.rebindTextures = rebindTextures; 30564 this.setupRenderTarget = setupRenderTarget; 30565 this.updateRenderTargetMipmap = updateRenderTargetMipmap; 30566 this.updateMultisampleRenderTarget = updateMultisampleRenderTarget; 30567 this.setupDepthRenderbuffer = setupDepthRenderbuffer; 30568 this.setupFrameBufferTexture = setupFrameBufferTexture; 30569 this.useMultisampledRTT = useMultisampledRTT; 30570 this.isReversedDepthBuffer = function() { 30571 return state.buffers.depth.getReversed(); 30572 }; 30573} 30574function WebGLUtils(gl, extensions) { 30575 function convert(p, colorSpace = NoColorSpace) { 30576 let extension; 30577 const transfer = ColorManagement.getTransfer(colorSpace); 30578 if (p === UnsignedByteType) return gl.UNSIGNED_BYTE; 30579 if (p === UnsignedShort4444Type) return gl.UNSIGNED_SHORT_4_4_4_4; 30580 if (p === UnsignedShort5551Type) return gl.UNSIGNED_SHORT_5_5_5_1; 30581 if (p === UnsignedInt5999Type) return gl.UNSIGNED_INT_5_9_9_9_REV; 30582 if (p === UnsignedInt101111Type) return gl.UNSIGNED_INT_10F_11F_11F_REV; 30583 if (p === ByteType) return gl.BYTE; 30584 if (p === ShortType) return gl.SHORT; 30585 if (p === UnsignedShortType) return gl.UNSIGNED_SHORT; 30586 if (p === IntType) return gl.INT; 30587 if (p === UnsignedIntType) return gl.UNSIGNED_INT; 30588 if (p === FloatType) return gl.FLOAT; 30589 if (p === HalfFloatType) return gl.HALF_FLOAT; 30590 if (p === AlphaFormat) return gl.ALPHA; 30591 if (p === RGBFormat) return gl.RGB; 30592 if (p === RGBAFormat) return gl.RGBA; 30593 if (p === DepthFormat) return gl.DEPTH_COMPONENT; 30594 if (p === DepthStencilFormat) return gl.DEPTH_STENCIL; 30595 if (p === RedFormat) return gl.RED; 30596 if (p === RedIntegerFormat) return gl.RED_INTEGER; 30597 if (p === RGFormat) return gl.RG; 30598 if (p === RGIntegerFormat) return gl.RG_INTEGER; 30599 if (p === RGBAIntegerFormat) return gl.RGBA_INTEGER; 30600 if (p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format) { 30601 if (transfer === SRGBTransfer) { 30602 extension = extensions.get("WEBGL_compressed_texture_s3tc_srgb"); 30603 if (extension !== null) { 30604 if (p === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_SRGB_S3TC_DXT1_EXT; 30605 if (p === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; 30606 if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; 30607 if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; 30608 } else { 30609 return null; 30610 } 30611 } else { 30612 extension = extensions.get("WEBGL_compressed_texture_s3tc"); 30613 if (extension !== null) { 30614 if (p === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT; 30615 if (p === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT; 30616 if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; 30617 if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; 30618 } else { 30619 return null; 30620 } 30621 } 30622 } 30623 if (p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format) { 30624 extension = extensions.get("WEBGL_compressed_texture_pvrtc"); 30625 if (extension !== null) { 30626 if (p === RGB_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; 30627 if (p === RGB_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; 30628 if (p === RGBA_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; 30629 if (p === RGBA_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; 30630 } else { 30631 return null; 30632 } 30633 } 30634 if (p === RGB_ETC1_Format || p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format || p === R11_EAC_Format || p === SIGNED_R11_EAC_Format || p === RG11_EAC_Format || p === SIGNED_RG11_EAC_Format) { 30635 extension = extensions.get("WEBGL_compressed_texture_etc"); 30636 if (extension !== null) { 30637 if (p === RGB_ETC1_Format || p === RGB_ETC2_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ETC2 : extension.COMPRESSED_RGB8_ETC2; 30638 if (p === RGBA_ETC2_EAC_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : extension.COMPRESSED_RGBA8_ETC2_EAC; 30639 if (p === R11_EAC_Format) return extension.COMPRESSED_R11_EAC; 30640 if (p === SIGNED_R11_EAC_Format) return extension.COMPRESSED_SIGNED_R11_EAC; 30641 if (p === RG11_EAC_Format) return extension.COMPRESSED_RG11_EAC; 30642 if (p === SIGNED_RG11_EAC_Format) return extension.COMPRESSED_SIGNED_RG11_EAC; 30643 } else { 30644 return null; 30645 } 30646 } 30647 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) { 30648 extension = extensions.get("WEBGL_compressed_texture_astc"); 30649 if (extension !== null) { 30650 if (p === RGBA_ASTC_4x4_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : extension.COMPRESSED_RGBA_ASTC_4x4_KHR; 30651 if (p === RGBA_ASTC_5x4_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : extension.COMPRESSED_RGBA_ASTC_5x4_KHR; 30652 if (p === RGBA_ASTC_5x5_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR; 30653 if (p === RGBA_ASTC_6x5_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR; 30654 if (p === RGBA_ASTC_6x6_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR; 30655 if (p === RGBA_ASTC_8x5_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR; 30656 if (p === RGBA_ASTC_8x6_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR; 30657 if (p === RGBA_ASTC_8x8_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR; 30658 if (p === RGBA_ASTC_10x5_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR; 30659 if (p === RGBA_ASTC_10x6_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR; 30660 if (p === RGBA_ASTC_10x8_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR; 30661 if (p === RGBA_ASTC_10x10_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR; 30662 if (p === RGBA_ASTC_12x10_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR; 30663 if (p === RGBA_ASTC_12x12_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR; 30664 } else { 30665 return null; 30666 } 30667 } 30668 if (p === RGBA_BPTC_Format || p === RGB_BPTC_SIGNED_Format || p === RGB_BPTC_UNSIGNED_Format) { 30669 extension = extensions.get("EXT_texture_compression_bptc"); 30670 if (extension !== null) { 30671 if (p === RGBA_BPTC_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : extension.COMPRESSED_RGBA_BPTC_UNORM_EXT; 30672 if (p === RGB_BPTC_SIGNED_Format) return extension.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT; 30673 if (p === RGB_BPTC_UNSIGNED_Format) return extension.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT; 30674 } else { 30675 return null; 30676 } 30677 } 30678 if (p === RED_RGTC1_Format || p === SIGNED_RED_RGTC1_Format || p === RED_GREEN_RGTC2_Format || p === SIGNED_RED_GREEN_RGTC2_Format) { 30679 extension = extensions.get("EXT_texture_compression_rgtc"); 30680 if (extension !== null) { 30681 if (p === RED_RGTC1_Format) return extension.COMPRESSED_RED_RGTC1_EXT; 30682 if (p === SIGNED_RED_RGTC1_Format) return extension.COMPRESSED_SIGNED_RED_RGTC1_EXT; 30683 if (p === RED_GREEN_RGTC2_Format) return extension.COMPRESSED_RED_GREEN_RGTC2_EXT; 30684 if (p === SIGNED_RED_GREEN_RGTC2_Format) return extension.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT; 30685 } else { 30686 return null; 30687 } 30688 } 30689 if (p === UnsignedInt248Type) return gl.UNSIGNED_INT_24_8; 30690 return gl[p] !== void 0 ? gl[p] : null; 30691 } 30692 return { convert }; 30693} 30694var _occlusion_vertex = ` 30695void main() { 30696 30697 gl_Position = vec4( position, 1.0 ); 30698 30699}`; 30700var _occlusion_fragment = ` 30701uniform sampler2DArray depthColor; 30702uniform float depthWidth; 30703uniform float depthHeight; 30704 30705void main() { 30706 30707 vec2 coord = vec2( gl_FragCoord.x / depthWidth, gl_FragCoord.y / depthHeight ); 30708 30709 if ( coord.x >= 1.0 ) { 30710 30711 gl_FragDepth = texture( depthColor, vec3( coord.x - 1.0, coord.y, 1 ) ).r; 30712 30713 } else { 30714 30715 gl_FragDepth = texture( depthColor, vec3( coord.x, coord.y, 0 ) ).r; 30716 30717 } 30718 30719}`; 30720var WebXRDepthSensing = class { 30721 /** 30722 * Constructs a new depth sensing module. 30723 */ 30724 constructor() { 30725 this.texture = null; 30726 this.mesh = null; 30727 this.depthNear = 0; 30728 this.depthFar = 0; 30729 } 30730 /** 30731 * Inits the depth sensing module 30732 * 30733 * @param {XRWebGLDepthInformation} depthData - The XR depth data. 30734 * @param {XRRenderState} renderState - The XR render state. 30735 */ 30736 init(depthData, renderState) { 30737 if (this.texture === null) { 30738 const texture = new ExternalTexture(depthData.texture); 30739 if (depthData.depthNear !== renderState.depthNear || depthData.depthFar !== renderState.depthFar) { 30740 this.depthNear = depthData.depthNear; 30741 this.depthFar = depthData.depthFar; 30742 } 30743 this.texture = texture; 30744 } 30745 } 30746 /** 30747 * Returns a plane mesh that visualizes the depth texture. 30748 * 30749 * @param {ArrayCamera} cameraXR - The XR camera. 30750 * @return {?Mesh} The plane mesh. 30751 */ 30752 getMesh(cameraXR) { 30753 if (this.texture !== null) { 30754 if (this.mesh === null) { 30755 const viewport = cameraXR.cameras[0].viewport; 30756 const material = new ShaderMaterial({ 30757 vertexShader: _occlusion_vertex, 30758 fragmentShader: _occlusion_fragment, 30759 uniforms: { 30760 depthColor: { value: this.texture }, 30761 depthWidth: { value: viewport.z }, 30762 depthHeight: { value: viewport.w } 30763 } 30764 }); 30765 this.mesh = new Mesh(new PlaneGeometry(20, 20), material); 30766 } 30767 } 30768 return this.mesh; 30769 } 30770 /** 30771 * Resets the module 30772 */ 30773 reset() { 30774 this.texture = null; 30775 this.mesh = null; 30776 } 30777 /** 30778 * Returns a texture representing the depth of the user's environment. 30779 * 30780 * @return {?ExternalTexture} The depth texture. 30781 */ 30782 getDepthTexture() { 30783 return this.texture; 30784 } 30785}; 30786var WebXRManager = class extends EventDispatcher { 30787 /** 30788 * Constructs a new WebGL renderer. 30789 * 30790 * @param {WebGLRenderer} renderer - The renderer. 30791 * @param {WebGL2RenderingContext} gl - The rendering context. 30792 */ 30793 constructor(renderer, gl) { 30794 super(); 30795 const scope = this; 30796 let session = null; 30797 let framebufferScaleFactor = 1; 30798 let referenceSpace = null; 30799 let referenceSpaceType = "local-floor"; 30800 let foveation = 1; 30801 let customReferenceSpace = null; 30802 let pose = null; 30803 let glBinding = null; 30804 let glProjLayer = null; 30805 let glBaseLayer = null; 30806 let xrFrame = null; 30807 const supportsGlBinding = typeof XRWebGLBinding !== "undefined"; 30808 const depthSensing = new WebXRDepthSensing(); 30809 const cameraAccessTextures = {}; 30810 const attributes = gl.getContextAttributes(); 30811 let initialRenderTarget = null; 30812 let newRenderTarget = null; 30813 const controllers = []; 30814 const controllerInputSources = []; 30815 const currentSize = new Vector2(); 30816 let currentPixelRatio = null; 30817 const cameraL = new PerspectiveCamera(); 30818 cameraL.viewport = new Vector4(); 30819 const cameraR = new PerspectiveCamera(); 30820 cameraR.viewport = new Vector4(); 30821 const cameras = [cameraL, cameraR]; 30822 const cameraXR = new ArrayCamera(); 30823 let _currentDepthNear = null; 30824 let _currentDepthFar = null; 30825 this.cameraAutoUpdate = true; 30826 this.enabled = false; 30827 this.isPresenting = false; 30828 this.getController = function(index) { 30829 let controller = controllers[index]; 30830 if (controller === void 0) { 30831 controller = new WebXRController(); 30832 controllers[index] = controller; 30833 } 30834 return controller.getTargetRaySpace(); 30835 }; 30836 this.getControllerGrip = function(index) { 30837 let controller = controllers[index]; 30838 if (controller === void 0) { 30839 controller = new WebXRController(); 30840 controllers[index] = controller; 30841 } 30842 return controller.getGripSpace(); 30843 }; 30844 this.getHand = function(index) { 30845 let controller = controllers[index]; 30846 if (controller === void 0) { 30847 controller = new WebXRController(); 30848 controllers[index] = controller; 30849 } 30850 return controller.getHandSpace(); 30851 }; 30852 function onSessionEvent(event) { 30853 const controllerIndex = controllerInputSources.indexOf(event.inputSource); 30854 if (controllerIndex === -1) { 30855 return; 30856 } 30857 const controller = controllers[controllerIndex]; 30858 if (controller !== void 0) { 30859 controller.update(event.inputSource, event.frame, customReferenceSpace || referenceSpace); 30860 controller.dispatchEvent({ type: event.type, data: event.inputSource }); 30861 } 30862 } 30863 function onSessionEnd() { 30864 session.removeEventListener("select", onSessionEvent); 30865 session.removeEventListener("selectstart", onSessionEvent); 30866 session.removeEventListener("selectend", onSessionEvent); 30867 session.removeEventListener("squeeze", onSessionEvent); 30868 session.removeEventListener("squeezestart", onSessionEvent); 30869 session.removeEventListener("squeezeend", onSessionEvent); 30870 session.removeEventListener("end", onSessionEnd); 30871 session.removeEventListener("inputsourceschange", onInputSourcesChange); 30872 for (let i = 0; i < controllers.length; i++) { 30873 const inputSource = controllerInputSources[i]; 30874 if (inputSource === null) continue; 30875 controllerInputSources[i] = null; 30876 controllers[i].disconnect(inputSource); 30877 } 30878 _currentDepthNear = null; 30879 _currentDepthFar = null; 30880 depthSensing.reset(); 30881 for (const key in cameraAccessTextures) { 30882 delete cameraAccessTextures[key]; 30883 } 30884 renderer.setRenderTarget(initialRenderTarget); 30885 glBaseLayer = null; 30886 glProjLayer = null; 30887 glBinding = null; 30888 session = null; 30889 newRenderTarget = null; 30890 animation.stop(); 30891 scope.isPresenting = false; 30892 renderer.setPixelRatio(currentPixelRatio); 30893 renderer.setSize(currentSize.width, currentSize.height, false); 30894 scope.dispatchEvent({ type: "sessionend" }); 30895 } 30896 this.setFramebufferScaleFactor = function(value) { 30897 framebufferScaleFactor = value; 30898 if (scope.isPresenting === true) { 30899 warn("WebXRManager: Cannot change framebuffer scale while presenting."); 30900 } 30901 }; 30902 this.setReferenceSpaceType = function(value) { 30903 referenceSpaceType = value; 30904 if (scope.isPresenting === true) { 30905 warn("WebXRManager: Cannot change reference space type while presenting."); 30906 } 30907 }; 30908 this.getReferenceSpace = function() { 30909 return customReferenceSpace || referenceSpace; 30910 }; 30911 this.setReferenceSpace = function(space) { 30912 customReferenceSpace = space; 30913 }; 30914 this.getBaseLayer = function() { 30915 return glProjLayer !== null ? glProjLayer : glBaseLayer; 30916 }; 30917 this.getBinding = function() { 30918 if (glBinding === null && supportsGlBinding) { 30919 glBinding = new XRWebGLBinding(session, gl); 30920 } 30921 return glBinding; 30922 }; 30923 this.getFrame = function() { 30924 return xrFrame; 30925 }; 30926 this.getSession = function() { 30927 return session; 30928 }; 30929 this.setSession = async function(value) { 30930 session = value; 30931 if (session !== null) { 30932 initialRenderTarget = renderer.getRenderTarget(); 30933 session.addEventListener("select", onSessionEvent); 30934 session.addEventListener("selectstart", onSessionEvent); 30935 session.addEventListener("selectend", onSessionEvent); 30936 session.addEventListener("squeeze", onSessionEvent); 30937 session.addEventListener("squeezestart", onSessionEvent); 30938 session.addEventListener("squeezeend", onSessionEvent); 30939 session.addEventListener("end", onSessionEnd); 30940 session.addEventListener("inputsourceschange", onInputSourcesChange); 30941 if (attributes.xrCompatible !== true) { 30942 await gl.makeXRCompatible(); 30943 } 30944 currentPixelRatio = renderer.getPixelRatio(); 30945 renderer.getSize(currentSize); 30946 const supportsLayers = supportsGlBinding && "createProjectionLayer" in XRWebGLBinding.prototype; 30947 if (!supportsLayers) { 30948 const layerInit = { 30949 antialias: attributes.antialias, 30950 alpha: true, 30951 depth: attributes.depth, 30952 stencil: attributes.stencil, 30953 framebufferScaleFactor 30954 }; 30955 glBaseLayer = new XRWebGLLayer(session, gl, layerInit); 30956 session.updateRenderState({ baseLayer: glBaseLayer }); 30957 renderer.setPixelRatio(1); 30958 renderer.setSize(glBaseLayer.framebufferWidth, glBaseLayer.framebufferHeight, false); 30959 newRenderTarget = new WebGLRenderTarget( 30960 glBaseLayer.framebufferWidth, 30961 glBaseLayer.framebufferHeight, 30962 { 30963 format: RGBAFormat, 30964 type: UnsignedByteType, 30965 colorSpace: renderer.outputColorSpace, 30966 stencilBuffer: attributes.stencil, 30967 resolveDepthBuffer: glBaseLayer.ignoreDepthValues === false, 30968 resolveStencilBuffer: glBaseLayer.ignoreDepthValues === false 30969 } 30970 ); 30971 } else { 30972 let depthFormat = null; 30973 let depthType = null; 30974 let glDepthFormat = null; 30975 if (attributes.depth) { 30976 glDepthFormat = attributes.stencil ? gl.DEPTH24_STENCIL8 : gl.DEPTH_COMPONENT24; 30977 depthFormat = attributes.stencil ? DepthStencilFormat : DepthFormat; 30978 depthType = attributes.stencil ? UnsignedInt248Type : UnsignedIntType; 30979 } 30980 const projectionlayerInit = { 30981 colorFormat: gl.RGBA8, 30982 depthFormat: glDepthFormat, 30983 scaleFactor: framebufferScaleFactor 30984 }; 30985 glBinding = this.getBinding(); 30986 glProjLayer = glBinding.createProjectionLayer(projectionlayerInit); 30987 session.updateRenderState({ layers: [glProjLayer] }); 30988 renderer.setPixelRatio(1); 30989 renderer.setSize(glProjLayer.textureWidth, glProjLayer.textureHeight, false); 30990 newRenderTarget = new WebGLRenderTarget( 30991 glProjLayer.textureWidth, 30992 glProjLayer.textureHeight, 30993 { 30994 format: RGBAFormat, 30995 type: UnsignedByteType, 30996 depthTexture: new DepthTexture(glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, void 0, void 0, void 0, void 0, void 0, void 0, depthFormat), 30997 stencilBuffer: attributes.stencil, 30998 colorSpace: renderer.outputColorSpace, 30999 samples: attributes.antialias ? 4 : 0, 31000 resolveDepthBuffer: glProjLayer.ignoreDepthValues === false, 31001 resolveStencilBuffer: glProjLayer.ignoreDepthValues === false 31002 } 31003 ); 31004 } 31005 newRenderTarget.isXRRenderTarget = true; 31006 this.setFoveation(foveation); 31007 customReferenceSpace = null; 31008 referenceSpace = await session.requestReferenceSpace(referenceSpaceType); 31009 animation.setContext(session); 31010 animation.start(); 31011 scope.isPresenting = true; 31012 scope.dispatchEvent({ type: "sessionstart" }); 31013 } 31014 }; 31015 this.getEnvironmentBlendMode = function() { 31016 if (session !== null) { 31017 return session.environmentBlendMode; 31018 } 31019 }; 31020 this.getDepthTexture = function() { 31021 return depthSensing.getDepthTexture(); 31022 }; 31023 function onInputSourcesChange(event) { 31024 for (let i = 0; i < event.removed.length; i++) { 31025 const inputSource = event.removed[i]; 31026 const index = controllerInputSources.indexOf(inputSource); 31027 if (index >= 0) { 31028 controllerInputSources[index] = null; 31029 controllers[index].disconnect(inputSource); 31030 } 31031 } 31032 for (let i = 0; i < event.added.length; i++) { 31033 const inputSource = event.added[i]; 31034 let controllerIndex = controllerInputSources.indexOf(inputSource); 31035 if (controllerIndex === -1) { 31036 for (let i2 = 0; i2 < controllers.length; i2++) { 31037 if (i2 >= controllerInputSources.length) { 31038 controllerInputSources.push(inputSource); 31039 controllerIndex = i2; 31040 break; 31041 } else if (controllerInputSources[i2] === null) { 31042 controllerInputSources[i2] = inputSource; 31043 controllerIndex = i2; 31044 break; 31045 } 31046 } 31047 if (controllerIndex === -1) break; 31048 } 31049 const controller = controllers[controllerIndex]; 31050 if (controller) { 31051 controller.connect(inputSource); 31052 } 31053 } 31054 } 31055 const cameraLPos = new Vector3(); 31056 const cameraRPos = new Vector3(); 31057 function setProjectionFromUnion(camera, cameraL2, cameraR2) { 31058 cameraLPos.setFromMatrixPosition(cameraL2.matrixWorld); 31059 cameraRPos.setFromMatrixPosition(cameraR2.matrixWorld); 31060 const ipd = cameraLPos.distanceTo(cameraRPos); 31061 const projL = cameraL2.projectionMatrix.elements; 31062 const projR = cameraR2.projectionMatrix.elements; 31063 const near = projL[14] / (projL[10] - 1); 31064 const far = projL[14] / (projL[10] + 1); 31065 const topFov = (projL[9] + 1) / projL[5]; 31066 const bottomFov = (projL[9] - 1) / projL[5]; 31067 const leftFov = (projL[8] - 1) / projL[0]; 31068 const rightFov = (projR[8] + 1) / projR[0]; 31069 const left = near * leftFov; 31070 const right = near * rightFov; 31071 const zOffset = ipd / (-leftFov + rightFov); 31072 const xOffset = zOffset * -leftFov; 31073 cameraL2.matrixWorld.decompose(camera.position, camera.quaternion, camera.scale); 31074 camera.translateX(xOffset); 31075 camera.translateZ(zOffset); 31076 camera.matrixWorld.compose(camera.position, camera.quaternion, camera.scale); 31077 camera.matrixWorldInverse.copy(camera.matrixWorld).invert(); 31078 if (projL[10] === -1) { 31079 camera.projectionMatrix.copy(cameraL2.projectionMatrix); 31080 camera.projectionMatrixInverse.copy(cameraL2.projectionMatrixInverse); 31081 } else { 31082 const near2 = near + zOffset; 31083 const far2 = far + zOffset; 31084 const left2 = left - xOffset; 31085 const right2 = right + (ipd - xOffset); 31086 const top2 = topFov * far / far2 * near2; 31087 const bottom2 = bottomFov * far / far2 * near2; 31088 camera.projectionMatrix.makePerspective(left2, right2, top2, bottom2, near2, far2); 31089 camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert(); 31090 } 31091 } 31092 function updateCamera(camera, parent) { 31093 if (parent === null) { 31094 camera.matrixWorld.copy(camera.matrix); 31095 } else { 31096 camera.matrixWorld.multiplyMatrices(parent.matrixWorld, camera.matrix); 31097 } 31098 camera.matrixWorldInverse.copy(camera.matrixWorld).invert(); 31099 } 31100 this.updateCamera = function(camera) { 31101 if (session === null) return; 31102 let depthNear = camera.near; 31103 let depthFar = camera.far; 31104 if (depthSensing.texture !== null) { 31105 if (depthSensing.depthNear > 0) depthNear = depthSensing.depthNear; 31106 if (depthSensing.depthFar > 0) depthFar = depthSensing.depthFar; 31107 } 31108 cameraXR.near = cameraR.near = cameraL.near = depthNear; 31109 cameraXR.far = cameraR.far = cameraL.far = depthFar; 31110 if (_currentDepthNear !== cameraXR.near || _currentDepthFar !== cameraXR.far) { 31111 session.updateRenderState({ 31112 depthNear: cameraXR.near, 31113 depthFar: cameraXR.far 31114 }); 31115 _currentDepthNear = cameraXR.near; 31116 _currentDepthFar = cameraXR.far; 31117 } 31118 cameraXR.layers.mask = camera.layers.mask | 6; 31119 cameraL.layers.mask = cameraXR.layers.mask & -5; 31120 cameraR.layers.mask = cameraXR.layers.mask & -3; 31121 const parent = camera.parent; 31122 const cameras2 = cameraXR.cameras; 31123 updateCamera(cameraXR, parent); 31124 for (let i = 0; i < cameras2.length; i++) { 31125 updateCamera(cameras2[i], parent); 31126 } 31127 if (cameras2.length === 2) { 31128 setProjectionFromUnion(cameraXR, cameraL, cameraR); 31129 } else { 31130 cameraXR.projectionMatrix.copy(cameraL.projectionMatrix); 31131 } 31132 updateUserCamera(camera, cameraXR, parent); 31133 }; 31134 function updateUserCamera(camera, cameraXR2, parent) { 31135 if (parent === null) { 31136 camera.matrix.copy(cameraXR2.matrixWorld); 31137 } else { 31138 camera.matrix.copy(parent.matrixWorld); 31139 camera.matrix.invert(); 31140 camera.matrix.multiply(cameraXR2.matrixWorld); 31141 } 31142 camera.matrix.decompose(camera.position, camera.quaternion, camera.scale); 31143 camera.updateMatrixWorld(true); 31144 camera.projectionMatrix.copy(cameraXR2.projectionMatrix); 31145 camera.projectionMatrixInverse.copy(cameraXR2.projectionMatrixInverse); 31146 if (camera.isPerspectiveCamera) { 31147 camera.fov = RAD2DEG * 2 * Math.atan(1 / camera.projectionMatrix.elements[5]); 31148 camera.zoom = 1; 31149 } 31150 } 31151 this.getCamera = function() { 31152 return cameraXR; 31153 }; 31154 this.getFoveation = function() { 31155 if (glProjLayer === null && glBaseLayer === null) { 31156 return void 0; 31157 } 31158 return foveation; 31159 }; 31160 this.setFoveation = function(value) { 31161 foveation = value; 31162 if (glProjLayer !== null) { 31163 glProjLayer.fixedFoveation = value; 31164 } 31165 if (glBaseLayer !== null && glBaseLayer.fixedFoveation !== void 0) { 31166 glBaseLayer.fixedFoveation = value; 31167 } 31168 }; 31169 this.hasDepthSensing = function() { 31170 return depthSensing.texture !== null; 31171 }; 31172 this.getDepthSensingMesh = function() { 31173 return depthSensing.getMesh(cameraXR); 31174 }; 31175 this.getCameraTexture = function(xrCamera) { 31176 return cameraAccessTextures[xrCamera]; 31177 }; 31178 let onAnimationFrameCallback = null; 31179 function onAnimationFrame(time, frame) { 31180 pose = frame.getViewerPose(customReferenceSpace || referenceSpace); 31181 xrFrame = frame; 31182 if (pose !== null) { 31183 const views = pose.views; 31184 if (glBaseLayer !== null) { 31185 renderer.setRenderTargetFramebuffer(newRenderTarget, glBaseLayer.framebuffer); 31186 renderer.setRenderTarget(newRenderTarget); 31187 } 31188 let cameraXRNeedsUpdate = false; 31189 if (views.length !== cameraXR.cameras.length) { 31190 cameraXR.cameras.length = 0; 31191 cameraXRNeedsUpdate = true; 31192 } 31193 for (let i = 0; i < views.length; i++) { 31194 const view = views[i]; 31195 let viewport = null; 31196 if (glBaseLayer !== null) { 31197 viewport = glBaseLayer.getViewport(view); 31198 } else { 31199 const glSubImage = glBinding.getViewSubImage(glProjLayer, view); 31200 viewport = glSubImage.viewport; 31201 if (i === 0) { 31202 renderer.setRenderTargetTextures( 31203 newRenderTarget, 31204 glSubImage.colorTexture, 31205 glSubImage.depthStencilTexture 31206 ); 31207 renderer.setRenderTarget(newRenderTarget); 31208 } 31209 } 31210 let camera = cameras[i]; 31211 if (camera === void 0) { 31212 camera = new PerspectiveCamera(); 31213 camera.layers.enable(i); 31214 camera.viewport = new Vector4(); 31215 cameras[i] = camera; 31216 } 31217 camera.matrix.fromArray(view.transform.matrix); 31218 camera.matrix.decompose(camera.position, camera.quaternion, camera.scale); 31219 camera.projectionMatrix.fromArray(view.projectionMatrix); 31220 camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert(); 31221 camera.viewport.set(viewport.x, viewport.y, viewport.width, viewport.height); 31222 if (i === 0) { 31223 cameraXR.matrix.copy(camera.matrix); 31224 cameraXR.matrix.decompose(cameraXR.position, cameraXR.quaternion, cameraXR.scale); 31225 } 31226 if (cameraXRNeedsUpdate === true) { 31227 cameraXR.cameras.push(camera); 31228 } 31229 } 31230 const enabledFeatures = session.enabledFeatures; 31231 const gpuDepthSensingEnabled = enabledFeatures && enabledFeatures.includes("depth-sensing") && session.depthUsage == "gpu-optimized"; 31232 if (gpuDepthSensingEnabled && supportsGlBinding) { 31233 glBinding = scope.getBinding(); 31234 const depthData = glBinding.getDepthInformation(views[0]); 31235 if (depthData && depthData.isValid && depthData.texture) { 31236 depthSensing.init(depthData, session.renderState); 31237 } 31238 } 31239 const cameraAccessEnabled = enabledFeatures && enabledFeatures.includes("camera-access"); 31240 if (cameraAccessEnabled && supportsGlBinding) { 31241 renderer.state.unbindTexture(); 31242 glBinding = scope.getBinding(); 31243 for (let i = 0; i < views.length; i++) { 31244 const camera = views[i].camera; 31245 if (camera) { 31246 let cameraTex = cameraAccessTextures[camera]; 31247 if (!cameraTex) { 31248 cameraTex = new ExternalTexture(); 31249 cameraAccessTextures[camera] = cameraTex; 31250 } 31251 const glTexture = glBinding.getCameraImage(camera); 31252 cameraTex.sourceTexture = glTexture; 31253 } 31254 } 31255 } 31256 } 31257 for (let i = 0; i < controllers.length; i++) { 31258 const inputSource = controllerInputSources[i]; 31259 const controller = controllers[i]; 31260 if (inputSource !== null && controller !== void 0) { 31261 controller.update(inputSource, frame, customReferenceSpace || referenceSpace); 31262 } 31263 } 31264 if (onAnimationFrameCallback) onAnimationFrameCallback(time, frame); 31265 if (frame.detectedPlanes) { 31266 scope.dispatchEvent({ type: "planesdetected", data: frame }); 31267 } 31268 xrFrame = null; 31269 } 31270 const animation = new WebGLAnimation(); 31271 animation.setAnimationLoop(onAnimationFrame); 31272 this.setAnimationLoop = function(callback) { 31273 onAnimationFrameCallback = callback; 31274 }; 31275 this.dispose = function() { 31276 }; 31277 } 31278}; 31279var _m12 = /* @__PURE__ */ new Matrix4(); 31280var _m = /* @__PURE__ */ new Matrix3(); 31281_m.set(-1, 0, 0, 0, 1, 0, 0, 0, 1); 31282function WebGLMaterials(renderer, properties) { 31283 function refreshTransformUniform(map, uniform) { 31284 if (map.matrixAutoUpdate === true) { 31285 map.updateMatrix(); 31286 } 31287 uniform.value.copy(map.matrix); 31288 } 31289 function refreshFogUniforms(uniforms, fog) { 31290 fog.color.getRGB(uniforms.fogColor.value, getUnlitUniformColorSpace(renderer)); 31291 if (fog.isFog) { 31292 uniforms.fogNear.value = fog.near; 31293 uniforms.fogFar.value = fog.far; 31294 } else if (fog.isFogExp2) { 31295 uniforms.fogDensity.value = fog.density; 31296 } 31297 } 31298 function refreshMaterialUniforms(uniforms, material, pixelRatio, height, transmissionRenderTarget) { 31299 if (material.isNodeMaterial) { 31300 material.uniformsNeedUpdate = false; 31301 } else if (material.isMeshBasicMaterial) { 31302 refreshUniformsCommon(uniforms, material); 31303 } else if (material.isMeshLambertMaterial) { 31304 refreshUniformsCommon(uniforms, material); 31305 if (material.envMap) { 31306 uniforms.envMapIntensity.value = material.envMapIntensity; 31307 } 31308 } else if (material.isMeshToonMaterial) { 31309 refreshUniformsCommon(uniforms, material); 31310 refreshUniformsToon(uniforms, material); 31311 } else if (material.isMeshPhongMaterial) { 31312 refreshUniformsCommon(uniforms, material); 31313 refreshUniformsPhong(uniforms, material); 31314 if (material.envMap) { 31315 uniforms.envMapIntensity.value = material.envMapIntensity; 31316 } 31317 } else if (material.isMeshStandardMaterial) { 31318 refreshUniformsCommon(uniforms, material); 31319 refreshUniformsStandard(uniforms, material); 31320 if (material.isMeshPhysicalMaterial) { 31321 refreshUniformsPhysical(uniforms, material, transmissionRenderTarget); 31322 } 31323 } else if (material.isMeshMatcapMaterial) { 31324 refreshUniformsCommon(uniforms, material); 31325 refreshUniformsMatcap(uniforms, material); 31326 } else if (material.isMeshDepthMaterial) { 31327 refreshUniformsCommon(uniforms, material); 31328 } else if (material.isMeshDistanceMaterial) { 31329 refreshUniformsCommon(uniforms, material); 31330 refreshUniformsDistance(uniforms, material); 31331 } else if (material.isMeshNormalMaterial) { 31332 refreshUniformsCommon(uniforms, material); 31333 } else if (material.isLineBasicMaterial) { 31334 refreshUniformsLine(uniforms, material); 31335 if (material.isLineDashedMaterial) { 31336 refreshUniformsDash(uniforms, material); 31337 } 31338 } else if (material.isPointsMaterial) { 31339 refreshUniformsPoints(uniforms, material, pixelRatio, height); 31340 } else if (material.isSpriteMaterial) { 31341 refreshUniformsSprites(uniforms, material); 31342 } else if (material.isShadowMaterial) { 31343 uniforms.color.value.copy(material.color); 31344 uniforms.opacity.value = material.opacity; 31345 } else if (material.isShaderMaterial) { 31346 material.uniformsNeedUpdate = false; 31347 } 31348 } 31349 function refreshUniformsCommon(uniforms, material) { 31350 uniforms.opacity.value = material.opacity; 31351 if (material.color) { 31352 uniforms.diffuse.value.copy(material.color); 31353 } 31354 if (material.emissive) { 31355 uniforms.emissive.value.copy(material.emissive).multiplyScalar(material.emissiveIntensity); 31356 } 31357 if (material.map) { 31358 uniforms.map.value = material.map; 31359 refreshTransformUniform(material.map, uniforms.mapTransform); 31360 } 31361 if (material.alphaMap) { 31362 uniforms.alphaMap.value = material.alphaMap; 31363 refreshTransformUniform(material.alphaMap, uniforms.alphaMapTransform); 31364 } 31365 if (material.bumpMap) { 31366 uniforms.bumpMap.value = material.bumpMap; 31367 refreshTransformUniform(material.bumpMap, uniforms.bumpMapTransform); 31368 uniforms.bumpScale.value = material.bumpScale; 31369 if (material.side === BackSide) { 31370 uniforms.bumpScale.value *= -1; 31371 } 31372 } 31373 if (material.normalMap) { 31374 uniforms.normalMap.value = material.normalMap; 31375 refreshTransformUniform(material.normalMap, uniforms.normalMapTransform); 31376 uniforms.normalScale.value.copy(material.normalScale); 31377 if (material.side === BackSide) { 31378 uniforms.normalScale.value.negate(); 31379 } 31380 } 31381 if (material.displacementMap) { 31382 uniforms.displacementMap.value = material.displacementMap; 31383 refreshTransformUniform(material.displacementMap, uniforms.displacementMapTransform); 31384 uniforms.displacementScale.value = material.displacementScale; 31385 uniforms.displacementBias.value = material.displacementBias; 31386 } 31387 if (material.emissiveMap) { 31388 uniforms.emissiveMap.value = material.emissiveMap; 31389 refreshTransformUniform(material.emissiveMap, uniforms.emissiveMapTransform); 31390 } 31391 if (material.specularMap) { 31392 uniforms.specularMap.value = material.specularMap; 31393 refreshTransformUniform(material.specularMap, uniforms.specularMapTransform); 31394 } 31395 if (material.alphaTest > 0) { 31396 uniforms.alphaTest.value = material.alphaTest; 31397 } 31398 const materialProperties = properties.get(material); 31399 const envMap = materialProperties.envMap; 31400 const envMapRotation = materialProperties.envMapRotation; 31401 if (envMap) { 31402 uniforms.envMap.value = envMap; 31403 uniforms.envMapRotation.value.setFromMatrix4(_m12.makeRotationFromEuler(envMapRotation)).transpose(); 31404 if (envMap.isCubeTexture && envMap.isRenderTargetTexture === false) { 31405 uniforms.envMapRotation.value.premultiply(_m); 31406 } 31407 uniforms.reflectivity.value = material.reflectivity; 31408 uniforms.ior.value = material.ior; 31409 uniforms.refractionRatio.value = material.refractionRatio; 31410 } 31411 if (material.lightMap) { 31412 uniforms.lightMap.value = material.lightMap; 31413 uniforms.lightMapIntensity.value = material.lightMapIntensity; 31414 refreshTransformUniform(material.lightMap, uniforms.lightMapTransform); 31415 } 31416 if (material.aoMap) { 31417 uniforms.aoMap.value = material.aoMap; 31418 uniforms.aoMapIntensity.value = material.aoMapIntensity; 31419 refreshTransformUniform(material.aoMap, uniforms.aoMapTransform); 31420 } 31421 } 31422 function refreshUniformsLine(uniforms, material) { 31423 uniforms.diffuse.value.copy(material.color); 31424 uniforms.opacity.value = material.opacity; 31425 if (material.map) { 31426 uniforms.map.value = material.map; 31427 refreshTransformUniform(material.map, uniforms.mapTransform); 31428 } 31429 } 31430 function refreshUniformsDash(uniforms, material) { 31431 uniforms.dashSize.value = material.dashSize; 31432 uniforms.totalSize.value = material.dashSize + material.gapSize; 31433 uniforms.scale.value = material.scale; 31434 } 31435 function refreshUniformsPoints(uniforms, material, pixelRatio, height) { 31436 uniforms.diffuse.value.copy(material.color); 31437 uniforms.opacity.value = material.opacity; 31438 uniforms.size.value = material.size * pixelRatio; 31439 uniforms.scale.value = height * 0.5; 31440 if (material.map) { 31441 uniforms.map.value = material.map; 31442 refreshTransformUniform(material.map, uniforms.uvTransform); 31443 } 31444 if (material.alphaMap) { 31445 uniforms.alphaMap.value = material.alphaMap; 31446 refreshTransformUniform(material.alphaMap, uniforms.alphaMapTransform); 31447 } 31448 if (material.alphaTest > 0) { 31449 uniforms.alphaTest.value = material.alphaTest; 31450 } 31451 } 31452 function refreshUniformsSprites(uniforms, material) { 31453 uniforms.diffuse.value.copy(material.color); 31454 uniforms.opacity.value = material.opacity; 31455 uniforms.rotation.value = material.rotation; 31456 if (material.map) { 31457 uniforms.map.value = material.map; 31458 refreshTransformUniform(material.map, uniforms.mapTransform); 31459 } 31460 if (material.alphaMap) { 31461 uniforms.alphaMap.value = material.alphaMap; 31462 refreshTransformUniform(material.alphaMap, uniforms.alphaMapTransform); 31463 } 31464 if (material.alphaTest > 0) { 31465 uniforms.alphaTest.value = material.alphaTest; 31466 } 31467 } 31468 function refreshUniformsPhong(uniforms, material) { 31469 uniforms.specular.value.copy(material.specular); 31470 uniforms.shininess.value = Math.max(material.shininess, 1e-4); 31471 } 31472 function refreshUniformsToon(uniforms, material) { 31473 if (material.gradientMap) { 31474 uniforms.gradientMap.value = material.gradientMap; 31475 } 31476 } 31477 function refreshUniformsStandard(uniforms, material) { 31478 uniforms.metalness.value = material.metalness; 31479 if (material.metalnessMap) { 31480 uniforms.metalnessMap.value = material.metalnessMap; 31481 refreshTransformUniform(material.metalnessMap, uniforms.metalnessMapTransform); 31482 } 31483 uniforms.roughness.value = material.roughness; 31484 if (material.roughnessMap) { 31485 uniforms.roughnessMap.value = material.roughnessMap; 31486 refreshTransformUniform(material.roughnessMap, uniforms.roughnessMapTransform); 31487 } 31488 if (material.envMap) { 31489 uniforms.envMapIntensity.value = material.envMapIntensity; 31490 } 31491 } 31492 function refreshUniformsPhysical(uniforms, material, transmissionRenderTarget) { 31493 uniforms.ior.value = material.ior; 31494 if (material.sheen > 0) { 31495 uniforms.sheenColor.value.copy(material.sheenColor).multiplyScalar(material.sheen); 31496 uniforms.sheenRoughness.value = material.sheenRoughness; 31497 if (material.sheenColorMap) { 31498 uniforms.sheenColorMap.value = material.sheenColorMap; 31499 refreshTransformUniform(material.sheenColorMap, uniforms.sheenColorMapTransform); 31500 } 31501 if (material.sheenRoughnessMap) { 31502 uniforms.sheenRoughnessMap.value = material.sheenRoughnessMap; 31503 refreshTransformUniform(material.sheenRoughnessMap, uniforms.sheenRoughnessMapTransform); 31504 } 31505 } 31506 if (material.clearcoat > 0) { 31507 uniforms.clearcoat.value = material.clearcoat; 31508 uniforms.clearcoatRoughness.value = material.clearcoatRoughness; 31509 if (material.clearcoatMap) { 31510 uniforms.clearcoatMap.value = material.clearcoatMap; 31511 refreshTransformUniform(material.clearcoatMap, uniforms.clearcoatMapTransform); 31512 } 31513 if (material.clearcoatRoughnessMap) { 31514 uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap; 31515 refreshTransformUniform(material.clearcoatRoughnessMap, uniforms.clearcoatRoughnessMapTransform); 31516 } 31517 if (material.clearcoatNormalMap) { 31518 uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap; 31519 refreshTransformUniform(material.clearcoatNormalMap, uniforms.clearcoatNormalMapTransform); 31520 uniforms.clearcoatNormalScale.value.copy(material.clearcoatNormalScale); 31521 if (material.side === BackSide) { 31522 uniforms.clearcoatNormalScale.value.negate(); 31523 } 31524 } 31525 } 31526 if (material.dispersion > 0) { 31527 uniforms.dispersion.value = material.dispersion; 31528 } 31529 if (material.iridescence > 0) { 31530 uniforms.iridescence.value = material.iridescence; 31531 uniforms.iridescenceIOR.value = material.iridescenceIOR; 31532 uniforms.iridescenceThicknessMinimum.value = material.iridescenceThicknessRange[0]; 31533 uniforms.iridescenceThicknessMaximum.value = material.iridescenceThicknessRange[1]; 31534 if (material.iridescenceMap) { 31535 uniforms.iridescenceMap.value = material.iridescenceMap; 31536 refreshTransformUniform(material.iridescenceMap, uniforms.iridescenceMapTransform); 31537 } 31538 if (material.iridescenceThicknessMap) { 31539 uniforms.iridescenceThicknessMap.value = material.iridescenceThicknessMap; 31540 refreshTransformUniform(material.iridescenceThicknessMap, uniforms.iridescenceThicknessMapTransform); 31541 } 31542 } 31543 if (material.transmission > 0) { 31544 uniforms.transmission.value = material.transmission; 31545 uniforms.transmissionSamplerMap.value = transmissionRenderTarget.texture; 31546 uniforms.transmissionSamplerSize.value.set(transmissionRenderTarget.width, transmissionRenderTarget.height); 31547 if (material.transmissionMap) { 31548 uniforms.transmissionMap.value = material.transmissionMap; 31549 refreshTransformUniform(material.transmissionMap, uniforms.transmissionMapTransform); 31550 } 31551 uniforms.thickness.value = material.thickness; 31552 if (material.thicknessMap) { 31553 uniforms.thicknessMap.value = material.thicknessMap; 31554 refreshTransformUniform(material.thicknessMap, uniforms.thicknessMapTransform); 31555 } 31556 uniforms.attenuationDistance.value = material.attenuationDistance; 31557 uniforms.attenuationColor.value.copy(material.attenuationColor); 31558 } 31559 if (material.anisotropy > 0) { 31560 uniforms.anisotropyVector.value.set(material.anisotropy * Math.cos(material.anisotropyRotation), material.anisotropy * Math.sin(material.anisotropyRotation)); 31561 if (material.anisotropyMap) { 31562 uniforms.anisotropyMap.value = material.anisotropyMap; 31563 refreshTransformUniform(material.anisotropyMap, uniforms.anisotropyMapTransform); 31564 } 31565 } 31566 uniforms.specularIntensity.value = material.specularIntensity; 31567 uniforms.specularColor.value.copy(material.specularColor); 31568 if (material.specularColorMap) { 31569 uniforms.specularColorMap.value = material.specularColorMap; 31570 refreshTransformUniform(material.specularColorMap, uniforms.specularColorMapTransform); 31571 } 31572 if (material.specularIntensityMap) { 31573 uniforms.specularIntensityMap.value = material.specularIntensityMap; 31574 refreshTransformUniform(material.specularIntensityMap, uniforms.specularIntensityMapTransform); 31575 } 31576 } 31577 function refreshUniformsMatcap(uniforms, material) { 31578 if (material.matcap) { 31579 uniforms.matcap.value = material.matcap; 31580 } 31581 } 31582 function refreshUniformsDistance(uniforms, material) { 31583 const light = properties.get(material).light; 31584 uniforms.referencePosition.value.setFromMatrixPosition(light.matrixWorld); 31585 uniforms.nearDistance.value = light.shadow.camera.near; 31586 uniforms.farDistance.value = light.shadow.camera.far; 31587 } 31588 return { 31589 refreshFogUniforms, 31590 refreshMaterialUniforms 31591 }; 31592} 31593function WebGLUniformsGroups(gl, info, capabilities, state) { 31594 let buffers = {}; 31595 let updateList = {}; 31596 let allocatedBindingPoints = []; 31597 const maxBindingPoints = gl.getParameter(gl.MAX_UNIFORM_BUFFER_BINDINGS); 31598 function bind(uniformsGroup, program) { 31599 const webglProgram = program.program; 31600 state.uniformBlockBinding(uniformsGroup, webglProgram); 31601 } 31602 function update(uniformsGroup, program) { 31603 let buffer = buffers[uniformsGroup.id]; 31604 if (buffer === void 0) { 31605 prepareUniformsGroup(uniformsGroup); 31606 buffer = createBuffer(uniformsGroup); 31607 buffers[uniformsGroup.id] = buffer; 31608 uniformsGroup.addEventListener("dispose", onUniformsGroupsDispose); 31609 } 31610 const webglProgram = program.program; 31611 state.updateUBOMapping(uniformsGroup, webglProgram); 31612 const frame = info.render.frame; 31613 if (updateList[uniformsGroup.id] !== frame) { 31614 updateBufferData(uniformsGroup); 31615 updateList[uniformsGroup.id] = frame; 31616 } 31617 } 31618 function createBuffer(uniformsGroup) { 31619 const bindingPointIndex = allocateBindingPointIndex(); 31620 uniformsGroup.__bindingPointIndex = bindingPointIndex; 31621 const buffer = gl.createBuffer(); 31622 const size = uniformsGroup.__size; 31623 const usage = uniformsGroup.usage; 31624 gl.bindBuffer(gl.UNIFORM_BUFFER, buffer); 31625 gl.bufferData(gl.UNIFORM_BUFFER, size, usage); 31626 gl.bindBuffer(gl.UNIFORM_BUFFER, null); 31627 gl.bindBufferBase(gl.UNIFORM_BUFFER, bindingPointIndex, buffer); 31628 return buffer; 31629 } 31630 function allocateBindingPointIndex() { 31631 for (let i = 0; i < maxBindingPoints; i++) { 31632 if (allocatedBindingPoints.indexOf(i) === -1) { 31633 allocatedBindingPoints.push(i); 31634 return i; 31635 } 31636 } 31637 error("WebGLRenderer: Maximum number of simultaneously usable uniforms groups reached."); 31638 return 0; 31639 } 31640 function updateBufferData(uniformsGroup) { 31641 const buffer = buffers[uniformsGroup.id]; 31642 const uniforms = uniformsGroup.uniforms; 31643 const cache = uniformsGroup.__cache; 31644 gl.bindBuffer(gl.UNIFORM_BUFFER, buffer); 31645 for (let i = 0, il = uniforms.length; i < il; i++) { 31646 const uniformArray = Array.isArray(uniforms[i]) ? uniforms[i] : [uniforms[i]]; 31647 for (let j = 0, jl = uniformArray.length; j < jl; j++) { 31648 const uniform = uniformArray[j]; 31649 if (hasUniformChanged(uniform, i, j, cache) === true) { 31650 const offset = uniform.__offset; 31651 const values = Array.isArray(uniform.value) ? uniform.value : [uniform.value]; 31652 let arrayOffset = 0; 31653 for (let k = 0; k < values.length; k++) { 31654 const value = values[k]; 31655 const info2 = getUniformSize(value); 31656 if (typeof value === "number" || typeof value === "boolean") { 31657 uniform.__data[0] = value; 31658 gl.bufferSubData(gl.UNIFORM_BUFFER, offset + arrayOffset, uniform.__data); 31659 } else if (value.isMatrix3) { 31660 uniform.__data[0] = value.elements[0]; 31661 uniform.__data[1] = value.elements[1]; 31662 uniform.__data[2] = value.elements[2]; 31663 uniform.__data[3] = 0; 31664 uniform.__data[4] = value.elements[3]; 31665 uniform.__data[5] = value.elements[4]; 31666 uniform.__data[6] = value.elements[5]; 31667 uniform.__data[7] = 0; 31668 uniform.__data[8] = value.elements[6]; 31669 uniform.__data[9] = value.elements[7]; 31670 uniform.__data[10] = value.elements[8]; 31671 uniform.__data[11] = 0; 31672 } else if (ArrayBuffer.isView(value)) { 31673 uniform.__data.set(new value.constructor(value.buffer, value.byteOffset, uniform.__data.length)); 31674 } else { 31675 value.toArray(uniform.__data, arrayOffset); 31676 arrayOffset += info2.storage / Float32Array.BYTES_PER_ELEMENT; 31677 } 31678 } 31679 gl.bufferSubData(gl.UNIFORM_BUFFER, offset, uniform.__data); 31680 } 31681 } 31682 } 31683 gl.bindBuffer(gl.UNIFORM_BUFFER, null); 31684 } 31685 function hasUniformChanged(uniform, index, indexArray, cache) { 31686 const value = uniform.value; 31687 const indexString = index + "_" + indexArray; 31688 if (cache[indexString] === void 0) { 31689 if (typeof value === "number" || typeof value === "boolean") { 31690 cache[indexString] = value; 31691 } else if (ArrayBuffer.isView(value)) { 31692 cache[indexString] = value.slice(); 31693 } else { 31694 cache[indexString] = value.clone(); 31695 } 31696 return true; 31697 } else { 31698 const cachedObject = cache[indexString]; 31699 if (typeof value === "number" || typeof value === "boolean") { 31700 if (cachedObject !== value) { 31701 cache[indexString] = value; 31702 return true; 31703 } 31704 } else if (ArrayBuffer.isView(value)) { 31705 return true; 31706 } else { 31707 if (cachedObject.equals(value) === false) { 31708 cachedObject.copy(value); 31709 return true; 31710 } 31711 } 31712 } 31713 return false; 31714 } 31715 function prepareUniformsGroup(uniformsGroup) { 31716 const uniforms = uniformsGroup.uniforms; 31717 let offset = 0; 31718 const chunkSize = 16; 31719 for (let i = 0, l = uniforms.length; i < l; i++) { 31720 const uniformArray = Array.isArray(uniforms[i]) ? uniforms[i] : [uniforms[i]]; 31721 for (let j = 0, jl = uniformArray.length; j < jl; j++) { 31722 const uniform = uniformArray[j]; 31723 const values = Array.isArray(uniform.value) ? uniform.value : [uniform.value]; 31724 for (let k = 0, kl = values.length; k < kl; k++) { 31725 const value = values[k]; 31726 const info2 = getUniformSize(value); 31727 const chunkOffset2 = offset % chunkSize; 31728 const chunkPadding = chunkOffset2 % info2.boundary; 31729 const chunkStart = chunkOffset2 + chunkPadding; 31730 offset += chunkPadding; 31731 if (chunkStart !== 0 && chunkSize - chunkStart < info2.storage) { 31732 offset += chunkSize - chunkStart; 31733 } 31734 uniform.__data = new Float32Array(info2.storage / Float32Array.BYTES_PER_ELEMENT); 31735 uniform.__offset = offset; 31736 offset += info2.storage; 31737 } 31738 } 31739 } 31740 const chunkOffset = offset % chunkSize; 31741 if (chunkOffset > 0) offset += chunkSize - chunkOffset; 31742 uniformsGroup.__size = offset; 31743 uniformsGroup.__cache = {}; 31744 return this; 31745 } 31746 function getUniformSize(value) { 31747 const info2 = { 31748 boundary: 0, 31749 // bytes 31750 storage: 0 31751 // bytes 31752 }; 31753 if (typeof value === "number" || typeof value === "boolean") { 31754 info2.boundary = 4; 31755 info2.storage = 4; 31756 } else if (value.isVector2) { 31757 info2.boundary = 8; 31758 info2.storage = 8; 31759 } else if (value.isVector3 || value.isColor) { 31760 info2.boundary = 16; 31761 info2.storage = 12; 31762 } else if (value.isVector4) { 31763 info2.boundary = 16; 31764 info2.storage = 16; 31765 } else if (value.isMatrix3) { 31766 info2.boundary = 48; 31767 info2.storage = 48; 31768 } else if (value.isMatrix4) { 31769 info2.boundary = 64; 31770 info2.storage = 64; 31771 } else if (value.isTexture) { 31772 warn("WebGLRenderer: Texture samplers can not be part of an uniforms group."); 31773 } else if (ArrayBuffer.isView(value)) { 31774 info2.boundary = 16; 31775 info2.storage = value.byteLength; 31776 } else { 31777 warn("WebGLRenderer: Unsupported uniform value type.", value); 31778 } 31779 return info2; 31780 } 31781 function onUniformsGroupsDispose(event) { 31782 const uniformsGroup = event.target; 31783 uniformsGroup.removeEventListener("dispose", onUniformsGroupsDispose); 31784 const index = allocatedBindingPoints.indexOf(uniformsGroup.__bindingPointIndex); 31785 allocatedBindingPoints.splice(index, 1); 31786 gl.deleteBuffer(buffers[uniformsGroup.id]); 31787 delete buffers[uniformsGroup.id]; 31788 delete updateList[uniformsGroup.id]; 31789 } 31790 function dispose2() { 31791 for (const id in buffers) { 31792 gl.deleteBuffer(buffers[id]); 31793 } 31794 allocatedBindingPoints = []; 31795 buffers = {}; 31796 updateList = {}; 31797 } 31798 return { 31799 bind, 31800 update, 31801 dispose: dispose2 31802 }; 31803} 31804var DATA = new Uint16Array([ 31805 12469, 31806 15057, 31807 12620, 31808 14925, 31809 13266, 31810 14620, 31811 13807, 31812 14376, 31813 14323, 31814 13990, 31815 14545, 31816 13625, 31817 14713, 31818 13328, 31819 14840, 31820 12882, 31821 14931, 31822 12528, 31823 14996, 31824 12233, 31825 15039, 31826 11829, 31827 15066, 31828 11525, 31829 15080, 31830 11295, 31831 15085, 31832 10976, 31833 15082, 31834 10705, 31835 15073, 31836 10495, 31837 13880, 31838 14564, 31839 13898, 31840 14542, 31841 13977, 31842 14430, 31843 14158, 31844 14124, 31845 14393, 31846 13732, 31847 14556, 31848 13410, 31849 14702, 31850 12996, 31851 14814, 31852 12596, 31853 14891, 31854 12291, 31855 14937, 31856 11834, 31857 14957, 31858 11489, 31859 14958, 31860 11194, 31861 14943, 31862 10803, 31863 14921, 31864 10506, 31865 14893, 31866 10278, 31867 14858, 31868 9960, 31869 14484, 31870 14039, 31871 14487, 31872 14025, 31873 14499, 31874 13941, 31875 14524, 31876 13740, 31877 14574, 31878 13468, 31879 14654, 31880 13106, 31881 14743, 31882 12678, 31883 14818, 31884 12344, 31885 14867, 31886 11893, 31887 14889, 31888 11509, 31889 14893, 31890 11180, 31891 14881, 31892 10751, 31893 14852, 31894 10428, 31895 14812, 31896 10128, 31897 14765, 31898 9754, 31899 14712, 31900 9466, 31901 14764, 31902 13480, 31903 14764, 31904 13475, 31905 14766, 31906 13440, 31907 14766, 31908 13347, 31909 14769, 31910 13070, 31911 14786, 31912 12713, 31913 14816, 31914 12387, 31915 14844, 31916 11957, 31917 14860, 31918 11549, 31919 14868, 31920 11215, 31921 14855, 31922 10751, 31923 14825, 31924 10403, 31925 14782, 31926 10044, 31927 14729, 31928 9651, 31929 14666, 31930 9352, 31931 14599, 31932 9029, 31933 14967, 31934 12835, 31935 14966, 31936 12831, 31937 14963, 31938 12804, 31939 14954, 31940 12723, 31941 14936, 31942 12564, 31943 14917, 31944 12347, 31945 14900, 31946 11958, 31947 14886, 31948 11569, 31949 14878, 31950 11247, 31951 14859, 31952 10765, 31953 14828, 31954 10401, 31955 14784, 31956 10011, 31957 14727, 31958 9600, 31959 14660, 31960 9289, 31961 14586, 31962 8893, 31963 14508, 31964 8533, 31965 15111, 31966 12234, 31967 15110, 31968 12234, 31969 15104, 31970 12216, 31971 15092, 31972 12156, 31973 15067, 31974 12010, 31975 15028, 31976 11776, 31977 14981, 31978 11500, 31979 14942, 31980 11205, 31981 14902, 31982 10752, 31983 14861, 31984 10393, 31985 14812, 31986 9991, 31987 14752, 31988 9570, 31989 14682, 31990 9252, 31991 14603, 31992 8808, 31993 14519, 31994 8445, 31995 14431, 31996 8145, 31997 15209, 31998 11449, 31999 15208, 32000 11451, 32001 15202, 32002 11451, 32003 15190, 32004 11438, 32005 15163, 32006 11384, 32007 15117, 32008 11274, 32009 15055, 32010 10979, 32011 14994, 32012 10648, 32013 14932, 32014 10343, 32015 14871, 32016 9936, 32017 14803, 32018 9532, 32019 14729, 32020 9218, 32021 14645, 32022 8742, 32023 14556, 32024 8381, 32025 14461, 32026 8020, 32027 14365, 32028 7603, 32029 15273, 32030 10603, 32031 15272, 32032 10607, 32033 15267, 32034 10619, 32035 15256, 32036 10631, 32037 15231, 32038 10614, 32039 15182, 32040 10535, 32041 15118, 32042 10389, 32043 15042, 32044 10167, 32045 14963, 32046 9787, 32047 14883, 32048 9447, 32049 14800, 32050 9115, 32051 14710, 32052 8665, 32053 14615, 32054 8318, 32055 14514, 32056 7911, 32057 14411, 32058 7507, 32059 14279, 32060 7198, 32061 15314, 32062 9675, 32063 15313, 32064 9683, 32065 15309, 32066 9712, 32067 15298, 32068 9759, 32069 15277, 32070 9797, 32071 15229, 32072 9773, 32073 15166, 32074 9668, 32075 15084, 32076 9487, 32077 14995, 32078 9274, 32079 14898, 32080 8910, 32081 14800, 32082 8539, 32083 14697, 32084 8234, 32085 14590, 32086 7790, 32087 14479, 32088 7409, 32089 14367, 32090 7067, 32091 14178, 32092 6621, 32093 15337, 32094 8619, 32095 15337, 32096 8631, 32097 15333, 32098 8677, 32099 15325, 32100 8769, 32101 15305, 32102 8871, 32103 15264, 32104 8940, 32105 15202, 32106 8909, 32107 15119, 32108 8775, 32109 15022, 32110 8565, 32111 14916, 32112 8328, 32113 14804, 32114 8009, 32115 14688, 32116 7614, 32117 14569, 32118 7287, 32119 14448, 32120 6888, 32121 14321, 32122 6483, 32123 14088, 32124 6171, 32125 15350, 32126 7402, 32127 15350, 32128 7419, 32129 15347, 32130 7480, 32131 15340, 32132 7613, 32133 15322, 32134 7804, 32135 15287, 32136 7973, 32137 15229, 32138 8057, 32139 15148, 32140 8012, 32141 15046, 32142 7846, 32143 14933, 32144 7611, 32145 14810, 32146 7357, 32147 14682, 32148 7069, 32149 14552, 32150 6656, 32151 14421, 32152 6316, 32153 14251, 32154 5948, 32155 14007, 32156 5528, 32157 15356, 32158 5942, 32159 15356, 32160 5977, 32161 15353, 32162 6119, 32163 15348, 32164 6294, 32165 15332, 32166 6551, 32167 15302, 32168 6824, 32169 15249, 32170 7044, 32171 15171, 32172 7122, 32173 15070, 32174 7050, 32175 14949, 32176 6861, 32177 14818, 32178 6611, 32179 14679, 32180 6349, 32181 14538, 32182 6067, 32183 14398, 32184 5651, 32185 14189, 32186 5311, 32187 13935, 32188 4958, 32189 15359, 32190 4123, 32191 15359, 32192 4153, 32193 15356, 32194 4296, 32195 15353, 32196 4646, 32197 15338, 32198 5160, 32199 15311, 32200 5508, 32201 15263, 32202 5829, 32203 15188, 32204 6042, 32205 15088, 32206 6094, 32207 14966, 32208 6001, 32209 14826, 32210 5796, 32211 14678, 32212 5543, 32213 14527, 32214 5287, 32215 14377, 32216 4985, 32217 14133, 32218 4586, 32219 13869, 32220 4257, 32221 15360, 32222 1563, 32223 15360, 32224 1642, 32225 15358, 32226 2076, 32227 15354, 32228 2636, 32229 15341, 32230 3350, 32231 15317, 32232 4019, 32233 15273, 32234 4429, 32235 15203, 32236 4732, 32237 15105, 32238 4911, 32239 14981, 32240 4932, 32241 14836, 32242 4818, 32243 14679, 32244 4621, 32245 14517, 32246 4386, 32247 14359, 32248 4156, 32249 14083, 32250 3795, 32251 13808, 32252 3437, 32253 15360, 32254 122, 32255 15360, 32256 137, 32257 15358, 32258 285, 32259 15355, 32260 636, 32261 15344, 32262 1274, 32263 15322, 32264 2177, 32265 15281, 32266 2765, 32267 15215, 32268 3223, 32269 15120, 32270 3451, 32271 14995, 32272 3569, 32273 14846, 32274 3567, 32275 14681, 32276 3466, 32277 14511, 32278 3305, 32279 14344, 32280 3121, 32281 14037, 32282 2800, 32283 13753, 32284 2467, 32285 15360, 32286 0, 32287 15360, 32288 1, 32289 15359, 32290 21, 32291 15355, 32292 89, 32293 15346, 32294 253, 32295 15325, 32296 479, 32297 15287, 32298 796, 32299 15225, 32300 1148, 32301 15133, 32302 1492, 32303 15008, 32304 1749, 32305 14856, 32306 1882, 32307 14685, 32308 1886, 32309 14506, 32310 1783, 32311 14324, 32312 1608, 32313 13996, 32314 1398, 32315 13702, 32316 1183 32317]); 32318var lut = null; 32319function getDFGLUT() { 32320 if (lut === null) { 32321 lut = new DataTexture(DATA, 16, 16, RGFormat, HalfFloatType); 32322 lut.name = "DFG_LUT"; 32323 lut.minFilter = LinearFilter; 32324 lut.magFilter = LinearFilter; 32325 lut.wrapS = ClampToEdgeWrapping; 32326 lut.wrapT = ClampToEdgeWrapping; 32327 lut.generateMipmaps = false; 32328 lut.needsUpdate = true; 32329 } 32330 return lut; 32331} 32332var WebGLRenderer = class { 32333 /** 32334 * Constructs a new WebGL renderer. 32335 * 32336 * @param {WebGLRenderer~Options} [parameters] - The configuration parameter. 32337 */ 32338 constructor(parameters = {}) { 32339 const { 32340 canvas = createCanvasElement(), 32341 context = null, 32342 depth = true, 32343 stencil = false, 32344 alpha = false, 32345 antialias = false, 32346 premultipliedAlpha = true, 32347 preserveDrawingBuffer = false, 32348 powerPreference = "default", 32349 failIfMajorPerformanceCaveat = false, 32350 reversedDepthBuffer = false, 32351 outputBufferType = UnsignedByteType 32352 } = parameters; 32353 this.isWebGLRenderer = true; 32354 let _alpha; 32355 if (context !== null) { 32356 if (typeof WebGLRenderingContext !== "undefined" && context instanceof WebGLRenderingContext) { 32357 throw new Error("THREE.WebGLRenderer: WebGL 1 is not supported since r163."); 32358 } 32359 _alpha = context.getContextAttributes().alpha; 32360 } else { 32361 _alpha = alpha; 32362 } 32363 const _outputBufferType = outputBufferType; 32364 const INTEGER_FORMATS = /* @__PURE__ */ new Set([ 32365 RGBAIntegerFormat, 32366 RGIntegerFormat, 32367 RedIntegerFormat 32368 ]); 32369 const UNSIGNED_TYPES = /* @__PURE__ */ new Set([ 32370 UnsignedByteType, 32371 UnsignedIntType, 32372 UnsignedShortType, 32373 UnsignedInt248Type, 32374 UnsignedShort4444Type, 32375 UnsignedShort5551Type 32376 ]); 32377 const uintClearColor = new Uint32Array(4); 32378 const intClearColor = new Int32Array(4); 32379 const objectPosition = new Vector3(); 32380 let currentRenderList = null; 32381 let currentRenderState = null; 32382 const renderListStack = []; 32383 const renderStateStack = []; 32384 let output = null; 32385 this.domElement = canvas; 32386 this.debug = { 32387 /** 32388 * Enables error checking and reporting when shader programs are being compiled. 32389 * @type {boolean} 32390 */ 32391 checkShaderErrors: true, 32392 /** 32393 * Callback for custom error reporting. 32394 * @type {?Function} 32395 */ 32396 onShaderError: null 32397 }; 32398 this.autoClear = true; 32399 this.autoClearColor = true; 32400 this.autoClearDepth = true; 32401 this.autoClearStencil = true; 32402 this.sortObjects = true; 32403 this.clippingPlanes = []; 32404 this.localClippingEnabled = false; 32405 this.toneMapping = NoToneMapping; 32406 this.toneMappingExposure = 1; 32407 this.transmissionResolutionScale = 1; 32408 const _this = this; 32409 let _isContextLost = false; 32410 let _nodesHandler = null; 32411 this._outputColorSpace = SRGBColorSpace; 32412 let _currentActiveCubeFace = 0; 32413 let _currentActiveMipmapLevel = 0; 32414 let _currentRenderTarget = null; 32415 let _currentMaterialId = -1; 32416 let _currentCamera = null; 32417 const _currentViewport = new Vector4(); 32418 const _currentScissor = new Vector4(); 32419 let _currentScissorTest = null; 32420 const _currentClearColor = new Color(0); 32421 let _currentClearAlpha = 0; 32422 let _width = canvas.width; 32423 let _height = canvas.height; 32424 let _pixelRatio = 1; 32425 let _opaqueSort = null; 32426 let _transparentSort = null; 32427 const _viewport = new Vector4(0, 0, _width, _height); 32428 const _scissor = new Vector4(0, 0, _width, _height); 32429 let _scissorTest = false; 32430 const _frustum = new Frustum(); 32431 let _clippingEnabled = false; 32432 let _localClippingEnabled = false; 32433 const _projScreenMatrix3 = new Matrix4(); 32434 const _vector3 = new Vector3(); 32435 const _vector42 = new Vector4(); 32436 const _emptyScene = { background: null, fog: null, environment: null, overrideMaterial: null, isScene: true }; 32437 let _renderBackground = false; 32438 function getTargetPixelRatio() { 32439 return _currentRenderTarget === null ? _pixelRatio : 1; 32440 } 32441 let _gl = context; 32442 function getContext(contextName, contextAttributes) { 32443 return canvas.getContext(contextName, contextAttributes); 32444 } 32445 try { 32446 const contextAttributes = { 32447 alpha: true, 32448 depth, 32449 stencil, 32450 antialias, 32451 premultipliedAlpha, 32452 preserveDrawingBuffer, 32453 powerPreference, 32454 failIfMajorPerformanceCaveat 32455 }; 32456 if ("setAttribute" in canvas) canvas.setAttribute("data-engine", `three.js r${REVISION}`); 32457 canvas.addEventListener("webglcontextlost", onContextLost, false); 32458 canvas.addEventListener("webglcontextrestored", onContextRestore, false); 32459 canvas.addEventListener("webglcontextcreationerror", onContextCreationError, false); 32460 if (_gl === null) { 32461 const contextName = "webgl2"; 32462 _gl = getContext(contextName, contextAttributes); 32463 if (_gl === null) { 32464 if (getContext(contextName)) { 32465 throw new Error("Error creating WebGL context with your selected attributes."); 32466 } else { 32467 throw new Error("Error creating WebGL context."); 32468 } 32469 } 32470 } 32471 } catch (e) { 32472 error("WebGLRenderer: " + e.message); 32473 throw e; 32474 } 32475 let extensions, capabilities, state, info; 32476 let properties, textures, environments, attributes, geometries, objects; 32477 let programCache, materials, renderLists, renderStates, clipping, shadowMap; 32478 let background, morphtargets, bufferRenderer, indexedBufferRenderer; 32479 let utils, bindingStates, uniformsGroups; 32480 function initGLContext() { 32481 extensions = new WebGLExtensions(_gl); 32482 extensions.init(); 32483 utils = new WebGLUtils(_gl, extensions); 32484 capabilities = new WebGLCapabilities(_gl, extensions, parameters, utils); 32485 state = new WebGLState(_gl, extensions); 32486 if (capabilities.reversedDepthBuffer && reversedDepthBuffer) { 32487 state.buffers.depth.setReversed(true); 32488 } 32489 info = new WebGLInfo(_gl); 32490 properties = new WebGLProperties(); 32491 textures = new WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info); 32492 environments = new WebGLEnvironments(_this); 32493 attributes = new WebGLAttributes(_gl); 32494 bindingStates = new WebGLBindingStates(_gl, attributes); 32495 geometries = new WebGLGeometries(_gl, attributes, info, bindingStates); 32496 objects = new WebGLObjects(_gl, geometries, attributes, bindingStates, info); 32497 morphtargets = new WebGLMorphtargets(_gl, capabilities, textures); 32498 clipping = new WebGLClipping(properties); 32499 programCache = new WebGLPrograms(_this, environments, extensions, capabilities, bindingStates, clipping); 32500 materials = new WebGLMaterials(_this, properties); 32501 renderLists = new WebGLRenderLists(); 32502 renderStates = new WebGLRenderStates(extensions); 32503 background = new WebGLBackground(_this, environments, state, objects, _alpha, premultipliedAlpha); 32504 shadowMap = new WebGLShadowMap(_this, objects, capabilities); 32505 uniformsGroups = new WebGLUniformsGroups(_gl, info, capabilities, state); 32506 bufferRenderer = new WebGLBufferRenderer(_gl, extensions, info); 32507 indexedBufferRenderer = new WebGLIndexedBufferRenderer(_gl, extensions, info); 32508 info.programs = programCache.programs; 32509 _this.capabilities = capabilities; 32510 _this.extensions = extensions; 32511 _this.properties = properties; 32512 _this.renderLists = renderLists; 32513 _this.shadowMap = shadowMap; 32514 _this.state = state; 32515 _this.info = info; 32516 } 32517 initGLContext(); 32518 if (_outputBufferType !== UnsignedByteType) { 32519 output = new WebGLOutput(_outputBufferType, canvas.width, canvas.height, depth, stencil); 32520 } 32521 const xr = new WebXRManager(_this, _gl); 32522 this.xr = xr; 32523 this.getContext = function() { 32524 return _gl; 32525 }; 32526 this.getContextAttributes = function() { 32527 return _gl.getContextAttributes(); 32528 }; 32529 this.forceContextLoss = function() { 32530 const extension = extensions.get("WEBGL_lose_context"); 32531 if (extension) extension.loseContext(); 32532 }; 32533 this.forceContextRestore = function() { 32534 const extension = extensions.get("WEBGL_lose_context"); 32535 if (extension) extension.restoreContext(); 32536 }; 32537 this.getPixelRatio = function() { 32538 return _pixelRatio; 32539 }; 32540 this.setPixelRatio = function(value) { 32541 if (value === void 0) return; 32542 _pixelRatio = value; 32543 this.setSize(_width, _height, false); 32544 }; 32545 this.getSize = function(target) { 32546 return target.set(_width, _height); 32547 }; 32548 this.setSize = function(width, height, updateStyle = true) { 32549 if (xr.isPresenting) { 32550 warn("WebGLRenderer: Can't change size while VR device is presenting."); 32551 return; 32552 } 32553 _width = width; 32554 _height = height; 32555 canvas.width = Math.floor(width * _pixelRatio); 32556 canvas.height = Math.floor(height * _pixelRatio); 32557 if (updateStyle === true) { 32558 canvas.style.width = width + "px"; 32559 canvas.style.height = height + "px"; 32560 } 32561 if (output !== null) { 32562 output.setSize(canvas.width, canvas.height); 32563 } 32564 this.setViewport(0, 0, width, height); 32565 }; 32566 this.getDrawingBufferSize = function(target) { 32567 return target.set(_width * _pixelRatio, _height * _pixelRatio).floor(); 32568 }; 32569 this.setDrawingBufferSize = function(width, height, pixelRatio) { 32570 _width = width; 32571 _height = height; 32572 _pixelRatio = pixelRatio; 32573 canvas.width = Math.floor(width * pixelRatio); 32574 canvas.height = Math.floor(height * pixelRatio); 32575 this.setViewport(0, 0, width, height); 32576 }; 32577 this.setEffects = function(effects) { 32578 if (_outputBufferType === UnsignedByteType) { 32579 error("THREE.WebGLRenderer: setEffects() requires outputBufferType set to HalfFloatType or FloatType."); 32580 return; 32581 } 32582 if (effects) { 32583 for (let i = 0; i < effects.length; i++) { 32584 if (effects[i].isOutputPass === true) { 32585 warn("THREE.WebGLRenderer: OutputPass is not needed in setEffects(). Tone mapping and color space conversion are applied automatically."); 32586 break; 32587 } 32588 } 32589 } 32590 output.setEffects(effects || []); 32591 }; 32592 this.getCurrentViewport = function(target) { 32593 return target.copy(_currentViewport); 32594 }; 32595 this.getViewport = function(target) { 32596 return target.copy(_viewport); 32597 }; 32598 this.setViewport = function(x, y, width, height) { 32599 if (x.isVector4) { 32600 _viewport.set(x.x, x.y, x.z, x.w); 32601 } else { 32602 _viewport.set(x, y, width, height); 32603 } 32604 state.viewport(_currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).round()); 32605 }; 32606 this.getScissor = function(target) { 32607 return target.copy(_scissor); 32608 }; 32609 this.setScissor = function(x, y, width, height) { 32610 if (x.isVector4) { 32611 _scissor.set(x.x, x.y, x.z, x.w); 32612 } else { 32613 _scissor.set(x, y, width, height); 32614 } 32615 state.scissor(_currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).round()); 32616 }; 32617 this.getScissorTest = function() { 32618 return _scissorTest; 32619 }; 32620 this.setScissorTest = function(boolean) { 32621 state.setScissorTest(_scissorTest = boolean); 32622 }; 32623 this.setOpaqueSort = function(method) { 32624 _opaqueSort = method; 32625 }; 32626 this.setTransparentSort = function(method) { 32627 _transparentSort = method; 32628 }; 32629 this.getClearColor = function(target) { 32630 return target.copy(background.getClearColor()); 32631 }; 32632 this.setClearColor = function() { 32633 background.setClearColor(...arguments); 32634 }; 32635 this.getClearAlpha = function() { 32636 return background.getClearAlpha(); 32637 }; 32638 this.setClearAlpha = function() { 32639 background.setClearAlpha(...arguments); 32640 }; 32641 this.clear = function(color = true, depth2 = true, stencil2 = true) { 32642 let bits = 0; 32643 if (color) { 32644 let isIntegerFormat = false; 32645 if (_currentRenderTarget !== null) { 32646 const targetFormat = _currentRenderTarget.texture.format; 32647 isIntegerFormat = INTEGER_FORMATS.has(targetFormat); 32648 } 32649 if (isIntegerFormat) { 32650 const targetType = _currentRenderTarget.texture.type; 32651 const isUnsignedType = UNSIGNED_TYPES.has(targetType); 32652 const clearColor = background.getClearColor(); 32653 const a = background.getClearAlpha(); 32654 const r = clearColor.r; 32655 const g = clearColor.g; 32656 const b = clearColor.b; 32657 if (isUnsignedType) { 32658 uintClearColor[0] = r; 32659 uintClearColor[1] = g; 32660 uintClearColor[2] = b; 32661 uintClearColor[3] = a; 32662 _gl.clearBufferuiv(_gl.COLOR, 0, uintClearColor); 32663 } else { 32664 intClearColor[0] = r; 32665 intClearColor[1] = g; 32666 intClearColor[2] = b; 32667 intClearColor[3] = a; 32668 _gl.clearBufferiv(_gl.COLOR, 0, intClearColor); 32669 } 32670 } else { 32671 bits |= _gl.COLOR_BUFFER_BIT; 32672 } 32673 } 32674 if (depth2) { 32675 bits |= _gl.DEPTH_BUFFER_BIT; 32676 this.state.buffers.depth.setMask(true); 32677 } 32678 if (stencil2) { 32679 bits |= _gl.STENCIL_BUFFER_BIT; 32680 this.state.buffers.stencil.setMask(4294967295); 32681 } 32682 if (bits !== 0) { 32683 _gl.clear(bits); 32684 } 32685 }; 32686 this.clearColor = function() { 32687 this.clear(true, false, false); 32688 }; 32689 this.clearDepth = function() { 32690 this.clear(false, true, false); 32691 }; 32692 this.clearStencil = function() { 32693 this.clear(false, false, true); 32694 }; 32695 this.setNodesHandler = function(nodesHandler) { 32696 nodesHandler.setRenderer(this); 32697 _nodesHandler = nodesHandler; 32698 }; 32699 this.dispose = function() { 32700 canvas.removeEventListener("webglcontextlost", onContextLost, false); 32701 canvas.removeEventListener("webglcontextrestored", onContextRestore, false); 32702 canvas.removeEventListener("webglcontextcreationerror", onContextCreationError, false); 32703 background.dispose(); 32704 renderLists.dispose(); 32705 renderStates.dispose(); 32706 properties.dispose(); 32707 environments.dispose(); 32708 objects.dispose(); 32709 bindingStates.dispose(); 32710 uniformsGroups.dispose(); 32711 programCache.dispose(); 32712 xr.dispose(); 32713 xr.removeEventListener("sessionstart", onXRSessionStart); 32714 xr.removeEventListener("sessionend", onXRSessionEnd); 32715 animation.stop(); 32716 }; 32717 function onContextLost(event) { 32718 event.preventDefault(); 32719 log("WebGLRenderer: Context Lost."); 32720 _isContextLost = true; 32721 } 32722 function onContextRestore() { 32723 log("WebGLRenderer: Context Restored."); 32724 _isContextLost = false; 32725 const infoAutoReset = info.autoReset; 32726 const shadowMapEnabled = shadowMap.enabled; 32727 const shadowMapAutoUpdate = shadowMap.autoUpdate; 32728 const shadowMapNeedsUpdate = shadowMap.needsUpdate; 32729 const shadowMapType = shadowMap.type; 32730 initGLContext(); 32731 info.autoReset = infoAutoReset; 32732 shadowMap.enabled = shadowMapEnabled; 32733 shadowMap.autoUpdate = shadowMapAutoUpdate; 32734 shadowMap.needsUpdate = shadowMapNeedsUpdate; 32735 shadowMap.type = shadowMapType; 32736 } 32737 function onContextCreationError(event) { 32738 error("WebGLRenderer: A WebGL context could not be created. Reason: ", event.statusMessage); 32739 } 32740 function onMaterialDispose(event) { 32741 const material = event.target; 32742 material.removeEventListener("dispose", onMaterialDispose); 32743 deallocateMaterial(material); 32744 } 32745 function deallocateMaterial(material) { 32746 releaseMaterialProgramReferences(material); 32747 properties.remove(material); 32748 } 32749 function releaseMaterialProgramReferences(material) { 32750 const programs = properties.get(material).programs; 32751 if (programs !== void 0) { 32752 programs.forEach(function(program) { 32753 programCache.releaseProgram(program); 32754 }); 32755 if (material.isShaderMaterial) { 32756 programCache.releaseShaderCache(material); 32757 } 32758 } 32759 } 32760 this.renderBufferDirect = function(camera, scene, geometry, material, object, group) { 32761 if (scene === null) scene = _emptyScene; 32762 const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0; 32763 const program = setProgram(camera, scene, geometry, material, object); 32764 state.setMaterial(material, frontFaceCW); 32765 let index = geometry.index; 32766 let rangeFactor = 1; 32767 if (material.wireframe === true) { 32768 index = geometries.getWireframeAttribute(geometry); 32769 if (index === void 0) return; 32770 rangeFactor = 2; 32771 } 32772 const drawRange = geometry.drawRange; 32773 const position = geometry.attributes.position; 32774 let drawStart = drawRange.start * rangeFactor; 32775 let drawEnd = (drawRange.start + drawRange.count) * rangeFactor; 32776 if (group !== null) { 32777 drawStart = Math.max(drawStart, group.start * rangeFactor); 32778 drawEnd = Math.min(drawEnd, (group.start + group.count) * rangeFactor); 32779 } 32780 if (index !== null) { 32781 drawStart = Math.max(drawStart, 0); 32782 drawEnd = Math.min(drawEnd, index.count); 32783 } else if (position !== void 0 && position !== null) { 32784 drawStart = Math.max(drawStart, 0); 32785 drawEnd = Math.min(drawEnd, position.count); 32786 } 32787 const drawCount = drawEnd - drawStart; 32788 if (drawCount < 0 || drawCount === Infinity) return; 32789 bindingStates.setup(object, material, program, geometry, index); 32790 let attribute; 32791 let renderer = bufferRenderer; 32792 if (index !== null) { 32793 attribute = attributes.get(index); 32794 renderer = indexedBufferRenderer; 32795 renderer.setIndex(attribute); 32796 } 32797 if (object.isMesh) { 32798 if (material.wireframe === true) { 32799 state.setLineWidth(material.wireframeLinewidth * getTargetPixelRatio()); 32800 renderer.setMode(_gl.LINES); 32801 } else { 32802 renderer.setMode(_gl.TRIANGLES); 32803 } 32804 } else if (object.isLine) { 32805 let lineWidth = material.linewidth; 32806 if (lineWidth === void 0) lineWidth = 1; 32807 state.setLineWidth(lineWidth * getTargetPixelRatio()); 32808 if (object.isLineSegments) { 32809 renderer.setMode(_gl.LINES); 32810 } else if (object.isLineLoop) { 32811 renderer.setMode(_gl.LINE_LOOP); 32812 } else { 32813 renderer.setMode(_gl.LINE_STRIP); 32814 } 32815 } else if (object.isPoints) { 32816 renderer.setMode(_gl.POINTS); 32817 } else if (object.isSprite) { 32818 renderer.setMode(_gl.TRIANGLES); 32819 } 32820 if (object.isBatchedMesh) { 32821 if (!extensions.get("WEBGL_multi_draw")) { 32822 const starts = object._multiDrawStarts; 32823 const counts = object._multiDrawCounts; 32824 const drawCount2 = object._multiDrawCount; 32825 const bytesPerElement = index ? attributes.get(index).bytesPerElement : 1; 32826 const uniforms = properties.get(material).currentProgram.getUniforms(); 32827 for (let i = 0; i < drawCount2; i++) { 32828 uniforms.setValue(_gl, "_gl_DrawID", i); 32829 renderer.render(starts[i] / bytesPerElement, counts[i]); 32830 } 32831 } else { 32832 renderer.renderMultiDraw(object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount); 32833 } 32834 } else if (object.isInstancedMesh) { 32835 renderer.renderInstances(drawStart, drawCount, object.count); 32836 } else if (geometry.isInstancedBufferGeometry) { 32837 const maxInstanceCount = geometry._maxInstanceCount !== void 0 ? geometry._maxInstanceCount : Infinity; 32838 const instanceCount = Math.min(geometry.instanceCount, maxInstanceCount); 32839 renderer.renderInstances(drawStart, drawCount, instanceCount); 32840 } else { 32841 renderer.render(drawStart, drawCount); 32842 } 32843 }; 32844 function prepareMaterial(material, scene, object) { 32845 if (material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false) { 32846 material.side = BackSide; 32847 material.needsUpdate = true; 32848 getProgram(material, scene, object); 32849 material.side = FrontSide; 32850 material.needsUpdate = true; 32851 getProgram(material, scene, object); 32852 material.side = DoubleSide; 32853 } else { 32854 getProgram(material, scene, object); 32855 } 32856 } 32857 this.compile = function(scene, camera, targetScene = null) { 32858 if (targetScene === null) targetScene = scene; 32859 currentRenderState = renderStates.get(targetScene); 32860 currentRenderState.init(camera); 32861 renderStateStack.push(currentRenderState); 32862 targetScene.traverseVisible(function(object) { 32863 if (object.isLight && object.layers.test(camera.layers)) { 32864 currentRenderState.pushLight(object); 32865 if (object.castShadow) { 32866 currentRenderState.pushShadow(object); 32867 } 32868 } 32869 }); 32870 if (scene !== targetScene) { 32871 scene.traverseVisible(function(object) { 32872 if (object.isLight && object.layers.test(camera.layers)) { 32873 currentRenderState.pushLight(object); 32874 if (object.castShadow) { 32875 currentRenderState.pushShadow(object); 32876 } 32877 } 32878 }); 32879 } 32880 currentRenderState.setupLights(); 32881 const materials2 = /* @__PURE__ */ new Set(); 32882 scene.traverse(function(object) { 32883 if (!(object.isMesh || object.isPoints || object.isLine || object.isSprite)) { 32884 return; 32885 } 32886 const material = object.material; 32887 if (material) { 32888 if (Array.isArray(material)) { 32889 for (let i = 0; i < material.length; i++) { 32890 const material2 = material[i]; 32891 prepareMaterial(material2, targetScene, object); 32892 materials2.add(material2); 32893 } 32894 } else { 32895 prepareMaterial(material, targetScene, object); 32896 materials2.add(material); 32897 } 32898 } 32899 }); 32900 currentRenderState = renderStateStack.pop(); 32901 return materials2; 32902 }; 32903 this.compileAsync = function(scene, camera, targetScene = null) { 32904 const materials2 = this.compile(scene, camera, targetScene); 32905 return new Promise((resolve) => { 32906 function checkMaterialsReady() { 32907 materials2.forEach(function(material) { 32908 const materialProperties = properties.get(material); 32909 const program = materialProperties.currentProgram; 32910 if (program.isReady()) { 32911 materials2.delete(material); 32912 } 32913 }); 32914 if (materials2.size === 0) { 32915 resolve(scene); 32916 return; 32917 } 32918 setTimeout(checkMaterialsReady, 10); 32919 } 32920 if (extensions.get("KHR_parallel_shader_compile") !== null) { 32921 checkMaterialsReady(); 32922 } else { 32923 setTimeout(checkMaterialsReady, 10); 32924 } 32925 }); 32926 }; 32927 let onAnimationFrameCallback = null; 32928 function onAnimationFrame(time) { 32929 if (onAnimationFrameCallback) onAnimationFrameCallback(time); 32930 } 32931 function onXRSessionStart() { 32932 animation.stop(); 32933 } 32934 function onXRSessionEnd() { 32935 animation.start(); 32936 } 32937 const animation = new WebGLAnimation(); 32938 animation.setAnimationLoop(onAnimationFrame); 32939 if (typeof self !== "undefined") animation.setContext(self); 32940 this.setAnimationLoop = function(callback) { 32941 onAnimationFrameCallback = callback; 32942 xr.setAnimationLoop(callback); 32943 callback === null ? animation.stop() : animation.start(); 32944 }; 32945 xr.addEventListener("sessionstart", onXRSessionStart); 32946 xr.addEventListener("sessionend", onXRSessionEnd); 32947 this.render = function(scene, camera) { 32948 if (camera !== void 0 && camera.isCamera !== true) { 32949 error("WebGLRenderer.render: camera is not an instance of THREE.Camera."); 32950 return; 32951 } 32952 if (_isContextLost === true) return; 32953 if (_nodesHandler !== null) { 32954 _nodesHandler.renderStart(scene, camera); 32955 } 32956 const isXRPresenting = xr.enabled === true && xr.isPresenting === true; 32957 const useOutput = output !== null && (_currentRenderTarget === null || isXRPresenting) && output.begin(_this, _currentRenderTarget); 32958 if (scene.matrixWorldAutoUpdate === true) scene.updateMatrixWorld(); 32959 if (camera.parent === null && camera.matrixWorldAutoUpdate === true) camera.updateMatrixWorld(); 32960 if (xr.enabled === true && xr.isPresenting === true && (output === null || output.isCompositing() === false)) { 32961 if (xr.cameraAutoUpdate === true) xr.updateCamera(camera); 32962 camera = xr.getCamera(); 32963 } 32964 if (scene.isScene === true) scene.onBeforeRender(_this, scene, camera, _currentRenderTarget); 32965 currentRenderState = renderStates.get(scene, renderStateStack.length); 32966 currentRenderState.init(camera); 32967 currentRenderState.state.textureUnits = textures.getTextureUnits(); 32968 renderStateStack.push(currentRenderState); 32969 _projScreenMatrix3.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); 32970 _frustum.setFromProjectionMatrix(_projScreenMatrix3, WebGLCoordinateSystem, camera.reversedDepth); 32971 _localClippingEnabled = this.localClippingEnabled; 32972 _clippingEnabled = clipping.init(this.clippingPlanes, _localClippingEnabled); 32973 currentRenderList = renderLists.get(scene, renderListStack.length); 32974 currentRenderList.init(); 32975 renderListStack.push(currentRenderList); 32976 if (xr.enabled === true && xr.isPresenting === true) { 32977 const depthSensingMesh = _this.xr.getDepthSensingMesh(); 32978 if (depthSensingMesh !== null) { 32979 projectObject(depthSensingMesh, camera, -Infinity, _this.sortObjects); 32980 } 32981 } 32982 projectObject(scene, camera, 0, _this.sortObjects); 32983 currentRenderList.finish(); 32984 if (_this.sortObjects === true) { 32985 currentRenderList.sort(_opaqueSort, _transparentSort); 32986 } 32987 _renderBackground = xr.enabled === false || xr.isPresenting === false || xr.hasDepthSensing() === false; 32988 if (_renderBackground) { 32989 background.addToRenderList(currentRenderList, scene); 32990 } 32991 this.info.render.frame++; 32992 if (_clippingEnabled === true) clipping.beginShadows(); 32993 const shadowsArray = currentRenderState.state.shadowsArray; 32994 shadowMap.render(shadowsArray, scene, camera); 32995 if (_clippingEnabled === true) clipping.endShadows(); 32996 if (this.info.autoReset === true) this.info.reset(); 32997 const skipSceneRender = useOutput && output.hasRenderPass(); 32998 if (skipSceneRender === false) { 32999 const opaqueObjects = currentRenderList.opaque; 33000 const transmissiveObjects = currentRenderList.transmissive; 33001 currentRenderState.setupLights(); 33002 if (camera.isArrayCamera) { 33003 const cameras = camera.cameras; 33004 if (transmissiveObjects.length > 0) { 33005 for (let i = 0, l = cameras.length; i < l; i++) { 33006 const camera2 = cameras[i]; 33007 renderTransmissionPass(opaqueObjects, transmissiveObjects, scene, camera2); 33008 } 33009 } 33010 if (_renderBackground) background.render(scene); 33011 for (let i = 0, l = cameras.length; i < l; i++) { 33012 const camera2 = cameras[i]; 33013 renderScene(currentRenderList, scene, camera2, camera2.viewport); 33014 } 33015 } else { 33016 if (transmissiveObjects.length > 0) renderTransmissionPass(opaqueObjects, transmissiveObjects, scene, camera); 33017 if (_renderBackground) background.render(scene); 33018 renderScene(currentRenderList, scene, camera); 33019 } 33020 } 33021 if (_currentRenderTarget !== null && _currentActiveMipmapLevel === 0) { 33022 textures.updateMultisampleRenderTarget(_currentRenderTarget); 33023 textures.updateRenderTargetMipmap(_currentRenderTarget); 33024 } 33025 if (useOutput) { 33026 output.end(_this); 33027 } 33028 if (scene.isScene === true) scene.onAfterRender(_this, scene, camera); 33029 bindingStates.resetDefaultState(); 33030 _currentMaterialId = -1; 33031 _currentCamera = null; 33032 renderStateStack.pop(); 33033 if (renderStateStack.length > 0) { 33034 currentRenderState = renderStateStack[renderStateStack.length - 1]; 33035 textures.setTextureUnits(currentRenderState.state.textureUnits); 33036 if (_clippingEnabled === true) clipping.setGlobalState(_this.clippingPlanes, currentRenderState.state.camera); 33037 } else { 33038 currentRenderState = null; 33039 } 33040 renderListStack.pop(); 33041 if (renderListStack.length > 0) { 33042 currentRenderList = renderListStack[renderListStack.length - 1]; 33043 } else { 33044 currentRenderList = null; 33045 } 33046 if (_nodesHandler !== null) { 33047 _nodesHandler.renderEnd(); 33048 } 33049 }; 33050 function projectObject(object, camera, groupOrder, sortObjects) { 33051 if (object.visible === false) return; 33052 const visible = object.layers.test(camera.layers); 33053 if (visible) { 33054 if (object.isGroup) { 33055 groupOrder = object.renderOrder; 33056 } else if (object.isLOD) { 33057 if (object.autoUpdate === true) object.update(camera); 33058 } else if (object.isLightProbeGrid) { 33059 currentRenderState.pushLightProbeGrid(object); 33060 } else if (object.isLight) { 33061 currentRenderState.pushLight(object); 33062 if (object.castShadow) { 33063 currentRenderState.pushShadow(object); 33064 } 33065 } else if (object.isSprite) { 33066 if (!object.frustumCulled || _frustum.intersectsSprite(object)) { 33067 if (sortObjects) { 33068 _vector42.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix3); 33069 } 33070 const geometry = objects.update(object); 33071 const material = object.material; 33072 if (material.visible) { 33073 currentRenderList.push(object, geometry, material, groupOrder, _vector42.z, null); 33074 } 33075 } 33076 } else if (object.isMesh || object.isLine || object.isPoints) { 33077 if (!object.frustumCulled || _frustum.intersectsObject(object)) { 33078 const geometry = objects.update(object); 33079 const material = object.material; 33080 if (sortObjects) { 33081 if (object.boundingSphere !== void 0) { 33082 if (object.boundingSphere === null) object.computeBoundingSphere(); 33083 _vector42.copy(object.boundingSphere.center); 33084 } else { 33085 if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); 33086 _vector42.copy(geometry.boundingSphere.center); 33087 } 33088 _vector42.applyMatrix4(object.matrixWorld).applyMatrix4(_projScreenMatrix3); 33089 } 33090 if (Array.isArray(material)) { 33091 const groups = geometry.groups; 33092 for (let i = 0, l = groups.length; i < l; i++) { 33093 const group = groups[i]; 33094 const groupMaterial = material[group.materialIndex]; 33095 if (groupMaterial && groupMaterial.visible) { 33096 currentRenderList.push(object, geometry, groupMaterial, groupOrder, _vector42.z, group); 33097 } 33098 } 33099 } else if (material.visible) { 33100 currentRenderList.push(object, geometry, material, groupOrder, _vector42.z, null); 33101 } 33102 } 33103 } 33104 } 33105 const children2 = object.children; 33106 for (let i = 0, l = children2.length; i < l; i++) { 33107 projectObject(children2[i], camera, groupOrder, sortObjects); 33108 } 33109 } 33110 function renderScene(currentRenderList2, scene, camera, viewport) { 33111 const { opaque: opaqueObjects, transmissive: transmissiveObjects, transparent: transparentObjects } = currentRenderList2; 33112 currentRenderState.setupLightsView(camera); 33113 if (_clippingEnabled === true) clipping.setGlobalState(_this.clippingPlanes, camera); 33114 if (viewport) state.viewport(_currentViewport.copy(viewport)); 33115 if (opaqueObjects.length > 0) renderObjects(opaqueObjects, scene, camera); 33116 if (transmissiveObjects.length > 0) renderObjects(transmissiveObjects, scene, camera); 33117 if (transparentObjects.length > 0) renderObjects(transparentObjects, scene, camera); 33118 state.buffers.depth.setTest(true); 33119 state.buffers.depth.setMask(true); 33120 state.buffers.color.setMask(true); 33121 state.setPolygonOffset(false); 33122 } 33123 function renderTransmissionPass(opaqueObjects, transmissiveObjects, scene, camera) { 33124 const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null; 33125 if (overrideMaterial !== null) { 33126 return; 33127 } 33128 if (currentRenderState.state.transmissionRenderTarget[camera.id] === void 0) { 33129 const hasHalfFloatSupport = extensions.has("EXT_color_buffer_half_float") || extensions.has("EXT_color_buffer_float"); 33130 currentRenderState.state.transmissionRenderTarget[camera.id] = new WebGLRenderTarget(1, 1, { 33131 generateMipmaps: true, 33132 type: hasHalfFloatSupport ? HalfFloatType : UnsignedByteType, 33133 minFilter: LinearMipmapLinearFilter, 33134 samples: Math.max(4, capabilities.samples), 33135 // to avoid feedback loops, the transmission render target requires a resolve, see #26177 33136 stencilBuffer: stencil, 33137 resolveDepthBuffer: false, 33138 resolveStencilBuffer: false, 33139 colorSpace: ColorManagement.workingColorSpace 33140 }); 33141 } 33142 const transmissionRenderTarget = currentRenderState.state.transmissionRenderTarget[camera.id]; 33143 const activeViewport = camera.viewport || _currentViewport; 33144 transmissionRenderTarget.setSize(activeViewport.z * _this.transmissionResolutionScale, activeViewport.w * _this.transmissionResolutionScale); 33145 const currentRenderTarget = _this.getRenderTarget(); 33146 const currentActiveCubeFace = _this.getActiveCubeFace(); 33147 const currentActiveMipmapLevel = _this.getActiveMipmapLevel(); 33148 _this.setRenderTarget(transmissionRenderTarget); 33149 _this.getClearColor(_currentClearColor); 33150 _currentClearAlpha = _this.getClearAlpha(); 33151 if (_currentClearAlpha < 1) _this.setClearColor(16777215, 0.5); 33152 _this.clear(); 33153 if (_renderBackground) background.render(scene); 33154 const currentToneMapping = _this.toneMapping; 33155 _this.toneMapping = NoToneMapping; 33156 const currentCameraViewport = camera.viewport; 33157 if (camera.viewport !== void 0) camera.viewport = void 0; 33158 currentRenderState.setupLightsView(camera); 33159 if (_clippingEnabled === true) clipping.setGlobalState(_this.clippingPlanes, camera); 33160 renderObjects(opaqueObjects, scene, camera); 33161 textures.updateMultisampleRenderTarget(transmissionRenderTarget); 33162 textures.updateRenderTargetMipmap(transmissionRenderTarget); 33163 if (extensions.has("WEBGL_multisampled_render_to_texture") === false) { 33164 let renderTargetNeedsUpdate = false; 33165 for (let i = 0, l = transmissiveObjects.length; i < l; i++) { 33166 const renderItem = transmissiveObjects[i]; 33167 const { object, geometry, material, group } = renderItem; 33168 if (material.side === DoubleSide && object.layers.test(camera.layers)) { 33169 const currentSide = material.side; 33170 material.side = BackSide; 33171 material.needsUpdate = true; 33172 renderObject(object, scene, camera, geometry, material, group); 33173 material.side = currentSide; 33174 material.needsUpdate = true; 33175 renderTargetNeedsUpdate = true; 33176 } 33177 } 33178 if (renderTargetNeedsUpdate === true) { 33179 textures.updateMultisampleRenderTarget(transmissionRenderTarget); 33180 textures.updateRenderTargetMipmap(transmissionRenderTarget); 33181 } 33182 } 33183 _this.setRenderTarget(currentRenderTarget, currentActiveCubeFace, currentActiveMipmapLevel); 33184 _this.setClearColor(_currentClearColor, _currentClearAlpha); 33185 if (currentCameraViewport !== void 0) camera.viewport = currentCameraViewport; 33186 _this.toneMapping = currentToneMapping; 33187 } 33188 function renderObjects(renderList, scene, camera) { 33189 const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null; 33190 for (let i = 0, l = renderList.length; i < l; i++) { 33191 const renderItem = renderList[i]; 33192 const { object, geometry, group } = renderItem; 33193 let material = renderItem.material; 33194 if (material.allowOverride === true && overrideMaterial !== null) { 33195 material = overrideMaterial; 33196 } 33197 if (object.layers.test(camera.layers)) { 33198 renderObject(object, scene, camera, geometry, material, group); 33199 } 33200 } 33201 } 33202 function renderObject(object, scene, camera, geometry, material, group) { 33203 object.onBeforeRender(_this, scene, camera, geometry, material, group); 33204 object.modelViewMatrix.multiplyMatrices(camera.matrixWorldInverse, object.matrixWorld); 33205 object.normalMatrix.getNormalMatrix(object.modelViewMatrix); 33206 material.onBeforeRender(_this, scene, camera, geometry, object, group); 33207 if (material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false) { 33208 material.side = BackSide; 33209 material.needsUpdate = true; 33210 _this.renderBufferDirect(camera, scene, geometry, material, object, group); 33211 material.side = FrontSide; 33212 material.needsUpdate = true; 33213 _this.renderBufferDirect(camera, scene, geometry, material, object, group); 33214 material.side = DoubleSide; 33215 } else { 33216 _this.renderBufferDirect(camera, scene, geometry, material, object, group); 33217 } 33218 object.onAfterRender(_this, scene, camera, geometry, material, group); 33219 } 33220 function getProgram(material, scene, object) { 33221 if (scene.isScene !== true) scene = _emptyScene; 33222 const materialProperties = properties.get(material); 33223 const lights = currentRenderState.state.lights; 33224 const shadowsArray = currentRenderState.state.shadowsArray; 33225 const lightsStateVersion = lights.state.version; 33226 const parameters2 = programCache.getParameters(material, lights.state, shadowsArray, scene, object, currentRenderState.state.lightProbeGridArray); 33227 const programCacheKey = programCache.getProgramCacheKey(parameters2); 33228 let programs = materialProperties.programs; 33229 materialProperties.environment = material.isMeshStandardMaterial || material.isMeshLambertMaterial || material.isMeshPhongMaterial ? scene.environment : null; 33230 materialProperties.fog = scene.fog; 33231 const usePMREM = material.isMeshStandardMaterial || material.isMeshLambertMaterial && !material.envMap || material.isMeshPhongMaterial && !material.envMap; 33232 materialProperties.envMap = environments.get(material.envMap || materialProperties.environment, usePMREM); 33233 materialProperties.envMapRotation = materialProperties.environment !== null && material.envMap === null ? scene.environmentRotation : material.envMapRotation; 33234 if (programs === void 0) { 33235 material.addEventListener("dispose", onMaterialDispose); 33236 programs = /* @__PURE__ */ new Map(); 33237 materialProperties.programs = programs; 33238 } 33239 let program = programs.get(programCacheKey); 33240 if (program !== void 0) { 33241 if (materialProperties.currentProgram === program && materialProperties.lightsStateVersion === lightsStateVersion) { 33242 updateCommonMaterialProperties(material, parameters2); 33243 return program; 33244 } 33245 } else { 33246 parameters2.uniforms = programCache.getUniforms(material); 33247 if (_nodesHandler !== null && material.isNodeMaterial) { 33248 _nodesHandler.build(material, object, parameters2); 33249 } 33250 material.onBeforeCompile(parameters2, _this); 33251 program = programCache.acquireProgram(parameters2, programCacheKey); 33252 programs.set(programCacheKey, program); 33253 materialProperties.uniforms = parameters2.uniforms; 33254 } 33255 const uniforms = materialProperties.uniforms; 33256 if (!material.isShaderMaterial && !material.isRawShaderMaterial || material.clipping === true) { 33257 uniforms.clippingPlanes = clipping.uniform; 33258 } 33259 updateCommonMaterialProperties(material, parameters2); 33260 materialProperties.needsLights = materialNeedsLights(material); 33261 materialProperties.lightsStateVersion = lightsStateVersion; 33262 if (materialProperties.needsLights) { 33263 uniforms.ambientLightColor.value = lights.state.ambient; 33264 uniforms.lightProbe.value = lights.state.probe; 33265 uniforms.directionalLights.value = lights.state.directional; 33266 uniforms.directionalLightShadows.value = lights.state.directionalShadow; 33267 uniforms.spotLights.value = lights.state.spot; 33268 uniforms.spotLightShadows.value = lights.state.spotShadow; 33269 uniforms.rectAreaLights.value = lights.state.rectArea; 33270 uniforms.ltc_1.value = lights.state.rectAreaLTC1; 33271 uniforms.ltc_2.value = lights.state.rectAreaLTC2; 33272 uniforms.pointLights.value = lights.state.point; 33273 uniforms.pointLightShadows.value = lights.state.pointShadow; 33274 uniforms.hemisphereLights.value = lights.state.hemi; 33275 uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix; 33276 uniforms.spotLightMatrix.value = lights.state.spotLightMatrix; 33277 uniforms.spotLightMap.value = lights.state.spotLightMap; 33278 uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; 33279 } 33280 materialProperties.lightProbeGrid = currentRenderState.state.lightProbeGridArray.length > 0; 33281 materialProperties.currentProgram = program; 33282 materialProperties.uniformsList = null; 33283 return program; 33284 } 33285 function getUniformList(materialProperties) { 33286 if (materialProperties.uniformsList === null) { 33287 const progUniforms = materialProperties.currentProgram.getUniforms(); 33288 materialProperties.uniformsList = WebGLUniforms.seqWithValue(progUniforms.seq, materialProperties.uniforms); 33289 } 33290 return materialProperties.uniformsList; 33291 } 33292 function updateCommonMaterialProperties(material, parameters2) { 33293 const materialProperties = properties.get(material); 33294 materialProperties.outputColorSpace = parameters2.outputColorSpace; 33295 materialProperties.batching = parameters2.batching; 33296 materialProperties.batchingColor = parameters2.batchingColor; 33297 materialProperties.instancing = parameters2.instancing; 33298 materialProperties.instancingColor = parameters2.instancingColor; 33299 materialProperties.instancingMorph = parameters2.instancingMorph; 33300 materialProperties.skinning = parameters2.skinning; 33301 materialProperties.morphTargets = parameters2.morphTargets; 33302 materialProperties.morphNormals = parameters2.morphNormals; 33303 materialProperties.morphColors = parameters2.morphColors; 33304 materialProperties.morphTargetsCount = parameters2.morphTargetsCount; 33305 materialProperties.numClippingPlanes = parameters2.numClippingPlanes; 33306 materialProperties.numIntersection = parameters2.numClipIntersection; 33307 materialProperties.vertexAlphas = parameters2.vertexAlphas; 33308 materialProperties.vertexTangents = parameters2.vertexTangents; 33309 materialProperties.toneMapping = parameters2.toneMapping; 33310 } 33311 function findLightProbeGrid(volumes, object) { 33312 if (volumes.length === 0) return null; 33313 if (volumes.length === 1) { 33314 return volumes[0].texture !== null ? volumes[0] : null; 33315 } 33316 objectPosition.setFromMatrixPosition(object.matrixWorld); 33317 for (let i = 0, l = volumes.length; i < l; i++) { 33318 const v = volumes[i]; 33319 if (v.texture !== null && v.boundingBox.containsPoint(objectPosition)) return v; 33320 } 33321 return null; 33322 } 33323 function setProgram(camera, scene, geometry, material, object) { 33324 if (scene.isScene !== true) scene = _emptyScene; 33325 textures.resetTextureUnits(); 33326 const fog = scene.fog; 33327 const environment = material.isMeshStandardMaterial || material.isMeshLambertMaterial || material.isMeshPhongMaterial ? scene.environment : null; 33328 const colorSpace = _currentRenderTarget === null ? _this.outputColorSpace : _currentRenderTarget.isXRRenderTarget === true ? _currentRenderTarget.texture.colorSpace : ColorManagement.workingColorSpace; 33329 const usePMREM = material.isMeshStandardMaterial || material.isMeshLambertMaterial && !material.envMap || material.isMeshPhongMaterial && !material.envMap; 33330 const envMap = environments.get(material.envMap || environment, usePMREM); 33331 const vertexAlphas = material.vertexColors === true && !!geometry.attributes.color && geometry.attributes.color.itemSize === 4; 33332 const vertexTangents = !!geometry.attributes.tangent && (!!material.normalMap || material.anisotropy > 0); 33333 const morphTargets = !!geometry.morphAttributes.position; 33334 const morphNormals = !!geometry.morphAttributes.normal; 33335 const morphColors = !!geometry.morphAttributes.color; 33336 let toneMapping = NoToneMapping; 33337 if (material.toneMapped) { 33338 if (_currentRenderTarget === null || _currentRenderTarget.isXRRenderTarget === true) { 33339 toneMapping = _this.toneMapping; 33340 } 33341 } 33342 const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; 33343 const morphTargetsCount = morphAttribute !== void 0 ? morphAttribute.length : 0; 33344 const materialProperties = properties.get(material); 33345 const lights = currentRenderState.state.lights; 33346 if (_clippingEnabled === true) { 33347 if (_localClippingEnabled === true || camera !== _currentCamera) { 33348 const useCache = camera === _currentCamera && material.id === _currentMaterialId; 33349 clipping.setState(material, camera, useCache); 33350 } 33351 } 33352 let needsProgramChange = false; 33353 if (material.version === materialProperties.__version) { 33354 if (materialProperties.needsLights && materialProperties.lightsStateVersion !== lights.state.version) { 33355 needsProgramChange = true; 33356 } else if (materialProperties.outputColorSpace !== colorSpace) { 33357 needsProgramChange = true; 33358 } else if (object.isBatchedMesh && materialProperties.batching === false) { 33359 needsProgramChange = true; 33360 } else if (!object.isBatchedMesh && materialProperties.batching === true) { 33361 needsProgramChange = true; 33362 } else if (object.isBatchedMesh && materialProperties.batchingColor === true && object.colorTexture === null) { 33363 needsProgramChange = true; 33364 } else if (object.isBatchedMesh && materialProperties.batchingColor === false && object.colorTexture !== null) { 33365 needsProgramChange = true; 33366 } else if (object.isInstancedMesh && materialProperties.instancing === false) { 33367 needsProgramChange = true; 33368 } else if (!object.isInstancedMesh && materialProperties.instancing === true) { 33369 needsProgramChange = true; 33370 } else if (object.isSkinnedMesh && materialProperties.skinning === false) { 33371 needsProgramChange = true; 33372 } else if (!object.isSkinnedMesh && materialProperties.skinning === true) { 33373 needsProgramChange = true; 33374 } else if (object.isInstancedMesh && materialProperties.instancingColor === true && object.instanceColor === null) { 33375 needsProgramChange = true; 33376 } else if (object.isInstancedMesh && materialProperties.instancingColor === false && object.instanceColor !== null) { 33377 needsProgramChange = true; 33378 } else if (object.isInstancedMesh && materialProperties.instancingMorph === true && object.morphTexture === null) { 33379 needsProgramChange = true; 33380 } else if (object.isInstancedMesh && materialProperties.instancingMorph === false && object.morphTexture !== null) { 33381 needsProgramChange = true; 33382 } else if (materialProperties.envMap !== envMap) { 33383 needsProgramChange = true; 33384 } else if (material.fog === true && materialProperties.fog !== fog) { 33385 needsProgramChange = true; 33386 } else if (materialProperties.numClippingPlanes !== void 0 && (materialProperties.numClippingPlanes !== clipping.numPlanes || materialProperties.numIntersection !== clipping.numIntersection)) { 33387 needsProgramChange = true; 33388 } else if (materialProperties.vertexAlphas !== vertexAlphas) { 33389 needsProgramChange = true; 33390 } else if (materialProperties.vertexTangents !== vertexTangents) { 33391 needsProgramChange = true; 33392 } else if (materialProperties.morphTargets !== morphTargets) { 33393 needsProgramChange = true; 33394 } else if (materialProperties.morphNormals !== morphNormals) { 33395 needsProgramChange = true; 33396 } else if (materialProperties.morphColors !== morphColors) { 33397 needsProgramChange = true; 33398 } else if (materialProperties.toneMapping !== toneMapping) { 33399 needsProgramChange = true; 33400 } else if (materialProperties.morphTargetsCount !== morphTargetsCount) { 33401 needsProgramChange = true; 33402 } else if (!!materialProperties.lightProbeGrid !== currentRenderState.state.lightProbeGridArray.length > 0) { 33403 needsProgramChange = true; 33404 } 33405 } else { 33406 needsProgramChange = true; 33407 materialProperties.__version = material.version; 33408 } 33409 let program = materialProperties.currentProgram; 33410 if (needsProgramChange === true) { 33411 program = getProgram(material, scene, object); 33412 if (_nodesHandler && material.isNodeMaterial) { 33413 _nodesHandler.onUpdateProgram(material, program, materialProperties); 33414 } 33415 } 33416 let refreshProgram = false; 33417 let refreshMaterial = false; 33418 let refreshLights = false; 33419 const p_uniforms = program.getUniforms(), m_uniforms = materialProperties.uniforms; 33420 if (state.useProgram(program.program)) { 33421 refreshProgram = true; 33422 refreshMaterial = true; 33423 refreshLights = true; 33424 } 33425 if (material.id !== _currentMaterialId) { 33426 _currentMaterialId = material.id; 33427 refreshMaterial = true; 33428 } 33429 if (materialProperties.needsLights) { 33430 const objectVolume = findLightProbeGrid(currentRenderState.state.lightProbeGridArray, object); 33431 if (materialProperties.lightProbeGrid !== objectVolume) { 33432 materialProperties.lightProbeGrid = objectVolume; 33433 refreshMaterial = true; 33434 } 33435 } 33436 if (refreshProgram || _currentCamera !== camera) { 33437 const reversedDepthBuffer2 = state.buffers.depth.getReversed(); 33438 if (reversedDepthBuffer2 && camera.reversedDepth !== true) { 33439 camera._reversedDepth = true; 33440 camera.updateProjectionMatrix(); 33441 } 33442 p_uniforms.setValue(_gl, "projectionMatrix", camera.projectionMatrix); 33443 p_uniforms.setValue(_gl, "viewMatrix", camera.matrixWorldInverse); 33444 const uCamPos = p_uniforms.map.cameraPosition; 33445 if (uCamPos !== void 0) { 33446 uCamPos.setValue(_gl, _vector3.setFromMatrixPosition(camera.matrixWorld)); 33447 } 33448 if (capabilities.logarithmicDepthBuffer) { 33449 p_uniforms.setValue( 33450 _gl, 33451 "logDepthBufFC", 33452 2 / (Math.log(camera.far + 1) / Math.LN2) 33453 ); 33454 } 33455 if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial) { 33456 p_uniforms.setValue(_gl, "isOrthographic", camera.isOrthographicCamera === true); 33457 } 33458 if (_currentCamera !== camera) { 33459 _currentCamera = camera; 33460 refreshMaterial = true; 33461 refreshLights = true; 33462 } 33463 } 33464 if (materialProperties.needsLights) { 33465 if (lights.state.directionalShadowMap.length > 0) { 33466 p_uniforms.setValue(_gl, "directionalShadowMap", lights.state.directionalShadowMap, textures); 33467 } 33468 if (lights.state.spotShadowMap.length > 0) { 33469 p_uniforms.setValue(_gl, "spotShadowMap", lights.state.spotShadowMap, textures); 33470 } 33471 if (lights.state.pointShadowMap.length > 0) { 33472 p_uniforms.setValue(_gl, "pointShadowMap", lights.state.pointShadowMap, textures); 33473 } 33474 } 33475 if (object.isSkinnedMesh) { 33476 p_uniforms.setOptional(_gl, object, "bindMatrix"); 33477 p_uniforms.setOptional(_gl, object, "bindMatrixInverse"); 33478 const skeleton = object.skeleton; 33479 if (skeleton) { 33480 if (skeleton.boneTexture === null) skeleton.computeBoneTexture(); 33481 p_uniforms.setValue(_gl, "boneTexture", skeleton.boneTexture, textures); 33482 } 33483 } 33484 if (object.isBatchedMesh) { 33485 p_uniforms.setOptional(_gl, object, "batchingTexture"); 33486 p_uniforms.setValue(_gl, "batchingTexture", object._matricesTexture, textures); 33487 p_uniforms.setOptional(_gl, object, "batchingIdTexture"); 33488 p_uniforms.setValue(_gl, "batchingIdTexture", object._indirectTexture, textures); 33489 p_uniforms.setOptional(_gl, object, "batchingColorTexture"); 33490 if (object._colorsTexture !== null) { 33491 p_uniforms.setValue(_gl, "batchingColorTexture", object._colorsTexture, textures); 33492 } 33493 } 33494 const morphAttributes = geometry.morphAttributes; 33495 if (morphAttributes.position !== void 0 || morphAttributes.normal !== void 0 || morphAttributes.color !== void 0) { 33496 morphtargets.update(object, geometry, program); 33497 } 33498 if (refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow) { 33499 materialProperties.receiveShadow = object.receiveShadow; 33500 p_uniforms.setValue(_gl, "receiveShadow", object.receiveShadow); 33501 } 33502 if ((material.isMeshStandardMaterial || material.isMeshLambertMaterial || material.isMeshPhongMaterial) && material.envMap === null && scene.environment !== null) { 33503 m_uniforms.envMapIntensity.value = scene.environmentIntensity; 33504 } 33505 if (m_uniforms.dfgLUT !== void 0) { 33506 m_uniforms.dfgLUT.value = getDFGLUT(); 33507 } 33508 if (refreshMaterial) { 33509 p_uniforms.setValue(_gl, "toneMappingExposure", _this.toneMappingExposure); 33510 if (materialProperties.needsLights) { 33511 markUniformsLightsNeedsUpdate(m_uniforms, refreshLights); 33512 } 33513 if (fog && material.fog === true) { 33514 materials.refreshFogUniforms(m_uniforms, fog); 33515 } 33516 materials.refreshMaterialUniforms(m_uniforms, material, _pixelRatio, _height, currentRenderState.state.transmissionRenderTarget[camera.id]); 33517 if (materialProperties.needsLights && materialProperties.lightProbeGrid) { 33518 const volume = materialProperties.lightProbeGrid; 33519 m_uniforms.probesSH.value = volume.texture; 33520 m_uniforms.probesMin.value.copy(volume.boundingBox.min); 33521 m_uniforms.probesMax.value.copy(volume.boundingBox.max); 33522 m_uniforms.probesResolution.value.copy(volume.resolution); 33523 } 33524 WebGLUniforms.upload(_gl, getUniformList(materialProperties), m_uniforms, textures); 33525 } 33526 if (material.isShaderMaterial && material.uniformsNeedUpdate === true) { 33527 WebGLUniforms.upload(_gl, getUniformList(materialProperties), m_uniforms, textures); 33528 material.uniformsNeedUpdate = false; 33529 } 33530 if (material.isSpriteMaterial) { 33531 p_uniforms.setValue(_gl, "center", object.center); 33532 } 33533 p_uniforms.setValue(_gl, "modelViewMatrix", object.modelViewMatrix); 33534 p_uniforms.setValue(_gl, "normalMatrix", object.normalMatrix); 33535 p_uniforms.setValue(_gl, "modelMatrix", object.matrixWorld); 33536 if (material.uniformsGroups !== void 0) { 33537 const groups = material.uniformsGroups; 33538 for (let i = 0, l = groups.length; i < l; i++) { 33539 const group = groups[i]; 33540 uniformsGroups.update(group, program); 33541 uniformsGroups.bind(group, program); 33542 } 33543 } 33544 return program; 33545 } 33546 function markUniformsLightsNeedsUpdate(uniforms, value) { 33547 uniforms.ambientLightColor.needsUpdate = value; 33548 uniforms.lightProbe.needsUpdate = value; 33549 uniforms.directionalLights.needsUpdate = value; 33550 uniforms.directionalLightShadows.needsUpdate = value; 33551 uniforms.pointLights.needsUpdate = value; 33552 uniforms.pointLightShadows.needsUpdate = value; 33553 uniforms.spotLights.needsUpdate = value; 33554 uniforms.spotLightShadows.needsUpdate = value; 33555 uniforms.rectAreaLights.needsUpdate = value; 33556 uniforms.hemisphereLights.needsUpdate = value; 33557 } 33558 function materialNeedsLights(material) { 33559 return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial || material.isShadowMaterial || material.isShaderMaterial && material.lights === true; 33560 } 33561 this.getActiveCubeFace = function() { 33562 return _currentActiveCubeFace; 33563 }; 33564 this.getActiveMipmapLevel = function() { 33565 return _currentActiveMipmapLevel; 33566 }; 33567 this.getRenderTarget = function() { 33568 return _currentRenderTarget; 33569 }; 33570 this.setRenderTargetTextures = function(renderTarget, colorTexture, depthTexture) { 33571 const renderTargetProperties = properties.get(renderTarget); 33572 renderTargetProperties.__autoAllocateDepthBuffer = renderTarget.resolveDepthBuffer === false; 33573 if (renderTargetProperties.__autoAllocateDepthBuffer === false) { 33574 renderTargetProperties.__useRenderToTexture = false; 33575 } 33576 properties.get(renderTarget.texture).__webglTexture = colorTexture; 33577 properties.get(renderTarget.depthTexture).__webglTexture = renderTargetProperties.__autoAllocateDepthBuffer ? void 0 : depthTexture; 33578 renderTargetProperties.__hasExternalTextures = true; 33579 }; 33580 this.setRenderTargetFramebuffer = function(renderTarget, defaultFramebuffer) { 33581 const renderTargetProperties = properties.get(renderTarget); 33582 renderTargetProperties.__webglFramebuffer = defaultFramebuffer; 33583 renderTargetProperties.__useDefaultFramebuffer = defaultFramebuffer === void 0; 33584 }; 33585 const _scratchFrameBuffer = _gl.createFramebuffer(); 33586 this.setRenderTarget = function(renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) { 33587 _currentRenderTarget = renderTarget; 33588 _currentActiveCubeFace = activeCubeFace; 33589 _currentActiveMipmapLevel = activeMipmapLevel; 33590 let framebuffer = null; 33591 let isCube = false; 33592 let isRenderTarget3D = false; 33593 if (renderTarget) { 33594 const renderTargetProperties = properties.get(renderTarget); 33595 if (renderTargetProperties.__useDefaultFramebuffer !== void 0) { 33596 state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); 33597 _currentViewport.copy(renderTarget.viewport); 33598 _currentScissor.copy(renderTarget.scissor); 33599 _currentScissorTest = renderTarget.scissorTest; 33600 state.viewport(_currentViewport); 33601 state.scissor(_currentScissor); 33602 state.setScissorTest(_currentScissorTest); 33603 _currentMaterialId = -1; 33604 return; 33605 } else if (renderTargetProperties.__webglFramebuffer === void 0) { 33606 textures.setupRenderTarget(renderTarget); 33607 } else if (renderTargetProperties.__hasExternalTextures) { 33608 textures.rebindTextures(renderTarget, properties.get(renderTarget.texture).__webglTexture, properties.get(renderTarget.depthTexture).__webglTexture); 33609 } else if (renderTarget.depthBuffer) { 33610 const depthTexture = renderTarget.depthTexture; 33611 if (renderTargetProperties.__boundDepthTexture !== depthTexture) { 33612 if (depthTexture !== null && properties.has(depthTexture) && (renderTarget.width !== depthTexture.image.width || renderTarget.height !== depthTexture.image.height)) { 33613 throw new Error("WebGLRenderTarget: Attached DepthTexture is initialized to the incorrect size."); 33614 } 33615 textures.setupDepthRenderbuffer(renderTarget); 33616 } 33617 } 33618 const texture = renderTarget.texture; 33619 if (texture.isData3DTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture) { 33620 isRenderTarget3D = true; 33621 } 33622 const __webglFramebuffer = properties.get(renderTarget).__webglFramebuffer; 33623 if (renderTarget.isWebGLCubeRenderTarget) { 33624 if (Array.isArray(__webglFramebuffer[activeCubeFace])) { 33625 framebuffer = __webglFramebuffer[activeCubeFace][activeMipmapLevel]; 33626 } else { 33627 framebuffer = __webglFramebuffer[activeCubeFace]; 33628 } 33629 isCube = true; 33630 } else if (renderTarget.samples > 0 && textures.useMultisampledRTT(renderTarget) === false) { 33631 framebuffer = properties.get(renderTarget).__webglMultisampledFramebuffer; 33632 } else { 33633 if (Array.isArray(__webglFramebuffer)) { 33634 framebuffer = __webglFramebuffer[activeMipmapLevel]; 33635 } else { 33636 framebuffer = __webglFramebuffer; 33637 } 33638 } 33639 _currentViewport.copy(renderTarget.viewport); 33640 _currentScissor.copy(renderTarget.scissor); 33641 _currentScissorTest = renderTarget.scissorTest; 33642 } else { 33643 _currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor(); 33644 _currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor(); 33645 _currentScissorTest = _scissorTest; 33646 } 33647 if (activeMipmapLevel !== 0) { 33648 framebuffer = _scratchFrameBuffer; 33649 } 33650 const framebufferBound = state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); 33651 if (framebufferBound) { 33652 state.drawBuffers(renderTarget, framebuffer); 33653 } 33654 state.viewport(_currentViewport); 33655 state.scissor(_currentScissor); 33656 state.setScissorTest(_currentScissorTest); 33657 if (isCube) { 33658 const textureProperties = properties.get(renderTarget.texture); 33659 _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + activeCubeFace, textureProperties.__webglTexture, activeMipmapLevel); 33660 } else if (isRenderTarget3D) { 33661 const layer = activeCubeFace; 33662 for (let i = 0; i < renderTarget.textures.length; i++) { 33663 const textureProperties = properties.get(renderTarget.textures[i]); 33664 _gl.framebufferTextureLayer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, textureProperties.__webglTexture, activeMipmapLevel, layer); 33665 } 33666 } else if (renderTarget !== null && activeMipmapLevel !== 0) { 33667 const textureProperties = properties.get(renderTarget.texture); 33668 _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, textureProperties.__webglTexture, activeMipmapLevel); 33669 } 33670 _currentMaterialId = -1; 33671 }; 33672 this.readRenderTargetPixels = function(renderTarget, x, y, width, height, buffer, activeCubeFaceIndex, textureIndex = 0) { 33673 if (!(renderTarget && renderTarget.isWebGLRenderTarget)) { 33674 error("WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget."); 33675 return; 33676 } 33677 let framebuffer = properties.get(renderTarget).__webglFramebuffer; 33678 if (renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== void 0) { 33679 framebuffer = framebuffer[activeCubeFaceIndex]; 33680 } 33681 if (framebuffer) { 33682 state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); 33683 try { 33684 const texture = renderTarget.textures[textureIndex]; 33685 const textureFormat = texture.format; 33686 const textureType = texture.type; 33687 if (renderTarget.textures.length > 1) _gl.readBuffer(_gl.COLOR_ATTACHMENT0 + textureIndex); 33688 if (!capabilities.textureFormatReadable(textureFormat)) { 33689 error("WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format."); 33690 return; 33691 } 33692 if (!capabilities.textureTypeReadable(textureType)) { 33693 error("WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type."); 33694 return; 33695 } 33696 if (x >= 0 && x <= renderTarget.width - width && (y >= 0 && y <= renderTarget.height - height)) { 33697 _gl.readPixels(x, y, width, height, utils.convert(textureFormat), utils.convert(textureType), buffer); 33698 } 33699 } finally { 33700 const framebuffer2 = _currentRenderTarget !== null ? properties.get(_currentRenderTarget).__webglFramebuffer : null; 33701 state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer2); 33702 } 33703 } 33704 }; 33705 this.readRenderTargetPixelsAsync = async function(renderTarget, x, y, width, height, buffer, activeCubeFaceIndex, textureIndex = 0) { 33706 if (!(renderTarget && renderTarget.isWebGLRenderTarget)) { 33707 throw new Error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget."); 33708 } 33709 let framebuffer = properties.get(renderTarget).__webglFramebuffer; 33710 if (renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== void 0) { 33711 framebuffer = framebuffer[activeCubeFaceIndex]; 33712 } 33713 if (framebuffer) { 33714 if (x >= 0 && x <= renderTarget.width - width && (y >= 0 && y <= renderTarget.height - height)) { 33715 state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); 33716 const texture = renderTarget.textures[textureIndex]; 33717 const textureFormat = texture.format; 33718 const textureType = texture.type; 33719 if (renderTarget.textures.length > 1) _gl.readBuffer(_gl.COLOR_ATTACHMENT0 + textureIndex); 33720 if (!capabilities.textureFormatReadable(textureFormat)) { 33721 throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format."); 33722 } 33723 if (!capabilities.textureTypeReadable(textureType)) { 33724 throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type."); 33725 } 33726 const glBuffer = _gl.createBuffer(); 33727 _gl.bindBuffer(_gl.PIXEL_PACK_BUFFER, glBuffer); 33728 _gl.bufferData(_gl.PIXEL_PACK_BUFFER, buffer.byteLength, _gl.STREAM_READ); 33729 _gl.readPixels(x, y, width, height, utils.convert(textureFormat), utils.convert(textureType), 0); 33730 const currFramebuffer = _currentRenderTarget !== null ? properties.get(_currentRenderTarget).__webglFramebuffer : null; 33731 state.bindFramebuffer(_gl.FRAMEBUFFER, currFramebuffer); 33732 const sync = _gl.fenceSync(_gl.SYNC_GPU_COMMANDS_COMPLETE, 0); 33733 _gl.flush(); 33734 await probeAsync(_gl, sync, 4); 33735 _gl.bindBuffer(_gl.PIXEL_PACK_BUFFER, glBuffer); 33736 _gl.getBufferSubData(_gl.PIXEL_PACK_BUFFER, 0, buffer); 33737 _gl.deleteBuffer(glBuffer); 33738 _gl.deleteSync(sync); 33739 return buffer; 33740 } else { 33741 throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: requested read bounds are out of range."); 33742 } 33743 } 33744 }; 33745 this.copyFramebufferToTexture = function(texture, position = null, level = 0) { 33746 const levelScale = Math.pow(2, -level); 33747 const width = Math.floor(texture.image.width * levelScale); 33748 const height = Math.floor(texture.image.height * levelScale); 33749 const x = position !== null ? position.x : 0; 33750 const y = position !== null ? position.y : 0; 33751 textures.setTexture2D(texture, 0); 33752 _gl.copyTexSubImage2D(_gl.TEXTURE_2D, level, 0, 0, x, y, width, height); 33753 state.unbindTexture(); 33754 }; 33755 const _srcFramebuffer = _gl.createFramebuffer(); 33756 const _dstFramebuffer = _gl.createFramebuffer(); 33757 this.copyTextureToTexture = function(srcTexture, dstTexture, srcRegion = null, dstPosition = null, srcLevel = 0, dstLevel = 0) { 33758 let width, height, depth2, minX, minY, minZ; 33759 let dstX, dstY, dstZ; 33760 const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[dstLevel] : srcTexture.image; 33761 if (srcRegion !== null) { 33762 width = srcRegion.max.x - srcRegion.min.x; 33763 height = srcRegion.max.y - srcRegion.min.y; 33764 depth2 = srcRegion.isBox3 ? srcRegion.max.z - srcRegion.min.z : 1; 33765 minX = srcRegion.min.x; 33766 minY = srcRegion.min.y; 33767 minZ = srcRegion.isBox3 ? srcRegion.min.z : 0; 33768 } else { 33769 const levelScale = Math.pow(2, -srcLevel); 33770 width = Math.floor(image.width * levelScale); 33771 height = Math.floor(image.height * levelScale); 33772 if (srcTexture.isDataArrayTexture) { 33773 depth2 = image.depth; 33774 } else if (srcTexture.isData3DTexture) { 33775 depth2 = Math.floor(image.depth * levelScale); 33776 } else { 33777 depth2 = 1; 33778 } 33779 minX = 0; 33780 minY = 0; 33781 minZ = 0; 33782 } 33783 if (dstPosition !== null) { 33784 dstX = dstPosition.x; 33785 dstY = dstPosition.y; 33786 dstZ = dstPosition.z; 33787 } else { 33788 dstX = 0; 33789 dstY = 0; 33790 dstZ = 0; 33791 } 33792 const glFormat = utils.convert(dstTexture.format); 33793 const glType = utils.convert(dstTexture.type); 33794 let glTarget; 33795 if (dstTexture.isData3DTexture) { 33796 textures.setTexture3D(dstTexture, 0); 33797 glTarget = _gl.TEXTURE_3D; 33798 } else if (dstTexture.isDataArrayTexture || dstTexture.isCompressedArrayTexture) { 33799 textures.setTexture2DArray(dstTexture, 0); 33800 glTarget = _gl.TEXTURE_2D_ARRAY; 33801 } else { 33802 textures.setTexture2D(dstTexture, 0); 33803 glTarget = _gl.TEXTURE_2D; 33804 } 33805 state.activeTexture(_gl.TEXTURE0); 33806 state.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY); 33807 state.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha); 33808 state.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment); 33809 const currentUnpackRowLen = state.getParameter(_gl.UNPACK_ROW_LENGTH); 33810 const currentUnpackImageHeight = state.getParameter(_gl.UNPACK_IMAGE_HEIGHT); 33811 const currentUnpackSkipPixels = state.getParameter(_gl.UNPACK_SKIP_PIXELS); 33812 const currentUnpackSkipRows = state.getParameter(_gl.UNPACK_SKIP_ROWS); 33813 const currentUnpackSkipImages = state.getParameter(_gl.UNPACK_SKIP_IMAGES); 33814 state.pixelStorei(_gl.UNPACK_ROW_LENGTH, image.width); 33815 state.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, image.height); 33816 state.pixelStorei(_gl.UNPACK_SKIP_PIXELS, minX); 33817 state.pixelStorei(_gl.UNPACK_SKIP_ROWS, minY); 33818 state.pixelStorei(_gl.UNPACK_SKIP_IMAGES, minZ); 33819 const isSrc3D = srcTexture.isDataArrayTexture || srcTexture.isData3DTexture; 33820 const isDst3D = dstTexture.isDataArrayTexture || dstTexture.isData3DTexture; 33821 if (srcTexture.isDepthTexture) { 33822 const srcTextureProperties = properties.get(srcTexture); 33823 const dstTextureProperties = properties.get(dstTexture); 33824 const srcRenderTargetProperties = properties.get(srcTextureProperties.__renderTarget); 33825 const dstRenderTargetProperties = properties.get(dstTextureProperties.__renderTarget); 33826 state.bindFramebuffer(_gl.READ_FRAMEBUFFER, srcRenderTargetProperties.__webglFramebuffer); 33827 state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, dstRenderTargetProperties.__webglFramebuffer); 33828 for (let i = 0; i < depth2; i++) { 33829 if (isSrc3D) { 33830 _gl.framebufferTextureLayer(_gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get(srcTexture).__webglTexture, srcLevel, minZ + i); 33831 _gl.framebufferTextureLayer(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get(dstTexture).__webglTexture, dstLevel, dstZ + i); 33832 } 33833 _gl.blitFramebuffer(minX, minY, width, height, dstX, dstY, width, height, _gl.DEPTH_BUFFER_BIT, _gl.NEAREST); 33834 } 33835 state.bindFramebuffer(_gl.READ_FRAMEBUFFER, null); 33836 state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, null); 33837 } else if (srcLevel !== 0 || srcTexture.isRenderTargetTexture || properties.has(srcTexture)) { 33838 const srcTextureProperties = properties.get(srcTexture); 33839 const dstTextureProperties = properties.get(dstTexture); 33840 state.bindFramebuffer(_gl.READ_FRAMEBUFFER, _srcFramebuffer); 33841 state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, _dstFramebuffer); 33842 for (let i = 0; i < depth2; i++) { 33843 if (isSrc3D) { 33844 _gl.framebufferTextureLayer(_gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, srcTextureProperties.__webglTexture, srcLevel, minZ + i); 33845 } else { 33846 _gl.framebufferTexture2D(_gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, srcTextureProperties.__webglTexture, srcLevel); 33847 } 33848 if (isDst3D) { 33849 _gl.framebufferTextureLayer(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, dstTextureProperties.__webglTexture, dstLevel, dstZ + i); 33850 } else { 33851 _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, dstTextureProperties.__webglTexture, dstLevel); 33852 } 33853 if (srcLevel !== 0) { 33854 _gl.blitFramebuffer(minX, minY, width, height, dstX, dstY, width, height, _gl.COLOR_BUFFER_BIT, _gl.NEAREST); 33855 } else if (isDst3D) { 33856 _gl.copyTexSubImage3D(glTarget, dstLevel, dstX, dstY, dstZ + i, minX, minY, width, height); 33857 } else { 33858 _gl.copyTexSubImage2D(glTarget, dstLevel, dstX, dstY, minX, minY, width, height); 33859 } 33860 } 33861 state.bindFramebuffer(_gl.READ_FRAMEBUFFER, null); 33862 state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, null); 33863 } else { 33864 if (isDst3D) { 33865 if (srcTexture.isDataTexture || srcTexture.isData3DTexture) { 33866 _gl.texSubImage3D(glTarget, dstLevel, dstX, dstY, dstZ, width, height, depth2, glFormat, glType, image.data); 33867 } else if (dstTexture.isCompressedArrayTexture) { 33868 _gl.compressedTexSubImage3D(glTarget, dstLevel, dstX, dstY, dstZ, width, height, depth2, glFormat, image.data); 33869 } else { 33870 _gl.texSubImage3D(glTarget, dstLevel, dstX, dstY, dstZ, width, height, depth2, glFormat, glType, image); 33871 } 33872 } else { 33873 if (srcTexture.isDataTexture) { 33874 _gl.texSubImage2D(_gl.TEXTURE_2D, dstLevel, dstX, dstY, width, height, glFormat, glType, image.data); 33875 } else if (srcTexture.isCompressedTexture) { 33876 _gl.compressedTexSubImage2D(_gl.TEXTURE_2D, dstLevel, dstX, dstY, image.width, image.height, glFormat, image.data); 33877 } else { 33878 _gl.texSubImage2D(_gl.TEXTURE_2D, dstLevel, dstX, dstY, width, height, glFormat, glType, image); 33879 } 33880 } 33881 } 33882 state.pixelStorei(_gl.UNPACK_ROW_LENGTH, currentUnpackRowLen); 33883 state.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight); 33884 state.pixelStorei(_gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels); 33885 state.pixelStorei(_gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows); 33886 state.pixelStorei(_gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages); 33887 if (dstLevel === 0 && dstTexture.generateMipmaps) { 33888 _gl.generateMipmap(glTarget); 33889 } 33890 state.unbindTexture(); 33891 }; 33892 this.initRenderTarget = function(target) { 33893 if (properties.get(target).__webglFramebuffer === void 0) { 33894 textures.setupRenderTarget(target); 33895 } 33896 }; 33897 this.initTexture = function(texture) { 33898 if (texture.isCubeTexture) { 33899 textures.setTextureCube(texture, 0); 33900 } else if (texture.isData3DTexture) { 33901 textures.setTexture3D(texture, 0); 33902 } else if (texture.isDataArrayTexture || texture.isCompressedArrayTexture) { 33903 textures.setTexture2DArray(texture, 0); 33904 } else { 33905 textures.setTexture2D(texture, 0); 33906 } 33907 state.unbindTexture(); 33908 }; 33909 this.resetState = function() { 33910 _currentActiveCubeFace = 0; 33911 _currentActiveMipmapLevel = 0; 33912 _currentRenderTarget = null; 33913 state.reset(); 33914 bindingStates.reset(); 33915 }; 33916 if (typeof __THREE_DEVTOOLS__ !== "undefined") { 33917 __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe", { detail: this })); 33918 } 33919 } 33920 /** 33921 * Defines the coordinate system of the renderer. 33922 * 33923 * In `WebGLRenderer`, the value is always `WebGLCoordinateSystem`. 33924 * 33925 * @type {WebGLCoordinateSystem|WebGPUCoordinateSystem} 33926 * @default WebGLCoordinateSystem 33927 * @readonly 33928 */ 33929 get coordinateSystem() { 33930 return WebGLCoordinateSystem; 33931 } 33932 /** 33933 * Defines the output color space of the renderer. 33934 * 33935 * @type {SRGBColorSpace|LinearSRGBColorSpace} 33936 * @default SRGBColorSpace 33937 */ 33938 get outputColorSpace() { 33939 return this._outputColorSpace; 33940 } 33941 set outputColorSpace(colorSpace) { 33942 this._outputColorSpace = colorSpace; 33943 const gl = this.getContext(); 33944 gl.drawingBufferColorSpace = ColorManagement._getDrawingBufferColorSpace(colorSpace); 33945 gl.unpackColorSpace = ColorManagement._getUnpackColorSpace(); 33946 } 33947}; 33948 33949export { 33950 sharedConfig, 33951 $PROXY, 33952 $TRACK, 33953 $DEVCOMP, 33954 createRoot, 33955 createSignal, 33956 createComputed, 33957 createRenderEffect, 33958 createEffect, 33959 createMemo, 33960 createResource, 33961 batch, 33962 untrack, 33963 on, 33964 onMount, 33965 onCleanup, 33966 getListener, 33967 getOwner, 33968 createContext, 33969 useContext, 33970 children, 33971 mapArray, 33972 createComponent, 33973 mergeProps, 33974 splitProps, 33975 lazy, 33976 createUniqueId, 33977 For, 33978 Show, 33979 Switch, 33980 Match, 33981 ErrorBoundary, 33982 Suspense, 33983 DEV, 33984 SVGElements, 33985 memo, 33986 render, 33987 template, 33988 delegateEvents, 33989 setAttribute, 33990 className, 33991 addEventListener, 33992 style, 33993 spread, 33994 use, 33995 insert, 33996 getNextElement, 33997 voidFn, 33998 ssrElement, 33999 isServer, 34000 Portal, 34001 Dynamic, 34002 REVISION, 34003 MOUSE, 34004 CullFaceNone, 34005 CullFaceBack, 34006 CullFaceFront, 34007 BasicShadowMap, 34008 PCFShadowMap, 34009 PCFSoftShadowMap, 34010 VSMShadowMap, 34011 FrontSide, 34012 BackSide, 34013 DoubleSide, 34014 NoBlending, 34015 NormalBlending, 34016 AdditiveBlending, 34017 SubtractiveBlending, 34018 MultiplyBlending, 34019 CustomBlending, 34020 MaterialBlending, 34021 AddEquation, 34022 SubtractEquation, 34023 ReverseSubtractEquation, 34024 MinEquation, 34025 MaxEquation, 34026 ZeroFactor, 34027 OneFactor, 34028 SrcColorFactor, 34029 OneMinusSrcColorFactor, 34030 SrcAlphaFactor, 34031 OneMinusSrcAlphaFactor, 34032 DstAlphaFactor, 34033 OneMinusDstAlphaFactor, 34034 DstColorFactor, 34035 OneMinusDstColorFactor, 34036 SrcAlphaSaturateFactor, 34037 NeverDepth, 34038 AlwaysDepth, 34039 LessDepth, 34040 LessEqualDepth, 34041 EqualDepth, 34042 GreaterEqualDepth, 34043 GreaterDepth, 34044 NotEqualDepth, 34045 MultiplyOperation, 34046 MixOperation, 34047 AddOperation, 34048 NoToneMapping, 34049 LinearToneMapping, 34050 ReinhardToneMapping, 34051 CineonToneMapping, 34052 ACESFilmicToneMapping, 34053 AgXToneMapping, 34054 NeutralToneMapping, 34055 UVMapping, 34056 CubeReflectionMapping, 34057 CubeRefractionMapping, 34058 EquirectangularReflectionMapping, 34059 EquirectangularRefractionMapping, 34060 CubeUVReflectionMapping, 34061 RepeatWrapping, 34062 ClampToEdgeWrapping, 34063 MirroredRepeatWrapping, 34064 NearestFilter, 34065 NearestMipmapNearestFilter, 34066 NearestMipmapLinearFilter, 34067 LinearFilter, 34068 LinearMipmapNearestFilter, 34069 LinearMipmapLinearFilter, 34070 LinearMipMapLinearFilter, 34071 UnsignedByteType, 34072 ByteType, 34073 ShortType, 34074 UnsignedShortType, 34075 IntType, 34076 UnsignedIntType, 34077 FloatType, 34078 HalfFloatType, 34079 UnsignedShort4444Type, 34080 UnsignedShort5551Type, 34081 UnsignedInt248Type, 34082 UnsignedInt5999Type, 34083 UnsignedInt101111Type, 34084 AlphaFormat, 34085 RGBFormat, 34086 RGBAFormat, 34087 DepthFormat, 34088 DepthStencilFormat, 34089 RedFormat, 34090 RedIntegerFormat, 34091 RGFormat, 34092 RGIntegerFormat, 34093 RGBIntegerFormat, 34094 RGBAIntegerFormat, 34095 RGB_S3TC_DXT1_Format, 34096 RGBA_S3TC_DXT1_Format, 34097 RGBA_S3TC_DXT3_Format, 34098 RGBA_S3TC_DXT5_Format, 34099 RGB_PVRTC_4BPPV1_Format, 34100 RGB_PVRTC_2BPPV1_Format, 34101 RGBA_PVRTC_4BPPV1_Format, 34102 RGBA_PVRTC_2BPPV1_Format, 34103 RGB_ETC1_Format, 34104 RGB_ETC2_Format, 34105 RGBA_ETC2_EAC_Format, 34106 R11_EAC_Format, 34107 SIGNED_R11_EAC_Format, 34108 RG11_EAC_Format, 34109 SIGNED_RG11_EAC_Format, 34110 RGBA_ASTC_4x4_Format, 34111 RGBA_ASTC_5x4_Format, 34112 RGBA_ASTC_5x5_Format, 34113 RGBA_ASTC_6x5_Format, 34114 RGBA_ASTC_6x6_Format, 34115 RGBA_ASTC_8x5_Format, 34116 RGBA_ASTC_8x6_Format, 34117 RGBA_ASTC_8x8_Format, 34118 RGBA_ASTC_10x5_Format, 34119 RGBA_ASTC_10x6_Format, 34120 RGBA_ASTC_10x8_Format, 34121 RGBA_ASTC_10x10_Format, 34122 RGBA_ASTC_12x10_Format, 34123 RGBA_ASTC_12x12_Format, 34124 RGBA_BPTC_Format, 34125 RED_RGTC1_Format, 34126 SIGNED_RED_RGTC1_Format, 34127 RED_GREEN_RGTC2_Format, 34128 SIGNED_RED_GREEN_RGTC2_Format, 34129 InterpolateDiscrete, 34130 InterpolateLinear, 34131 TrianglesDrawMode, 34132 TriangleStripDrawMode, 34133 TriangleFanDrawMode, 34134 TangentSpaceNormalMap, 34135 ObjectSpaceNormalMap, 34136 NoColorSpace, 34137 SRGBColorSpace, 34138 LinearSRGBColorSpace, 34139 LinearTransfer, 34140 SRGBTransfer, 34141 NoNormalPacking, 34142 NormalRGPacking, 34143 NormalGAPacking, 34144 ZeroStencilOp, 34145 KeepStencilOp, 34146 ReplaceStencilOp, 34147 IncrementStencilOp, 34148 DecrementStencilOp, 34149 IncrementWrapStencilOp, 34150 DecrementWrapStencilOp, 34151 InvertStencilOp, 34152 NeverStencilFunc, 34153 LessStencilFunc, 34154 EqualStencilFunc, 34155 LessEqualStencilFunc, 34156 GreaterStencilFunc, 34157 NotEqualStencilFunc, 34158 GreaterEqualStencilFunc, 34159 AlwaysStencilFunc, 34160 NeverCompare, 34161 LessCompare, 34162 EqualCompare, 34163 LessEqualCompare, 34164 GreaterCompare, 34165 NotEqualCompare, 34166 GreaterEqualCompare, 34167 AlwaysCompare, 34168 StaticDrawUsage, 34169 DynamicDrawUsage, 34170 WebGLCoordinateSystem, 34171 WebGPUCoordinateSystem, 34172 TimestampQuery, 34173 Compatibility, 34174 isTypedArray, 34175 createCanvasElement, 34176 log, 34177 warn, 34178 error, 34179 warnOnce, 34180 yieldToMain, 34181 ReversedDepthFuncs, 34182 EventDispatcher, 34183 RAD2DEG, 34184 MathUtils, 34185 Vector2, 34186 Quaternion, 34187 Vector3, 34188 Matrix3, 34189 ColorManagement, 34190 Texture, 34191 Vector4, 34192 RenderTarget, 34193 DataArrayTexture, 34194 Matrix4, 34195 Euler, 34196 Object3D, 34197 Group, 34198 WebXRController, 34199 Color, 34200 Scene, 34201 Box3, 34202 BufferAttribute, 34203 Uint16BufferAttribute, 34204 Uint32BufferAttribute, 34205 Float16BufferAttribute, 34206 Float32BufferAttribute, 34207 Sphere, 34208 BufferGeometry, 34209 InterleavedBuffer, 34210 InterleavedBufferAttribute, 34211 Material, 34212 SpriteMaterial, 34213 MeshBasicMaterial, 34214 Mesh, 34215 SkinnedMesh, 34216 Bone, 34217 DataTexture, 34218 Skeleton, 34219 InstancedBufferAttribute, 34220 InstancedMesh, 34221 Plane, 34222 Frustum, 34223 FrustumArray, 34224 LineBasicMaterial, 34225 Line, 34226 LineSegments, 34227 LineLoop, 34228 PointsMaterial, 34229 Points, 34230 FramebufferTexture, 34231 CompressedTexture, 34232 CubeTexture, 34233 DepthTexture, 34234 CubeDepthTexture, 34235 BoxGeometry, 34236 CylinderGeometry, 34237 ConeGeometry, 34238 ShapeUtils, 34239 PlaneGeometry, 34240 SphereGeometry, 34241 TorusGeometry, 34242 ShadowMaterial, 34243 ShaderMaterial, 34244 MeshStandardMaterial, 34245 MeshPhysicalMaterial, 34246 MeshPhongMaterial, 34247 MeshToonMaterial, 34248 MeshNormalMaterial, 34249 MeshLambertMaterial, 34250 MeshMatcapMaterial, 34251 LineDashedMaterial, 34252 Interpolant, 34253 NumberKeyframeTrack, 34254 QuaternionKeyframeTrack, 34255 VectorKeyframeTrack, 34256 AnimationClip, 34257 Loader, 34258 FileLoader, 34259 TextureLoader, 34260 HemisphereLight, 34261 Camera, 34262 PerspectiveCamera, 34263 SpotLight, 34264 PointLight, 34265 OrthographicCamera, 34266 DirectionalLight, 34267 AmbientLight, 34268 RectAreaLight, 34269 LightProbe, 34270 LoaderUtils, 34271 ImageBitmapLoader, 34272 CubeCamera, 34273 ArrayCamera, 34274 PropertyBinding, 34275 Uniform, 34276 InstancedInterleavedBuffer, 34277 Raycaster, 34278 Clock, 34279 Matrix2, 34280 getByteLength, 34281 WebGLRenderer 34282}; 34283/*! Bundled license information: 34284 34285three/build/three.core.js: 34286three/build/three.module.js: 34287 (** 34288 * @license 34289 * Copyright 2010-2026 Three.js Authors 34290 * SPDX-License-Identifier: MIT 34291 *) 34292*/
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.