UNPKG

1.54 MBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.AS = {}));
5})(this, (function (exports) { 'use strict';
6
7 function imagePromise(url) {
8 return new Promise((resolve, reject) => {
9 const img = new Image();
10 img.crossOrigin = 'Anonymous';
11 img.onload = () => resolve(img);
12 img.onerror = () => reject(`Could not load image ${url}`);
13 img.src = url;
14 })
15 }
16 async function imageToImageBitmap(img) {
17 return createImageBitmap(img, {
18 premultiplyAlpha: 'none',
19 colorSpaceConversion: 'none',
20 })
21 }
22 async function imageBitmapRendererCtx(imageBitmap) {
23 const { width, height } = imageBitmap;
24 const can = new OffscreenCanvas(width, height);
25 const ctx = can.getContext('bitmaprenderer');
26 ctx.transferFromImageBitmap(imageBitmap);
27 return ctx
28 }
29 function imageBitmap2dCtx(imageBitmap) {
30 const { width, height } = imageBitmap;
31 const can = new OffscreenCanvas(width, height);
32 const ctx = can.getContext('2d');
33 ctx.drawImage(imageBitmap, 0, 0);
34 return ctx
35 }
36 async function imageBitmapData(imageBitmap) {
37 const ctx = imageBitmap2dCtx(imageBitmap);
38 return ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height)
39 }
40 async function canvasToBlob(can, mimeType = 'png', quality = undefined) {
41 if (!mimeType.startsWith('image/')) mimeType = 'image/' + mimeType;
42 return new Promise(resolve => {
43 can.toBlob(blob => resolve(blob), mimeType, quality);
44 })
45 }
46 function AsyncFunction(argsArray, fcnBody) {
47 const ctor = Object.getPrototypeOf(async function () {}).constructor;
48 const asyncFcn = new ctor(...argsArray, fcnBody);
49 return asyncFcn
50 }
51 async function blobToData(blob, type = 'dataURL') {
52 type = type[0].toUpperCase() + type.slice(1);
53 const types = ['Text', 'ArrayBuffer', 'DataURL'];
54 if (!types.includes(type))
55 throw Error('blobToData: data must be one of ' + types.toString())
56 const reader = new FileReader();
57 return new Promise((resolve, reject) => {
58 reader.addEventListener('load', () => resolve(reader.result));
59 reader.addEventListener('error', e => reject(e));
60 reader['readAs' + type](blob);
61 })
62 }
63 async function fetchData(url, type = 'blob') {
64 const types = ['arrayBuffer', 'blob', 'json', 'text'];
65 if (!types.includes(type))
66 throw Error('fetchData: data must be one of ' + types.toString())
67 return fetch(url).then(res => res[type]())
68 }
69 async function fetchJson(url) {
70 return fetchData(url, 'json')
71 }
72 async function fetchText(url) {
73 return fetchData(url, 'text')
74 }
75 function toDataURL(data, type = undefined) {
76 if (data.toDataURL) return data.toDataURL(type, type)
77 if (!type) type = 'text/plain;charset=US-ASCII';
78 return `data:${type};base64,${btoa(data)}}`
79 }
80 async function blobsEqual(blob0, blob1) {
81 const text0 = await blob0.text();
82 const text1 = await blob1.text();
83 return text0 === text1
84 }
85 function downloadCanvas(can, name = 'download.png', quality = null) {
86 if (!(name.endsWith('.png') || name.endsWith('.jpeg'))) ;
87 const type = name.endsWith('.png') ? 'image/png' : 'image/jpeg';
88 const url = typeOf(can) === 'string' ? can : can.toDataURL(type, quality);
89 const link = document.createElement('a');
90 link.download = name;
91 link.href = url;
92 link.click();
93 }
94 function downloadBlob(blobable, name = 'download', format = true) {
95 if (isDataSet(blobable) && !Array.isArray(blobable.data))
96 blobable.data = Array.from(blobable.data);
97 if (isTypedArray(blobable)) blobable = Array.from(blobable);
98 if (isObject$1(blobable) || isArray(blobable))
99 blobable = format
100 ? JSON.stringify(blobable, null, 2)
101 : JSON.stringify(blobable);
102 let blob = typeOf(blobable) === 'blob' ? blobable : new Blob([blobable]);
103 const url = URL.createObjectURL(blob);
104 const link = document.createElement('a');
105 link.download = name;
106 link.href = url;
107 link.click();
108 URL.revokeObjectURL(url);
109 }
110 function xhrPromise(url, type = 'text', method = 'GET') {
111 return new Promise((resolve, reject) => {
112 const xhr = new XMLHttpRequest();
113 xhr.open(method, url);
114 xhr.responseType = type;
115 xhr.onload = () => resolve(xhr.response);
116 xhr.onerror = () =>
117 reject(Error(`Could not load ${url}: ${xhr.status}`));
118 xhr.send();
119 })
120 }
121 function pause(ms = 1000) {
122 return new Promise(resolve => {
123 setTimeout(resolve, ms);
124 })
125 }
126 async function timeoutLoop(fcn, steps = -1, ms = 0) {
127 let i = 0;
128 while (i++ !== steps) {
129 fcn(i - 1);
130 await pause(ms);
131 }
132 }
133 function waitPromise(done, ms = 10) {
134 return new Promise(resolve => {
135 function waitOn() {
136 if (done()) return resolve()
137 else setTimeout(waitOn, ms);
138 }
139 waitOn();
140 })
141 }
142 function offscreenOK() {
143 return inWorker()
144 }
145 function createCanvas(width, height, offscreen = offscreenOK()) {
146 if (offscreen) return new OffscreenCanvas(width, height)
147 const can = document.createElement('canvas');
148 can.width = width;
149 can.height = height;
150 return can
151 }
152 function createCtx(
153 width,
154 height,
155 offscreen = offscreenOK(),
156 attrs = {}
157 ) {
158 const can = createCanvas(width, height, offscreen);
159 return can.getContext('2d', attrs)
160 }
161 function cloneCanvas(can, offscreen = offscreenOK()) {
162 const ctx = createCtx(can.width, can.height, offscreen);
163 ctx.drawImage(can, 0, 0);
164 return ctx.canvas
165 }
166 function resizeCtx(ctx, width, height) {
167 const copy = cloneCanvas(ctx.canvas);
168 ctx.canvas.width = width;
169 ctx.canvas.height = height;
170 ctx.drawImage(copy, 0, 0);
171 }
172 function resizeCanvas(
173 can,
174 width,
175 height = (width / can.width) * can.height
176 ) {
177 const ctx = createCtx(width, height);
178 ctx.drawImage(can, 0, 0, width, height);
179 return ctx.canvas
180 }
181 function setCanvasSize(can, width, height) {
182 if (can.width !== width || can.height != height) {
183 can.width = width;
184 can.height = height;
185 }
186 }
187 function setIdentity(ctx) {
188 ctx.save();
189 ctx.setTransform(1, 0, 0, 1, 0, 0);
190 }
191 function setTextProperties(
192 ctx,
193 font,
194 textAlign = 'center',
195 textBaseline = 'middle'
196 ) {
197 Object.assign(ctx, { font, textAlign, textBaseline });
198 }
199 function drawText(ctx, string, x, y, color, useIdentity = true) {
200 if (useIdentity) setIdentity(ctx);
201 ctx.fillStyle = color.css || color;
202 ctx.fillText(string, x, y);
203 if (useIdentity) ctx.restore();
204 }
205 function ctxImageData(ctx) {
206 return ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height)
207 }
208 function ctxImageColors(ctx) {
209 const typedArray = ctxImageData(ctx).data;
210 const colors = [];
211 step(typedArray.length, 4, i => colors.push(typedArray.subarray(i, i + 4)));
212 return colors
213 }
214 function ctxImagePixels(ctx) {
215 const imageData = ctxImageData(ctx);
216 const pixels = new Uint32Array(imageData.data.buffer);
217 return pixels
218 }
219 function clearCtx(ctx, cssColor = undefined) {
220 const { width, height } = ctx.canvas;
221 setIdentity(ctx);
222 if (!cssColor || cssColor === 'transparent') {
223 ctx.clearRect(0, 0, width, height);
224 } else {
225 cssColor = cssColor.css || cssColor;
226 ctx.fillStyle = cssColor;
227 ctx.fillRect(0, 0, width, height);
228 }
229 ctx.restore();
230 }
231 function imageToCtx(img) {
232 const ctx = createCtx(img.width, img.height);
233 fillCtxWithImage(ctx, img);
234 return ctx
235 }
236 function imageToCanvas(img) {
237 return imageToCtx(img).canvas
238 }
239 function fillCtxWithImage(ctx, img) {
240 setIdentity(ctx);
241 ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height);
242 ctx.restore();
243 }
244 function setCtxImage(ctx, img) {
245 setCanvasSize(ctx.canvas, img.width, img.height);
246 fillCtxWithImage(ctx, img);
247 }
248 let skipChecks = false;
249 function skipErrorChecks(bool) {
250 skipChecks = bool;
251 }
252 function checkArg$1(arg, type = 'number', name = 'Function') {
253 if (skipChecks) return
254 if (typeof arg !== type) {
255 throw new Error(`${name} expected a ${type}, got ${arg}`)
256 }
257 }
258 function checkArgs$1(argsArray, type = 'number', name = 'Function') {
259 if (skipChecks) return
260 if (typeOf(argsArray) === 'arguments') argsArray = Array.from(argsArray);
261 argsArray.forEach((val, i) => {
262 checkArg$1(val, type, name);
263 });
264 }
265 const logOnceMsgSet = new Set();
266 function logOnce(msg, useWarn = false) {
267 if (!logOnceMsgSet.has(msg)) {
268 if (useWarn) {
269 console.warn(msg);
270 } else {
271 console.log(msg);
272 }
273 logOnceMsgSet.add(msg);
274 }
275 }
276 function warn(msg) {
277 logOnce(msg, true);
278 }
279 function timeit(f, runs = 1e5, name = 'test') {
280 name = name + '-' + runs;
281 console.time(name);
282 for (let i = 0; i < runs; i++) f(i);
283 console.timeEnd(name);
284 }
285 function fps() {
286 const timer = typeof performance === 'undefined' ? Date : performance;
287 const start = timer.now();
288 let steps = 0;
289 function perf() {
290 steps++;
291 const ms = timer.now() - start;
292 const fps = parseFloat((steps / (ms / 1000)).toFixed(2));
293 Object.assign(perf, { fps, ms, start, steps });
294 }
295 perf.steps = 0;
296 return perf
297 }
298 function pps(obj, title = '') {
299 if (title) console.log(title);
300 let count = 1;
301 let str = '';
302 while (obj) {
303 if (typeof obj === 'function') {
304 str = obj.constructor.toString();
305 } else {
306 const okeys = Object.keys(obj);
307 str =
308 okeys.length > 0
309 ? `[${okeys.join(', ')}]`
310 : `[${obj.constructor.name}]`;
311 }
312 console.log(`[${count++}]: ${str}`);
313 obj = Object.getPrototypeOf(obj);
314 }
315 }
316 function toWindow(obj) {
317 Object.assign(window, obj);
318 console.log('toWindow:', Object.keys(obj).join(', '));
319 }
320 function logAll(obj) {
321 Object.keys(obj).forEach(key => console.log(' ', key, obj[key]));
322 }
323 function dump(model = window.model) {
324 let { patches: ps, turtles: ts, links: ls } = model;
325 Object.assign(window, { ps, ts, ls });
326 window.p = ps.length > 0 ? ps.oneOf() : {};
327 window.t = ts.length > 0 ? ts.oneOf() : {};
328 window.l = ls.length > 0 ? ls.oneOf() : {};
329 console.log('debug: ps, ts, ls, p, t, l dumped to window');
330 }
331 function addCssLink(url) {
332 const link = document.createElement('link');
333 link.setAttribute('rel', 'stylesheet');
334 link.setAttribute('href', url);
335 document.head.appendChild(link);
336 }
337 async function fetchCssStyle(url) {
338 const response = await fetch(url);
339 if (!response.ok) throw Error(`fetchCssStyle: Not found: ${url}`)
340 const css = await response.text();
341 addCssStyle(css);
342 return css
343 }
344 function addCssStyle(css) {
345 var style = document.createElement('style');
346 style.innerHTML = css;
347 document.head.appendChild(style);
348 }
349 function getQueryString() {
350 return window.location.search.substr(1)
351 }
352 function parseQueryString(
353 paramsString = getQueryString()
354 ) {
355 const results = {};
356 const searchParams = new URLSearchParams(paramsString);
357 for (var pair of searchParams.entries()) {
358 let [key, val] = pair;
359 if (val.match(/^[0-9.]+$/) || val.match(/^[0-9.]+e[0-9]+$/))
360 val = Number(val);
361 if (['true', 't', ''].includes(val)) val = true;
362 if (['false', 'f'].includes(val)) val = false;
363 results[key] = val;
364 }
365 return results
366 }
367 function RESTapi(parameters) {
368 return Object.assign(parameters, parseQueryString())
369 }
370 function inWorker() {
371 return !inNode() && typeof self.window === 'undefined'
372 }
373 function inNode() {
374 return typeof global !== 'undefined'
375 }
376 function inDeno() {
377 return !!Deno
378 }
379 function printToPage(msg, element = document.body) {
380 if (typeof msg === 'object') {
381 msg = JSON.stringify(msg, null, 2);
382 }
383 msg = '<pre>' + msg + '</pre>';
384 if (typeof element === 'string') {
385 element = document.getElementById(element);
386 }
387 element.style.fontFamily = 'monospace';
388 element.innerHTML += msg;
389 }
390 function getEventXY(element, evt) {
391 const rect = element.getBoundingClientRect();
392 return [evt.clientX - rect.left, evt.clientY - rect.top]
393 }
394 function fcnToWorker(fcn) {
395 const href = document.location.href;
396 const root = href.replace(/\/[^\/]+$/, '/');
397 const fcnStr = `(${fcn.toString(root)})("${root}")`;
398 const objUrl = URL.createObjectURL(
399 new Blob([fcnStr], { type: 'text/javascript' })
400 );
401 const worker = new Worker(objUrl);
402 worker.onerror = function (e) {
403 console.log('Worker ERROR: Line ', e.lineno, ': ', e.message);
404 };
405 return worker
406 }
407 const PI$2 = Math.PI;
408 function randomInt(max) {
409 return Math.floor(Math.random() * max)
410 }
411 function randomInt2(min, max) {
412 return min + Math.floor(Math.random() * (max - min))
413 }
414 function randomFloat(max) {
415 return Math.random() * max
416 }
417 function randomFloat2(min, max) {
418 return min + Math.random() * (max - min)
419 }
420 function randomCentered(r) {
421 return randomFloat2(-r / 2, r / 2)
422 }
423 function randomNormal(mean = 0.0, sigma = 1.0) {
424 const [u1, u2] = [1.0 - Math.random(), Math.random()];
425 const norm = Math.sqrt(-2.0 * Math.log(u1)) * Math.cos(2.0 * PI$2 * u2);
426 return norm * sigma + mean
427 }
428 function randomSeed(seed = 123456) {
429 seed = seed % 2147483647;
430 Math.random = () => {
431 seed = (seed * 16807) % 2147483647;
432 return (seed - 1) / 2147483646
433 };
434 }
435 function precision(num, digits = 4) {
436 if (num === -0) return 0
437 if (Array.isArray(num)) return num.map(val => precision(val, digits))
438 const mult = 10 ** digits;
439 return Math.round(num * mult) / mult
440 }
441 const isPowerOf2 = num => (num & (num - 1)) === 0;
442 const nextPowerOf2 = num => Math.pow(2, Math.ceil(Math.log2(num)));
443 function mod(v, n) {
444 return ((v % n) + n) % n
445 }
446 const wrap = (v, min, max) => min + mod(v - min, max - min);
447 function clamp(v, min, max) {
448 if (v < min) return min
449 if (v > max) return max
450 return v
451 }
452 const isBetween = (val, min, max) => min <= val && val <= max;
453 const lerp = (lo, hi, scale) =>
454 lo <= hi ? lo + (hi - lo) * scale : lo - (lo - hi) * scale;
455 function lerpScale(number, lo, hi) {
456 if (lo === hi) throw Error('lerpScale: lo === hi')
457 number = clamp(number, lo, hi);
458 return (number - lo) / (hi - lo)
459 }
460 const toDeg$1 = 180 / Math.PI;
461 const toRad$1 = Math.PI / 180;
462 function degToRad(degrees) {
463 return mod2pi(degrees * toRad$1)
464 }
465 function radToDeg(radians) {
466 return mod360(radians * toDeg$1)
467 }
468 function radToHeading(radians) {
469 const deg = radians * toDeg$1;
470 return mod360(90 - deg)
471 }
472 function headingToRad(heading) {
473 const deg = mod360(90 - heading);
474 return deg * toRad$1
475 }
476 function radToHeadingAngle(radians) {
477 return -radToDeg(radians)
478 }
479 function headingAngleToRad(headingAngle) {
480 return -degToRad(headingAngle)
481 }
482 const degToHeading = degrees => mod360(90 - degrees);
483 const headingToDeg = heading => mod360(90 - heading);
484 function mod360(degrees) {
485 return mod(degrees, 360)
486 }
487 function mod2pi(radians) {
488 return mod(radians, 2 * PI$2)
489 }
490 function modpipi(radians) {
491 return mod(radians, 2 * PI$2) - PI$2
492 }
493 function mod180180(degrees) {
494 return mod360(degrees) - 180
495 }
496 function degreesEqual(deg1, deg2) {
497 return mod360(deg1) === mod360(deg2)
498 }
499 function radsEqual(rads1, rads2) {
500 return mod2pi(rads1) === mod2pi(rads2)
501 }
502 const headingsEq = degreesEqual;
503 function subtractRadians(rad1, rad0) {
504 let dr = mod2pi(rad1 - rad0);
505 if (dr > PI$2) dr = dr - 2 * PI$2;
506 return dr
507 }
508 function subtractDegrees(deg1, deg0) {
509 let dAngle = mod360(deg1 - deg0);
510 if (dAngle > 180) dAngle = dAngle - 360;
511 return dAngle
512 }
513 function subtractHeadings(head1, head0) {
514 return -subtractDegrees(head1, head0)
515 }
516 function radiansTowardXY(x, y, x1, y1) {
517 return Math.atan2(y1 - y, x1 - x)
518 }
519 function headingTowardXY(x, y, x1, y1) {
520 return radToHeading(radiansTowardXY(x, y, x1, y1))
521 }
522 function degreesTowardXY(x, y, x1, y1) {
523 return radToDeg(radiansTowardXY(x, y, x1, y1))
524 }
525 const sqDistance = (x, y, x1, y1) => (x - x1) ** 2 + (y - y1) ** 2;
526 const distance = (x, y, x1, y1) => Math.sqrt(sqDistance(x, y, x1, y1));
527 const sqDistance3 = (x, y, z, x1, y1, z1) =>
528 (x - x1) ** 2 + (y - y1) ** 2 + (z - z1) ** 2;
529 const distance3 = (x, y, z, x1, y1, z1) =>
530 Math.sqrt(sqDistance3(x, y, z, x1, y1, z1));
531 function inCone(x, y, radius, coneAngle, direction, x0, y0) {
532 if (sqDistance(x0, y0, x, y) > radius * radius) return false
533 const angle12 = radiansTowardXY(x0, y0, x, y);
534 return coneAngle / 2 >= Math.abs(subtractRadians(direction, angle12))
535 }
536 function toJSON$2(obj, indent = 0, topLevelArrayOK = true) {
537 let firstCall = topLevelArrayOK;
538 const blackList = ['rectCache'];
539 const json = JSON.stringify(
540 obj,
541 (key, val) => {
542 if (blackList.includes(key)) {
543 return undefined
544 }
545 const isAgentArray =
546 Array.isArray(val) &&
547 val.length > 0 &&
548 Number.isInteger(val[0].id);
549 if (isAgentArray && !firstCall) {
550 return val.map(v => v.id)
551 }
552 firstCall = false;
553 return val
554 },
555 indent
556 );
557 return json
558 }
559 function sampleModel(model) {
560 const obj = {
561 ticks: model.ticks,
562 model: Object.keys(model),
563 patches: model.patches.length,
564 patch: model.patches.oneOf(),
565 turtles: model.turtles.length,
566 turtle: model.turtles.oneOf(),
567 links: model.links.length,
568 link: model.links.oneOf(),
569 };
570 const json = toJSON$2(obj);
571 return JSON.parse(json)
572 }
573 const identityFcn = o => o;
574 const noopFcn = () => {};
575 const propFcn = prop => o => o[prop];
576 function arraysEqual$1(a1, a2) {
577 if (a1.length !== a2.length) return false
578 for (let i = 0; i < a1.length; i++) {
579 if (a1[i] !== a2[i]) return false
580 }
581 return true
582 }
583 function removeArrayItem(array, item) {
584 const ix = array.indexOf(item);
585 if (ix !== -1) {
586 array.splice(ix, 1);
587 } else {
588 throw Error(`removeArrayItem: ${item} not in array`)
589 }
590 return array
591 }
592 const arraysToString = arrays => arrays.map(a => `${a}`).join(',');
593 function forLoop(arrayOrObj, fcn) {
594 if (arrayOrObj.slice) {
595 for (let i = 0, len = arrayOrObj.length; i < len; i++) {
596 fcn(arrayOrObj[i], i, arrayOrObj);
597 }
598 } else {
599 Object.keys(arrayOrObj).forEach(k => fcn(arrayOrObj[k], k, arrayOrObj));
600 }
601 }
602 function repeat(n, f, a = []) {
603 for (let i = 0; i < n; i++) f(i, a);
604 return a
605 }
606 function step(n, step, f) {
607 for (let i = 0; i < n; i += step) f(i);
608 }
609 function range(length) {
610 return repeat(length, (i, a) => {
611 a[i] = i;
612 })
613 }
614 function override(defaults, options) {
615 const overrides = defaults;
616 forLoop(defaults, (val, key) => {
617 if (options[key]) {
618 overrides[key] = options[key];
619 }
620 });
621 return overrides
622 }
623 function concatArrays(array1, array2) {
624 const Type = array1.constructor;
625 if (Type === Array) {
626 return array1.concat(convertArrayType(array2, Array))
627 }
628 const array = new Type(array1.length + array2.length);
629 array.set(array1);
630 array.set(array2, array1.length);
631 return array
632 }
633 function objectToString(obj, indent = 2, jsKeys = true) {
634 let str = JSON.stringify(obj, null, indent);
635 if (jsKeys) str = str.replace(/"([^"]+)":/gm, '$1:');
636 return str
637 }
638 const objectsEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
639 function oneOf(array) {
640 return array[randomInt(array.length)]
641 }
642 function otherOneOf(array, item) {
643 if (array.length < 2) throw Error('otherOneOf: array.length < 2')
644 do {
645 var other = oneOf(array);
646 } while (item === other)
647 return other
648 }
649 const oneKeyOf = obj => oneOf(Object.keys(obj));
650 const oneValOf = obj => obj[oneKeyOf(obj)];
651 function sortNums(array, ascending = true) {
652 return array.sort((a, b) => (ascending ? a - b : b - a))
653 }
654 function sortObjs(array, fcn, ascending = true) {
655 if (typeof fcn === 'string') fcn = propFcn(fcn);
656 const comp = (a, b) => fcn(a) - fcn(b);
657 return array.sort((a, b) => (ascending ? comp(a, b) : -comp(a, b)))
658 }
659 function shuffle(array) {
660 for (let i = array.length - 1; i > 0; i--) {
661 const j = randomInt(i)
662 ;[array[j], array[i]] = [array[i], array[j]];
663 }
664 return array
665 }
666 function union(a1, a2) {
667 return Array.from(new Set(a1.concat(a2)))
668 }
669 function intersection(a1, a2) {
670 const set2 = new Set(a2);
671 return a1.filter(x => set2.has(x))
672 }
673 function difference(a1, a2) {
674 const set2 = new Set(a2);
675 return a1.filter(x => !set2.has(x))
676 }
677 function floatRamp(start, stop, numItems) {
678 if (numItems <= 1) throw Error('floatRamp: numItems must be > 1')
679 const a = [];
680 for (let i = 0; i < numItems; i++) {
681 a.push(start + (stop - start) * (i / (numItems - 1)));
682 }
683 return a
684 }
685 function integerRamp(start, stop, numItems = stop - start + 1) {
686 return floatRamp(start, stop, numItems).map(a => Math.round(a))
687 }
688 function nestedProperty(obj, path) {
689 if (typeof path === 'string') path = path.split('.');
690 switch (path.length) {
691 case 1:
692 return obj[path[0]]
693 case 2:
694 return obj[path[0]][path[1]]
695 case 3:
696 return obj[path[0]][path[1]][path[2]]
697 case 4:
698 return obj[path[0]][path[1]][path[2]][path[3]]
699 default:
700 return path.reduce((obj, param) => obj[param], obj)
701 }
702 }
703 const arrayLast = array => array[array.length - 1];
704 const arrayMax$1 = array => array.reduce((a, b) => Math.max(a, b));
705 const arrayMin = array => array.reduce((a, b) => Math.min(a, b));
706 const arrayExtent = array => [arrayMin(array), arrayMax$1(array)];
707 const arraysDiff = (a1, a2, ifcn = i => i) => {
708 if (a1.length !== a2.length)
709 return console.log('lengths differ', a1.length, a2.length)
710 const diffs = [];
711 for (let i = 0; i < a1.length; i++) {
712 if (a1[i] !== a2[i]) diffs.push([ifcn(i), a1[i], a2[i]]);
713 }
714 return diffs
715 };
716 function arrayToMatrix(array, width, height) {
717 if (array.length !== width * height)
718 throw Error('arrayToMatrix: length !== width * height')
719 const matrix = [];
720 for (let i = 0; i < height; i++) {
721 const row = array.slice(i * width, (i + 1) * width);
722 matrix.push(row);
723 }
724 return matrix
725 }
726 const matrixToArray = matrix => matrix.flat();
727 function isOofA(data) {
728 if (!isObject$1(data)) return false
729 return Object.values(data).every(v => isTypedArray(v))
730 }
731 function toOofA(aofo, spec) {
732 const length = aofo.length;
733 const keys = Object.keys(spec);
734 const oofa = {};
735 keys.forEach(k => {
736 oofa[k] = new spec[k](length);
737 });
738 forLoop(aofo, (o, i) => {
739 keys.forEach(key => (oofa[key][i] = o[key]));
740 });
741 return oofa
742 }
743 function oofaObject(oofa, i, keys) {
744 const obj = {};
745 keys.forEach(key => {
746 obj[key] = oofa[key][i];
747 });
748 return obj
749 }
750 function toAofO(oofa, keys = Object.keys(oofa)) {
751 const length = oofa[keys[0]].length;
752 const aofo = new Array(length);
753 forLoop(aofo, (val, i) => {
754 aofo[i] = oofaObject(oofa, i, keys);
755 });
756 return aofo
757 }
758 function oofaBuffers(postData) {
759 const buffers = [];
760 forLoop(postData, obj => forLoop(obj, a => buffers.push(a.buffer)));
761 return buffers
762 }
763 const typeOf = obj =>
764 ({}.toString
765 .call(obj)
766 .match(/\s(\w+)/)[1]
767 .toLowerCase());
768 const isType = (obj, string) => typeOf(obj) === string;
769 const isOneOfTypes = (obj, array) => array.includes(typeOf(obj));
770 const isString = obj => isType(obj, 'string');
771 const isObject$1 = obj => isType(obj, 'object');
772 const isArray = obj => Array.isArray(obj);
773 const isNumber$1 = obj => isType(obj, 'number');
774 const isInteger = n => Number.isInteger(n);
775 const isFunction = obj => isType(obj, 'function');
776 const isImage = obj => isType(obj, 'image');
777 const isCanvas = obj =>
778 isOneOfTypes(obj, ['htmlcanvaselement', 'offscreencanvas']);
779 const isImageable = obj =>
780 isOneOfTypes(obj, [
781 'image',
782 'htmlimageelement',
783 'htmlcanvaselement',
784 'offscreencanvas',
785 'imagebitmap',
786 ]);
787 const isTypedArray = obj => typeOf(obj.buffer) === 'arraybuffer';
788 const isUintArray = obj => /^uint.*array$/.test(typeOf(obj));
789 const isIntArray = obj => /^int.*array$/.test(typeOf(obj));
790 const isFloatArray = obj => /^float.*array$/.test(typeOf(obj));
791 const isArrayLike = obj => isArray(obj) || isTypedArray(obj);
792 const isColorLikeArray = obj =>
793 isArrayLike(obj) &&
794 [3, 4].includes(obj.length) &&
795 obj.every(
796 i =>
797 (isInteger(i) && isBetween(i, 0, 255)) ||
798 (isNumber$1(i) && isBetween(i, 0, 1))
799 );
800 function isLittleEndian() {
801 const d32 = new Uint32Array([0x01020304]);
802 return new Uint8ClampedArray(d32.buffer)[0] === 4
803 }
804 function convertArrayType(array, Type) {
805 const Type0 = array.constructor;
806 if (Type0 === Type) return array
807 return Type.from(array)
808 }
809 function isDataSet(obj) {
810 return typeOf(obj) === 'object' && obj.width != null && obj.height != null
811 }
812
813 var util = /*#__PURE__*/Object.freeze({
814 __proto__: null,
815 imagePromise: imagePromise,
816 imageToImageBitmap: imageToImageBitmap,
817 imageBitmapRendererCtx: imageBitmapRendererCtx,
818 imageBitmap2dCtx: imageBitmap2dCtx,
819 imageBitmapData: imageBitmapData,
820 canvasToBlob: canvasToBlob,
821 AsyncFunction: AsyncFunction,
822 blobToData: blobToData,
823 fetchData: fetchData,
824 fetchJson: fetchJson,
825 fetchText: fetchText,
826 toDataURL: toDataURL,
827 blobsEqual: blobsEqual,
828 downloadCanvas: downloadCanvas,
829 downloadBlob: downloadBlob,
830 xhrPromise: xhrPromise,
831 pause: pause,
832 timeoutLoop: timeoutLoop,
833 waitPromise: waitPromise,
834 createCanvas: createCanvas,
835 createCtx: createCtx,
836 cloneCanvas: cloneCanvas,
837 resizeCtx: resizeCtx,
838 resizeCanvas: resizeCanvas,
839 setCanvasSize: setCanvasSize,
840 setIdentity: setIdentity,
841 setTextProperties: setTextProperties,
842 drawText: drawText,
843 ctxImageData: ctxImageData,
844 ctxImageColors: ctxImageColors,
845 ctxImagePixels: ctxImagePixels,
846 clearCtx: clearCtx,
847 imageToCtx: imageToCtx,
848 imageToCanvas: imageToCanvas,
849 fillCtxWithImage: fillCtxWithImage,
850 setCtxImage: setCtxImage,
851 skipErrorChecks: skipErrorChecks,
852 checkArg: checkArg$1,
853 checkArgs: checkArgs$1,
854 logOnce: logOnce,
855 warn: warn,
856 timeit: timeit,
857 fps: fps,
858 pps: pps,
859 toWindow: toWindow,
860 logAll: logAll,
861 dump: dump,
862 addCssLink: addCssLink,
863 fetchCssStyle: fetchCssStyle,
864 addCssStyle: addCssStyle,
865 getQueryString: getQueryString,
866 parseQueryString: parseQueryString,
867 RESTapi: RESTapi,
868 inWorker: inWorker,
869 inNode: inNode,
870 inDeno: inDeno,
871 printToPage: printToPage,
872 getEventXY: getEventXY,
873 fcnToWorker: fcnToWorker,
874 PI: PI$2,
875 randomInt: randomInt,
876 randomInt2: randomInt2,
877 randomFloat: randomFloat,
878 randomFloat2: randomFloat2,
879 randomCentered: randomCentered,
880 randomNormal: randomNormal,
881 randomSeed: randomSeed,
882 precision: precision,
883 isPowerOf2: isPowerOf2,
884 nextPowerOf2: nextPowerOf2,
885 mod: mod,
886 wrap: wrap,
887 clamp: clamp,
888 isBetween: isBetween,
889 lerp: lerp,
890 lerpScale: lerpScale,
891 toDeg: toDeg$1,
892 toRad: toRad$1,
893 degToRad: degToRad,
894 radToDeg: radToDeg,
895 radToHeading: radToHeading,
896 headingToRad: headingToRad,
897 radToHeadingAngle: radToHeadingAngle,
898 headingAngleToRad: headingAngleToRad,
899 degToHeading: degToHeading,
900 headingToDeg: headingToDeg,
901 mod360: mod360,
902 mod2pi: mod2pi,
903 modpipi: modpipi,
904 mod180180: mod180180,
905 degreesEqual: degreesEqual,
906 radsEqual: radsEqual,
907 headingsEq: headingsEq,
908 subtractRadians: subtractRadians,
909 subtractDegrees: subtractDegrees,
910 subtractHeadings: subtractHeadings,
911 radiansTowardXY: radiansTowardXY,
912 headingTowardXY: headingTowardXY,
913 degreesTowardXY: degreesTowardXY,
914 sqDistance: sqDistance,
915 distance: distance,
916 sqDistance3: sqDistance3,
917 distance3: distance3,
918 inCone: inCone,
919 toJSON: toJSON$2,
920 sampleModel: sampleModel,
921 identityFcn: identityFcn,
922 noopFcn: noopFcn,
923 propFcn: propFcn,
924 arraysEqual: arraysEqual$1,
925 removeArrayItem: removeArrayItem,
926 arraysToString: arraysToString,
927 forLoop: forLoop,
928 repeat: repeat,
929 step: step,
930 range: range,
931 override: override,
932 concatArrays: concatArrays,
933 objectToString: objectToString,
934 objectsEqual: objectsEqual,
935 oneOf: oneOf,
936 otherOneOf: otherOneOf,
937 oneKeyOf: oneKeyOf,
938 oneValOf: oneValOf,
939 sortNums: sortNums,
940 sortObjs: sortObjs,
941 shuffle: shuffle,
942 union: union,
943 intersection: intersection,
944 difference: difference,
945 floatRamp: floatRamp,
946 integerRamp: integerRamp,
947 nestedProperty: nestedProperty,
948 arrayLast: arrayLast,
949 arrayMax: arrayMax$1,
950 arrayMin: arrayMin,
951 arrayExtent: arrayExtent,
952 arraysDiff: arraysDiff,
953 arrayToMatrix: arrayToMatrix,
954 matrixToArray: matrixToArray,
955 isOofA: isOofA,
956 toOofA: toOofA,
957 oofaObject: oofaObject,
958 toAofO: toAofO,
959 oofaBuffers: oofaBuffers,
960 typeOf: typeOf,
961 isType: isType,
962 isOneOfTypes: isOneOfTypes,
963 isString: isString,
964 isObject: isObject$1,
965 isArray: isArray,
966 isNumber: isNumber$1,
967 isInteger: isInteger,
968 isFunction: isFunction,
969 isImage: isImage,
970 isCanvas: isCanvas,
971 isImageable: isImageable,
972 isTypedArray: isTypedArray,
973 isUintArray: isUintArray,
974 isIntArray: isIntArray,
975 isFloatArray: isFloatArray,
976 isArrayLike: isArrayLike,
977 isColorLikeArray: isColorLikeArray,
978 isLittleEndian: isLittleEndian,
979 convertArrayType: convertArrayType,
980 isDataSet: isDataSet
981 });
982
983 async function toContext(img) {
984 const type = typeOf(img);
985 switch (type) {
986 case 'string':
987 img = await imagePromise(img);
988 case 'htmlimageelement':
989 return imageToCtx(img)
990 case 'htmlcanvaselement':
991 case 'offscreencanvas':
992 return img.getContext('2d')
993 case 'canvasrenderingcontext2d':
994 return img
995 default:
996 throw Error('toContext: bad img type: ' + type)
997 }
998 }
999 function toUint8Array(msg) {
1000 const type = typeOf(msg);
1001 switch (type) {
1002 case 'number':
1003 msg = String.fromCharCode(msg);
1004 case 'string':
1005 return new TextEncoder().encode(msg)
1006 case 'uint8array':
1007 case 'uint8clampedarray':
1008 return msg
1009 default:
1010 throw Error('toUint8Array: bad msg type: ' + type)
1011 }
1012 }
1013 function charToBits(char) {
1014 return [
1015 char >> bits[0].shift,
1016 (char >> bits[1].shift) & bits[1].msgMask,
1017 char & bits[2].msgMask,
1018 ]
1019 }
1020 const bits = [
1021 { shift: 5, msgMask: 0b00000111, dataMask: 0b11111000 },
1022 { shift: 3, msgMask: 0b00000011, dataMask: 0b11111100 },
1023 { shift: 0, msgMask: 0b00000111, dataMask: 0b11111000 },
1024 ];
1025 function checkSize(msg, width, height) {
1026 const imgSize = width * height;
1027 if (imgSize < msg.length)
1028 throw Error(`encode: image size < msg.length: ${imgSize} ${msg.length}`)
1029 }
1030 function stegMsgSize(imgData) {
1031 for (let i = 3; i < imgData.length; i = i + 4) {
1032 if (imgData[i] === 254) return (i - 3) / 4
1033 }
1034 throw Error(
1035 `decode: no message terminator in image data, length = ${imgData.length}`
1036 )
1037 }
1038 async function encode(img, msg) {
1039 const ctx = await toContext(img);
1040 const { width, height } = ctx.canvas;
1041 checkSize(msg, width, height);
1042 const msgArray = toUint8Array(msg);
1043 console.log('msg buffer', msgArray);
1044 const imageData = ctx.getImageData(0, 0, width, height);
1045 const data = imageData.data;
1046 console.log('imgageData.data', data);
1047 let ix;
1048 msgArray.forEach((char, i) => {
1049 const [ch0, ch1, ch2] = charToBits(char);
1050 ix = i * 4;
1051 data[ix] = (data[ix++] & bits[0].dataMask) + ch0;
1052 data[ix] = (data[ix++] & bits[1].dataMask) + ch1;
1053 data[ix] = (data[ix++] & bits[2].dataMask) + ch2;
1054 data[ix] = 255;
1055 });
1056 data[ix + 4] = 254;
1057 console.log('encoded imgageData.data', data);
1058 ctx.putImageData(imageData, 0, 0);
1059 console.log('msg length', msg.length);
1060 console.log('encode: embedded msg size', stegMsgSize(data));
1061 return ctx
1062 }
1063 async function decode(img, returnU8 = false) {
1064 const ctx = await toContext(img);
1065 const { width, height } = ctx.canvas;
1066 const data = ctx.getImageData(0, 0, width, height).data;
1067 const msgSize = stegMsgSize(data);
1068 console.log('decode: embedded msg size', msgSize);
1069 const msgArray = new Uint8Array(msgSize);
1070 msgArray.forEach((char, i) => {
1071 let ix = i * 4;
1072 const ch0 = (bits[0].msgMask & data[ix++]) << bits[0].shift;
1073 const ch1 = (bits[1].msgMask & data[ix++]) << bits[1].shift;
1074 const ch2 = (bits[2].msgMask & data[ix++]) << bits[2].shift;
1075 msgArray[i] = ch0 + ch1 + ch2;
1076 });
1077 console.log('decode msgArray', msgArray);
1078 if (returnU8) return msgArray
1079 return new TextDecoder().decode(msgArray)
1080 }
1081
1082 var steg = /*#__PURE__*/Object.freeze({
1083 __proto__: null,
1084 stegMsgSize: stegMsgSize,
1085 encode: encode,
1086 decode: decode
1087 });
1088
1089 var earthRadius = 6371008.8;
1090 var factors = {
1091 centimeters: earthRadius * 100,
1092 centimetres: earthRadius * 100,
1093 degrees: earthRadius / 111325,
1094 feet: earthRadius * 3.28084,
1095 inches: earthRadius * 39.37,
1096 kilometers: earthRadius / 1000,
1097 kilometres: earthRadius / 1000,
1098 meters: earthRadius,
1099 metres: earthRadius,
1100 miles: earthRadius / 1609.344,
1101 millimeters: earthRadius * 1000,
1102 millimetres: earthRadius * 1000,
1103 nauticalmiles: earthRadius / 1852,
1104 radians: 1,
1105 yards: earthRadius * 1.0936,
1106 };
1107 var areaFactors = {
1108 acres: 0.000247105,
1109 centimeters: 10000,
1110 centimetres: 10000,
1111 feet: 10.763910417,
1112 hectares: 0.0001,
1113 inches: 1550.003100006,
1114 kilometers: 0.000001,
1115 kilometres: 0.000001,
1116 meters: 1,
1117 metres: 1,
1118 miles: 3.86e-7,
1119 millimeters: 1000000,
1120 millimetres: 1000000,
1121 yards: 1.195990046,
1122 };
1123 function feature(geom, properties, options) {
1124 if (options === void 0) { options = {}; }
1125 var feat = { type: "Feature" };
1126 if (options.id === 0 || options.id) {
1127 feat.id = options.id;
1128 }
1129 if (options.bbox) {
1130 feat.bbox = options.bbox;
1131 }
1132 feat.properties = properties || {};
1133 feat.geometry = geom;
1134 return feat;
1135 }
1136 function geometry(type, coordinates, _options) {
1137 switch (type) {
1138 case "Point":
1139 return point(coordinates).geometry;
1140 case "LineString":
1141 return lineString(coordinates).geometry;
1142 case "Polygon":
1143 return polygon(coordinates).geometry;
1144 case "MultiPoint":
1145 return multiPoint(coordinates).geometry;
1146 case "MultiLineString":
1147 return multiLineString(coordinates).geometry;
1148 case "MultiPolygon":
1149 return multiPolygon(coordinates).geometry;
1150 default:
1151 throw new Error(type + " is invalid");
1152 }
1153 }
1154 function point(coordinates, properties, options) {
1155 if (options === void 0) { options = {}; }
1156 if (!coordinates) {
1157 throw new Error("coordinates is required");
1158 }
1159 if (!Array.isArray(coordinates)) {
1160 throw new Error("coordinates must be an Array");
1161 }
1162 if (coordinates.length < 2) {
1163 throw new Error("coordinates must be at least 2 numbers long");
1164 }
1165 if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) {
1166 throw new Error("coordinates must contain numbers");
1167 }
1168 var geom = {
1169 type: "Point",
1170 coordinates: coordinates,
1171 };
1172 return feature(geom, properties, options);
1173 }
1174 function points(coordinates, properties, options) {
1175 if (options === void 0) { options = {}; }
1176 return featureCollection(coordinates.map(function (coords) {
1177 return point(coords, properties);
1178 }), options);
1179 }
1180 function polygon(coordinates, properties, options) {
1181 if (options === void 0) { options = {}; }
1182 for (var _i = 0, coordinates_1 = coordinates; _i < coordinates_1.length; _i++) {
1183 var ring = coordinates_1[_i];
1184 if (ring.length < 4) {
1185 throw new Error("Each LinearRing of a Polygon must have 4 or more Positions.");
1186 }
1187 for (var j = 0; j < ring[ring.length - 1].length; j++) {
1188 if (ring[ring.length - 1][j] !== ring[0][j]) {
1189 throw new Error("First and last Position are not equivalent.");
1190 }
1191 }
1192 }
1193 var geom = {
1194 type: "Polygon",
1195 coordinates: coordinates,
1196 };
1197 return feature(geom, properties, options);
1198 }
1199 function polygons(coordinates, properties, options) {
1200 if (options === void 0) { options = {}; }
1201 return featureCollection(coordinates.map(function (coords) {
1202 return polygon(coords, properties);
1203 }), options);
1204 }
1205 function lineString(coordinates, properties, options) {
1206 if (options === void 0) { options = {}; }
1207 if (coordinates.length < 2) {
1208 throw new Error("coordinates must be an array of two or more positions");
1209 }
1210 var geom = {
1211 type: "LineString",
1212 coordinates: coordinates,
1213 };
1214 return feature(geom, properties, options);
1215 }
1216 function lineStrings(coordinates, properties, options) {
1217 if (options === void 0) { options = {}; }
1218 return featureCollection(coordinates.map(function (coords) {
1219 return lineString(coords, properties);
1220 }), options);
1221 }
1222 function featureCollection(features, options) {
1223 if (options === void 0) { options = {}; }
1224 var fc = { type: "FeatureCollection" };
1225 if (options.id) {
1226 fc.id = options.id;
1227 }
1228 if (options.bbox) {
1229 fc.bbox = options.bbox;
1230 }
1231 fc.features = features;
1232 return fc;
1233 }
1234 function multiLineString(coordinates, properties, options) {
1235 if (options === void 0) { options = {}; }
1236 var geom = {
1237 type: "MultiLineString",
1238 coordinates: coordinates,
1239 };
1240 return feature(geom, properties, options);
1241 }
1242 function multiPoint(coordinates, properties, options) {
1243 if (options === void 0) { options = {}; }
1244 var geom = {
1245 type: "MultiPoint",
1246 coordinates: coordinates,
1247 };
1248 return feature(geom, properties, options);
1249 }
1250 function multiPolygon(coordinates, properties, options) {
1251 if (options === void 0) { options = {}; }
1252 var geom = {
1253 type: "MultiPolygon",
1254 coordinates: coordinates,
1255 };
1256 return feature(geom, properties, options);
1257 }
1258 function geometryCollection(geometries, properties, options) {
1259 if (options === void 0) { options = {}; }
1260 var geom = {
1261 type: "GeometryCollection",
1262 geometries: geometries,
1263 };
1264 return feature(geom, properties, options);
1265 }
1266 function radiansToLength(radians, units) {
1267 if (units === void 0) { units = "kilometers"; }
1268 var factor = factors[units];
1269 if (!factor) {
1270 throw new Error(units + " units is invalid");
1271 }
1272 return radians * factor;
1273 }
1274 function lengthToRadians(distance, units) {
1275 if (units === void 0) { units = "kilometers"; }
1276 var factor = factors[units];
1277 if (!factor) {
1278 throw new Error(units + " units is invalid");
1279 }
1280 return distance / factor;
1281 }
1282 function lengthToDegrees(distance, units) {
1283 return radiansToDegrees(lengthToRadians(distance, units));
1284 }
1285 function bearingToAzimuth(bearing) {
1286 var angle = bearing % 360;
1287 if (angle < 0) {
1288 angle += 360;
1289 }
1290 return angle;
1291 }
1292 function radiansToDegrees(radians) {
1293 var degrees = radians % (2 * Math.PI);
1294 return (degrees * 180) / Math.PI;
1295 }
1296 function convertLength(length, originalUnit, finalUnit) {
1297 if (originalUnit === void 0) { originalUnit = "kilometers"; }
1298 if (finalUnit === void 0) { finalUnit = "kilometers"; }
1299 if (!(length >= 0)) {
1300 throw new Error("length must be a positive number");
1301 }
1302 return radiansToLength(lengthToRadians(length, originalUnit), finalUnit);
1303 }
1304 function convertArea(area, originalUnit, finalUnit) {
1305 if (originalUnit === void 0) { originalUnit = "meters"; }
1306 if (finalUnit === void 0) { finalUnit = "kilometers"; }
1307 if (!(area >= 0)) {
1308 throw new Error("area must be a positive number");
1309 }
1310 var startFactor = areaFactors[originalUnit];
1311 if (!startFactor) {
1312 throw new Error("invalid original units");
1313 }
1314 var finalFactor = areaFactors[finalUnit];
1315 if (!finalFactor) {
1316 throw new Error("invalid final units");
1317 }
1318 return (area / startFactor) * finalFactor;
1319 }
1320 function isNumber(num) {
1321 return !isNaN(num) && num !== null && !Array.isArray(num);
1322 }
1323 function isObject(input) {
1324 return !!input && input.constructor === Object;
1325 }
1326 function coordEach(geojson, callback, excludeWrapCoord) {
1327 if (geojson === null) return;
1328 var j,
1329 k,
1330 l,
1331 geometry,
1332 stopG,
1333 coords,
1334 geometryMaybeCollection,
1335 wrapShrink = 0,
1336 coordIndex = 0,
1337 isGeometryCollection,
1338 type = geojson.type,
1339 isFeatureCollection = type === "FeatureCollection",
1340 isFeature = type === "Feature",
1341 stop = isFeatureCollection ? geojson.features.length : 1;
1342 for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
1343 geometryMaybeCollection = isFeatureCollection
1344 ? geojson.features[featureIndex].geometry
1345 : isFeature
1346 ? geojson.geometry
1347 : geojson;
1348 isGeometryCollection = geometryMaybeCollection
1349 ? geometryMaybeCollection.type === "GeometryCollection"
1350 : false;
1351 stopG = isGeometryCollection
1352 ? geometryMaybeCollection.geometries.length
1353 : 1;
1354 for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
1355 var multiFeatureIndex = 0;
1356 var geometryIndex = 0;
1357 geometry = isGeometryCollection
1358 ? geometryMaybeCollection.geometries[geomIndex]
1359 : geometryMaybeCollection;
1360 if (geometry === null) continue;
1361 coords = geometry.coordinates;
1362 var geomType = geometry.type;
1363 wrapShrink =
1364 excludeWrapCoord &&
1365 (geomType === "Polygon" || geomType === "MultiPolygon")
1366 ? 1
1367 : 0;
1368 switch (geomType) {
1369 case null:
1370 break;
1371 case "Point":
1372 if (
1373 callback(
1374 coords,
1375 coordIndex,
1376 featureIndex,
1377 multiFeatureIndex,
1378 geometryIndex
1379 ) === false
1380 )
1381 return false;
1382 coordIndex++;
1383 multiFeatureIndex++;
1384 break;
1385 case "LineString":
1386 case "MultiPoint":
1387 for (j = 0; j < coords.length; j++) {
1388 if (
1389 callback(
1390 coords[j],
1391 coordIndex,
1392 featureIndex,
1393 multiFeatureIndex,
1394 geometryIndex
1395 ) === false
1396 )
1397 return false;
1398 coordIndex++;
1399 if (geomType === "MultiPoint") multiFeatureIndex++;
1400 }
1401 if (geomType === "LineString") multiFeatureIndex++;
1402 break;
1403 case "Polygon":
1404 case "MultiLineString":
1405 for (j = 0; j < coords.length; j++) {
1406 for (k = 0; k < coords[j].length - wrapShrink; k++) {
1407 if (
1408 callback(
1409 coords[j][k],
1410 coordIndex,
1411 featureIndex,
1412 multiFeatureIndex,
1413 geometryIndex
1414 ) === false
1415 )
1416 return false;
1417 coordIndex++;
1418 }
1419 if (geomType === "MultiLineString") multiFeatureIndex++;
1420 if (geomType === "Polygon") geometryIndex++;
1421 }
1422 if (geomType === "Polygon") multiFeatureIndex++;
1423 break;
1424 case "MultiPolygon":
1425 for (j = 0; j < coords.length; j++) {
1426 geometryIndex = 0;
1427 for (k = 0; k < coords[j].length; k++) {
1428 for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
1429 if (
1430 callback(
1431 coords[j][k][l],
1432 coordIndex,
1433 featureIndex,
1434 multiFeatureIndex,
1435 geometryIndex
1436 ) === false
1437 )
1438 return false;
1439 coordIndex++;
1440 }
1441 geometryIndex++;
1442 }
1443 multiFeatureIndex++;
1444 }
1445 break;
1446 case "GeometryCollection":
1447 for (j = 0; j < geometry.geometries.length; j++)
1448 if (
1449 coordEach(geometry.geometries[j], callback, excludeWrapCoord) ===
1450 false
1451 )
1452 return false;
1453 break;
1454 default:
1455 throw new Error("Unknown Geometry Type");
1456 }
1457 }
1458 }
1459 }
1460 function coordReduce(geojson, callback, initialValue, excludeWrapCoord) {
1461 var previousValue = initialValue;
1462 coordEach(
1463 geojson,
1464 function (
1465 currentCoord,
1466 coordIndex,
1467 featureIndex,
1468 multiFeatureIndex,
1469 geometryIndex
1470 ) {
1471 if (coordIndex === 0 && initialValue === undefined)
1472 previousValue = currentCoord;
1473 else
1474 previousValue = callback(
1475 previousValue,
1476 currentCoord,
1477 coordIndex,
1478 featureIndex,
1479 multiFeatureIndex,
1480 geometryIndex
1481 );
1482 },
1483 excludeWrapCoord
1484 );
1485 return previousValue;
1486 }
1487 function propEach(geojson, callback) {
1488 var i;
1489 switch (geojson.type) {
1490 case "FeatureCollection":
1491 for (i = 0; i < geojson.features.length; i++) {
1492 if (callback(geojson.features[i].properties, i) === false) break;
1493 }
1494 break;
1495 case "Feature":
1496 callback(geojson.properties, 0);
1497 break;
1498 }
1499 }
1500 function propReduce(geojson, callback, initialValue) {
1501 var previousValue = initialValue;
1502 propEach(geojson, function (currentProperties, featureIndex) {
1503 if (featureIndex === 0 && initialValue === undefined)
1504 previousValue = currentProperties;
1505 else
1506 previousValue = callback(previousValue, currentProperties, featureIndex);
1507 });
1508 return previousValue;
1509 }
1510 function featureEach(geojson, callback) {
1511 if (geojson.type === "Feature") {
1512 callback(geojson, 0);
1513 } else if (geojson.type === "FeatureCollection") {
1514 for (var i = 0; i < geojson.features.length; i++) {
1515 if (callback(geojson.features[i], i) === false) break;
1516 }
1517 }
1518 }
1519 function featureReduce(geojson, callback, initialValue) {
1520 var previousValue = initialValue;
1521 featureEach(geojson, function (currentFeature, featureIndex) {
1522 if (featureIndex === 0 && initialValue === undefined)
1523 previousValue = currentFeature;
1524 else previousValue = callback(previousValue, currentFeature, featureIndex);
1525 });
1526 return previousValue;
1527 }
1528 function coordAll(geojson) {
1529 var coords = [];
1530 coordEach(geojson, function (coord) {
1531 coords.push(coord);
1532 });
1533 return coords;
1534 }
1535 function geomEach(geojson, callback) {
1536 var i,
1537 j,
1538 g,
1539 geometry,
1540 stopG,
1541 geometryMaybeCollection,
1542 isGeometryCollection,
1543 featureProperties,
1544 featureBBox,
1545 featureId,
1546 featureIndex = 0,
1547 isFeatureCollection = geojson.type === "FeatureCollection",
1548 isFeature = geojson.type === "Feature",
1549 stop = isFeatureCollection ? geojson.features.length : 1;
1550 for (i = 0; i < stop; i++) {
1551 geometryMaybeCollection = isFeatureCollection
1552 ? geojson.features[i].geometry
1553 : isFeature
1554 ? geojson.geometry
1555 : geojson;
1556 featureProperties = isFeatureCollection
1557 ? geojson.features[i].properties
1558 : isFeature
1559 ? geojson.properties
1560 : {};
1561 featureBBox = isFeatureCollection
1562 ? geojson.features[i].bbox
1563 : isFeature
1564 ? geojson.bbox
1565 : undefined;
1566 featureId = isFeatureCollection
1567 ? geojson.features[i].id
1568 : isFeature
1569 ? geojson.id
1570 : undefined;
1571 isGeometryCollection = geometryMaybeCollection
1572 ? geometryMaybeCollection.type === "GeometryCollection"
1573 : false;
1574 stopG = isGeometryCollection
1575 ? geometryMaybeCollection.geometries.length
1576 : 1;
1577 for (g = 0; g < stopG; g++) {
1578 geometry = isGeometryCollection
1579 ? geometryMaybeCollection.geometries[g]
1580 : geometryMaybeCollection;
1581 if (geometry === null) {
1582 if (
1583 callback(
1584 null,
1585 featureIndex,
1586 featureProperties,
1587 featureBBox,
1588 featureId
1589 ) === false
1590 )
1591 return false;
1592 continue;
1593 }
1594 switch (geometry.type) {
1595 case "Point":
1596 case "LineString":
1597 case "MultiPoint":
1598 case "Polygon":
1599 case "MultiLineString":
1600 case "MultiPolygon": {
1601 if (
1602 callback(
1603 geometry,
1604 featureIndex,
1605 featureProperties,
1606 featureBBox,
1607 featureId
1608 ) === false
1609 )
1610 return false;
1611 break;
1612 }
1613 case "GeometryCollection": {
1614 for (j = 0; j < geometry.geometries.length; j++) {
1615 if (
1616 callback(
1617 geometry.geometries[j],
1618 featureIndex,
1619 featureProperties,
1620 featureBBox,
1621 featureId
1622 ) === false
1623 )
1624 return false;
1625 }
1626 break;
1627 }
1628 default:
1629 throw new Error("Unknown Geometry Type");
1630 }
1631 }
1632 featureIndex++;
1633 }
1634 }
1635 function geomReduce(geojson, callback, initialValue) {
1636 var previousValue = initialValue;
1637 geomEach(
1638 geojson,
1639 function (
1640 currentGeometry,
1641 featureIndex,
1642 featureProperties,
1643 featureBBox,
1644 featureId
1645 ) {
1646 if (featureIndex === 0 && initialValue === undefined)
1647 previousValue = currentGeometry;
1648 else
1649 previousValue = callback(
1650 previousValue,
1651 currentGeometry,
1652 featureIndex,
1653 featureProperties,
1654 featureBBox,
1655 featureId
1656 );
1657 }
1658 );
1659 return previousValue;
1660 }
1661 function flattenEach(geojson, callback) {
1662 geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) {
1663 var type = geometry === null ? null : geometry.type;
1664 switch (type) {
1665 case null:
1666 case "Point":
1667 case "LineString":
1668 case "Polygon":
1669 if (
1670 callback(
1671 feature(geometry, properties, { bbox: bbox, id: id }),
1672 featureIndex,
1673 0
1674 ) === false
1675 )
1676 return false;
1677 return;
1678 }
1679 var geomType;
1680 switch (type) {
1681 case "MultiPoint":
1682 geomType = "Point";
1683 break;
1684 case "MultiLineString":
1685 geomType = "LineString";
1686 break;
1687 case "MultiPolygon":
1688 geomType = "Polygon";
1689 break;
1690 }
1691 for (
1692 var multiFeatureIndex = 0;
1693 multiFeatureIndex < geometry.coordinates.length;
1694 multiFeatureIndex++
1695 ) {
1696 var coordinate = geometry.coordinates[multiFeatureIndex];
1697 var geom = {
1698 type: geomType,
1699 coordinates: coordinate,
1700 };
1701 if (
1702 callback(feature(geom, properties), featureIndex, multiFeatureIndex) ===
1703 false
1704 )
1705 return false;
1706 }
1707 });
1708 }
1709 function flattenReduce(geojson, callback, initialValue) {
1710 var previousValue = initialValue;
1711 flattenEach(
1712 geojson,
1713 function (currentFeature, featureIndex, multiFeatureIndex) {
1714 if (
1715 featureIndex === 0 &&
1716 multiFeatureIndex === 0 &&
1717 initialValue === undefined
1718 )
1719 previousValue = currentFeature;
1720 else
1721 previousValue = callback(
1722 previousValue,
1723 currentFeature,
1724 featureIndex,
1725 multiFeatureIndex
1726 );
1727 }
1728 );
1729 return previousValue;
1730 }
1731 function segmentEach(geojson, callback) {
1732 flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {
1733 var segmentIndex = 0;
1734 if (!feature.geometry) return;
1735 var type = feature.geometry.type;
1736 if (type === "Point" || type === "MultiPoint") return;
1737 var previousCoords;
1738 var previousFeatureIndex = 0;
1739 var previousMultiIndex = 0;
1740 var prevGeomIndex = 0;
1741 if (
1742 coordEach(
1743 feature,
1744 function (
1745 currentCoord,
1746 coordIndex,
1747 featureIndexCoord,
1748 multiPartIndexCoord,
1749 geometryIndex
1750 ) {
1751 if (
1752 previousCoords === undefined ||
1753 featureIndex > previousFeatureIndex ||
1754 multiPartIndexCoord > previousMultiIndex ||
1755 geometryIndex > prevGeomIndex
1756 ) {
1757 previousCoords = currentCoord;
1758 previousFeatureIndex = featureIndex;
1759 previousMultiIndex = multiPartIndexCoord;
1760 prevGeomIndex = geometryIndex;
1761 segmentIndex = 0;
1762 return;
1763 }
1764 var currentSegment = lineString(
1765 [previousCoords, currentCoord],
1766 feature.properties
1767 );
1768 if (
1769 callback(
1770 currentSegment,
1771 featureIndex,
1772 multiFeatureIndex,
1773 geometryIndex,
1774 segmentIndex
1775 ) === false
1776 )
1777 return false;
1778 segmentIndex++;
1779 previousCoords = currentCoord;
1780 }
1781 ) === false
1782 )
1783 return false;
1784 });
1785 }
1786 function segmentReduce(geojson, callback, initialValue) {
1787 var previousValue = initialValue;
1788 var started = false;
1789 segmentEach(
1790 geojson,
1791 function (
1792 currentSegment,
1793 featureIndex,
1794 multiFeatureIndex,
1795 geometryIndex,
1796 segmentIndex
1797 ) {
1798 if (started === false && initialValue === undefined)
1799 previousValue = currentSegment;
1800 else
1801 previousValue = callback(
1802 previousValue,
1803 currentSegment,
1804 featureIndex,
1805 multiFeatureIndex,
1806 geometryIndex,
1807 segmentIndex
1808 );
1809 started = true;
1810 }
1811 );
1812 return previousValue;
1813 }
1814 function lineEach(geojson, callback) {
1815 if (!geojson) throw new Error("geojson is required");
1816 flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {
1817 if (feature.geometry === null) return;
1818 var type = feature.geometry.type;
1819 var coords = feature.geometry.coordinates;
1820 switch (type) {
1821 case "LineString":
1822 if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false)
1823 return false;
1824 break;
1825 case "Polygon":
1826 for (
1827 var geometryIndex = 0;
1828 geometryIndex < coords.length;
1829 geometryIndex++
1830 ) {
1831 if (
1832 callback(
1833 lineString(coords[geometryIndex], feature.properties),
1834 featureIndex,
1835 multiFeatureIndex,
1836 geometryIndex
1837 ) === false
1838 )
1839 return false;
1840 }
1841 break;
1842 }
1843 });
1844 }
1845 function lineReduce(geojson, callback, initialValue) {
1846 var previousValue = initialValue;
1847 lineEach(
1848 geojson,
1849 function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {
1850 if (featureIndex === 0 && initialValue === undefined)
1851 previousValue = currentLine;
1852 else
1853 previousValue = callback(
1854 previousValue,
1855 currentLine,
1856 featureIndex,
1857 multiFeatureIndex,
1858 geometryIndex
1859 );
1860 }
1861 );
1862 return previousValue;
1863 }
1864 function findSegment(geojson, options) {
1865 options = options || {};
1866 if (!isObject(options)) throw new Error("options is invalid");
1867 var featureIndex = options.featureIndex || 0;
1868 var multiFeatureIndex = options.multiFeatureIndex || 0;
1869 var geometryIndex = options.geometryIndex || 0;
1870 var segmentIndex = options.segmentIndex || 0;
1871 var properties = options.properties;
1872 var geometry;
1873 switch (geojson.type) {
1874 case "FeatureCollection":
1875 if (featureIndex < 0)
1876 featureIndex = geojson.features.length + featureIndex;
1877 properties = properties || geojson.features[featureIndex].properties;
1878 geometry = geojson.features[featureIndex].geometry;
1879 break;
1880 case "Feature":
1881 properties = properties || geojson.properties;
1882 geometry = geojson.geometry;
1883 break;
1884 case "Point":
1885 case "MultiPoint":
1886 return null;
1887 case "LineString":
1888 case "Polygon":
1889 case "MultiLineString":
1890 case "MultiPolygon":
1891 geometry = geojson;
1892 break;
1893 default:
1894 throw new Error("geojson is invalid");
1895 }
1896 if (geometry === null) return null;
1897 var coords = geometry.coordinates;
1898 switch (geometry.type) {
1899 case "Point":
1900 case "MultiPoint":
1901 return null;
1902 case "LineString":
1903 if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1;
1904 return lineString(
1905 [coords[segmentIndex], coords[segmentIndex + 1]],
1906 properties,
1907 options
1908 );
1909 case "Polygon":
1910 if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;
1911 if (segmentIndex < 0)
1912 segmentIndex = coords[geometryIndex].length + segmentIndex - 1;
1913 return lineString(
1914 [
1915 coords[geometryIndex][segmentIndex],
1916 coords[geometryIndex][segmentIndex + 1],
1917 ],
1918 properties,
1919 options
1920 );
1921 case "MultiLineString":
1922 if (multiFeatureIndex < 0)
1923 multiFeatureIndex = coords.length + multiFeatureIndex;
1924 if (segmentIndex < 0)
1925 segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1;
1926 return lineString(
1927 [
1928 coords[multiFeatureIndex][segmentIndex],
1929 coords[multiFeatureIndex][segmentIndex + 1],
1930 ],
1931 properties,
1932 options
1933 );
1934 case "MultiPolygon":
1935 if (multiFeatureIndex < 0)
1936 multiFeatureIndex = coords.length + multiFeatureIndex;
1937 if (geometryIndex < 0)
1938 geometryIndex = coords[multiFeatureIndex].length + geometryIndex;
1939 if (segmentIndex < 0)
1940 segmentIndex =
1941 coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1;
1942 return lineString(
1943 [
1944 coords[multiFeatureIndex][geometryIndex][segmentIndex],
1945 coords[multiFeatureIndex][geometryIndex][segmentIndex + 1],
1946 ],
1947 properties,
1948 options
1949 );
1950 }
1951 throw new Error("geojson is invalid");
1952 }
1953 function findPoint(geojson, options) {
1954 options = options || {};
1955 if (!isObject(options)) throw new Error("options is invalid");
1956 var featureIndex = options.featureIndex || 0;
1957 var multiFeatureIndex = options.multiFeatureIndex || 0;
1958 var geometryIndex = options.geometryIndex || 0;
1959 var coordIndex = options.coordIndex || 0;
1960 var properties = options.properties;
1961 var geometry;
1962 switch (geojson.type) {
1963 case "FeatureCollection":
1964 if (featureIndex < 0)
1965 featureIndex = geojson.features.length + featureIndex;
1966 properties = properties || geojson.features[featureIndex].properties;
1967 geometry = geojson.features[featureIndex].geometry;
1968 break;
1969 case "Feature":
1970 properties = properties || geojson.properties;
1971 geometry = geojson.geometry;
1972 break;
1973 case "Point":
1974 case "MultiPoint":
1975 return null;
1976 case "LineString":
1977 case "Polygon":
1978 case "MultiLineString":
1979 case "MultiPolygon":
1980 geometry = geojson;
1981 break;
1982 default:
1983 throw new Error("geojson is invalid");
1984 }
1985 if (geometry === null) return null;
1986 var coords = geometry.coordinates;
1987 switch (geometry.type) {
1988 case "Point":
1989 return point(coords, properties, options);
1990 case "MultiPoint":
1991 if (multiFeatureIndex < 0)
1992 multiFeatureIndex = coords.length + multiFeatureIndex;
1993 return point(coords[multiFeatureIndex], properties, options);
1994 case "LineString":
1995 if (coordIndex < 0) coordIndex = coords.length + coordIndex;
1996 return point(coords[coordIndex], properties, options);
1997 case "Polygon":
1998 if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;
1999 if (coordIndex < 0)
2000 coordIndex = coords[geometryIndex].length + coordIndex;
2001 return point(coords[geometryIndex][coordIndex], properties, options);
2002 case "MultiLineString":
2003 if (multiFeatureIndex < 0)
2004 multiFeatureIndex = coords.length + multiFeatureIndex;
2005 if (coordIndex < 0)
2006 coordIndex = coords[multiFeatureIndex].length + coordIndex;
2007 return point(coords[multiFeatureIndex][coordIndex], properties, options);
2008 case "MultiPolygon":
2009 if (multiFeatureIndex < 0)
2010 multiFeatureIndex = coords.length + multiFeatureIndex;
2011 if (geometryIndex < 0)
2012 geometryIndex = coords[multiFeatureIndex].length + geometryIndex;
2013 if (coordIndex < 0)
2014 coordIndex =
2015 coords[multiFeatureIndex][geometryIndex].length - coordIndex;
2016 return point(
2017 coords[multiFeatureIndex][geometryIndex][coordIndex],
2018 properties,
2019 options
2020 );
2021 }
2022 throw new Error("geojson is invalid");
2023 }
2024 function bbox(geojson) {
2025 var result = [Infinity, Infinity, -Infinity, -Infinity];
2026 coordEach(geojson, function (coord) {
2027 if (result[0] > coord[0]) {
2028 result[0] = coord[0];
2029 }
2030 if (result[1] > coord[1]) {
2031 result[1] = coord[1];
2032 }
2033 if (result[2] < coord[0]) {
2034 result[2] = coord[0];
2035 }
2036 if (result[3] < coord[1]) {
2037 result[3] = coord[1];
2038 }
2039 });
2040 return result;
2041 }
2042 bbox["default"] = bbox;
2043 function bboxPolygon(bbox, options) {
2044 if (options === void 0) { options = {}; }
2045 var west = Number(bbox[0]);
2046 var south = Number(bbox[1]);
2047 var east = Number(bbox[2]);
2048 var north = Number(bbox[3]);
2049 if (bbox.length === 6) {
2050 throw new Error("@turf/bbox-polygon does not support BBox with 6 positions");
2051 }
2052 var lowLeft = [west, south];
2053 var topLeft = [west, north];
2054 var topRight = [east, north];
2055 var lowRight = [east, south];
2056 return polygon([[lowLeft, lowRight, topRight, topLeft, lowLeft]], options.properties, { bbox: bbox, id: options.id });
2057 }
2058 function getCoord(coord) {
2059 if (!coord) {
2060 throw new Error("coord is required");
2061 }
2062 if (!Array.isArray(coord)) {
2063 if (coord.type === "Feature" &&
2064 coord.geometry !== null &&
2065 coord.geometry.type === "Point") {
2066 return coord.geometry.coordinates;
2067 }
2068 if (coord.type === "Point") {
2069 return coord.coordinates;
2070 }
2071 }
2072 if (Array.isArray(coord) &&
2073 coord.length >= 2 &&
2074 !Array.isArray(coord[0]) &&
2075 !Array.isArray(coord[1])) {
2076 return coord;
2077 }
2078 throw new Error("coord must be GeoJSON Point or an Array of numbers");
2079 }
2080 function getCoords(coords) {
2081 if (Array.isArray(coords)) {
2082 return coords;
2083 }
2084 if (coords.type === "Feature") {
2085 if (coords.geometry !== null) {
2086 return coords.geometry.coordinates;
2087 }
2088 }
2089 else {
2090 if (coords.coordinates) {
2091 return coords.coordinates;
2092 }
2093 }
2094 throw new Error("coords must be GeoJSON Feature, Geometry Object or an Array");
2095 }
2096 function containsNumber(coordinates) {
2097 if (coordinates.length > 1 &&
2098 isNumber(coordinates[0]) &&
2099 isNumber(coordinates[1])) {
2100 return true;
2101 }
2102 if (Array.isArray(coordinates[0]) && coordinates[0].length) {
2103 return containsNumber(coordinates[0]);
2104 }
2105 throw new Error("coordinates must only contain numbers");
2106 }
2107 function geojsonType(value, type, name) {
2108 if (!type || !name) {
2109 throw new Error("type and name required");
2110 }
2111 if (!value || value.type !== type) {
2112 throw new Error("Invalid input to " +
2113 name +
2114 ": must be a " +
2115 type +
2116 ", given " +
2117 value.type);
2118 }
2119 }
2120 function featureOf(feature, type, name) {
2121 if (!feature) {
2122 throw new Error("No feature passed");
2123 }
2124 if (!name) {
2125 throw new Error(".featureOf() requires a name");
2126 }
2127 if (!feature || feature.type !== "Feature" || !feature.geometry) {
2128 throw new Error("Invalid input to " + name + ", Feature with geometry required");
2129 }
2130 if (!feature.geometry || feature.geometry.type !== type) {
2131 throw new Error("Invalid input to " +
2132 name +
2133 ": must be a " +
2134 type +
2135 ", given " +
2136 feature.geometry.type);
2137 }
2138 }
2139 function collectionOf(featureCollection, type, name) {
2140 if (!featureCollection) {
2141 throw new Error("No featureCollection passed");
2142 }
2143 if (!name) {
2144 throw new Error(".collectionOf() requires a name");
2145 }
2146 if (!featureCollection || featureCollection.type !== "FeatureCollection") {
2147 throw new Error("Invalid input to " + name + ", FeatureCollection required");
2148 }
2149 for (var _i = 0, _a = featureCollection.features; _i < _a.length; _i++) {
2150 var feature = _a[_i];
2151 if (!feature || feature.type !== "Feature" || !feature.geometry) {
2152 throw new Error("Invalid input to " + name + ", Feature with geometry required");
2153 }
2154 if (!feature.geometry || feature.geometry.type !== type) {
2155 throw new Error("Invalid input to " +
2156 name +
2157 ": must be a " +
2158 type +
2159 ", given " +
2160 feature.geometry.type);
2161 }
2162 }
2163 }
2164 function getGeom(geojson) {
2165 if (geojson.type === "Feature") {
2166 return geojson.geometry;
2167 }
2168 return geojson;
2169 }
2170 function getType(geojson, _name) {
2171 if (geojson.type === "FeatureCollection") {
2172 return "FeatureCollection";
2173 }
2174 if (geojson.type === "GeometryCollection") {
2175 return "GeometryCollection";
2176 }
2177 if (geojson.type === "Feature" && geojson.geometry !== null) {
2178 return geojson.geometry.type;
2179 }
2180 return geojson.type;
2181 }
2182 function booleanPointInPolygon(point, polygon, options) {
2183 if (options === void 0) { options = {}; }
2184 if (!point) {
2185 throw new Error("point is required");
2186 }
2187 if (!polygon) {
2188 throw new Error("polygon is required");
2189 }
2190 var pt = getCoord(point);
2191 var geom = getGeom(polygon);
2192 var type = geom.type;
2193 var bbox = polygon.bbox;
2194 var polys = geom.coordinates;
2195 if (bbox && inBBox(pt, bbox) === false) {
2196 return false;
2197 }
2198 if (type === "Polygon") {
2199 polys = [polys];
2200 }
2201 var insidePoly = false;
2202 for (var i = 0; i < polys.length && !insidePoly; i++) {
2203 if (inRing(pt, polys[i][0], options.ignoreBoundary)) {
2204 var inHole = false;
2205 var k = 1;
2206 while (k < polys[i].length && !inHole) {
2207 if (inRing(pt, polys[i][k], !options.ignoreBoundary)) {
2208 inHole = true;
2209 }
2210 k++;
2211 }
2212 if (!inHole) {
2213 insidePoly = true;
2214 }
2215 }
2216 }
2217 return insidePoly;
2218 }
2219 function inRing(pt, ring, ignoreBoundary) {
2220 var isInside = false;
2221 if (ring[0][0] === ring[ring.length - 1][0] &&
2222 ring[0][1] === ring[ring.length - 1][1]) {
2223 ring = ring.slice(0, ring.length - 1);
2224 }
2225 for (var i = 0, j = ring.length - 1; i < ring.length; j = i++) {
2226 var xi = ring[i][0];
2227 var yi = ring[i][1];
2228 var xj = ring[j][0];
2229 var yj = ring[j][1];
2230 var onBoundary = pt[1] * (xi - xj) + yi * (xj - pt[0]) + yj * (pt[0] - xi) === 0 &&
2231 (xi - pt[0]) * (xj - pt[0]) <= 0 &&
2232 (yi - pt[1]) * (yj - pt[1]) <= 0;
2233 if (onBoundary) {
2234 return !ignoreBoundary;
2235 }
2236 var intersect = yi > pt[1] !== yj > pt[1] &&
2237 pt[0] < ((xj - xi) * (pt[1] - yi)) / (yj - yi) + xi;
2238 if (intersect) {
2239 isInside = !isInside;
2240 }
2241 }
2242 return isInside;
2243 }
2244 function inBBox(pt, bbox) {
2245 return (bbox[0] <= pt[0] && bbox[1] <= pt[1] && bbox[2] >= pt[0] && bbox[3] >= pt[1]);
2246 }
2247
2248 var turfImports = /*#__PURE__*/Object.freeze({
2249 __proto__: null,
2250 bbox: bbox,
2251 bboxPolygon: bboxPolygon,
2252 bearingToAzimuth: bearingToAzimuth,
2253 booleanPointInPolygon: booleanPointInPolygon,
2254 collectionOf: collectionOf,
2255 containsNumber: containsNumber,
2256 convertArea: convertArea,
2257 convertLength: convertLength,
2258 coordAll: coordAll,
2259 coordEach: coordEach,
2260 coordReduce: coordReduce,
2261 feature: feature,
2262 featureCollection: featureCollection,
2263 featureEach: featureEach,
2264 featureOf: featureOf,
2265 featureReduce: featureReduce,
2266 findPoint: findPoint,
2267 findSegment: findSegment,
2268 flattenEach: flattenEach,
2269 flattenReduce: flattenReduce,
2270 geojsonType: geojsonType,
2271 geomEach: geomEach,
2272 geomReduce: geomReduce,
2273 geometry: geometry,
2274 geometryCollection: geometryCollection,
2275 getCoord: getCoord,
2276 getCoords: getCoords,
2277 getGeom: getGeom,
2278 getType: getType,
2279 lengthToDegrees: lengthToDegrees,
2280 lengthToRadians: lengthToRadians,
2281 lineEach: lineEach,
2282 lineReduce: lineReduce,
2283 lineString: lineString,
2284 lineStrings: lineStrings,
2285 multiLineString: multiLineString,
2286 multiPoint: multiPoint,
2287 multiPolygon: multiPolygon,
2288 point: point,
2289 points: points,
2290 polygon: polygon,
2291 polygons: polygons,
2292 propEach: propEach,
2293 propReduce: propReduce,
2294 radiansToLength: radiansToLength,
2295 segmentEach: segmentEach,
2296 segmentReduce: segmentReduce
2297 });
2298
2299 class AgentArray extends Array {
2300 static get [Symbol.species]() {
2301 return AgentArray
2302 }
2303 static fromArray(array) {
2304 const aarray = Object.setPrototypeOf(array, AgentArray.prototype);
2305 return aarray
2306 }
2307 constructor(...args) {
2308 super(...args);
2309 }
2310 toArray() {
2311 Object.setPrototypeOf(this, Array.prototype);
2312 return this
2313 }
2314 isEmpty() {
2315 return this.length === 0
2316 }
2317 first() {
2318 return this[0]
2319 }
2320 last() {
2321 return this[this.length - 1]
2322 }
2323 atIndex(i) {
2324 if (this.length === 0) return undefined
2325 const index = mod(i, this.length);
2326 return this[index]
2327 }
2328 all(fcn) {
2329 return this.every(fcn)
2330 }
2331 props(key, type = AgentArray) {
2332 const result = new type(this.length);
2333 for (let i = 0; i < this.length; i++) {
2334 result[i] = this[i][key];
2335 }
2336 return result
2337 }
2338 typedSample(obj) {
2339 const result = {};
2340 forLoop(obj, (val, key) => {
2341 result[key] = this.props(key, val);
2342 });
2343 return result
2344 }
2345 uniq() {
2346 return AgentArray.from(new Set(this))
2347 }
2348 forLoop(fcn) {
2349 for (let i = 0, len = this.length; i < len; i++) {
2350 fcn(this[i], i, this);
2351 }
2352 return this
2353 }
2354 ask(fcn) {
2355 const length = this.length;
2356 for (let i = 0; i < Math.min(length, this.length); i++) {
2357 fcn(this[i], i, this);
2358 }
2359 if (length != this.length) {
2360 const name = this.name || this.constructor.name;
2361 const direction = this.length < length ? 'decreasing' : 'increasing';
2362 warn(`AgentArray.ask array mutation: ${name}: ${direction}`);
2363 }
2364 }
2365 with(fcn) {
2366 return this.filter(fcn)
2367 }
2368 other(t) {
2369 return this.filter(o => o !== t)
2370 }
2371 getValues(fcn) {
2372 const props = new AgentArray();
2373 if (isString(fcn)) {
2374 this.forLoop(obj => props.push(obj[fcn]));
2375 } else {
2376 this.forLoop(obj => props.push(fcn(obj)));
2377 }
2378 return props
2379 }
2380 count(reporter) {
2381 return this.reduce((prev, o) => prev + (reporter(o) ? 1 : 0), 0)
2382 }
2383 sum(key) {
2384 return this.reduce((prev, o) => prev + (key ? o[key] : o), 0)
2385 }
2386 avg(key) {
2387 return this.sum(key) / this.length
2388 }
2389 min(key) {
2390 return this.reduce(
2391 (prev, o) => Math.min(prev, key ? o[key] : o),
2392 Infinity
2393 )
2394 }
2395 max(key) {
2396 return this.reduce(
2397 (prev, o) => Math.max(prev, key ? o[key] : o),
2398 -Infinity
2399 )
2400 }
2401 extent(key) {
2402 return [this.min(key), this.max(key)]
2403 }
2404 histogram(key, bins = 10, min = this.min(key), max = this.max(key)) {
2405 const binSize = (max - min) / bins;
2406 const aa = new AgentArray(bins);
2407 aa.fill(0);
2408 this.ask(a => {
2409 const val = key ? a[key] : a;
2410 if (val < min || val > max) {
2411 warn(`histogram bounds error: ${val}: ${min}-${max}`);
2412 } else {
2413 let bin = Math.floor((val - min) / binSize);
2414 if (bin === bins) bin--;
2415 aa[bin]++;
2416 }
2417 });
2418 aa.parameters = { key, bins, min, max, binSize, arraySize: this.length };
2419 return aa
2420 }
2421 clone() {
2422 return this.slice(0)
2423 }
2424 shuffle() {
2425 return shuffle(this)
2426 }
2427 sortBy(reporter, ascending = true) {
2428 sortObjs(this, reporter, ascending);
2429 return this
2430 }
2431 remove(o, f) {
2432 const i = this.agentIndex(o, f);
2433 if (i !== -1) this.splice(i, 1);
2434 else warn(`remove: ${o} not in AgentArray`);
2435 return this
2436 }
2437 insert(o, f) {
2438 const i = this.sortedIndex(o, f);
2439 if (this[i] === o) throw Error('insert: item already in AgentArray')
2440 this.splice(i, 0, o);
2441 }
2442 sortedIndex(item, f = identityFcn) {
2443 if (isString(f)) f = propFcn(f);
2444 const value = f(item);
2445 let low = 0;
2446 let high = this.length;
2447 while (low < high) {
2448 const mid = (low + high) >>> 1;
2449 if (f(this[mid]) < value) {
2450 low = mid + 1;
2451 } else {
2452 high = mid;
2453 }
2454 }
2455 return low
2456 }
2457 agentIndex(item, property) {
2458 if (!property) return this.indexOf(item)
2459 const i = this.sortedIndex(item, property);
2460 return this[i] === item ? i : -1
2461 }
2462 contains(item, f) {
2463 return this.agentIndex(item, f) >= 0
2464 }
2465 oneOf() {
2466 return oneOf(this)
2467 }
2468 otherOneOf(agent) {
2469 return otherOneOf(this, agent)
2470 }
2471 otherNOf(n, item) {
2472 if (this.length < n) throw Error('AgentArray: otherNOf: length < N')
2473 return this.clone().remove(item).shuffle().slice(0, n)
2474 }
2475 minOrMaxOf(min, reporter, valueToo = false) {
2476 if (this.isEmpty()) throw Error('min/max OneOf: empty array')
2477 if (typeof reporter === 'string') reporter = propFcn(reporter);
2478 let o = null;
2479 let val = min ? Infinity : -Infinity;
2480 for (let i = 0; i < this.length; i++) {
2481 const a = this[i];
2482 const aval = reporter(a);
2483 if ((min && aval < val) || (!min && aval > val)) {
2484 [o, val] = [a, aval];
2485 }
2486 }
2487 return valueToo ? [o, val] : o
2488 }
2489 minOneOf(reporter) {
2490 return this.minOrMaxOf(true, reporter)
2491 }
2492 maxOneOf(reporter) {
2493 return this.minOrMaxOf(false, reporter)
2494 }
2495 minValOf(reporter) {
2496 return this.minOrMaxOf(true, reporter, true)
2497 }
2498 maxValOf(reporter) {
2499 return this.minOrMaxOf(false, reporter, true)
2500 }
2501 nOf(n) {
2502 if (n > this.length) throw Error('nOf: n larger than AgentArray')
2503 if (n === this.length) return this
2504 const result = new AgentArray();
2505 while (result.length < n) {
2506 const o = this.oneOf();
2507 if (!(o in result)) result.push(o);
2508 }
2509 return result
2510 }
2511 minOrMaxNOf(min, n, reporter) {
2512 if (n > this.length) {
2513 throw Error('min/max nOf: n larger than AgentArray')
2514 }
2515 const as = this.clone().sortBy(reporter);
2516 return min ? as.slice(0, n) : as.slice(as.length - n)
2517 }
2518 minNOf(n, reporter) {
2519 return this.minOrMaxNOf(true, n, reporter)
2520 }
2521 maxNOf(n, reporter) {
2522 return this.minOrMaxNOf(false, n, reporter)
2523 }
2524 }
2525
2526 class AgentList extends AgentArray {
2527 constructor(model, ...args) {
2528 if (!model) throw Error('AgentList requires model')
2529 super(...args);
2530 this.model = model;
2531 }
2532 inRect(agent, dx, dy = dx, meToo = false) {
2533 const agents = new AgentList(this.model);
2534 const minX = agent.x - dx;
2535 const maxX = agent.x + dx;
2536 const minY = agent.y - dy;
2537 const maxY = agent.y + dy;
2538 this.ask(a => {
2539 if (minX <= a.x && a.x <= maxX && minY <= a.y && a.y <= maxY) {
2540 if (meToo || agent !== a) agents.push(a);
2541 }
2542 });
2543 return agents
2544 }
2545 inRadius(agent, radius, meToo = false) {
2546 const agents = new AgentList(this.model);
2547 const d2 = radius * radius;
2548 const sqDistance$1 = sqDistance;
2549 this.ask(a => {
2550 if (sqDistance$1(agent.x, agent.y, a.x, a.y) <= d2) {
2551 if (meToo || agent !== a) agents.push(a);
2552 }
2553 });
2554 return agents
2555 }
2556 inCone(agent, radius, coneAngle, heading, meToo = false) {
2557 heading = this.model.toRads(heading);
2558 coneAngle = this.model.toAngleRads(coneAngle);
2559 const agents = new AgentList(this.model);
2560 this.ask(a => {
2561 if (
2562 inCone(
2563 a.x,
2564 a.y,
2565 radius,
2566 coneAngle,
2567 heading,
2568 agent.x,
2569 agent.y
2570 )
2571 ) {
2572 if (meToo || agent !== a) agents.push(a);
2573 }
2574 });
2575 return agents
2576 }
2577 }
2578
2579 class AgentSet extends AgentArray {
2580 model
2581 name
2582 baseSet
2583 AgentClass
2584 static get [Symbol.species]() {
2585 return AgentArray
2586 }
2587 constructor(model, AgentClass, name, baseSet = null) {
2588 super();
2589 baseSet = baseSet || this;
2590 Object.assign(this, { model, name, baseSet, AgentClass });
2591 if (this.isBaseSet()) {
2592 this.breeds = {};
2593 this.ID = 0;
2594 } else {
2595 Object.setPrototypeOf(this, Object.getPrototypeOf(baseSet));
2596 this.baseSet.breeds[name] = this;
2597 }
2598 this.ownVariables = [];
2599 this.agentProto = new AgentClass(this);
2600 this.protoMixin(this.agentProto, AgentClass);
2601 }
2602 protoMixin(agentProto, AgentClass) {
2603 Object.assign(agentProto, {
2604 agentSet: this,
2605 model: this.model,
2606 });
2607 agentProto[this.baseSet.name] = this.baseSet;
2608 if (!AgentClass.prototype.setBreed) {
2609 Object.assign(AgentClass.prototype, {
2610 setBreed(breed) {
2611 breed.setBreed(this);
2612 },
2613 getBreed() {
2614 return this.agentSet
2615 },
2616 isBreed(breed) {
2617 return this.agentSet === breed
2618 },
2619 });
2620 Object.defineProperty(AgentClass.prototype, 'breed', {
2621 get: function () {
2622 return this.agentSet
2623 },
2624 });
2625 }
2626 }
2627 newBreed(name) {
2628 return new AgentSet(this.model, this.AgentClass, name, this)
2629 }
2630 isBreedSet() {
2631 return this.baseSet !== this
2632 }
2633 isBaseSet() {
2634 return this.baseSet === this
2635 }
2636 withBreed(breed) {
2637 return this.filter(a => a.agentSet === breed)
2638 }
2639 create() {
2640 console.log(`AgentSet: Abstract method called: ${this}`);
2641 }
2642 addAgent(o = undefined) {
2643 o = o || Object.create(this.agentProto);
2644 if (this.isBreedSet()) {
2645 this.baseSet.addAgent(o);
2646 } else {
2647 o.id = this.ID++;
2648 if (o.agentConstructor) o.agentConstructor();
2649 }
2650 this.push(o);
2651 return o
2652 }
2653 clear() {
2654 while (!this.isEmpty()) this.last().die();
2655 }
2656 removeAgent(o) {
2657 if (o.id != -1) {
2658 if (this.isBreedSet()) this.baseSet.remove(o, 'id');
2659 this.remove(o, 'id');
2660 }
2661 return this
2662 }
2663 setDefault(name, value) {
2664 this.agentProto[name] = value;
2665 return this
2666 }
2667 getDefault(name) {
2668 return this.agentProto[name]
2669 }
2670 setBreed(a) {
2671 if (a.agentSet === this) return
2672 if (a.agentSet.isBreedSet()) a.agentSet.remove(a, 'id');
2673 if (this.isBreedSet()) this.insert(a, 'id');
2674 const avars = a.agentSet.ownVariables;
2675 for (const avar of avars) {
2676 if (!this.ownVariables.includes(avar)) delete a[avar];
2677 }
2678 for (const ownvar of this.ownVariables) {
2679 if (!avars.includes(ownvar)) a[ownvar] = 0;
2680 }
2681 return Object.setPrototypeOf(a, this.agentProto)
2682 }
2683 ask(fcn) {
2684 if (this.length === 0) return
2685 const lastID = this.last().id;
2686 for (let i = 0; i < this.length && this[i].id <= lastID; i++) {
2687 fcn(this[i], i, this);
2688 }
2689 }
2690 askSet(fcn) {
2691 if (this.length === 0) return
2692 if (this.name === 'patches') super.forLoop(fcn);
2693 else if (this.isBaseSet()) this.baseSetAsk(fcn);
2694 else if (this.isBreedSet()) this.cloneAsk(fcn);
2695 }
2696 baseSetAsk(fcn) {
2697 if (this.length === 0) return
2698 const lastID = this.last().id;
2699 for (let i = 0; i < this.length; i++) {
2700 const obj = this[i];
2701 const id = obj.id;
2702 if (id > lastID) break
2703 fcn(obj, i, this);
2704 if (i >= this.length) break
2705 if (this[i].id > id) {
2706 while (i >= 0 && this[i].id > id) i--;
2707 }
2708 }
2709 }
2710 cloneAsk(fcn) {
2711 const clone = this.clone();
2712 for (let i = 0; i < clone.length; i++) {
2713 const obj = clone[i];
2714 if (obj.breed == this && obj.id > 0) {
2715 fcn(obj, i, clone);
2716 }
2717 }
2718 }
2719 }
2720
2721 class DataSet {
2722 width
2723 height
2724 data
2725 static emptyDataSet(width, height, Type = Array) {
2726 return new DataSet(width, height, new Type(width * height))
2727 }
2728 constructor(width, height, data) {
2729 if (data.length !== width * height) {
2730 throw Error(
2731 `new DataSet length: ${data.length} !== ${width} * ${height}`
2732 )
2733 }
2734 Object.assign(this, { width, height, data });
2735 }
2736 checkXY(x, y) {
2737 if (!this.inBounds(x, y)) {
2738 throw Error(`DataSet: x,y out of range: ${x}, ${y}`)
2739 }
2740 }
2741 inBounds(x, y) {
2742 return (
2743 isBetween(x, 0, this.width - 1) &&
2744 isBetween(y, 0, this.height - 1)
2745 )
2746 }
2747 dataType() {
2748 return this.data.constructor
2749 }
2750 type() {
2751 return this.constructor
2752 }
2753 toIndex(x, y) {
2754 return x + y * this.width
2755 }
2756 toXY(i) {
2757 return [i % this.width, Math.floor(i / this.width)]
2758 }
2759 getXY(x, y) {
2760 return this.data[this.toIndex(x, y)]
2761 }
2762 setXY(x, y, num) {
2763 this.data[this.toIndex(x, y)] = num;
2764 }
2765 sample(x, y, useNearest = true) {
2766 this.checkXY(x, y);
2767 return useNearest ? this.nearest(x, y) : this.bilinear(x, y)
2768 }
2769 nearest(x, y) {
2770 return this.getXY(Math.round(x), Math.round(y))
2771 }
2772 bilinear(x, y) {
2773 const x0 = Math.floor(x);
2774 const y0 = Math.floor(y);
2775 const i = this.toIndex(x0, y0);
2776 const w = this.width;
2777 const dx = x - x0;
2778 const dy = y - y0;
2779 const dx1 = 1 - dx;
2780 const dy1 = 1 - dy;
2781 const f00 = this.data[i];
2782 const f10 = this.data[i + 1] || 0;
2783 const f01 = this.data[i + w] || 0;
2784 const f11 = this.data[i + 1 + w] || 0;
2785 return f00 * dx1 * dy1 + f10 * dx * dy1 + f01 * dx1 * dy + f11 * dx * dy
2786 }
2787 clone() {
2788 return new DataSet(this.width, this.height, this.data.slice(0))
2789 }
2790 emptyDataSet(width, height, type = this.dataType()) {
2791 return DataSet.emptyDataSet(width, height, type)
2792 }
2793 emptyArray(length) {
2794 const Type = this.type();
2795 return new Type(length)
2796 }
2797 resample(width, height, useNearest = true, Type = Array) {
2798 if (width === this.width && height === this.height) return this.clone()
2799 const ds = DataSet.emptyDataSet(width, height, Type);
2800 for (let y = 0; y < height; y++) {
2801 for (let x = 0; x < width; x++) {
2802 ds.setXY(
2803 x,
2804 y,
2805 this.sample(
2806 (x * (this.width - 1)) / (width - 1),
2807 (y * (this.height - 1)) / (height - 1),
2808 useNearest
2809 )
2810 );
2811 }
2812 }
2813 return ds
2814 }
2815 scale(min, max) {
2816 const dsMin = this.min();
2817 const dsMax = this.max();
2818 const dsDelta = dsMax - dsMin;
2819 const delta = max - min;
2820 const m = delta / dsDelta;
2821 const b = min - m * dsMin;
2822 return this.map(x => m * x + b)
2823 }
2824 subset(x, y, width, height) {
2825 if (x + width > this.width || y + height > this.height) {
2826 console.log('subset: x+width', x + width, 'this.width', this.width);
2827 console.log(
2828 'subset: y+height',
2829 y + height,
2830 'this.height',
2831 this.height
2832 );
2833 throw Error('DataSet.subSet: params out of range')
2834 }
2835 const ds = this.emptyDataSet(width, height);
2836 for (let i = 0; i < width; i++) {
2837 for (let j = 0; j < height; j++) {
2838 ds.setXY(i, j, this.getXY(i + x, j + y));
2839 }
2840 }
2841 return ds
2842 }
2843 crop(top, bottom, left, right) {
2844 if (bottom === undefined) {
2845 var { top, bottom, left, right } = top;
2846 }
2847 const width = this.width - left - right;
2848 const height = this.height - top - bottom;
2849 return this.subset(left, top, width, height)
2850 }
2851 map(f) {
2852 return new DataSet(this.width, this.height, this.data.map(f))
2853 }
2854 col(x) {
2855 const [w, h, data] = [this.width, this.height, this.data];
2856 if (x >= w) throw Error(`col: x out of range width: ${w} x: ${x}`)
2857 const colData = this.emptyArray(h);
2858 for (let i = 0; i < h; i++) colData[i] = data[x + i * w];
2859 return colData
2860 }
2861 row(y) {
2862 const [w, h] = [this.width, this.height];
2863 if (y >= h) throw Error(`row: y out of range height: ${h} x: ${y}`)
2864 return this.data.slice(y * w, (y + 1) * w)
2865 }
2866 convertType(type) {
2867 this.data = convertArrayType(this.data, type);
2868 }
2869 concatEast(ds) {
2870 const [w, h] = [this.width, this.height];
2871 const [w1, h1] = [ds.width, ds.height];
2872 if (h !== h1) throw Error(`concatEast: heights not equal ${h}, ${h1}`)
2873 const ds1 = this.emptyDataSet(w + w1, h);
2874 for (let x = 0; x < w; x++) {
2875 for (let y = 0; y < h; y++) {
2876 ds1.setXY(x, y, this.getXY(x, y));
2877 }
2878 }
2879 for (let x = 0; x < w1; x++) {
2880 for (let y = 0; y < h1; y++) {
2881 ds1.setXY(x + w, y, ds.getXY(x, y));
2882 }
2883 }
2884 return ds1
2885 }
2886 concatSouth(dataset) {
2887 const [w, h, data] = [this.width, this.height, this.data];
2888 if (w !== dataset.width) {
2889 throw Error(`concatSouth: widths not equal ${w}, ${dataset.width}`)
2890 }
2891 const data1 = concatArrays(data, dataset.data);
2892 return new DataSet(w, h + dataset.height, data1)
2893 }
2894 transformCoords(x, y, tlx, tly, w, h) {
2895 const xs = ((x - tlx) * (this.width - 1)) / w;
2896 const ys = ((tly - y) * (this.height - 1)) / h;
2897 return [xs, ys]
2898 }
2899 coordSample(x, y, tlx, tly, w, h, useNearest = true) {
2900 const [xs, ys] = this.transformCoords(x, y, tlx, tly, w, h);
2901 return this.sample(xs, ys, useNearest)
2902 }
2903 neighborhood(x, y, array = []) {
2904 array.length = 0;
2905 const clampNeeded =
2906 x === 0 || x === this.width - 1 || y === 0 || y === this.height - 1;
2907 for (let dy = -1; dy <= +1; dy++) {
2908 for (let dx = -1; dx <= +1; dx++) {
2909 let x0 = x + dx;
2910 let y0 = y + dy;
2911 if (clampNeeded) {
2912 x0 = clamp(x0, 0, this.width - 1);
2913 y0 = clamp(y0, 0, this.height - 1);
2914 }
2915 array.push(this.data[this.toIndex(x0, y0)]);
2916 }
2917 }
2918 return array
2919 }
2920 convolve(kernel, factor = 1, crop = false) {
2921 const [x0, y0, h, w] = crop
2922 ? [1, 1, this.height - 1, this.width - 1]
2923 : [0, 0, this.height, this.width];
2924 const newDS = this.emptyDataSet(w, h);
2925 const newData = newDS.data;
2926 let i = 0;
2927 for (let y = y0; y < h; y++) {
2928 for (let x = x0; x < w; x++) {
2929 const nei = this.neighborhood(x, y);
2930 let sum2 = 0;
2931 for (let i2 = 0; i2 < kernel.length; i2++) {
2932 sum2 = sum2 + kernel[i2] * nei[i2];
2933 }
2934 newData[i++] = sum2 * factor;
2935 }
2936 }
2937 return newDS
2938 }
2939 dzdx(n = 2, factor = 1 / 8) {
2940 return this.convolve([-1, 0, 1, -n, 0, n, -1, 0, 1], factor)
2941 }
2942 dzdy(n = 2, factor = 1 / 8) {
2943 return this.convolve([1, n, 1, 0, 0, 0, -1, -n, -1], factor)
2944 }
2945 laplace8() {
2946 return this.convolve([-1, -1, -1, -1, 8, -1, -1, -1, -1])
2947 }
2948 laplace4() {
2949 return this.convolve([0, -1, 0, -1, 4, -1, 0, -1, 0])
2950 }
2951 blur(factor = 0.0625) {
2952 return this.convolve([1, 2, 1, 2, 4, 2, 1, 2, 1], factor)
2953 }
2954 edge() {
2955 return this.convolve([1, 1, 1, 1, -7, 1, 1, 1, 1])
2956 }
2957 slopeAndAspect(cellSize = 1, posAngle = true) {
2958 const dzdx = this.dzdx();
2959 const dzdy = this.dzdy();
2960 let [aspect, slope] = [[], []];
2961 const [h, w] = [dzdx.height, dzdx.width];
2962 for (let y = 0; y < h; y++) {
2963 for (let x = 0; x < w; x++) {
2964 const [gx, gy] = [dzdx.getXY(x, y), dzdy.getXY(x, y)];
2965 slope.push(Math.atan(distance(0, 0, gx, gy)) / cellSize);
2966 let rad = Math.atan2(-gy, -gx);
2967 if (posAngle && rad < 0) rad += 2 * Math.PI;
2968 aspect.push(rad);
2969 }
2970 }
2971 slope = new DataSet(w, h, slope);
2972 aspect = new DataSet(w, h, aspect);
2973 return { slope, aspect, dzdx, dzdy }
2974 }
2975 max() {
2976 return this.data.reduce((a, b) => Math.max(a, b))
2977 }
2978 min() {
2979 return this.data.reduce((a, b) => Math.min(a, b))
2980 }
2981 extent() {
2982 return [this.min(), this.max()]
2983 }
2984 sum() {
2985 return this.data.reduce((a, b) => a + b)
2986 }
2987 normalize(lo = 0, hi = 1, round = false) {
2988 const [min, max] = this.extent();
2989 const scale = 1 / (max - min);
2990 let data = this.data.map(n => lerp(lo, hi, scale * (n - min)));
2991 if (round) data = data.map(n => Math.round(n));
2992 return new DataSet(this.width, this.height, data)
2993 }
2994 equals(dataset) {
2995 return (
2996 this.width === dataset.width &&
2997 this.height === dataset.height &&
2998 arraysEqual$1(this.data, dataset.data)
2999 )
3000 }
3001 }
3002
3003 class Link {
3004 hidden = false
3005 end0 = null
3006 end1 = null
3007 width = 1
3008 agentSet
3009 model
3010 name
3011 init(from, to) {
3012 this.end0 = from;
3013 this.end1 = to;
3014 from.links.push(this);
3015 to.links.push(this);
3016 }
3017 die() {
3018 if (this.id === -1) return
3019 this.agentSet.removeAgent(this);
3020 removeArrayItem(this.end0.links, this);
3021 removeArrayItem(this.end1.links, this);
3022 this.id = -1;
3023 }
3024 isDead() {
3025 return this.id === -1
3026 }
3027 bothEnds() {
3028 return AgentArray.fromArray([this.end0, this.end1])
3029 }
3030 length() {
3031 return this.end0.distance(this.end1)
3032 }
3033 get heading() {
3034 const { x0, x1, y0, y1 } = this;
3035 const rads = Math.atan2(y1 - y0, x1 - x0);
3036 return this.model.fromRads(rads)
3037 }
3038 otherEnd(turtle) {
3039 if (turtle === this.end0) return this.end1
3040 if (turtle === this.end1) return this.end0
3041 throw Error(`Link.otherEnd: turtle not a link turtle: ${turtle}`)
3042 }
3043 distanceXY(x, y) {
3044 return (
3045 this.bothEnds()
3046 .map(t => t.distanceXY(x, y))
3047 .sum() - this.length()
3048 )
3049 }
3050 get x0() {
3051 return this.end0.x
3052 }
3053 get y0() {
3054 return this.end0.y
3055 }
3056 get z0() {
3057 return this.end0.z ? this.end0.z : 0
3058 }
3059 get x1() {
3060 return this.end1.x
3061 }
3062 get y1() {
3063 return this.end1.y
3064 }
3065 get z1() {
3066 return this.end1.z ? this.end1.z : 0
3067 }
3068 }
3069
3070 class Links extends AgentSet {
3071 createOne(from, to, initFcn = link => {}) {
3072 const link = this.addAgent();
3073 link.init(from, to);
3074 initFcn(link);
3075 return link
3076 }
3077 create(from, to, initFcn = link => {}) {
3078 if (!Array.isArray(to)) to = [to];
3079 return to.map(t => {
3080 return this.createOne(from, t, initFcn)
3081 })
3082 }
3083 }
3084
3085 class World {
3086 maxX = 16
3087 minX = -16
3088 maxY = 16
3089 minY = -16
3090 maxZ = 16
3091 minZ = -16
3092 static defaultOptions(maxX = 16, maxY = maxX, maxZ = Math.max(maxX, maxY)) {
3093 return {
3094 minX: -maxX,
3095 maxX: maxX,
3096 minY: -maxY,
3097 maxY: maxY,
3098 minZ: -maxZ,
3099 maxZ: maxZ,
3100 }
3101 }
3102 static defaultWorld(maxX = 16, maxY = maxX, maxZ = maxX) {
3103 return new World(World.defaultOptions(maxX, maxY, maxZ))
3104 }
3105 constructor(options = {}) {
3106 Object.assign(this, options);
3107 this.setWorld();
3108 }
3109 setWorld() {
3110 let { minX, maxX, minY, maxY, minZ, maxZ } = this;
3111 forLoop({ minX, maxX, minY, maxY, minZ, maxZ }, (val, key) => {
3112 if (!Number.isInteger(val))
3113 throw Error(`World: ${key}:${val} must be an integer`)
3114 });
3115 this.numX = this.width = maxX - minX + 1;
3116 this.numY = this.height = maxY - minY + 1;
3117 this.numZ = this.depth = maxZ - minZ + 1;
3118 this.minXcor = minX - 0.5;
3119 this.maxXcor = maxX + 0.5;
3120 this.minYcor = minY - 0.5;
3121 this.maxYcor = maxY + 0.5;
3122 this.minZcor = minZ - 0.5;
3123 this.maxZcor = maxZ + 0.5;
3124 this.centerX = (minX + maxX) / 2;
3125 this.centerY = (minY + maxY) / 2;
3126 this.centerZ = (minZ + maxZ) / 2;
3127 this.numPatches = this.numX * this.numY;
3128 }
3129 getOptions() {
3130 const { minX, minY, minZ, maxX, maxY, maxZ } = this;
3131 return { minX, minY, minZ, maxX, maxY, maxZ }
3132 }
3133 randomPoint() {
3134 return [
3135 randomFloat2(this.minXcor, this.maxXcor),
3136 randomFloat2(this.minYcor, this.maxYcor),
3137 ]
3138 }
3139 random3DPoint() {
3140 return [
3141 randomFloat2(this.minXcor, this.maxXcor),
3142 randomFloat2(this.minYcor, this.maxYcor),
3143 randomFloat2(this.minZcor, this.maxZcor),
3144 ]
3145 }
3146 randomPatchPoint() {
3147 return [
3148 randomInt2(this.minX, this.maxX),
3149 randomInt2(this.minY, this.maxY),
3150 ]
3151 }
3152 isOnWorld(x, y, z = this.centerZ) {
3153 return (
3154 this.minXcor <= x &&
3155 x <= this.maxXcor &&
3156 this.minYcor <= y &&
3157 y <= this.maxYcor &&
3158 this.minZcor <= z &&
3159 z <= this.maxZcor
3160 )
3161 }
3162 bboxTransform(minX, minY, maxX, maxY) {
3163 return new BBoxTransform(minX, minY, maxX, maxY, this)
3164 }
3165 getWorldSize(patchSize = 1) {
3166 return [this.numX * patchSize, this.numY * patchSize]
3167 }
3168 setEuclideanTransform(ctx, patchSize) {
3169 this.setCanvasSize(ctx.canvas, patchSize);
3170 ctx.restore();
3171 ctx.save();
3172 ctx.scale(patchSize, -patchSize);
3173 ctx.translate(-this.minXcor, -this.maxYcor);
3174 }
3175 patchSize(canvas) {
3176 const { numX, numY } = this;
3177 const { clientWidth: width, clientHeight: height } = canvas;
3178 const xSize = width / numX;
3179 const ySize = height / numY;
3180 if (xSize !== ySize) {
3181 throw Error(`World patchSize: x/y sizes differ ${xSize}, ${ySize}`)
3182 }
3183 return xSize
3184 }
3185 setCanvasSize(canvas, patchSize) {
3186 const [width, height] = this.getWorldSize(patchSize);
3187 setCanvasSize(canvas, width, height);
3188 }
3189 pixelXYtoPatchXY(x, y, patchSize) {
3190 return [this.minXcor + x / patchSize, this.maxYcor - y / patchSize]
3191 }
3192 patchXYtoPixelXY(x, y, patchSize) {
3193 return [(x - this.minXcor) * patchSize, (this.maxYcor - y) * patchSize]
3194 }
3195 xyToPatchIndex(x, y) {
3196 if (!this.isOnWorld(x, y)) return undefined
3197 const { minX, maxX, maxY, numX, maxXcor, maxYcor } = this;
3198 x = x === maxXcor ? maxX : Math.round(x);
3199 y = y === maxYcor ? maxY : Math.round(y);
3200 return x - minX + numX * (maxY - y)
3201 }
3202 }
3203 class BBoxTransform {
3204 constructor(minX, minY, maxX, maxY, world) {
3205 this.bbox = [minX, minY, maxX, maxY];
3206 if (minX < maxX) console.log('flipX');
3207 if (maxY < minY) console.log('flipY');
3208 if (minX < maxX) [minX, maxX] = [maxX, minX];
3209 if (maxY < minY) [maxY, minY] = [minY, maxY];
3210 const { maxXcor, maxYcor, minXcor, minYcor } = world;
3211 const mx = (minX - maxX) / (maxXcor - minXcor);
3212 const my = (maxY - minY) / (maxYcor - minYcor);
3213 const bx = (minX + maxX - mx * (maxXcor + minXcor)) / 2;
3214 const by = (maxY + minY - my * (maxYcor + minYcor)) / 2;
3215 Object.assign(this, { mx, my, bx, by });
3216 }
3217 toWorld(bboxPoint) {
3218 const { mx, my, bx, by } = this;
3219 const [bboxX, bboxY] = bboxPoint;
3220 const x = (bboxX - bx) / mx;
3221 const y = (bboxY - by) / my;
3222 return [x, y]
3223 }
3224 toBBox(worldPoint) {
3225 const { mx, my, bx, by } = this;
3226 const [worldX, worldY] = worldPoint;
3227 const x = mx * worldX + bx;
3228 const y = my * worldY + by;
3229 return [x, y]
3230 }
3231 }
3232
3233 const { PI: PI$1, atan, atan2, cos, floor, log, pow, sin, sinh, sqrt, tan, abs } =
3234 Math;
3235 const radians = degrees => (degrees * PI$1) / 180;
3236 const degrees = radians => (radians * 180) / PI$1;
3237 function latlon(lonlat) {
3238 if (typeof lonlat[0] !== 'number') return lonlat.map(val => latlon(val))
3239 return [lonlat[1], lonlat[0]]
3240 }
3241 function lonz2xFloat(lon, z) {
3242 return ((lon + 180) / 360) * pow(2, z)
3243 }
3244 function lonz2x(lon, z) {
3245 return floor(lonz2xFloat(lon, z))
3246 }
3247 function latz2yFloat(lat, z) {
3248 const latRads = radians(lat);
3249 return (1 - log(tan(latRads) + 1 / cos(latRads)) / PI$1) * pow(2, z - 1)
3250 }
3251 function latz2y(lat, z) {
3252 return floor(latz2yFloat(lat, z))
3253 }
3254 function lonlatz2xyFloat(lon, lat, z) {
3255 return [lonz2xFloat(lon, z), latz2yFloat(lat, z)]
3256 }
3257 function lonlatz2xy(lon, lat, z) {
3258 return [lonz2x(lon, z), latz2y(lat, z)]
3259 }
3260 function xz2lon(x, z) {
3261 return (x / pow(2, z)) * 360 - 180
3262 }
3263 function yz2lat(y, z) {
3264 const rads = atan(sinh(PI$1 - (2 * PI$1 * y) / pow(2, z)));
3265 return degrees(rads)
3266 }
3267 function xyz2lonlat(x, y, z) {
3268 return [xz2lon(x, z), yz2lat(y, z)]
3269 }
3270 function xyz2centerLonlat(x, y, z) {
3271 return [xz2lon(x + 0.5, z), yz2lat(y + 0.5, z)]
3272 }
3273 function xyz2bbox(x, y, z, digits = null) {
3274 const [west, north] = xyz2lonlat(x, y, z);
3275 const [east, south] = xyz2lonlat(x + 1, y + 1, z);
3276 if (!digits) return [west, south, east, north]
3277 return precision([west, south, east, north], digits)
3278 }
3279 function xyInBBox(bbox, pt) {
3280 const [west, south, east, north] = bbox;
3281 const [x, y] = pt;
3282 return isBetween(x, west, east) && isBetween(y, south, north)
3283 }
3284 function lonLatz2bbox(lon, lat, z) {
3285 const [x, y] = lonlatz2xy(lon, lat, z);
3286 return xyz2bbox(x, y, z)
3287 }
3288 function Lbounds2bbox(leafletBounds) {
3289 let { lng: west, lat: north } = leafletBounds.getNorthWest();
3290 let { lng: east, lat: south } = leafletBounds.getSouthEast();
3291 return [west, south, east, north]
3292 }
3293 function tilesBBox(bbox, z) {
3294 const [west, south, east, north] = bbox;
3295 const [westX, northY] = lonlatz2xy(west, north, z);
3296 let [eastX, southY] = lonlatz2xyFloat(east, south, z);
3297 eastX = floor(eastX);
3298 southY = Number.isInteger(southY) ? southY - 1 : floor(southY);
3299 return [westX, southY, eastX, northY]
3300 }
3301 function bboxCenter(bbox) {
3302 const [west, south, east, north] = bbox;
3303 return [(west + east) / 2, (south + north) / 2]
3304 }
3305 function bboxCoords(bbox) {
3306 const [west, south, east, north] = bbox;
3307 return [
3308 [west, north],
3309 [east, north],
3310 [east, south],
3311 [west, south],
3312 ]
3313 }
3314 function bboxBounds(bbox) {
3315 const [west, south, east, north] = bbox;
3316 return [
3317 [west, north],
3318 [east, south],
3319 ]
3320 }
3321 function bboxFeature$1(bbox, properties = {}) {
3322 const coords = bboxCoords(bbox);
3323 coords.push(coords[0]);
3324 return {
3325 type: 'Feature',
3326 geometry: {
3327 type: 'Polygon',
3328 coordinates: [coords],
3329 },
3330 properties,
3331 }
3332 }
3333 function bboxFromCenter(center, dLon = 1, dLat = dLon) {
3334 let [lon, lat] = center;
3335 return [lon - dLon, lat - dLat, lon + dLon, lat + dLat]
3336 }
3337 const santaFeCenter = [-105.978, 35.66];
3338 const santaFeBBox = bboxFromCenter(santaFeCenter, 0.2, 0.1);
3339 const newMexicoBBox = [-109.050044, 31.332301, -103.001964, 37.000104];
3340 const newMexicoCenter = bboxCenter(newMexicoBBox);
3341 const usaBBox = [-124.733174, 24.544701, -66.949895, 49.384358];
3342 const usaCenter = bboxCenter(usaBBox);
3343 function bboxSize(bbox) {
3344 const [west, south, east, north] = bbox;
3345 const width = abs(west - east);
3346 const height = abs(north - south);
3347 return [width, height]
3348 }
3349 function bboxAspect(bbox) {
3350 const [width, height] = bboxSize(bbox);
3351 return width / height
3352 }
3353 function bboxMetricSize(bbox) {
3354 const [west, south, east, north] = bbox;
3355 const topLeft = [west, north];
3356 const botLeft = [west, south];
3357 const topRight = [east, north];
3358 const width = lonLat2meters(topLeft, topRight);
3359 const height = lonLat2meters(topLeft, botLeft);
3360 return [width, height]
3361 }
3362 function bboxMetricAspect(bbox) {
3363 const [width, height] = bboxMetricSize(bbox);
3364 return width / height
3365 }
3366 function getOsmURL(south, west, north, east) {
3367 const url = 'https://overpass-api.de/api/interpreter?data=';
3368 const params = `\
3369[out:json][timeout:180][bbox:${south},${west},${north},${east}];
3370way[highway];
3371(._;>;);
3372out;`;
3373 return url + encodeURIComponent(params)
3374 }
3375 async function bbox2osm(bbox) {
3376 const [west, south, east, north] = bbox;
3377 const url = getOsmURL(south, west, north, east);
3378 const osm = await fetch(url).then(resp => resp.json());
3379 return osm
3380 }
3381 function lonLat2meters(pt1, pt2) {
3382 const [lon1, lat1] = pt1.map(val => radians(val));
3383 const [lon2, lat2] = pt2.map(val => radians(val));
3384 const R = 6378.137;
3385 const dLat = lat2 - lat1;
3386 const dLon = lon2 - lon1;
3387 const a = sin(dLat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dLon / 2) ** 2;
3388 const c = 2 * atan2(sqrt(a), sqrt(1 - a));
3389 const d = R * c;
3390 return d * 1000
3391 }
3392 function attribution(who = 'osm') {
3393 const prefix = 'Map data &copy; ';
3394 switch (who) {
3395 case 'osm':
3396 return (
3397 prefix + '<a href="https://openstreetmap.org">OpenStreetMap</a>'
3398 )
3399 case 'topo':
3400 return prefix + '<a href="https://opentopomap.org">OpenTopoMap</a>'
3401 case 'topo1':
3402 return (
3403 prefix + '<a href="https://www.maptiler.com">OpenTopoMap</a>'
3404 )
3405 case 'smooth':
3406 return prefix + '<a href="https://stadiamaps.com/">Stadia Maps</a>'
3407 case 'usgs':
3408 return (
3409 prefix +
3410 'Tiles courtesy of the <a href="https://usgs.gov/">U.S. Geological Survey</a>'
3411 )
3412 }
3413 throw Error('gis.attribution: name unknown:', who)
3414 }
3415 function template(who = 'osm') {
3416 switch (who) {
3417 case 'osm':
3418 return 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'
3419 case 'topo':
3420 return 'https://a.tile.opentopomap.org/{z}/{x}/{y}.png'
3421 case 'topo1':
3422 return 'https://api.maptiler.com/maps/topo/{z}/{x}/{y}.png?key=iQurAP6lArV1UP4gfSVs'
3423 case 'smooth':
3424 return 'https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png'
3425 case 'usgs':
3426 return 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSTopo/MapServer/tile/{z}/{y}/{x}'
3427 case 'contour':
3428 return 'https://api.maptiler.com/tiles/contours/tiles.json?key=iQurAP6lArV1UP4gfSVs'
3429 }
3430 throw Error('gis.template: name unknown:', who)
3431 }
3432 function url(z, x, y, who = 'osm') {
3433 switch (who) {
3434 case 'osm':
3435 return `https://tile.openstreetmap.org/${z}/${x}/${y}.png`
3436 case 'topo':
3437 return `https://tile.opentopomap.org/${z}/${x}/${y}.png`
3438 case 'topo1':
3439 return `https://api.maptiler.com/maps/topo/${z}/${x}/${y}.png?key=iQurAP6lArV1UP4gfSVs`
3440 case 'smooth':
3441 return `https://tiles.stadiamaps.com/tiles/alidade_smooth/${z}/${x}/${y}{r}.png`
3442 case 'usgs':
3443 return `https://basemap.nationalmap.gov/arcgis/rest/services/USGSTopo/MapServer/tile/${z}/${y}/${x}`
3444 }
3445 throw Error('gis.url: name unknown:', who)
3446 }
3447 function elevationTemplate(who = 'mapzen') {
3448 switch (who) {
3449 case 'mapzen':
3450 return `https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png`
3451 case 'maptiler':
3452 return `https://api.maptiler.com/tiles/terrain-rgb/{z}/{x}/{y}.png?key=iQurAP6lArV1UP4gfSVs`
3453 case 'redfishUSA':
3454 return `https://s3-us-west-2.amazonaws.com/simtable-elevation-tiles/{z}/{x}/{y}.png`
3455 case 'redfishWorld':
3456 return `https://s3-us-west-2.amazonaws.com/world-elevation-tiles/DEM_tiles/{z}/{x}/{y}.png`
3457 case 'mapbox':
3458 return (
3459 `https://api.mapbox.com/v4/mapbox.terrain-rgb/{z}/{x}/{y}.png?access_token=` +
3460 'pk.eyJ1IjoiYmFja3NwYWNlcyIsImEiOiJjanVrbzI4dncwOXl3M3ptcGJtN3oxMmhoIn0.x9iSCrtm0iADEqixVgPwqQ'
3461 )
3462 }
3463 throw Error('gis.elevationTemplate: name unknown:', who)
3464 }
3465
3466 var gis = /*#__PURE__*/Object.freeze({
3467 __proto__: null,
3468 latlon: latlon,
3469 lonz2xFloat: lonz2xFloat,
3470 lonz2x: lonz2x,
3471 latz2yFloat: latz2yFloat,
3472 latz2y: latz2y,
3473 lonlatz2xyFloat: lonlatz2xyFloat,
3474 lonlatz2xy: lonlatz2xy,
3475 xz2lon: xz2lon,
3476 yz2lat: yz2lat,
3477 xyz2lonlat: xyz2lonlat,
3478 xyz2centerLonlat: xyz2centerLonlat,
3479 xyz2bbox: xyz2bbox,
3480 xyInBBox: xyInBBox,
3481 lonLatz2bbox: lonLatz2bbox,
3482 Lbounds2bbox: Lbounds2bbox,
3483 tilesBBox: tilesBBox,
3484 bboxCenter: bboxCenter,
3485 bboxCoords: bboxCoords,
3486 bboxBounds: bboxBounds,
3487 bboxFeature: bboxFeature$1,
3488 bboxFromCenter: bboxFromCenter,
3489 santaFeCenter: santaFeCenter,
3490 santaFeBBox: santaFeBBox,
3491 newMexicoBBox: newMexicoBBox,
3492 newMexicoCenter: newMexicoCenter,
3493 usaBBox: usaBBox,
3494 usaCenter: usaCenter,
3495 bboxSize: bboxSize,
3496 bboxAspect: bboxAspect,
3497 bboxMetricSize: bboxMetricSize,
3498 bboxMetricAspect: bboxMetricAspect,
3499 getOsmURL: getOsmURL,
3500 bbox2osm: bbox2osm,
3501 lonLat2meters: lonLat2meters,
3502 attribution: attribution,
3503 template: template,
3504 url: url,
3505 elevationTemplate: elevationTemplate
3506 });
3507
3508 class GeoWorld extends World {
3509 static defaultOptions(bbox = newMexicoBBox, patchesWidth = 100) {
3510 return {
3511 bbox,
3512 patchesWidth,
3513 }
3514 }
3515 constructor(options = GeoWorld.defaultOptions()) {
3516 let { bbox: bbox$1, patchesWidth } = options;
3517 let json;
3518 if (!Array.isArray(bbox$1)) {
3519 json = bbox$1;
3520 bbox$1 = bbox(json);
3521 }
3522 const aspect = bboxMetricAspect(bbox$1);
3523 const maxZ = Math.round(patchesWidth / 2);
3524 super({
3525 minX: 0,
3526 maxX: patchesWidth - 1,
3527 minY: 0,
3528 maxY: Math.round(patchesWidth / aspect),
3529 minZ: -maxZ,
3530 maxZ: maxZ,
3531 });
3532 this.bbox = bbox$1;
3533 this.xfm = this.bboxTransform(...bbox$1);
3534 if (json) this.geojson = json;
3535 }
3536 toGeo(x, y) {
3537 return this.xfm.toBBox([x, y])
3538 }
3539 toWorld(geoX, geoY) {
3540 return this.xfm.toWorld([geoX, geoY])
3541 }
3542 bboxCenter() {
3543 return bboxCenter(this.bbox)
3544 }
3545 bboxCoords() {
3546 return bboxCoords(this.bbox)
3547 }
3548 bboxFeature(options = {}) {
3549 return bboxFeature$1(this.bbox, options)
3550 }
3551 }
3552
3553 class Patches extends AgentSet {
3554 constructor(model, AgentClass, name) {
3555 super(model, AgentClass, name);
3556 if (this.isBreedSet()) return
3557 this.populate();
3558 this.labels = [];
3559 }
3560 populate() {
3561 repeat(this.model.world.numX * this.model.world.numY, i => {
3562 this.addAgent();
3563 });
3564 }
3565 neighborsOffsets(x, y) {
3566 const { minX, maxX, minY, maxY, numX } = this.model.world;
3567 if (x === minX) {
3568 if (y === minY) return [-numX, -numX + 1, 1]
3569 if (y === maxY) return [1, numX + 1, numX]
3570 return [-numX, -numX + 1, 1, numX + 1, numX]
3571 }
3572 if (x === maxX) {
3573 if (y === minY) return [-numX - 1, -numX, -1]
3574 if (y === maxY) return [numX, numX - 1, -1]
3575 return [-numX - 1, -numX, numX, numX - 1, -1]
3576 }
3577 if (y === minY) return [-numX - 1, -numX, -numX + 1, 1, -1]
3578 if (y === maxY) return [1, numX + 1, numX, numX - 1, -1]
3579 return [-numX - 1, -numX, -numX + 1, 1, numX + 1, numX, numX - 1, -1]
3580 }
3581 neighbors4Offsets(x, y) {
3582 const numX = this.model.world.numX;
3583 return this.neighborsOffsets(x, y).filter(
3584 n => Math.abs(n) === 1 || Math.abs(n) === numX
3585 )
3586 }
3587 neighbors(patch) {
3588 const { id, x, y } = patch;
3589 const offsets = this.neighborsOffsets(x, y);
3590 const as = new AgentList(this.model, offsets.length);
3591 offsets.forEach((o, i) => {
3592 as[i] = this[o + id];
3593 });
3594 return as
3595 }
3596 neighbors4(patch) {
3597 const { id, x, y } = patch;
3598 const offsets = this.neighbors4Offsets(x, y);
3599 const as = new AgentList(this.model, offsets.length);
3600 offsets.forEach((o, i) => {
3601 as[i] = this[o + id];
3602 });
3603 return as
3604 }
3605 importDataSet(dataSet, property, useNearest = false) {
3606 if (this.isBreedSet()) {
3607 warn('Patches: exportDataSet called with breed, using patches');
3608 this.baseSet.importDataSet(dataSet, property, useNearest);
3609 return
3610 }
3611 const { numX, numY } = this.model.world;
3612 const dataset = dataSet.resample(numX, numY, useNearest);
3613 this.ask(p => {
3614 p[property] = dataset.data[p.id];
3615 });
3616 }
3617 exportDataSet(property, Type = Array) {
3618 if (this.isBreedSet()) {
3619 warn('Patches: exportDataSet called with breed, using patches');
3620 return this.baseSet.exportDataSet(property, Type)
3621 }
3622 const { numX, numY } = this.model.world;
3623 let data = this.props(property);
3624 data = convertArrayType(data, Type);
3625 return new DataSet(numX, numY, data)
3626 }
3627 patchIndex(x, y) {
3628 const { minX, maxY, numX } = this.model.world;
3629 return x - minX + numX * (maxY - y)
3630 }
3631 patch(x, y) {
3632 if (!this.model.world.isOnWorld(x, y)) return undefined
3633 const intX =
3634 x === this.model.world.maxXcor
3635 ? this.model.world.maxX
3636 : Math.round(x);
3637 const intY =
3638 y === this.model.world.maxYcor
3639 ? this.model.world.maxY
3640 : Math.round(y);
3641 return this.patchXY(intX, intY)
3642 }
3643 patchXY(x, y) {
3644 return this[this.patchIndex(x, y)]
3645 }
3646 patchRect(p, dx, dy = dx, meToo = true) {
3647 if (p.rectCache) {
3648 const index = this.cacheIndex(dx, dy, meToo);
3649 const rect = p.rectCache[index];
3650 if (rect) return rect
3651 }
3652 const rect = new AgentList(this.model);
3653 let { minX, maxX, minY, maxY } = this.model.world;
3654 minX = Math.max(minX, p.x - dx);
3655 maxX = Math.min(maxX, p.x + dx);
3656 minY = Math.max(minY, p.y - dy);
3657 maxY = Math.min(maxY, p.y + dy);
3658 for (let y = minY; y <= maxY; y++) {
3659 for (let x = minX; x <= maxX; x++) {
3660 const pnext = this.patchXY(x, y);
3661 if (p !== pnext || meToo) rect.push(pnext);
3662 }
3663 }
3664 return rect
3665 }
3666 patchRectXY(x, y, dx, dy = dx, meToo = true) {
3667 return this.patchRect(this.patch(x, y), dx, dy, meToo)
3668 }
3669 cacheIndex(dx, dy = dx, meToo = true) {
3670 return (2 * dx + 1) * (2 * dy + 1) + (meToo ? 0 : -1)
3671 }
3672 cacheRect(dx, dy = dx, meToo = true, clear = true) {
3673 const index = this.cacheIndex(dx, dy, meToo);
3674 this.ask(p => {
3675 if (!p.rectCache || clear) p.rectCache = [];
3676 const rect = this.inRect(p, dx, dy, meToo);
3677 p.rectCache[index] = rect;
3678 });
3679 }
3680 inRect(patch, dx, dy = dx, meToo = true) {
3681 const pRect = this.patchRect(patch, dx, dy, meToo);
3682 if (this.isBaseSet()) return pRect
3683 return pRect.withBreed(this)
3684 }
3685 inRadius(patch, radius, meToo = true) {
3686 const dxy = Math.ceil(radius);
3687 const pRect = this.inRect(patch, dxy, dxy, meToo);
3688 return pRect.inRadius(patch, radius, meToo)
3689 }
3690 inCone(patch, radius, coneAngle, heading, meToo = true) {
3691 const dxy = Math.ceil(radius);
3692 const pRect = this.inRect(patch, dxy, dxy, meToo);
3693 return pRect.inCone(patch, radius, coneAngle, heading, meToo)
3694 }
3695 patchAtHeadingAndDistance(agent, heading, distance) {
3696 heading = this.model.toRads(heading);
3697 let { x, y } = agent;
3698 x = x + distance * Math.cos(heading);
3699 y = y + distance * Math.sin(heading);
3700 return this.patch(x, y)
3701 }
3702 isOnEdge(patch) {
3703 const { x, y } = patch;
3704 const { minX, maxX, minY, maxY } = this.model.world;
3705 return x === minX || x === maxX || y === minY || y === maxY
3706 }
3707 edgePatches() {
3708 return this.filter(p => this.isOnEdge(p))
3709 }
3710 diffuse(v, rate) {
3711 this.diffuseN(8, v, rate);
3712 }
3713 diffuse4(v, rate) {
3714 this.diffuseN(4, v, rate);
3715 }
3716 diffuseN(n, v, rate) {
3717 if (this[0]._diffuseNext === undefined) {
3718 for (let i = 0; i < this.length; i++) this[i]._diffuseNext = 0;
3719 }
3720 for (let i = 0; i < this.length; i++) {
3721 const p = this[i];
3722 const dv = p[v] * rate;
3723 const dvn = dv / n;
3724 const neighbors = n === 8 ? p.neighbors : p.neighbors4;
3725 const nn = neighbors.length;
3726 p._diffuseNext += p[v] - dv + (n - nn) * dvn;
3727 for (let i = 0; i < neighbors.length; i++) {
3728 neighbors[i]._diffuseNext += dvn;
3729 }
3730 }
3731 for (let i = 0; i < this.length; i++) {
3732 const p = this[i];
3733 p[v] = p._diffuseNext;
3734 p._diffuseNext = 0;
3735 }
3736 }
3737 }
3738
3739 class Patch {
3740 agentSet
3741 model
3742 name
3743 turtles
3744 z = 0
3745 get x() {
3746 return (this.id % this.model.world.width) + this.model.world.minX
3747 }
3748 get y() {
3749 return (
3750 this.model.world.maxY - Math.floor(this.id / this.model.world.width)
3751 )
3752 }
3753 isOnEdge() {
3754 return this.patches.isOnEdge(this)
3755 }
3756 get neighbors() {
3757 const n = this.patches.neighbors(this);
3758 Object.defineProperty(this, 'neighbors', { value: n, enumerable: true });
3759 return n
3760 }
3761 get neighbors4() {
3762 const n = this.patches.neighbors4(this);
3763 Object.defineProperty(this, 'neighbors4', {
3764 value: n,
3765 enumerable: true,
3766 });
3767 return n
3768 }
3769 get turtlesHere() {
3770 if (this.turtles == null) {
3771 this.patches.ask(p => {
3772 p.turtles = new AgentList(this.model);
3773 });
3774 this.model.turtles.ask(t => {
3775 t.patch.turtles.push(t);
3776 });
3777 }
3778 return this.turtles
3779 }
3780 breedsHere(breed) {
3781 const turtles = this.turtlesHere;
3782 return turtles.withBreed(breed)
3783 }
3784 distanceXY(x, y, z = null) {
3785 const useZ = z != null && this.z != null;
3786 return useZ
3787 ? distance3(this.x, this.y, this.z, x, y, z)
3788 : distance(this.x, this.y, x, y)
3789 }
3790 distance(agent) {
3791 const { x, y, z } = agent;
3792 return this.distanceXY(x, y, z)
3793 }
3794 towards(agent) {
3795 return this.towardsXY(agent.x, agent.y)
3796 }
3797 towardsXY(x, y) {
3798 let rads = radiansTowardXY(this.x, this.y, x, y);
3799 return this.model.fromRads(rads)
3800 }
3801 patchAt(dx, dy) {
3802 return this.patches.patch(this.x + dx, this.y + dy)
3803 }
3804 patchAtHeadingAndDistance(heading, distance) {
3805 return this.patches.patchAtHeadingAndDistance(this, heading, distance)
3806 }
3807 sprout(num = 1, breed = this.model.turtles, initFcn = turtle => {}) {
3808 return breed.create(num, turtle => {
3809 turtle.setxy(this.x, this.y);
3810 initFcn(turtle);
3811 })
3812 }
3813 }
3814
3815 class Turtles extends AgentSet {
3816 constructor(model, AgentClass, name, baseSet = null) {
3817 super(model, AgentClass, name, baseSet);
3818 }
3819 createOne(initFcn = turtle => {}) {
3820 const turtle = this.addAgent();
3821 turtle.heading = this.model.fromRads(randomFloat(Math.PI * 2));
3822 const p = turtle.patch;
3823 if (p.turtles != null) {
3824 p.turtles.push(turtle);
3825 }
3826 initFcn(turtle);
3827 return turtle
3828 }
3829 create(num, initFcn = turtle => {}) {
3830 return repeat(num, (i, a) => {
3831 a.push(this.createOne(initFcn));
3832 })
3833 }
3834 closestTurtle(x, y, radius) {
3835 const ts = this.inPatchRectXY(x, y, radius);
3836 if (ts.length === 0) return null
3837 return ts.minOneOf(t => t.distanceXY(x, y))
3838 }
3839 inPatches(patches) {
3840 let array = new AgentList(this.model);
3841 for (const p of patches) array.push(...p.turtlesHere);
3842 if (this.isBreedSet()) array = array.filter(a => a.agentSet === this);
3843 return array
3844 }
3845 inPatchRect(turtle, dx, dy = dx, meToo = false) {
3846 const agents = this.inPatchRectXY(turtle.x, turtle.y, dx, dy);
3847 if (!meToo) removeArrayItem(agents, turtle);
3848 return agents
3849 }
3850 inPatchRectXY(x, y, dx, dy = dx) {
3851 const patches = this.model.patches.patchRectXY(x, y, dx, dy, true);
3852 return this.inPatches(patches)
3853 }
3854 inRadius(turtle, radius, meToo = false) {
3855 const agents = this.inPatchRect(turtle, radius, radius, true);
3856 return agents.inRadius(turtle, radius, meToo)
3857 }
3858 inCone(turtle, radius, coneAngle, meToo = false) {
3859 const agents = this.inPatchRect(turtle, radius, radius, true);
3860 return agents.inCone(turtle, radius, coneAngle, turtle.heading, meToo)
3861 }
3862 layoutCircle(radius = this.model.world.maxX * 0.9, center = [0, 0]) {
3863 const startAngle = Math.PI / 2;
3864 const direction = -1;
3865 const dTheta = (2 * Math.PI) / this.length;
3866 const [x0, y0] = center;
3867 this.ask((turtle, i) => {
3868 turtle.setxy(x0, y0);
3869 turtle.theta = startAngle + direction * dTheta * i;
3870 turtle.forward(radius);
3871 });
3872 }
3873 }
3874
3875 class Turtle {
3876 atEdge = 'wrap'
3877 hidden = false
3878 agentSet
3879 model
3880 name
3881 agentConstructor() {
3882 this.theta = null;
3883 this.x = 0;
3884 this.y = 0;
3885 this.agentSet.setDefault('z', null);
3886 }
3887 die() {
3888 if (this.id === -1) return
3889 this.agentSet.removeAgent(this);
3890 if (this.hasOwnProperty('links')) {
3891 while (this.links.length > 0) this.links[0].die();
3892 }
3893 if (this.patch && this.patch.turtles)
3894 removeArrayItem(this.patch.turtles, this);
3895 this.id = -1;
3896 }
3897 isDead() {
3898 return this.id === -1
3899 }
3900 hatch(num = 1, breed = this.agentSet, init = turtle => {}) {
3901 return breed.create(num, turtle => {
3902 turtle.setxy(this.x, this.y, this.z);
3903 turtle.theta = this.theta;
3904 for (const key of breed.ownVariables) {
3905 if (turtle[key] == null) turtle[key] = this[key];
3906 }
3907 init(turtle);
3908 })
3909 }
3910 get links() {
3911 Object.defineProperty(this, 'links', {
3912 value: new AgentList(this.model),
3913 enumerable: true,
3914 });
3915 return this.links
3916 }
3917 get patch() {
3918 return this.model.patches.patch(this.x, this.y)
3919 }
3920 get heading() {
3921 return this.model.fromRads(this.theta)
3922 }
3923 set heading(heading) {
3924 this.theta = this.model.toRads(heading);
3925 }
3926 subtractHeading(heading) {
3927 return subtractHeadings(heading, this.heading)
3928 }
3929 setxy(x, y, z = undefined) {
3930 const p0 = this.patch;
3931 this.x = x;
3932 this.y = y;
3933 if (z != null) this.z = z;
3934 this.checkXYZ(p0);
3935 }
3936 checkXYZ(p0) {
3937 this.checkEdge();
3938 this.checkPatch(p0);
3939 }
3940 checkEdge() {
3941 const { x, y, z } = this;
3942 if (!this.model.world.isOnWorld(x, y, z) && this.atEdge !== 'OK') {
3943 this.handleEdge(x, y, z);
3944 }
3945 }
3946 checkPatch(p0) {
3947 const p = this.patch;
3948 if (p != p0) {
3949 if (p0 && p0.turtles) removeArrayItem(p0.turtles, this);
3950 if (p && p.turtles) p.turtles.push(this);
3951 }
3952 }
3953 handleEdge(x, y, z = undefined) {
3954 let atEdge = this.atEdge;
3955 if (isString(atEdge)) {
3956 const { minXcor, maxXcor, minYcor, maxYcor, minZcor, maxZcor } =
3957 this.model.world;
3958 if (atEdge === 'wrap') {
3959 this.x = wrap(x, minXcor, maxXcor);
3960 this.y = wrap(y, minYcor, maxYcor);
3961 if (z != null) this.z = wrap(z, minZcor, maxZcor);
3962 } else if (atEdge === 'die') {
3963 this.die();
3964 } else if (atEdge === 'random') {
3965 this.setxy(...this.model.world.randomPoint());
3966 } else if (atEdge === 'clamp' || atEdge === 'bounce') {
3967 this.x = clamp(x, minXcor, maxXcor);
3968 this.y = clamp(y, minYcor, maxYcor);
3969 if (z != null) this.z = clamp(z, minZcor, maxZcor);
3970 if (atEdge === 'bounce') {
3971 if (this.x === minXcor || this.x === maxXcor) {
3972 this.theta = Math.PI - this.theta;
3973 } else if (this.y === minYcor || this.y === maxYcor) {
3974 this.theta = -this.theta;
3975 } else if (this.z === minZcor || this.z === maxZcor) {
3976 if (this.pitch) {
3977 this.pitch = -this.pitch;
3978 } else {
3979 this.z = wrap(z, minZcor, maxZcor);
3980 }
3981 }
3982 }
3983 } else {
3984 throw Error(`turtle.handleEdge: bad atEdge: ${atEdge}`)
3985 }
3986 } else {
3987 this.atEdge(this);
3988 }
3989 }
3990 moveTo(agent) {
3991 this.setxy(agent.x, agent.y, agent.z);
3992 }
3993 forward(d) {
3994 this.setxy(
3995 this.x + d * Math.cos(this.theta),
3996 this.y + d * Math.sin(this.theta)
3997 );
3998 }
3999 rotate(angle) {
4000 angle = this.model.toCCW(angle);
4001 this.heading += angle;
4002 }
4003 right(angle) {
4004 this.rotate(-angle);
4005 }
4006 left(angle) {
4007 this.rotate(angle);
4008 }
4009 face(agent) {
4010 this.heading = this.towards(agent);
4011 }
4012 facexy(x, y) {
4013 this.heading = this.towardsXY(x, y);
4014 }
4015 patchAhead(distance) {
4016 return this.patchAtHeadingAndDistance(this.heading, distance)
4017 }
4018 patchRightAndAhead(angle, distance) {
4019 angle = this.model.toCCW(angle);
4020 return this.patchAtHeadingAndDistance(this.heading - angle, distance)
4021 }
4022 patchLeftAndAhead(angle, distance) {
4023 return this.patchRightAndAhead(-angle, distance)
4024 }
4025 canMove(distance) {
4026 return this.patchAhead(distance) != null
4027 }
4028 distanceXY(x, y, z = null) {
4029 const useZ = z != null && this.z != null;
4030 return useZ
4031 ? distance3(this.x, this.y, this.z, x, y, z)
4032 : distance(this.x, this.y, x, y)
4033 }
4034 distance(agent) {
4035 const { x, y, z } = agent;
4036 return this.distanceXY(x, y, z)
4037 }
4038 get dx() {
4039 return Math.cos(this.theta)
4040 }
4041 get dy() {
4042 return Math.sin(this.theta)
4043 }
4044 towards(agent) {
4045 return this.towardsXY(agent.x, agent.y)
4046 }
4047 towardsXY(x, y) {
4048 let rads = radiansTowardXY(this.x, this.y, x, y);
4049 return this.model.fromRads(rads)
4050 }
4051 patchAt(dx, dy) {
4052 return this.model.patches.patch(this.x + dx, this.y + dy)
4053 }
4054 patchAtHeadingAndDistance(heading, distance) {
4055 return this.model.patches.patchAtHeadingAndDistance(
4056 this,
4057 heading,
4058 distance
4059 )
4060 }
4061 otherEnd(l) {
4062 return l.end0 === this ? l.end1 : l.end0
4063 }
4064 linkNeighbors() {
4065 return this.links.map(l => this.otherEnd(l))
4066 }
4067 isLinkNeighbor(t) {
4068 return t in this.linkNeighbors()
4069 }
4070 }
4071
4072 class Model {
4073 world
4074 patches
4075 turtles
4076 links
4077 ticks
4078 constructor(worldOptions = World.defaultOptions()) {
4079 this.resetModel(worldOptions);
4080 this.setAutoTick(true);
4081 this.setGeometry('heading');
4082 }
4083 initAgentSet(name, AgentsetClass, AgentClass) {
4084 this[name] = new AgentsetClass(this, AgentClass, name);
4085 }
4086 options2world(worldOptions) {
4087 return worldOptions.bbox
4088 ? new GeoWorld(worldOptions)
4089 : new World(worldOptions)
4090 }
4091 resetModel(worldOptions) {
4092 this.ticks = 0;
4093 this.world =
4094 worldOptions.maxXcor === undefined
4095 ? this.options2world(worldOptions)
4096 : worldOptions;
4097 this.initAgentSet('patches', Patches, Patch);
4098 this.initAgentSet('turtles', Turtles, Turtle);
4099 this.initAgentSet('links', Links, Link);
4100 }
4101 reset(worldOptions = this.world) {
4102 this.resetModel(worldOptions);
4103 }
4104 tick() {
4105 this.ticks++;
4106 }
4107 async startup() {}
4108 setup() {}
4109 step() {}
4110 setAutoTick(autoTick = true) {
4111 const isAutoTick = this.hasOwnProperty('step');
4112 if (autoTick) {
4113 if (isAutoTick) return
4114 this.step0 = this.step;
4115 this.step = this.stepAndTick;
4116 } else {
4117 delete this.step;
4118 delete this.step0;
4119 }
4120 }
4121 stepAndTick() {
4122 this.step0();
4123 this.tick();
4124 }
4125 patchBreeds(breedNames) {
4126 for (const breedName of breedNames.split(' ')) {
4127 this[breedName] = this.patches.newBreed(breedName);
4128 }
4129 }
4130 turtleBreeds(breedNames) {
4131 for (const breedName of breedNames.split(' ')) {
4132 this[breedName] = this.turtles.newBreed(breedName);
4133 }
4134 }
4135 linkBreeds(breedNames) {
4136 for (const breedName of breedNames.split(' ')) {
4137 this[breedName] = this.links.newBreed(breedName);
4138 }
4139 }
4140 setGeometry(name = 'heading') {
4141 const geometry = geometries$1[name];
4142 if (!geometry) throw Error(`setGeometry: ${name} geometry not defined`)
4143 Object.assign(this, geometry);
4144 }
4145 }
4146 const toDeg = 180 / Math.PI;
4147 const toRad = Math.PI / 180;
4148 const geometries$1 = {
4149 radians: {
4150 toRads: rads => rads,
4151 fromRads: rads => rads,
4152 toAngleRads: rads => rads,
4153 fromAngleRads: rads => rads,
4154 toCCW: angle => angle,
4155 },
4156 degrees: {
4157 toRads: deg => deg * toRad,
4158 fromRads: rads => rads * toDeg,
4159 toAngleRads: deg => deg * toRad,
4160 fromAngleRads: rads => rads * toDeg,
4161 toCCW: angle => angle,
4162 },
4163 heading: {
4164 toRads: deg => (90 - deg) * toRad,
4165 fromRads: rads => 90 - rads * toDeg,
4166 toAngleRads: deg => deg * toRad,
4167 fromAngleRads: rads => rads * toDeg,
4168 toCCW: angle => -angle,
4169 },
4170 };
4171
4172 const _lut$1 = [];
4173 for ( let i = 0; i < 256; i ++ ) {
4174 _lut$1[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 );
4175 }
4176 let _seed$1 = 1234567;
4177 const MathUtils$1 = {
4178 DEG2RAD: Math.PI / 180,
4179 RAD2DEG: 180 / Math.PI,
4180 generateUUID: function () {
4181 const d0 = Math.random() * 0xffffffff | 0;
4182 const d1 = Math.random() * 0xffffffff | 0;
4183 const d2 = Math.random() * 0xffffffff | 0;
4184 const d3 = Math.random() * 0xffffffff | 0;
4185 const uuid = _lut$1[ d0 & 0xff ] + _lut$1[ d0 >> 8 & 0xff ] + _lut$1[ d0 >> 16 & 0xff ] + _lut$1[ d0 >> 24 & 0xff ] + '-' +
4186 _lut$1[ d1 & 0xff ] + _lut$1[ d1 >> 8 & 0xff ] + '-' + _lut$1[ d1 >> 16 & 0x0f | 0x40 ] + _lut$1[ d1 >> 24 & 0xff ] + '-' +
4187 _lut$1[ d2 & 0x3f | 0x80 ] + _lut$1[ d2 >> 8 & 0xff ] + '-' + _lut$1[ d2 >> 16 & 0xff ] + _lut$1[ d2 >> 24 & 0xff ] +
4188 _lut$1[ d3 & 0xff ] + _lut$1[ d3 >> 8 & 0xff ] + _lut$1[ d3 >> 16 & 0xff ] + _lut$1[ d3 >> 24 & 0xff ];
4189 return uuid.toUpperCase();
4190 },
4191 clamp: function ( value, min, max ) {
4192 return Math.max( min, Math.min( max, value ) );
4193 },
4194 euclideanModulo: function ( n, m ) {
4195 return ( ( n % m ) + m ) % m;
4196 },
4197 mapLinear: function ( x, a1, a2, b1, b2 ) {
4198 return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
4199 },
4200 lerp: function ( x, y, t ) {
4201 return ( 1 - t ) * x + t * y;
4202 },
4203 smoothstep: function ( x, min, max ) {
4204 if ( x <= min ) return 0;
4205 if ( x >= max ) return 1;
4206 x = ( x - min ) / ( max - min );
4207 return x * x * ( 3 - 2 * x );
4208 },
4209 smootherstep: function ( x, min, max ) {
4210 if ( x <= min ) return 0;
4211 if ( x >= max ) return 1;
4212 x = ( x - min ) / ( max - min );
4213 return x * x * x * ( x * ( x * 6 - 15 ) + 10 );
4214 },
4215 randInt: function ( low, high ) {
4216 return low + Math.floor( Math.random() * ( high - low + 1 ) );
4217 },
4218 randFloat: function ( low, high ) {
4219 return low + Math.random() * ( high - low );
4220 },
4221 randFloatSpread: function ( range ) {
4222 return range * ( 0.5 - Math.random() );
4223 },
4224 seededRandom: function ( s ) {
4225 if ( s !== undefined ) _seed$1 = s % 2147483647;
4226 _seed$1 = _seed$1 * 16807 % 2147483647;
4227 return ( _seed$1 - 1 ) / 2147483646;
4228 },
4229 degToRad: function ( degrees ) {
4230 return degrees * MathUtils$1.DEG2RAD;
4231 },
4232 radToDeg: function ( radians ) {
4233 return radians * MathUtils$1.RAD2DEG;
4234 },
4235 isPowerOfTwo: function ( value ) {
4236 return ( value & ( value - 1 ) ) === 0 && value !== 0;
4237 },
4238 ceilPowerOfTwo: function ( value ) {
4239 return Math.pow( 2, Math.ceil( Math.log( value ) / Math.LN2 ) );
4240 },
4241 floorPowerOfTwo: function ( value ) {
4242 return Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) );
4243 },
4244 setQuaternionFromProperEuler: function ( q, a, b, c, order ) {
4245 const cos = Math.cos;
4246 const sin = Math.sin;
4247 const c2 = cos( b / 2 );
4248 const s2 = sin( b / 2 );
4249 const c13 = cos( ( a + c ) / 2 );
4250 const s13 = sin( ( a + c ) / 2 );
4251 const c1_3 = cos( ( a - c ) / 2 );
4252 const s1_3 = sin( ( a - c ) / 2 );
4253 const c3_1 = cos( ( c - a ) / 2 );
4254 const s3_1 = sin( ( c - a ) / 2 );
4255 switch ( order ) {
4256 case 'XYX':
4257 q.set( c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13 );
4258 break;
4259 case 'YZY':
4260 q.set( s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13 );
4261 break;
4262 case 'ZXZ':
4263 q.set( s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13 );
4264 break;
4265 case 'XZX':
4266 q.set( c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13 );
4267 break;
4268 case 'YXY':
4269 q.set( s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13 );
4270 break;
4271 case 'ZYZ':
4272 q.set( s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13 );
4273 break;
4274 default:
4275 console.warn( 'THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order );
4276 }
4277 }
4278 };
4279 let Quaternion$1 = class Quaternion {
4280 constructor( x = 0, y = 0, z = 0, w = 1 ) {
4281 Object.defineProperty( this, 'isQuaternion', { value: true } );
4282 this._x = x;
4283 this._y = y;
4284 this._z = z;
4285 this._w = w;
4286 }
4287 static slerp( qa, qb, qm, t ) {
4288 return qm.copy( qa ).slerp( qb, t );
4289 }
4290 static slerpFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {
4291 let x0 = src0[ srcOffset0 + 0 ],
4292 y0 = src0[ srcOffset0 + 1 ],
4293 z0 = src0[ srcOffset0 + 2 ],
4294 w0 = src0[ srcOffset0 + 3 ];
4295 const x1 = src1[ srcOffset1 + 0 ],
4296 y1 = src1[ srcOffset1 + 1 ],
4297 z1 = src1[ srcOffset1 + 2 ],
4298 w1 = src1[ srcOffset1 + 3 ];
4299 if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {
4300 let s = 1 - t;
4301 const cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,
4302 dir = ( cos >= 0 ? 1 : - 1 ),
4303 sqrSin = 1 - cos * cos;
4304 if ( sqrSin > Number.EPSILON ) {
4305 const sin = Math.sqrt( sqrSin ),
4306 len = Math.atan2( sin, cos * dir );
4307 s = Math.sin( s * len ) / sin;
4308 t = Math.sin( t * len ) / sin;
4309 }
4310 const tDir = t * dir;
4311 x0 = x0 * s + x1 * tDir;
4312 y0 = y0 * s + y1 * tDir;
4313 z0 = z0 * s + z1 * tDir;
4314 w0 = w0 * s + w1 * tDir;
4315 if ( s === 1 - t ) {
4316 const f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );
4317 x0 *= f;
4318 y0 *= f;
4319 z0 *= f;
4320 w0 *= f;
4321 }
4322 }
4323 dst[ dstOffset ] = x0;
4324 dst[ dstOffset + 1 ] = y0;
4325 dst[ dstOffset + 2 ] = z0;
4326 dst[ dstOffset + 3 ] = w0;
4327 }
4328 static multiplyQuaternionsFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1 ) {
4329 const x0 = src0[ srcOffset0 ];
4330 const y0 = src0[ srcOffset0 + 1 ];
4331 const z0 = src0[ srcOffset0 + 2 ];
4332 const w0 = src0[ srcOffset0 + 3 ];
4333 const x1 = src1[ srcOffset1 ];
4334 const y1 = src1[ srcOffset1 + 1 ];
4335 const z1 = src1[ srcOffset1 + 2 ];
4336 const w1 = src1[ srcOffset1 + 3 ];
4337 dst[ dstOffset ] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1;
4338 dst[ dstOffset + 1 ] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1;
4339 dst[ dstOffset + 2 ] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1;
4340 dst[ dstOffset + 3 ] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;
4341 return dst;
4342 }
4343 get x() {
4344 return this._x;
4345 }
4346 set x( value ) {
4347 this._x = value;
4348 this._onChangeCallback();
4349 }
4350 get y() {
4351 return this._y;
4352 }
4353 set y( value ) {
4354 this._y = value;
4355 this._onChangeCallback();
4356 }
4357 get z() {
4358 return this._z;
4359 }
4360 set z( value ) {
4361 this._z = value;
4362 this._onChangeCallback();
4363 }
4364 get w() {
4365 return this._w;
4366 }
4367 set w( value ) {
4368 this._w = value;
4369 this._onChangeCallback();
4370 }
4371 set( x, y, z, w ) {
4372 this._x = x;
4373 this._y = y;
4374 this._z = z;
4375 this._w = w;
4376 this._onChangeCallback();
4377 return this;
4378 }
4379 clone() {
4380 return new this.constructor( this._x, this._y, this._z, this._w );
4381 }
4382 copy( quaternion ) {
4383 this._x = quaternion.x;
4384 this._y = quaternion.y;
4385 this._z = quaternion.z;
4386 this._w = quaternion.w;
4387 this._onChangeCallback();
4388 return this;
4389 }
4390 setFromEuler( euler, update ) {
4391 if ( ! ( euler && euler.isEuler ) ) {
4392 throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );
4393 }
4394 const x = euler._x, y = euler._y, z = euler._z, order = euler._order;
4395 const cos = Math.cos;
4396 const sin = Math.sin;
4397 const c1 = cos( x / 2 );
4398 const c2 = cos( y / 2 );
4399 const c3 = cos( z / 2 );
4400 const s1 = sin( x / 2 );
4401 const s2 = sin( y / 2 );
4402 const s3 = sin( z / 2 );
4403 switch ( order ) {
4404 case 'XYZ':
4405 this._x = s1 * c2 * c3 + c1 * s2 * s3;
4406 this._y = c1 * s2 * c3 - s1 * c2 * s3;
4407 this._z = c1 * c2 * s3 + s1 * s2 * c3;
4408 this._w = c1 * c2 * c3 - s1 * s2 * s3;
4409 break;
4410 case 'YXZ':
4411 this._x = s1 * c2 * c3 + c1 * s2 * s3;
4412 this._y = c1 * s2 * c3 - s1 * c2 * s3;
4413 this._z = c1 * c2 * s3 - s1 * s2 * c3;
4414 this._w = c1 * c2 * c3 + s1 * s2 * s3;
4415 break;
4416 case 'ZXY':
4417 this._x = s1 * c2 * c3 - c1 * s2 * s3;
4418 this._y = c1 * s2 * c3 + s1 * c2 * s3;
4419 this._z = c1 * c2 * s3 + s1 * s2 * c3;
4420 this._w = c1 * c2 * c3 - s1 * s2 * s3;
4421 break;
4422 case 'ZYX':
4423 this._x = s1 * c2 * c3 - c1 * s2 * s3;
4424 this._y = c1 * s2 * c3 + s1 * c2 * s3;
4425 this._z = c1 * c2 * s3 - s1 * s2 * c3;
4426 this._w = c1 * c2 * c3 + s1 * s2 * s3;
4427 break;
4428 case 'YZX':
4429 this._x = s1 * c2 * c3 + c1 * s2 * s3;
4430 this._y = c1 * s2 * c3 + s1 * c2 * s3;
4431 this._z = c1 * c2 * s3 - s1 * s2 * c3;
4432 this._w = c1 * c2 * c3 - s1 * s2 * s3;
4433 break;
4434 case 'XZY':
4435 this._x = s1 * c2 * c3 - c1 * s2 * s3;
4436 this._y = c1 * s2 * c3 - s1 * c2 * s3;
4437 this._z = c1 * c2 * s3 + s1 * s2 * c3;
4438 this._w = c1 * c2 * c3 + s1 * s2 * s3;
4439 break;
4440 default:
4441 console.warn( 'THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order );
4442 }
4443 if ( update !== false ) this._onChangeCallback();
4444 return this;
4445 }
4446 setFromAxisAngle( axis, angle ) {
4447 const halfAngle = angle / 2, s = Math.sin( halfAngle );
4448 this._x = axis.x * s;
4449 this._y = axis.y * s;
4450 this._z = axis.z * s;
4451 this._w = Math.cos( halfAngle );
4452 this._onChangeCallback();
4453 return this;
4454 }
4455 setFromRotationMatrix( m ) {
4456 const te = m.elements,
4457 m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],
4458 m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],
4459 m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],
4460 trace = m11 + m22 + m33;
4461 if ( trace > 0 ) {
4462 const s = 0.5 / Math.sqrt( trace + 1.0 );
4463 this._w = 0.25 / s;
4464 this._x = ( m32 - m23 ) * s;
4465 this._y = ( m13 - m31 ) * s;
4466 this._z = ( m21 - m12 ) * s;
4467 } else if ( m11 > m22 && m11 > m33 ) {
4468 const s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );
4469 this._w = ( m32 - m23 ) / s;
4470 this._x = 0.25 * s;
4471 this._y = ( m12 + m21 ) / s;
4472 this._z = ( m13 + m31 ) / s;
4473 } else if ( m22 > m33 ) {
4474 const s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );
4475 this._w = ( m13 - m31 ) / s;
4476 this._x = ( m12 + m21 ) / s;
4477 this._y = 0.25 * s;
4478 this._z = ( m23 + m32 ) / s;
4479 } else {
4480 const s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );
4481 this._w = ( m21 - m12 ) / s;
4482 this._x = ( m13 + m31 ) / s;
4483 this._y = ( m23 + m32 ) / s;
4484 this._z = 0.25 * s;
4485 }
4486 this._onChangeCallback();
4487 return this;
4488 }
4489 setFromUnitVectors( vFrom, vTo ) {
4490 const EPS = 0.000001;
4491 let r = vFrom.dot( vTo ) + 1;
4492 if ( r < EPS ) {
4493 r = 0;
4494 if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {
4495 this._x = - vFrom.y;
4496 this._y = vFrom.x;
4497 this._z = 0;
4498 this._w = r;
4499 } else {
4500 this._x = 0;
4501 this._y = - vFrom.z;
4502 this._z = vFrom.y;
4503 this._w = r;
4504 }
4505 } else {
4506 this._x = vFrom.y * vTo.z - vFrom.z * vTo.y;
4507 this._y = vFrom.z * vTo.x - vFrom.x * vTo.z;
4508 this._z = vFrom.x * vTo.y - vFrom.y * vTo.x;
4509 this._w = r;
4510 }
4511 return this.normalize();
4512 }
4513 angleTo( q ) {
4514 return 2 * Math.acos( Math.abs( MathUtils$1.clamp( this.dot( q ), - 1, 1 ) ) );
4515 }
4516 rotateTowards( q, step ) {
4517 const angle = this.angleTo( q );
4518 if ( angle === 0 ) return this;
4519 const t = Math.min( 1, step / angle );
4520 this.slerp( q, t );
4521 return this;
4522 }
4523 identity() {
4524 return this.set( 0, 0, 0, 1 );
4525 }
4526 inverse() {
4527 return this.conjugate();
4528 }
4529 conjugate() {
4530 this._x *= - 1;
4531 this._y *= - 1;
4532 this._z *= - 1;
4533 this._onChangeCallback();
4534 return this;
4535 }
4536 dot( v ) {
4537 return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
4538 }
4539 lengthSq() {
4540 return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
4541 }
4542 length() {
4543 return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );
4544 }
4545 normalize() {
4546 let l = this.length();
4547 if ( l === 0 ) {
4548 this._x = 0;
4549 this._y = 0;
4550 this._z = 0;
4551 this._w = 1;
4552 } else {
4553 l = 1 / l;
4554 this._x = this._x * l;
4555 this._y = this._y * l;
4556 this._z = this._z * l;
4557 this._w = this._w * l;
4558 }
4559 this._onChangeCallback();
4560 return this;
4561 }
4562 multiply( q, p ) {
4563 if ( p !== undefined ) {
4564 console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );
4565 return this.multiplyQuaternions( q, p );
4566 }
4567 return this.multiplyQuaternions( this, q );
4568 }
4569 premultiply( q ) {
4570 return this.multiplyQuaternions( q, this );
4571 }
4572 multiplyQuaternions( a, b ) {
4573 const qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;
4574 const qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;
4575 this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
4576 this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
4577 this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
4578 this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
4579 this._onChangeCallback();
4580 return this;
4581 }
4582 slerp( qb, t ) {
4583 if ( t === 0 ) return this;
4584 if ( t === 1 ) return this.copy( qb );
4585 const x = this._x, y = this._y, z = this._z, w = this._w;
4586 let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;
4587 if ( cosHalfTheta < 0 ) {
4588 this._w = - qb._w;
4589 this._x = - qb._x;
4590 this._y = - qb._y;
4591 this._z = - qb._z;
4592 cosHalfTheta = - cosHalfTheta;
4593 } else {
4594 this.copy( qb );
4595 }
4596 if ( cosHalfTheta >= 1.0 ) {
4597 this._w = w;
4598 this._x = x;
4599 this._y = y;
4600 this._z = z;
4601 return this;
4602 }
4603 const sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta;
4604 if ( sqrSinHalfTheta <= Number.EPSILON ) {
4605 const s = 1 - t;
4606 this._w = s * w + t * this._w;
4607 this._x = s * x + t * this._x;
4608 this._y = s * y + t * this._y;
4609 this._z = s * z + t * this._z;
4610 this.normalize();
4611 this._onChangeCallback();
4612 return this;
4613 }
4614 const sinHalfTheta = Math.sqrt( sqrSinHalfTheta );
4615 const halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );
4616 const ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
4617 ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
4618 this._w = ( w * ratioA + this._w * ratioB );
4619 this._x = ( x * ratioA + this._x * ratioB );
4620 this._y = ( y * ratioA + this._y * ratioB );
4621 this._z = ( z * ratioA + this._z * ratioB );
4622 this._onChangeCallback();
4623 return this;
4624 }
4625 equals( quaternion ) {
4626 return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );
4627 }
4628 fromArray( array, offset ) {
4629 if ( offset === undefined ) offset = 0;
4630 this._x = array[ offset ];
4631 this._y = array[ offset + 1 ];
4632 this._z = array[ offset + 2 ];
4633 this._w = array[ offset + 3 ];
4634 this._onChangeCallback();
4635 return this;
4636 }
4637 toArray( array, offset ) {
4638 if ( array === undefined ) array = [];
4639 if ( offset === undefined ) offset = 0;
4640 array[ offset ] = this._x;
4641 array[ offset + 1 ] = this._y;
4642 array[ offset + 2 ] = this._z;
4643 array[ offset + 3 ] = this._w;
4644 return array;
4645 }
4646 fromBufferAttribute( attribute, index ) {
4647 this._x = attribute.getX( index );
4648 this._y = attribute.getY( index );
4649 this._z = attribute.getZ( index );
4650 this._w = attribute.getW( index );
4651 return this;
4652 }
4653 _onChange( callback ) {
4654 this._onChangeCallback = callback;
4655 return this;
4656 }
4657 _onChangeCallback() {}
4658 };
4659 let Vector3$1 = class Vector3 {
4660 constructor( x = 0, y = 0, z = 0 ) {
4661 Object.defineProperty( this, 'isVector3', { value: true } );
4662 this.x = x;
4663 this.y = y;
4664 this.z = z;
4665 }
4666 set( x, y, z ) {
4667 if ( z === undefined ) z = this.z;
4668 this.x = x;
4669 this.y = y;
4670 this.z = z;
4671 return this;
4672 }
4673 setScalar( scalar ) {
4674 this.x = scalar;
4675 this.y = scalar;
4676 this.z = scalar;
4677 return this;
4678 }
4679 setX( x ) {
4680 this.x = x;
4681 return this;
4682 }
4683 setY( y ) {
4684 this.y = y;
4685 return this;
4686 }
4687 setZ( z ) {
4688 this.z = z;
4689 return this;
4690 }
4691 setComponent( index, value ) {
4692 switch ( index ) {
4693 case 0: this.x = value; break;
4694 case 1: this.y = value; break;
4695 case 2: this.z = value; break;
4696 default: throw new Error( 'index is out of range: ' + index );
4697 }
4698 return this;
4699 }
4700 getComponent( index ) {
4701 switch ( index ) {
4702 case 0: return this.x;
4703 case 1: return this.y;
4704 case 2: return this.z;
4705 default: throw new Error( 'index is out of range: ' + index );
4706 }
4707 }
4708 clone() {
4709 return new this.constructor( this.x, this.y, this.z );
4710 }
4711 copy( v ) {
4712 this.x = v.x;
4713 this.y = v.y;
4714 this.z = v.z;
4715 return this;
4716 }
4717 add( v, w ) {
4718 if ( w !== undefined ) {
4719 console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
4720 return this.addVectors( v, w );
4721 }
4722 this.x += v.x;
4723 this.y += v.y;
4724 this.z += v.z;
4725 return this;
4726 }
4727 addScalar( s ) {
4728 this.x += s;
4729 this.y += s;
4730 this.z += s;
4731 return this;
4732 }
4733 addVectors( a, b ) {
4734 this.x = a.x + b.x;
4735 this.y = a.y + b.y;
4736 this.z = a.z + b.z;
4737 return this;
4738 }
4739 addScaledVector( v, s ) {
4740 this.x += v.x * s;
4741 this.y += v.y * s;
4742 this.z += v.z * s;
4743 return this;
4744 }
4745 sub( v, w ) {
4746 if ( w !== undefined ) {
4747 console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
4748 return this.subVectors( v, w );
4749 }
4750 this.x -= v.x;
4751 this.y -= v.y;
4752 this.z -= v.z;
4753 return this;
4754 }
4755 subScalar( s ) {
4756 this.x -= s;
4757 this.y -= s;
4758 this.z -= s;
4759 return this;
4760 }
4761 subVectors( a, b ) {
4762 this.x = a.x - b.x;
4763 this.y = a.y - b.y;
4764 this.z = a.z - b.z;
4765 return this;
4766 }
4767 multiply( v, w ) {
4768 if ( w !== undefined ) {
4769 console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );
4770 return this.multiplyVectors( v, w );
4771 }
4772 this.x *= v.x;
4773 this.y *= v.y;
4774 this.z *= v.z;
4775 return this;
4776 }
4777 multiplyScalar( scalar ) {
4778 this.x *= scalar;
4779 this.y *= scalar;
4780 this.z *= scalar;
4781 return this;
4782 }
4783 multiplyVectors( a, b ) {
4784 this.x = a.x * b.x;
4785 this.y = a.y * b.y;
4786 this.z = a.z * b.z;
4787 return this;
4788 }
4789 applyEuler( euler ) {
4790 if ( ! ( euler && euler.isEuler ) ) {
4791 console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );
4792 }
4793 return this.applyQuaternion( _quaternion$2$1.setFromEuler( euler ) );
4794 }
4795 applyAxisAngle( axis, angle ) {
4796 return this.applyQuaternion( _quaternion$2$1.setFromAxisAngle( axis, angle ) );
4797 }
4798 applyMatrix3( m ) {
4799 const x = this.x, y = this.y, z = this.z;
4800 const e = m.elements;
4801 this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;
4802 this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;
4803 this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;
4804 return this;
4805 }
4806 applyNormalMatrix( m ) {
4807 return this.applyMatrix3( m ).normalize();
4808 }
4809 applyMatrix4( m ) {
4810 const x = this.x, y = this.y, z = this.z;
4811 const e = m.elements;
4812 const w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] );
4813 this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w;
4814 this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w;
4815 this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w;
4816 return this;
4817 }
4818 applyQuaternion( q ) {
4819 const x = this.x, y = this.y, z = this.z;
4820 const qx = q.x, qy = q.y, qz = q.z, qw = q.w;
4821 const ix = qw * x + qy * z - qz * y;
4822 const iy = qw * y + qz * x - qx * z;
4823 const iz = qw * z + qx * y - qy * x;
4824 const iw = - qx * x - qy * y - qz * z;
4825 this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
4826 this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
4827 this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;
4828 return this;
4829 }
4830 project( camera ) {
4831 return this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix );
4832 }
4833 unproject( camera ) {
4834 return this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld );
4835 }
4836 transformDirection( m ) {
4837 const x = this.x, y = this.y, z = this.z;
4838 const e = m.elements;
4839 this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;
4840 this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;
4841 this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;
4842 return this.normalize();
4843 }
4844 divide( v ) {
4845 this.x /= v.x;
4846 this.y /= v.y;
4847 this.z /= v.z;
4848 return this;
4849 }
4850 divideScalar( scalar ) {
4851 return this.multiplyScalar( 1 / scalar );
4852 }
4853 min( v ) {
4854 this.x = Math.min( this.x, v.x );
4855 this.y = Math.min( this.y, v.y );
4856 this.z = Math.min( this.z, v.z );
4857 return this;
4858 }
4859 max( v ) {
4860 this.x = Math.max( this.x, v.x );
4861 this.y = Math.max( this.y, v.y );
4862 this.z = Math.max( this.z, v.z );
4863 return this;
4864 }
4865 clamp( min, max ) {
4866 this.x = Math.max( min.x, Math.min( max.x, this.x ) );
4867 this.y = Math.max( min.y, Math.min( max.y, this.y ) );
4868 this.z = Math.max( min.z, Math.min( max.z, this.z ) );
4869 return this;
4870 }
4871 clampScalar( minVal, maxVal ) {
4872 this.x = Math.max( minVal, Math.min( maxVal, this.x ) );
4873 this.y = Math.max( minVal, Math.min( maxVal, this.y ) );
4874 this.z = Math.max( minVal, Math.min( maxVal, this.z ) );
4875 return this;
4876 }
4877 clampLength( min, max ) {
4878 const length = this.length();
4879 return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
4880 }
4881 floor() {
4882 this.x = Math.floor( this.x );
4883 this.y = Math.floor( this.y );
4884 this.z = Math.floor( this.z );
4885 return this;
4886 }
4887 ceil() {
4888 this.x = Math.ceil( this.x );
4889 this.y = Math.ceil( this.y );
4890 this.z = Math.ceil( this.z );
4891 return this;
4892 }
4893 round() {
4894 this.x = Math.round( this.x );
4895 this.y = Math.round( this.y );
4896 this.z = Math.round( this.z );
4897 return this;
4898 }
4899 roundToZero() {
4900 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
4901 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
4902 this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
4903 return this;
4904 }
4905 negate() {
4906 this.x = - this.x;
4907 this.y = - this.y;
4908 this.z = - this.z;
4909 return this;
4910 }
4911 dot( v ) {
4912 return this.x * v.x + this.y * v.y + this.z * v.z;
4913 }
4914 lengthSq() {
4915 return this.x * this.x + this.y * this.y + this.z * this.z;
4916 }
4917 length() {
4918 return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
4919 }
4920 manhattanLength() {
4921 return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );
4922 }
4923 normalize() {
4924 return this.divideScalar( this.length() || 1 );
4925 }
4926 setLength( length ) {
4927 return this.normalize().multiplyScalar( length );
4928 }
4929 lerp( v, alpha ) {
4930 this.x += ( v.x - this.x ) * alpha;
4931 this.y += ( v.y - this.y ) * alpha;
4932 this.z += ( v.z - this.z ) * alpha;
4933 return this;
4934 }
4935 lerpVectors( v1, v2, alpha ) {
4936 this.x = v1.x + ( v2.x - v1.x ) * alpha;
4937 this.y = v1.y + ( v2.y - v1.y ) * alpha;
4938 this.z = v1.z + ( v2.z - v1.z ) * alpha;
4939 return this;
4940 }
4941 cross( v, w ) {
4942 if ( w !== undefined ) {
4943 console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );
4944 return this.crossVectors( v, w );
4945 }
4946 return this.crossVectors( this, v );
4947 }
4948 crossVectors( a, b ) {
4949 const ax = a.x, ay = a.y, az = a.z;
4950 const bx = b.x, by = b.y, bz = b.z;
4951 this.x = ay * bz - az * by;
4952 this.y = az * bx - ax * bz;
4953 this.z = ax * by - ay * bx;
4954 return this;
4955 }
4956 projectOnVector( v ) {
4957 const denominator = v.lengthSq();
4958 if ( denominator === 0 ) return this.set( 0, 0, 0 );
4959 const scalar = v.dot( this ) / denominator;
4960 return this.copy( v ).multiplyScalar( scalar );
4961 }
4962 projectOnPlane( planeNormal ) {
4963 _vector$c.copy( this ).projectOnVector( planeNormal );
4964 return this.sub( _vector$c );
4965 }
4966 reflect( normal ) {
4967 return this.sub( _vector$c.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );
4968 }
4969 angleTo( v ) {
4970 const denominator = Math.sqrt( this.lengthSq() * v.lengthSq() );
4971 if ( denominator === 0 ) return Math.PI / 2;
4972 const theta = this.dot( v ) / denominator;
4973 return Math.acos( MathUtils$1.clamp( theta, - 1, 1 ) );
4974 }
4975 distanceTo( v ) {
4976 return Math.sqrt( this.distanceToSquared( v ) );
4977 }
4978 distanceToSquared( v ) {
4979 const dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;
4980 return dx * dx + dy * dy + dz * dz;
4981 }
4982 manhattanDistanceTo( v ) {
4983 return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );
4984 }
4985 setFromSpherical( s ) {
4986 return this.setFromSphericalCoords( s.radius, s.phi, s.theta );
4987 }
4988 setFromSphericalCoords( radius, phi, theta ) {
4989 const sinPhiRadius = Math.sin( phi ) * radius;
4990 this.x = sinPhiRadius * Math.sin( theta );
4991 this.y = Math.cos( phi ) * radius;
4992 this.z = sinPhiRadius * Math.cos( theta );
4993 return this;
4994 }
4995 setFromCylindrical( c ) {
4996 return this.setFromCylindricalCoords( c.radius, c.theta, c.y );
4997 }
4998 setFromCylindricalCoords( radius, theta, y ) {
4999 this.x = radius * Math.sin( theta );
5000 this.y = y;
5001 this.z = radius * Math.cos( theta );
5002 return this;
5003 }
5004 setFromMatrixPosition( m ) {
5005 const e = m.elements;
5006 this.x = e[ 12 ];
5007 this.y = e[ 13 ];
5008 this.z = e[ 14 ];
5009 return this;
5010 }
5011 setFromMatrixScale( m ) {
5012 const sx = this.setFromMatrixColumn( m, 0 ).length();
5013 const sy = this.setFromMatrixColumn( m, 1 ).length();
5014 const sz = this.setFromMatrixColumn( m, 2 ).length();
5015 this.x = sx;
5016 this.y = sy;
5017 this.z = sz;
5018 return this;
5019 }
5020 setFromMatrixColumn( m, index ) {
5021 return this.fromArray( m.elements, index * 4 );
5022 }
5023 setFromMatrix3Column( m, index ) {
5024 return this.fromArray( m.elements, index * 3 );
5025 }
5026 equals( v ) {
5027 return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );
5028 }
5029 fromArray( array, offset ) {
5030 if ( offset === undefined ) offset = 0;
5031 this.x = array[ offset ];
5032 this.y = array[ offset + 1 ];
5033 this.z = array[ offset + 2 ];
5034 return this;
5035 }
5036 toArray( array, offset ) {
5037 if ( array === undefined ) array = [];
5038 if ( offset === undefined ) offset = 0;
5039 array[ offset ] = this.x;
5040 array[ offset + 1 ] = this.y;
5041 array[ offset + 2 ] = this.z;
5042 return array;
5043 }
5044 fromBufferAttribute( attribute, index, offset ) {
5045 if ( offset !== undefined ) {
5046 console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );
5047 }
5048 this.x = attribute.getX( index );
5049 this.y = attribute.getY( index );
5050 this.z = attribute.getZ( index );
5051 return this;
5052 }
5053 random() {
5054 this.x = Math.random();
5055 this.y = Math.random();
5056 this.z = Math.random();
5057 return this;
5058 }
5059 };
5060 const _vector$c = new Vector3$1();
5061 const _quaternion$2$1 = new Quaternion$1();
5062 let Matrix4$1 = class Matrix4 {
5063 constructor() {
5064 Object.defineProperty( this, 'isMatrix4', { value: true } );
5065 this.elements = [
5066 1, 0, 0, 0,
5067 0, 1, 0, 0,
5068 0, 0, 1, 0,
5069 0, 0, 0, 1
5070 ];
5071 if ( arguments.length > 0 ) {
5072 console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );
5073 }
5074 }
5075 set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
5076 const te = this.elements;
5077 te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;
5078 te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;
5079 te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;
5080 te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;
5081 return this;
5082 }
5083 identity() {
5084 this.set(
5085 1, 0, 0, 0,
5086 0, 1, 0, 0,
5087 0, 0, 1, 0,
5088 0, 0, 0, 1
5089 );
5090 return this;
5091 }
5092 clone() {
5093 return new Matrix4$1().fromArray( this.elements );
5094 }
5095 copy( m ) {
5096 const te = this.elements;
5097 const me = m.elements;
5098 te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ];
5099 te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ];
5100 te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ];
5101 te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ];
5102 return this;
5103 }
5104 copyPosition( m ) {
5105 const te = this.elements, me = m.elements;
5106 te[ 12 ] = me[ 12 ];
5107 te[ 13 ] = me[ 13 ];
5108 te[ 14 ] = me[ 14 ];
5109 return this;
5110 }
5111 extractBasis( xAxis, yAxis, zAxis ) {
5112 xAxis.setFromMatrixColumn( this, 0 );
5113 yAxis.setFromMatrixColumn( this, 1 );
5114 zAxis.setFromMatrixColumn( this, 2 );
5115 return this;
5116 }
5117 makeBasis( xAxis, yAxis, zAxis ) {
5118 this.set(
5119 xAxis.x, yAxis.x, zAxis.x, 0,
5120 xAxis.y, yAxis.y, zAxis.y, 0,
5121 xAxis.z, yAxis.z, zAxis.z, 0,
5122 0, 0, 0, 1
5123 );
5124 return this;
5125 }
5126 extractRotation( m ) {
5127 const te = this.elements;
5128 const me = m.elements;
5129 const scaleX = 1 / _v1$1$1.setFromMatrixColumn( m, 0 ).length();
5130 const scaleY = 1 / _v1$1$1.setFromMatrixColumn( m, 1 ).length();
5131 const scaleZ = 1 / _v1$1$1.setFromMatrixColumn( m, 2 ).length();
5132 te[ 0 ] = me[ 0 ] * scaleX;
5133 te[ 1 ] = me[ 1 ] * scaleX;
5134 te[ 2 ] = me[ 2 ] * scaleX;
5135 te[ 3 ] = 0;
5136 te[ 4 ] = me[ 4 ] * scaleY;
5137 te[ 5 ] = me[ 5 ] * scaleY;
5138 te[ 6 ] = me[ 6 ] * scaleY;
5139 te[ 7 ] = 0;
5140 te[ 8 ] = me[ 8 ] * scaleZ;
5141 te[ 9 ] = me[ 9 ] * scaleZ;
5142 te[ 10 ] = me[ 10 ] * scaleZ;
5143 te[ 11 ] = 0;
5144 te[ 12 ] = 0;
5145 te[ 13 ] = 0;
5146 te[ 14 ] = 0;
5147 te[ 15 ] = 1;
5148 return this;
5149 }
5150 makeRotationFromEuler( euler ) {
5151 if ( ! ( euler && euler.isEuler ) ) {
5152 console.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );
5153 }
5154 const te = this.elements;
5155 const x = euler.x, y = euler.y, z = euler.z;
5156 const a = Math.cos( x ), b = Math.sin( x );
5157 const c = Math.cos( y ), d = Math.sin( y );
5158 const e = Math.cos( z ), f = Math.sin( z );
5159 if ( euler.order === 'XYZ' ) {
5160 const ae = a * e, af = a * f, be = b * e, bf = b * f;
5161 te[ 0 ] = c * e;
5162 te[ 4 ] = - c * f;
5163 te[ 8 ] = d;
5164 te[ 1 ] = af + be * d;
5165 te[ 5 ] = ae - bf * d;
5166 te[ 9 ] = - b * c;
5167 te[ 2 ] = bf - ae * d;
5168 te[ 6 ] = be + af * d;
5169 te[ 10 ] = a * c;
5170 } else if ( euler.order === 'YXZ' ) {
5171 const ce = c * e, cf = c * f, de = d * e, df = d * f;
5172 te[ 0 ] = ce + df * b;
5173 te[ 4 ] = de * b - cf;
5174 te[ 8 ] = a * d;
5175 te[ 1 ] = a * f;
5176 te[ 5 ] = a * e;
5177 te[ 9 ] = - b;
5178 te[ 2 ] = cf * b - de;
5179 te[ 6 ] = df + ce * b;
5180 te[ 10 ] = a * c;
5181 } else if ( euler.order === 'ZXY' ) {
5182 const ce = c * e, cf = c * f, de = d * e, df = d * f;
5183 te[ 0 ] = ce - df * b;
5184 te[ 4 ] = - a * f;
5185 te[ 8 ] = de + cf * b;
5186 te[ 1 ] = cf + de * b;
5187 te[ 5 ] = a * e;
5188 te[ 9 ] = df - ce * b;
5189 te[ 2 ] = - a * d;
5190 te[ 6 ] = b;
5191 te[ 10 ] = a * c;
5192 } else if ( euler.order === 'ZYX' ) {
5193 const ae = a * e, af = a * f, be = b * e, bf = b * f;
5194 te[ 0 ] = c * e;
5195 te[ 4 ] = be * d - af;
5196 te[ 8 ] = ae * d + bf;
5197 te[ 1 ] = c * f;
5198 te[ 5 ] = bf * d + ae;
5199 te[ 9 ] = af * d - be;
5200 te[ 2 ] = - d;
5201 te[ 6 ] = b * c;
5202 te[ 10 ] = a * c;
5203 } else if ( euler.order === 'YZX' ) {
5204 const ac = a * c, ad = a * d, bc = b * c, bd = b * d;
5205 te[ 0 ] = c * e;
5206 te[ 4 ] = bd - ac * f;
5207 te[ 8 ] = bc * f + ad;
5208 te[ 1 ] = f;
5209 te[ 5 ] = a * e;
5210 te[ 9 ] = - b * e;
5211 te[ 2 ] = - d * e;
5212 te[ 6 ] = ad * f + bc;
5213 te[ 10 ] = ac - bd * f;
5214 } else if ( euler.order === 'XZY' ) {
5215 const ac = a * c, ad = a * d, bc = b * c, bd = b * d;
5216 te[ 0 ] = c * e;
5217 te[ 4 ] = - f;
5218 te[ 8 ] = d * e;
5219 te[ 1 ] = ac * f + bd;
5220 te[ 5 ] = a * e;
5221 te[ 9 ] = ad * f - bc;
5222 te[ 2 ] = bc * f - ad;
5223 te[ 6 ] = b * e;
5224 te[ 10 ] = bd * f + ac;
5225 }
5226 te[ 3 ] = 0;
5227 te[ 7 ] = 0;
5228 te[ 11 ] = 0;
5229 te[ 12 ] = 0;
5230 te[ 13 ] = 0;
5231 te[ 14 ] = 0;
5232 te[ 15 ] = 1;
5233 return this;
5234 }
5235 makeRotationFromQuaternion( q ) {
5236 return this.compose( _zero$1, q, _one$1 );
5237 }
5238 lookAt( eye, target, up ) {
5239 const te = this.elements;
5240 _z$1.subVectors( eye, target );
5241 if ( _z$1.lengthSq() === 0 ) {
5242 _z$1.z = 1;
5243 }
5244 _z$1.normalize();
5245 _x$1.crossVectors( up, _z$1 );
5246 if ( _x$1.lengthSq() === 0 ) {
5247 if ( Math.abs( up.z ) === 1 ) {
5248 _z$1.x += 0.0001;
5249 } else {
5250 _z$1.z += 0.0001;
5251 }
5252 _z$1.normalize();
5253 _x$1.crossVectors( up, _z$1 );
5254 }
5255 _x$1.normalize();
5256 _y$1.crossVectors( _z$1, _x$1 );
5257 te[ 0 ] = _x$1.x; te[ 4 ] = _y$1.x; te[ 8 ] = _z$1.x;
5258 te[ 1 ] = _x$1.y; te[ 5 ] = _y$1.y; te[ 9 ] = _z$1.y;
5259 te[ 2 ] = _x$1.z; te[ 6 ] = _y$1.z; te[ 10 ] = _z$1.z;
5260 return this;
5261 }
5262 multiply( m, n ) {
5263 if ( n !== undefined ) {
5264 console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );
5265 return this.multiplyMatrices( m, n );
5266 }
5267 return this.multiplyMatrices( this, m );
5268 }
5269 premultiply( m ) {
5270 return this.multiplyMatrices( m, this );
5271 }
5272 multiplyMatrices( a, b ) {
5273 const ae = a.elements;
5274 const be = b.elements;
5275 const te = this.elements;
5276 const a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];
5277 const a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];
5278 const a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];
5279 const a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];
5280 const b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];
5281 const b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];
5282 const b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];
5283 const b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];
5284 te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
5285 te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
5286 te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
5287 te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
5288 te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
5289 te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
5290 te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
5291 te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
5292 te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
5293 te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
5294 te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
5295 te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
5296 te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
5297 te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
5298 te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
5299 te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
5300 return this;
5301 }
5302 multiplyScalar( s ) {
5303 const te = this.elements;
5304 te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;
5305 te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;
5306 te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;
5307 te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;
5308 return this;
5309 }
5310 determinant() {
5311 const te = this.elements;
5312 const n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];
5313 const n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];
5314 const n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];
5315 const n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];
5316 return (
5317 n41 * (
5318 + n14 * n23 * n32
5319 - n13 * n24 * n32
5320 - n14 * n22 * n33
5321 + n12 * n24 * n33
5322 + n13 * n22 * n34
5323 - n12 * n23 * n34
5324 ) +
5325 n42 * (
5326 + n11 * n23 * n34
5327 - n11 * n24 * n33
5328 + n14 * n21 * n33
5329 - n13 * n21 * n34
5330 + n13 * n24 * n31
5331 - n14 * n23 * n31
5332 ) +
5333 n43 * (
5334 + n11 * n24 * n32
5335 - n11 * n22 * n34
5336 - n14 * n21 * n32
5337 + n12 * n21 * n34
5338 + n14 * n22 * n31
5339 - n12 * n24 * n31
5340 ) +
5341 n44 * (
5342 - n13 * n22 * n31
5343 - n11 * n23 * n32
5344 + n11 * n22 * n33
5345 + n13 * n21 * n32
5346 - n12 * n21 * n33
5347 + n12 * n23 * n31
5348 )
5349 );
5350 }
5351 transpose() {
5352 const te = this.elements;
5353 let tmp;
5354 tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;
5355 tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;
5356 tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;
5357 tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;
5358 tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;
5359 tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;
5360 return this;
5361 }
5362 setPosition( x, y, z ) {
5363 const te = this.elements;
5364 if ( x.isVector3 ) {
5365 te[ 12 ] = x.x;
5366 te[ 13 ] = x.y;
5367 te[ 14 ] = x.z;
5368 } else {
5369 te[ 12 ] = x;
5370 te[ 13 ] = y;
5371 te[ 14 ] = z;
5372 }
5373 return this;
5374 }
5375 getInverse( m, throwOnDegenerate ) {
5376 if ( throwOnDegenerate !== undefined ) {
5377 console.warn( "THREE.Matrix4: .getInverse() can no longer be configured to throw on degenerate." );
5378 }
5379 const te = this.elements,
5380 me = m.elements,
5381 n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],
5382 n12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],
5383 n13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],
5384 n14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],
5385 t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,
5386 t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,
5387 t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,
5388 t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
5389 const det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
5390 if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
5391 const detInv = 1 / det;
5392 te[ 0 ] = t11 * detInv;
5393 te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;
5394 te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;
5395 te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;
5396 te[ 4 ] = t12 * detInv;
5397 te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;
5398 te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;
5399 te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;
5400 te[ 8 ] = t13 * detInv;
5401 te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;
5402 te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;
5403 te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;
5404 te[ 12 ] = t14 * detInv;
5405 te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;
5406 te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;
5407 te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;
5408 return this;
5409 }
5410 scale( v ) {
5411 const te = this.elements;
5412 const x = v.x, y = v.y, z = v.z;
5413 te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;
5414 te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;
5415 te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;
5416 te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;
5417 return this;
5418 }
5419 getMaxScaleOnAxis() {
5420 const te = this.elements;
5421 const scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];
5422 const scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];
5423 const scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];
5424 return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );
5425 }
5426 makeTranslation( x, y, z ) {
5427 this.set(
5428 1, 0, 0, x,
5429 0, 1, 0, y,
5430 0, 0, 1, z,
5431 0, 0, 0, 1
5432 );
5433 return this;
5434 }
5435 makeRotationX( theta ) {
5436 const c = Math.cos( theta ), s = Math.sin( theta );
5437 this.set(
5438 1, 0, 0, 0,
5439 0, c, - s, 0,
5440 0, s, c, 0,
5441 0, 0, 0, 1
5442 );
5443 return this;
5444 }
5445 makeRotationY( theta ) {
5446 const c = Math.cos( theta ), s = Math.sin( theta );
5447 this.set(
5448 c, 0, s, 0,
5449 0, 1, 0, 0,
5450 - s, 0, c, 0,
5451 0, 0, 0, 1
5452 );
5453 return this;
5454 }
5455 makeRotationZ( theta ) {
5456 const c = Math.cos( theta ), s = Math.sin( theta );
5457 this.set(
5458 c, - s, 0, 0,
5459 s, c, 0, 0,
5460 0, 0, 1, 0,
5461 0, 0, 0, 1
5462 );
5463 return this;
5464 }
5465 makeRotationAxis( axis, angle ) {
5466 const c = Math.cos( angle );
5467 const s = Math.sin( angle );
5468 const t = 1 - c;
5469 const x = axis.x, y = axis.y, z = axis.z;
5470 const tx = t * x, ty = t * y;
5471 this.set(
5472 tx * x + c, tx * y - s * z, tx * z + s * y, 0,
5473 tx * y + s * z, ty * y + c, ty * z - s * x, 0,
5474 tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
5475 0, 0, 0, 1
5476 );
5477 return this;
5478 }
5479 makeScale( x, y, z ) {
5480 this.set(
5481 x, 0, 0, 0,
5482 0, y, 0, 0,
5483 0, 0, z, 0,
5484 0, 0, 0, 1
5485 );
5486 return this;
5487 }
5488 makeShear( x, y, z ) {
5489 this.set(
5490 1, y, z, 0,
5491 x, 1, z, 0,
5492 x, y, 1, 0,
5493 0, 0, 0, 1
5494 );
5495 return this;
5496 }
5497 compose( position, quaternion, scale ) {
5498 const te = this.elements;
5499 const x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w;
5500 const x2 = x + x, y2 = y + y, z2 = z + z;
5501 const xx = x * x2, xy = x * y2, xz = x * z2;
5502 const yy = y * y2, yz = y * z2, zz = z * z2;
5503 const wx = w * x2, wy = w * y2, wz = w * z2;
5504 const sx = scale.x, sy = scale.y, sz = scale.z;
5505 te[ 0 ] = ( 1 - ( yy + zz ) ) * sx;
5506 te[ 1 ] = ( xy + wz ) * sx;
5507 te[ 2 ] = ( xz - wy ) * sx;
5508 te[ 3 ] = 0;
5509 te[ 4 ] = ( xy - wz ) * sy;
5510 te[ 5 ] = ( 1 - ( xx + zz ) ) * sy;
5511 te[ 6 ] = ( yz + wx ) * sy;
5512 te[ 7 ] = 0;
5513 te[ 8 ] = ( xz + wy ) * sz;
5514 te[ 9 ] = ( yz - wx ) * sz;
5515 te[ 10 ] = ( 1 - ( xx + yy ) ) * sz;
5516 te[ 11 ] = 0;
5517 te[ 12 ] = position.x;
5518 te[ 13 ] = position.y;
5519 te[ 14 ] = position.z;
5520 te[ 15 ] = 1;
5521 return this;
5522 }
5523 decompose( position, quaternion, scale ) {
5524 const te = this.elements;
5525 let sx = _v1$1$1.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();
5526 const sy = _v1$1$1.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();
5527 const sz = _v1$1$1.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();
5528 const det = this.determinant();
5529 if ( det < 0 ) sx = - sx;
5530 position.x = te[ 12 ];
5531 position.y = te[ 13 ];
5532 position.z = te[ 14 ];
5533 _m1$1$1.copy( this );
5534 const invSX = 1 / sx;
5535 const invSY = 1 / sy;
5536 const invSZ = 1 / sz;
5537 _m1$1$1.elements[ 0 ] *= invSX;
5538 _m1$1$1.elements[ 1 ] *= invSX;
5539 _m1$1$1.elements[ 2 ] *= invSX;
5540 _m1$1$1.elements[ 4 ] *= invSY;
5541 _m1$1$1.elements[ 5 ] *= invSY;
5542 _m1$1$1.elements[ 6 ] *= invSY;
5543 _m1$1$1.elements[ 8 ] *= invSZ;
5544 _m1$1$1.elements[ 9 ] *= invSZ;
5545 _m1$1$1.elements[ 10 ] *= invSZ;
5546 quaternion.setFromRotationMatrix( _m1$1$1 );
5547 scale.x = sx;
5548 scale.y = sy;
5549 scale.z = sz;
5550 return this;
5551 }
5552 makePerspective( left, right, top, bottom, near, far ) {
5553 if ( far === undefined ) {
5554 console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );
5555 }
5556 const te = this.elements;
5557 const x = 2 * near / ( right - left );
5558 const y = 2 * near / ( top - bottom );
5559 const a = ( right + left ) / ( right - left );
5560 const b = ( top + bottom ) / ( top - bottom );
5561 const c = - ( far + near ) / ( far - near );
5562 const d = - 2 * far * near / ( far - near );
5563 te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0;
5564 te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0;
5565 te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d;
5566 te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0;
5567 return this;
5568 }
5569 makeOrthographic( left, right, top, bottom, near, far ) {
5570 const te = this.elements;
5571 const w = 1.0 / ( right - left );
5572 const h = 1.0 / ( top - bottom );
5573 const p = 1.0 / ( far - near );
5574 const x = ( right + left ) * w;
5575 const y = ( top + bottom ) * h;
5576 const z = ( far + near ) * p;
5577 te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x;
5578 te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y;
5579 te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 * p; te[ 14 ] = - z;
5580 te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1;
5581 return this;
5582 }
5583 equals( matrix ) {
5584 const te = this.elements;
5585 const me = matrix.elements;
5586 for ( let i = 0; i < 16; i ++ ) {
5587 if ( te[ i ] !== me[ i ] ) return false;
5588 }
5589 return true;
5590 }
5591 fromArray( array, offset ) {
5592 if ( offset === undefined ) offset = 0;
5593 for ( let i = 0; i < 16; i ++ ) {
5594 this.elements[ i ] = array[ i + offset ];
5595 }
5596 return this;
5597 }
5598 toArray( array, offset ) {
5599 if ( array === undefined ) array = [];
5600 if ( offset === undefined ) offset = 0;
5601 const te = this.elements;
5602 array[ offset ] = te[ 0 ];
5603 array[ offset + 1 ] = te[ 1 ];
5604 array[ offset + 2 ] = te[ 2 ];
5605 array[ offset + 3 ] = te[ 3 ];
5606 array[ offset + 4 ] = te[ 4 ];
5607 array[ offset + 5 ] = te[ 5 ];
5608 array[ offset + 6 ] = te[ 6 ];
5609 array[ offset + 7 ] = te[ 7 ];
5610 array[ offset + 8 ] = te[ 8 ];
5611 array[ offset + 9 ] = te[ 9 ];
5612 array[ offset + 10 ] = te[ 10 ];
5613 array[ offset + 11 ] = te[ 11 ];
5614 array[ offset + 12 ] = te[ 12 ];
5615 array[ offset + 13 ] = te[ 13 ];
5616 array[ offset + 14 ] = te[ 14 ];
5617 array[ offset + 15 ] = te[ 15 ];
5618 return array;
5619 }
5620 };
5621 const _v1$1$1 = new Vector3$1();
5622 const _m1$1$1 = new Matrix4$1();
5623 const _zero$1 = new Vector3$1( 0, 0, 0 );
5624 const _one$1 = new Vector3$1( 1, 1, 1 );
5625 const _x$1 = new Vector3$1();
5626 const _y$1 = new Vector3$1();
5627 const _z$1 = new Vector3$1();
5628 function EventDispatcher$1() {}
5629 Object.assign( EventDispatcher$1.prototype, {
5630 addEventListener: function ( type, listener ) {
5631 if ( this._listeners === undefined ) this._listeners = {};
5632 const listeners = this._listeners;
5633 if ( listeners[ type ] === undefined ) {
5634 listeners[ type ] = [];
5635 }
5636 if ( listeners[ type ].indexOf( listener ) === - 1 ) {
5637 listeners[ type ].push( listener );
5638 }
5639 },
5640 hasEventListener: function ( type, listener ) {
5641 if ( this._listeners === undefined ) return false;
5642 const listeners = this._listeners;
5643 return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;
5644 },
5645 removeEventListener: function ( type, listener ) {
5646 if ( this._listeners === undefined ) return;
5647 const listeners = this._listeners;
5648 const listenerArray = listeners[ type ];
5649 if ( listenerArray !== undefined ) {
5650 const index = listenerArray.indexOf( listener );
5651 if ( index !== - 1 ) {
5652 listenerArray.splice( index, 1 );
5653 }
5654 }
5655 },
5656 dispatchEvent: function ( event ) {
5657 if ( this._listeners === undefined ) return;
5658 const listeners = this._listeners;
5659 const listenerArray = listeners[ event.type ];
5660 if ( listenerArray !== undefined ) {
5661 event.target = this;
5662 const array = listenerArray.slice( 0 );
5663 for ( let i = 0, l = array.length; i < l; i ++ ) {
5664 array[ i ].call( this, event );
5665 }
5666 }
5667 }
5668 } );
5669 let Euler$1 = class Euler {
5670 constructor( x = 0, y = 0, z = 0, order = Euler$1.DefaultOrder ) {
5671 Object.defineProperty( this, 'isEuler', { value: true } );
5672 this._x = x;
5673 this._y = y;
5674 this._z = z;
5675 this._order = order;
5676 }
5677 get x() {
5678 return this._x;
5679 }
5680 set x( value ) {
5681 this._x = value;
5682 this._onChangeCallback();
5683 }
5684 get y() {
5685 return this._y;
5686 }
5687 set y( value ) {
5688 this._y = value;
5689 this._onChangeCallback();
5690 }
5691 get z() {
5692 return this._z;
5693 }
5694 set z( value ) {
5695 this._z = value;
5696 this._onChangeCallback();
5697 }
5698 get order() {
5699 return this._order;
5700 }
5701 set order( value ) {
5702 this._order = value;
5703 this._onChangeCallback();
5704 }
5705 set( x, y, z, order ) {
5706 this._x = x;
5707 this._y = y;
5708 this._z = z;
5709 this._order = order || this._order;
5710 this._onChangeCallback();
5711 return this;
5712 }
5713 clone() {
5714 return new this.constructor( this._x, this._y, this._z, this._order );
5715 }
5716 copy( euler ) {
5717 this._x = euler._x;
5718 this._y = euler._y;
5719 this._z = euler._z;
5720 this._order = euler._order;
5721 this._onChangeCallback();
5722 return this;
5723 }
5724 setFromRotationMatrix( m, order, update ) {
5725 const clamp = MathUtils$1.clamp;
5726 const te = m.elements;
5727 const m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];
5728 const m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];
5729 const m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];
5730 order = order || this._order;
5731 switch ( order ) {
5732 case 'XYZ':
5733 this._y = Math.asin( clamp( m13, - 1, 1 ) );
5734 if ( Math.abs( m13 ) < 0.9999999 ) {
5735 this._x = Math.atan2( - m23, m33 );
5736 this._z = Math.atan2( - m12, m11 );
5737 } else {
5738 this._x = Math.atan2( m32, m22 );
5739 this._z = 0;
5740 }
5741 break;
5742 case 'YXZ':
5743 this._x = Math.asin( - clamp( m23, - 1, 1 ) );
5744 if ( Math.abs( m23 ) < 0.9999999 ) {
5745 this._y = Math.atan2( m13, m33 );
5746 this._z = Math.atan2( m21, m22 );
5747 } else {
5748 this._y = Math.atan2( - m31, m11 );
5749 this._z = 0;
5750 }
5751 break;
5752 case 'ZXY':
5753 this._x = Math.asin( clamp( m32, - 1, 1 ) );
5754 if ( Math.abs( m32 ) < 0.9999999 ) {
5755 this._y = Math.atan2( - m31, m33 );
5756 this._z = Math.atan2( - m12, m22 );
5757 } else {
5758 this._y = 0;
5759 this._z = Math.atan2( m21, m11 );
5760 }
5761 break;
5762 case 'ZYX':
5763 this._y = Math.asin( - clamp( m31, - 1, 1 ) );
5764 if ( Math.abs( m31 ) < 0.9999999 ) {
5765 this._x = Math.atan2( m32, m33 );
5766 this._z = Math.atan2( m21, m11 );
5767 } else {
5768 this._x = 0;
5769 this._z = Math.atan2( - m12, m22 );
5770 }
5771 break;
5772 case 'YZX':
5773 this._z = Math.asin( clamp( m21, - 1, 1 ) );
5774 if ( Math.abs( m21 ) < 0.9999999 ) {
5775 this._x = Math.atan2( - m23, m22 );
5776 this._y = Math.atan2( - m31, m11 );
5777 } else {
5778 this._x = 0;
5779 this._y = Math.atan2( m13, m33 );
5780 }
5781 break;
5782 case 'XZY':
5783 this._z = Math.asin( - clamp( m12, - 1, 1 ) );
5784 if ( Math.abs( m12 ) < 0.9999999 ) {
5785 this._x = Math.atan2( m32, m22 );
5786 this._y = Math.atan2( m13, m11 );
5787 } else {
5788 this._x = Math.atan2( - m23, m33 );
5789 this._y = 0;
5790 }
5791 break;
5792 default:
5793 console.warn( 'THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order );
5794 }
5795 this._order = order;
5796 if ( update !== false ) this._onChangeCallback();
5797 return this;
5798 }
5799 setFromQuaternion( q, order, update ) {
5800 _matrix$1.makeRotationFromQuaternion( q );
5801 return this.setFromRotationMatrix( _matrix$1, order, update );
5802 }
5803 setFromVector3( v, order ) {
5804 return this.set( v.x, v.y, v.z, order || this._order );
5805 }
5806 reorder( newOrder ) {
5807 _quaternion$1$1.setFromEuler( this );
5808 return this.setFromQuaternion( _quaternion$1$1, newOrder );
5809 }
5810 equals( euler ) {
5811 return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );
5812 }
5813 fromArray( array ) {
5814 this._x = array[ 0 ];
5815 this._y = array[ 1 ];
5816 this._z = array[ 2 ];
5817 if ( array[ 3 ] !== undefined ) this._order = array[ 3 ];
5818 this._onChangeCallback();
5819 return this;
5820 }
5821 toArray( array, offset ) {
5822 if ( array === undefined ) array = [];
5823 if ( offset === undefined ) offset = 0;
5824 array[ offset ] = this._x;
5825 array[ offset + 1 ] = this._y;
5826 array[ offset + 2 ] = this._z;
5827 array[ offset + 3 ] = this._order;
5828 return array;
5829 }
5830 toVector3( optionalResult ) {
5831 if ( optionalResult ) {
5832 return optionalResult.set( this._x, this._y, this._z );
5833 } else {
5834 return new Vector3$1( this._x, this._y, this._z );
5835 }
5836 }
5837 _onChange( callback ) {
5838 this._onChangeCallback = callback;
5839 return this;
5840 }
5841 _onChangeCallback() {}
5842 };
5843 Euler$1.DefaultOrder = 'XYZ';
5844 Euler$1.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];
5845 const _matrix$1 = new Matrix4$1();
5846 const _quaternion$1$1 = new Quaternion$1();
5847 let Layers$1 = class Layers {
5848 constructor() {
5849 this.mask = 1 | 0;
5850 }
5851 set( channel ) {
5852 this.mask = 1 << channel | 0;
5853 }
5854 enable( channel ) {
5855 this.mask |= 1 << channel | 0;
5856 }
5857 enableAll() {
5858 this.mask = 0xffffffff | 0;
5859 }
5860 toggle( channel ) {
5861 this.mask ^= 1 << channel | 0;
5862 }
5863 disable( channel ) {
5864 this.mask &= ~ ( 1 << channel | 0 );
5865 }
5866 disableAll() {
5867 this.mask = 0;
5868 }
5869 test( layers ) {
5870 return ( this.mask & layers.mask ) !== 0;
5871 }
5872 };
5873 let Matrix3$1 = class Matrix3 {
5874 constructor() {
5875 Object.defineProperty( this, 'isMatrix3', { value: true } );
5876 this.elements = [
5877 1, 0, 0,
5878 0, 1, 0,
5879 0, 0, 1
5880 ];
5881 if ( arguments.length > 0 ) {
5882 console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );
5883 }
5884 }
5885 set( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
5886 const te = this.elements;
5887 te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;
5888 te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;
5889 te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;
5890 return this;
5891 }
5892 identity() {
5893 this.set(
5894 1, 0, 0,
5895 0, 1, 0,
5896 0, 0, 1
5897 );
5898 return this;
5899 }
5900 clone() {
5901 return new this.constructor().fromArray( this.elements );
5902 }
5903 copy( m ) {
5904 const te = this.elements;
5905 const me = m.elements;
5906 te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ];
5907 te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ];
5908 te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ];
5909 return this;
5910 }
5911 extractBasis( xAxis, yAxis, zAxis ) {
5912 xAxis.setFromMatrix3Column( this, 0 );
5913 yAxis.setFromMatrix3Column( this, 1 );
5914 zAxis.setFromMatrix3Column( this, 2 );
5915 return this;
5916 }
5917 setFromMatrix4( m ) {
5918 const me = m.elements;
5919 this.set(
5920 me[ 0 ], me[ 4 ], me[ 8 ],
5921 me[ 1 ], me[ 5 ], me[ 9 ],
5922 me[ 2 ], me[ 6 ], me[ 10 ]
5923 );
5924 return this;
5925 }
5926 multiply( m ) {
5927 return this.multiplyMatrices( this, m );
5928 }
5929 premultiply( m ) {
5930 return this.multiplyMatrices( m, this );
5931 }
5932 multiplyMatrices( a, b ) {
5933 const ae = a.elements;
5934 const be = b.elements;
5935 const te = this.elements;
5936 const a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ];
5937 const a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ];
5938 const a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ];
5939 const b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ];
5940 const b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ];
5941 const b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ];
5942 te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31;
5943 te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32;
5944 te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33;
5945 te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31;
5946 te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32;
5947 te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33;
5948 te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31;
5949 te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32;
5950 te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33;
5951 return this;
5952 }
5953 multiplyScalar( s ) {
5954 const te = this.elements;
5955 te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;
5956 te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;
5957 te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;
5958 return this;
5959 }
5960 determinant() {
5961 const te = this.elements;
5962 const a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],
5963 d = te[ 3 ], e = te[ 4 ], f = te[ 5 ],
5964 g = te[ 6 ], h = te[ 7 ], i = te[ 8 ];
5965 return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;
5966 }
5967 getInverse( matrix, throwOnDegenerate ) {
5968 if ( throwOnDegenerate !== undefined ) {
5969 console.warn( "THREE.Matrix3: .getInverse() can no longer be configured to throw on degenerate." );
5970 }
5971 const me = matrix.elements,
5972 te = this.elements,
5973 n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],
5974 n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],
5975 n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],
5976 t11 = n33 * n22 - n32 * n23,
5977 t12 = n32 * n13 - n33 * n12,
5978 t13 = n23 * n12 - n22 * n13,
5979 det = n11 * t11 + n21 * t12 + n31 * t13;
5980 if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0 );
5981 const detInv = 1 / det;
5982 te[ 0 ] = t11 * detInv;
5983 te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;
5984 te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;
5985 te[ 3 ] = t12 * detInv;
5986 te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;
5987 te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;
5988 te[ 6 ] = t13 * detInv;
5989 te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;
5990 te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;
5991 return this;
5992 }
5993 transpose() {
5994 let tmp;
5995 const m = this.elements;
5996 tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;
5997 tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;
5998 tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;
5999 return this;
6000 }
6001 getNormalMatrix( matrix4 ) {
6002 return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();
6003 }
6004 transposeIntoArray( r ) {
6005 const m = this.elements;
6006 r[ 0 ] = m[ 0 ];
6007 r[ 1 ] = m[ 3 ];
6008 r[ 2 ] = m[ 6 ];
6009 r[ 3 ] = m[ 1 ];
6010 r[ 4 ] = m[ 4 ];
6011 r[ 5 ] = m[ 7 ];
6012 r[ 6 ] = m[ 2 ];
6013 r[ 7 ] = m[ 5 ];
6014 r[ 8 ] = m[ 8 ];
6015 return this;
6016 }
6017 setUvTransform( tx, ty, sx, sy, rotation, cx, cy ) {
6018 const c = Math.cos( rotation );
6019 const s = Math.sin( rotation );
6020 this.set(
6021 sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx,
6022 - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty,
6023 0, 0, 1
6024 );
6025 }
6026 scale( sx, sy ) {
6027 const te = this.elements;
6028 te[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx;
6029 te[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy;
6030 return this;
6031 }
6032 rotate( theta ) {
6033 const c = Math.cos( theta );
6034 const s = Math.sin( theta );
6035 const te = this.elements;
6036 const a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ];
6037 const a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ];
6038 te[ 0 ] = c * a11 + s * a21;
6039 te[ 3 ] = c * a12 + s * a22;
6040 te[ 6 ] = c * a13 + s * a23;
6041 te[ 1 ] = - s * a11 + c * a21;
6042 te[ 4 ] = - s * a12 + c * a22;
6043 te[ 7 ] = - s * a13 + c * a23;
6044 return this;
6045 }
6046 translate( tx, ty ) {
6047 const te = this.elements;
6048 te[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ];
6049 te[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ];
6050 return this;
6051 }
6052 equals( matrix ) {
6053 const te = this.elements;
6054 const me = matrix.elements;
6055 for ( let i = 0; i < 9; i ++ ) {
6056 if ( te[ i ] !== me[ i ] ) return false;
6057 }
6058 return true;
6059 }
6060 fromArray( array, offset ) {
6061 if ( offset === undefined ) offset = 0;
6062 for ( let i = 0; i < 9; i ++ ) {
6063 this.elements[ i ] = array[ i + offset ];
6064 }
6065 return this;
6066 }
6067 toArray( array, offset ) {
6068 if ( array === undefined ) array = [];
6069 if ( offset === undefined ) offset = 0;
6070 const te = this.elements;
6071 array[ offset ] = te[ 0 ];
6072 array[ offset + 1 ] = te[ 1 ];
6073 array[ offset + 2 ] = te[ 2 ];
6074 array[ offset + 3 ] = te[ 3 ];
6075 array[ offset + 4 ] = te[ 4 ];
6076 array[ offset + 5 ] = te[ 5 ];
6077 array[ offset + 6 ] = te[ 6 ];
6078 array[ offset + 7 ] = te[ 7 ];
6079 array[ offset + 8 ] = te[ 8 ];
6080 return array;
6081 }
6082 };
6083 let _object3DId$1 = 0;
6084 const _v1$6 = new Vector3$1();
6085 const _q1$1 = new Quaternion$1();
6086 const _m1$4 = new Matrix4$1();
6087 const _target$1 = new Vector3$1();
6088 const _position$4 = new Vector3$1();
6089 const _scale$3 = new Vector3$1();
6090 const _quaternion$5 = new Quaternion$1();
6091 const _xAxis$1 = new Vector3$1( 1, 0, 0 );
6092 const _yAxis$1 = new Vector3$1( 0, 1, 0 );
6093 const _zAxis$1 = new Vector3$1( 0, 0, 1 );
6094 const _addedEvent$1 = { type: 'added' };
6095 const _removedEvent$1 = { type: 'removed' };
6096 function Object3D$1() {
6097 Object.defineProperty( this, 'id', { value: _object3DId$1 ++ } );
6098 this.uuid = MathUtils$1.generateUUID();
6099 this.name = '';
6100 this.type = 'Object3D';
6101 this.parent = null;
6102 this.children = [];
6103 this.up = Object3D$1.DefaultUp.clone();
6104 const position = new Vector3$1();
6105 const rotation = new Euler$1();
6106 const quaternion = new Quaternion$1();
6107 const scale = new Vector3$1( 1, 1, 1 );
6108 function onRotationChange() {
6109 quaternion.setFromEuler( rotation, false );
6110 }
6111 function onQuaternionChange() {
6112 rotation.setFromQuaternion( quaternion, undefined, false );
6113 }
6114 rotation._onChange( onRotationChange );
6115 quaternion._onChange( onQuaternionChange );
6116 Object.defineProperties( this, {
6117 position: {
6118 configurable: true,
6119 enumerable: true,
6120 value: position
6121 },
6122 rotation: {
6123 configurable: true,
6124 enumerable: true,
6125 value: rotation
6126 },
6127 quaternion: {
6128 configurable: true,
6129 enumerable: true,
6130 value: quaternion
6131 },
6132 scale: {
6133 configurable: true,
6134 enumerable: true,
6135 value: scale
6136 },
6137 modelViewMatrix: {
6138 value: new Matrix4$1()
6139 },
6140 normalMatrix: {
6141 value: new Matrix3$1()
6142 }
6143 } );
6144 this.matrix = new Matrix4$1();
6145 this.matrixWorld = new Matrix4$1();
6146 this.matrixAutoUpdate = Object3D$1.DefaultMatrixAutoUpdate;
6147 this.matrixWorldNeedsUpdate = false;
6148 this.layers = new Layers$1();
6149 this.visible = true;
6150 this.castShadow = false;
6151 this.receiveShadow = false;
6152 this.frustumCulled = true;
6153 this.renderOrder = 0;
6154 this.userData = {};
6155 }
6156 Object3D$1.DefaultUp = new Vector3$1( 0, 1, 0 );
6157 Object3D$1.DefaultMatrixAutoUpdate = true;
6158 Object3D$1.prototype = Object.assign( Object.create( EventDispatcher$1.prototype ), {
6159 constructor: Object3D$1,
6160 isObject3D: true,
6161 onBeforeRender: function () {},
6162 onAfterRender: function () {},
6163 applyMatrix4: function ( matrix ) {
6164 if ( this.matrixAutoUpdate ) this.updateMatrix();
6165 this.matrix.premultiply( matrix );
6166 this.matrix.decompose( this.position, this.quaternion, this.scale );
6167 },
6168 applyQuaternion: function ( q ) {
6169 this.quaternion.premultiply( q );
6170 return this;
6171 },
6172 setRotationFromAxisAngle: function ( axis, angle ) {
6173 this.quaternion.setFromAxisAngle( axis, angle );
6174 },
6175 setRotationFromEuler: function ( euler ) {
6176 this.quaternion.setFromEuler( euler, true );
6177 },
6178 setRotationFromMatrix: function ( m ) {
6179 this.quaternion.setFromRotationMatrix( m );
6180 },
6181 setRotationFromQuaternion: function ( q ) {
6182 this.quaternion.copy( q );
6183 },
6184 rotateOnAxis: function ( axis, angle ) {
6185 _q1$1.setFromAxisAngle( axis, angle );
6186 this.quaternion.multiply( _q1$1 );
6187 return this;
6188 },
6189 rotateOnWorldAxis: function ( axis, angle ) {
6190 _q1$1.setFromAxisAngle( axis, angle );
6191 this.quaternion.premultiply( _q1$1 );
6192 return this;
6193 },
6194 rotateX: function ( angle ) {
6195 return this.rotateOnAxis( _xAxis$1, angle );
6196 },
6197 rotateY: function ( angle ) {
6198 return this.rotateOnAxis( _yAxis$1, angle );
6199 },
6200 rotateZ: function ( angle ) {
6201 return this.rotateOnAxis( _zAxis$1, angle );
6202 },
6203 translateOnAxis: function ( axis, distance ) {
6204 _v1$6.copy( axis ).applyQuaternion( this.quaternion );
6205 this.position.add( _v1$6.multiplyScalar( distance ) );
6206 return this;
6207 },
6208 translateX: function ( distance ) {
6209 return this.translateOnAxis( _xAxis$1, distance );
6210 },
6211 translateY: function ( distance ) {
6212 return this.translateOnAxis( _yAxis$1, distance );
6213 },
6214 translateZ: function ( distance ) {
6215 return this.translateOnAxis( _zAxis$1, distance );
6216 },
6217 localToWorld: function ( vector ) {
6218 return vector.applyMatrix4( this.matrixWorld );
6219 },
6220 worldToLocal: function ( vector ) {
6221 return vector.applyMatrix4( _m1$4.getInverse( this.matrixWorld ) );
6222 },
6223 lookAt: function ( x, y, z ) {
6224 if ( x.isVector3 ) {
6225 _target$1.copy( x );
6226 } else {
6227 _target$1.set( x, y, z );
6228 }
6229 const parent = this.parent;
6230 this.updateWorldMatrix( true, false );
6231 _position$4.setFromMatrixPosition( this.matrixWorld );
6232 if ( this.isCamera || this.isLight ) {
6233 _m1$4.lookAt( _position$4, _target$1, this.up );
6234 } else {
6235 _m1$4.lookAt( _target$1, _position$4, this.up );
6236 }
6237 this.quaternion.setFromRotationMatrix( _m1$4 );
6238 if ( parent ) {
6239 _m1$4.extractRotation( parent.matrixWorld );
6240 _q1$1.setFromRotationMatrix( _m1$4 );
6241 this.quaternion.premultiply( _q1$1.inverse() );
6242 }
6243 },
6244 add: function ( object ) {
6245 if ( arguments.length > 1 ) {
6246 for ( let i = 0; i < arguments.length; i ++ ) {
6247 this.add( arguments[ i ] );
6248 }
6249 return this;
6250 }
6251 if ( object === this ) {
6252 console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object );
6253 return this;
6254 }
6255 if ( ( object && object.isObject3D ) ) {
6256 if ( object.parent !== null ) {
6257 object.parent.remove( object );
6258 }
6259 object.parent = this;
6260 this.children.push( object );
6261 object.dispatchEvent( _addedEvent$1 );
6262 } else {
6263 console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object );
6264 }
6265 return this;
6266 },
6267 remove: function ( object ) {
6268 if ( arguments.length > 1 ) {
6269 for ( let i = 0; i < arguments.length; i ++ ) {
6270 this.remove( arguments[ i ] );
6271 }
6272 return this;
6273 }
6274 const index = this.children.indexOf( object );
6275 if ( index !== - 1 ) {
6276 object.parent = null;
6277 this.children.splice( index, 1 );
6278 object.dispatchEvent( _removedEvent$1 );
6279 }
6280 return this;
6281 },
6282 attach: function ( object ) {
6283 this.updateWorldMatrix( true, false );
6284 _m1$4.getInverse( this.matrixWorld );
6285 if ( object.parent !== null ) {
6286 object.parent.updateWorldMatrix( true, false );
6287 _m1$4.multiply( object.parent.matrixWorld );
6288 }
6289 object.applyMatrix4( _m1$4 );
6290 object.updateWorldMatrix( false, false );
6291 this.add( object );
6292 return this;
6293 },
6294 getObjectById: function ( id ) {
6295 return this.getObjectByProperty( 'id', id );
6296 },
6297 getObjectByName: function ( name ) {
6298 return this.getObjectByProperty( 'name', name );
6299 },
6300 getObjectByProperty: function ( name, value ) {
6301 if ( this[ name ] === value ) return this;
6302 for ( let i = 0, l = this.children.length; i < l; i ++ ) {
6303 const child = this.children[ i ];
6304 const object = child.getObjectByProperty( name, value );
6305 if ( object !== undefined ) {
6306 return object;
6307 }
6308 }
6309 return undefined;
6310 },
6311 getWorldPosition: function ( target ) {
6312 if ( target === undefined ) {
6313 console.warn( 'THREE.Object3D: .getWorldPosition() target is now required' );
6314 target = new Vector3$1();
6315 }
6316 this.updateMatrixWorld( true );
6317 return target.setFromMatrixPosition( this.matrixWorld );
6318 },
6319 getWorldQuaternion: function ( target ) {
6320 if ( target === undefined ) {
6321 console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' );
6322 target = new Quaternion$1();
6323 }
6324 this.updateMatrixWorld( true );
6325 this.matrixWorld.decompose( _position$4, target, _scale$3 );
6326 return target;
6327 },
6328 getWorldScale: function ( target ) {
6329 if ( target === undefined ) {
6330 console.warn( 'THREE.Object3D: .getWorldScale() target is now required' );
6331 target = new Vector3$1();
6332 }
6333 this.updateMatrixWorld( true );
6334 this.matrixWorld.decompose( _position$4, _quaternion$5, target );
6335 return target;
6336 },
6337 getWorldDirection: function ( target ) {
6338 if ( target === undefined ) {
6339 console.warn( 'THREE.Object3D: .getWorldDirection() target is now required' );
6340 target = new Vector3$1();
6341 }
6342 this.updateMatrixWorld( true );
6343 const e = this.matrixWorld.elements;
6344 return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize();
6345 },
6346 raycast: function () {},
6347 traverse: function ( callback ) {
6348 callback( this );
6349 const children = this.children;
6350 for ( let i = 0, l = children.length; i < l; i ++ ) {
6351 children[ i ].traverse( callback );
6352 }
6353 },
6354 traverseVisible: function ( callback ) {
6355 if ( this.visible === false ) return;
6356 callback( this );
6357 const children = this.children;
6358 for ( let i = 0, l = children.length; i < l; i ++ ) {
6359 children[ i ].traverseVisible( callback );
6360 }
6361 },
6362 traverseAncestors: function ( callback ) {
6363 const parent = this.parent;
6364 if ( parent !== null ) {
6365 callback( parent );
6366 parent.traverseAncestors( callback );
6367 }
6368 },
6369 updateMatrix: function () {
6370 this.matrix.compose( this.position, this.quaternion, this.scale );
6371 this.matrixWorldNeedsUpdate = true;
6372 },
6373 updateMatrixWorld: function ( force ) {
6374 if ( this.matrixAutoUpdate ) this.updateMatrix();
6375 if ( this.matrixWorldNeedsUpdate || force ) {
6376 if ( this.parent === null ) {
6377 this.matrixWorld.copy( this.matrix );
6378 } else {
6379 this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
6380 }
6381 this.matrixWorldNeedsUpdate = false;
6382 force = true;
6383 }
6384 const children = this.children;
6385 for ( let i = 0, l = children.length; i < l; i ++ ) {
6386 children[ i ].updateMatrixWorld( force );
6387 }
6388 },
6389 updateWorldMatrix: function ( updateParents, updateChildren ) {
6390 const parent = this.parent;
6391 if ( updateParents === true && parent !== null ) {
6392 parent.updateWorldMatrix( true, false );
6393 }
6394 if ( this.matrixAutoUpdate ) this.updateMatrix();
6395 if ( this.parent === null ) {
6396 this.matrixWorld.copy( this.matrix );
6397 } else {
6398 this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
6399 }
6400 if ( updateChildren === true ) {
6401 const children = this.children;
6402 for ( let i = 0, l = children.length; i < l; i ++ ) {
6403 children[ i ].updateWorldMatrix( false, true );
6404 }
6405 }
6406 },
6407 toJSON: function ( meta ) {
6408 const isRootObject = ( meta === undefined || typeof meta === 'string' );
6409 const output = {};
6410 if ( isRootObject ) {
6411 meta = {
6412 geometries: {},
6413 materials: {},
6414 textures: {},
6415 images: {},
6416 shapes: {}
6417 };
6418 output.metadata = {
6419 version: 4.5,
6420 type: 'Object',
6421 generator: 'Object3D.toJSON'
6422 };
6423 }
6424 const object = {};
6425 object.uuid = this.uuid;
6426 object.type = this.type;
6427 if ( this.name !== '' ) object.name = this.name;
6428 if ( this.castShadow === true ) object.castShadow = true;
6429 if ( this.receiveShadow === true ) object.receiveShadow = true;
6430 if ( this.visible === false ) object.visible = false;
6431 if ( this.frustumCulled === false ) object.frustumCulled = false;
6432 if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder;
6433 if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;
6434 object.layers = this.layers.mask;
6435 object.matrix = this.matrix.toArray();
6436 if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false;
6437 if ( this.isInstancedMesh ) {
6438 object.type = 'InstancedMesh';
6439 object.count = this.count;
6440 object.instanceMatrix = this.instanceMatrix.toJSON();
6441 }
6442 function serialize( library, element ) {
6443 if ( library[ element.uuid ] === undefined ) {
6444 library[ element.uuid ] = element.toJSON( meta );
6445 }
6446 return element.uuid;
6447 }
6448 if ( this.isMesh || this.isLine || this.isPoints ) {
6449 object.geometry = serialize( meta.geometries, this.geometry );
6450 const parameters = this.geometry.parameters;
6451 if ( parameters !== undefined && parameters.shapes !== undefined ) {
6452 const shapes = parameters.shapes;
6453 if ( Array.isArray( shapes ) ) {
6454 for ( let i = 0, l = shapes.length; i < l; i ++ ) {
6455 const shape = shapes[ i ];
6456 serialize( meta.shapes, shape );
6457 }
6458 } else {
6459 serialize( meta.shapes, shapes );
6460 }
6461 }
6462 }
6463 if ( this.material !== undefined ) {
6464 if ( Array.isArray( this.material ) ) {
6465 const uuids = [];
6466 for ( let i = 0, l = this.material.length; i < l; i ++ ) {
6467 uuids.push( serialize( meta.materials, this.material[ i ] ) );
6468 }
6469 object.material = uuids;
6470 } else {
6471 object.material = serialize( meta.materials, this.material );
6472 }
6473 }
6474 if ( this.children.length > 0 ) {
6475 object.children = [];
6476 for ( let i = 0; i < this.children.length; i ++ ) {
6477 object.children.push( this.children[ i ].toJSON( meta ).object );
6478 }
6479 }
6480 if ( isRootObject ) {
6481 const geometries = extractFromCache( meta.geometries );
6482 const materials = extractFromCache( meta.materials );
6483 const textures = extractFromCache( meta.textures );
6484 const images = extractFromCache( meta.images );
6485 const shapes = extractFromCache( meta.shapes );
6486 if ( geometries.length > 0 ) output.geometries = geometries;
6487 if ( materials.length > 0 ) output.materials = materials;
6488 if ( textures.length > 0 ) output.textures = textures;
6489 if ( images.length > 0 ) output.images = images;
6490 if ( shapes.length > 0 ) output.shapes = shapes;
6491 }
6492 output.object = object;
6493 return output;
6494 function extractFromCache( cache ) {
6495 const values = [];
6496 for ( const key in cache ) {
6497 const data = cache[ key ];
6498 delete data.metadata;
6499 values.push( data );
6500 }
6501 return values;
6502 }
6503 },
6504 clone: function ( recursive ) {
6505 return new this.constructor().copy( this, recursive );
6506 },
6507 copy: function ( source, recursive ) {
6508 if ( recursive === undefined ) recursive = true;
6509 this.name = source.name;
6510 this.up.copy( source.up );
6511 this.position.copy( source.position );
6512 this.rotation.order = source.rotation.order;
6513 this.quaternion.copy( source.quaternion );
6514 this.scale.copy( source.scale );
6515 this.matrix.copy( source.matrix );
6516 this.matrixWorld.copy( source.matrixWorld );
6517 this.matrixAutoUpdate = source.matrixAutoUpdate;
6518 this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
6519 this.layers.mask = source.layers.mask;
6520 this.visible = source.visible;
6521 this.castShadow = source.castShadow;
6522 this.receiveShadow = source.receiveShadow;
6523 this.frustumCulled = source.frustumCulled;
6524 this.renderOrder = source.renderOrder;
6525 this.userData = JSON.parse( JSON.stringify( source.userData ) );
6526 if ( recursive === true ) {
6527 for ( let i = 0; i < source.children.length; i ++ ) {
6528 const child = source.children[ i ];
6529 this.add( child.clone() );
6530 }
6531 }
6532 return this;
6533 }
6534 } );
6535
6536 const { checkArg, checkArgs } = util;
6537 class Turtle3D extends Turtle {
6538 static defaultVariables() {
6539 return {
6540 atEdge: 'wrap',
6541 hidden: false,
6542 }
6543 }
6544 constructor() {
6545 super();
6546 Object.assign(this, Turtle3D.defaultVariables());
6547 }
6548 agentConstructor() {
6549 this.obj3d = new Object3D$1();
6550 this.obj3d.rotation.order = 'ZYX';
6551 this.reset();
6552 }
6553 reset() {
6554 this.obj3d.position.set(0, 0, 0);
6555 this.obj3d.rotation.set(0, 0, 0);
6556 this.heading = 0;
6557 }
6558 setxyz(x, y, z) {
6559 checkArgs(arguments);
6560 super.setxy(x, y, z);
6561 }
6562 getxyz() {
6563 return this.obj3d.position.toArray()
6564 }
6565 setRotation(x, y, z) {
6566 checkArgs(arguments);
6567 this.obj3d.rotation.set(x, y, z);
6568 }
6569 getRotation() {
6570 const { x, y, z } = this.obj3d.rotation;
6571 return [x, y, z]
6572 }
6573 getThetaPhiPsi() {
6574 return this.getRotation().reverse()
6575 }
6576 getHeadingPitchRoll() {
6577 const [psi, phi, theta] = this.getRotation();
6578 const heading = radToHeading(theta);
6579 const pitch = radToDeg(-phi);
6580 const roll = radToDeg(psi);
6581 return [heading, pitch, roll]
6582 }
6583 getDxDyDz() {
6584 return [this.dx, this.dy, this.dz]
6585 }
6586 get x() {
6587 return this.obj3d.position.x
6588 }
6589 set x(d) {
6590 checkArg(d);
6591 this.obj3d.position.x = d;
6592 }
6593 get y() {
6594 return this.obj3d.position.y
6595 }
6596 set y(d) {
6597 checkArg(d);
6598 this.obj3d.position.y = d;
6599 }
6600 get z() {
6601 return this.obj3d.position.z
6602 }
6603 set z(d) {
6604 checkArg(d);
6605 this.obj3d.position.z = d;
6606 }
6607 get theta() {
6608 return this.obj3d.rotation.z
6609 }
6610 set theta(rad) {
6611 checkArg(rad);
6612 if (this.obj3d) this.obj3d.rotation.z = rad;
6613 }
6614 get heading() {
6615 return this.model.fromRads(this.obj3d.rotation.z)
6616 }
6617 set heading(angle) {
6618 checkArg(angle);
6619 this.obj3d.rotation.z = this.model.toRads(angle);
6620 }
6621 get pitch() {
6622 return -this.model.fromAngleRads(this.obj3d.rotation.y)
6623 }
6624 set pitch(angle) {
6625 checkArg(angle);
6626 this.obj3d.rotation.y = -this.model.toAngleRads(angle);
6627 }
6628 get roll() {
6629 return this.model.fromAngleRads(this.obj3d.rotation.x)
6630 }
6631 set roll(angle) {
6632 checkArg(angle);
6633 this.obj3d.rotation.x = this.model.toAngleRads(angle);
6634 }
6635 forward(d) {
6636 checkArg(d);
6637 const p0 = this.patch;
6638 this.obj3d.translateX(d);
6639 super.checkXYZ(p0);
6640 }
6641 right(angle) {
6642 this.left(-angle);
6643 }
6644 left(angle) {
6645 checkArg(angle);
6646 this.obj3d.rotateZ(this.model.toAngleRads(angle));
6647 }
6648 tiltUp(angle) {
6649 this.tiltDown(-angle);
6650 }
6651 tiltDown(angle) {
6652 checkArg(angle);
6653 this.obj3d.rotateY(this.model.toAngleRads(angle));
6654 }
6655 rollRight(angle) {
6656 checkArg(angle);
6657 this.obj3d.rotateX(this.model.toAngleRads(angle));
6658 }
6659 rollLeft(angle) {
6660 this.rollRight(-angle);
6661 }
6662 facexyz(x1, y1, z1) {
6663 checkArgs(arguments);
6664 const headingTowards = this.towardsXY(x1, y1);
6665 const pitchTowards = this.towardsPitchXYZ(x1, y1, z1);
6666 this.heading = headingTowards;
6667 this.pitch = pitchTowards;
6668 }
6669 face(agent) {
6670 checkArg(agent, 'object');
6671 const { x, y, z } = agent;
6672 this.facexyz(x, y, z);
6673 }
6674 towardsPitchXYZ(x1, y1, z1) {
6675 checkArgs(arguments);
6676 const [x, y, z] = this.getxyz();
6677 const [dx, dy, dz] = [x1 - x, y1 - y, z1 - z];
6678 const xyhypot = Math.hypot(dx, dy);
6679 const pitchRads = Math.atan2(dz, xyhypot);
6680 return this.model.fromAngleRads(pitchRads)
6681 }
6682 towardsPitch(agent) {
6683 checkArg(agent, 'object');
6684 const { x, y, z } = agent;
6685 this.towardsPitchXYZ(x, y, z);
6686 }
6687 distance(agent) {
6688 checkArg(agent, 'object');
6689 const { x, y, z } = agent;
6690 return this.distanceXYZ(x, y, z)
6691 }
6692 distanceXYZ(x1, y1, z1) {
6693 checkArgs(arguments);
6694 const { x, y, z } = this;
6695 return distance3(x, y, z, x1, y1, z1)
6696 }
6697 get dx() {
6698 const { y: pitch, z: heading } = this.obj3d.rotation;
6699 return Math.cos(pitch) * Math.cos(heading)
6700 }
6701 get dy() {
6702 const { y: pitch, z: heading } = this.obj3d.rotation;
6703 return Math.cos(pitch) * Math.sin(heading)
6704 }
6705 get dz() {
6706 const pitch = this.obj3d.rotation.y;
6707 return Math.sin(pitch)
6708 }
6709 }
6710
6711 class Model3D extends Model {
6712 initAgentSet(name, AgentsetClass, AgentClass) {
6713 if (name === 'turtles') AgentClass = Turtle3D;
6714 super.initAgentSet(name, AgentsetClass, AgentClass);
6715 }
6716 }
6717
6718 const Color$1 = {
6719 rgbaCssColor(r, g, b, a = 255) {
6720 a = a / 255;
6721 const a2 = a.toPrecision(2);
6722 return a === 1 ? `rgb(${r},${g},${b})` : `rgba(${r},${g},${b},${a2})`
6723 },
6724 hslCssColor(h, s = 100, l = 50, a = 255) {
6725 a = a / 255;
6726 const a4 = a.toPrecision(4);
6727 return a === 1
6728 ? `hsl(${h},${s}%,${l}%)`
6729 : `hsla(${h},${s}%,${l}%,${a4})`
6730 },
6731 hexCssColor(r, g, b) {
6732 return `#${(0x1000000 | (b | (g << 8) | (r << 16)))
6733 .toString(16)
6734 .slice(-6)}`
6735 },
6736 cssColor(r, g, b, a = 255) {
6737 return a === 255
6738 ? this.hexCssColor(r, g, b)
6739 : this.rgbaCssColor(r, g, b, a)
6740 },
6741 randomCssColor() {
6742 const r255 = () => randomInt(256);
6743 return this.cssColor(r255(), r255(), r255())
6744 },
6745 randomGrayCssColor(min = 0, max = 255) {
6746 const gray = randomInt2(min, max);
6747 return this.cssColor(gray, gray, gray)
6748 },
6749 cssToPixel(string) {
6750 const rgba = this.cssToUint8Array(string);
6751 return this.rgbaToPixel(...rgba)
6752 },
6753 rgbaToPixel(r, g, b, a = 255) {
6754 const rgba = new Uint8Array([r, g, b, a]);
6755 const pixels = new Uint32Array(rgba.buffer);
6756 return pixels[0]
6757 },
6758 randomPixel() {
6759 const r255 = () => randomInt(256);
6760 return this.rgbaToPixel(r255(), r255(), r255())
6761 },
6762 randomGrayPixel(min = 0, max = 255) {
6763 const gray = randomInt2(min, max);
6764 return this.rgbaToPixel(gray, gray, gray)
6765 },
6766 sharedCtx1x1: createCtx(1, 1, false, { willReadFrequently: true }),
6767 cssToUint8Array(string) {
6768 this.sharedCtx1x1.clearRect(0, 0, 1, 1);
6769 this.sharedCtx1x1.fillStyle = string;
6770 this.sharedCtx1x1.fillRect(0, 0, 1, 1);
6771 return this.sharedCtx1x1.getImageData(0, 0, 1, 1).data
6772 },
6773 typedColor(r, g, b, a = 255) {
6774 if (g === undefined) return this.toTypedColor(r)
6775 const u8array = new Uint8ClampedArray([r, g, b, a]);
6776 u8array.pixelArray = new Uint32Array(u8array.buffer);
6777 Object.setPrototypeOf(u8array, TypedColorProto);
6778 return u8array
6779 },
6780 isTypedColor(any) {
6781 return any && any.constructor === Uint8ClampedArray && any.pixelArray
6782 },
6783 toTypedColor(value, colorType) {
6784 if (this.isTypedColor(value)) return value
6785 const tc = this.typedColor(0, 0, 0, 0);
6786 if (colorType == null) {
6787 if (isString(value)) tc.css = value;
6788 else if (isNumber$1(value)) tc.pixel = value;
6789 else if (isArray(value)) tc.rgb = value;
6790 else if (isTypedArray(value)) tc.rgb = value;
6791 else throw Error(`toTypedColor: illegal value ${value}`)
6792 } else {
6793 tc[colorType] = value;
6794 }
6795 return tc
6796 },
6797 randomTypedColor() {
6798 const r255 = () => randomInt(256);
6799 return this.typedColor(r255(), r255(), r255())
6800 },
6801 randomGrayTypedColor(min = 0, max = 255) {
6802 const gray = randomInt2(min, max);
6803 return this.typedColor(gray, gray, gray)
6804 },
6805 randomColorArray(length) {
6806 const colors = new Array(length);
6807 forLoop(colors, (c, i) => (colors[i] = this.randomTypedColor()));
6808 return colors
6809 },
6810 randomGrayArray(length, min = 0, max = 255) {
6811 const grays = new Array(length);
6812 forLoop(
6813 grays,
6814 (g, i) => (grays[i] = this.randomGrayTypedColor(min, max))
6815 );
6816 return grays
6817 },
6818 };
6819 const TypedColorProto = {
6820 __proto__: Uint8ClampedArray.prototype,
6821 setColor(r, g, b, a = 255) {
6822 this.checkColorChange();
6823 this[0] = r;
6824 this[1] = g;
6825 this[2] = b;
6826 this[3] = a;
6827 },
6828 set rgb(rgbaArray) {
6829 this.setColor(...rgbaArray);
6830 },
6831 get rgb() {
6832 return this
6833 },
6834 setAlpha(alpha) {
6835 this.checkColorChange();
6836 this[3] = alpha;
6837 },
6838 getAlpha() {
6839 return this[3]
6840 },
6841 get alpha() {
6842 return this.getAlpha()
6843 },
6844 set alpha(alpha) {
6845 this.setAlpha(alpha);
6846 },
6847 setPixel(pixel) {
6848 this.checkColorChange();
6849 this.pixelArray[0] = pixel;
6850 },
6851 getPixel() {
6852 return this.pixelArray[0]
6853 },
6854 get pixel() {
6855 return this.getPixel()
6856 },
6857 set pixel(pixel) {
6858 this.setPixel(pixel);
6859 },
6860 setCss(string) {
6861 return this.setColor(...Color$1.cssToUint8Array(string))
6862 },
6863 getCss() {
6864 if (this.string == null) this.string = Color$1.cssColor(...this);
6865 return this.string
6866 },
6867 get css() {
6868 return this.getCss()
6869 },
6870 set css(string) {
6871 this.setCss(string);
6872 },
6873 setWebgl(array) {
6874 if (array.length !== 3)
6875 throw Error(
6876 'setWebgl array length must be 3, length:',
6877 array.length
6878 )
6879 this.setColor(
6880 array[0] * 255,
6881 array[1] * 255,
6882 array[2] * 255
6883 );
6884 },
6885 getWebgl() {
6886 return [this[0] / 255, this[1] / 255, this[2] / 255]
6887 },
6888 get webgl() {
6889 return this.getWebgl()
6890 },
6891 set webgl(array) {
6892 this.setWebgl(array);
6893 },
6894 checkColorChange() {
6895 this.string = null;
6896 },
6897 equals(color) {
6898 return this.getPixel() === color.getPixel()
6899 },
6900 toString() {
6901 return `[${Array.from(this).toString()}]`
6902 },
6903 rgbDistance(r, g, b) {
6904 const [r1, g1, b1] = this;
6905 const rMean = Math.round((r1 + r) / 2);
6906 const [dr, dg, db] = [r1 - r, g1 - g, b1 - b];
6907 const [dr2, dg2, db2] = [dr * dr, dg * dg, db * db];
6908 const distanceSq =
6909 (((512 + rMean) * dr2) >> 8) +
6910 4 * dg2 +
6911 (((767 - rMean) * db2) >> 8);
6912 return distanceSq
6913 },
6914 };
6915
6916 function getPixel(color) {
6917 if (typeof color === 'number') return color
6918 if (color.pixel) return color.pixel
6919 if (color === 'transparent') return 0
6920 return Color$1.toTypedColor(color).pixel
6921 }
6922 class PatchesView {
6923 constructor(width, height) {
6924 this.ctx = createCtx(width, height);
6925 this.resetImageData();
6926 this.useImageSmoothing = false;
6927 }
6928 resetImageData() {
6929 this.imageData = ctxImageData(this.ctx);
6930 this.pixels = new Uint32Array(this.imageData.data.buffer);
6931 }
6932 setPatchesSmoothing(smoothting) {
6933 this.useImageSmoothing = smoothting;
6934 }
6935 setPixels(data, pixelFcn = d => d) {
6936 if (isOofA(data)) data = toAofO(data);
6937 if (data.length !== this.pixels.length) {
6938 throw Error(
6939 'setPixels, data.length != pixels.length ' +
6940 data.length +
6941 ' ' +
6942 this.pixels.length
6943 )
6944 }
6945 forLoop(data, (d, i) => {
6946 this.pixels[i] = getPixel(pixelFcn(d));
6947 });
6948 }
6949 createPixels(pixelFcn) {
6950 repeat(this.pixels.length, i => {
6951 this.pixels[i] = getPixel(pixelFcn(i));
6952 });
6953 }
6954 setPixel(index, pixel) {
6955 this.pixels[index] = getPixel(pixel);
6956 }
6957 draw(ctx) {
6958 const smoothing = this.ctx.imageSmoothingEnabled;
6959 ctx.imageSmoothingEnabled = this.useImageSmoothing;
6960 this.ctx.putImageData(this.imageData, 0, 0);
6961 fillCtxWithImage(ctx, this.ctx.canvas);
6962 ctx.imageSmoothingEnabled = smoothing;
6963 }
6964 clear(color) {
6965 color = color.css || color;
6966 if (!color || typeof color === 'string') {
6967 clearCtx(this.ctx, color);
6968 } else if (typeof color === 'number') {
6969 this.createPixels(() => color);
6970 } else {
6971 throw Error('patchesView.clear(): illegal color ' + color)
6972 }
6973 if (typeof color === 'number') {
6974 this.updateCanvas();
6975 } else {
6976 this.resetImageData();
6977 }
6978 }
6979 getImageBitmap(options = {}) {
6980 return createImageBitmap(this.imageData, options)
6981 }
6982 drawImageBitmap(ctx, options = {}) {
6983 createImageBitmap(this.imageData, options).then(img =>
6984 fillCtxWithImage(ctx, img)
6985 );
6986 }
6987 updateCanvas() {
6988 this.ctx.putImageData(this.imageData, 0, 0);
6989 return this.ctx.canvas
6990 }
6991 }
6992
6993 class RGBDataSet extends DataSet {
6994 static rgbToInt24(r, g, b) {
6995 return r * 256 * 256 + g * 256 + b
6996 }
6997 static rgbScaleFunction(min, scale) {
6998 return (r, g, b) => min + (r * 256 * 256 + g * 256 + b) * scale
6999 }
7000 constructor(
7001 img,
7002 rgbToData = RGBDataSet.rgbToInt24,
7003 ArrayType = Float32Array
7004 ) {
7005 super(img.width, img.height, new ArrayType(img.width * img.height));
7006 if (Array.isArray(rgbToData))
7007 rgbToData = RGBDataSet.newRgbDataFunction(rgbToData);
7008 const ctx = imageToCtx(img);
7009 const imgData = ctxImageData(ctx);
7010 const convertedData = this.data;
7011 for (var i = 0; i < convertedData.length; i++) {
7012 const r = imgData.data[4 * i];
7013 const g = imgData.data[4 * i + 1];
7014 const b = imgData.data[4 * i + 2];
7015 convertedData[i] = rgbToData(r, g, b);
7016 }
7017 }
7018 }
7019
7020 class RGBADataSet extends DataSet {
7021 constructor(img, Type = Float32Array, options = {}) {
7022 const bytes = imageToBytes(img);
7023 const data = new Type(bytes.buffer);
7024 const dataPerPixel = (4 * data.length) / bytes.length;
7025 const width = dataPerPixel * img.width;
7026 const height = img.height;
7027 super(width, height, data);
7028 Object.assign(this, options);
7029 this.src = img.src;
7030 }
7031 }
7032 let imageToBytesCtx = null;
7033 function imageToBytes(img, flipY = false, imgFormat = 'RGBA') {
7034 if (!imageToBytesCtx) {
7035 const can = createCanvas(0, 0);
7036 imageToBytesCtx = can.getContext('webgl', {
7037 premultipliedAlpha: false,
7038 });
7039 }
7040 const { width, height } = img;
7041 const gl = imageToBytesCtx;
7042 Object.assign(gl.canvas, { width, height });
7043 const fmt = gl[imgFormat];
7044 const texture = gl.createTexture();
7045 gl.bindTexture(gl.TEXTURE_2D, texture);
7046 if (flipY) {
7047 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
7048 }
7049 gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
7050 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
7051 gl.texImage2D(gl.TEXTURE_2D, 0, fmt, fmt, gl.UNSIGNED_BYTE, img);
7052 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
7053 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
7054 const framebuffer = gl.createFramebuffer();
7055 gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
7056 gl.framebufferTexture2D(
7057 gl.FRAMEBUFFER,
7058 gl.COLOR_ATTACHMENT0,
7059 gl.TEXTURE_2D,
7060 texture,
7061 0
7062 );
7063 const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
7064 if (status !== gl.FRAMEBUFFER_COMPLETE) {
7065 throw Error(`imageToBytes: status not FRAMEBUFFER_COMPLETE: ${status}`)
7066 }
7067 const pixSize = imgFormat === 'RGB' ? 3 : 4;
7068 const pixels = new Uint8Array(pixSize * width * height);
7069 gl.readPixels(0, 0, width, height, fmt, gl.UNSIGNED_BYTE, pixels);
7070 gl.bindFramebuffer(gl.FRAMEBUFFER, null);
7071 return pixels
7072 }
7073
7074 var RGBADataSet$1 = /*#__PURE__*/Object.freeze({
7075 __proto__: null,
7076 imageToBytes: imageToBytes,
7077 default: RGBADataSet
7078 });
7079
7080 function rgbToInt24(r, g, b) {
7081 return r * 256 * 256 + g * 256 + b
7082 }
7083 function rgbScaleFunction(min, scale) {
7084 return (r, g, b) => min + rgbToInt24(r, g, b) * scale
7085 }
7086 function redfishElevation(r, g, b) {
7087 let negative = 1;
7088 if (r > 63) {
7089 negative = -1;
7090 r = 0;
7091 }
7092 return (negative * rgbToInt24(r, g, b)) / 10
7093 }
7094 const sharedTileObject = {
7095 zxyToTile: async function (z, x, y) {
7096 const tileUrl = this.zxyUrl(z, x, y);
7097 const img = await imagePromise(tileUrl);
7098 img.zxy = [z, x, y];
7099 return img
7100 },
7101 zxyToDataSet: async function (z, x, y, ArrayType = Float32Array) {
7102 const img = await this.zxyToTile(z, x, y);
7103 const dataSet = this.tileDataSet(img, ArrayType);
7104 dataSet.zxy = [z, x, y];
7105 return dataSet
7106 },
7107 tileDataSet: function (img, ArrayType = Float32Array) {
7108 const tileDecoder = this.elevationFcn;
7109 return new RGBDataSet(img, tileDecoder, ArrayType)
7110 },
7111 tileSize: 256,
7112 };
7113 const maptiler = Object.assign(
7114 {
7115 elevationFcn: rgbScaleFunction(-10000, 0.1),
7116 zxyUrl: (z, x, y) =>
7117 `https://api.maptiler.com/tiles/terrain-rgb/${z}/${x}/${y}.png?key=iQurAP6lArV1UP4gfSVs`,
7118 zxyTemplate:
7119 'https://api.maptiler.com/tiles/terrain-rgb/{z}/{x}/{y}.png?key=iQurAP6lArV1UP4gfSVs',
7120 minZoom: 0,
7121 maxZoom: 15,
7122 },
7123 sharedTileObject
7124 );
7125 const mapzen = Object.assign(
7126 {
7127 elevationFcn: rgbScaleFunction(-32768, 1 / 256),
7128 zxyUrl: (z, x, y) =>
7129 `https://s3.amazonaws.com/elevation-tiles-prod/terrarium/${z}/${x}/${y}.png`,
7130 zxyTemplate:
7131 'https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png',
7132 minZoom: 0,
7133 maxZoom: 15,
7134 },
7135 sharedTileObject
7136 );
7137 const redfishUSA = Object.assign(
7138 {
7139 elevationFcn: redfishElevation,
7140 zxyUrl: (z, x, y) =>
7141 `https://s3-us-west-2.amazonaws.com/simtable-elevation-tiles/${z}/${x}/${y}.png`,
7142 zxyTemplate:
7143 'https://s3-us-west-2.amazonaws.com/simtable-elevation-tiles/{z}/{x}/{y}.png',
7144 minZoom: 10,
7145 maxZoom: 14,
7146 },
7147 sharedTileObject
7148 );
7149 const redfishWorld = Object.assign(
7150 {
7151 elevationFcn: redfishElevation,
7152 zxyUrl: (z, x, y) =>
7153 `https://s3-us-west-2.amazonaws.com/world-elevation-tiles/DEM_tiles/${z}/${x}/${y}.png`,
7154 zxyTemplate:
7155 'https://s3-us-west-2.amazonaws.com/world-elevation-tiles/DEM_tiles/{z}/{x}/{y}.png',
7156 minZoom: 7,
7157 maxZoom: 13,
7158 },
7159 sharedTileObject
7160 );
7161 const mapboxToken =
7162 'pk.eyJ1IjoiYmFja3NwYWNlcyIsImEiOiJjanVrbzI4dncwOXl3M3ptcGJtN3oxMmhoIn0.x9iSCrtm0iADEqixVgPwqQ';
7163 const mapbox = Object.assign(
7164 {
7165 elevationFcn: rgbScaleFunction(-10000, 0.1),
7166 zxyUrl: (z, x, y) =>
7167 `https://api.mapbox.com/v4/mapbox.terrain-rgb/${z}/${x}/${y}.png?access_token=` +
7168 mapboxToken,
7169 zxyTemplate:
7170 'https://api.mapbox.com/v4/mapbox.terrain-rgb/{z}/{x}/{y}.png?access_token=' +
7171 mapboxToken,
7172 minZoom: 0,
7173 maxZoom: 18,
7174 },
7175 sharedTileObject
7176 );
7177
7178 var TileData = /*#__PURE__*/Object.freeze({
7179 __proto__: null,
7180 maptiler: maptiler,
7181 mapzen: mapzen,
7182 redfishUSA: redfishUSA,
7183 redfishWorld: redfishWorld,
7184 mapbox: mapbox
7185 });
7186
7187 const ColorMap = {
7188 gradientImageData(nColors, stops, locs) {
7189 const ctx = createCtx(nColors, 1);
7190 if (!locs) locs = floatRamp(0, 1, stops.length);
7191 const grad = ctx.createLinearGradient(0, 0, nColors, 0);
7192 repeat(stops.length, i => grad.addColorStop(locs[i], stops[i]));
7193 ctx.fillStyle = grad;
7194 ctx.fillRect(0, 0, nColors, 1);
7195 return ctxImageColors(ctx)
7196 },
7197 arrayToTypedColors(array) {
7198 return array.map(a => Color$1.toTypedColor(a))
7199 },
7200 permuteArrays(A1, A2 = A1, A3 = A1) {
7201 const array = [];
7202 for (const a3 of A3) {
7203 for (const a2 of A2) for (const a1 of A1) array.push([a1, a2, a3]);
7204 }
7205 return array
7206 },
7207 permuteRGBColors(numRs, numGs = numRs, numBs = numRs) {
7208 const toRamp = num => integerRamp(0, 255, num);
7209 const ramps = [numRs, numGs, numBs].map(toRamp);
7210 return this.permuteArrays(...ramps)
7211 },
7212 ColorMapProto: {
7213 __proto__: Array.prototype,
7214 createIndex() {
7215 this.index = [];
7216 repeat(this.length, i => {
7217 const px = this[i].getPixel();
7218 this.index[px] = i;
7219 if (this.cssNames) this.index[this.cssNames[i]] = i;
7220 });
7221 },
7222 randomColor() {
7223 return this[randomInt(this.length)]
7224 },
7225 setAlpha(alpha) {
7226 forLoop(this, color => color.setAlpha(alpha));
7227 },
7228 clone() {
7229 return this.cloneColorMap(this)
7230 },
7231 atIndex(index) {
7232 return this[index % this.length]
7233 },
7234 indexOf(color) {
7235 if (this.index) return this.index[color.getPixel()]
7236 for (let i = 0; i < this.length; i++) {
7237 if (color.equals(this[i])) return i
7238 }
7239 return undefined
7240 },
7241 scaleColor(number, min = 0, max = this.length - 1) {
7242 if (min === max) return this[min]
7243 const scale = lerpScale(number, min, max);
7244 const index = Math.round(lerp(0, this.length - 1, scale));
7245 return this[index]
7246 },
7247 toString() {
7248 return `${this.length} ${arraysToString(this)}`
7249 },
7250 rgbClosestIndex(r, g, b) {
7251 let minDist = Infinity;
7252 let ixMin = 0;
7253 for (var i = 0; i < this.length; i++) {
7254 const d = this[i].rgbDistance(r, g, b);
7255 if (d < minDist) {
7256 minDist = d;
7257 ixMin = i;
7258 if (d === 0) return ixMin
7259 }
7260 }
7261 return ixMin
7262 },
7263 rgbClosestColor(r, g, b) {
7264 return this[this.rgbClosestIndex(r, g, b)]
7265 },
7266 cubeClosestIndex(r, g, b) {
7267 const cube = this.cube;
7268 if (!cube) throw Error('cubeClosestIndex: requires the cube arrays')
7269 const rgbSteps = cube.map(c => 255 / (c - 1));
7270 const rgbLocs = [r, g, b].map((c, i) => Math.round(c / rgbSteps[i]));
7271 const [rLoc, gLoc, bLoc] = rgbLocs;
7272 return rLoc + gLoc * cube[0] + bLoc * cube[0] * cube[1]
7273 },
7274 cubeClosestColor(r, g, b) {
7275 return this[this.cubeClosestIndex(r, g, b)]
7276 },
7277 closestIndex(r, g, b) {
7278 return this.cube
7279 ? this.cubeClosestIndex(r, g, b)
7280 : this.rgbClosestIndex(r, g, b)
7281 },
7282 closestColor(r, g, b) {
7283 return this[this.closestIndex(r, g, b)]
7284 },
7285 },
7286 basicColorMap(colors) {
7287 colors = this.arrayToTypedColors(colors);
7288 Object.setPrototypeOf(colors, this.ColorMapProto);
7289 return colors
7290 },
7291 grayColorMap(min = 0, max = 255, size = max - min + 1) {
7292 const ramp = integerRamp(min, max, size);
7293 return this.basicColorMap(ramp.map(i => [i, i, i]))
7294 },
7295 rgbColorCube(numRs, numGs = numRs, numBs = numRs) {
7296 const array = this.permuteRGBColors(numRs, numGs, numBs);
7297 const map = this.basicColorMap(array);
7298 map.cube = [numRs, numGs, numBs];
7299 return map
7300 },
7301 rgbColorMap(R, G, B) {
7302 const array = this.permuteArrays(R, G, B);
7303 return this.basicColorMap(array)
7304 },
7305 hslColorMap(num = 360, S = 100, L = 50) {
7306 const hues = integerRamp(1, 360, num);
7307 const colors = hues.map(h => Color$1.hslCssColor(h));
7308 const typedColors = colors.map(c => Color$1.toTypedColor(c));
7309 return this.basicColorMap(typedColors)
7310 },
7311 transparentColorMap(num = 1) {
7312 return this.staticColorMap(0, num)
7313 },
7314 staticColorMap(color, num = 1) {
7315 color = Color$1.toTypedColor(color);
7316 const array = Array(num).fill(color);
7317 return this.basicColorMap(array)
7318 },
7319 gradientColorMap(nColors, stops, locs) {
7320 stops = stops.map(c => c.css || c);
7321 const uint8arrays = this.gradientImageData(nColors, stops, locs);
7322 const typedColors = this.arrayToTypedColors(uint8arrays);
7323 Object.setPrototypeOf(typedColors, this.ColorMapProto);
7324 return typedColors
7325 },
7326 jetColors: [
7327 'rgb(0, 0, 127)',
7328 'rgb(0, 0, 255)',
7329 'rgb(0, 127, 255)',
7330 'rgb(0, 255, 255)',
7331 'rgb(127, 255, 127)',
7332 'rgb(255, 255, 0)',
7333 'rgb(255, 127, 0)',
7334 'rgb(255, 0, 0)',
7335 'rgb(127, 0, 0)',
7336 ],
7337 basicColorNames:
7338 'white silver gray black red maroon yellow orange olive lime green cyan teal blue navy magenta purple'.split(
7339 ' '
7340 ),
7341 brightColorNames:
7342 'white silver red maroon yellow orange olive lime green cyan teal blue navy magenta purple'.split(
7343 ' '
7344 ),
7345 cssColorMap(cssArray, createNameIndex = false) {
7346 const array = cssArray.map(str => Color$1.cssToUint8Array(str));
7347 const map = this.basicColorMap(array);
7348 map.cssNames = cssArray;
7349 if (createNameIndex) {
7350 cssArray.forEach((name, ix) => {
7351 map[name] = map[ix];
7352 });
7353 if (map.cyan) map.aqua = map.cyan;
7354 if (map.magenta) map.fuchsia = map.magenta;
7355 }
7356 return map
7357 },
7358 cloneColorMap(colorMap) {
7359 const keys = Object.keys(colorMap);
7360 const clone = this.basicColorMap(colorMap);
7361 forLoop(keys, (val, i) => {
7362 if (clone[i] === undefined) clone[val] = colorMap[val];
7363 });
7364 return clone
7365 },
7366 LazyMap(name, map) {
7367 Object.defineProperty(this, name, { value: map, enumerable: true });
7368 return map
7369 },
7370 get Gray() {
7371 return this.LazyMap('Gray', this.grayColorMap())
7372 },
7373 get Hue() {
7374 return this.LazyMap('Hue', this.hslColorMap())
7375 },
7376 get LightGray() {
7377 return this.LazyMap('LightGray', this.grayColorMap(200))
7378 },
7379 get DarkGray() {
7380 return this.LazyMap('DarkGray', this.grayColorMap(0, 100))
7381 },
7382 get Jet() {
7383 return this.LazyMap('Jet', this.gradientColorMap(256, this.jetColors))
7384 },
7385 get Rgb256() {
7386 return this.LazyMap('Rgb256', this.rgbColorCube(8, 8, 4))
7387 },
7388 get Rgb() {
7389 return this.LazyMap('Rgb', this.rgbColorCube(16))
7390 },
7391 get Transparent() {
7392 return this.LazyMap('Transparent', this.transparentColorMap())
7393 },
7394 get Basic16() {
7395 return this.LazyMap(
7396 'Basic16',
7397 this.cssColorMap(this.basicColorNames, true)
7398 )
7399 },
7400 };
7401
7402 function cssColor$1(color) {
7403 if (color) return color.css || color
7404 return color
7405 }
7406 class Shapes {
7407 constructor() {
7408 this.cache = {};
7409 this.paths = paths;
7410 }
7411 addPath(name, pathFunction) {
7412 if (this.getPath(name)) ;
7413 paths[name] = pathFunction;
7414 }
7415 needsStrokeColor(shapeName) {
7416 return shapeName.endsWith('2')
7417 }
7418 getPathNames() {
7419 return Object.keys(paths)
7420 }
7421 getPath(name) {
7422 return paths[name]
7423 }
7424 oneOf() {
7425 return oneValOf(paths)
7426 }
7427 nameAtIndex(index) {
7428 const names = this.getPathNames();
7429 return names[mod(index, names.length)]
7430 }
7431 atIndex(index) {
7432 const name = this.nameAtIndex(index);
7433 return paths[name]
7434 }
7435 imagePathPromise(name, imgURL) {
7436 return imagePromise(imgURL).then(img => {
7437 this.createImagePath(name, img);
7438 })
7439 }
7440 createImagePath(name, img, flip = true) {
7441 if (!isImageable(img)) {
7442 throw Error('Shapes createImagePath: img not an imageable ' + img)
7443 }
7444 if (flip) img = flipImage(img);
7445 function imagePath(ctx) {
7446 ctx.drawImage(img, -0.5, -0.5, 1, 1);
7447 }
7448 this.addPath(name, imagePath);
7449 }
7450 imageName(name, pixels, fill, stroke) {
7451 const path = this.getPath(name);
7452 if (!Number.isInteger(pixels))
7453 throw Error(`imageName: pixels is not integer: ${name}`)
7454 if (!path) throw Error(`imageName: ${name} not in Shapes`)
7455 if (path.name === 'imagePath') return `${name}_${pixels}_image`
7456 if (!fill) throw Error(`imageName: No color for shape ${name}`)
7457 if (!this.needsStrokeColor(name)) stroke = null;
7458 return `${name}_${pixels}_${fill}${stroke ? `_${stroke}` : ''}`
7459 }
7460 shapeToImage(name, pixels, fill, stroke) {
7461 pixels = Math.ceil(pixels);
7462 const imgName = this.imageName(name, pixels, fill, stroke);
7463 if (this.cache && this.cache[imgName]) return this.cache[imgName]
7464 const ctx = createCtx(pixels, pixels);
7465 ctx.fillStyle = cssColor$1(fill);
7466 ctx.strokeStyle = cssColor$1(stroke);
7467 ctx.scale(pixels, -pixels);
7468 ctx.translate(0.5, -0.5);
7469 ctx.beginPath();
7470 paths[name](ctx);
7471 ctx.closePath();
7472 ctx.fill();
7473 ctx.canvas.name = imgName;
7474 if (this.cache) this.cache[imgName] = ctx.canvas;
7475 return ctx.canvas
7476 }
7477 imageNameToImage(imageName) {
7478 const [name, pixels, fill, stroke] = imageName.split('_');
7479 return this.shapeToImage(name, pixels, fill, stroke)
7480 }
7481 }
7482 function flipImage(img) {
7483 const { width, height } = img;
7484 const ctx = createCtx(width, height);
7485 ctx.scale(1, -1);
7486 ctx.drawImage(img, 0, -height);
7487 return ctx.canvas
7488 }
7489 function poly(ctx, points) {
7490 points.forEach((pt, i) => {
7491 if (i === 0) ctx.moveTo(pt[0], pt[1]);
7492 else ctx.lineTo(pt[0], pt[1]);
7493 });
7494 }
7495 function circle(ctx, x, y, radius, anticlockwise = false) {
7496 ctx.arc(x, y, radius, 0, 2 * Math.PI, anticlockwise);
7497 }
7498 function square(ctx, x, y, size) {
7499 ctx.fillRect(x - size / 2, y - size / 2, size, size);
7500 }
7501 const paths = {
7502 arrow(ctx) {
7503 poly(ctx, [
7504 [0.5, 0],
7505 [0, 0.5],
7506 [0, 0.2],
7507 [-0.5, 0.2],
7508 [-0.5, -0.2],
7509 [0, -0.2],
7510 [0, -0.5],
7511 ]);
7512 },
7513 bug(ctx) {
7514 ctx.strokeStyle = ctx.fillStyle;
7515 this.bug2(ctx);
7516 },
7517 bug2(ctx) {
7518 ctx.lineWidth = 0.05;
7519 poly(ctx, [
7520 [0.4, 0.225],
7521 [0.2, 0],
7522 [0.4, -0.225],
7523 ]);
7524 ctx.stroke();
7525 ctx.beginPath();
7526 circle(ctx, 0.12, 0, 0.13);
7527 circle(ctx, -0.05, 0, 0.13);
7528 circle(ctx, -0.27, 0, 0.2);
7529 },
7530 circle(ctx) {
7531 circle(ctx, 0, 0, 0.5);
7532 },
7533 dart(ctx) {
7534 poly(ctx, [
7535 [0.5, 0],
7536 [-0.5, 0.4],
7537 [-0.25, 0],
7538 [-0.5, -0.4],
7539 ]);
7540 },
7541 frame(ctx) {
7542 const inset = 0.2;
7543 const r = 0.5 - inset;
7544 poly(ctx, [
7545 [-0.5, -0.5],
7546 [0.5, -0.5],
7547 [0.5, 0.5],
7548 [-0.5, 0.5],
7549 ]);
7550 ctx.closePath();
7551 poly(ctx, [
7552 [-r, -r],
7553 [-r, r],
7554 [r, r],
7555 [r, -r],
7556 ]);
7557 },
7558 frame2(ctx) {
7559 const inset = 0.2;
7560 square(ctx, 0, 0, 1);
7561 ctx.fillStyle = ctx.strokeStyle;
7562 square(ctx, 0, 0, 1 - 2 * inset);
7563 },
7564 person(ctx) {
7565 ctx.strokeStyle = ctx.fillStyle;
7566 this.person2(ctx);
7567 },
7568 person2(ctx) {
7569 poly(ctx, [
7570 [0.15, 0.2],
7571 [0.3, 0],
7572 [0.125, -0.1],
7573 [0.125, 0.05],
7574 [0.1, -0.15],
7575 [0.25, -0.5],
7576 [0.05, -0.5],
7577 [0, -0.25],
7578 [-0.05, -0.5],
7579 [-0.25, -0.5],
7580 [-0.1, -0.15],
7581 [-0.125, 0.05],
7582 [-0.125, -0.1],
7583 [-0.3, 0],
7584 [-0.15, 0.2],
7585 ]);
7586 ctx.closePath();
7587 ctx.fill();
7588 ctx.beginPath();
7589 ctx.fillStyle = ctx.strokeStyle;
7590 circle(ctx, 0, 0.35, 0.15);
7591 },
7592 ring(ctx) {
7593 const [rOuter, rInner] = [0.5, 0.3];
7594 circle(ctx, 0, 0, rOuter);
7595 ctx.lineTo(rInner, 0);
7596 circle(ctx, 0, 0, rInner, true);
7597 },
7598 ring2(ctx) {
7599 const [rOuter, rInner] = [0.5, 0.3];
7600 circle(ctx, 0, 0, rOuter);
7601 ctx.closePath();
7602 ctx.fill();
7603 ctx.beginPath();
7604 ctx.fillStyle = ctx.strokeStyle;
7605 circle(ctx, 0, 0, rInner);
7606 },
7607 square(ctx) {
7608 square(ctx, 0, 0, 1);
7609 },
7610 triangle(ctx) {
7611 poly(ctx, [
7612 [0.5, 0],
7613 [-0.5, -0.4],
7614 [-0.5, 0.4],
7615 ]);
7616 },
7617 };
7618
7619 class SpriteSheet {
7620 constructor(spriteSize = 64, cols = 16, usePowerOf2 = false) {
7621 spriteSize = Math.ceil(spriteSize);
7622 Object.assign(this, { spriteSize, cols, usePowerOf2 });
7623 this.rows = 1;
7624 this.nextCol = 0;
7625 this.nextRow = 0;
7626 this.spritesIndex = {};
7627 this.sprites = [];
7628 this.shapes = new Shapes();
7629 if (usePowerOf2) this.checkPowerOf2();
7630 this.ctx = createCtx(this.width, this.height);
7631 this.texture = null;
7632 }
7633 getSprite(shapeName, color, strokeColor) {
7634 return this.newSprite(shapeName, color, strokeColor)
7635 }
7636 oneOf() {
7637 return oneOf(this.sprites)
7638 }
7639 draw(ctx, sprite, x, y, theta, world, patchSize, noRotate = false) {
7640 const [x0, y0] = world.patchXYtoPixelXY(x, y, patchSize);
7641 const theta0 = -theta;
7642 this.drawCanvas(ctx, sprite, x0, y0, theta0, noRotate);
7643 }
7644 drawCanvas(ctx, sprite, x, y, theta = 0, noRotate = false) {
7645 const { x: x0, y: y0, size } = sprite;
7646 const halfSize = size / 2;
7647 if (noRotate) theta = 0;
7648 if (theta === 0) {
7649 ctx.drawImage(
7650 this.ctx.canvas,
7651 x0,
7652 y0,
7653 size,
7654 size,
7655 x - halfSize,
7656 y - halfSize,
7657 size,
7658 size
7659 );
7660 } else {
7661 ctx.save();
7662 ctx.translate(x, y);
7663 ctx.rotate(theta);
7664 ctx.drawImage(
7665 this.ctx.canvas,
7666 x0,
7667 y0,
7668 size,
7669 size,
7670 -halfSize,
7671 -halfSize,
7672 size,
7673 size
7674 );
7675 ctx.restore();
7676 }
7677 }
7678 newSprite(shapeName, color, strokeColor = null) {
7679 const name = this.shapes.imageName(
7680 shapeName,
7681 this.spriteSize,
7682 color,
7683 strokeColor
7684 );
7685 if (this.spritesIndex[name]) return this.spritesIndex[name]
7686 const img = this.shapes.shapeToImage(
7687 shapeName,
7688 this.spriteSize,
7689 color,
7690 strokeColor
7691 );
7692 this.checkSheetSize();
7693 const [x, y, size] = [this.nextX, this.nextY, this.spriteSize];
7694 this.ctx.drawImage(img, x, y, size, size);
7695 const { nextRow: row, nextCol: col } = this;
7696 const sprite = {
7697 name,
7698 id: this.sprites.length,
7699 x,
7700 y,
7701 row,
7702 col,
7703 size,
7704 sheet: this,
7705 };
7706 sprite.uvs = this.getUVs(sprite);
7707 this.incrementRowCol();
7708 this.spritesIndex[name] = sprite;
7709 this.sprites.push(sprite);
7710 if (this.texture) this.texture.needsUpdate = true;
7711 return sprite
7712 }
7713 get width() {
7714 return this.spriteSize * this.cols
7715 }
7716 get height() {
7717 return this.spriteSize * this.rows
7718 }
7719 get nextX() {
7720 return this.spriteSize * this.nextCol
7721 }
7722 get nextY() {
7723 return this.spriteSize * this.nextRow
7724 }
7725 checkPowerOf2() {
7726 const { width, height } = this;
7727 if (!(isPowerOf2(width) && isPowerOf2(height))) {
7728 throw Error(`SpriteSheet non power of 2: ${width}x${height}`)
7729 }
7730 }
7731 checkSheetSize() {
7732 if (this.nextRow === this.rows) {
7733 this.rows = this.usePowerOf2 ? this.rows * 2 : this.rows + 1;
7734 resizeCtx(this.ctx, this.width, this.height);
7735 forLoop(this.sprites, sprite => {
7736 sprite.uvs = this.getUVs(sprite);
7737 });
7738 }
7739 }
7740 incrementRowCol() {
7741 this.nextCol += 1;
7742 if (this.nextCol < this.cols) return
7743 this.nextCol = 0;
7744 this.nextRow += 1;
7745 }
7746 getUVs(sprite) {
7747 const { row, col } = sprite;
7748 const { rows, cols } = this;
7749 const u0 = col / cols;
7750 const v0 = (rows - (row + 1)) / rows;
7751 const u1 = (col + 1) / cols;
7752 const v1 = (rows - row) / rows;
7753 return [u0, v0, u1, v0, u1, v1, u0, v1]
7754 }
7755 }
7756
7757 function cssColor(color) {
7758 if (color) return color.css || color
7759 return color
7760 }
7761 class TurtlesView {
7762 static defaultOptions() {
7763 return {
7764 useSprites: false,
7765 patchSize: 10,
7766 }
7767 }
7768 constructor(ctx, world, options = {}) {
7769 options = Object.assign(TurtlesView.defaultOptions(), options);
7770 Object.assign(this, { ctx, world }, options);
7771 this.shapes = new Shapes();
7772 this.reset(this.patchSize, this.useSprites);
7773 }
7774 reset(patchSize, useSprites = this.useSprites) {
7775 this.useSprites = useSprites;
7776 this.resetCtx(patchSize);
7777 }
7778 getImageBitmap() {
7779 return createImageBitmap(this.ctx.canvas)
7780 }
7781 resetCtx(patchSize) {
7782 this.patchSize = patchSize;
7783 if (this.useSprites) {
7784 this.world.setCanvasSize(this.ctx.canvas, patchSize);
7785 this.ctx.restore();
7786 } else {
7787 this.world.setEuclideanTransform(this.ctx, patchSize);
7788 }
7789 }
7790 drawTurtles(data, viewFcn) {
7791 if (isOofA(data)) data = toAofO(data);
7792 const constantView = isObject$1(viewFcn);
7793 forLoop(data, (turtle, i) => {
7794 const viewData = constantView ? viewFcn : viewFcn(turtle, i, data);
7795 this.drawTurtle(turtle, viewData);
7796 });
7797 }
7798 drawTurtle(turtle, viewData) {
7799 if (turtle.hidden) return
7800 if (viewData.size === 0) return
7801 if (this.useSprites) {
7802 let { sprite, noRotate } = viewData;
7803 if (!sprite) {
7804 const { shape, color, strokeColor, size } = viewData;
7805 const pixels = size * this.patchSize;
7806 sprite = this.shapes.shapeToImage(
7807 shape,
7808 pixels,
7809 color,
7810 strokeColor
7811 );
7812 }
7813 if (sprite.sheet) {
7814 sprite.sheet.draw(
7815 this.ctx,
7816 sprite,
7817 turtle.x,
7818 turtle.y,
7819 turtle.theta,
7820 this.world,
7821 this.patchSize,
7822 noRotate
7823 );
7824 } else {
7825 this.drawImage(
7826 sprite,
7827 turtle.x,
7828 turtle.y,
7829 noRotate ? 0 : turtle.theta
7830 );
7831 }
7832 } else {
7833 const { shape, color, strokeColor, size, noRotate } = viewData;
7834 this.drawShape(
7835 shape,
7836 turtle.x,
7837 turtle.y,
7838 noRotate ? 0 : turtle.theta,
7839 size,
7840 color,
7841 strokeColor
7842 );
7843 }
7844 }
7845 drawShape(name, x, y, theta = 0, size = 1, fill, stroke) {
7846 const ctx = this.ctx;
7847 ctx.save();
7848 ctx.fillStyle = cssColor(fill);
7849 ctx.strokeStyle = cssColor(stroke);
7850 ctx.translate(x, y);
7851 ctx.scale(size, size);
7852 if (theta !== 0) ctx.rotate(theta);
7853 ctx.beginPath();
7854 this.shapes.paths[name](ctx);
7855 ctx.closePath();
7856 ctx.fill();
7857 ctx.restore();
7858 }
7859 drawImage(img, x, y, theta = 0) {
7860 const halfPix = img.width / 2;
7861 const patchSize = this.patchSize;
7862 const [x0, y0] = this.world.patchXYtoPixelXY(x, y, patchSize);
7863 const ctx = this.ctx;
7864 if (theta === 0) {
7865 ctx.drawImage(img, x0 - halfPix, y0 - halfPix);
7866 } else {
7867 ctx.save();
7868 ctx.translate(x0, y0);
7869 ctx.rotate(-theta);
7870 ctx.drawImage(img, -halfPix, -halfPix);
7871 ctx.restore();
7872 }
7873 }
7874 drawLinks(data, viewFcn) {
7875 if (isOofA(data)) data = toAofO(data);
7876 const uniformLinks = isObject$1(viewFcn);
7877 const ctx = this.ctx;
7878 setIdentity(this.ctx);
7879 if (uniformLinks) {
7880 ctx.strokeStyle = cssColor(viewFcn.color);
7881 ctx.lineWidth = viewFcn.width || 1;
7882 ctx.beginPath();
7883 }
7884 forLoop(data, (link, i) => {
7885 if (uniformLinks) {
7886 this.drawLink(link);
7887 } else {
7888 const { color, width } = viewFcn(link, i, data);
7889 this.drawLink(link, color, width);
7890 }
7891 });
7892 if (uniformLinks) {
7893 ctx.closePath();
7894 ctx.stroke();
7895 }
7896 this.ctx.restore();
7897 }
7898 drawLink(link, color, width = 1) {
7899 this.drawLine(link.x0, link.y0, link.x1, link.y1, color, width);
7900 }
7901 drawLine(x0, y0, x1, y1, stroke, width = 1) {
7902 const ctx = this.ctx
7903 ;[x0, y0] = this.world.patchXYtoPixelXY(x0, y0, this.patchSize)
7904 ;[x1, y1] = this.world.patchXYtoPixelXY(x1, y1, this.patchSize);
7905 if (stroke) {
7906 ctx.strokeStyle = cssColor(stroke);
7907 ctx.lineWidth = width;
7908 ctx.beginPath();
7909 }
7910 ctx.moveTo(x0, y0);
7911 ctx.lineTo(x1, y1);
7912 if (stroke) {
7913 ctx.closePath();
7914 ctx.stroke();
7915 }
7916 }
7917 }
7918
7919 class TwoView {
7920 static defaultOptions() {
7921 return {
7922 div: document.body,
7923 useSprites: false,
7924 patchSize: 10,
7925 }
7926 }
7927 constructor(world, options = {}) {
7928 if (world.world) world = world.world;
7929 options = Object.assign(TwoView.defaultOptions(), options);
7930 if (options.width) {
7931 options.patchSize = options.width / world.width;
7932 delete options.width;
7933 }
7934 let div = options.div;
7935 let can = div;
7936 div = isString(div) ? document.getElementById(div) : div;
7937 if (!isCanvas(can)) {
7938 can = createCanvas(0, 0, false);
7939 div.appendChild(can);
7940 }
7941 this.ctx = can.getContext('2d');
7942 this.world = world;
7943 this.patchesView = new PatchesView(this.world.width, this.world.height);
7944 this.turtlesView = new TurtlesView(this.ctx, this.world, options);
7945 this.ticks = 0;
7946 this.clear();
7947 }
7948 tick() {
7949 this.ticks++;
7950 }
7951 get canvas() {
7952 return this.ctx.canvas
7953 }
7954 reset(patchSize, useSprites = this.useSprites) {
7955 this.turtlesView.reset(patchSize, useSprites);
7956 }
7957 downloadCanvas(name = undefined) {
7958 if (!name)
7959 name = this.model.constructor.name
7960 .toLowerCase()
7961 .replace(/model$/, '');
7962 downloadCanvas(this.canvas, name);
7963 }
7964 get width() {
7965 return this.world.width * this.patchSize
7966 }
7967 set width(val) {
7968 this.reset(val / this.world.width);
7969 }
7970 get patchSize() {
7971 return this.turtlesView.patchSize
7972 }
7973 set patchSize(val) {
7974 this.reset(val);
7975 }
7976 get useSprites() {
7977 return this.turtlesView.useSprites
7978 }
7979 set useSprites(val) {
7980 this.reset(this.patchSize, val);
7981 }
7982 clear(cssColor) {
7983 clearCtx(this.ctx, cssColor);
7984 }
7985 createPatchPixels(pixelFcn) {
7986 this.patchesView.createPixels(pixelFcn);
7987 }
7988 setPatchPixel(index, pixel) {
7989 this.patchesView.setPixel(index, pixel);
7990 }
7991 setPatchesPixels(data, pixelFcn) {
7992 this.patchesView.setPixels(data, pixelFcn);
7993 }
7994 setPatchesSmoothing(smoothing) {
7995 this.patchesView.setPatchesSmoothing(smoothing);
7996 }
7997 drawPatchesImage(img) {
7998 fillCtxWithImage(this.ctx, img);
7999 }
8000 drawPatches(data, pixelFcn) {
8001 if (data != null) {
8002 this.patchesView.setPixels(data, pixelFcn);
8003 }
8004 this.patchesView.draw(this.ctx);
8005 }
8006 drawTurtles(data, viewFcn) {
8007 this.turtlesView.drawTurtles(data, viewFcn);
8008 }
8009 drawLinks(data, viewFcn) {
8010 this.turtlesView.drawLinks(data, viewFcn);
8011 }
8012 setTextProperties(font, textAlign = 'center', textBaseline = 'middle') {
8013 if (typeof font === 'number')
8014 font = `${this.patchSize * font}px sans-serif`;
8015 setTextProperties(this.ctx, font, textAlign, textBaseline);
8016 }
8017 drawText(string, x, y, color = 'black') {
8018 [x, y] = this.world.patchXYtoPixelXY(x, y, this.patchSize);
8019 string = '' + string;
8020 drawText(this.ctx, string, x, y, color);
8021 }
8022 }
8023
8024 class TwoDraw extends TwoView {
8025 static defaultOptions(model) {
8026 return {
8027 patchesColor: 'random',
8028 initPatches: null,
8029 turtles: model.turtles,
8030 turtlesColor: 'random',
8031 turtlesStrokeColor: 'random',
8032 turtlesShape: 'dart',
8033 turtlesSize: 1,
8034 turtlesRotate: true,
8035 links: model.links,
8036 linksColor: 'random',
8037 linksWidth: 1,
8038 textProperty: null,
8039 textSize: 0.5,
8040 textColor: 'black',
8041 patchesMap: 'DarkGray',
8042 turtlesMap: 'Basic16',
8043 }
8044 }
8045 static separateDrawOptions(viewOptions, drawOptions) {
8046 if (viewOptions.drawOptions) {
8047 Object.assign(drawOptions, viewOptions.drawOptions);
8048 delete viewOptions.drawOptions;
8049 }
8050 return drawOptions
8051 }
8052 constructor(model, viewOptions = {}, drawOptions = {}) {
8053 drawOptions = TwoDraw.separateDrawOptions(viewOptions, drawOptions);
8054 drawOptions = Object.assign(
8055 TwoDraw.defaultOptions(model),
8056 drawOptions
8057 );
8058 super(model, viewOptions);
8059 this.model = model;
8060 this.checkOptions(drawOptions);
8061 this.drawOptions = drawOptions;
8062 }
8063 checkOptions(drawOptions) {
8064 const keys = Object.keys(drawOptions);
8065 const defaults = TwoDraw.defaultOptions(this.model);
8066 keys.forEach(k => {
8067 if (defaults[k] === undefined) {
8068 console.log(
8069 'Legal TwoDraw parameters',
8070 Object.keys(TwoDraw.defaultOptions(this.model))
8071 );
8072 throw Error('Unknown TwoDraw parameter: ' + k)
8073 }
8074 });
8075 if (typeof drawOptions.patchesMap === 'string') {
8076 drawOptions.patchesMap = ColorMap[drawOptions.patchesMap];
8077 if (!drawOptions.patchesMap)
8078 Error('Unknown patchMap: ' + drawOptions.patchesMap);
8079 }
8080 if (typeof drawOptions.turtlesMap === 'string') {
8081 drawOptions.turtlesMap = ColorMap[drawOptions.turtlesMap];
8082 if (!drawOptions.turtlesMap)
8083 Error('Unknown turtlesMap: ' + drawOptions.turtlesMap);
8084 }
8085 }
8086 resetOptions(drawOptions = this.drawOptions) {
8087 this.checkOptions(drawOptions);
8088 this.drawOptions = drawOptions;
8089 this.ticks = 0;
8090 return drawOptions
8091 }
8092 draw() {
8093 const model = this.model;
8094 const view = this;
8095 let {
8096 patchesColor,
8097 initPatches,
8098 turtles,
8099 turtlesColor,
8100 turtlesStrokeColor,
8101 turtlesShape,
8102 turtlesSize,
8103 turtlesRotate,
8104 links,
8105 linksColor,
8106 linksWidth,
8107 textProperty,
8108 textSize,
8109 textColor,
8110 patchesMap,
8111 turtlesMap,
8112 } = this.drawOptions;
8113 if (view.ticks === 0) {
8114 if (textProperty) view.setTextProperties(textSize);
8115 if (initPatches) {
8116 const colors = initPatches(model, view);
8117 view.createPatchPixels(i => colors[i]);
8118 } else if (patchesColor === 'random') {
8119 view.createPatchPixels(i => patchesMap.randomColor());
8120 }
8121 }
8122 if (patchesColor === 'random' || initPatches) {
8123 view.clear();
8124 view.drawPatches();
8125 } else if (typeof patchesColor === 'function') {
8126 view.drawPatches(model.patches, p => patchesColor(p));
8127 } else if (isImageable(patchesColor)) {
8128 view.drawPatchesImage(patchesColor);
8129 } else {
8130 view.clear(patchesColor);
8131 }
8132 const checkColor = (agent, color) =>
8133 color === 'random' ? turtlesMap.atIndex(agent.id).css : color;
8134 view.drawLinks(links, l => ({
8135 color:
8136 linksColor === 'random'
8137 ? turtlesMap.atIndex(l.id)
8138 : typeof linksColor === 'function'
8139 ? checkColor(l, linksColor(l))
8140 : linksColor,
8141 width: linksWidth,
8142 }));
8143 view.drawTurtles(turtles, t => ({
8144 shape:
8145 typeof turtlesShape === 'function'
8146 ? turtlesShape(t)
8147 : turtlesShape,
8148 color:
8149 turtlesColor === 'random'
8150 ? turtlesMap.atIndex(t.id).css
8151 : typeof turtlesColor === 'function'
8152 ? checkColor(t, turtlesColor(t))
8153 : turtlesColor,
8154 strokeColor:
8155 turtlesStrokeColor === 'random'
8156 ? turtlesMap.atIndex(t.id + 4).css
8157 : typeof turtlesColor === 'function'
8158 ? checkColor(t, turtlesColor(t))
8159 : turtlesColor,
8160 size:
8161 typeof turtlesSize === 'function'
8162 ? turtlesSize(t)
8163 : turtlesSize,
8164 noRotate:
8165 typeof turtlesRotate === 'function'
8166 ? !turtlesRotate(t)
8167 : !turtlesRotate,
8168 }));
8169 if (textProperty) {
8170 turtles.ask(t => {
8171 if (t[textProperty] != null)
8172 view.drawText(t[textProperty], t.x, t.y, textColor);
8173 });
8174 }
8175 view.tick();
8176 }
8177 }
8178
8179 if ( Number.EPSILON === undefined ) {
8180 Number.EPSILON = Math.pow( 2, - 52 );
8181 }
8182 if ( Number.isInteger === undefined ) {
8183 Number.isInteger = function ( value ) {
8184 return typeof value === 'number' && isFinite( value ) && Math.floor( value ) === value;
8185 };
8186 }
8187 if ( Math.sign === undefined ) {
8188 Math.sign = function ( x ) {
8189 return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;
8190 };
8191 }
8192 if ( 'name' in Function.prototype === false ) {
8193 Object.defineProperty( Function.prototype, 'name', {
8194 get: function () {
8195 return this.toString().match( /^\s*function\s*([^\(\s]*)/ )[ 1 ];
8196 }
8197 } );
8198 }
8199 if ( Object.assign === undefined ) {
8200 Object.assign = function ( target ) {
8201 if ( target === undefined || target === null ) {
8202 throw new TypeError( 'Cannot convert undefined or null to object' );
8203 }
8204 const output = Object( target );
8205 for ( let index = 1; index < arguments.length; index ++ ) {
8206 const source = arguments[ index ];
8207 if ( source !== undefined && source !== null ) {
8208 for ( const nextKey in source ) {
8209 if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {
8210 output[ nextKey ] = source[ nextKey ];
8211 }
8212 }
8213 }
8214 }
8215 return output;
8216 };
8217 }
8218 const REVISION = '120';
8219 const MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };
8220 const TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };
8221 const CullFaceNone = 0;
8222 const CullFaceBack = 1;
8223 const CullFaceFront = 2;
8224 const CullFaceFrontBack = 3;
8225 const BasicShadowMap = 0;
8226 const PCFShadowMap = 1;
8227 const PCFSoftShadowMap = 2;
8228 const VSMShadowMap = 3;
8229 const FrontSide = 0;
8230 const BackSide = 1;
8231 const DoubleSide = 2;
8232 const FlatShading = 1;
8233 const SmoothShading = 2;
8234 const NoBlending = 0;
8235 const NormalBlending = 1;
8236 const AdditiveBlending = 2;
8237 const SubtractiveBlending = 3;
8238 const MultiplyBlending = 4;
8239 const CustomBlending = 5;
8240 const AddEquation = 100;
8241 const SubtractEquation = 101;
8242 const ReverseSubtractEquation = 102;
8243 const MinEquation = 103;
8244 const MaxEquation = 104;
8245 const ZeroFactor = 200;
8246 const OneFactor = 201;
8247 const SrcColorFactor = 202;
8248 const OneMinusSrcColorFactor = 203;
8249 const SrcAlphaFactor = 204;
8250 const OneMinusSrcAlphaFactor = 205;
8251 const DstAlphaFactor = 206;
8252 const OneMinusDstAlphaFactor = 207;
8253 const DstColorFactor = 208;
8254 const OneMinusDstColorFactor = 209;
8255 const SrcAlphaSaturateFactor = 210;
8256 const NeverDepth = 0;
8257 const AlwaysDepth = 1;
8258 const LessDepth = 2;
8259 const LessEqualDepth = 3;
8260 const EqualDepth = 4;
8261 const GreaterEqualDepth = 5;
8262 const GreaterDepth = 6;
8263 const NotEqualDepth = 7;
8264 const MultiplyOperation = 0;
8265 const MixOperation = 1;
8266 const AddOperation = 2;
8267 const NoToneMapping = 0;
8268 const LinearToneMapping = 1;
8269 const ReinhardToneMapping = 2;
8270 const CineonToneMapping = 3;
8271 const ACESFilmicToneMapping = 4;
8272 const CustomToneMapping = 5;
8273 const UVMapping = 300;
8274 const CubeReflectionMapping = 301;
8275 const CubeRefractionMapping = 302;
8276 const EquirectangularReflectionMapping = 303;
8277 const EquirectangularRefractionMapping = 304;
8278 const CubeUVReflectionMapping = 306;
8279 const CubeUVRefractionMapping = 307;
8280 const RepeatWrapping = 1000;
8281 const ClampToEdgeWrapping = 1001;
8282 const MirroredRepeatWrapping = 1002;
8283 const NearestFilter = 1003;
8284 const NearestMipmapNearestFilter = 1004;
8285 const NearestMipMapNearestFilter = 1004;
8286 const NearestMipmapLinearFilter = 1005;
8287 const NearestMipMapLinearFilter = 1005;
8288 const LinearFilter = 1006;
8289 const LinearMipmapNearestFilter = 1007;
8290 const LinearMipMapNearestFilter = 1007;
8291 const LinearMipmapLinearFilter = 1008;
8292 const LinearMipMapLinearFilter = 1008;
8293 const UnsignedByteType = 1009;
8294 const ByteType = 1010;
8295 const ShortType = 1011;
8296 const UnsignedShortType = 1012;
8297 const IntType = 1013;
8298 const UnsignedIntType = 1014;
8299 const FloatType = 1015;
8300 const HalfFloatType = 1016;
8301 const UnsignedShort4444Type = 1017;
8302 const UnsignedShort5551Type = 1018;
8303 const UnsignedShort565Type = 1019;
8304 const UnsignedInt248Type = 1020;
8305 const AlphaFormat = 1021;
8306 const RGBFormat = 1022;
8307 const RGBAFormat = 1023;
8308 const LuminanceFormat = 1024;
8309 const LuminanceAlphaFormat = 1025;
8310 const RGBEFormat = RGBAFormat;
8311 const DepthFormat = 1026;
8312 const DepthStencilFormat = 1027;
8313 const RedFormat = 1028;
8314 const RedIntegerFormat = 1029;
8315 const RGFormat = 1030;
8316 const RGIntegerFormat = 1031;
8317 const RGBIntegerFormat = 1032;
8318 const RGBAIntegerFormat = 1033;
8319 const RGB_S3TC_DXT1_Format = 33776;
8320 const RGBA_S3TC_DXT1_Format = 33777;
8321 const RGBA_S3TC_DXT3_Format = 33778;
8322 const RGBA_S3TC_DXT5_Format = 33779;
8323 const RGB_PVRTC_4BPPV1_Format = 35840;
8324 const RGB_PVRTC_2BPPV1_Format = 35841;
8325 const RGBA_PVRTC_4BPPV1_Format = 35842;
8326 const RGBA_PVRTC_2BPPV1_Format = 35843;
8327 const RGB_ETC1_Format = 36196;
8328 const RGB_ETC2_Format = 37492;
8329 const RGBA_ETC2_EAC_Format = 37496;
8330 const RGBA_ASTC_4x4_Format = 37808;
8331 const RGBA_ASTC_5x4_Format = 37809;
8332 const RGBA_ASTC_5x5_Format = 37810;
8333 const RGBA_ASTC_6x5_Format = 37811;
8334 const RGBA_ASTC_6x6_Format = 37812;
8335 const RGBA_ASTC_8x5_Format = 37813;
8336 const RGBA_ASTC_8x6_Format = 37814;
8337 const RGBA_ASTC_8x8_Format = 37815;
8338 const RGBA_ASTC_10x5_Format = 37816;
8339 const RGBA_ASTC_10x6_Format = 37817;
8340 const RGBA_ASTC_10x8_Format = 37818;
8341 const RGBA_ASTC_10x10_Format = 37819;
8342 const RGBA_ASTC_12x10_Format = 37820;
8343 const RGBA_ASTC_12x12_Format = 37821;
8344 const RGBA_BPTC_Format = 36492;
8345 const SRGB8_ALPHA8_ASTC_4x4_Format = 37840;
8346 const SRGB8_ALPHA8_ASTC_5x4_Format = 37841;
8347 const SRGB8_ALPHA8_ASTC_5x5_Format = 37842;
8348 const SRGB8_ALPHA8_ASTC_6x5_Format = 37843;
8349 const SRGB8_ALPHA8_ASTC_6x6_Format = 37844;
8350 const SRGB8_ALPHA8_ASTC_8x5_Format = 37845;
8351 const SRGB8_ALPHA8_ASTC_8x6_Format = 37846;
8352 const SRGB8_ALPHA8_ASTC_8x8_Format = 37847;
8353 const SRGB8_ALPHA8_ASTC_10x5_Format = 37848;
8354 const SRGB8_ALPHA8_ASTC_10x6_Format = 37849;
8355 const SRGB8_ALPHA8_ASTC_10x8_Format = 37850;
8356 const SRGB8_ALPHA8_ASTC_10x10_Format = 37851;
8357 const SRGB8_ALPHA8_ASTC_12x10_Format = 37852;
8358 const SRGB8_ALPHA8_ASTC_12x12_Format = 37853;
8359 const LoopOnce = 2200;
8360 const LoopRepeat = 2201;
8361 const LoopPingPong = 2202;
8362 const InterpolateDiscrete = 2300;
8363 const InterpolateLinear = 2301;
8364 const InterpolateSmooth = 2302;
8365 const ZeroCurvatureEnding = 2400;
8366 const ZeroSlopeEnding = 2401;
8367 const WrapAroundEnding = 2402;
8368 const NormalAnimationBlendMode = 2500;
8369 const AdditiveAnimationBlendMode = 2501;
8370 const TrianglesDrawMode = 0;
8371 const TriangleStripDrawMode = 1;
8372 const TriangleFanDrawMode = 2;
8373 const LinearEncoding = 3000;
8374 const sRGBEncoding = 3001;
8375 const GammaEncoding = 3007;
8376 const RGBEEncoding = 3002;
8377 const LogLuvEncoding = 3003;
8378 const RGBM7Encoding = 3004;
8379 const RGBM16Encoding = 3005;
8380 const RGBDEncoding = 3006;
8381 const BasicDepthPacking = 3200;
8382 const RGBADepthPacking = 3201;
8383 const TangentSpaceNormalMap = 0;
8384 const ObjectSpaceNormalMap = 1;
8385 const ZeroStencilOp = 0;
8386 const KeepStencilOp = 7680;
8387 const ReplaceStencilOp = 7681;
8388 const IncrementStencilOp = 7682;
8389 const DecrementStencilOp = 7683;
8390 const IncrementWrapStencilOp = 34055;
8391 const DecrementWrapStencilOp = 34056;
8392 const InvertStencilOp = 5386;
8393 const NeverStencilFunc = 512;
8394 const LessStencilFunc = 513;
8395 const EqualStencilFunc = 514;
8396 const LessEqualStencilFunc = 515;
8397 const GreaterStencilFunc = 516;
8398 const NotEqualStencilFunc = 517;
8399 const GreaterEqualStencilFunc = 518;
8400 const AlwaysStencilFunc = 519;
8401 const StaticDrawUsage = 35044;
8402 const DynamicDrawUsage = 35048;
8403 const StreamDrawUsage = 35040;
8404 const StaticReadUsage = 35045;
8405 const DynamicReadUsage = 35049;
8406 const StreamReadUsage = 35041;
8407 const StaticCopyUsage = 35046;
8408 const DynamicCopyUsage = 35050;
8409 const StreamCopyUsage = 35042;
8410 const GLSL1 = "100";
8411 const GLSL3 = "300 es";
8412 function EventDispatcher() {}
8413 Object.assign( EventDispatcher.prototype, {
8414 addEventListener: function ( type, listener ) {
8415 if ( this._listeners === undefined ) this._listeners = {};
8416 const listeners = this._listeners;
8417 if ( listeners[ type ] === undefined ) {
8418 listeners[ type ] = [];
8419 }
8420 if ( listeners[ type ].indexOf( listener ) === - 1 ) {
8421 listeners[ type ].push( listener );
8422 }
8423 },
8424 hasEventListener: function ( type, listener ) {
8425 if ( this._listeners === undefined ) return false;
8426 const listeners = this._listeners;
8427 return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;
8428 },
8429 removeEventListener: function ( type, listener ) {
8430 if ( this._listeners === undefined ) return;
8431 const listeners = this._listeners;
8432 const listenerArray = listeners[ type ];
8433 if ( listenerArray !== undefined ) {
8434 const index = listenerArray.indexOf( listener );
8435 if ( index !== - 1 ) {
8436 listenerArray.splice( index, 1 );
8437 }
8438 }
8439 },
8440 dispatchEvent: function ( event ) {
8441 if ( this._listeners === undefined ) return;
8442 const listeners = this._listeners;
8443 const listenerArray = listeners[ event.type ];
8444 if ( listenerArray !== undefined ) {
8445 event.target = this;
8446 const array = listenerArray.slice( 0 );
8447 for ( let i = 0, l = array.length; i < l; i ++ ) {
8448 array[ i ].call( this, event );
8449 }
8450 }
8451 }
8452 } );
8453 const _lut = [];
8454 for ( let i = 0; i < 256; i ++ ) {
8455 _lut[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 );
8456 }
8457 let _seed = 1234567;
8458 const MathUtils = {
8459 DEG2RAD: Math.PI / 180,
8460 RAD2DEG: 180 / Math.PI,
8461 generateUUID: function () {
8462 const d0 = Math.random() * 0xffffffff | 0;
8463 const d1 = Math.random() * 0xffffffff | 0;
8464 const d2 = Math.random() * 0xffffffff | 0;
8465 const d3 = Math.random() * 0xffffffff | 0;
8466 const uuid = _lut[ d0 & 0xff ] + _lut[ d0 >> 8 & 0xff ] + _lut[ d0 >> 16 & 0xff ] + _lut[ d0 >> 24 & 0xff ] + '-' +
8467 _lut[ d1 & 0xff ] + _lut[ d1 >> 8 & 0xff ] + '-' + _lut[ d1 >> 16 & 0x0f | 0x40 ] + _lut[ d1 >> 24 & 0xff ] + '-' +
8468 _lut[ d2 & 0x3f | 0x80 ] + _lut[ d2 >> 8 & 0xff ] + '-' + _lut[ d2 >> 16 & 0xff ] + _lut[ d2 >> 24 & 0xff ] +
8469 _lut[ d3 & 0xff ] + _lut[ d3 >> 8 & 0xff ] + _lut[ d3 >> 16 & 0xff ] + _lut[ d3 >> 24 & 0xff ];
8470 return uuid.toUpperCase();
8471 },
8472 clamp: function ( value, min, max ) {
8473 return Math.max( min, Math.min( max, value ) );
8474 },
8475 euclideanModulo: function ( n, m ) {
8476 return ( ( n % m ) + m ) % m;
8477 },
8478 mapLinear: function ( x, a1, a2, b1, b2 ) {
8479 return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
8480 },
8481 lerp: function ( x, y, t ) {
8482 return ( 1 - t ) * x + t * y;
8483 },
8484 smoothstep: function ( x, min, max ) {
8485 if ( x <= min ) return 0;
8486 if ( x >= max ) return 1;
8487 x = ( x - min ) / ( max - min );
8488 return x * x * ( 3 - 2 * x );
8489 },
8490 smootherstep: function ( x, min, max ) {
8491 if ( x <= min ) return 0;
8492 if ( x >= max ) return 1;
8493 x = ( x - min ) / ( max - min );
8494 return x * x * x * ( x * ( x * 6 - 15 ) + 10 );
8495 },
8496 randInt: function ( low, high ) {
8497 return low + Math.floor( Math.random() * ( high - low + 1 ) );
8498 },
8499 randFloat: function ( low, high ) {
8500 return low + Math.random() * ( high - low );
8501 },
8502 randFloatSpread: function ( range ) {
8503 return range * ( 0.5 - Math.random() );
8504 },
8505 seededRandom: function ( s ) {
8506 if ( s !== undefined ) _seed = s % 2147483647;
8507 _seed = _seed * 16807 % 2147483647;
8508 return ( _seed - 1 ) / 2147483646;
8509 },
8510 degToRad: function ( degrees ) {
8511 return degrees * MathUtils.DEG2RAD;
8512 },
8513 radToDeg: function ( radians ) {
8514 return radians * MathUtils.RAD2DEG;
8515 },
8516 isPowerOfTwo: function ( value ) {
8517 return ( value & ( value - 1 ) ) === 0 && value !== 0;
8518 },
8519 ceilPowerOfTwo: function ( value ) {
8520 return Math.pow( 2, Math.ceil( Math.log( value ) / Math.LN2 ) );
8521 },
8522 floorPowerOfTwo: function ( value ) {
8523 return Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) );
8524 },
8525 setQuaternionFromProperEuler: function ( q, a, b, c, order ) {
8526 const cos = Math.cos;
8527 const sin = Math.sin;
8528 const c2 = cos( b / 2 );
8529 const s2 = sin( b / 2 );
8530 const c13 = cos( ( a + c ) / 2 );
8531 const s13 = sin( ( a + c ) / 2 );
8532 const c1_3 = cos( ( a - c ) / 2 );
8533 const s1_3 = sin( ( a - c ) / 2 );
8534 const c3_1 = cos( ( c - a ) / 2 );
8535 const s3_1 = sin( ( c - a ) / 2 );
8536 switch ( order ) {
8537 case 'XYX':
8538 q.set( c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13 );
8539 break;
8540 case 'YZY':
8541 q.set( s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13 );
8542 break;
8543 case 'ZXZ':
8544 q.set( s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13 );
8545 break;
8546 case 'XZX':
8547 q.set( c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13 );
8548 break;
8549 case 'YXY':
8550 q.set( s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13 );
8551 break;
8552 case 'ZYZ':
8553 q.set( s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13 );
8554 break;
8555 default:
8556 console.warn( 'THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order );
8557 }
8558 }
8559 };
8560 class Vector2 {
8561 constructor( x = 0, y = 0 ) {
8562 Object.defineProperty( this, 'isVector2', { value: true } );
8563 this.x = x;
8564 this.y = y;
8565 }
8566 get width() {
8567 return this.x;
8568 }
8569 set width( value ) {
8570 this.x = value;
8571 }
8572 get height() {
8573 return this.y;
8574 }
8575 set height( value ) {
8576 this.y = value;
8577 }
8578 set( x, y ) {
8579 this.x = x;
8580 this.y = y;
8581 return this;
8582 }
8583 setScalar( scalar ) {
8584 this.x = scalar;
8585 this.y = scalar;
8586 return this;
8587 }
8588 setX( x ) {
8589 this.x = x;
8590 return this;
8591 }
8592 setY( y ) {
8593 this.y = y;
8594 return this;
8595 }
8596 setComponent( index, value ) {
8597 switch ( index ) {
8598 case 0: this.x = value; break;
8599 case 1: this.y = value; break;
8600 default: throw new Error( 'index is out of range: ' + index );
8601 }
8602 return this;
8603 }
8604 getComponent( index ) {
8605 switch ( index ) {
8606 case 0: return this.x;
8607 case 1: return this.y;
8608 default: throw new Error( 'index is out of range: ' + index );
8609 }
8610 }
8611 clone() {
8612 return new this.constructor( this.x, this.y );
8613 }
8614 copy( v ) {
8615 this.x = v.x;
8616 this.y = v.y;
8617 return this;
8618 }
8619 add( v, w ) {
8620 if ( w !== undefined ) {
8621 console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
8622 return this.addVectors( v, w );
8623 }
8624 this.x += v.x;
8625 this.y += v.y;
8626 return this;
8627 }
8628 addScalar( s ) {
8629 this.x += s;
8630 this.y += s;
8631 return this;
8632 }
8633 addVectors( a, b ) {
8634 this.x = a.x + b.x;
8635 this.y = a.y + b.y;
8636 return this;
8637 }
8638 addScaledVector( v, s ) {
8639 this.x += v.x * s;
8640 this.y += v.y * s;
8641 return this;
8642 }
8643 sub( v, w ) {
8644 if ( w !== undefined ) {
8645 console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
8646 return this.subVectors( v, w );
8647 }
8648 this.x -= v.x;
8649 this.y -= v.y;
8650 return this;
8651 }
8652 subScalar( s ) {
8653 this.x -= s;
8654 this.y -= s;
8655 return this;
8656 }
8657 subVectors( a, b ) {
8658 this.x = a.x - b.x;
8659 this.y = a.y - b.y;
8660 return this;
8661 }
8662 multiply( v ) {
8663 this.x *= v.x;
8664 this.y *= v.y;
8665 return this;
8666 }
8667 multiplyScalar( scalar ) {
8668 this.x *= scalar;
8669 this.y *= scalar;
8670 return this;
8671 }
8672 divide( v ) {
8673 this.x /= v.x;
8674 this.y /= v.y;
8675 return this;
8676 }
8677 divideScalar( scalar ) {
8678 return this.multiplyScalar( 1 / scalar );
8679 }
8680 applyMatrix3( m ) {
8681 const x = this.x, y = this.y;
8682 const e = m.elements;
8683 this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ];
8684 this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ];
8685 return this;
8686 }
8687 min( v ) {
8688 this.x = Math.min( this.x, v.x );
8689 this.y = Math.min( this.y, v.y );
8690 return this;
8691 }
8692 max( v ) {
8693 this.x = Math.max( this.x, v.x );
8694 this.y = Math.max( this.y, v.y );
8695 return this;
8696 }
8697 clamp( min, max ) {
8698 this.x = Math.max( min.x, Math.min( max.x, this.x ) );
8699 this.y = Math.max( min.y, Math.min( max.y, this.y ) );
8700 return this;
8701 }
8702 clampScalar( minVal, maxVal ) {
8703 this.x = Math.max( minVal, Math.min( maxVal, this.x ) );
8704 this.y = Math.max( minVal, Math.min( maxVal, this.y ) );
8705 return this;
8706 }
8707 clampLength( min, max ) {
8708 const length = this.length();
8709 return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
8710 }
8711 floor() {
8712 this.x = Math.floor( this.x );
8713 this.y = Math.floor( this.y );
8714 return this;
8715 }
8716 ceil() {
8717 this.x = Math.ceil( this.x );
8718 this.y = Math.ceil( this.y );
8719 return this;
8720 }
8721 round() {
8722 this.x = Math.round( this.x );
8723 this.y = Math.round( this.y );
8724 return this;
8725 }
8726 roundToZero() {
8727 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
8728 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
8729 return this;
8730 }
8731 negate() {
8732 this.x = - this.x;
8733 this.y = - this.y;
8734 return this;
8735 }
8736 dot( v ) {
8737 return this.x * v.x + this.y * v.y;
8738 }
8739 cross( v ) {
8740 return this.x * v.y - this.y * v.x;
8741 }
8742 lengthSq() {
8743 return this.x * this.x + this.y * this.y;
8744 }
8745 length() {
8746 return Math.sqrt( this.x * this.x + this.y * this.y );
8747 }
8748 manhattanLength() {
8749 return Math.abs( this.x ) + Math.abs( this.y );
8750 }
8751 normalize() {
8752 return this.divideScalar( this.length() || 1 );
8753 }
8754 angle() {
8755 const angle = Math.atan2( - this.y, - this.x ) + Math.PI;
8756 return angle;
8757 }
8758 distanceTo( v ) {
8759 return Math.sqrt( this.distanceToSquared( v ) );
8760 }
8761 distanceToSquared( v ) {
8762 const dx = this.x - v.x, dy = this.y - v.y;
8763 return dx * dx + dy * dy;
8764 }
8765 manhattanDistanceTo( v ) {
8766 return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );
8767 }
8768 setLength( length ) {
8769 return this.normalize().multiplyScalar( length );
8770 }
8771 lerp( v, alpha ) {
8772 this.x += ( v.x - this.x ) * alpha;
8773 this.y += ( v.y - this.y ) * alpha;
8774 return this;
8775 }
8776 lerpVectors( v1, v2, alpha ) {
8777 this.x = v1.x + ( v2.x - v1.x ) * alpha;
8778 this.y = v1.y + ( v2.y - v1.y ) * alpha;
8779 return this;
8780 }
8781 equals( v ) {
8782 return ( ( v.x === this.x ) && ( v.y === this.y ) );
8783 }
8784 fromArray( array, offset ) {
8785 if ( offset === undefined ) offset = 0;
8786 this.x = array[ offset ];
8787 this.y = array[ offset + 1 ];
8788 return this;
8789 }
8790 toArray( array, offset ) {
8791 if ( array === undefined ) array = [];
8792 if ( offset === undefined ) offset = 0;
8793 array[ offset ] = this.x;
8794 array[ offset + 1 ] = this.y;
8795 return array;
8796 }
8797 fromBufferAttribute( attribute, index, offset ) {
8798 if ( offset !== undefined ) {
8799 console.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );
8800 }
8801 this.x = attribute.getX( index );
8802 this.y = attribute.getY( index );
8803 return this;
8804 }
8805 rotateAround( center, angle ) {
8806 const c = Math.cos( angle ), s = Math.sin( angle );
8807 const x = this.x - center.x;
8808 const y = this.y - center.y;
8809 this.x = x * c - y * s + center.x;
8810 this.y = x * s + y * c + center.y;
8811 return this;
8812 }
8813 random() {
8814 this.x = Math.random();
8815 this.y = Math.random();
8816 return this;
8817 }
8818 }
8819 class Matrix3 {
8820 constructor() {
8821 Object.defineProperty( this, 'isMatrix3', { value: true } );
8822 this.elements = [
8823 1, 0, 0,
8824 0, 1, 0,
8825 0, 0, 1
8826 ];
8827 if ( arguments.length > 0 ) {
8828 console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );
8829 }
8830 }
8831 set( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
8832 const te = this.elements;
8833 te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;
8834 te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;
8835 te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;
8836 return this;
8837 }
8838 identity() {
8839 this.set(
8840 1, 0, 0,
8841 0, 1, 0,
8842 0, 0, 1
8843 );
8844 return this;
8845 }
8846 clone() {
8847 return new this.constructor().fromArray( this.elements );
8848 }
8849 copy( m ) {
8850 const te = this.elements;
8851 const me = m.elements;
8852 te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ];
8853 te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ];
8854 te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ];
8855 return this;
8856 }
8857 extractBasis( xAxis, yAxis, zAxis ) {
8858 xAxis.setFromMatrix3Column( this, 0 );
8859 yAxis.setFromMatrix3Column( this, 1 );
8860 zAxis.setFromMatrix3Column( this, 2 );
8861 return this;
8862 }
8863 setFromMatrix4( m ) {
8864 const me = m.elements;
8865 this.set(
8866 me[ 0 ], me[ 4 ], me[ 8 ],
8867 me[ 1 ], me[ 5 ], me[ 9 ],
8868 me[ 2 ], me[ 6 ], me[ 10 ]
8869 );
8870 return this;
8871 }
8872 multiply( m ) {
8873 return this.multiplyMatrices( this, m );
8874 }
8875 premultiply( m ) {
8876 return this.multiplyMatrices( m, this );
8877 }
8878 multiplyMatrices( a, b ) {
8879 const ae = a.elements;
8880 const be = b.elements;
8881 const te = this.elements;
8882 const a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ];
8883 const a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ];
8884 const a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ];
8885 const b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ];
8886 const b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ];
8887 const b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ];
8888 te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31;
8889 te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32;
8890 te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33;
8891 te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31;
8892 te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32;
8893 te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33;
8894 te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31;
8895 te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32;
8896 te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33;
8897 return this;
8898 }
8899 multiplyScalar( s ) {
8900 const te = this.elements;
8901 te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;
8902 te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;
8903 te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;
8904 return this;
8905 }
8906 determinant() {
8907 const te = this.elements;
8908 const a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],
8909 d = te[ 3 ], e = te[ 4 ], f = te[ 5 ],
8910 g = te[ 6 ], h = te[ 7 ], i = te[ 8 ];
8911 return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;
8912 }
8913 getInverse( matrix, throwOnDegenerate ) {
8914 if ( throwOnDegenerate !== undefined ) {
8915 console.warn( "THREE.Matrix3: .getInverse() can no longer be configured to throw on degenerate." );
8916 }
8917 const me = matrix.elements,
8918 te = this.elements,
8919 n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],
8920 n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],
8921 n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],
8922 t11 = n33 * n22 - n32 * n23,
8923 t12 = n32 * n13 - n33 * n12,
8924 t13 = n23 * n12 - n22 * n13,
8925 det = n11 * t11 + n21 * t12 + n31 * t13;
8926 if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0 );
8927 const detInv = 1 / det;
8928 te[ 0 ] = t11 * detInv;
8929 te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;
8930 te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;
8931 te[ 3 ] = t12 * detInv;
8932 te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;
8933 te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;
8934 te[ 6 ] = t13 * detInv;
8935 te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;
8936 te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;
8937 return this;
8938 }
8939 transpose() {
8940 let tmp;
8941 const m = this.elements;
8942 tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;
8943 tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;
8944 tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;
8945 return this;
8946 }
8947 getNormalMatrix( matrix4 ) {
8948 return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();
8949 }
8950 transposeIntoArray( r ) {
8951 const m = this.elements;
8952 r[ 0 ] = m[ 0 ];
8953 r[ 1 ] = m[ 3 ];
8954 r[ 2 ] = m[ 6 ];
8955 r[ 3 ] = m[ 1 ];
8956 r[ 4 ] = m[ 4 ];
8957 r[ 5 ] = m[ 7 ];
8958 r[ 6 ] = m[ 2 ];
8959 r[ 7 ] = m[ 5 ];
8960 r[ 8 ] = m[ 8 ];
8961 return this;
8962 }
8963 setUvTransform( tx, ty, sx, sy, rotation, cx, cy ) {
8964 const c = Math.cos( rotation );
8965 const s = Math.sin( rotation );
8966 this.set(
8967 sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx,
8968 - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty,
8969 0, 0, 1
8970 );
8971 }
8972 scale( sx, sy ) {
8973 const te = this.elements;
8974 te[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx;
8975 te[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy;
8976 return this;
8977 }
8978 rotate( theta ) {
8979 const c = Math.cos( theta );
8980 const s = Math.sin( theta );
8981 const te = this.elements;
8982 const a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ];
8983 const a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ];
8984 te[ 0 ] = c * a11 + s * a21;
8985 te[ 3 ] = c * a12 + s * a22;
8986 te[ 6 ] = c * a13 + s * a23;
8987 te[ 1 ] = - s * a11 + c * a21;
8988 te[ 4 ] = - s * a12 + c * a22;
8989 te[ 7 ] = - s * a13 + c * a23;
8990 return this;
8991 }
8992 translate( tx, ty ) {
8993 const te = this.elements;
8994 te[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ];
8995 te[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ];
8996 return this;
8997 }
8998 equals( matrix ) {
8999 const te = this.elements;
9000 const me = matrix.elements;
9001 for ( let i = 0; i < 9; i ++ ) {
9002 if ( te[ i ] !== me[ i ] ) return false;
9003 }
9004 return true;
9005 }
9006 fromArray( array, offset ) {
9007 if ( offset === undefined ) offset = 0;
9008 for ( let i = 0; i < 9; i ++ ) {
9009 this.elements[ i ] = array[ i + offset ];
9010 }
9011 return this;
9012 }
9013 toArray( array, offset ) {
9014 if ( array === undefined ) array = [];
9015 if ( offset === undefined ) offset = 0;
9016 const te = this.elements;
9017 array[ offset ] = te[ 0 ];
9018 array[ offset + 1 ] = te[ 1 ];
9019 array[ offset + 2 ] = te[ 2 ];
9020 array[ offset + 3 ] = te[ 3 ];
9021 array[ offset + 4 ] = te[ 4 ];
9022 array[ offset + 5 ] = te[ 5 ];
9023 array[ offset + 6 ] = te[ 6 ];
9024 array[ offset + 7 ] = te[ 7 ];
9025 array[ offset + 8 ] = te[ 8 ];
9026 return array;
9027 }
9028 }
9029 let _canvas;
9030 const ImageUtils = {
9031 getDataURL: function ( image ) {
9032 if ( /^data:/i.test( image.src ) ) {
9033 return image.src;
9034 }
9035 if ( typeof HTMLCanvasElement == 'undefined' ) {
9036 return image.src;
9037 }
9038 let canvas;
9039 if ( image instanceof HTMLCanvasElement ) {
9040 canvas = image;
9041 } else {
9042 if ( _canvas === undefined ) _canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
9043 _canvas.width = image.width;
9044 _canvas.height = image.height;
9045 const context = _canvas.getContext( '2d' );
9046 if ( image instanceof ImageData ) {
9047 context.putImageData( image, 0, 0 );
9048 } else {
9049 context.drawImage( image, 0, 0, image.width, image.height );
9050 }
9051 canvas = _canvas;
9052 }
9053 if ( canvas.width > 2048 || canvas.height > 2048 ) {
9054 return canvas.toDataURL( 'image/jpeg', 0.6 );
9055 } else {
9056 return canvas.toDataURL( 'image/png' );
9057 }
9058 }
9059 };
9060 let textureId = 0;
9061 function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {
9062 Object.defineProperty( this, 'id', { value: textureId ++ } );
9063 this.uuid = MathUtils.generateUUID();
9064 this.name = '';
9065 this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;
9066 this.mipmaps = [];
9067 this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;
9068 this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;
9069 this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;
9070 this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
9071 this.minFilter = minFilter !== undefined ? minFilter : LinearMipmapLinearFilter;
9072 this.anisotropy = anisotropy !== undefined ? anisotropy : 1;
9073 this.format = format !== undefined ? format : RGBAFormat;
9074 this.internalFormat = null;
9075 this.type = type !== undefined ? type : UnsignedByteType;
9076 this.offset = new Vector2( 0, 0 );
9077 this.repeat = new Vector2( 1, 1 );
9078 this.center = new Vector2( 0, 0 );
9079 this.rotation = 0;
9080 this.matrixAutoUpdate = true;
9081 this.matrix = new Matrix3();
9082 this.generateMipmaps = true;
9083 this.premultiplyAlpha = false;
9084 this.flipY = true;
9085 this.unpackAlignment = 4;
9086 this.encoding = encoding !== undefined ? encoding : LinearEncoding;
9087 this.version = 0;
9088 this.onUpdate = null;
9089 }
9090 Texture.DEFAULT_IMAGE = undefined;
9091 Texture.DEFAULT_MAPPING = UVMapping;
9092 Texture.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
9093 constructor: Texture,
9094 isTexture: true,
9095 updateMatrix: function () {
9096 this.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y );
9097 },
9098 clone: function () {
9099 return new this.constructor().copy( this );
9100 },
9101 copy: function ( source ) {
9102 this.name = source.name;
9103 this.image = source.image;
9104 this.mipmaps = source.mipmaps.slice( 0 );
9105 this.mapping = source.mapping;
9106 this.wrapS = source.wrapS;
9107 this.wrapT = source.wrapT;
9108 this.magFilter = source.magFilter;
9109 this.minFilter = source.minFilter;
9110 this.anisotropy = source.anisotropy;
9111 this.format = source.format;
9112 this.internalFormat = source.internalFormat;
9113 this.type = source.type;
9114 this.offset.copy( source.offset );
9115 this.repeat.copy( source.repeat );
9116 this.center.copy( source.center );
9117 this.rotation = source.rotation;
9118 this.matrixAutoUpdate = source.matrixAutoUpdate;
9119 this.matrix.copy( source.matrix );
9120 this.generateMipmaps = source.generateMipmaps;
9121 this.premultiplyAlpha = source.premultiplyAlpha;
9122 this.flipY = source.flipY;
9123 this.unpackAlignment = source.unpackAlignment;
9124 this.encoding = source.encoding;
9125 return this;
9126 },
9127 toJSON: function ( meta ) {
9128 const isRootObject = ( meta === undefined || typeof meta === 'string' );
9129 if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) {
9130 return meta.textures[ this.uuid ];
9131 }
9132 const output = {
9133 metadata: {
9134 version: 4.5,
9135 type: 'Texture',
9136 generator: 'Texture.toJSON'
9137 },
9138 uuid: this.uuid,
9139 name: this.name,
9140 mapping: this.mapping,
9141 repeat: [ this.repeat.x, this.repeat.y ],
9142 offset: [ this.offset.x, this.offset.y ],
9143 center: [ this.center.x, this.center.y ],
9144 rotation: this.rotation,
9145 wrap: [ this.wrapS, this.wrapT ],
9146 format: this.format,
9147 type: this.type,
9148 encoding: this.encoding,
9149 minFilter: this.minFilter,
9150 magFilter: this.magFilter,
9151 anisotropy: this.anisotropy,
9152 flipY: this.flipY,
9153 premultiplyAlpha: this.premultiplyAlpha,
9154 unpackAlignment: this.unpackAlignment
9155 };
9156 if ( this.image !== undefined ) {
9157 const image = this.image;
9158 if ( image.uuid === undefined ) {
9159 image.uuid = MathUtils.generateUUID();
9160 }
9161 if ( ! isRootObject && meta.images[ image.uuid ] === undefined ) {
9162 let url;
9163 if ( Array.isArray( image ) ) {
9164 url = [];
9165 for ( let i = 0, l = image.length; i < l; i ++ ) {
9166 url.push( ImageUtils.getDataURL( image[ i ] ) );
9167 }
9168 } else {
9169 url = ImageUtils.getDataURL( image );
9170 }
9171 meta.images[ image.uuid ] = {
9172 uuid: image.uuid,
9173 url: url
9174 };
9175 }
9176 output.image = image.uuid;
9177 }
9178 if ( ! isRootObject ) {
9179 meta.textures[ this.uuid ] = output;
9180 }
9181 return output;
9182 },
9183 dispose: function () {
9184 this.dispatchEvent( { type: 'dispose' } );
9185 },
9186 transformUv: function ( uv ) {
9187 if ( this.mapping !== UVMapping ) return uv;
9188 uv.applyMatrix3( this.matrix );
9189 if ( uv.x < 0 || uv.x > 1 ) {
9190 switch ( this.wrapS ) {
9191 case RepeatWrapping:
9192 uv.x = uv.x - Math.floor( uv.x );
9193 break;
9194 case ClampToEdgeWrapping:
9195 uv.x = uv.x < 0 ? 0 : 1;
9196 break;
9197 case MirroredRepeatWrapping:
9198 if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {
9199 uv.x = Math.ceil( uv.x ) - uv.x;
9200 } else {
9201 uv.x = uv.x - Math.floor( uv.x );
9202 }
9203 break;
9204 }
9205 }
9206 if ( uv.y < 0 || uv.y > 1 ) {
9207 switch ( this.wrapT ) {
9208 case RepeatWrapping:
9209 uv.y = uv.y - Math.floor( uv.y );
9210 break;
9211 case ClampToEdgeWrapping:
9212 uv.y = uv.y < 0 ? 0 : 1;
9213 break;
9214 case MirroredRepeatWrapping:
9215 if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {
9216 uv.y = Math.ceil( uv.y ) - uv.y;
9217 } else {
9218 uv.y = uv.y - Math.floor( uv.y );
9219 }
9220 break;
9221 }
9222 }
9223 if ( this.flipY ) {
9224 uv.y = 1 - uv.y;
9225 }
9226 return uv;
9227 }
9228 } );
9229 Object.defineProperty( Texture.prototype, "needsUpdate", {
9230 set: function ( value ) {
9231 if ( value === true ) this.version ++;
9232 }
9233 } );
9234 class Vector4 {
9235 constructor( x = 0, y = 0, z = 0, w = 1 ) {
9236 Object.defineProperty( this, 'isVector4', { value: true } );
9237 this.x = x;
9238 this.y = y;
9239 this.z = z;
9240 this.w = w;
9241 }
9242 get width() {
9243 return this.z;
9244 }
9245 set width( value ) {
9246 this.z = value;
9247 }
9248 get height() {
9249 return this.w;
9250 }
9251 set height( value ) {
9252 this.w = value;
9253 }
9254 set( x, y, z, w ) {
9255 this.x = x;
9256 this.y = y;
9257 this.z = z;
9258 this.w = w;
9259 return this;
9260 }
9261 setScalar( scalar ) {
9262 this.x = scalar;
9263 this.y = scalar;
9264 this.z = scalar;
9265 this.w = scalar;
9266 return this;
9267 }
9268 setX( x ) {
9269 this.x = x;
9270 return this;
9271 }
9272 setY( y ) {
9273 this.y = y;
9274 return this;
9275 }
9276 setZ( z ) {
9277 this.z = z;
9278 return this;
9279 }
9280 setW( w ) {
9281 this.w = w;
9282 return this;
9283 }
9284 setComponent( index, value ) {
9285 switch ( index ) {
9286 case 0: this.x = value; break;
9287 case 1: this.y = value; break;
9288 case 2: this.z = value; break;
9289 case 3: this.w = value; break;
9290 default: throw new Error( 'index is out of range: ' + index );
9291 }
9292 return this;
9293 }
9294 getComponent( index ) {
9295 switch ( index ) {
9296 case 0: return this.x;
9297 case 1: return this.y;
9298 case 2: return this.z;
9299 case 3: return this.w;
9300 default: throw new Error( 'index is out of range: ' + index );
9301 }
9302 }
9303 clone() {
9304 return new this.constructor( this.x, this.y, this.z, this.w );
9305 }
9306 copy( v ) {
9307 this.x = v.x;
9308 this.y = v.y;
9309 this.z = v.z;
9310 this.w = ( v.w !== undefined ) ? v.w : 1;
9311 return this;
9312 }
9313 add( v, w ) {
9314 if ( w !== undefined ) {
9315 console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
9316 return this.addVectors( v, w );
9317 }
9318 this.x += v.x;
9319 this.y += v.y;
9320 this.z += v.z;
9321 this.w += v.w;
9322 return this;
9323 }
9324 addScalar( s ) {
9325 this.x += s;
9326 this.y += s;
9327 this.z += s;
9328 this.w += s;
9329 return this;
9330 }
9331 addVectors( a, b ) {
9332 this.x = a.x + b.x;
9333 this.y = a.y + b.y;
9334 this.z = a.z + b.z;
9335 this.w = a.w + b.w;
9336 return this;
9337 }
9338 addScaledVector( v, s ) {
9339 this.x += v.x * s;
9340 this.y += v.y * s;
9341 this.z += v.z * s;
9342 this.w += v.w * s;
9343 return this;
9344 }
9345 sub( v, w ) {
9346 if ( w !== undefined ) {
9347 console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
9348 return this.subVectors( v, w );
9349 }
9350 this.x -= v.x;
9351 this.y -= v.y;
9352 this.z -= v.z;
9353 this.w -= v.w;
9354 return this;
9355 }
9356 subScalar( s ) {
9357 this.x -= s;
9358 this.y -= s;
9359 this.z -= s;
9360 this.w -= s;
9361 return this;
9362 }
9363 subVectors( a, b ) {
9364 this.x = a.x - b.x;
9365 this.y = a.y - b.y;
9366 this.z = a.z - b.z;
9367 this.w = a.w - b.w;
9368 return this;
9369 }
9370 multiplyScalar( scalar ) {
9371 this.x *= scalar;
9372 this.y *= scalar;
9373 this.z *= scalar;
9374 this.w *= scalar;
9375 return this;
9376 }
9377 applyMatrix4( m ) {
9378 const x = this.x, y = this.y, z = this.z, w = this.w;
9379 const e = m.elements;
9380 this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;
9381 this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;
9382 this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;
9383 this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;
9384 return this;
9385 }
9386 divideScalar( scalar ) {
9387 return this.multiplyScalar( 1 / scalar );
9388 }
9389 setAxisAngleFromQuaternion( q ) {
9390 this.w = 2 * Math.acos( q.w );
9391 const s = Math.sqrt( 1 - q.w * q.w );
9392 if ( s < 0.0001 ) {
9393 this.x = 1;
9394 this.y = 0;
9395 this.z = 0;
9396 } else {
9397 this.x = q.x / s;
9398 this.y = q.y / s;
9399 this.z = q.z / s;
9400 }
9401 return this;
9402 }
9403 setAxisAngleFromRotationMatrix( m ) {
9404 let angle, x, y, z;
9405 const epsilon = 0.01,
9406 epsilon2 = 0.1,
9407 te = m.elements,
9408 m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],
9409 m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],
9410 m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];
9411 if ( ( Math.abs( m12 - m21 ) < epsilon ) &&
9412 ( Math.abs( m13 - m31 ) < epsilon ) &&
9413 ( Math.abs( m23 - m32 ) < epsilon ) ) {
9414 if ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&
9415 ( Math.abs( m13 + m31 ) < epsilon2 ) &&
9416 ( Math.abs( m23 + m32 ) < epsilon2 ) &&
9417 ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {
9418 this.set( 1, 0, 0, 0 );
9419 return this;
9420 }
9421 angle = Math.PI;
9422 const xx = ( m11 + 1 ) / 2;
9423 const yy = ( m22 + 1 ) / 2;
9424 const zz = ( m33 + 1 ) / 2;
9425 const xy = ( m12 + m21 ) / 4;
9426 const xz = ( m13 + m31 ) / 4;
9427 const yz = ( m23 + m32 ) / 4;
9428 if ( ( xx > yy ) && ( xx > zz ) ) {
9429 if ( xx < epsilon ) {
9430 x = 0;
9431 y = 0.707106781;
9432 z = 0.707106781;
9433 } else {
9434 x = Math.sqrt( xx );
9435 y = xy / x;
9436 z = xz / x;
9437 }
9438 } else if ( yy > zz ) {
9439 if ( yy < epsilon ) {
9440 x = 0.707106781;
9441 y = 0;
9442 z = 0.707106781;
9443 } else {
9444 y = Math.sqrt( yy );
9445 x = xy / y;
9446 z = yz / y;
9447 }
9448 } else {
9449 if ( zz < epsilon ) {
9450 x = 0.707106781;
9451 y = 0.707106781;
9452 z = 0;
9453 } else {
9454 z = Math.sqrt( zz );
9455 x = xz / z;
9456 y = yz / z;
9457 }
9458 }
9459 this.set( x, y, z, angle );
9460 return this;
9461 }
9462 let s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +
9463 ( m13 - m31 ) * ( m13 - m31 ) +
9464 ( m21 - m12 ) * ( m21 - m12 ) );
9465 if ( Math.abs( s ) < 0.001 ) s = 1;
9466 this.x = ( m32 - m23 ) / s;
9467 this.y = ( m13 - m31 ) / s;
9468 this.z = ( m21 - m12 ) / s;
9469 this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );
9470 return this;
9471 }
9472 min( v ) {
9473 this.x = Math.min( this.x, v.x );
9474 this.y = Math.min( this.y, v.y );
9475 this.z = Math.min( this.z, v.z );
9476 this.w = Math.min( this.w, v.w );
9477 return this;
9478 }
9479 max( v ) {
9480 this.x = Math.max( this.x, v.x );
9481 this.y = Math.max( this.y, v.y );
9482 this.z = Math.max( this.z, v.z );
9483 this.w = Math.max( this.w, v.w );
9484 return this;
9485 }
9486 clamp( min, max ) {
9487 this.x = Math.max( min.x, Math.min( max.x, this.x ) );
9488 this.y = Math.max( min.y, Math.min( max.y, this.y ) );
9489 this.z = Math.max( min.z, Math.min( max.z, this.z ) );
9490 this.w = Math.max( min.w, Math.min( max.w, this.w ) );
9491 return this;
9492 }
9493 clampScalar( minVal, maxVal ) {
9494 this.x = Math.max( minVal, Math.min( maxVal, this.x ) );
9495 this.y = Math.max( minVal, Math.min( maxVal, this.y ) );
9496 this.z = Math.max( minVal, Math.min( maxVal, this.z ) );
9497 this.w = Math.max( minVal, Math.min( maxVal, this.w ) );
9498 return this;
9499 }
9500 clampLength( min, max ) {
9501 const length = this.length();
9502 return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
9503 }
9504 floor() {
9505 this.x = Math.floor( this.x );
9506 this.y = Math.floor( this.y );
9507 this.z = Math.floor( this.z );
9508 this.w = Math.floor( this.w );
9509 return this;
9510 }
9511 ceil() {
9512 this.x = Math.ceil( this.x );
9513 this.y = Math.ceil( this.y );
9514 this.z = Math.ceil( this.z );
9515 this.w = Math.ceil( this.w );
9516 return this;
9517 }
9518 round() {
9519 this.x = Math.round( this.x );
9520 this.y = Math.round( this.y );
9521 this.z = Math.round( this.z );
9522 this.w = Math.round( this.w );
9523 return this;
9524 }
9525 roundToZero() {
9526 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
9527 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
9528 this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
9529 this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );
9530 return this;
9531 }
9532 negate() {
9533 this.x = - this.x;
9534 this.y = - this.y;
9535 this.z = - this.z;
9536 this.w = - this.w;
9537 return this;
9538 }
9539 dot( v ) {
9540 return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
9541 }
9542 lengthSq() {
9543 return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
9544 }
9545 length() {
9546 return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
9547 }
9548 manhattanLength() {
9549 return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );
9550 }
9551 normalize() {
9552 return this.divideScalar( this.length() || 1 );
9553 }
9554 setLength( length ) {
9555 return this.normalize().multiplyScalar( length );
9556 }
9557 lerp( v, alpha ) {
9558 this.x += ( v.x - this.x ) * alpha;
9559 this.y += ( v.y - this.y ) * alpha;
9560 this.z += ( v.z - this.z ) * alpha;
9561 this.w += ( v.w - this.w ) * alpha;
9562 return this;
9563 }
9564 lerpVectors( v1, v2, alpha ) {
9565 this.x = v1.x + ( v2.x - v1.x ) * alpha;
9566 this.y = v1.y + ( v2.y - v1.y ) * alpha;
9567 this.z = v1.z + ( v2.z - v1.z ) * alpha;
9568 this.w = v1.w + ( v2.w - v1.w ) * alpha;
9569 return this;
9570 }
9571 equals( v ) {
9572 return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );
9573 }
9574 fromArray( array, offset ) {
9575 if ( offset === undefined ) offset = 0;
9576 this.x = array[ offset ];
9577 this.y = array[ offset + 1 ];
9578 this.z = array[ offset + 2 ];
9579 this.w = array[ offset + 3 ];
9580 return this;
9581 }
9582 toArray( array, offset ) {
9583 if ( array === undefined ) array = [];
9584 if ( offset === undefined ) offset = 0;
9585 array[ offset ] = this.x;
9586 array[ offset + 1 ] = this.y;
9587 array[ offset + 2 ] = this.z;
9588 array[ offset + 3 ] = this.w;
9589 return array;
9590 }
9591 fromBufferAttribute( attribute, index, offset ) {
9592 if ( offset !== undefined ) {
9593 console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );
9594 }
9595 this.x = attribute.getX( index );
9596 this.y = attribute.getY( index );
9597 this.z = attribute.getZ( index );
9598 this.w = attribute.getW( index );
9599 return this;
9600 }
9601 random() {
9602 this.x = Math.random();
9603 this.y = Math.random();
9604 this.z = Math.random();
9605 this.w = Math.random();
9606 return this;
9607 }
9608 }
9609 function WebGLRenderTarget( width, height, options ) {
9610 this.width = width;
9611 this.height = height;
9612 this.scissor = new Vector4( 0, 0, width, height );
9613 this.scissorTest = false;
9614 this.viewport = new Vector4( 0, 0, width, height );
9615 options = options || {};
9616 this.texture = new Texture( undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );
9617 this.texture.image = {};
9618 this.texture.image.width = width;
9619 this.texture.image.height = height;
9620 this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;
9621 this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;
9622 this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
9623 this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : false;
9624 this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;
9625 }
9626 WebGLRenderTarget.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
9627 constructor: WebGLRenderTarget,
9628 isWebGLRenderTarget: true,
9629 setSize: function ( width, height ) {
9630 if ( this.width !== width || this.height !== height ) {
9631 this.width = width;
9632 this.height = height;
9633 this.texture.image.width = width;
9634 this.texture.image.height = height;
9635 this.dispose();
9636 }
9637 this.viewport.set( 0, 0, width, height );
9638 this.scissor.set( 0, 0, width, height );
9639 },
9640 clone: function () {
9641 return new this.constructor().copy( this );
9642 },
9643 copy: function ( source ) {
9644 this.width = source.width;
9645 this.height = source.height;
9646 this.viewport.copy( source.viewport );
9647 this.texture = source.texture.clone();
9648 this.depthBuffer = source.depthBuffer;
9649 this.stencilBuffer = source.stencilBuffer;
9650 this.depthTexture = source.depthTexture;
9651 return this;
9652 },
9653 dispose: function () {
9654 this.dispatchEvent( { type: 'dispose' } );
9655 }
9656 } );
9657 function WebGLMultisampleRenderTarget( width, height, options ) {
9658 WebGLRenderTarget.call( this, width, height, options );
9659 this.samples = 4;
9660 }
9661 WebGLMultisampleRenderTarget.prototype = Object.assign( Object.create( WebGLRenderTarget.prototype ), {
9662 constructor: WebGLMultisampleRenderTarget,
9663 isWebGLMultisampleRenderTarget: true,
9664 copy: function ( source ) {
9665 WebGLRenderTarget.prototype.copy.call( this, source );
9666 this.samples = source.samples;
9667 return this;
9668 }
9669 } );
9670 class Quaternion {
9671 constructor( x = 0, y = 0, z = 0, w = 1 ) {
9672 Object.defineProperty( this, 'isQuaternion', { value: true } );
9673 this._x = x;
9674 this._y = y;
9675 this._z = z;
9676 this._w = w;
9677 }
9678 static slerp( qa, qb, qm, t ) {
9679 return qm.copy( qa ).slerp( qb, t );
9680 }
9681 static slerpFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {
9682 let x0 = src0[ srcOffset0 + 0 ],
9683 y0 = src0[ srcOffset0 + 1 ],
9684 z0 = src0[ srcOffset0 + 2 ],
9685 w0 = src0[ srcOffset0 + 3 ];
9686 const x1 = src1[ srcOffset1 + 0 ],
9687 y1 = src1[ srcOffset1 + 1 ],
9688 z1 = src1[ srcOffset1 + 2 ],
9689 w1 = src1[ srcOffset1 + 3 ];
9690 if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {
9691 let s = 1 - t;
9692 const cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,
9693 dir = ( cos >= 0 ? 1 : - 1 ),
9694 sqrSin = 1 - cos * cos;
9695 if ( sqrSin > Number.EPSILON ) {
9696 const sin = Math.sqrt( sqrSin ),
9697 len = Math.atan2( sin, cos * dir );
9698 s = Math.sin( s * len ) / sin;
9699 t = Math.sin( t * len ) / sin;
9700 }
9701 const tDir = t * dir;
9702 x0 = x0 * s + x1 * tDir;
9703 y0 = y0 * s + y1 * tDir;
9704 z0 = z0 * s + z1 * tDir;
9705 w0 = w0 * s + w1 * tDir;
9706 if ( s === 1 - t ) {
9707 const f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );
9708 x0 *= f;
9709 y0 *= f;
9710 z0 *= f;
9711 w0 *= f;
9712 }
9713 }
9714 dst[ dstOffset ] = x0;
9715 dst[ dstOffset + 1 ] = y0;
9716 dst[ dstOffset + 2 ] = z0;
9717 dst[ dstOffset + 3 ] = w0;
9718 }
9719 static multiplyQuaternionsFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1 ) {
9720 const x0 = src0[ srcOffset0 ];
9721 const y0 = src0[ srcOffset0 + 1 ];
9722 const z0 = src0[ srcOffset0 + 2 ];
9723 const w0 = src0[ srcOffset0 + 3 ];
9724 const x1 = src1[ srcOffset1 ];
9725 const y1 = src1[ srcOffset1 + 1 ];
9726 const z1 = src1[ srcOffset1 + 2 ];
9727 const w1 = src1[ srcOffset1 + 3 ];
9728 dst[ dstOffset ] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1;
9729 dst[ dstOffset + 1 ] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1;
9730 dst[ dstOffset + 2 ] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1;
9731 dst[ dstOffset + 3 ] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;
9732 return dst;
9733 }
9734 get x() {
9735 return this._x;
9736 }
9737 set x( value ) {
9738 this._x = value;
9739 this._onChangeCallback();
9740 }
9741 get y() {
9742 return this._y;
9743 }
9744 set y( value ) {
9745 this._y = value;
9746 this._onChangeCallback();
9747 }
9748 get z() {
9749 return this._z;
9750 }
9751 set z( value ) {
9752 this._z = value;
9753 this._onChangeCallback();
9754 }
9755 get w() {
9756 return this._w;
9757 }
9758 set w( value ) {
9759 this._w = value;
9760 this._onChangeCallback();
9761 }
9762 set( x, y, z, w ) {
9763 this._x = x;
9764 this._y = y;
9765 this._z = z;
9766 this._w = w;
9767 this._onChangeCallback();
9768 return this;
9769 }
9770 clone() {
9771 return new this.constructor( this._x, this._y, this._z, this._w );
9772 }
9773 copy( quaternion ) {
9774 this._x = quaternion.x;
9775 this._y = quaternion.y;
9776 this._z = quaternion.z;
9777 this._w = quaternion.w;
9778 this._onChangeCallback();
9779 return this;
9780 }
9781 setFromEuler( euler, update ) {
9782 if ( ! ( euler && euler.isEuler ) ) {
9783 throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );
9784 }
9785 const x = euler._x, y = euler._y, z = euler._z, order = euler._order;
9786 const cos = Math.cos;
9787 const sin = Math.sin;
9788 const c1 = cos( x / 2 );
9789 const c2 = cos( y / 2 );
9790 const c3 = cos( z / 2 );
9791 const s1 = sin( x / 2 );
9792 const s2 = sin( y / 2 );
9793 const s3 = sin( z / 2 );
9794 switch ( order ) {
9795 case 'XYZ':
9796 this._x = s1 * c2 * c3 + c1 * s2 * s3;
9797 this._y = c1 * s2 * c3 - s1 * c2 * s3;
9798 this._z = c1 * c2 * s3 + s1 * s2 * c3;
9799 this._w = c1 * c2 * c3 - s1 * s2 * s3;
9800 break;
9801 case 'YXZ':
9802 this._x = s1 * c2 * c3 + c1 * s2 * s3;
9803 this._y = c1 * s2 * c3 - s1 * c2 * s3;
9804 this._z = c1 * c2 * s3 - s1 * s2 * c3;
9805 this._w = c1 * c2 * c3 + s1 * s2 * s3;
9806 break;
9807 case 'ZXY':
9808 this._x = s1 * c2 * c3 - c1 * s2 * s3;
9809 this._y = c1 * s2 * c3 + s1 * c2 * s3;
9810 this._z = c1 * c2 * s3 + s1 * s2 * c3;
9811 this._w = c1 * c2 * c3 - s1 * s2 * s3;
9812 break;
9813 case 'ZYX':
9814 this._x = s1 * c2 * c3 - c1 * s2 * s3;
9815 this._y = c1 * s2 * c3 + s1 * c2 * s3;
9816 this._z = c1 * c2 * s3 - s1 * s2 * c3;
9817 this._w = c1 * c2 * c3 + s1 * s2 * s3;
9818 break;
9819 case 'YZX':
9820 this._x = s1 * c2 * c3 + c1 * s2 * s3;
9821 this._y = c1 * s2 * c3 + s1 * c2 * s3;
9822 this._z = c1 * c2 * s3 - s1 * s2 * c3;
9823 this._w = c1 * c2 * c3 - s1 * s2 * s3;
9824 break;
9825 case 'XZY':
9826 this._x = s1 * c2 * c3 - c1 * s2 * s3;
9827 this._y = c1 * s2 * c3 - s1 * c2 * s3;
9828 this._z = c1 * c2 * s3 + s1 * s2 * c3;
9829 this._w = c1 * c2 * c3 + s1 * s2 * s3;
9830 break;
9831 default:
9832 console.warn( 'THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order );
9833 }
9834 if ( update !== false ) this._onChangeCallback();
9835 return this;
9836 }
9837 setFromAxisAngle( axis, angle ) {
9838 const halfAngle = angle / 2, s = Math.sin( halfAngle );
9839 this._x = axis.x * s;
9840 this._y = axis.y * s;
9841 this._z = axis.z * s;
9842 this._w = Math.cos( halfAngle );
9843 this._onChangeCallback();
9844 return this;
9845 }
9846 setFromRotationMatrix( m ) {
9847 const te = m.elements,
9848 m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],
9849 m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],
9850 m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],
9851 trace = m11 + m22 + m33;
9852 if ( trace > 0 ) {
9853 const s = 0.5 / Math.sqrt( trace + 1.0 );
9854 this._w = 0.25 / s;
9855 this._x = ( m32 - m23 ) * s;
9856 this._y = ( m13 - m31 ) * s;
9857 this._z = ( m21 - m12 ) * s;
9858 } else if ( m11 > m22 && m11 > m33 ) {
9859 const s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );
9860 this._w = ( m32 - m23 ) / s;
9861 this._x = 0.25 * s;
9862 this._y = ( m12 + m21 ) / s;
9863 this._z = ( m13 + m31 ) / s;
9864 } else if ( m22 > m33 ) {
9865 const s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );
9866 this._w = ( m13 - m31 ) / s;
9867 this._x = ( m12 + m21 ) / s;
9868 this._y = 0.25 * s;
9869 this._z = ( m23 + m32 ) / s;
9870 } else {
9871 const s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );
9872 this._w = ( m21 - m12 ) / s;
9873 this._x = ( m13 + m31 ) / s;
9874 this._y = ( m23 + m32 ) / s;
9875 this._z = 0.25 * s;
9876 }
9877 this._onChangeCallback();
9878 return this;
9879 }
9880 setFromUnitVectors( vFrom, vTo ) {
9881 const EPS = 0.000001;
9882 let r = vFrom.dot( vTo ) + 1;
9883 if ( r < EPS ) {
9884 r = 0;
9885 if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {
9886 this._x = - vFrom.y;
9887 this._y = vFrom.x;
9888 this._z = 0;
9889 this._w = r;
9890 } else {
9891 this._x = 0;
9892 this._y = - vFrom.z;
9893 this._z = vFrom.y;
9894 this._w = r;
9895 }
9896 } else {
9897 this._x = vFrom.y * vTo.z - vFrom.z * vTo.y;
9898 this._y = vFrom.z * vTo.x - vFrom.x * vTo.z;
9899 this._z = vFrom.x * vTo.y - vFrom.y * vTo.x;
9900 this._w = r;
9901 }
9902 return this.normalize();
9903 }
9904 angleTo( q ) {
9905 return 2 * Math.acos( Math.abs( MathUtils.clamp( this.dot( q ), - 1, 1 ) ) );
9906 }
9907 rotateTowards( q, step ) {
9908 const angle = this.angleTo( q );
9909 if ( angle === 0 ) return this;
9910 const t = Math.min( 1, step / angle );
9911 this.slerp( q, t );
9912 return this;
9913 }
9914 identity() {
9915 return this.set( 0, 0, 0, 1 );
9916 }
9917 inverse() {
9918 return this.conjugate();
9919 }
9920 conjugate() {
9921 this._x *= - 1;
9922 this._y *= - 1;
9923 this._z *= - 1;
9924 this._onChangeCallback();
9925 return this;
9926 }
9927 dot( v ) {
9928 return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
9929 }
9930 lengthSq() {
9931 return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
9932 }
9933 length() {
9934 return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );
9935 }
9936 normalize() {
9937 let l = this.length();
9938 if ( l === 0 ) {
9939 this._x = 0;
9940 this._y = 0;
9941 this._z = 0;
9942 this._w = 1;
9943 } else {
9944 l = 1 / l;
9945 this._x = this._x * l;
9946 this._y = this._y * l;
9947 this._z = this._z * l;
9948 this._w = this._w * l;
9949 }
9950 this._onChangeCallback();
9951 return this;
9952 }
9953 multiply( q, p ) {
9954 if ( p !== undefined ) {
9955 console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );
9956 return this.multiplyQuaternions( q, p );
9957 }
9958 return this.multiplyQuaternions( this, q );
9959 }
9960 premultiply( q ) {
9961 return this.multiplyQuaternions( q, this );
9962 }
9963 multiplyQuaternions( a, b ) {
9964 const qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;
9965 const qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;
9966 this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
9967 this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
9968 this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
9969 this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
9970 this._onChangeCallback();
9971 return this;
9972 }
9973 slerp( qb, t ) {
9974 if ( t === 0 ) return this;
9975 if ( t === 1 ) return this.copy( qb );
9976 const x = this._x, y = this._y, z = this._z, w = this._w;
9977 let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;
9978 if ( cosHalfTheta < 0 ) {
9979 this._w = - qb._w;
9980 this._x = - qb._x;
9981 this._y = - qb._y;
9982 this._z = - qb._z;
9983 cosHalfTheta = - cosHalfTheta;
9984 } else {
9985 this.copy( qb );
9986 }
9987 if ( cosHalfTheta >= 1.0 ) {
9988 this._w = w;
9989 this._x = x;
9990 this._y = y;
9991 this._z = z;
9992 return this;
9993 }
9994 const sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta;
9995 if ( sqrSinHalfTheta <= Number.EPSILON ) {
9996 const s = 1 - t;
9997 this._w = s * w + t * this._w;
9998 this._x = s * x + t * this._x;
9999 this._y = s * y + t * this._y;
10000 this._z = s * z + t * this._z;
10001 this.normalize();
10002 this._onChangeCallback();
10003 return this;
10004 }
10005 const sinHalfTheta = Math.sqrt( sqrSinHalfTheta );
10006 const halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );
10007 const ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
10008 ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
10009 this._w = ( w * ratioA + this._w * ratioB );
10010 this._x = ( x * ratioA + this._x * ratioB );
10011 this._y = ( y * ratioA + this._y * ratioB );
10012 this._z = ( z * ratioA + this._z * ratioB );
10013 this._onChangeCallback();
10014 return this;
10015 }
10016 equals( quaternion ) {
10017 return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );
10018 }
10019 fromArray( array, offset ) {
10020 if ( offset === undefined ) offset = 0;
10021 this._x = array[ offset ];
10022 this._y = array[ offset + 1 ];
10023 this._z = array[ offset + 2 ];
10024 this._w = array[ offset + 3 ];
10025 this._onChangeCallback();
10026 return this;
10027 }
10028 toArray( array, offset ) {
10029 if ( array === undefined ) array = [];
10030 if ( offset === undefined ) offset = 0;
10031 array[ offset ] = this._x;
10032 array[ offset + 1 ] = this._y;
10033 array[ offset + 2 ] = this._z;
10034 array[ offset + 3 ] = this._w;
10035 return array;
10036 }
10037 fromBufferAttribute( attribute, index ) {
10038 this._x = attribute.getX( index );
10039 this._y = attribute.getY( index );
10040 this._z = attribute.getZ( index );
10041 this._w = attribute.getW( index );
10042 return this;
10043 }
10044 _onChange( callback ) {
10045 this._onChangeCallback = callback;
10046 return this;
10047 }
10048 _onChangeCallback() {}
10049 }
10050 class Vector3 {
10051 constructor( x = 0, y = 0, z = 0 ) {
10052 Object.defineProperty( this, 'isVector3', { value: true } );
10053 this.x = x;
10054 this.y = y;
10055 this.z = z;
10056 }
10057 set( x, y, z ) {
10058 if ( z === undefined ) z = this.z;
10059 this.x = x;
10060 this.y = y;
10061 this.z = z;
10062 return this;
10063 }
10064 setScalar( scalar ) {
10065 this.x = scalar;
10066 this.y = scalar;
10067 this.z = scalar;
10068 return this;
10069 }
10070 setX( x ) {
10071 this.x = x;
10072 return this;
10073 }
10074 setY( y ) {
10075 this.y = y;
10076 return this;
10077 }
10078 setZ( z ) {
10079 this.z = z;
10080 return this;
10081 }
10082 setComponent( index, value ) {
10083 switch ( index ) {
10084 case 0: this.x = value; break;
10085 case 1: this.y = value; break;
10086 case 2: this.z = value; break;
10087 default: throw new Error( 'index is out of range: ' + index );
10088 }
10089 return this;
10090 }
10091 getComponent( index ) {
10092 switch ( index ) {
10093 case 0: return this.x;
10094 case 1: return this.y;
10095 case 2: return this.z;
10096 default: throw new Error( 'index is out of range: ' + index );
10097 }
10098 }
10099 clone() {
10100 return new this.constructor( this.x, this.y, this.z );
10101 }
10102 copy( v ) {
10103 this.x = v.x;
10104 this.y = v.y;
10105 this.z = v.z;
10106 return this;
10107 }
10108 add( v, w ) {
10109 if ( w !== undefined ) {
10110 console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
10111 return this.addVectors( v, w );
10112 }
10113 this.x += v.x;
10114 this.y += v.y;
10115 this.z += v.z;
10116 return this;
10117 }
10118 addScalar( s ) {
10119 this.x += s;
10120 this.y += s;
10121 this.z += s;
10122 return this;
10123 }
10124 addVectors( a, b ) {
10125 this.x = a.x + b.x;
10126 this.y = a.y + b.y;
10127 this.z = a.z + b.z;
10128 return this;
10129 }
10130 addScaledVector( v, s ) {
10131 this.x += v.x * s;
10132 this.y += v.y * s;
10133 this.z += v.z * s;
10134 return this;
10135 }
10136 sub( v, w ) {
10137 if ( w !== undefined ) {
10138 console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
10139 return this.subVectors( v, w );
10140 }
10141 this.x -= v.x;
10142 this.y -= v.y;
10143 this.z -= v.z;
10144 return this;
10145 }
10146 subScalar( s ) {
10147 this.x -= s;
10148 this.y -= s;
10149 this.z -= s;
10150 return this;
10151 }
10152 subVectors( a, b ) {
10153 this.x = a.x - b.x;
10154 this.y = a.y - b.y;
10155 this.z = a.z - b.z;
10156 return this;
10157 }
10158 multiply( v, w ) {
10159 if ( w !== undefined ) {
10160 console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );
10161 return this.multiplyVectors( v, w );
10162 }
10163 this.x *= v.x;
10164 this.y *= v.y;
10165 this.z *= v.z;
10166 return this;
10167 }
10168 multiplyScalar( scalar ) {
10169 this.x *= scalar;
10170 this.y *= scalar;
10171 this.z *= scalar;
10172 return this;
10173 }
10174 multiplyVectors( a, b ) {
10175 this.x = a.x * b.x;
10176 this.y = a.y * b.y;
10177 this.z = a.z * b.z;
10178 return this;
10179 }
10180 applyEuler( euler ) {
10181 if ( ! ( euler && euler.isEuler ) ) {
10182 console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );
10183 }
10184 return this.applyQuaternion( _quaternion.setFromEuler( euler ) );
10185 }
10186 applyAxisAngle( axis, angle ) {
10187 return this.applyQuaternion( _quaternion.setFromAxisAngle( axis, angle ) );
10188 }
10189 applyMatrix3( m ) {
10190 const x = this.x, y = this.y, z = this.z;
10191 const e = m.elements;
10192 this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;
10193 this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;
10194 this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;
10195 return this;
10196 }
10197 applyNormalMatrix( m ) {
10198 return this.applyMatrix3( m ).normalize();
10199 }
10200 applyMatrix4( m ) {
10201 const x = this.x, y = this.y, z = this.z;
10202 const e = m.elements;
10203 const w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] );
10204 this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w;
10205 this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w;
10206 this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w;
10207 return this;
10208 }
10209 applyQuaternion( q ) {
10210 const x = this.x, y = this.y, z = this.z;
10211 const qx = q.x, qy = q.y, qz = q.z, qw = q.w;
10212 const ix = qw * x + qy * z - qz * y;
10213 const iy = qw * y + qz * x - qx * z;
10214 const iz = qw * z + qx * y - qy * x;
10215 const iw = - qx * x - qy * y - qz * z;
10216 this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
10217 this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
10218 this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;
10219 return this;
10220 }
10221 project( camera ) {
10222 return this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix );
10223 }
10224 unproject( camera ) {
10225 return this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld );
10226 }
10227 transformDirection( m ) {
10228 const x = this.x, y = this.y, z = this.z;
10229 const e = m.elements;
10230 this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;
10231 this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;
10232 this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;
10233 return this.normalize();
10234 }
10235 divide( v ) {
10236 this.x /= v.x;
10237 this.y /= v.y;
10238 this.z /= v.z;
10239 return this;
10240 }
10241 divideScalar( scalar ) {
10242 return this.multiplyScalar( 1 / scalar );
10243 }
10244 min( v ) {
10245 this.x = Math.min( this.x, v.x );
10246 this.y = Math.min( this.y, v.y );
10247 this.z = Math.min( this.z, v.z );
10248 return this;
10249 }
10250 max( v ) {
10251 this.x = Math.max( this.x, v.x );
10252 this.y = Math.max( this.y, v.y );
10253 this.z = Math.max( this.z, v.z );
10254 return this;
10255 }
10256 clamp( min, max ) {
10257 this.x = Math.max( min.x, Math.min( max.x, this.x ) );
10258 this.y = Math.max( min.y, Math.min( max.y, this.y ) );
10259 this.z = Math.max( min.z, Math.min( max.z, this.z ) );
10260 return this;
10261 }
10262 clampScalar( minVal, maxVal ) {
10263 this.x = Math.max( minVal, Math.min( maxVal, this.x ) );
10264 this.y = Math.max( minVal, Math.min( maxVal, this.y ) );
10265 this.z = Math.max( minVal, Math.min( maxVal, this.z ) );
10266 return this;
10267 }
10268 clampLength( min, max ) {
10269 const length = this.length();
10270 return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
10271 }
10272 floor() {
10273 this.x = Math.floor( this.x );
10274 this.y = Math.floor( this.y );
10275 this.z = Math.floor( this.z );
10276 return this;
10277 }
10278 ceil() {
10279 this.x = Math.ceil( this.x );
10280 this.y = Math.ceil( this.y );
10281 this.z = Math.ceil( this.z );
10282 return this;
10283 }
10284 round() {
10285 this.x = Math.round( this.x );
10286 this.y = Math.round( this.y );
10287 this.z = Math.round( this.z );
10288 return this;
10289 }
10290 roundToZero() {
10291 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
10292 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
10293 this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
10294 return this;
10295 }
10296 negate() {
10297 this.x = - this.x;
10298 this.y = - this.y;
10299 this.z = - this.z;
10300 return this;
10301 }
10302 dot( v ) {
10303 return this.x * v.x + this.y * v.y + this.z * v.z;
10304 }
10305 lengthSq() {
10306 return this.x * this.x + this.y * this.y + this.z * this.z;
10307 }
10308 length() {
10309 return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
10310 }
10311 manhattanLength() {
10312 return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );
10313 }
10314 normalize() {
10315 return this.divideScalar( this.length() || 1 );
10316 }
10317 setLength( length ) {
10318 return this.normalize().multiplyScalar( length );
10319 }
10320 lerp( v, alpha ) {
10321 this.x += ( v.x - this.x ) * alpha;
10322 this.y += ( v.y - this.y ) * alpha;
10323 this.z += ( v.z - this.z ) * alpha;
10324 return this;
10325 }
10326 lerpVectors( v1, v2, alpha ) {
10327 this.x = v1.x + ( v2.x - v1.x ) * alpha;
10328 this.y = v1.y + ( v2.y - v1.y ) * alpha;
10329 this.z = v1.z + ( v2.z - v1.z ) * alpha;
10330 return this;
10331 }
10332 cross( v, w ) {
10333 if ( w !== undefined ) {
10334 console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );
10335 return this.crossVectors( v, w );
10336 }
10337 return this.crossVectors( this, v );
10338 }
10339 crossVectors( a, b ) {
10340 const ax = a.x, ay = a.y, az = a.z;
10341 const bx = b.x, by = b.y, bz = b.z;
10342 this.x = ay * bz - az * by;
10343 this.y = az * bx - ax * bz;
10344 this.z = ax * by - ay * bx;
10345 return this;
10346 }
10347 projectOnVector( v ) {
10348 const denominator = v.lengthSq();
10349 if ( denominator === 0 ) return this.set( 0, 0, 0 );
10350 const scalar = v.dot( this ) / denominator;
10351 return this.copy( v ).multiplyScalar( scalar );
10352 }
10353 projectOnPlane( planeNormal ) {
10354 _vector.copy( this ).projectOnVector( planeNormal );
10355 return this.sub( _vector );
10356 }
10357 reflect( normal ) {
10358 return this.sub( _vector.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );
10359 }
10360 angleTo( v ) {
10361 const denominator = Math.sqrt( this.lengthSq() * v.lengthSq() );
10362 if ( denominator === 0 ) return Math.PI / 2;
10363 const theta = this.dot( v ) / denominator;
10364 return Math.acos( MathUtils.clamp( theta, - 1, 1 ) );
10365 }
10366 distanceTo( v ) {
10367 return Math.sqrt( this.distanceToSquared( v ) );
10368 }
10369 distanceToSquared( v ) {
10370 const dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;
10371 return dx * dx + dy * dy + dz * dz;
10372 }
10373 manhattanDistanceTo( v ) {
10374 return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );
10375 }
10376 setFromSpherical( s ) {
10377 return this.setFromSphericalCoords( s.radius, s.phi, s.theta );
10378 }
10379 setFromSphericalCoords( radius, phi, theta ) {
10380 const sinPhiRadius = Math.sin( phi ) * radius;
10381 this.x = sinPhiRadius * Math.sin( theta );
10382 this.y = Math.cos( phi ) * radius;
10383 this.z = sinPhiRadius * Math.cos( theta );
10384 return this;
10385 }
10386 setFromCylindrical( c ) {
10387 return this.setFromCylindricalCoords( c.radius, c.theta, c.y );
10388 }
10389 setFromCylindricalCoords( radius, theta, y ) {
10390 this.x = radius * Math.sin( theta );
10391 this.y = y;
10392 this.z = radius * Math.cos( theta );
10393 return this;
10394 }
10395 setFromMatrixPosition( m ) {
10396 const e = m.elements;
10397 this.x = e[ 12 ];
10398 this.y = e[ 13 ];
10399 this.z = e[ 14 ];
10400 return this;
10401 }
10402 setFromMatrixScale( m ) {
10403 const sx = this.setFromMatrixColumn( m, 0 ).length();
10404 const sy = this.setFromMatrixColumn( m, 1 ).length();
10405 const sz = this.setFromMatrixColumn( m, 2 ).length();
10406 this.x = sx;
10407 this.y = sy;
10408 this.z = sz;
10409 return this;
10410 }
10411 setFromMatrixColumn( m, index ) {
10412 return this.fromArray( m.elements, index * 4 );
10413 }
10414 setFromMatrix3Column( m, index ) {
10415 return this.fromArray( m.elements, index * 3 );
10416 }
10417 equals( v ) {
10418 return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );
10419 }
10420 fromArray( array, offset ) {
10421 if ( offset === undefined ) offset = 0;
10422 this.x = array[ offset ];
10423 this.y = array[ offset + 1 ];
10424 this.z = array[ offset + 2 ];
10425 return this;
10426 }
10427 toArray( array, offset ) {
10428 if ( array === undefined ) array = [];
10429 if ( offset === undefined ) offset = 0;
10430 array[ offset ] = this.x;
10431 array[ offset + 1 ] = this.y;
10432 array[ offset + 2 ] = this.z;
10433 return array;
10434 }
10435 fromBufferAttribute( attribute, index, offset ) {
10436 if ( offset !== undefined ) {
10437 console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );
10438 }
10439 this.x = attribute.getX( index );
10440 this.y = attribute.getY( index );
10441 this.z = attribute.getZ( index );
10442 return this;
10443 }
10444 random() {
10445 this.x = Math.random();
10446 this.y = Math.random();
10447 this.z = Math.random();
10448 return this;
10449 }
10450 }
10451 const _vector = new Vector3();
10452 const _quaternion = new Quaternion();
10453 class Box3 {
10454 constructor( min, max ) {
10455 Object.defineProperty( this, 'isBox3', { value: true } );
10456 this.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );
10457 this.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );
10458 }
10459 set( min, max ) {
10460 this.min.copy( min );
10461 this.max.copy( max );
10462 return this;
10463 }
10464 setFromArray( array ) {
10465 let minX = + Infinity;
10466 let minY = + Infinity;
10467 let minZ = + Infinity;
10468 let maxX = - Infinity;
10469 let maxY = - Infinity;
10470 let maxZ = - Infinity;
10471 for ( let i = 0, l = array.length; i < l; i += 3 ) {
10472 const x = array[ i ];
10473 const y = array[ i + 1 ];
10474 const z = array[ i + 2 ];
10475 if ( x < minX ) minX = x;
10476 if ( y < minY ) minY = y;
10477 if ( z < minZ ) minZ = z;
10478 if ( x > maxX ) maxX = x;
10479 if ( y > maxY ) maxY = y;
10480 if ( z > maxZ ) maxZ = z;
10481 }
10482 this.min.set( minX, minY, minZ );
10483 this.max.set( maxX, maxY, maxZ );
10484 return this;
10485 }
10486 setFromBufferAttribute( attribute ) {
10487 let minX = + Infinity;
10488 let minY = + Infinity;
10489 let minZ = + Infinity;
10490 let maxX = - Infinity;
10491 let maxY = - Infinity;
10492 let maxZ = - Infinity;
10493 for ( let i = 0, l = attribute.count; i < l; i ++ ) {
10494 const x = attribute.getX( i );
10495 const y = attribute.getY( i );
10496 const z = attribute.getZ( i );
10497 if ( x < minX ) minX = x;
10498 if ( y < minY ) minY = y;
10499 if ( z < minZ ) minZ = z;
10500 if ( x > maxX ) maxX = x;
10501 if ( y > maxY ) maxY = y;
10502 if ( z > maxZ ) maxZ = z;
10503 }
10504 this.min.set( minX, minY, minZ );
10505 this.max.set( maxX, maxY, maxZ );
10506 return this;
10507 }
10508 setFromPoints( points ) {
10509 this.makeEmpty();
10510 for ( let i = 0, il = points.length; i < il; i ++ ) {
10511 this.expandByPoint( points[ i ] );
10512 }
10513 return this;
10514 }
10515 setFromCenterAndSize( center, size ) {
10516 const halfSize = _vector$1.copy( size ).multiplyScalar( 0.5 );
10517 this.min.copy( center ).sub( halfSize );
10518 this.max.copy( center ).add( halfSize );
10519 return this;
10520 }
10521 setFromObject( object ) {
10522 this.makeEmpty();
10523 return this.expandByObject( object );
10524 }
10525 clone() {
10526 return new this.constructor().copy( this );
10527 }
10528 copy( box ) {
10529 this.min.copy( box.min );
10530 this.max.copy( box.max );
10531 return this;
10532 }
10533 makeEmpty() {
10534 this.min.x = this.min.y = this.min.z = + Infinity;
10535 this.max.x = this.max.y = this.max.z = - Infinity;
10536 return this;
10537 }
10538 isEmpty() {
10539 return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );
10540 }
10541 getCenter( target ) {
10542 if ( target === undefined ) {
10543 console.warn( 'THREE.Box3: .getCenter() target is now required' );
10544 target = new Vector3();
10545 }
10546 return this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
10547 }
10548 getSize( target ) {
10549 if ( target === undefined ) {
10550 console.warn( 'THREE.Box3: .getSize() target is now required' );
10551 target = new Vector3();
10552 }
10553 return this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min );
10554 }
10555 expandByPoint( point ) {
10556 this.min.min( point );
10557 this.max.max( point );
10558 return this;
10559 }
10560 expandByVector( vector ) {
10561 this.min.sub( vector );
10562 this.max.add( vector );
10563 return this;
10564 }
10565 expandByScalar( scalar ) {
10566 this.min.addScalar( - scalar );
10567 this.max.addScalar( scalar );
10568 return this;
10569 }
10570 expandByObject( object ) {
10571 object.updateWorldMatrix( false, false );
10572 const geometry = object.geometry;
10573 if ( geometry !== undefined ) {
10574 if ( geometry.boundingBox === null ) {
10575 geometry.computeBoundingBox();
10576 }
10577 _box.copy( geometry.boundingBox );
10578 _box.applyMatrix4( object.matrixWorld );
10579 this.union( _box );
10580 }
10581 const children = object.children;
10582 for ( let i = 0, l = children.length; i < l; i ++ ) {
10583 this.expandByObject( children[ i ] );
10584 }
10585 return this;
10586 }
10587 containsPoint( point ) {
10588 return point.x < this.min.x || point.x > this.max.x ||
10589 point.y < this.min.y || point.y > this.max.y ||
10590 point.z < this.min.z || point.z > this.max.z ? false : true;
10591 }
10592 containsBox( box ) {
10593 return this.min.x <= box.min.x && box.max.x <= this.max.x &&
10594 this.min.y <= box.min.y && box.max.y <= this.max.y &&
10595 this.min.z <= box.min.z && box.max.z <= this.max.z;
10596 }
10597 getParameter( point, target ) {
10598 if ( target === undefined ) {
10599 console.warn( 'THREE.Box3: .getParameter() target is now required' );
10600 target = new Vector3();
10601 }
10602 return target.set(
10603 ( point.x - this.min.x ) / ( this.max.x - this.min.x ),
10604 ( point.y - this.min.y ) / ( this.max.y - this.min.y ),
10605 ( point.z - this.min.z ) / ( this.max.z - this.min.z )
10606 );
10607 }
10608 intersectsBox( box ) {
10609 return box.max.x < this.min.x || box.min.x > this.max.x ||
10610 box.max.y < this.min.y || box.min.y > this.max.y ||
10611 box.max.z < this.min.z || box.min.z > this.max.z ? false : true;
10612 }
10613 intersectsSphere( sphere ) {
10614 this.clampPoint( sphere.center, _vector$1 );
10615 return _vector$1.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );
10616 }
10617 intersectsPlane( plane ) {
10618 let min, max;
10619 if ( plane.normal.x > 0 ) {
10620 min = plane.normal.x * this.min.x;
10621 max = plane.normal.x * this.max.x;
10622 } else {
10623 min = plane.normal.x * this.max.x;
10624 max = plane.normal.x * this.min.x;
10625 }
10626 if ( plane.normal.y > 0 ) {
10627 min += plane.normal.y * this.min.y;
10628 max += plane.normal.y * this.max.y;
10629 } else {
10630 min += plane.normal.y * this.max.y;
10631 max += plane.normal.y * this.min.y;
10632 }
10633 if ( plane.normal.z > 0 ) {
10634 min += plane.normal.z * this.min.z;
10635 max += plane.normal.z * this.max.z;
10636 } else {
10637 min += plane.normal.z * this.max.z;
10638 max += plane.normal.z * this.min.z;
10639 }
10640 return ( min <= - plane.constant && max >= - plane.constant );
10641 }
10642 intersectsTriangle( triangle ) {
10643 if ( this.isEmpty() ) {
10644 return false;
10645 }
10646 this.getCenter( _center );
10647 _extents.subVectors( this.max, _center );
10648 _v0.subVectors( triangle.a, _center );
10649 _v1.subVectors( triangle.b, _center );
10650 _v2.subVectors( triangle.c, _center );
10651 _f0.subVectors( _v1, _v0 );
10652 _f1.subVectors( _v2, _v1 );
10653 _f2.subVectors( _v0, _v2 );
10654 let axes = [
10655 0, - _f0.z, _f0.y, 0, - _f1.z, _f1.y, 0, - _f2.z, _f2.y,
10656 _f0.z, 0, - _f0.x, _f1.z, 0, - _f1.x, _f2.z, 0, - _f2.x,
10657 - _f0.y, _f0.x, 0, - _f1.y, _f1.x, 0, - _f2.y, _f2.x, 0
10658 ];
10659 if ( ! satForAxes( axes, _v0, _v1, _v2, _extents ) ) {
10660 return false;
10661 }
10662 axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ];
10663 if ( ! satForAxes( axes, _v0, _v1, _v2, _extents ) ) {
10664 return false;
10665 }
10666 _triangleNormal.crossVectors( _f0, _f1 );
10667 axes = [ _triangleNormal.x, _triangleNormal.y, _triangleNormal.z ];
10668 return satForAxes( axes, _v0, _v1, _v2, _extents );
10669 }
10670 clampPoint( point, target ) {
10671 if ( target === undefined ) {
10672 console.warn( 'THREE.Box3: .clampPoint() target is now required' );
10673 target = new Vector3();
10674 }
10675 return target.copy( point ).clamp( this.min, this.max );
10676 }
10677 distanceToPoint( point ) {
10678 const clampedPoint = _vector$1.copy( point ).clamp( this.min, this.max );
10679 return clampedPoint.sub( point ).length();
10680 }
10681 getBoundingSphere( target ) {
10682 if ( target === undefined ) {
10683 console.error( 'THREE.Box3: .getBoundingSphere() target is now required' );
10684 }
10685 this.getCenter( target.center );
10686 target.radius = this.getSize( _vector$1 ).length() * 0.5;
10687 return target;
10688 }
10689 intersect( box ) {
10690 this.min.max( box.min );
10691 this.max.min( box.max );
10692 if ( this.isEmpty() ) this.makeEmpty();
10693 return this;
10694 }
10695 union( box ) {
10696 this.min.min( box.min );
10697 this.max.max( box.max );
10698 return this;
10699 }
10700 applyMatrix4( matrix ) {
10701 if ( this.isEmpty() ) return this;
10702 _points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix );
10703 _points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix );
10704 _points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix );
10705 _points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix );
10706 _points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix );
10707 _points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix );
10708 _points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix );
10709 _points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );
10710 this.setFromPoints( _points );
10711 return this;
10712 }
10713 translate( offset ) {
10714 this.min.add( offset );
10715 this.max.add( offset );
10716 return this;
10717 }
10718 equals( box ) {
10719 return box.min.equals( this.min ) && box.max.equals( this.max );
10720 }
10721 }
10722 function satForAxes( axes, v0, v1, v2, extents ) {
10723 for ( let i = 0, j = axes.length - 3; i <= j; i += 3 ) {
10724 _testAxis.fromArray( axes, i );
10725 const r = extents.x * Math.abs( _testAxis.x ) + extents.y * Math.abs( _testAxis.y ) + extents.z * Math.abs( _testAxis.z );
10726 const p0 = v0.dot( _testAxis );
10727 const p1 = v1.dot( _testAxis );
10728 const p2 = v2.dot( _testAxis );
10729 if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) {
10730 return false;
10731 }
10732 }
10733 return true;
10734 }
10735 const _points = [
10736 new Vector3(),
10737 new Vector3(),
10738 new Vector3(),
10739 new Vector3(),
10740 new Vector3(),
10741 new Vector3(),
10742 new Vector3(),
10743 new Vector3()
10744 ];
10745 const _vector$1 = new Vector3();
10746 const _box = new Box3();
10747 const _v0 = new Vector3();
10748 const _v1 = new Vector3();
10749 const _v2 = new Vector3();
10750 const _f0 = new Vector3();
10751 const _f1 = new Vector3();
10752 const _f2 = new Vector3();
10753 const _center = new Vector3();
10754 const _extents = new Vector3();
10755 const _triangleNormal = new Vector3();
10756 const _testAxis = new Vector3();
10757 const _box$1 = new Box3();
10758 class Sphere {
10759 constructor( center, radius ) {
10760 this.center = ( center !== undefined ) ? center : new Vector3();
10761 this.radius = ( radius !== undefined ) ? radius : - 1;
10762 }
10763 set( center, radius ) {
10764 this.center.copy( center );
10765 this.radius = radius;
10766 return this;
10767 }
10768 setFromPoints( points, optionalCenter ) {
10769 const center = this.center;
10770 if ( optionalCenter !== undefined ) {
10771 center.copy( optionalCenter );
10772 } else {
10773 _box$1.setFromPoints( points ).getCenter( center );
10774 }
10775 let maxRadiusSq = 0;
10776 for ( let i = 0, il = points.length; i < il; i ++ ) {
10777 maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );
10778 }
10779 this.radius = Math.sqrt( maxRadiusSq );
10780 return this;
10781 }
10782 clone() {
10783 return new this.constructor().copy( this );
10784 }
10785 copy( sphere ) {
10786 this.center.copy( sphere.center );
10787 this.radius = sphere.radius;
10788 return this;
10789 }
10790 isEmpty() {
10791 return ( this.radius < 0 );
10792 }
10793 makeEmpty() {
10794 this.center.set( 0, 0, 0 );
10795 this.radius = - 1;
10796 return this;
10797 }
10798 containsPoint( point ) {
10799 return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );
10800 }
10801 distanceToPoint( point ) {
10802 return ( point.distanceTo( this.center ) - this.radius );
10803 }
10804 intersectsSphere( sphere ) {
10805 const radiusSum = this.radius + sphere.radius;
10806 return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );
10807 }
10808 intersectsBox( box ) {
10809 return box.intersectsSphere( this );
10810 }
10811 intersectsPlane( plane ) {
10812 return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius;
10813 }
10814 clampPoint( point, target ) {
10815 const deltaLengthSq = this.center.distanceToSquared( point );
10816 if ( target === undefined ) {
10817 console.warn( 'THREE.Sphere: .clampPoint() target is now required' );
10818 target = new Vector3();
10819 }
10820 target.copy( point );
10821 if ( deltaLengthSq > ( this.radius * this.radius ) ) {
10822 target.sub( this.center ).normalize();
10823 target.multiplyScalar( this.radius ).add( this.center );
10824 }
10825 return target;
10826 }
10827 getBoundingBox( target ) {
10828 if ( target === undefined ) {
10829 console.warn( 'THREE.Sphere: .getBoundingBox() target is now required' );
10830 target = new Box3();
10831 }
10832 if ( this.isEmpty() ) {
10833 target.makeEmpty();
10834 return target;
10835 }
10836 target.set( this.center, this.center );
10837 target.expandByScalar( this.radius );
10838 return target;
10839 }
10840 applyMatrix4( matrix ) {
10841 this.center.applyMatrix4( matrix );
10842 this.radius = this.radius * matrix.getMaxScaleOnAxis();
10843 return this;
10844 }
10845 translate( offset ) {
10846 this.center.add( offset );
10847 return this;
10848 }
10849 equals( sphere ) {
10850 return sphere.center.equals( this.center ) && ( sphere.radius === this.radius );
10851 }
10852 }
10853 const _vector$2 = new Vector3();
10854 const _segCenter = new Vector3();
10855 const _segDir = new Vector3();
10856 const _diff = new Vector3();
10857 const _edge1 = new Vector3();
10858 const _edge2 = new Vector3();
10859 const _normal = new Vector3();
10860 class Ray {
10861 constructor( origin, direction ) {
10862 this.origin = ( origin !== undefined ) ? origin : new Vector3();
10863 this.direction = ( direction !== undefined ) ? direction : new Vector3( 0, 0, - 1 );
10864 }
10865 set( origin, direction ) {
10866 this.origin.copy( origin );
10867 this.direction.copy( direction );
10868 return this;
10869 }
10870 clone() {
10871 return new this.constructor().copy( this );
10872 }
10873 copy( ray ) {
10874 this.origin.copy( ray.origin );
10875 this.direction.copy( ray.direction );
10876 return this;
10877 }
10878 at( t, target ) {
10879 if ( target === undefined ) {
10880 console.warn( 'THREE.Ray: .at() target is now required' );
10881 target = new Vector3();
10882 }
10883 return target.copy( this.direction ).multiplyScalar( t ).add( this.origin );
10884 }
10885 lookAt( v ) {
10886 this.direction.copy( v ).sub( this.origin ).normalize();
10887 return this;
10888 }
10889 recast( t ) {
10890 this.origin.copy( this.at( t, _vector$2 ) );
10891 return this;
10892 }
10893 closestPointToPoint( point, target ) {
10894 if ( target === undefined ) {
10895 console.warn( 'THREE.Ray: .closestPointToPoint() target is now required' );
10896 target = new Vector3();
10897 }
10898 target.subVectors( point, this.origin );
10899 const directionDistance = target.dot( this.direction );
10900 if ( directionDistance < 0 ) {
10901 return target.copy( this.origin );
10902 }
10903 return target.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
10904 }
10905 distanceToPoint( point ) {
10906 return Math.sqrt( this.distanceSqToPoint( point ) );
10907 }
10908 distanceSqToPoint( point ) {
10909 const directionDistance = _vector$2.subVectors( point, this.origin ).dot( this.direction );
10910 if ( directionDistance < 0 ) {
10911 return this.origin.distanceToSquared( point );
10912 }
10913 _vector$2.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
10914 return _vector$2.distanceToSquared( point );
10915 }
10916 distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {
10917 _segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );
10918 _segDir.copy( v1 ).sub( v0 ).normalize();
10919 _diff.copy( this.origin ).sub( _segCenter );
10920 const segExtent = v0.distanceTo( v1 ) * 0.5;
10921 const a01 = - this.direction.dot( _segDir );
10922 const b0 = _diff.dot( this.direction );
10923 const b1 = - _diff.dot( _segDir );
10924 const c = _diff.lengthSq();
10925 const det = Math.abs( 1 - a01 * a01 );
10926 let s0, s1, sqrDist, extDet;
10927 if ( det > 0 ) {
10928 s0 = a01 * b1 - b0;
10929 s1 = a01 * b0 - b1;
10930 extDet = segExtent * det;
10931 if ( s0 >= 0 ) {
10932 if ( s1 >= - extDet ) {
10933 if ( s1 <= extDet ) {
10934 const invDet = 1 / det;
10935 s0 *= invDet;
10936 s1 *= invDet;
10937 sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;
10938 } else {
10939 s1 = segExtent;
10940 s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
10941 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
10942 }
10943 } else {
10944 s1 = - segExtent;
10945 s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
10946 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
10947 }
10948 } else {
10949 if ( s1 <= - extDet ) {
10950 s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );
10951 s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
10952 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
10953 } else if ( s1 <= extDet ) {
10954 s0 = 0;
10955 s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );
10956 sqrDist = s1 * ( s1 + 2 * b1 ) + c;
10957 } else {
10958 s0 = Math.max( 0, - ( a01 * segExtent + b0 ) );
10959 s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
10960 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
10961 }
10962 }
10963 } else {
10964 s1 = ( a01 > 0 ) ? - segExtent : segExtent;
10965 s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
10966 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
10967 }
10968 if ( optionalPointOnRay ) {
10969 optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );
10970 }
10971 if ( optionalPointOnSegment ) {
10972 optionalPointOnSegment.copy( _segDir ).multiplyScalar( s1 ).add( _segCenter );
10973 }
10974 return sqrDist;
10975 }
10976 intersectSphere( sphere, target ) {
10977 _vector$2.subVectors( sphere.center, this.origin );
10978 const tca = _vector$2.dot( this.direction );
10979 const d2 = _vector$2.dot( _vector$2 ) - tca * tca;
10980 const radius2 = sphere.radius * sphere.radius;
10981 if ( d2 > radius2 ) return null;
10982 const thc = Math.sqrt( radius2 - d2 );
10983 const t0 = tca - thc;
10984 const t1 = tca + thc;
10985 if ( t0 < 0 && t1 < 0 ) return null;
10986 if ( t0 < 0 ) return this.at( t1, target );
10987 return this.at( t0, target );
10988 }
10989 intersectsSphere( sphere ) {
10990 return this.distanceSqToPoint( sphere.center ) <= ( sphere.radius * sphere.radius );
10991 }
10992 distanceToPlane( plane ) {
10993 const denominator = plane.normal.dot( this.direction );
10994 if ( denominator === 0 ) {
10995 if ( plane.distanceToPoint( this.origin ) === 0 ) {
10996 return 0;
10997 }
10998 return null;
10999 }
11000 const t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;
11001 return t >= 0 ? t : null;
11002 }
11003 intersectPlane( plane, target ) {
11004 const t = this.distanceToPlane( plane );
11005 if ( t === null ) {
11006 return null;
11007 }
11008 return this.at( t, target );
11009 }
11010 intersectsPlane( plane ) {
11011 const distToPoint = plane.distanceToPoint( this.origin );
11012 if ( distToPoint === 0 ) {
11013 return true;
11014 }
11015 const denominator = plane.normal.dot( this.direction );
11016 if ( denominator * distToPoint < 0 ) {
11017 return true;
11018 }
11019 return false;
11020 }
11021 intersectBox( box, target ) {
11022 let tmin, tmax, tymin, tymax, tzmin, tzmax;
11023 const invdirx = 1 / this.direction.x,
11024 invdiry = 1 / this.direction.y,
11025 invdirz = 1 / this.direction.z;
11026 const origin = this.origin;
11027 if ( invdirx >= 0 ) {
11028 tmin = ( box.min.x - origin.x ) * invdirx;
11029 tmax = ( box.max.x - origin.x ) * invdirx;
11030 } else {
11031 tmin = ( box.max.x - origin.x ) * invdirx;
11032 tmax = ( box.min.x - origin.x ) * invdirx;
11033 }
11034 if ( invdiry >= 0 ) {
11035 tymin = ( box.min.y - origin.y ) * invdiry;
11036 tymax = ( box.max.y - origin.y ) * invdiry;
11037 } else {
11038 tymin = ( box.max.y - origin.y ) * invdiry;
11039 tymax = ( box.min.y - origin.y ) * invdiry;
11040 }
11041 if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;
11042 if ( tymin > tmin || tmin !== tmin ) tmin = tymin;
11043 if ( tymax < tmax || tmax !== tmax ) tmax = tymax;
11044 if ( invdirz >= 0 ) {
11045 tzmin = ( box.min.z - origin.z ) * invdirz;
11046 tzmax = ( box.max.z - origin.z ) * invdirz;
11047 } else {
11048 tzmin = ( box.max.z - origin.z ) * invdirz;
11049 tzmax = ( box.min.z - origin.z ) * invdirz;
11050 }
11051 if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;
11052 if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;
11053 if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;
11054 if ( tmax < 0 ) return null;
11055 return this.at( tmin >= 0 ? tmin : tmax, target );
11056 }
11057 intersectsBox( box ) {
11058 return this.intersectBox( box, _vector$2 ) !== null;
11059 }
11060 intersectTriangle( a, b, c, backfaceCulling, target ) {
11061 _edge1.subVectors( b, a );
11062 _edge2.subVectors( c, a );
11063 _normal.crossVectors( _edge1, _edge2 );
11064 let DdN = this.direction.dot( _normal );
11065 let sign;
11066 if ( DdN > 0 ) {
11067 if ( backfaceCulling ) return null;
11068 sign = 1;
11069 } else if ( DdN < 0 ) {
11070 sign = - 1;
11071 DdN = - DdN;
11072 } else {
11073 return null;
11074 }
11075 _diff.subVectors( this.origin, a );
11076 const DdQxE2 = sign * this.direction.dot( _edge2.crossVectors( _diff, _edge2 ) );
11077 if ( DdQxE2 < 0 ) {
11078 return null;
11079 }
11080 const DdE1xQ = sign * this.direction.dot( _edge1.cross( _diff ) );
11081 if ( DdE1xQ < 0 ) {
11082 return null;
11083 }
11084 if ( DdQxE2 + DdE1xQ > DdN ) {
11085 return null;
11086 }
11087 const QdN = - sign * _diff.dot( _normal );
11088 if ( QdN < 0 ) {
11089 return null;
11090 }
11091 return this.at( QdN / DdN, target );
11092 }
11093 applyMatrix4( matrix4 ) {
11094 this.origin.applyMatrix4( matrix4 );
11095 this.direction.transformDirection( matrix4 );
11096 return this;
11097 }
11098 equals( ray ) {
11099 return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );
11100 }
11101 }
11102 class Matrix4 {
11103 constructor() {
11104 Object.defineProperty( this, 'isMatrix4', { value: true } );
11105 this.elements = [
11106 1, 0, 0, 0,
11107 0, 1, 0, 0,
11108 0, 0, 1, 0,
11109 0, 0, 0, 1
11110 ];
11111 if ( arguments.length > 0 ) {
11112 console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );
11113 }
11114 }
11115 set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
11116 const te = this.elements;
11117 te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;
11118 te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;
11119 te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;
11120 te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;
11121 return this;
11122 }
11123 identity() {
11124 this.set(
11125 1, 0, 0, 0,
11126 0, 1, 0, 0,
11127 0, 0, 1, 0,
11128 0, 0, 0, 1
11129 );
11130 return this;
11131 }
11132 clone() {
11133 return new Matrix4().fromArray( this.elements );
11134 }
11135 copy( m ) {
11136 const te = this.elements;
11137 const me = m.elements;
11138 te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ];
11139 te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ];
11140 te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ];
11141 te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ];
11142 return this;
11143 }
11144 copyPosition( m ) {
11145 const te = this.elements, me = m.elements;
11146 te[ 12 ] = me[ 12 ];
11147 te[ 13 ] = me[ 13 ];
11148 te[ 14 ] = me[ 14 ];
11149 return this;
11150 }
11151 extractBasis( xAxis, yAxis, zAxis ) {
11152 xAxis.setFromMatrixColumn( this, 0 );
11153 yAxis.setFromMatrixColumn( this, 1 );
11154 zAxis.setFromMatrixColumn( this, 2 );
11155 return this;
11156 }
11157 makeBasis( xAxis, yAxis, zAxis ) {
11158 this.set(
11159 xAxis.x, yAxis.x, zAxis.x, 0,
11160 xAxis.y, yAxis.y, zAxis.y, 0,
11161 xAxis.z, yAxis.z, zAxis.z, 0,
11162 0, 0, 0, 1
11163 );
11164 return this;
11165 }
11166 extractRotation( m ) {
11167 const te = this.elements;
11168 const me = m.elements;
11169 const scaleX = 1 / _v1$1.setFromMatrixColumn( m, 0 ).length();
11170 const scaleY = 1 / _v1$1.setFromMatrixColumn( m, 1 ).length();
11171 const scaleZ = 1 / _v1$1.setFromMatrixColumn( m, 2 ).length();
11172 te[ 0 ] = me[ 0 ] * scaleX;
11173 te[ 1 ] = me[ 1 ] * scaleX;
11174 te[ 2 ] = me[ 2 ] * scaleX;
11175 te[ 3 ] = 0;
11176 te[ 4 ] = me[ 4 ] * scaleY;
11177 te[ 5 ] = me[ 5 ] * scaleY;
11178 te[ 6 ] = me[ 6 ] * scaleY;
11179 te[ 7 ] = 0;
11180 te[ 8 ] = me[ 8 ] * scaleZ;
11181 te[ 9 ] = me[ 9 ] * scaleZ;
11182 te[ 10 ] = me[ 10 ] * scaleZ;
11183 te[ 11 ] = 0;
11184 te[ 12 ] = 0;
11185 te[ 13 ] = 0;
11186 te[ 14 ] = 0;
11187 te[ 15 ] = 1;
11188 return this;
11189 }
11190 makeRotationFromEuler( euler ) {
11191 if ( ! ( euler && euler.isEuler ) ) {
11192 console.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );
11193 }
11194 const te = this.elements;
11195 const x = euler.x, y = euler.y, z = euler.z;
11196 const a = Math.cos( x ), b = Math.sin( x );
11197 const c = Math.cos( y ), d = Math.sin( y );
11198 const e = Math.cos( z ), f = Math.sin( z );
11199 if ( euler.order === 'XYZ' ) {
11200 const ae = a * e, af = a * f, be = b * e, bf = b * f;
11201 te[ 0 ] = c * e;
11202 te[ 4 ] = - c * f;
11203 te[ 8 ] = d;
11204 te[ 1 ] = af + be * d;
11205 te[ 5 ] = ae - bf * d;
11206 te[ 9 ] = - b * c;
11207 te[ 2 ] = bf - ae * d;
11208 te[ 6 ] = be + af * d;
11209 te[ 10 ] = a * c;
11210 } else if ( euler.order === 'YXZ' ) {
11211 const ce = c * e, cf = c * f, de = d * e, df = d * f;
11212 te[ 0 ] = ce + df * b;
11213 te[ 4 ] = de * b - cf;
11214 te[ 8 ] = a * d;
11215 te[ 1 ] = a * f;
11216 te[ 5 ] = a * e;
11217 te[ 9 ] = - b;
11218 te[ 2 ] = cf * b - de;
11219 te[ 6 ] = df + ce * b;
11220 te[ 10 ] = a * c;
11221 } else if ( euler.order === 'ZXY' ) {
11222 const ce = c * e, cf = c * f, de = d * e, df = d * f;
11223 te[ 0 ] = ce - df * b;
11224 te[ 4 ] = - a * f;
11225 te[ 8 ] = de + cf * b;
11226 te[ 1 ] = cf + de * b;
11227 te[ 5 ] = a * e;
11228 te[ 9 ] = df - ce * b;
11229 te[ 2 ] = - a * d;
11230 te[ 6 ] = b;
11231 te[ 10 ] = a * c;
11232 } else if ( euler.order === 'ZYX' ) {
11233 const ae = a * e, af = a * f, be = b * e, bf = b * f;
11234 te[ 0 ] = c * e;
11235 te[ 4 ] = be * d - af;
11236 te[ 8 ] = ae * d + bf;
11237 te[ 1 ] = c * f;
11238 te[ 5 ] = bf * d + ae;
11239 te[ 9 ] = af * d - be;
11240 te[ 2 ] = - d;
11241 te[ 6 ] = b * c;
11242 te[ 10 ] = a * c;
11243 } else if ( euler.order === 'YZX' ) {
11244 const ac = a * c, ad = a * d, bc = b * c, bd = b * d;
11245 te[ 0 ] = c * e;
11246 te[ 4 ] = bd - ac * f;
11247 te[ 8 ] = bc * f + ad;
11248 te[ 1 ] = f;
11249 te[ 5 ] = a * e;
11250 te[ 9 ] = - b * e;
11251 te[ 2 ] = - d * e;
11252 te[ 6 ] = ad * f + bc;
11253 te[ 10 ] = ac - bd * f;
11254 } else if ( euler.order === 'XZY' ) {
11255 const ac = a * c, ad = a * d, bc = b * c, bd = b * d;
11256 te[ 0 ] = c * e;
11257 te[ 4 ] = - f;
11258 te[ 8 ] = d * e;
11259 te[ 1 ] = ac * f + bd;
11260 te[ 5 ] = a * e;
11261 te[ 9 ] = ad * f - bc;
11262 te[ 2 ] = bc * f - ad;
11263 te[ 6 ] = b * e;
11264 te[ 10 ] = bd * f + ac;
11265 }
11266 te[ 3 ] = 0;
11267 te[ 7 ] = 0;
11268 te[ 11 ] = 0;
11269 te[ 12 ] = 0;
11270 te[ 13 ] = 0;
11271 te[ 14 ] = 0;
11272 te[ 15 ] = 1;
11273 return this;
11274 }
11275 makeRotationFromQuaternion( q ) {
11276 return this.compose( _zero, q, _one );
11277 }
11278 lookAt( eye, target, up ) {
11279 const te = this.elements;
11280 _z.subVectors( eye, target );
11281 if ( _z.lengthSq() === 0 ) {
11282 _z.z = 1;
11283 }
11284 _z.normalize();
11285 _x.crossVectors( up, _z );
11286 if ( _x.lengthSq() === 0 ) {
11287 if ( Math.abs( up.z ) === 1 ) {
11288 _z.x += 0.0001;
11289 } else {
11290 _z.z += 0.0001;
11291 }
11292 _z.normalize();
11293 _x.crossVectors( up, _z );
11294 }
11295 _x.normalize();
11296 _y.crossVectors( _z, _x );
11297 te[ 0 ] = _x.x; te[ 4 ] = _y.x; te[ 8 ] = _z.x;
11298 te[ 1 ] = _x.y; te[ 5 ] = _y.y; te[ 9 ] = _z.y;
11299 te[ 2 ] = _x.z; te[ 6 ] = _y.z; te[ 10 ] = _z.z;
11300 return this;
11301 }
11302 multiply( m, n ) {
11303 if ( n !== undefined ) {
11304 console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );
11305 return this.multiplyMatrices( m, n );
11306 }
11307 return this.multiplyMatrices( this, m );
11308 }
11309 premultiply( m ) {
11310 return this.multiplyMatrices( m, this );
11311 }
11312 multiplyMatrices( a, b ) {
11313 const ae = a.elements;
11314 const be = b.elements;
11315 const te = this.elements;
11316 const a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];
11317 const a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];
11318 const a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];
11319 const a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];
11320 const b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];
11321 const b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];
11322 const b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];
11323 const b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];
11324 te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
11325 te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
11326 te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
11327 te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
11328 te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
11329 te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
11330 te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
11331 te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
11332 te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
11333 te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
11334 te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
11335 te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
11336 te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
11337 te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
11338 te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
11339 te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
11340 return this;
11341 }
11342 multiplyScalar( s ) {
11343 const te = this.elements;
11344 te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;
11345 te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;
11346 te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;
11347 te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;
11348 return this;
11349 }
11350 determinant() {
11351 const te = this.elements;
11352 const n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];
11353 const n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];
11354 const n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];
11355 const n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];
11356 return (
11357 n41 * (
11358 + n14 * n23 * n32
11359 - n13 * n24 * n32
11360 - n14 * n22 * n33
11361 + n12 * n24 * n33
11362 + n13 * n22 * n34
11363 - n12 * n23 * n34
11364 ) +
11365 n42 * (
11366 + n11 * n23 * n34
11367 - n11 * n24 * n33
11368 + n14 * n21 * n33
11369 - n13 * n21 * n34
11370 + n13 * n24 * n31
11371 - n14 * n23 * n31
11372 ) +
11373 n43 * (
11374 + n11 * n24 * n32
11375 - n11 * n22 * n34
11376 - n14 * n21 * n32
11377 + n12 * n21 * n34
11378 + n14 * n22 * n31
11379 - n12 * n24 * n31
11380 ) +
11381 n44 * (
11382 - n13 * n22 * n31
11383 - n11 * n23 * n32
11384 + n11 * n22 * n33
11385 + n13 * n21 * n32
11386 - n12 * n21 * n33
11387 + n12 * n23 * n31
11388 )
11389 );
11390 }
11391 transpose() {
11392 const te = this.elements;
11393 let tmp;
11394 tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;
11395 tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;
11396 tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;
11397 tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;
11398 tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;
11399 tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;
11400 return this;
11401 }
11402 setPosition( x, y, z ) {
11403 const te = this.elements;
11404 if ( x.isVector3 ) {
11405 te[ 12 ] = x.x;
11406 te[ 13 ] = x.y;
11407 te[ 14 ] = x.z;
11408 } else {
11409 te[ 12 ] = x;
11410 te[ 13 ] = y;
11411 te[ 14 ] = z;
11412 }
11413 return this;
11414 }
11415 getInverse( m, throwOnDegenerate ) {
11416 if ( throwOnDegenerate !== undefined ) {
11417 console.warn( "THREE.Matrix4: .getInverse() can no longer be configured to throw on degenerate." );
11418 }
11419 const te = this.elements,
11420 me = m.elements,
11421 n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],
11422 n12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],
11423 n13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],
11424 n14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],
11425 t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,
11426 t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,
11427 t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,
11428 t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
11429 const det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
11430 if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
11431 const detInv = 1 / det;
11432 te[ 0 ] = t11 * detInv;
11433 te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;
11434 te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;
11435 te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;
11436 te[ 4 ] = t12 * detInv;
11437 te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;
11438 te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;
11439 te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;
11440 te[ 8 ] = t13 * detInv;
11441 te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;
11442 te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;
11443 te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;
11444 te[ 12 ] = t14 * detInv;
11445 te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;
11446 te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;
11447 te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;
11448 return this;
11449 }
11450 scale( v ) {
11451 const te = this.elements;
11452 const x = v.x, y = v.y, z = v.z;
11453 te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;
11454 te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;
11455 te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;
11456 te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;
11457 return this;
11458 }
11459 getMaxScaleOnAxis() {
11460 const te = this.elements;
11461 const scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];
11462 const scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];
11463 const scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];
11464 return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );
11465 }
11466 makeTranslation( x, y, z ) {
11467 this.set(
11468 1, 0, 0, x,
11469 0, 1, 0, y,
11470 0, 0, 1, z,
11471 0, 0, 0, 1
11472 );
11473 return this;
11474 }
11475 makeRotationX( theta ) {
11476 const c = Math.cos( theta ), s = Math.sin( theta );
11477 this.set(
11478 1, 0, 0, 0,
11479 0, c, - s, 0,
11480 0, s, c, 0,
11481 0, 0, 0, 1
11482 );
11483 return this;
11484 }
11485 makeRotationY( theta ) {
11486 const c = Math.cos( theta ), s = Math.sin( theta );
11487 this.set(
11488 c, 0, s, 0,
11489 0, 1, 0, 0,
11490 - s, 0, c, 0,
11491 0, 0, 0, 1
11492 );
11493 return this;
11494 }
11495 makeRotationZ( theta ) {
11496 const c = Math.cos( theta ), s = Math.sin( theta );
11497 this.set(
11498 c, - s, 0, 0,
11499 s, c, 0, 0,
11500 0, 0, 1, 0,
11501 0, 0, 0, 1
11502 );
11503 return this;
11504 }
11505 makeRotationAxis( axis, angle ) {
11506 const c = Math.cos( angle );
11507 const s = Math.sin( angle );
11508 const t = 1 - c;
11509 const x = axis.x, y = axis.y, z = axis.z;
11510 const tx = t * x, ty = t * y;
11511 this.set(
11512 tx * x + c, tx * y - s * z, tx * z + s * y, 0,
11513 tx * y + s * z, ty * y + c, ty * z - s * x, 0,
11514 tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
11515 0, 0, 0, 1
11516 );
11517 return this;
11518 }
11519 makeScale( x, y, z ) {
11520 this.set(
11521 x, 0, 0, 0,
11522 0, y, 0, 0,
11523 0, 0, z, 0,
11524 0, 0, 0, 1
11525 );
11526 return this;
11527 }
11528 makeShear( x, y, z ) {
11529 this.set(
11530 1, y, z, 0,
11531 x, 1, z, 0,
11532 x, y, 1, 0,
11533 0, 0, 0, 1
11534 );
11535 return this;
11536 }
11537 compose( position, quaternion, scale ) {
11538 const te = this.elements;
11539 const x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w;
11540 const x2 = x + x, y2 = y + y, z2 = z + z;
11541 const xx = x * x2, xy = x * y2, xz = x * z2;
11542 const yy = y * y2, yz = y * z2, zz = z * z2;
11543 const wx = w * x2, wy = w * y2, wz = w * z2;
11544 const sx = scale.x, sy = scale.y, sz = scale.z;
11545 te[ 0 ] = ( 1 - ( yy + zz ) ) * sx;
11546 te[ 1 ] = ( xy + wz ) * sx;
11547 te[ 2 ] = ( xz - wy ) * sx;
11548 te[ 3 ] = 0;
11549 te[ 4 ] = ( xy - wz ) * sy;
11550 te[ 5 ] = ( 1 - ( xx + zz ) ) * sy;
11551 te[ 6 ] = ( yz + wx ) * sy;
11552 te[ 7 ] = 0;
11553 te[ 8 ] = ( xz + wy ) * sz;
11554 te[ 9 ] = ( yz - wx ) * sz;
11555 te[ 10 ] = ( 1 - ( xx + yy ) ) * sz;
11556 te[ 11 ] = 0;
11557 te[ 12 ] = position.x;
11558 te[ 13 ] = position.y;
11559 te[ 14 ] = position.z;
11560 te[ 15 ] = 1;
11561 return this;
11562 }
11563 decompose( position, quaternion, scale ) {
11564 const te = this.elements;
11565 let sx = _v1$1.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();
11566 const sy = _v1$1.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();
11567 const sz = _v1$1.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();
11568 const det = this.determinant();
11569 if ( det < 0 ) sx = - sx;
11570 position.x = te[ 12 ];
11571 position.y = te[ 13 ];
11572 position.z = te[ 14 ];
11573 _m1.copy( this );
11574 const invSX = 1 / sx;
11575 const invSY = 1 / sy;
11576 const invSZ = 1 / sz;
11577 _m1.elements[ 0 ] *= invSX;
11578 _m1.elements[ 1 ] *= invSX;
11579 _m1.elements[ 2 ] *= invSX;
11580 _m1.elements[ 4 ] *= invSY;
11581 _m1.elements[ 5 ] *= invSY;
11582 _m1.elements[ 6 ] *= invSY;
11583 _m1.elements[ 8 ] *= invSZ;
11584 _m1.elements[ 9 ] *= invSZ;
11585 _m1.elements[ 10 ] *= invSZ;
11586 quaternion.setFromRotationMatrix( _m1 );
11587 scale.x = sx;
11588 scale.y = sy;
11589 scale.z = sz;
11590 return this;
11591 }
11592 makePerspective( left, right, top, bottom, near, far ) {
11593 if ( far === undefined ) {
11594 console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );
11595 }
11596 const te = this.elements;
11597 const x = 2 * near / ( right - left );
11598 const y = 2 * near / ( top - bottom );
11599 const a = ( right + left ) / ( right - left );
11600 const b = ( top + bottom ) / ( top - bottom );
11601 const c = - ( far + near ) / ( far - near );
11602 const d = - 2 * far * near / ( far - near );
11603 te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0;
11604 te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0;
11605 te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d;
11606 te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0;
11607 return this;
11608 }
11609 makeOrthographic( left, right, top, bottom, near, far ) {
11610 const te = this.elements;
11611 const w = 1.0 / ( right - left );
11612 const h = 1.0 / ( top - bottom );
11613 const p = 1.0 / ( far - near );
11614 const x = ( right + left ) * w;
11615 const y = ( top + bottom ) * h;
11616 const z = ( far + near ) * p;
11617 te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x;
11618 te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y;
11619 te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 * p; te[ 14 ] = - z;
11620 te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1;
11621 return this;
11622 }
11623 equals( matrix ) {
11624 const te = this.elements;
11625 const me = matrix.elements;
11626 for ( let i = 0; i < 16; i ++ ) {
11627 if ( te[ i ] !== me[ i ] ) return false;
11628 }
11629 return true;
11630 }
11631 fromArray( array, offset ) {
11632 if ( offset === undefined ) offset = 0;
11633 for ( let i = 0; i < 16; i ++ ) {
11634 this.elements[ i ] = array[ i + offset ];
11635 }
11636 return this;
11637 }
11638 toArray( array, offset ) {
11639 if ( array === undefined ) array = [];
11640 if ( offset === undefined ) offset = 0;
11641 const te = this.elements;
11642 array[ offset ] = te[ 0 ];
11643 array[ offset + 1 ] = te[ 1 ];
11644 array[ offset + 2 ] = te[ 2 ];
11645 array[ offset + 3 ] = te[ 3 ];
11646 array[ offset + 4 ] = te[ 4 ];
11647 array[ offset + 5 ] = te[ 5 ];
11648 array[ offset + 6 ] = te[ 6 ];
11649 array[ offset + 7 ] = te[ 7 ];
11650 array[ offset + 8 ] = te[ 8 ];
11651 array[ offset + 9 ] = te[ 9 ];
11652 array[ offset + 10 ] = te[ 10 ];
11653 array[ offset + 11 ] = te[ 11 ];
11654 array[ offset + 12 ] = te[ 12 ];
11655 array[ offset + 13 ] = te[ 13 ];
11656 array[ offset + 14 ] = te[ 14 ];
11657 array[ offset + 15 ] = te[ 15 ];
11658 return array;
11659 }
11660 }
11661 const _v1$1 = new Vector3();
11662 const _m1 = new Matrix4();
11663 const _zero = new Vector3( 0, 0, 0 );
11664 const _one = new Vector3( 1, 1, 1 );
11665 const _x = new Vector3();
11666 const _y = new Vector3();
11667 const _z = new Vector3();
11668 class Euler {
11669 constructor( x = 0, y = 0, z = 0, order = Euler.DefaultOrder ) {
11670 Object.defineProperty( this, 'isEuler', { value: true } );
11671 this._x = x;
11672 this._y = y;
11673 this._z = z;
11674 this._order = order;
11675 }
11676 get x() {
11677 return this._x;
11678 }
11679 set x( value ) {
11680 this._x = value;
11681 this._onChangeCallback();
11682 }
11683 get y() {
11684 return this._y;
11685 }
11686 set y( value ) {
11687 this._y = value;
11688 this._onChangeCallback();
11689 }
11690 get z() {
11691 return this._z;
11692 }
11693 set z( value ) {
11694 this._z = value;
11695 this._onChangeCallback();
11696 }
11697 get order() {
11698 return this._order;
11699 }
11700 set order( value ) {
11701 this._order = value;
11702 this._onChangeCallback();
11703 }
11704 set( x, y, z, order ) {
11705 this._x = x;
11706 this._y = y;
11707 this._z = z;
11708 this._order = order || this._order;
11709 this._onChangeCallback();
11710 return this;
11711 }
11712 clone() {
11713 return new this.constructor( this._x, this._y, this._z, this._order );
11714 }
11715 copy( euler ) {
11716 this._x = euler._x;
11717 this._y = euler._y;
11718 this._z = euler._z;
11719 this._order = euler._order;
11720 this._onChangeCallback();
11721 return this;
11722 }
11723 setFromRotationMatrix( m, order, update ) {
11724 const clamp = MathUtils.clamp;
11725 const te = m.elements;
11726 const m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];
11727 const m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];
11728 const m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];
11729 order = order || this._order;
11730 switch ( order ) {
11731 case 'XYZ':
11732 this._y = Math.asin( clamp( m13, - 1, 1 ) );
11733 if ( Math.abs( m13 ) < 0.9999999 ) {
11734 this._x = Math.atan2( - m23, m33 );
11735 this._z = Math.atan2( - m12, m11 );
11736 } else {
11737 this._x = Math.atan2( m32, m22 );
11738 this._z = 0;
11739 }
11740 break;
11741 case 'YXZ':
11742 this._x = Math.asin( - clamp( m23, - 1, 1 ) );
11743 if ( Math.abs( m23 ) < 0.9999999 ) {
11744 this._y = Math.atan2( m13, m33 );
11745 this._z = Math.atan2( m21, m22 );
11746 } else {
11747 this._y = Math.atan2( - m31, m11 );
11748 this._z = 0;
11749 }
11750 break;
11751 case 'ZXY':
11752 this._x = Math.asin( clamp( m32, - 1, 1 ) );
11753 if ( Math.abs( m32 ) < 0.9999999 ) {
11754 this._y = Math.atan2( - m31, m33 );
11755 this._z = Math.atan2( - m12, m22 );
11756 } else {
11757 this._y = 0;
11758 this._z = Math.atan2( m21, m11 );
11759 }
11760 break;
11761 case 'ZYX':
11762 this._y = Math.asin( - clamp( m31, - 1, 1 ) );
11763 if ( Math.abs( m31 ) < 0.9999999 ) {
11764 this._x = Math.atan2( m32, m33 );
11765 this._z = Math.atan2( m21, m11 );
11766 } else {
11767 this._x = 0;
11768 this._z = Math.atan2( - m12, m22 );
11769 }
11770 break;
11771 case 'YZX':
11772 this._z = Math.asin( clamp( m21, - 1, 1 ) );
11773 if ( Math.abs( m21 ) < 0.9999999 ) {
11774 this._x = Math.atan2( - m23, m22 );
11775 this._y = Math.atan2( - m31, m11 );
11776 } else {
11777 this._x = 0;
11778 this._y = Math.atan2( m13, m33 );
11779 }
11780 break;
11781 case 'XZY':
11782 this._z = Math.asin( - clamp( m12, - 1, 1 ) );
11783 if ( Math.abs( m12 ) < 0.9999999 ) {
11784 this._x = Math.atan2( m32, m22 );
11785 this._y = Math.atan2( m13, m11 );
11786 } else {
11787 this._x = Math.atan2( - m23, m33 );
11788 this._y = 0;
11789 }
11790 break;
11791 default:
11792 console.warn( 'THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order );
11793 }
11794 this._order = order;
11795 if ( update !== false ) this._onChangeCallback();
11796 return this;
11797 }
11798 setFromQuaternion( q, order, update ) {
11799 _matrix.makeRotationFromQuaternion( q );
11800 return this.setFromRotationMatrix( _matrix, order, update );
11801 }
11802 setFromVector3( v, order ) {
11803 return this.set( v.x, v.y, v.z, order || this._order );
11804 }
11805 reorder( newOrder ) {
11806 _quaternion$1.setFromEuler( this );
11807 return this.setFromQuaternion( _quaternion$1, newOrder );
11808 }
11809 equals( euler ) {
11810 return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );
11811 }
11812 fromArray( array ) {
11813 this._x = array[ 0 ];
11814 this._y = array[ 1 ];
11815 this._z = array[ 2 ];
11816 if ( array[ 3 ] !== undefined ) this._order = array[ 3 ];
11817 this._onChangeCallback();
11818 return this;
11819 }
11820 toArray( array, offset ) {
11821 if ( array === undefined ) array = [];
11822 if ( offset === undefined ) offset = 0;
11823 array[ offset ] = this._x;
11824 array[ offset + 1 ] = this._y;
11825 array[ offset + 2 ] = this._z;
11826 array[ offset + 3 ] = this._order;
11827 return array;
11828 }
11829 toVector3( optionalResult ) {
11830 if ( optionalResult ) {
11831 return optionalResult.set( this._x, this._y, this._z );
11832 } else {
11833 return new Vector3( this._x, this._y, this._z );
11834 }
11835 }
11836 _onChange( callback ) {
11837 this._onChangeCallback = callback;
11838 return this;
11839 }
11840 _onChangeCallback() {}
11841 }
11842 Euler.DefaultOrder = 'XYZ';
11843 Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];
11844 const _matrix = new Matrix4();
11845 const _quaternion$1 = new Quaternion();
11846 class Layers {
11847 constructor() {
11848 this.mask = 1 | 0;
11849 }
11850 set( channel ) {
11851 this.mask = 1 << channel | 0;
11852 }
11853 enable( channel ) {
11854 this.mask |= 1 << channel | 0;
11855 }
11856 enableAll() {
11857 this.mask = 0xffffffff | 0;
11858 }
11859 toggle( channel ) {
11860 this.mask ^= 1 << channel | 0;
11861 }
11862 disable( channel ) {
11863 this.mask &= ~ ( 1 << channel | 0 );
11864 }
11865 disableAll() {
11866 this.mask = 0;
11867 }
11868 test( layers ) {
11869 return ( this.mask & layers.mask ) !== 0;
11870 }
11871 }
11872 let _object3DId = 0;
11873 const _v1$2 = new Vector3();
11874 const _q1 = new Quaternion();
11875 const _m1$1 = new Matrix4();
11876 const _target = new Vector3();
11877 const _position = new Vector3();
11878 const _scale = new Vector3();
11879 const _quaternion$2 = new Quaternion();
11880 const _xAxis = new Vector3( 1, 0, 0 );
11881 const _yAxis = new Vector3( 0, 1, 0 );
11882 const _zAxis = new Vector3( 0, 0, 1 );
11883 const _addedEvent = { type: 'added' };
11884 const _removedEvent = { type: 'removed' };
11885 function Object3D() {
11886 Object.defineProperty( this, 'id', { value: _object3DId ++ } );
11887 this.uuid = MathUtils.generateUUID();
11888 this.name = '';
11889 this.type = 'Object3D';
11890 this.parent = null;
11891 this.children = [];
11892 this.up = Object3D.DefaultUp.clone();
11893 const position = new Vector3();
11894 const rotation = new Euler();
11895 const quaternion = new Quaternion();
11896 const scale = new Vector3( 1, 1, 1 );
11897 function onRotationChange() {
11898 quaternion.setFromEuler( rotation, false );
11899 }
11900 function onQuaternionChange() {
11901 rotation.setFromQuaternion( quaternion, undefined, false );
11902 }
11903 rotation._onChange( onRotationChange );
11904 quaternion._onChange( onQuaternionChange );
11905 Object.defineProperties( this, {
11906 position: {
11907 configurable: true,
11908 enumerable: true,
11909 value: position
11910 },
11911 rotation: {
11912 configurable: true,
11913 enumerable: true,
11914 value: rotation
11915 },
11916 quaternion: {
11917 configurable: true,
11918 enumerable: true,
11919 value: quaternion
11920 },
11921 scale: {
11922 configurable: true,
11923 enumerable: true,
11924 value: scale
11925 },
11926 modelViewMatrix: {
11927 value: new Matrix4()
11928 },
11929 normalMatrix: {
11930 value: new Matrix3()
11931 }
11932 } );
11933 this.matrix = new Matrix4();
11934 this.matrixWorld = new Matrix4();
11935 this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;
11936 this.matrixWorldNeedsUpdate = false;
11937 this.layers = new Layers();
11938 this.visible = true;
11939 this.castShadow = false;
11940 this.receiveShadow = false;
11941 this.frustumCulled = true;
11942 this.renderOrder = 0;
11943 this.userData = {};
11944 }
11945 Object3D.DefaultUp = new Vector3( 0, 1, 0 );
11946 Object3D.DefaultMatrixAutoUpdate = true;
11947 Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
11948 constructor: Object3D,
11949 isObject3D: true,
11950 onBeforeRender: function () {},
11951 onAfterRender: function () {},
11952 applyMatrix4: function ( matrix ) {
11953 if ( this.matrixAutoUpdate ) this.updateMatrix();
11954 this.matrix.premultiply( matrix );
11955 this.matrix.decompose( this.position, this.quaternion, this.scale );
11956 },
11957 applyQuaternion: function ( q ) {
11958 this.quaternion.premultiply( q );
11959 return this;
11960 },
11961 setRotationFromAxisAngle: function ( axis, angle ) {
11962 this.quaternion.setFromAxisAngle( axis, angle );
11963 },
11964 setRotationFromEuler: function ( euler ) {
11965 this.quaternion.setFromEuler( euler, true );
11966 },
11967 setRotationFromMatrix: function ( m ) {
11968 this.quaternion.setFromRotationMatrix( m );
11969 },
11970 setRotationFromQuaternion: function ( q ) {
11971 this.quaternion.copy( q );
11972 },
11973 rotateOnAxis: function ( axis, angle ) {
11974 _q1.setFromAxisAngle( axis, angle );
11975 this.quaternion.multiply( _q1 );
11976 return this;
11977 },
11978 rotateOnWorldAxis: function ( axis, angle ) {
11979 _q1.setFromAxisAngle( axis, angle );
11980 this.quaternion.premultiply( _q1 );
11981 return this;
11982 },
11983 rotateX: function ( angle ) {
11984 return this.rotateOnAxis( _xAxis, angle );
11985 },
11986 rotateY: function ( angle ) {
11987 return this.rotateOnAxis( _yAxis, angle );
11988 },
11989 rotateZ: function ( angle ) {
11990 return this.rotateOnAxis( _zAxis, angle );
11991 },
11992 translateOnAxis: function ( axis, distance ) {
11993 _v1$2.copy( axis ).applyQuaternion( this.quaternion );
11994 this.position.add( _v1$2.multiplyScalar( distance ) );
11995 return this;
11996 },
11997 translateX: function ( distance ) {
11998 return this.translateOnAxis( _xAxis, distance );
11999 },
12000 translateY: function ( distance ) {
12001 return this.translateOnAxis( _yAxis, distance );
12002 },
12003 translateZ: function ( distance ) {
12004 return this.translateOnAxis( _zAxis, distance );
12005 },
12006 localToWorld: function ( vector ) {
12007 return vector.applyMatrix4( this.matrixWorld );
12008 },
12009 worldToLocal: function ( vector ) {
12010 return vector.applyMatrix4( _m1$1.getInverse( this.matrixWorld ) );
12011 },
12012 lookAt: function ( x, y, z ) {
12013 if ( x.isVector3 ) {
12014 _target.copy( x );
12015 } else {
12016 _target.set( x, y, z );
12017 }
12018 const parent = this.parent;
12019 this.updateWorldMatrix( true, false );
12020 _position.setFromMatrixPosition( this.matrixWorld );
12021 if ( this.isCamera || this.isLight ) {
12022 _m1$1.lookAt( _position, _target, this.up );
12023 } else {
12024 _m1$1.lookAt( _target, _position, this.up );
12025 }
12026 this.quaternion.setFromRotationMatrix( _m1$1 );
12027 if ( parent ) {
12028 _m1$1.extractRotation( parent.matrixWorld );
12029 _q1.setFromRotationMatrix( _m1$1 );
12030 this.quaternion.premultiply( _q1.inverse() );
12031 }
12032 },
12033 add: function ( object ) {
12034 if ( arguments.length > 1 ) {
12035 for ( let i = 0; i < arguments.length; i ++ ) {
12036 this.add( arguments[ i ] );
12037 }
12038 return this;
12039 }
12040 if ( object === this ) {
12041 console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object );
12042 return this;
12043 }
12044 if ( ( object && object.isObject3D ) ) {
12045 if ( object.parent !== null ) {
12046 object.parent.remove( object );
12047 }
12048 object.parent = this;
12049 this.children.push( object );
12050 object.dispatchEvent( _addedEvent );
12051 } else {
12052 console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object );
12053 }
12054 return this;
12055 },
12056 remove: function ( object ) {
12057 if ( arguments.length > 1 ) {
12058 for ( let i = 0; i < arguments.length; i ++ ) {
12059 this.remove( arguments[ i ] );
12060 }
12061 return this;
12062 }
12063 const index = this.children.indexOf( object );
12064 if ( index !== - 1 ) {
12065 object.parent = null;
12066 this.children.splice( index, 1 );
12067 object.dispatchEvent( _removedEvent );
12068 }
12069 return this;
12070 },
12071 attach: function ( object ) {
12072 this.updateWorldMatrix( true, false );
12073 _m1$1.getInverse( this.matrixWorld );
12074 if ( object.parent !== null ) {
12075 object.parent.updateWorldMatrix( true, false );
12076 _m1$1.multiply( object.parent.matrixWorld );
12077 }
12078 object.applyMatrix4( _m1$1 );
12079 object.updateWorldMatrix( false, false );
12080 this.add( object );
12081 return this;
12082 },
12083 getObjectById: function ( id ) {
12084 return this.getObjectByProperty( 'id', id );
12085 },
12086 getObjectByName: function ( name ) {
12087 return this.getObjectByProperty( 'name', name );
12088 },
12089 getObjectByProperty: function ( name, value ) {
12090 if ( this[ name ] === value ) return this;
12091 for ( let i = 0, l = this.children.length; i < l; i ++ ) {
12092 const child = this.children[ i ];
12093 const object = child.getObjectByProperty( name, value );
12094 if ( object !== undefined ) {
12095 return object;
12096 }
12097 }
12098 return undefined;
12099 },
12100 getWorldPosition: function ( target ) {
12101 if ( target === undefined ) {
12102 console.warn( 'THREE.Object3D: .getWorldPosition() target is now required' );
12103 target = new Vector3();
12104 }
12105 this.updateMatrixWorld( true );
12106 return target.setFromMatrixPosition( this.matrixWorld );
12107 },
12108 getWorldQuaternion: function ( target ) {
12109 if ( target === undefined ) {
12110 console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' );
12111 target = new Quaternion();
12112 }
12113 this.updateMatrixWorld( true );
12114 this.matrixWorld.decompose( _position, target, _scale );
12115 return target;
12116 },
12117 getWorldScale: function ( target ) {
12118 if ( target === undefined ) {
12119 console.warn( 'THREE.Object3D: .getWorldScale() target is now required' );
12120 target = new Vector3();
12121 }
12122 this.updateMatrixWorld( true );
12123 this.matrixWorld.decompose( _position, _quaternion$2, target );
12124 return target;
12125 },
12126 getWorldDirection: function ( target ) {
12127 if ( target === undefined ) {
12128 console.warn( 'THREE.Object3D: .getWorldDirection() target is now required' );
12129 target = new Vector3();
12130 }
12131 this.updateMatrixWorld( true );
12132 const e = this.matrixWorld.elements;
12133 return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize();
12134 },
12135 raycast: function () {},
12136 traverse: function ( callback ) {
12137 callback( this );
12138 const children = this.children;
12139 for ( let i = 0, l = children.length; i < l; i ++ ) {
12140 children[ i ].traverse( callback );
12141 }
12142 },
12143 traverseVisible: function ( callback ) {
12144 if ( this.visible === false ) return;
12145 callback( this );
12146 const children = this.children;
12147 for ( let i = 0, l = children.length; i < l; i ++ ) {
12148 children[ i ].traverseVisible( callback );
12149 }
12150 },
12151 traverseAncestors: function ( callback ) {
12152 const parent = this.parent;
12153 if ( parent !== null ) {
12154 callback( parent );
12155 parent.traverseAncestors( callback );
12156 }
12157 },
12158 updateMatrix: function () {
12159 this.matrix.compose( this.position, this.quaternion, this.scale );
12160 this.matrixWorldNeedsUpdate = true;
12161 },
12162 updateMatrixWorld: function ( force ) {
12163 if ( this.matrixAutoUpdate ) this.updateMatrix();
12164 if ( this.matrixWorldNeedsUpdate || force ) {
12165 if ( this.parent === null ) {
12166 this.matrixWorld.copy( this.matrix );
12167 } else {
12168 this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
12169 }
12170 this.matrixWorldNeedsUpdate = false;
12171 force = true;
12172 }
12173 const children = this.children;
12174 for ( let i = 0, l = children.length; i < l; i ++ ) {
12175 children[ i ].updateMatrixWorld( force );
12176 }
12177 },
12178 updateWorldMatrix: function ( updateParents, updateChildren ) {
12179 const parent = this.parent;
12180 if ( updateParents === true && parent !== null ) {
12181 parent.updateWorldMatrix( true, false );
12182 }
12183 if ( this.matrixAutoUpdate ) this.updateMatrix();
12184 if ( this.parent === null ) {
12185 this.matrixWorld.copy( this.matrix );
12186 } else {
12187 this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
12188 }
12189 if ( updateChildren === true ) {
12190 const children = this.children;
12191 for ( let i = 0, l = children.length; i < l; i ++ ) {
12192 children[ i ].updateWorldMatrix( false, true );
12193 }
12194 }
12195 },
12196 toJSON: function ( meta ) {
12197 const isRootObject = ( meta === undefined || typeof meta === 'string' );
12198 const output = {};
12199 if ( isRootObject ) {
12200 meta = {
12201 geometries: {},
12202 materials: {},
12203 textures: {},
12204 images: {},
12205 shapes: {}
12206 };
12207 output.metadata = {
12208 version: 4.5,
12209 type: 'Object',
12210 generator: 'Object3D.toJSON'
12211 };
12212 }
12213 const object = {};
12214 object.uuid = this.uuid;
12215 object.type = this.type;
12216 if ( this.name !== '' ) object.name = this.name;
12217 if ( this.castShadow === true ) object.castShadow = true;
12218 if ( this.receiveShadow === true ) object.receiveShadow = true;
12219 if ( this.visible === false ) object.visible = false;
12220 if ( this.frustumCulled === false ) object.frustumCulled = false;
12221 if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder;
12222 if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;
12223 object.layers = this.layers.mask;
12224 object.matrix = this.matrix.toArray();
12225 if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false;
12226 if ( this.isInstancedMesh ) {
12227 object.type = 'InstancedMesh';
12228 object.count = this.count;
12229 object.instanceMatrix = this.instanceMatrix.toJSON();
12230 }
12231 function serialize( library, element ) {
12232 if ( library[ element.uuid ] === undefined ) {
12233 library[ element.uuid ] = element.toJSON( meta );
12234 }
12235 return element.uuid;
12236 }
12237 if ( this.isMesh || this.isLine || this.isPoints ) {
12238 object.geometry = serialize( meta.geometries, this.geometry );
12239 const parameters = this.geometry.parameters;
12240 if ( parameters !== undefined && parameters.shapes !== undefined ) {
12241 const shapes = parameters.shapes;
12242 if ( Array.isArray( shapes ) ) {
12243 for ( let i = 0, l = shapes.length; i < l; i ++ ) {
12244 const shape = shapes[ i ];
12245 serialize( meta.shapes, shape );
12246 }
12247 } else {
12248 serialize( meta.shapes, shapes );
12249 }
12250 }
12251 }
12252 if ( this.material !== undefined ) {
12253 if ( Array.isArray( this.material ) ) {
12254 const uuids = [];
12255 for ( let i = 0, l = this.material.length; i < l; i ++ ) {
12256 uuids.push( serialize( meta.materials, this.material[ i ] ) );
12257 }
12258 object.material = uuids;
12259 } else {
12260 object.material = serialize( meta.materials, this.material );
12261 }
12262 }
12263 if ( this.children.length > 0 ) {
12264 object.children = [];
12265 for ( let i = 0; i < this.children.length; i ++ ) {
12266 object.children.push( this.children[ i ].toJSON( meta ).object );
12267 }
12268 }
12269 if ( isRootObject ) {
12270 const geometries = extractFromCache( meta.geometries );
12271 const materials = extractFromCache( meta.materials );
12272 const textures = extractFromCache( meta.textures );
12273 const images = extractFromCache( meta.images );
12274 const shapes = extractFromCache( meta.shapes );
12275 if ( geometries.length > 0 ) output.geometries = geometries;
12276 if ( materials.length > 0 ) output.materials = materials;
12277 if ( textures.length > 0 ) output.textures = textures;
12278 if ( images.length > 0 ) output.images = images;
12279 if ( shapes.length > 0 ) output.shapes = shapes;
12280 }
12281 output.object = object;
12282 return output;
12283 function extractFromCache( cache ) {
12284 const values = [];
12285 for ( const key in cache ) {
12286 const data = cache[ key ];
12287 delete data.metadata;
12288 values.push( data );
12289 }
12290 return values;
12291 }
12292 },
12293 clone: function ( recursive ) {
12294 return new this.constructor().copy( this, recursive );
12295 },
12296 copy: function ( source, recursive ) {
12297 if ( recursive === undefined ) recursive = true;
12298 this.name = source.name;
12299 this.up.copy( source.up );
12300 this.position.copy( source.position );
12301 this.rotation.order = source.rotation.order;
12302 this.quaternion.copy( source.quaternion );
12303 this.scale.copy( source.scale );
12304 this.matrix.copy( source.matrix );
12305 this.matrixWorld.copy( source.matrixWorld );
12306 this.matrixAutoUpdate = source.matrixAutoUpdate;
12307 this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
12308 this.layers.mask = source.layers.mask;
12309 this.visible = source.visible;
12310 this.castShadow = source.castShadow;
12311 this.receiveShadow = source.receiveShadow;
12312 this.frustumCulled = source.frustumCulled;
12313 this.renderOrder = source.renderOrder;
12314 this.userData = JSON.parse( JSON.stringify( source.userData ) );
12315 if ( recursive === true ) {
12316 for ( let i = 0; i < source.children.length; i ++ ) {
12317 const child = source.children[ i ];
12318 this.add( child.clone() );
12319 }
12320 }
12321 return this;
12322 }
12323 } );
12324 const _vector1 = new Vector3();
12325 const _vector2 = new Vector3();
12326 const _normalMatrix = new Matrix3();
12327 class Plane {
12328 constructor( normal, constant ) {
12329 Object.defineProperty( this, 'isPlane', { value: true } );
12330 this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );
12331 this.constant = ( constant !== undefined ) ? constant : 0;
12332 }
12333 set( normal, constant ) {
12334 this.normal.copy( normal );
12335 this.constant = constant;
12336 return this;
12337 }
12338 setComponents( x, y, z, w ) {
12339 this.normal.set( x, y, z );
12340 this.constant = w;
12341 return this;
12342 }
12343 setFromNormalAndCoplanarPoint( normal, point ) {
12344 this.normal.copy( normal );
12345 this.constant = - point.dot( this.normal );
12346 return this;
12347 }
12348 setFromCoplanarPoints( a, b, c ) {
12349 const normal = _vector1.subVectors( c, b ).cross( _vector2.subVectors( a, b ) ).normalize();
12350 this.setFromNormalAndCoplanarPoint( normal, a );
12351 return this;
12352 }
12353 clone() {
12354 return new this.constructor().copy( this );
12355 }
12356 copy( plane ) {
12357 this.normal.copy( plane.normal );
12358 this.constant = plane.constant;
12359 return this;
12360 }
12361 normalize() {
12362 const inverseNormalLength = 1.0 / this.normal.length();
12363 this.normal.multiplyScalar( inverseNormalLength );
12364 this.constant *= inverseNormalLength;
12365 return this;
12366 }
12367 negate() {
12368 this.constant *= - 1;
12369 this.normal.negate();
12370 return this;
12371 }
12372 distanceToPoint( point ) {
12373 return this.normal.dot( point ) + this.constant;
12374 }
12375 distanceToSphere( sphere ) {
12376 return this.distanceToPoint( sphere.center ) - sphere.radius;
12377 }
12378 projectPoint( point, target ) {
12379 if ( target === undefined ) {
12380 console.warn( 'THREE.Plane: .projectPoint() target is now required' );
12381 target = new Vector3();
12382 }
12383 return target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point );
12384 }
12385 intersectLine( line, target ) {
12386 if ( target === undefined ) {
12387 console.warn( 'THREE.Plane: .intersectLine() target is now required' );
12388 target = new Vector3();
12389 }
12390 const direction = line.delta( _vector1 );
12391 const denominator = this.normal.dot( direction );
12392 if ( denominator === 0 ) {
12393 if ( this.distanceToPoint( line.start ) === 0 ) {
12394 return target.copy( line.start );
12395 }
12396 return undefined;
12397 }
12398 const t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;
12399 if ( t < 0 || t > 1 ) {
12400 return undefined;
12401 }
12402 return target.copy( direction ).multiplyScalar( t ).add( line.start );
12403 }
12404 intersectsLine( line ) {
12405 const startSign = this.distanceToPoint( line.start );
12406 const endSign = this.distanceToPoint( line.end );
12407 return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );
12408 }
12409 intersectsBox( box ) {
12410 return box.intersectsPlane( this );
12411 }
12412 intersectsSphere( sphere ) {
12413 return sphere.intersectsPlane( this );
12414 }
12415 coplanarPoint( target ) {
12416 if ( target === undefined ) {
12417 console.warn( 'THREE.Plane: .coplanarPoint() target is now required' );
12418 target = new Vector3();
12419 }
12420 return target.copy( this.normal ).multiplyScalar( - this.constant );
12421 }
12422 applyMatrix4( matrix, optionalNormalMatrix ) {
12423 const normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix( matrix );
12424 const referencePoint = this.coplanarPoint( _vector1 ).applyMatrix4( matrix );
12425 const normal = this.normal.applyMatrix3( normalMatrix ).normalize();
12426 this.constant = - referencePoint.dot( normal );
12427 return this;
12428 }
12429 translate( offset ) {
12430 this.constant -= offset.dot( this.normal );
12431 return this;
12432 }
12433 equals( plane ) {
12434 return plane.normal.equals( this.normal ) && ( plane.constant === this.constant );
12435 }
12436 }
12437 const _v0$1 = new Vector3();
12438 const _v1$3 = new Vector3();
12439 const _v2$1 = new Vector3();
12440 const _v3 = new Vector3();
12441 const _vab = new Vector3();
12442 const _vac = new Vector3();
12443 const _vbc = new Vector3();
12444 const _vap = new Vector3();
12445 const _vbp = new Vector3();
12446 const _vcp = new Vector3();
12447 class Triangle {
12448 constructor( a, b, c ) {
12449 this.a = ( a !== undefined ) ? a : new Vector3();
12450 this.b = ( b !== undefined ) ? b : new Vector3();
12451 this.c = ( c !== undefined ) ? c : new Vector3();
12452 }
12453 static getNormal( a, b, c, target ) {
12454 if ( target === undefined ) {
12455 console.warn( 'THREE.Triangle: .getNormal() target is now required' );
12456 target = new Vector3();
12457 }
12458 target.subVectors( c, b );
12459 _v0$1.subVectors( a, b );
12460 target.cross( _v0$1 );
12461 const targetLengthSq = target.lengthSq();
12462 if ( targetLengthSq > 0 ) {
12463 return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) );
12464 }
12465 return target.set( 0, 0, 0 );
12466 }
12467 static getBarycoord( point, a, b, c, target ) {
12468 _v0$1.subVectors( c, a );
12469 _v1$3.subVectors( b, a );
12470 _v2$1.subVectors( point, a );
12471 const dot00 = _v0$1.dot( _v0$1 );
12472 const dot01 = _v0$1.dot( _v1$3 );
12473 const dot02 = _v0$1.dot( _v2$1 );
12474 const dot11 = _v1$3.dot( _v1$3 );
12475 const dot12 = _v1$3.dot( _v2$1 );
12476 const denom = ( dot00 * dot11 - dot01 * dot01 );
12477 if ( target === undefined ) {
12478 console.warn( 'THREE.Triangle: .getBarycoord() target is now required' );
12479 target = new Vector3();
12480 }
12481 if ( denom === 0 ) {
12482 return target.set( - 2, - 1, - 1 );
12483 }
12484 const invDenom = 1 / denom;
12485 const u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
12486 const v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
12487 return target.set( 1 - u - v, v, u );
12488 }
12489 static containsPoint( point, a, b, c ) {
12490 this.getBarycoord( point, a, b, c, _v3 );
12491 return ( _v3.x >= 0 ) && ( _v3.y >= 0 ) && ( ( _v3.x + _v3.y ) <= 1 );
12492 }
12493 static getUV( point, p1, p2, p3, uv1, uv2, uv3, target ) {
12494 this.getBarycoord( point, p1, p2, p3, _v3 );
12495 target.set( 0, 0 );
12496 target.addScaledVector( uv1, _v3.x );
12497 target.addScaledVector( uv2, _v3.y );
12498 target.addScaledVector( uv3, _v3.z );
12499 return target;
12500 }
12501 static isFrontFacing( a, b, c, direction ) {
12502 _v0$1.subVectors( c, b );
12503 _v1$3.subVectors( a, b );
12504 return ( _v0$1.cross( _v1$3 ).dot( direction ) < 0 ) ? true : false;
12505 }
12506 set( a, b, c ) {
12507 this.a.copy( a );
12508 this.b.copy( b );
12509 this.c.copy( c );
12510 return this;
12511 }
12512 setFromPointsAndIndices( points, i0, i1, i2 ) {
12513 this.a.copy( points[ i0 ] );
12514 this.b.copy( points[ i1 ] );
12515 this.c.copy( points[ i2 ] );
12516 return this;
12517 }
12518 clone() {
12519 return new this.constructor().copy( this );
12520 }
12521 copy( triangle ) {
12522 this.a.copy( triangle.a );
12523 this.b.copy( triangle.b );
12524 this.c.copy( triangle.c );
12525 return this;
12526 }
12527 getArea() {
12528 _v0$1.subVectors( this.c, this.b );
12529 _v1$3.subVectors( this.a, this.b );
12530 return _v0$1.cross( _v1$3 ).length() * 0.5;
12531 }
12532 getMidpoint( target ) {
12533 if ( target === undefined ) {
12534 console.warn( 'THREE.Triangle: .getMidpoint() target is now required' );
12535 target = new Vector3();
12536 }
12537 return target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );
12538 }
12539 getNormal( target ) {
12540 return Triangle.getNormal( this.a, this.b, this.c, target );
12541 }
12542 getPlane( target ) {
12543 if ( target === undefined ) {
12544 console.warn( 'THREE.Triangle: .getPlane() target is now required' );
12545 target = new Plane();
12546 }
12547 return target.setFromCoplanarPoints( this.a, this.b, this.c );
12548 }
12549 getBarycoord( point, target ) {
12550 return Triangle.getBarycoord( point, this.a, this.b, this.c, target );
12551 }
12552 getUV( point, uv1, uv2, uv3, target ) {
12553 return Triangle.getUV( point, this.a, this.b, this.c, uv1, uv2, uv3, target );
12554 }
12555 containsPoint( point ) {
12556 return Triangle.containsPoint( point, this.a, this.b, this.c );
12557 }
12558 isFrontFacing( direction ) {
12559 return Triangle.isFrontFacing( this.a, this.b, this.c, direction );
12560 }
12561 intersectsBox( box ) {
12562 return box.intersectsTriangle( this );
12563 }
12564 closestPointToPoint( p, target ) {
12565 if ( target === undefined ) {
12566 console.warn( 'THREE.Triangle: .closestPointToPoint() target is now required' );
12567 target = new Vector3();
12568 }
12569 const a = this.a, b = this.b, c = this.c;
12570 let v, w;
12571 _vab.subVectors( b, a );
12572 _vac.subVectors( c, a );
12573 _vap.subVectors( p, a );
12574 const d1 = _vab.dot( _vap );
12575 const d2 = _vac.dot( _vap );
12576 if ( d1 <= 0 && d2 <= 0 ) {
12577 return target.copy( a );
12578 }
12579 _vbp.subVectors( p, b );
12580 const d3 = _vab.dot( _vbp );
12581 const d4 = _vac.dot( _vbp );
12582 if ( d3 >= 0 && d4 <= d3 ) {
12583 return target.copy( b );
12584 }
12585 const vc = d1 * d4 - d3 * d2;
12586 if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) {
12587 v = d1 / ( d1 - d3 );
12588 return target.copy( a ).addScaledVector( _vab, v );
12589 }
12590 _vcp.subVectors( p, c );
12591 const d5 = _vab.dot( _vcp );
12592 const d6 = _vac.dot( _vcp );
12593 if ( d6 >= 0 && d5 <= d6 ) {
12594 return target.copy( c );
12595 }
12596 const vb = d5 * d2 - d1 * d6;
12597 if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) {
12598 w = d2 / ( d2 - d6 );
12599 return target.copy( a ).addScaledVector( _vac, w );
12600 }
12601 const va = d3 * d6 - d5 * d4;
12602 if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) {
12603 _vbc.subVectors( c, b );
12604 w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) );
12605 return target.copy( b ).addScaledVector( _vbc, w );
12606 }
12607 const denom = 1 / ( va + vb + vc );
12608 v = vb * denom;
12609 w = vc * denom;
12610 return target.copy( a ).addScaledVector( _vab, v ).addScaledVector( _vac, w );
12611 }
12612 equals( triangle ) {
12613 return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );
12614 }
12615 }
12616 const _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,
12617 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,
12618 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,
12619 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,
12620 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,
12621 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,
12622 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,
12623 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,
12624 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,
12625 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,
12626 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,
12627 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,
12628 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,
12629 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,
12630 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,
12631 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,
12632 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,
12633 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,
12634 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,
12635 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,
12636 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,
12637 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,
12638 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,
12639 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };
12640 const _hslA = { h: 0, s: 0, l: 0 };
12641 const _hslB = { h: 0, s: 0, l: 0 };
12642 function hue2rgb( p, q, t ) {
12643 if ( t < 0 ) t += 1;
12644 if ( t > 1 ) t -= 1;
12645 if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;
12646 if ( t < 1 / 2 ) return q;
12647 if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );
12648 return p;
12649 }
12650 function SRGBToLinear( c ) {
12651 return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );
12652 }
12653 function LinearToSRGB( c ) {
12654 return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;
12655 }
12656 class Color {
12657 constructor( r, g, b ) {
12658 Object.defineProperty( this, 'isColor', { value: true } );
12659 if ( g === undefined && b === undefined ) {
12660 return this.set( r );
12661 }
12662 return this.setRGB( r, g, b );
12663 }
12664 set( value ) {
12665 if ( value && value.isColor ) {
12666 this.copy( value );
12667 } else if ( typeof value === 'number' ) {
12668 this.setHex( value );
12669 } else if ( typeof value === 'string' ) {
12670 this.setStyle( value );
12671 }
12672 return this;
12673 }
12674 setScalar( scalar ) {
12675 this.r = scalar;
12676 this.g = scalar;
12677 this.b = scalar;
12678 return this;
12679 }
12680 setHex( hex ) {
12681 hex = Math.floor( hex );
12682 this.r = ( hex >> 16 & 255 ) / 255;
12683 this.g = ( hex >> 8 & 255 ) / 255;
12684 this.b = ( hex & 255 ) / 255;
12685 return this;
12686 }
12687 setRGB( r, g, b ) {
12688 this.r = r;
12689 this.g = g;
12690 this.b = b;
12691 return this;
12692 }
12693 setHSL( h, s, l ) {
12694 h = MathUtils.euclideanModulo( h, 1 );
12695 s = MathUtils.clamp( s, 0, 1 );
12696 l = MathUtils.clamp( l, 0, 1 );
12697 if ( s === 0 ) {
12698 this.r = this.g = this.b = l;
12699 } else {
12700 const p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );
12701 const q = ( 2 * l ) - p;
12702 this.r = hue2rgb( q, p, h + 1 / 3 );
12703 this.g = hue2rgb( q, p, h );
12704 this.b = hue2rgb( q, p, h - 1 / 3 );
12705 }
12706 return this;
12707 }
12708 setStyle( style ) {
12709 function handleAlpha( string ) {
12710 if ( string === undefined ) return;
12711 if ( parseFloat( string ) < 1 ) {
12712 console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );
12713 }
12714 }
12715 let m;
12716 if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) {
12717 let color;
12718 const name = m[ 1 ];
12719 const components = m[ 2 ];
12720 switch ( name ) {
12721 case 'rgb':
12722 case 'rgba':
12723 if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
12724 this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;
12725 this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;
12726 this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;
12727 handleAlpha( color[ 5 ] );
12728 return this;
12729 }
12730 if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
12731 this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;
12732 this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;
12733 this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;
12734 handleAlpha( color[ 5 ] );
12735 return this;
12736 }
12737 break;
12738 case 'hsl':
12739 case 'hsla':
12740 if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
12741 const h = parseFloat( color[ 1 ] ) / 360;
12742 const s = parseInt( color[ 2 ], 10 ) / 100;
12743 const l = parseInt( color[ 3 ], 10 ) / 100;
12744 handleAlpha( color[ 5 ] );
12745 return this.setHSL( h, s, l );
12746 }
12747 break;
12748 }
12749 } else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) {
12750 const hex = m[ 1 ];
12751 const size = hex.length;
12752 if ( size === 3 ) {
12753 this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;
12754 this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;
12755 this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;
12756 return this;
12757 } else if ( size === 6 ) {
12758 this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;
12759 this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;
12760 this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;
12761 return this;
12762 }
12763 }
12764 if ( style && style.length > 0 ) {
12765 return this.setColorName( style );
12766 }
12767 return this;
12768 }
12769 setColorName( style ) {
12770 const hex = _colorKeywords[ style ];
12771 if ( hex !== undefined ) {
12772 this.setHex( hex );
12773 } else {
12774 console.warn( 'THREE.Color: Unknown color ' + style );
12775 }
12776 return this;
12777 }
12778 clone() {
12779 return new this.constructor( this.r, this.g, this.b );
12780 }
12781 copy( color ) {
12782 this.r = color.r;
12783 this.g = color.g;
12784 this.b = color.b;
12785 return this;
12786 }
12787 copyGammaToLinear( color, gammaFactor ) {
12788 if ( gammaFactor === undefined ) gammaFactor = 2.0;
12789 this.r = Math.pow( color.r, gammaFactor );
12790 this.g = Math.pow( color.g, gammaFactor );
12791 this.b = Math.pow( color.b, gammaFactor );
12792 return this;
12793 }
12794 copyLinearToGamma( color, gammaFactor ) {
12795 if ( gammaFactor === undefined ) gammaFactor = 2.0;
12796 const safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;
12797 this.r = Math.pow( color.r, safeInverse );
12798 this.g = Math.pow( color.g, safeInverse );
12799 this.b = Math.pow( color.b, safeInverse );
12800 return this;
12801 }
12802 convertGammaToLinear( gammaFactor ) {
12803 this.copyGammaToLinear( this, gammaFactor );
12804 return this;
12805 }
12806 convertLinearToGamma( gammaFactor ) {
12807 this.copyLinearToGamma( this, gammaFactor );
12808 return this;
12809 }
12810 copySRGBToLinear( color ) {
12811 this.r = SRGBToLinear( color.r );
12812 this.g = SRGBToLinear( color.g );
12813 this.b = SRGBToLinear( color.b );
12814 return this;
12815 }
12816 copyLinearToSRGB( color ) {
12817 this.r = LinearToSRGB( color.r );
12818 this.g = LinearToSRGB( color.g );
12819 this.b = LinearToSRGB( color.b );
12820 return this;
12821 }
12822 convertSRGBToLinear() {
12823 this.copySRGBToLinear( this );
12824 return this;
12825 }
12826 convertLinearToSRGB() {
12827 this.copyLinearToSRGB( this );
12828 return this;
12829 }
12830 getHex() {
12831 return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;
12832 }
12833 getHexString() {
12834 return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );
12835 }
12836 getHSL( target ) {
12837 if ( target === undefined ) {
12838 console.warn( 'THREE.Color: .getHSL() target is now required' );
12839 target = { h: 0, s: 0, l: 0 };
12840 }
12841 const r = this.r, g = this.g, b = this.b;
12842 const max = Math.max( r, g, b );
12843 const min = Math.min( r, g, b );
12844 let hue, saturation;
12845 const lightness = ( min + max ) / 2.0;
12846 if ( min === max ) {
12847 hue = 0;
12848 saturation = 0;
12849 } else {
12850 const delta = max - min;
12851 saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );
12852 switch ( max ) {
12853 case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;
12854 case g: hue = ( b - r ) / delta + 2; break;
12855 case b: hue = ( r - g ) / delta + 4; break;
12856 }
12857 hue /= 6;
12858 }
12859 target.h = hue;
12860 target.s = saturation;
12861 target.l = lightness;
12862 return target;
12863 }
12864 getStyle() {
12865 return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';
12866 }
12867 offsetHSL( h, s, l ) {
12868 this.getHSL( _hslA );
12869 _hslA.h += h; _hslA.s += s; _hslA.l += l;
12870 this.setHSL( _hslA.h, _hslA.s, _hslA.l );
12871 return this;
12872 }
12873 add( color ) {
12874 this.r += color.r;
12875 this.g += color.g;
12876 this.b += color.b;
12877 return this;
12878 }
12879 addColors( color1, color2 ) {
12880 this.r = color1.r + color2.r;
12881 this.g = color1.g + color2.g;
12882 this.b = color1.b + color2.b;
12883 return this;
12884 }
12885 addScalar( s ) {
12886 this.r += s;
12887 this.g += s;
12888 this.b += s;
12889 return this;
12890 }
12891 sub( color ) {
12892 this.r = Math.max( 0, this.r - color.r );
12893 this.g = Math.max( 0, this.g - color.g );
12894 this.b = Math.max( 0, this.b - color.b );
12895 return this;
12896 }
12897 multiply( color ) {
12898 this.r *= color.r;
12899 this.g *= color.g;
12900 this.b *= color.b;
12901 return this;
12902 }
12903 multiplyScalar( s ) {
12904 this.r *= s;
12905 this.g *= s;
12906 this.b *= s;
12907 return this;
12908 }
12909 lerp( color, alpha ) {
12910 this.r += ( color.r - this.r ) * alpha;
12911 this.g += ( color.g - this.g ) * alpha;
12912 this.b += ( color.b - this.b ) * alpha;
12913 return this;
12914 }
12915 lerpHSL( color, alpha ) {
12916 this.getHSL( _hslA );
12917 color.getHSL( _hslB );
12918 const h = MathUtils.lerp( _hslA.h, _hslB.h, alpha );
12919 const s = MathUtils.lerp( _hslA.s, _hslB.s, alpha );
12920 const l = MathUtils.lerp( _hslA.l, _hslB.l, alpha );
12921 this.setHSL( h, s, l );
12922 return this;
12923 }
12924 equals( c ) {
12925 return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );
12926 }
12927 fromArray( array, offset ) {
12928 if ( offset === undefined ) offset = 0;
12929 this.r = array[ offset ];
12930 this.g = array[ offset + 1 ];
12931 this.b = array[ offset + 2 ];
12932 return this;
12933 }
12934 toArray( array, offset ) {
12935 if ( array === undefined ) array = [];
12936 if ( offset === undefined ) offset = 0;
12937 array[ offset ] = this.r;
12938 array[ offset + 1 ] = this.g;
12939 array[ offset + 2 ] = this.b;
12940 return array;
12941 }
12942 fromBufferAttribute( attribute, index ) {
12943 this.r = attribute.getX( index );
12944 this.g = attribute.getY( index );
12945 this.b = attribute.getZ( index );
12946 if ( attribute.normalized === true ) {
12947 this.r /= 255;
12948 this.g /= 255;
12949 this.b /= 255;
12950 }
12951 return this;
12952 }
12953 toJSON() {
12954 return this.getHex();
12955 }
12956 }
12957 Color.NAMES = _colorKeywords;
12958 Color.prototype.r = 1;
12959 Color.prototype.g = 1;
12960 Color.prototype.b = 1;
12961 class Face3 {
12962 constructor( a, b, c, normal, color, materialIndex ) {
12963 this.a = a;
12964 this.b = b;
12965 this.c = c;
12966 this.normal = ( normal && normal.isVector3 ) ? normal : new Vector3();
12967 this.vertexNormals = Array.isArray( normal ) ? normal : [];
12968 this.color = ( color && color.isColor ) ? color : new Color();
12969 this.vertexColors = Array.isArray( color ) ? color : [];
12970 this.materialIndex = materialIndex !== undefined ? materialIndex : 0;
12971 }
12972 clone() {
12973 return new this.constructor().copy( this );
12974 }
12975 copy( source ) {
12976 this.a = source.a;
12977 this.b = source.b;
12978 this.c = source.c;
12979 this.normal.copy( source.normal );
12980 this.color.copy( source.color );
12981 this.materialIndex = source.materialIndex;
12982 for ( let i = 0, il = source.vertexNormals.length; i < il; i ++ ) {
12983 this.vertexNormals[ i ] = source.vertexNormals[ i ].clone();
12984 }
12985 for ( let i = 0, il = source.vertexColors.length; i < il; i ++ ) {
12986 this.vertexColors[ i ] = source.vertexColors[ i ].clone();
12987 }
12988 return this;
12989 }
12990 }
12991 let materialId = 0;
12992 function Material() {
12993 Object.defineProperty( this, 'id', { value: materialId ++ } );
12994 this.uuid = MathUtils.generateUUID();
12995 this.name = '';
12996 this.type = 'Material';
12997 this.fog = true;
12998 this.blending = NormalBlending;
12999 this.side = FrontSide;
13000 this.flatShading = false;
13001 this.vertexColors = false;
13002 this.opacity = 1;
13003 this.transparent = false;
13004 this.blendSrc = SrcAlphaFactor;
13005 this.blendDst = OneMinusSrcAlphaFactor;
13006 this.blendEquation = AddEquation;
13007 this.blendSrcAlpha = null;
13008 this.blendDstAlpha = null;
13009 this.blendEquationAlpha = null;
13010 this.depthFunc = LessEqualDepth;
13011 this.depthTest = true;
13012 this.depthWrite = true;
13013 this.stencilWriteMask = 0xff;
13014 this.stencilFunc = AlwaysStencilFunc;
13015 this.stencilRef = 0;
13016 this.stencilFuncMask = 0xff;
13017 this.stencilFail = KeepStencilOp;
13018 this.stencilZFail = KeepStencilOp;
13019 this.stencilZPass = KeepStencilOp;
13020 this.stencilWrite = false;
13021 this.clippingPlanes = null;
13022 this.clipIntersection = false;
13023 this.clipShadows = false;
13024 this.shadowSide = null;
13025 this.colorWrite = true;
13026 this.precision = null;
13027 this.polygonOffset = false;
13028 this.polygonOffsetFactor = 0;
13029 this.polygonOffsetUnits = 0;
13030 this.dithering = false;
13031 this.alphaTest = 0;
13032 this.premultipliedAlpha = false;
13033 this.visible = true;
13034 this.toneMapped = true;
13035 this.userData = {};
13036 this.version = 0;
13037 }
13038 Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
13039 constructor: Material,
13040 isMaterial: true,
13041 onBeforeCompile: function ( ) {},
13042 customProgramCacheKey: function () {
13043 return this.onBeforeCompile.toString();
13044 },
13045 setValues: function ( values ) {
13046 if ( values === undefined ) return;
13047 for ( const key in values ) {
13048 const newValue = values[ key ];
13049 if ( newValue === undefined ) {
13050 console.warn( "THREE.Material: '" + key + "' parameter is undefined." );
13051 continue;
13052 }
13053 if ( key === 'shading' ) {
13054 console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' );
13055 this.flatShading = ( newValue === FlatShading ) ? true : false;
13056 continue;
13057 }
13058 const currentValue = this[ key ];
13059 if ( currentValue === undefined ) {
13060 console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." );
13061 continue;
13062 }
13063 if ( currentValue && currentValue.isColor ) {
13064 currentValue.set( newValue );
13065 } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {
13066 currentValue.copy( newValue );
13067 } else {
13068 this[ key ] = newValue;
13069 }
13070 }
13071 },
13072 toJSON: function ( meta ) {
13073 const isRoot = ( meta === undefined || typeof meta === 'string' );
13074 if ( isRoot ) {
13075 meta = {
13076 textures: {},
13077 images: {}
13078 };
13079 }
13080 const data = {
13081 metadata: {
13082 version: 4.5,
13083 type: 'Material',
13084 generator: 'Material.toJSON'
13085 }
13086 };
13087 data.uuid = this.uuid;
13088 data.type = this.type;
13089 if ( this.name !== '' ) data.name = this.name;
13090 if ( this.color && this.color.isColor ) data.color = this.color.getHex();
13091 if ( this.roughness !== undefined ) data.roughness = this.roughness;
13092 if ( this.metalness !== undefined ) data.metalness = this.metalness;
13093 if ( this.sheen && this.sheen.isColor ) data.sheen = this.sheen.getHex();
13094 if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();
13095 if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity;
13096 if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();
13097 if ( this.shininess !== undefined ) data.shininess = this.shininess;
13098 if ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat;
13099 if ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness;
13100 if ( this.clearcoatMap && this.clearcoatMap.isTexture ) {
13101 data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid;
13102 }
13103 if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) {
13104 data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid;
13105 }
13106 if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) {
13107 data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid;
13108 data.clearcoatNormalScale = this.clearcoatNormalScale.toArray();
13109 }
13110 if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;
13111 if ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid;
13112 if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;
13113 if ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;
13114 if ( this.aoMap && this.aoMap.isTexture ) {
13115 data.aoMap = this.aoMap.toJSON( meta ).uuid;
13116 data.aoMapIntensity = this.aoMapIntensity;
13117 }
13118 if ( this.bumpMap && this.bumpMap.isTexture ) {
13119 data.bumpMap = this.bumpMap.toJSON( meta ).uuid;
13120 data.bumpScale = this.bumpScale;
13121 }
13122 if ( this.normalMap && this.normalMap.isTexture ) {
13123 data.normalMap = this.normalMap.toJSON( meta ).uuid;
13124 data.normalMapType = this.normalMapType;
13125 data.normalScale = this.normalScale.toArray();
13126 }
13127 if ( this.displacementMap && this.displacementMap.isTexture ) {
13128 data.displacementMap = this.displacementMap.toJSON( meta ).uuid;
13129 data.displacementScale = this.displacementScale;
13130 data.displacementBias = this.displacementBias;
13131 }
13132 if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;
13133 if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;
13134 if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;
13135 if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;
13136 if ( this.envMap && this.envMap.isTexture ) {
13137 data.envMap = this.envMap.toJSON( meta ).uuid;
13138 data.reflectivity = this.reflectivity;
13139 data.refractionRatio = this.refractionRatio;
13140 if ( this.combine !== undefined ) data.combine = this.combine;
13141 if ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity;
13142 }
13143 if ( this.gradientMap && this.gradientMap.isTexture ) {
13144 data.gradientMap = this.gradientMap.toJSON( meta ).uuid;
13145 }
13146 if ( this.size !== undefined ) data.size = this.size;
13147 if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;
13148 if ( this.blending !== NormalBlending ) data.blending = this.blending;
13149 if ( this.flatShading === true ) data.flatShading = this.flatShading;
13150 if ( this.side !== FrontSide ) data.side = this.side;
13151 if ( this.vertexColors ) data.vertexColors = true;
13152 if ( this.opacity < 1 ) data.opacity = this.opacity;
13153 if ( this.transparent === true ) data.transparent = this.transparent;
13154 data.depthFunc = this.depthFunc;
13155 data.depthTest = this.depthTest;
13156 data.depthWrite = this.depthWrite;
13157 data.stencilWrite = this.stencilWrite;
13158 data.stencilWriteMask = this.stencilWriteMask;
13159 data.stencilFunc = this.stencilFunc;
13160 data.stencilRef = this.stencilRef;
13161 data.stencilFuncMask = this.stencilFuncMask;
13162 data.stencilFail = this.stencilFail;
13163 data.stencilZFail = this.stencilZFail;
13164 data.stencilZPass = this.stencilZPass;
13165 if ( this.rotation && this.rotation !== 0 ) data.rotation = this.rotation;
13166 if ( this.polygonOffset === true ) data.polygonOffset = true;
13167 if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor;
13168 if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits;
13169 if ( this.linewidth && this.linewidth !== 1 ) data.linewidth = this.linewidth;
13170 if ( this.dashSize !== undefined ) data.dashSize = this.dashSize;
13171 if ( this.gapSize !== undefined ) data.gapSize = this.gapSize;
13172 if ( this.scale !== undefined ) data.scale = this.scale;
13173 if ( this.dithering === true ) data.dithering = true;
13174 if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;
13175 if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;
13176 if ( this.wireframe === true ) data.wireframe = this.wireframe;
13177 if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;
13178 if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;
13179 if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;
13180 if ( this.morphTargets === true ) data.morphTargets = true;
13181 if ( this.morphNormals === true ) data.morphNormals = true;
13182 if ( this.skinning === true ) data.skinning = true;
13183 if ( this.visible === false ) data.visible = false;
13184 if ( this.toneMapped === false ) data.toneMapped = false;
13185 if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData;
13186 function extractFromCache( cache ) {
13187 const values = [];
13188 for ( const key in cache ) {
13189 const data = cache[ key ];
13190 delete data.metadata;
13191 values.push( data );
13192 }
13193 return values;
13194 }
13195 if ( isRoot ) {
13196 const textures = extractFromCache( meta.textures );
13197 const images = extractFromCache( meta.images );
13198 if ( textures.length > 0 ) data.textures = textures;
13199 if ( images.length > 0 ) data.images = images;
13200 }
13201 return data;
13202 },
13203 clone: function () {
13204 return new this.constructor().copy( this );
13205 },
13206 copy: function ( source ) {
13207 this.name = source.name;
13208 this.fog = source.fog;
13209 this.blending = source.blending;
13210 this.side = source.side;
13211 this.flatShading = source.flatShading;
13212 this.vertexColors = source.vertexColors;
13213 this.opacity = source.opacity;
13214 this.transparent = source.transparent;
13215 this.blendSrc = source.blendSrc;
13216 this.blendDst = source.blendDst;
13217 this.blendEquation = source.blendEquation;
13218 this.blendSrcAlpha = source.blendSrcAlpha;
13219 this.blendDstAlpha = source.blendDstAlpha;
13220 this.blendEquationAlpha = source.blendEquationAlpha;
13221 this.depthFunc = source.depthFunc;
13222 this.depthTest = source.depthTest;
13223 this.depthWrite = source.depthWrite;
13224 this.stencilWriteMask = source.stencilWriteMask;
13225 this.stencilFunc = source.stencilFunc;
13226 this.stencilRef = source.stencilRef;
13227 this.stencilFuncMask = source.stencilFuncMask;
13228 this.stencilFail = source.stencilFail;
13229 this.stencilZFail = source.stencilZFail;
13230 this.stencilZPass = source.stencilZPass;
13231 this.stencilWrite = source.stencilWrite;
13232 const srcPlanes = source.clippingPlanes;
13233 let dstPlanes = null;
13234 if ( srcPlanes !== null ) {
13235 const n = srcPlanes.length;
13236 dstPlanes = new Array( n );
13237 for ( let i = 0; i !== n; ++ i ) {
13238 dstPlanes[ i ] = srcPlanes[ i ].clone();
13239 }
13240 }
13241 this.clippingPlanes = dstPlanes;
13242 this.clipIntersection = source.clipIntersection;
13243 this.clipShadows = source.clipShadows;
13244 this.shadowSide = source.shadowSide;
13245 this.colorWrite = source.colorWrite;
13246 this.precision = source.precision;
13247 this.polygonOffset = source.polygonOffset;
13248 this.polygonOffsetFactor = source.polygonOffsetFactor;
13249 this.polygonOffsetUnits = source.polygonOffsetUnits;
13250 this.dithering = source.dithering;
13251 this.alphaTest = source.alphaTest;
13252 this.premultipliedAlpha = source.premultipliedAlpha;
13253 this.visible = source.visible;
13254 this.toneMapped = source.toneMapped;
13255 this.userData = JSON.parse( JSON.stringify( source.userData ) );
13256 return this;
13257 },
13258 dispose: function () {
13259 this.dispatchEvent( { type: 'dispose' } );
13260 }
13261 } );
13262 Object.defineProperty( Material.prototype, 'needsUpdate', {
13263 set: function ( value ) {
13264 if ( value === true ) this.version ++;
13265 }
13266 } );
13267 function MeshBasicMaterial( parameters ) {
13268 Material.call( this );
13269 this.type = 'MeshBasicMaterial';
13270 this.color = new Color( 0xffffff );
13271 this.map = null;
13272 this.lightMap = null;
13273 this.lightMapIntensity = 1.0;
13274 this.aoMap = null;
13275 this.aoMapIntensity = 1.0;
13276 this.specularMap = null;
13277 this.alphaMap = null;
13278 this.envMap = null;
13279 this.combine = MultiplyOperation;
13280 this.reflectivity = 1;
13281 this.refractionRatio = 0.98;
13282 this.wireframe = false;
13283 this.wireframeLinewidth = 1;
13284 this.wireframeLinecap = 'round';
13285 this.wireframeLinejoin = 'round';
13286 this.skinning = false;
13287 this.morphTargets = false;
13288 this.setValues( parameters );
13289 }
13290 MeshBasicMaterial.prototype = Object.create( Material.prototype );
13291 MeshBasicMaterial.prototype.constructor = MeshBasicMaterial;
13292 MeshBasicMaterial.prototype.isMeshBasicMaterial = true;
13293 MeshBasicMaterial.prototype.copy = function ( source ) {
13294 Material.prototype.copy.call( this, source );
13295 this.color.copy( source.color );
13296 this.map = source.map;
13297 this.lightMap = source.lightMap;
13298 this.lightMapIntensity = source.lightMapIntensity;
13299 this.aoMap = source.aoMap;
13300 this.aoMapIntensity = source.aoMapIntensity;
13301 this.specularMap = source.specularMap;
13302 this.alphaMap = source.alphaMap;
13303 this.envMap = source.envMap;
13304 this.combine = source.combine;
13305 this.reflectivity = source.reflectivity;
13306 this.refractionRatio = source.refractionRatio;
13307 this.wireframe = source.wireframe;
13308 this.wireframeLinewidth = source.wireframeLinewidth;
13309 this.wireframeLinecap = source.wireframeLinecap;
13310 this.wireframeLinejoin = source.wireframeLinejoin;
13311 this.skinning = source.skinning;
13312 this.morphTargets = source.morphTargets;
13313 return this;
13314 };
13315 const _vector$3 = new Vector3();
13316 const _vector2$1 = new Vector2();
13317 function BufferAttribute( array, itemSize, normalized ) {
13318 if ( Array.isArray( array ) ) {
13319 throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
13320 }
13321 this.name = '';
13322 this.array = array;
13323 this.itemSize = itemSize;
13324 this.count = array !== undefined ? array.length / itemSize : 0;
13325 this.normalized = normalized === true;
13326 this.usage = StaticDrawUsage;
13327 this.updateRange = { offset: 0, count: - 1 };
13328 this.version = 0;
13329 }
13330 Object.defineProperty( BufferAttribute.prototype, 'needsUpdate', {
13331 set: function ( value ) {
13332 if ( value === true ) this.version ++;
13333 }
13334 } );
13335 Object.assign( BufferAttribute.prototype, {
13336 isBufferAttribute: true,
13337 onUploadCallback: function () {},
13338 setUsage: function ( value ) {
13339 this.usage = value;
13340 return this;
13341 },
13342 copy: function ( source ) {
13343 this.name = source.name;
13344 this.array = new source.array.constructor( source.array );
13345 this.itemSize = source.itemSize;
13346 this.count = source.count;
13347 this.normalized = source.normalized;
13348 this.usage = source.usage;
13349 return this;
13350 },
13351 copyAt: function ( index1, attribute, index2 ) {
13352 index1 *= this.itemSize;
13353 index2 *= attribute.itemSize;
13354 for ( let i = 0, l = this.itemSize; i < l; i ++ ) {
13355 this.array[ index1 + i ] = attribute.array[ index2 + i ];
13356 }
13357 return this;
13358 },
13359 copyArray: function ( array ) {
13360 this.array.set( array );
13361 return this;
13362 },
13363 copyColorsArray: function ( colors ) {
13364 const array = this.array;
13365 let offset = 0;
13366 for ( let i = 0, l = colors.length; i < l; i ++ ) {
13367 let color = colors[ i ];
13368 if ( color === undefined ) {
13369 console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );
13370 color = new Color();
13371 }
13372 array[ offset ++ ] = color.r;
13373 array[ offset ++ ] = color.g;
13374 array[ offset ++ ] = color.b;
13375 }
13376 return this;
13377 },
13378 copyVector2sArray: function ( vectors ) {
13379 const array = this.array;
13380 let offset = 0;
13381 for ( let i = 0, l = vectors.length; i < l; i ++ ) {
13382 let vector = vectors[ i ];
13383 if ( vector === undefined ) {
13384 console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );
13385 vector = new Vector2();
13386 }
13387 array[ offset ++ ] = vector.x;
13388 array[ offset ++ ] = vector.y;
13389 }
13390 return this;
13391 },
13392 copyVector3sArray: function ( vectors ) {
13393 const array = this.array;
13394 let offset = 0;
13395 for ( let i = 0, l = vectors.length; i < l; i ++ ) {
13396 let vector = vectors[ i ];
13397 if ( vector === undefined ) {
13398 console.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );
13399 vector = new Vector3();
13400 }
13401 array[ offset ++ ] = vector.x;
13402 array[ offset ++ ] = vector.y;
13403 array[ offset ++ ] = vector.z;
13404 }
13405 return this;
13406 },
13407 copyVector4sArray: function ( vectors ) {
13408 const array = this.array;
13409 let offset = 0;
13410 for ( let i = 0, l = vectors.length; i < l; i ++ ) {
13411 let vector = vectors[ i ];
13412 if ( vector === undefined ) {
13413 console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );
13414 vector = new Vector4();
13415 }
13416 array[ offset ++ ] = vector.x;
13417 array[ offset ++ ] = vector.y;
13418 array[ offset ++ ] = vector.z;
13419 array[ offset ++ ] = vector.w;
13420 }
13421 return this;
13422 },
13423 applyMatrix3: function ( m ) {
13424 if ( this.itemSize === 2 ) {
13425 for ( let i = 0, l = this.count; i < l; i ++ ) {
13426 _vector2$1.fromBufferAttribute( this, i );
13427 _vector2$1.applyMatrix3( m );
13428 this.setXY( i, _vector2$1.x, _vector2$1.y );
13429 }
13430 } else if ( this.itemSize === 3 ) {
13431 for ( let i = 0, l = this.count; i < l; i ++ ) {
13432 _vector$3.fromBufferAttribute( this, i );
13433 _vector$3.applyMatrix3( m );
13434 this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z );
13435 }
13436 }
13437 return this;
13438 },
13439 applyMatrix4: function ( m ) {
13440 for ( let i = 0, l = this.count; i < l; i ++ ) {
13441 _vector$3.x = this.getX( i );
13442 _vector$3.y = this.getY( i );
13443 _vector$3.z = this.getZ( i );
13444 _vector$3.applyMatrix4( m );
13445 this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z );
13446 }
13447 return this;
13448 },
13449 applyNormalMatrix: function ( m ) {
13450 for ( let i = 0, l = this.count; i < l; i ++ ) {
13451 _vector$3.x = this.getX( i );
13452 _vector$3.y = this.getY( i );
13453 _vector$3.z = this.getZ( i );
13454 _vector$3.applyNormalMatrix( m );
13455 this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z );
13456 }
13457 return this;
13458 },
13459 transformDirection: function ( m ) {
13460 for ( let i = 0, l = this.count; i < l; i ++ ) {
13461 _vector$3.x = this.getX( i );
13462 _vector$3.y = this.getY( i );
13463 _vector$3.z = this.getZ( i );
13464 _vector$3.transformDirection( m );
13465 this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z );
13466 }
13467 return this;
13468 },
13469 set: function ( value, offset ) {
13470 if ( offset === undefined ) offset = 0;
13471 this.array.set( value, offset );
13472 return this;
13473 },
13474 getX: function ( index ) {
13475 return this.array[ index * this.itemSize ];
13476 },
13477 setX: function ( index, x ) {
13478 this.array[ index * this.itemSize ] = x;
13479 return this;
13480 },
13481 getY: function ( index ) {
13482 return this.array[ index * this.itemSize + 1 ];
13483 },
13484 setY: function ( index, y ) {
13485 this.array[ index * this.itemSize + 1 ] = y;
13486 return this;
13487 },
13488 getZ: function ( index ) {
13489 return this.array[ index * this.itemSize + 2 ];
13490 },
13491 setZ: function ( index, z ) {
13492 this.array[ index * this.itemSize + 2 ] = z;
13493 return this;
13494 },
13495 getW: function ( index ) {
13496 return this.array[ index * this.itemSize + 3 ];
13497 },
13498 setW: function ( index, w ) {
13499 this.array[ index * this.itemSize + 3 ] = w;
13500 return this;
13501 },
13502 setXY: function ( index, x, y ) {
13503 index *= this.itemSize;
13504 this.array[ index + 0 ] = x;
13505 this.array[ index + 1 ] = y;
13506 return this;
13507 },
13508 setXYZ: function ( index, x, y, z ) {
13509 index *= this.itemSize;
13510 this.array[ index + 0 ] = x;
13511 this.array[ index + 1 ] = y;
13512 this.array[ index + 2 ] = z;
13513 return this;
13514 },
13515 setXYZW: function ( index, x, y, z, w ) {
13516 index *= this.itemSize;
13517 this.array[ index + 0 ] = x;
13518 this.array[ index + 1 ] = y;
13519 this.array[ index + 2 ] = z;
13520 this.array[ index + 3 ] = w;
13521 return this;
13522 },
13523 onUpload: function ( callback ) {
13524 this.onUploadCallback = callback;
13525 return this;
13526 },
13527 clone: function () {
13528 return new this.constructor( this.array, this.itemSize ).copy( this );
13529 },
13530 toJSON: function () {
13531 return {
13532 itemSize: this.itemSize,
13533 type: this.array.constructor.name,
13534 array: Array.prototype.slice.call( this.array ),
13535 normalized: this.normalized
13536 };
13537 }
13538 } );
13539 function Int8BufferAttribute( array, itemSize, normalized ) {
13540 BufferAttribute.call( this, new Int8Array( array ), itemSize, normalized );
13541 }
13542 Int8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
13543 Int8BufferAttribute.prototype.constructor = Int8BufferAttribute;
13544 function Uint8BufferAttribute( array, itemSize, normalized ) {
13545 BufferAttribute.call( this, new Uint8Array( array ), itemSize, normalized );
13546 }
13547 Uint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
13548 Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;
13549 function Uint8ClampedBufferAttribute( array, itemSize, normalized ) {
13550 BufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize, normalized );
13551 }
13552 Uint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );
13553 Uint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;
13554 function Int16BufferAttribute( array, itemSize, normalized ) {
13555 BufferAttribute.call( this, new Int16Array( array ), itemSize, normalized );
13556 }
13557 Int16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
13558 Int16BufferAttribute.prototype.constructor = Int16BufferAttribute;
13559 function Uint16BufferAttribute( array, itemSize, normalized ) {
13560 BufferAttribute.call( this, new Uint16Array( array ), itemSize, normalized );
13561 }
13562 Uint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
13563 Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;
13564 function Int32BufferAttribute( array, itemSize, normalized ) {
13565 BufferAttribute.call( this, new Int32Array( array ), itemSize, normalized );
13566 }
13567 Int32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
13568 Int32BufferAttribute.prototype.constructor = Int32BufferAttribute;
13569 function Uint32BufferAttribute( array, itemSize, normalized ) {
13570 BufferAttribute.call( this, new Uint32Array( array ), itemSize, normalized );
13571 }
13572 Uint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
13573 Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;
13574 function Float32BufferAttribute( array, itemSize, normalized ) {
13575 BufferAttribute.call( this, new Float32Array( array ), itemSize, normalized );
13576 }
13577 Float32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
13578 Float32BufferAttribute.prototype.constructor = Float32BufferAttribute;
13579 function Float64BufferAttribute( array, itemSize, normalized ) {
13580 BufferAttribute.call( this, new Float64Array( array ), itemSize, normalized );
13581 }
13582 Float64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
13583 Float64BufferAttribute.prototype.constructor = Float64BufferAttribute;
13584 class DirectGeometry {
13585 constructor() {
13586 this.vertices = [];
13587 this.normals = [];
13588 this.colors = [];
13589 this.uvs = [];
13590 this.uvs2 = [];
13591 this.groups = [];
13592 this.morphTargets = {};
13593 this.skinWeights = [];
13594 this.skinIndices = [];
13595 this.boundingBox = null;
13596 this.boundingSphere = null;
13597 this.verticesNeedUpdate = false;
13598 this.normalsNeedUpdate = false;
13599 this.colorsNeedUpdate = false;
13600 this.uvsNeedUpdate = false;
13601 this.groupsNeedUpdate = false;
13602 }
13603 computeGroups( geometry ) {
13604 const groups = [];
13605 let group, i;
13606 let materialIndex = undefined;
13607 const faces = geometry.faces;
13608 for ( i = 0; i < faces.length; i ++ ) {
13609 const face = faces[ i ];
13610 if ( face.materialIndex !== materialIndex ) {
13611 materialIndex = face.materialIndex;
13612 if ( group !== undefined ) {
13613 group.count = ( i * 3 ) - group.start;
13614 groups.push( group );
13615 }
13616 group = {
13617 start: i * 3,
13618 materialIndex: materialIndex
13619 };
13620 }
13621 }
13622 if ( group !== undefined ) {
13623 group.count = ( i * 3 ) - group.start;
13624 groups.push( group );
13625 }
13626 this.groups = groups;
13627 }
13628 fromGeometry( geometry ) {
13629 const faces = geometry.faces;
13630 const vertices = geometry.vertices;
13631 const faceVertexUvs = geometry.faceVertexUvs;
13632 const hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;
13633 const hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;
13634 const morphTargets = geometry.morphTargets;
13635 const morphTargetsLength = morphTargets.length;
13636 let morphTargetsPosition;
13637 if ( morphTargetsLength > 0 ) {
13638 morphTargetsPosition = [];
13639 for ( let i = 0; i < morphTargetsLength; i ++ ) {
13640 morphTargetsPosition[ i ] = {
13641 name: morphTargets[ i ].name,
13642 data: []
13643 };
13644 }
13645 this.morphTargets.position = morphTargetsPosition;
13646 }
13647 const morphNormals = geometry.morphNormals;
13648 const morphNormalsLength = morphNormals.length;
13649 let morphTargetsNormal;
13650 if ( morphNormalsLength > 0 ) {
13651 morphTargetsNormal = [];
13652 for ( let i = 0; i < morphNormalsLength; i ++ ) {
13653 morphTargetsNormal[ i ] = {
13654 name: morphNormals[ i ].name,
13655 data: []
13656 };
13657 }
13658 this.morphTargets.normal = morphTargetsNormal;
13659 }
13660 const skinIndices = geometry.skinIndices;
13661 const skinWeights = geometry.skinWeights;
13662 const hasSkinIndices = skinIndices.length === vertices.length;
13663 const hasSkinWeights = skinWeights.length === vertices.length;
13664 if ( vertices.length > 0 && faces.length === 0 ) {
13665 console.error( 'THREE.DirectGeometry: Faceless geometries are not supported.' );
13666 }
13667 for ( let i = 0; i < faces.length; i ++ ) {
13668 const face = faces[ i ];
13669 this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );
13670 const vertexNormals = face.vertexNormals;
13671 if ( vertexNormals.length === 3 ) {
13672 this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );
13673 } else {
13674 const normal = face.normal;
13675 this.normals.push( normal, normal, normal );
13676 }
13677 const vertexColors = face.vertexColors;
13678 if ( vertexColors.length === 3 ) {
13679 this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );
13680 } else {
13681 const color = face.color;
13682 this.colors.push( color, color, color );
13683 }
13684 if ( hasFaceVertexUv === true ) {
13685 const vertexUvs = faceVertexUvs[ 0 ][ i ];
13686 if ( vertexUvs !== undefined ) {
13687 this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
13688 } else {
13689 console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );
13690 this.uvs.push( new Vector2(), new Vector2(), new Vector2() );
13691 }
13692 }
13693 if ( hasFaceVertexUv2 === true ) {
13694 const vertexUvs = faceVertexUvs[ 1 ][ i ];
13695 if ( vertexUvs !== undefined ) {
13696 this.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
13697 } else {
13698 console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );
13699 this.uvs2.push( new Vector2(), new Vector2(), new Vector2() );
13700 }
13701 }
13702 for ( let j = 0; j < morphTargetsLength; j ++ ) {
13703 const morphTarget = morphTargets[ j ].vertices;
13704 morphTargetsPosition[ j ].data.push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );
13705 }
13706 for ( let j = 0; j < morphNormalsLength; j ++ ) {
13707 const morphNormal = morphNormals[ j ].vertexNormals[ i ];
13708 morphTargetsNormal[ j ].data.push( morphNormal.a, morphNormal.b, morphNormal.c );
13709 }
13710 if ( hasSkinIndices ) {
13711 this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );
13712 }
13713 if ( hasSkinWeights ) {
13714 this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );
13715 }
13716 }
13717 this.computeGroups( geometry );
13718 this.verticesNeedUpdate = geometry.verticesNeedUpdate;
13719 this.normalsNeedUpdate = geometry.normalsNeedUpdate;
13720 this.colorsNeedUpdate = geometry.colorsNeedUpdate;
13721 this.uvsNeedUpdate = geometry.uvsNeedUpdate;
13722 this.groupsNeedUpdate = geometry.groupsNeedUpdate;
13723 if ( geometry.boundingSphere !== null ) {
13724 this.boundingSphere = geometry.boundingSphere.clone();
13725 }
13726 if ( geometry.boundingBox !== null ) {
13727 this.boundingBox = geometry.boundingBox.clone();
13728 }
13729 return this;
13730 }
13731 }
13732 function arrayMax( array ) {
13733 if ( array.length === 0 ) return - Infinity;
13734 let max = array[ 0 ];
13735 for ( let i = 1, l = array.length; i < l; ++ i ) {
13736 if ( array[ i ] > max ) max = array[ i ];
13737 }
13738 return max;
13739 }
13740 let _bufferGeometryId = 1;
13741 const _m1$2 = new Matrix4();
13742 const _obj = new Object3D();
13743 const _offset = new Vector3();
13744 const _box$2 = new Box3();
13745 const _boxMorphTargets = new Box3();
13746 const _vector$4 = new Vector3();
13747 function BufferGeometry() {
13748 Object.defineProperty( this, 'id', { value: _bufferGeometryId += 2 } );
13749 this.uuid = MathUtils.generateUUID();
13750 this.name = '';
13751 this.type = 'BufferGeometry';
13752 this.index = null;
13753 this.attributes = {};
13754 this.morphAttributes = {};
13755 this.morphTargetsRelative = false;
13756 this.groups = [];
13757 this.boundingBox = null;
13758 this.boundingSphere = null;
13759 this.drawRange = { start: 0, count: Infinity };
13760 this.userData = {};
13761 }
13762 BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
13763 constructor: BufferGeometry,
13764 isBufferGeometry: true,
13765 getIndex: function () {
13766 return this.index;
13767 },
13768 setIndex: function ( index ) {
13769 if ( Array.isArray( index ) ) {
13770 this.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );
13771 } else {
13772 this.index = index;
13773 }
13774 },
13775 getAttribute: function ( name ) {
13776 return this.attributes[ name ];
13777 },
13778 setAttribute: function ( name, attribute ) {
13779 this.attributes[ name ] = attribute;
13780 return this;
13781 },
13782 deleteAttribute: function ( name ) {
13783 delete this.attributes[ name ];
13784 return this;
13785 },
13786 addGroup: function ( start, count, materialIndex ) {
13787 this.groups.push( {
13788 start: start,
13789 count: count,
13790 materialIndex: materialIndex !== undefined ? materialIndex : 0
13791 } );
13792 },
13793 clearGroups: function () {
13794 this.groups = [];
13795 },
13796 setDrawRange: function ( start, count ) {
13797 this.drawRange.start = start;
13798 this.drawRange.count = count;
13799 },
13800 applyMatrix4: function ( matrix ) {
13801 const position = this.attributes.position;
13802 if ( position !== undefined ) {
13803 position.applyMatrix4( matrix );
13804 position.needsUpdate = true;
13805 }
13806 const normal = this.attributes.normal;
13807 if ( normal !== undefined ) {
13808 const normalMatrix = new Matrix3().getNormalMatrix( matrix );
13809 normal.applyNormalMatrix( normalMatrix );
13810 normal.needsUpdate = true;
13811 }
13812 const tangent = this.attributes.tangent;
13813 if ( tangent !== undefined ) {
13814 tangent.transformDirection( matrix );
13815 tangent.needsUpdate = true;
13816 }
13817 if ( this.boundingBox !== null ) {
13818 this.computeBoundingBox();
13819 }
13820 if ( this.boundingSphere !== null ) {
13821 this.computeBoundingSphere();
13822 }
13823 return this;
13824 },
13825 rotateX: function ( angle ) {
13826 _m1$2.makeRotationX( angle );
13827 this.applyMatrix4( _m1$2 );
13828 return this;
13829 },
13830 rotateY: function ( angle ) {
13831 _m1$2.makeRotationY( angle );
13832 this.applyMatrix4( _m1$2 );
13833 return this;
13834 },
13835 rotateZ: function ( angle ) {
13836 _m1$2.makeRotationZ( angle );
13837 this.applyMatrix4( _m1$2 );
13838 return this;
13839 },
13840 translate: function ( x, y, z ) {
13841 _m1$2.makeTranslation( x, y, z );
13842 this.applyMatrix4( _m1$2 );
13843 return this;
13844 },
13845 scale: function ( x, y, z ) {
13846 _m1$2.makeScale( x, y, z );
13847 this.applyMatrix4( _m1$2 );
13848 return this;
13849 },
13850 lookAt: function ( vector ) {
13851 _obj.lookAt( vector );
13852 _obj.updateMatrix();
13853 this.applyMatrix4( _obj.matrix );
13854 return this;
13855 },
13856 center: function () {
13857 this.computeBoundingBox();
13858 this.boundingBox.getCenter( _offset ).negate();
13859 this.translate( _offset.x, _offset.y, _offset.z );
13860 return this;
13861 },
13862 setFromObject: function ( object ) {
13863 const geometry = object.geometry;
13864 if ( object.isPoints || object.isLine ) {
13865 const positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );
13866 const colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );
13867 this.setAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );
13868 this.setAttribute( 'color', colors.copyColorsArray( geometry.colors ) );
13869 if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {
13870 const lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );
13871 this.setAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );
13872 }
13873 if ( geometry.boundingSphere !== null ) {
13874 this.boundingSphere = geometry.boundingSphere.clone();
13875 }
13876 if ( geometry.boundingBox !== null ) {
13877 this.boundingBox = geometry.boundingBox.clone();
13878 }
13879 } else if ( object.isMesh ) {
13880 if ( geometry && geometry.isGeometry ) {
13881 this.fromGeometry( geometry );
13882 }
13883 }
13884 return this;
13885 },
13886 setFromPoints: function ( points ) {
13887 const position = [];
13888 for ( let i = 0, l = points.length; i < l; i ++ ) {
13889 const point = points[ i ];
13890 position.push( point.x, point.y, point.z || 0 );
13891 }
13892 this.setAttribute( 'position', new Float32BufferAttribute( position, 3 ) );
13893 return this;
13894 },
13895 updateFromObject: function ( object ) {
13896 let geometry = object.geometry;
13897 if ( object.isMesh ) {
13898 let direct = geometry.__directGeometry;
13899 if ( geometry.elementsNeedUpdate === true ) {
13900 direct = undefined;
13901 geometry.elementsNeedUpdate = false;
13902 }
13903 if ( direct === undefined ) {
13904 return this.fromGeometry( geometry );
13905 }
13906 direct.verticesNeedUpdate = geometry.verticesNeedUpdate;
13907 direct.normalsNeedUpdate = geometry.normalsNeedUpdate;
13908 direct.colorsNeedUpdate = geometry.colorsNeedUpdate;
13909 direct.uvsNeedUpdate = geometry.uvsNeedUpdate;
13910 direct.groupsNeedUpdate = geometry.groupsNeedUpdate;
13911 geometry.verticesNeedUpdate = false;
13912 geometry.normalsNeedUpdate = false;
13913 geometry.colorsNeedUpdate = false;
13914 geometry.uvsNeedUpdate = false;
13915 geometry.groupsNeedUpdate = false;
13916 geometry = direct;
13917 }
13918 if ( geometry.verticesNeedUpdate === true ) {
13919 const attribute = this.attributes.position;
13920 if ( attribute !== undefined ) {
13921 attribute.copyVector3sArray( geometry.vertices );
13922 attribute.needsUpdate = true;
13923 }
13924 geometry.verticesNeedUpdate = false;
13925 }
13926 if ( geometry.normalsNeedUpdate === true ) {
13927 const attribute = this.attributes.normal;
13928 if ( attribute !== undefined ) {
13929 attribute.copyVector3sArray( geometry.normals );
13930 attribute.needsUpdate = true;
13931 }
13932 geometry.normalsNeedUpdate = false;
13933 }
13934 if ( geometry.colorsNeedUpdate === true ) {
13935 const attribute = this.attributes.color;
13936 if ( attribute !== undefined ) {
13937 attribute.copyColorsArray( geometry.colors );
13938 attribute.needsUpdate = true;
13939 }
13940 geometry.colorsNeedUpdate = false;
13941 }
13942 if ( geometry.uvsNeedUpdate ) {
13943 const attribute = this.attributes.uv;
13944 if ( attribute !== undefined ) {
13945 attribute.copyVector2sArray( geometry.uvs );
13946 attribute.needsUpdate = true;
13947 }
13948 geometry.uvsNeedUpdate = false;
13949 }
13950 if ( geometry.lineDistancesNeedUpdate ) {
13951 const attribute = this.attributes.lineDistance;
13952 if ( attribute !== undefined ) {
13953 attribute.copyArray( geometry.lineDistances );
13954 attribute.needsUpdate = true;
13955 }
13956 geometry.lineDistancesNeedUpdate = false;
13957 }
13958 if ( geometry.groupsNeedUpdate ) {
13959 geometry.computeGroups( object.geometry );
13960 this.groups = geometry.groups;
13961 geometry.groupsNeedUpdate = false;
13962 }
13963 return this;
13964 },
13965 fromGeometry: function ( geometry ) {
13966 geometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );
13967 return this.fromDirectGeometry( geometry.__directGeometry );
13968 },
13969 fromDirectGeometry: function ( geometry ) {
13970 const positions = new Float32Array( geometry.vertices.length * 3 );
13971 this.setAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );
13972 if ( geometry.normals.length > 0 ) {
13973 const normals = new Float32Array( geometry.normals.length * 3 );
13974 this.setAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );
13975 }
13976 if ( geometry.colors.length > 0 ) {
13977 const colors = new Float32Array( geometry.colors.length * 3 );
13978 this.setAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );
13979 }
13980 if ( geometry.uvs.length > 0 ) {
13981 const uvs = new Float32Array( geometry.uvs.length * 2 );
13982 this.setAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );
13983 }
13984 if ( geometry.uvs2.length > 0 ) {
13985 const uvs2 = new Float32Array( geometry.uvs2.length * 2 );
13986 this.setAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );
13987 }
13988 this.groups = geometry.groups;
13989 for ( const name in geometry.morphTargets ) {
13990 const array = [];
13991 const morphTargets = geometry.morphTargets[ name ];
13992 for ( let i = 0, l = morphTargets.length; i < l; i ++ ) {
13993 const morphTarget = morphTargets[ i ];
13994 const attribute = new Float32BufferAttribute( morphTarget.data.length * 3, 3 );
13995 attribute.name = morphTarget.name;
13996 array.push( attribute.copyVector3sArray( morphTarget.data ) );
13997 }
13998 this.morphAttributes[ name ] = array;
13999 }
14000 if ( geometry.skinIndices.length > 0 ) {
14001 const skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );
14002 this.setAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );
14003 }
14004 if ( geometry.skinWeights.length > 0 ) {
14005 const skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );
14006 this.setAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );
14007 }
14008 if ( geometry.boundingSphere !== null ) {
14009 this.boundingSphere = geometry.boundingSphere.clone();
14010 }
14011 if ( geometry.boundingBox !== null ) {
14012 this.boundingBox = geometry.boundingBox.clone();
14013 }
14014 return this;
14015 },
14016 computeBoundingBox: function () {
14017 if ( this.boundingBox === null ) {
14018 this.boundingBox = new Box3();
14019 }
14020 const position = this.attributes.position;
14021 const morphAttributesPosition = this.morphAttributes.position;
14022 if ( position && position.isGLBufferAttribute ) {
14023 console.error( 'THREE.BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box. Alternatively set "mesh.frustumCulled" to "false".', this );
14024 this.boundingBox.set(
14025 new Vector3( - Infinity, - Infinity, - Infinity ),
14026 new Vector3( + Infinity, + Infinity, + Infinity )
14027 );
14028 return;
14029 }
14030 if ( position !== undefined ) {
14031 this.boundingBox.setFromBufferAttribute( position );
14032 if ( morphAttributesPosition ) {
14033 for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
14034 const morphAttribute = morphAttributesPosition[ i ];
14035 _box$2.setFromBufferAttribute( morphAttribute );
14036 if ( this.morphTargetsRelative ) {
14037 _vector$4.addVectors( this.boundingBox.min, _box$2.min );
14038 this.boundingBox.expandByPoint( _vector$4 );
14039 _vector$4.addVectors( this.boundingBox.max, _box$2.max );
14040 this.boundingBox.expandByPoint( _vector$4 );
14041 } else {
14042 this.boundingBox.expandByPoint( _box$2.min );
14043 this.boundingBox.expandByPoint( _box$2.max );
14044 }
14045 }
14046 }
14047 } else {
14048 this.boundingBox.makeEmpty();
14049 }
14050 if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {
14051 console.error( 'THREE.BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this );
14052 }
14053 },
14054 computeBoundingSphere: function () {
14055 if ( this.boundingSphere === null ) {
14056 this.boundingSphere = new Sphere();
14057 }
14058 const position = this.attributes.position;
14059 const morphAttributesPosition = this.morphAttributes.position;
14060 if ( position && position.isGLBufferAttribute ) {
14061 console.error( 'THREE.BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere. Alternatively set "mesh.frustumCulled" to "false".', this );
14062 this.boundingSphere.set( new Vector3(), Infinity );
14063 return;
14064 }
14065 if ( position ) {
14066 const center = this.boundingSphere.center;
14067 _box$2.setFromBufferAttribute( position );
14068 if ( morphAttributesPosition ) {
14069 for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
14070 const morphAttribute = morphAttributesPosition[ i ];
14071 _boxMorphTargets.setFromBufferAttribute( morphAttribute );
14072 if ( this.morphTargetsRelative ) {
14073 _vector$4.addVectors( _box$2.min, _boxMorphTargets.min );
14074 _box$2.expandByPoint( _vector$4 );
14075 _vector$4.addVectors( _box$2.max, _boxMorphTargets.max );
14076 _box$2.expandByPoint( _vector$4 );
14077 } else {
14078 _box$2.expandByPoint( _boxMorphTargets.min );
14079 _box$2.expandByPoint( _boxMorphTargets.max );
14080 }
14081 }
14082 }
14083 _box$2.getCenter( center );
14084 let maxRadiusSq = 0;
14085 for ( let i = 0, il = position.count; i < il; i ++ ) {
14086 _vector$4.fromBufferAttribute( position, i );
14087 maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$4 ) );
14088 }
14089 if ( morphAttributesPosition ) {
14090 for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
14091 const morphAttribute = morphAttributesPosition[ i ];
14092 const morphTargetsRelative = this.morphTargetsRelative;
14093 for ( let j = 0, jl = morphAttribute.count; j < jl; j ++ ) {
14094 _vector$4.fromBufferAttribute( morphAttribute, j );
14095 if ( morphTargetsRelative ) {
14096 _offset.fromBufferAttribute( position, j );
14097 _vector$4.add( _offset );
14098 }
14099 maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$4 ) );
14100 }
14101 }
14102 }
14103 this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
14104 if ( isNaN( this.boundingSphere.radius ) ) {
14105 console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this );
14106 }
14107 }
14108 },
14109 computeFaceNormals: function () {
14110 },
14111 computeVertexNormals: function () {
14112 const index = this.index;
14113 const positionAttribute = this.getAttribute( 'position' );
14114 if ( positionAttribute !== undefined ) {
14115 let normalAttribute = this.getAttribute( 'normal' );
14116 if ( normalAttribute === undefined ) {
14117 normalAttribute = new BufferAttribute( new Float32Array( positionAttribute.count * 3 ), 3 );
14118 this.setAttribute( 'normal', normalAttribute );
14119 } else {
14120 for ( let i = 0, il = normalAttribute.count; i < il; i ++ ) {
14121 normalAttribute.setXYZ( i, 0, 0, 0 );
14122 }
14123 }
14124 const pA = new Vector3(), pB = new Vector3(), pC = new Vector3();
14125 const nA = new Vector3(), nB = new Vector3(), nC = new Vector3();
14126 const cb = new Vector3(), ab = new Vector3();
14127 if ( index ) {
14128 for ( let i = 0, il = index.count; i < il; i += 3 ) {
14129 const vA = index.getX( i + 0 );
14130 const vB = index.getX( i + 1 );
14131 const vC = index.getX( i + 2 );
14132 pA.fromBufferAttribute( positionAttribute, vA );
14133 pB.fromBufferAttribute( positionAttribute, vB );
14134 pC.fromBufferAttribute( positionAttribute, vC );
14135 cb.subVectors( pC, pB );
14136 ab.subVectors( pA, pB );
14137 cb.cross( ab );
14138 nA.fromBufferAttribute( normalAttribute, vA );
14139 nB.fromBufferAttribute( normalAttribute, vB );
14140 nC.fromBufferAttribute( normalAttribute, vC );
14141 nA.add( cb );
14142 nB.add( cb );
14143 nC.add( cb );
14144 normalAttribute.setXYZ( vA, nA.x, nA.y, nA.z );
14145 normalAttribute.setXYZ( vB, nB.x, nB.y, nB.z );
14146 normalAttribute.setXYZ( vC, nC.x, nC.y, nC.z );
14147 }
14148 } else {
14149 for ( let i = 0, il = positionAttribute.count; i < il; i += 3 ) {
14150 pA.fromBufferAttribute( positionAttribute, i + 0 );
14151 pB.fromBufferAttribute( positionAttribute, i + 1 );
14152 pC.fromBufferAttribute( positionAttribute, i + 2 );
14153 cb.subVectors( pC, pB );
14154 ab.subVectors( pA, pB );
14155 cb.cross( ab );
14156 normalAttribute.setXYZ( i + 0, cb.x, cb.y, cb.z );
14157 normalAttribute.setXYZ( i + 1, cb.x, cb.y, cb.z );
14158 normalAttribute.setXYZ( i + 2, cb.x, cb.y, cb.z );
14159 }
14160 }
14161 this.normalizeNormals();
14162 normalAttribute.needsUpdate = true;
14163 }
14164 },
14165 merge: function ( geometry, offset ) {
14166 if ( ! ( geometry && geometry.isBufferGeometry ) ) {
14167 console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );
14168 return;
14169 }
14170 if ( offset === undefined ) {
14171 offset = 0;
14172 console.warn(
14173 'THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. '
14174 + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.'
14175 );
14176 }
14177 const attributes = this.attributes;
14178 for ( const key in attributes ) {
14179 if ( geometry.attributes[ key ] === undefined ) continue;
14180 const attribute1 = attributes[ key ];
14181 const attributeArray1 = attribute1.array;
14182 const attribute2 = geometry.attributes[ key ];
14183 const attributeArray2 = attribute2.array;
14184 const attributeOffset = attribute2.itemSize * offset;
14185 const length = Math.min( attributeArray2.length, attributeArray1.length - attributeOffset );
14186 for ( let i = 0, j = attributeOffset; i < length; i ++, j ++ ) {
14187 attributeArray1[ j ] = attributeArray2[ i ];
14188 }
14189 }
14190 return this;
14191 },
14192 normalizeNormals: function () {
14193 const normals = this.attributes.normal;
14194 for ( let i = 0, il = normals.count; i < il; i ++ ) {
14195 _vector$4.fromBufferAttribute( normals, i );
14196 _vector$4.normalize();
14197 normals.setXYZ( i, _vector$4.x, _vector$4.y, _vector$4.z );
14198 }
14199 },
14200 toNonIndexed: function () {
14201 function convertBufferAttribute( attribute, indices ) {
14202 const array = attribute.array;
14203 const itemSize = attribute.itemSize;
14204 const normalized = attribute.normalized;
14205 const array2 = new array.constructor( indices.length * itemSize );
14206 let index = 0, index2 = 0;
14207 for ( let i = 0, l = indices.length; i < l; i ++ ) {
14208 index = indices[ i ] * itemSize;
14209 for ( let j = 0; j < itemSize; j ++ ) {
14210 array2[ index2 ++ ] = array[ index ++ ];
14211 }
14212 }
14213 return new BufferAttribute( array2, itemSize, normalized );
14214 }
14215 if ( this.index === null ) {
14216 console.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );
14217 return this;
14218 }
14219 const geometry2 = new BufferGeometry();
14220 const indices = this.index.array;
14221 const attributes = this.attributes;
14222 for ( const name in attributes ) {
14223 const attribute = attributes[ name ];
14224 const newAttribute = convertBufferAttribute( attribute, indices );
14225 geometry2.setAttribute( name, newAttribute );
14226 }
14227 const morphAttributes = this.morphAttributes;
14228 for ( const name in morphAttributes ) {
14229 const morphArray = [];
14230 const morphAttribute = morphAttributes[ name ];
14231 for ( let i = 0, il = morphAttribute.length; i < il; i ++ ) {
14232 const attribute = morphAttribute[ i ];
14233 const newAttribute = convertBufferAttribute( attribute, indices );
14234 morphArray.push( newAttribute );
14235 }
14236 geometry2.morphAttributes[ name ] = morphArray;
14237 }
14238 geometry2.morphTargetsRelative = this.morphTargetsRelative;
14239 const groups = this.groups;
14240 for ( let i = 0, l = groups.length; i < l; i ++ ) {
14241 const group = groups[ i ];
14242 geometry2.addGroup( group.start, group.count, group.materialIndex );
14243 }
14244 return geometry2;
14245 },
14246 toJSON: function () {
14247 const data = {
14248 metadata: {
14249 version: 4.5,
14250 type: 'BufferGeometry',
14251 generator: 'BufferGeometry.toJSON'
14252 }
14253 };
14254 data.uuid = this.uuid;
14255 data.type = this.type;
14256 if ( this.name !== '' ) data.name = this.name;
14257 if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData;
14258 if ( this.parameters !== undefined ) {
14259 const parameters = this.parameters;
14260 for ( const key in parameters ) {
14261 if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];
14262 }
14263 return data;
14264 }
14265 data.data = { attributes: {} };
14266 const index = this.index;
14267 if ( index !== null ) {
14268 data.data.index = {
14269 type: index.array.constructor.name,
14270 array: Array.prototype.slice.call( index.array )
14271 };
14272 }
14273 const attributes = this.attributes;
14274 for ( const key in attributes ) {
14275 const attribute = attributes[ key ];
14276 const attributeData = attribute.toJSON( data.data );
14277 if ( attribute.name !== '' ) attributeData.name = attribute.name;
14278 data.data.attributes[ key ] = attributeData;
14279 }
14280 const morphAttributes = {};
14281 let hasMorphAttributes = false;
14282 for ( const key in this.morphAttributes ) {
14283 const attributeArray = this.morphAttributes[ key ];
14284 const array = [];
14285 for ( let i = 0, il = attributeArray.length; i < il; i ++ ) {
14286 const attribute = attributeArray[ i ];
14287 const attributeData = attribute.toJSON( data.data );
14288 if ( attribute.name !== '' ) attributeData.name = attribute.name;
14289 array.push( attributeData );
14290 }
14291 if ( array.length > 0 ) {
14292 morphAttributes[ key ] = array;
14293 hasMorphAttributes = true;
14294 }
14295 }
14296 if ( hasMorphAttributes ) {
14297 data.data.morphAttributes = morphAttributes;
14298 data.data.morphTargetsRelative = this.morphTargetsRelative;
14299 }
14300 const groups = this.groups;
14301 if ( groups.length > 0 ) {
14302 data.data.groups = JSON.parse( JSON.stringify( groups ) );
14303 }
14304 const boundingSphere = this.boundingSphere;
14305 if ( boundingSphere !== null ) {
14306 data.data.boundingSphere = {
14307 center: boundingSphere.center.toArray(),
14308 radius: boundingSphere.radius
14309 };
14310 }
14311 return data;
14312 },
14313 clone: function () {
14314 return new BufferGeometry().copy( this );
14315 },
14316 copy: function ( source ) {
14317 this.index = null;
14318 this.attributes = {};
14319 this.morphAttributes = {};
14320 this.groups = [];
14321 this.boundingBox = null;
14322 this.boundingSphere = null;
14323 const data = {};
14324 this.name = source.name;
14325 const index = source.index;
14326 if ( index !== null ) {
14327 this.setIndex( index.clone( data ) );
14328 }
14329 const attributes = source.attributes;
14330 for ( const name in attributes ) {
14331 const attribute = attributes[ name ];
14332 this.setAttribute( name, attribute.clone( data ) );
14333 }
14334 const morphAttributes = source.morphAttributes;
14335 for ( const name in morphAttributes ) {
14336 const array = [];
14337 const morphAttribute = morphAttributes[ name ];
14338 for ( let i = 0, l = morphAttribute.length; i < l; i ++ ) {
14339 array.push( morphAttribute[ i ].clone( data ) );
14340 }
14341 this.morphAttributes[ name ] = array;
14342 }
14343 this.morphTargetsRelative = source.morphTargetsRelative;
14344 const groups = source.groups;
14345 for ( let i = 0, l = groups.length; i < l; i ++ ) {
14346 const group = groups[ i ];
14347 this.addGroup( group.start, group.count, group.materialIndex );
14348 }
14349 const boundingBox = source.boundingBox;
14350 if ( boundingBox !== null ) {
14351 this.boundingBox = boundingBox.clone();
14352 }
14353 const boundingSphere = source.boundingSphere;
14354 if ( boundingSphere !== null ) {
14355 this.boundingSphere = boundingSphere.clone();
14356 }
14357 this.drawRange.start = source.drawRange.start;
14358 this.drawRange.count = source.drawRange.count;
14359 this.userData = source.userData;
14360 return this;
14361 },
14362 dispose: function () {
14363 this.dispatchEvent( { type: 'dispose' } );
14364 }
14365 } );
14366 const _inverseMatrix = new Matrix4();
14367 const _ray = new Ray();
14368 const _sphere = new Sphere();
14369 const _vA = new Vector3();
14370 const _vB = new Vector3();
14371 const _vC = new Vector3();
14372 const _tempA = new Vector3();
14373 const _tempB = new Vector3();
14374 const _tempC = new Vector3();
14375 const _morphA = new Vector3();
14376 const _morphB = new Vector3();
14377 const _morphC = new Vector3();
14378 const _uvA = new Vector2();
14379 const _uvB = new Vector2();
14380 const _uvC = new Vector2();
14381 const _intersectionPoint = new Vector3();
14382 const _intersectionPointWorld = new Vector3();
14383 function Mesh( geometry, material ) {
14384 Object3D.call( this );
14385 this.type = 'Mesh';
14386 this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
14387 this.material = material !== undefined ? material : new MeshBasicMaterial();
14388 this.updateMorphTargets();
14389 }
14390 Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
14391 constructor: Mesh,
14392 isMesh: true,
14393 copy: function ( source ) {
14394 Object3D.prototype.copy.call( this, source );
14395 if ( source.morphTargetInfluences !== undefined ) {
14396 this.morphTargetInfluences = source.morphTargetInfluences.slice();
14397 }
14398 if ( source.morphTargetDictionary !== undefined ) {
14399 this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary );
14400 }
14401 this.material = source.material;
14402 this.geometry = source.geometry;
14403 return this;
14404 },
14405 updateMorphTargets: function () {
14406 const geometry = this.geometry;
14407 if ( geometry.isBufferGeometry ) {
14408 const morphAttributes = geometry.morphAttributes;
14409 const keys = Object.keys( morphAttributes );
14410 if ( keys.length > 0 ) {
14411 const morphAttribute = morphAttributes[ keys[ 0 ] ];
14412 if ( morphAttribute !== undefined ) {
14413 this.morphTargetInfluences = [];
14414 this.morphTargetDictionary = {};
14415 for ( let m = 0, ml = morphAttribute.length; m < ml; m ++ ) {
14416 const name = morphAttribute[ m ].name || String( m );
14417 this.morphTargetInfluences.push( 0 );
14418 this.morphTargetDictionary[ name ] = m;
14419 }
14420 }
14421 }
14422 } else {
14423 const morphTargets = geometry.morphTargets;
14424 if ( morphTargets !== undefined && morphTargets.length > 0 ) {
14425 console.error( 'THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );
14426 }
14427 }
14428 },
14429 raycast: function ( raycaster, intersects ) {
14430 const geometry = this.geometry;
14431 const material = this.material;
14432 const matrixWorld = this.matrixWorld;
14433 if ( material === undefined ) return;
14434 if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
14435 _sphere.copy( geometry.boundingSphere );
14436 _sphere.applyMatrix4( matrixWorld );
14437 if ( raycaster.ray.intersectsSphere( _sphere ) === false ) return;
14438 _inverseMatrix.getInverse( matrixWorld );
14439 _ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
14440 if ( geometry.boundingBox !== null ) {
14441 if ( _ray.intersectsBox( geometry.boundingBox ) === false ) return;
14442 }
14443 let intersection;
14444 if ( geometry.isBufferGeometry ) {
14445 const index = geometry.index;
14446 const position = geometry.attributes.position;
14447 const morphPosition = geometry.morphAttributes.position;
14448 const morphTargetsRelative = geometry.morphTargetsRelative;
14449 const uv = geometry.attributes.uv;
14450 const uv2 = geometry.attributes.uv2;
14451 const groups = geometry.groups;
14452 const drawRange = geometry.drawRange;
14453 if ( index !== null ) {
14454 if ( Array.isArray( material ) ) {
14455 for ( let i = 0, il = groups.length; i < il; i ++ ) {
14456 const group = groups[ i ];
14457 const groupMaterial = material[ group.materialIndex ];
14458 const start = Math.max( group.start, drawRange.start );
14459 const end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
14460 for ( let j = start, jl = end; j < jl; j += 3 ) {
14461 const a = index.getX( j );
14462 const b = index.getX( j + 1 );
14463 const c = index.getX( j + 2 );
14464 intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
14465 if ( intersection ) {
14466 intersection.faceIndex = Math.floor( j / 3 );
14467 intersection.face.materialIndex = group.materialIndex;
14468 intersects.push( intersection );
14469 }
14470 }
14471 }
14472 } else {
14473 const start = Math.max( 0, drawRange.start );
14474 const end = Math.min( index.count, ( drawRange.start + drawRange.count ) );
14475 for ( let i = start, il = end; i < il; i += 3 ) {
14476 const a = index.getX( i );
14477 const b = index.getX( i + 1 );
14478 const c = index.getX( i + 2 );
14479 intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
14480 if ( intersection ) {
14481 intersection.faceIndex = Math.floor( i / 3 );
14482 intersects.push( intersection );
14483 }
14484 }
14485 }
14486 } else if ( position !== undefined ) {
14487 if ( Array.isArray( material ) ) {
14488 for ( let i = 0, il = groups.length; i < il; i ++ ) {
14489 const group = groups[ i ];
14490 const groupMaterial = material[ group.materialIndex ];
14491 const start = Math.max( group.start, drawRange.start );
14492 const end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
14493 for ( let j = start, jl = end; j < jl; j += 3 ) {
14494 const a = j;
14495 const b = j + 1;
14496 const c = j + 2;
14497 intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
14498 if ( intersection ) {
14499 intersection.faceIndex = Math.floor( j / 3 );
14500 intersection.face.materialIndex = group.materialIndex;
14501 intersects.push( intersection );
14502 }
14503 }
14504 }
14505 } else {
14506 const start = Math.max( 0, drawRange.start );
14507 const end = Math.min( position.count, ( drawRange.start + drawRange.count ) );
14508 for ( let i = start, il = end; i < il; i += 3 ) {
14509 const a = i;
14510 const b = i + 1;
14511 const c = i + 2;
14512 intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
14513 if ( intersection ) {
14514 intersection.faceIndex = Math.floor( i / 3 );
14515 intersects.push( intersection );
14516 }
14517 }
14518 }
14519 }
14520 } else if ( geometry.isGeometry ) {
14521 const isMultiMaterial = Array.isArray( material );
14522 const vertices = geometry.vertices;
14523 const faces = geometry.faces;
14524 let uvs;
14525 const faceVertexUvs = geometry.faceVertexUvs[ 0 ];
14526 if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;
14527 for ( let f = 0, fl = faces.length; f < fl; f ++ ) {
14528 const face = faces[ f ];
14529 const faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material;
14530 if ( faceMaterial === undefined ) continue;
14531 const fvA = vertices[ face.a ];
14532 const fvB = vertices[ face.b ];
14533 const fvC = vertices[ face.c ];
14534 intersection = checkIntersection( this, faceMaterial, raycaster, _ray, fvA, fvB, fvC, _intersectionPoint );
14535 if ( intersection ) {
14536 if ( uvs && uvs[ f ] ) {
14537 const uvs_f = uvs[ f ];
14538 _uvA.copy( uvs_f[ 0 ] );
14539 _uvB.copy( uvs_f[ 1 ] );
14540 _uvC.copy( uvs_f[ 2 ] );
14541 intersection.uv = Triangle.getUV( _intersectionPoint, fvA, fvB, fvC, _uvA, _uvB, _uvC, new Vector2() );
14542 }
14543 intersection.face = face;
14544 intersection.faceIndex = f;
14545 intersects.push( intersection );
14546 }
14547 }
14548 }
14549 }
14550 } );
14551 function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) {
14552 let intersect;
14553 if ( material.side === BackSide ) {
14554 intersect = ray.intersectTriangle( pC, pB, pA, true, point );
14555 } else {
14556 intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );
14557 }
14558 if ( intersect === null ) return null;
14559 _intersectionPointWorld.copy( point );
14560 _intersectionPointWorld.applyMatrix4( object.matrixWorld );
14561 const distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld );
14562 if ( distance < raycaster.near || distance > raycaster.far ) return null;
14563 return {
14564 distance: distance,
14565 point: _intersectionPointWorld.clone(),
14566 object: object
14567 };
14568 }
14569 function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ) {
14570 _vA.fromBufferAttribute( position, a );
14571 _vB.fromBufferAttribute( position, b );
14572 _vC.fromBufferAttribute( position, c );
14573 const morphInfluences = object.morphTargetInfluences;
14574 if ( material.morphTargets && morphPosition && morphInfluences ) {
14575 _morphA.set( 0, 0, 0 );
14576 _morphB.set( 0, 0, 0 );
14577 _morphC.set( 0, 0, 0 );
14578 for ( let i = 0, il = morphPosition.length; i < il; i ++ ) {
14579 const influence = morphInfluences[ i ];
14580 const morphAttribute = morphPosition[ i ];
14581 if ( influence === 0 ) continue;
14582 _tempA.fromBufferAttribute( morphAttribute, a );
14583 _tempB.fromBufferAttribute( morphAttribute, b );
14584 _tempC.fromBufferAttribute( morphAttribute, c );
14585 if ( morphTargetsRelative ) {
14586 _morphA.addScaledVector( _tempA, influence );
14587 _morphB.addScaledVector( _tempB, influence );
14588 _morphC.addScaledVector( _tempC, influence );
14589 } else {
14590 _morphA.addScaledVector( _tempA.sub( _vA ), influence );
14591 _morphB.addScaledVector( _tempB.sub( _vB ), influence );
14592 _morphC.addScaledVector( _tempC.sub( _vC ), influence );
14593 }
14594 }
14595 _vA.add( _morphA );
14596 _vB.add( _morphB );
14597 _vC.add( _morphC );
14598 }
14599 if ( object.isSkinnedMesh ) {
14600 object.boneTransform( a, _vA );
14601 object.boneTransform( b, _vB );
14602 object.boneTransform( c, _vC );
14603 }
14604 const intersection = checkIntersection( object, material, raycaster, ray, _vA, _vB, _vC, _intersectionPoint );
14605 if ( intersection ) {
14606 if ( uv ) {
14607 _uvA.fromBufferAttribute( uv, a );
14608 _uvB.fromBufferAttribute( uv, b );
14609 _uvC.fromBufferAttribute( uv, c );
14610 intersection.uv = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() );
14611 }
14612 if ( uv2 ) {
14613 _uvA.fromBufferAttribute( uv2, a );
14614 _uvB.fromBufferAttribute( uv2, b );
14615 _uvC.fromBufferAttribute( uv2, c );
14616 intersection.uv2 = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() );
14617 }
14618 const face = new Face3( a, b, c );
14619 Triangle.getNormal( _vA, _vB, _vC, face.normal );
14620 intersection.face = face;
14621 }
14622 return intersection;
14623 }
14624 let _geometryId = 0;
14625 const _m1$3 = new Matrix4();
14626 const _obj$1 = new Object3D();
14627 const _offset$1 = new Vector3();
14628 function Geometry() {
14629 Object.defineProperty( this, 'id', { value: _geometryId += 2 } );
14630 this.uuid = MathUtils.generateUUID();
14631 this.name = '';
14632 this.type = 'Geometry';
14633 this.vertices = [];
14634 this.colors = [];
14635 this.faces = [];
14636 this.faceVertexUvs = [[]];
14637 this.morphTargets = [];
14638 this.morphNormals = [];
14639 this.skinWeights = [];
14640 this.skinIndices = [];
14641 this.lineDistances = [];
14642 this.boundingBox = null;
14643 this.boundingSphere = null;
14644 this.elementsNeedUpdate = false;
14645 this.verticesNeedUpdate = false;
14646 this.uvsNeedUpdate = false;
14647 this.normalsNeedUpdate = false;
14648 this.colorsNeedUpdate = false;
14649 this.lineDistancesNeedUpdate = false;
14650 this.groupsNeedUpdate = false;
14651 }
14652 Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
14653 constructor: Geometry,
14654 isGeometry: true,
14655 applyMatrix4: function ( matrix ) {
14656 const normalMatrix = new Matrix3().getNormalMatrix( matrix );
14657 for ( let i = 0, il = this.vertices.length; i < il; i ++ ) {
14658 const vertex = this.vertices[ i ];
14659 vertex.applyMatrix4( matrix );
14660 }
14661 for ( let i = 0, il = this.faces.length; i < il; i ++ ) {
14662 const face = this.faces[ i ];
14663 face.normal.applyMatrix3( normalMatrix ).normalize();
14664 for ( let j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
14665 face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();
14666 }
14667 }
14668 if ( this.boundingBox !== null ) {
14669 this.computeBoundingBox();
14670 }
14671 if ( this.boundingSphere !== null ) {
14672 this.computeBoundingSphere();
14673 }
14674 this.verticesNeedUpdate = true;
14675 this.normalsNeedUpdate = true;
14676 return this;
14677 },
14678 rotateX: function ( angle ) {
14679 _m1$3.makeRotationX( angle );
14680 this.applyMatrix4( _m1$3 );
14681 return this;
14682 },
14683 rotateY: function ( angle ) {
14684 _m1$3.makeRotationY( angle );
14685 this.applyMatrix4( _m1$3 );
14686 return this;
14687 },
14688 rotateZ: function ( angle ) {
14689 _m1$3.makeRotationZ( angle );
14690 this.applyMatrix4( _m1$3 );
14691 return this;
14692 },
14693 translate: function ( x, y, z ) {
14694 _m1$3.makeTranslation( x, y, z );
14695 this.applyMatrix4( _m1$3 );
14696 return this;
14697 },
14698 scale: function ( x, y, z ) {
14699 _m1$3.makeScale( x, y, z );
14700 this.applyMatrix4( _m1$3 );
14701 return this;
14702 },
14703 lookAt: function ( vector ) {
14704 _obj$1.lookAt( vector );
14705 _obj$1.updateMatrix();
14706 this.applyMatrix4( _obj$1.matrix );
14707 return this;
14708 },
14709 fromBufferGeometry: function ( geometry ) {
14710 const scope = this;
14711 const index = geometry.index !== null ? geometry.index : undefined;
14712 const attributes = geometry.attributes;
14713 if ( attributes.position === undefined ) {
14714 console.error( 'THREE.Geometry.fromBufferGeometry(): Position attribute required for conversion.' );
14715 return this;
14716 }
14717 const position = attributes.position;
14718 const normal = attributes.normal;
14719 const color = attributes.color;
14720 const uv = attributes.uv;
14721 const uv2 = attributes.uv2;
14722 if ( uv2 !== undefined ) this.faceVertexUvs[ 1 ] = [];
14723 for ( let i = 0; i < position.count; i ++ ) {
14724 scope.vertices.push( new Vector3().fromBufferAttribute( position, i ) );
14725 if ( color !== undefined ) {
14726 scope.colors.push( new Color().fromBufferAttribute( color, i ) );
14727 }
14728 }
14729 function addFace( a, b, c, materialIndex ) {
14730 const vertexColors = ( color === undefined ) ? [] : [
14731 scope.colors[ a ].clone(),
14732 scope.colors[ b ].clone(),
14733 scope.colors[ c ].clone()
14734 ];
14735 const vertexNormals = ( normal === undefined ) ? [] : [
14736 new Vector3().fromBufferAttribute( normal, a ),
14737 new Vector3().fromBufferAttribute( normal, b ),
14738 new Vector3().fromBufferAttribute( normal, c )
14739 ];
14740 const face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );
14741 scope.faces.push( face );
14742 if ( uv !== undefined ) {
14743 scope.faceVertexUvs[ 0 ].push( [
14744 new Vector2().fromBufferAttribute( uv, a ),
14745 new Vector2().fromBufferAttribute( uv, b ),
14746 new Vector2().fromBufferAttribute( uv, c )
14747 ] );
14748 }
14749 if ( uv2 !== undefined ) {
14750 scope.faceVertexUvs[ 1 ].push( [
14751 new Vector2().fromBufferAttribute( uv2, a ),
14752 new Vector2().fromBufferAttribute( uv2, b ),
14753 new Vector2().fromBufferAttribute( uv2, c )
14754 ] );
14755 }
14756 }
14757 const groups = geometry.groups;
14758 if ( groups.length > 0 ) {
14759 for ( let i = 0; i < groups.length; i ++ ) {
14760 const group = groups[ i ];
14761 const start = group.start;
14762 const count = group.count;
14763 for ( let j = start, jl = start + count; j < jl; j += 3 ) {
14764 if ( index !== undefined ) {
14765 addFace( index.getX( j ), index.getX( j + 1 ), index.getX( j + 2 ), group.materialIndex );
14766 } else {
14767 addFace( j, j + 1, j + 2, group.materialIndex );
14768 }
14769 }
14770 }
14771 } else {
14772 if ( index !== undefined ) {
14773 for ( let i = 0; i < index.count; i += 3 ) {
14774 addFace( index.getX( i ), index.getX( i + 1 ), index.getX( i + 2 ) );
14775 }
14776 } else {
14777 for ( let i = 0; i < position.count; i += 3 ) {
14778 addFace( i, i + 1, i + 2 );
14779 }
14780 }
14781 }
14782 this.computeFaceNormals();
14783 if ( geometry.boundingBox !== null ) {
14784 this.boundingBox = geometry.boundingBox.clone();
14785 }
14786 if ( geometry.boundingSphere !== null ) {
14787 this.boundingSphere = geometry.boundingSphere.clone();
14788 }
14789 return this;
14790 },
14791 center: function () {
14792 this.computeBoundingBox();
14793 this.boundingBox.getCenter( _offset$1 ).negate();
14794 this.translate( _offset$1.x, _offset$1.y, _offset$1.z );
14795 return this;
14796 },
14797 normalize: function () {
14798 this.computeBoundingSphere();
14799 const center = this.boundingSphere.center;
14800 const radius = this.boundingSphere.radius;
14801 const s = radius === 0 ? 1 : 1.0 / radius;
14802 const matrix = new Matrix4();
14803 matrix.set(
14804 s, 0, 0, - s * center.x,
14805 0, s, 0, - s * center.y,
14806 0, 0, s, - s * center.z,
14807 0, 0, 0, 1
14808 );
14809 this.applyMatrix4( matrix );
14810 return this;
14811 },
14812 computeFaceNormals: function () {
14813 const cb = new Vector3(), ab = new Vector3();
14814 for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
14815 const face = this.faces[ f ];
14816 const vA = this.vertices[ face.a ];
14817 const vB = this.vertices[ face.b ];
14818 const vC = this.vertices[ face.c ];
14819 cb.subVectors( vC, vB );
14820 ab.subVectors( vA, vB );
14821 cb.cross( ab );
14822 cb.normalize();
14823 face.normal.copy( cb );
14824 }
14825 },
14826 computeVertexNormals: function ( areaWeighted ) {
14827 if ( areaWeighted === undefined ) areaWeighted = true;
14828 const vertices = new Array( this.vertices.length );
14829 for ( let v = 0, vl = this.vertices.length; v < vl; v ++ ) {
14830 vertices[ v ] = new Vector3();
14831 }
14832 if ( areaWeighted ) {
14833 const cb = new Vector3(), ab = new Vector3();
14834 for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
14835 const face = this.faces[ f ];
14836 const vA = this.vertices[ face.a ];
14837 const vB = this.vertices[ face.b ];
14838 const vC = this.vertices[ face.c ];
14839 cb.subVectors( vC, vB );
14840 ab.subVectors( vA, vB );
14841 cb.cross( ab );
14842 vertices[ face.a ].add( cb );
14843 vertices[ face.b ].add( cb );
14844 vertices[ face.c ].add( cb );
14845 }
14846 } else {
14847 this.computeFaceNormals();
14848 for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
14849 const face = this.faces[ f ];
14850 vertices[ face.a ].add( face.normal );
14851 vertices[ face.b ].add( face.normal );
14852 vertices[ face.c ].add( face.normal );
14853 }
14854 }
14855 for ( let v = 0, vl = this.vertices.length; v < vl; v ++ ) {
14856 vertices[ v ].normalize();
14857 }
14858 for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
14859 const face = this.faces[ f ];
14860 const vertexNormals = face.vertexNormals;
14861 if ( vertexNormals.length === 3 ) {
14862 vertexNormals[ 0 ].copy( vertices[ face.a ] );
14863 vertexNormals[ 1 ].copy( vertices[ face.b ] );
14864 vertexNormals[ 2 ].copy( vertices[ face.c ] );
14865 } else {
14866 vertexNormals[ 0 ] = vertices[ face.a ].clone();
14867 vertexNormals[ 1 ] = vertices[ face.b ].clone();
14868 vertexNormals[ 2 ] = vertices[ face.c ].clone();
14869 }
14870 }
14871 if ( this.faces.length > 0 ) {
14872 this.normalsNeedUpdate = true;
14873 }
14874 },
14875 computeFlatVertexNormals: function () {
14876 this.computeFaceNormals();
14877 for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
14878 const face = this.faces[ f ];
14879 const vertexNormals = face.vertexNormals;
14880 if ( vertexNormals.length === 3 ) {
14881 vertexNormals[ 0 ].copy( face.normal );
14882 vertexNormals[ 1 ].copy( face.normal );
14883 vertexNormals[ 2 ].copy( face.normal );
14884 } else {
14885 vertexNormals[ 0 ] = face.normal.clone();
14886 vertexNormals[ 1 ] = face.normal.clone();
14887 vertexNormals[ 2 ] = face.normal.clone();
14888 }
14889 }
14890 if ( this.faces.length > 0 ) {
14891 this.normalsNeedUpdate = true;
14892 }
14893 },
14894 computeMorphNormals: function () {
14895 for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
14896 const face = this.faces[ f ];
14897 if ( ! face.__originalFaceNormal ) {
14898 face.__originalFaceNormal = face.normal.clone();
14899 } else {
14900 face.__originalFaceNormal.copy( face.normal );
14901 }
14902 if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];
14903 for ( let i = 0, il = face.vertexNormals.length; i < il; i ++ ) {
14904 if ( ! face.__originalVertexNormals[ i ] ) {
14905 face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();
14906 } else {
14907 face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );
14908 }
14909 }
14910 }
14911 const tmpGeo = new Geometry();
14912 tmpGeo.faces = this.faces;
14913 for ( let i = 0, il = this.morphTargets.length; i < il; i ++ ) {
14914 if ( ! this.morphNormals[ i ] ) {
14915 this.morphNormals[ i ] = {};
14916 this.morphNormals[ i ].faceNormals = [];
14917 this.morphNormals[ i ].vertexNormals = [];
14918 const dstNormalsFace = this.morphNormals[ i ].faceNormals;
14919 const dstNormalsVertex = this.morphNormals[ i ].vertexNormals;
14920 for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
14921 const faceNormal = new Vector3();
14922 const vertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };
14923 dstNormalsFace.push( faceNormal );
14924 dstNormalsVertex.push( vertexNormals );
14925 }
14926 }
14927 const morphNormals = this.morphNormals[ i ];
14928 tmpGeo.vertices = this.morphTargets[ i ].vertices;
14929 tmpGeo.computeFaceNormals();
14930 tmpGeo.computeVertexNormals();
14931 for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
14932 const face = this.faces[ f ];
14933 const faceNormal = morphNormals.faceNormals[ f ];
14934 const vertexNormals = morphNormals.vertexNormals[ f ];
14935 faceNormal.copy( face.normal );
14936 vertexNormals.a.copy( face.vertexNormals[ 0 ] );
14937 vertexNormals.b.copy( face.vertexNormals[ 1 ] );
14938 vertexNormals.c.copy( face.vertexNormals[ 2 ] );
14939 }
14940 }
14941 for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
14942 const face = this.faces[ f ];
14943 face.normal = face.__originalFaceNormal;
14944 face.vertexNormals = face.__originalVertexNormals;
14945 }
14946 },
14947 computeBoundingBox: function () {
14948 if ( this.boundingBox === null ) {
14949 this.boundingBox = new Box3();
14950 }
14951 this.boundingBox.setFromPoints( this.vertices );
14952 },
14953 computeBoundingSphere: function () {
14954 if ( this.boundingSphere === null ) {
14955 this.boundingSphere = new Sphere();
14956 }
14957 this.boundingSphere.setFromPoints( this.vertices );
14958 },
14959 merge: function ( geometry, matrix, materialIndexOffset ) {
14960 if ( ! ( geometry && geometry.isGeometry ) ) {
14961 console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );
14962 return;
14963 }
14964 let normalMatrix;
14965 const vertexOffset = this.vertices.length,
14966 vertices1 = this.vertices,
14967 vertices2 = geometry.vertices,
14968 faces1 = this.faces,
14969 faces2 = geometry.faces,
14970 colors1 = this.colors,
14971 colors2 = geometry.colors;
14972 if ( materialIndexOffset === undefined ) materialIndexOffset = 0;
14973 if ( matrix !== undefined ) {
14974 normalMatrix = new Matrix3().getNormalMatrix( matrix );
14975 }
14976 for ( let i = 0, il = vertices2.length; i < il; i ++ ) {
14977 const vertex = vertices2[ i ];
14978 const vertexCopy = vertex.clone();
14979 if ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );
14980 vertices1.push( vertexCopy );
14981 }
14982 for ( let i = 0, il = colors2.length; i < il; i ++ ) {
14983 colors1.push( colors2[ i ].clone() );
14984 }
14985 for ( let i = 0, il = faces2.length; i < il; i ++ ) {
14986 const face = faces2[ i ];
14987 let normal, color;
14988 const faceVertexNormals = face.vertexNormals,
14989 faceVertexColors = face.vertexColors;
14990 const faceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );
14991 faceCopy.normal.copy( face.normal );
14992 if ( normalMatrix !== undefined ) {
14993 faceCopy.normal.applyMatrix3( normalMatrix ).normalize();
14994 }
14995 for ( let j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {
14996 normal = faceVertexNormals[ j ].clone();
14997 if ( normalMatrix !== undefined ) {
14998 normal.applyMatrix3( normalMatrix ).normalize();
14999 }
15000 faceCopy.vertexNormals.push( normal );
15001 }
15002 faceCopy.color.copy( face.color );
15003 for ( let j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {
15004 color = faceVertexColors[ j ];
15005 faceCopy.vertexColors.push( color.clone() );
15006 }
15007 faceCopy.materialIndex = face.materialIndex + materialIndexOffset;
15008 faces1.push( faceCopy );
15009 }
15010 for ( let i = 0, il = geometry.faceVertexUvs.length; i < il; i ++ ) {
15011 const faceVertexUvs2 = geometry.faceVertexUvs[ i ];
15012 if ( this.faceVertexUvs[ i ] === undefined ) this.faceVertexUvs[ i ] = [];
15013 for ( let j = 0, jl = faceVertexUvs2.length; j < jl; j ++ ) {
15014 const uvs2 = faceVertexUvs2[ j ], uvsCopy = [];
15015 for ( let k = 0, kl = uvs2.length; k < kl; k ++ ) {
15016 uvsCopy.push( uvs2[ k ].clone() );
15017 }
15018 this.faceVertexUvs[ i ].push( uvsCopy );
15019 }
15020 }
15021 },
15022 mergeMesh: function ( mesh ) {
15023 if ( ! ( mesh && mesh.isMesh ) ) {
15024 console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );
15025 return;
15026 }
15027 if ( mesh.matrixAutoUpdate ) mesh.updateMatrix();
15028 this.merge( mesh.geometry, mesh.matrix );
15029 },
15030 mergeVertices: function () {
15031 const verticesMap = {};
15032 const unique = [], changes = [];
15033 const precisionPoints = 4;
15034 const precision = Math.pow( 10, precisionPoints );
15035 for ( let i = 0, il = this.vertices.length; i < il; i ++ ) {
15036 const v = this.vertices[ i ];
15037 const key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );
15038 if ( verticesMap[ key ] === undefined ) {
15039 verticesMap[ key ] = i;
15040 unique.push( this.vertices[ i ] );
15041 changes[ i ] = unique.length - 1;
15042 } else {
15043 changes[ i ] = changes[ verticesMap[ key ] ];
15044 }
15045 }
15046 const faceIndicesToRemove = [];
15047 for ( let i = 0, il = this.faces.length; i < il; i ++ ) {
15048 const face = this.faces[ i ];
15049 face.a = changes[ face.a ];
15050 face.b = changes[ face.b ];
15051 face.c = changes[ face.c ];
15052 const indices = [ face.a, face.b, face.c ];
15053 for ( let n = 0; n < 3; n ++ ) {
15054 if ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {
15055 faceIndicesToRemove.push( i );
15056 break;
15057 }
15058 }
15059 }
15060 for ( let i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {
15061 const idx = faceIndicesToRemove[ i ];
15062 this.faces.splice( idx, 1 );
15063 for ( let j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
15064 this.faceVertexUvs[ j ].splice( idx, 1 );
15065 }
15066 }
15067 const diff = this.vertices.length - unique.length;
15068 this.vertices = unique;
15069 return diff;
15070 },
15071 setFromPoints: function ( points ) {
15072 this.vertices = [];
15073 for ( let i = 0, l = points.length; i < l; i ++ ) {
15074 const point = points[ i ];
15075 this.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );
15076 }
15077 return this;
15078 },
15079 sortFacesByMaterialIndex: function () {
15080 const faces = this.faces;
15081 const length = faces.length;
15082 for ( let i = 0; i < length; i ++ ) {
15083 faces[ i ]._id = i;
15084 }
15085 function materialIndexSort( a, b ) {
15086 return a.materialIndex - b.materialIndex;
15087 }
15088 faces.sort( materialIndexSort );
15089 const uvs1 = this.faceVertexUvs[ 0 ];
15090 const uvs2 = this.faceVertexUvs[ 1 ];
15091 let newUvs1, newUvs2;
15092 if ( uvs1 && uvs1.length === length ) newUvs1 = [];
15093 if ( uvs2 && uvs2.length === length ) newUvs2 = [];
15094 for ( let i = 0; i < length; i ++ ) {
15095 const id = faces[ i ]._id;
15096 if ( newUvs1 ) newUvs1.push( uvs1[ id ] );
15097 if ( newUvs2 ) newUvs2.push( uvs2[ id ] );
15098 }
15099 if ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;
15100 if ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;
15101 },
15102 toJSON: function () {
15103 const data = {
15104 metadata: {
15105 version: 4.5,
15106 type: 'Geometry',
15107 generator: 'Geometry.toJSON'
15108 }
15109 };
15110 data.uuid = this.uuid;
15111 data.type = this.type;
15112 if ( this.name !== '' ) data.name = this.name;
15113 if ( this.parameters !== undefined ) {
15114 const parameters = this.parameters;
15115 for ( const key in parameters ) {
15116 if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];
15117 }
15118 return data;
15119 }
15120 const vertices = [];
15121 for ( let i = 0; i < this.vertices.length; i ++ ) {
15122 const vertex = this.vertices[ i ];
15123 vertices.push( vertex.x, vertex.y, vertex.z );
15124 }
15125 const faces = [];
15126 const normals = [];
15127 const normalsHash = {};
15128 const colors = [];
15129 const colorsHash = {};
15130 const uvs = [];
15131 const uvsHash = {};
15132 for ( let i = 0; i < this.faces.length; i ++ ) {
15133 const face = this.faces[ i ];
15134 const hasMaterial = true;
15135 const hasFaceUv = false;
15136 const hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;
15137 const hasFaceNormal = face.normal.length() > 0;
15138 const hasFaceVertexNormal = face.vertexNormals.length > 0;
15139 const hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;
15140 const hasFaceVertexColor = face.vertexColors.length > 0;
15141 let faceType = 0;
15142 faceType = setBit( faceType, 0, 0 );
15143 faceType = setBit( faceType, 1, hasMaterial );
15144 faceType = setBit( faceType, 2, hasFaceUv );
15145 faceType = setBit( faceType, 3, hasFaceVertexUv );
15146 faceType = setBit( faceType, 4, hasFaceNormal );
15147 faceType = setBit( faceType, 5, hasFaceVertexNormal );
15148 faceType = setBit( faceType, 6, hasFaceColor );
15149 faceType = setBit( faceType, 7, hasFaceVertexColor );
15150 faces.push( faceType );
15151 faces.push( face.a, face.b, face.c );
15152 faces.push( face.materialIndex );
15153 if ( hasFaceVertexUv ) {
15154 const faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];
15155 faces.push(
15156 getUvIndex( faceVertexUvs[ 0 ] ),
15157 getUvIndex( faceVertexUvs[ 1 ] ),
15158 getUvIndex( faceVertexUvs[ 2 ] )
15159 );
15160 }
15161 if ( hasFaceNormal ) {
15162 faces.push( getNormalIndex( face.normal ) );
15163 }
15164 if ( hasFaceVertexNormal ) {
15165 const vertexNormals = face.vertexNormals;
15166 faces.push(
15167 getNormalIndex( vertexNormals[ 0 ] ),
15168 getNormalIndex( vertexNormals[ 1 ] ),
15169 getNormalIndex( vertexNormals[ 2 ] )
15170 );
15171 }
15172 if ( hasFaceColor ) {
15173 faces.push( getColorIndex( face.color ) );
15174 }
15175 if ( hasFaceVertexColor ) {
15176 const vertexColors = face.vertexColors;
15177 faces.push(
15178 getColorIndex( vertexColors[ 0 ] ),
15179 getColorIndex( vertexColors[ 1 ] ),
15180 getColorIndex( vertexColors[ 2 ] )
15181 );
15182 }
15183 }
15184 function setBit( value, position, enabled ) {
15185 return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );
15186 }
15187 function getNormalIndex( normal ) {
15188 const hash = normal.x.toString() + normal.y.toString() + normal.z.toString();
15189 if ( normalsHash[ hash ] !== undefined ) {
15190 return normalsHash[ hash ];
15191 }
15192 normalsHash[ hash ] = normals.length / 3;
15193 normals.push( normal.x, normal.y, normal.z );
15194 return normalsHash[ hash ];
15195 }
15196 function getColorIndex( color ) {
15197 const hash = color.r.toString() + color.g.toString() + color.b.toString();
15198 if ( colorsHash[ hash ] !== undefined ) {
15199 return colorsHash[ hash ];
15200 }
15201 colorsHash[ hash ] = colors.length;
15202 colors.push( color.getHex() );
15203 return colorsHash[ hash ];
15204 }
15205 function getUvIndex( uv ) {
15206 const hash = uv.x.toString() + uv.y.toString();
15207 if ( uvsHash[ hash ] !== undefined ) {
15208 return uvsHash[ hash ];
15209 }
15210 uvsHash[ hash ] = uvs.length / 2;
15211 uvs.push( uv.x, uv.y );
15212 return uvsHash[ hash ];
15213 }
15214 data.data = {};
15215 data.data.vertices = vertices;
15216 data.data.normals = normals;
15217 if ( colors.length > 0 ) data.data.colors = colors;
15218 if ( uvs.length > 0 ) data.data.uvs = [ uvs ];
15219 data.data.faces = faces;
15220 return data;
15221 },
15222 clone: function () {
15223 return new Geometry().copy( this );
15224 },
15225 copy: function ( source ) {
15226 this.vertices = [];
15227 this.colors = [];
15228 this.faces = [];
15229 this.faceVertexUvs = [[]];
15230 this.morphTargets = [];
15231 this.morphNormals = [];
15232 this.skinWeights = [];
15233 this.skinIndices = [];
15234 this.lineDistances = [];
15235 this.boundingBox = null;
15236 this.boundingSphere = null;
15237 this.name = source.name;
15238 const vertices = source.vertices;
15239 for ( let i = 0, il = vertices.length; i < il; i ++ ) {
15240 this.vertices.push( vertices[ i ].clone() );
15241 }
15242 const colors = source.colors;
15243 for ( let i = 0, il = colors.length; i < il; i ++ ) {
15244 this.colors.push( colors[ i ].clone() );
15245 }
15246 const faces = source.faces;
15247 for ( let i = 0, il = faces.length; i < il; i ++ ) {
15248 this.faces.push( faces[ i ].clone() );
15249 }
15250 for ( let i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {
15251 const faceVertexUvs = source.faceVertexUvs[ i ];
15252 if ( this.faceVertexUvs[ i ] === undefined ) {
15253 this.faceVertexUvs[ i ] = [];
15254 }
15255 for ( let j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {
15256 const uvs = faceVertexUvs[ j ], uvsCopy = [];
15257 for ( let k = 0, kl = uvs.length; k < kl; k ++ ) {
15258 const uv = uvs[ k ];
15259 uvsCopy.push( uv.clone() );
15260 }
15261 this.faceVertexUvs[ i ].push( uvsCopy );
15262 }
15263 }
15264 const morphTargets = source.morphTargets;
15265 for ( let i = 0, il = morphTargets.length; i < il; i ++ ) {
15266 const morphTarget = {};
15267 morphTarget.name = morphTargets[ i ].name;
15268 if ( morphTargets[ i ].vertices !== undefined ) {
15269 morphTarget.vertices = [];
15270 for ( let j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) {
15271 morphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() );
15272 }
15273 }
15274 if ( morphTargets[ i ].normals !== undefined ) {
15275 morphTarget.normals = [];
15276 for ( let j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) {
15277 morphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() );
15278 }
15279 }
15280 this.morphTargets.push( morphTarget );
15281 }
15282 const morphNormals = source.morphNormals;
15283 for ( let i = 0, il = morphNormals.length; i < il; i ++ ) {
15284 const morphNormal = {};
15285 if ( morphNormals[ i ].vertexNormals !== undefined ) {
15286 morphNormal.vertexNormals = [];
15287 for ( let j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) {
15288 const srcVertexNormal = morphNormals[ i ].vertexNormals[ j ];
15289 const destVertexNormal = {};
15290 destVertexNormal.a = srcVertexNormal.a.clone();
15291 destVertexNormal.b = srcVertexNormal.b.clone();
15292 destVertexNormal.c = srcVertexNormal.c.clone();
15293 morphNormal.vertexNormals.push( destVertexNormal );
15294 }
15295 }
15296 if ( morphNormals[ i ].faceNormals !== undefined ) {
15297 morphNormal.faceNormals = [];
15298 for ( let j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) {
15299 morphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() );
15300 }
15301 }
15302 this.morphNormals.push( morphNormal );
15303 }
15304 const skinWeights = source.skinWeights;
15305 for ( let i = 0, il = skinWeights.length; i < il; i ++ ) {
15306 this.skinWeights.push( skinWeights[ i ].clone() );
15307 }
15308 const skinIndices = source.skinIndices;
15309 for ( let i = 0, il = skinIndices.length; i < il; i ++ ) {
15310 this.skinIndices.push( skinIndices[ i ].clone() );
15311 }
15312 const lineDistances = source.lineDistances;
15313 for ( let i = 0, il = lineDistances.length; i < il; i ++ ) {
15314 this.lineDistances.push( lineDistances[ i ] );
15315 }
15316 const boundingBox = source.boundingBox;
15317 if ( boundingBox !== null ) {
15318 this.boundingBox = boundingBox.clone();
15319 }
15320 const boundingSphere = source.boundingSphere;
15321 if ( boundingSphere !== null ) {
15322 this.boundingSphere = boundingSphere.clone();
15323 }
15324 this.elementsNeedUpdate = source.elementsNeedUpdate;
15325 this.verticesNeedUpdate = source.verticesNeedUpdate;
15326 this.uvsNeedUpdate = source.uvsNeedUpdate;
15327 this.normalsNeedUpdate = source.normalsNeedUpdate;
15328 this.colorsNeedUpdate = source.colorsNeedUpdate;
15329 this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;
15330 this.groupsNeedUpdate = source.groupsNeedUpdate;
15331 return this;
15332 },
15333 dispose: function () {
15334 this.dispatchEvent( { type: 'dispose' } );
15335 }
15336 } );
15337 class BoxGeometry extends Geometry {
15338 constructor( width, height, depth, widthSegments, heightSegments, depthSegments ) {
15339 super();
15340 this.type = 'BoxGeometry';
15341 this.parameters = {
15342 width: width,
15343 height: height,
15344 depth: depth,
15345 widthSegments: widthSegments,
15346 heightSegments: heightSegments,
15347 depthSegments: depthSegments
15348 };
15349 this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );
15350 this.mergeVertices();
15351 }
15352 }
15353 class BoxBufferGeometry extends BufferGeometry {
15354 constructor( width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1 ) {
15355 super();
15356 this.type = 'BoxBufferGeometry';
15357 this.parameters = {
15358 width: width,
15359 height: height,
15360 depth: depth,
15361 widthSegments: widthSegments,
15362 heightSegments: heightSegments,
15363 depthSegments: depthSegments
15364 };
15365 const scope = this;
15366 widthSegments = Math.floor( widthSegments );
15367 heightSegments = Math.floor( heightSegments );
15368 depthSegments = Math.floor( depthSegments );
15369 const indices = [];
15370 const vertices = [];
15371 const normals = [];
15372 const uvs = [];
15373 let numberOfVertices = 0;
15374 let groupStart = 0;
15375 buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 );
15376 buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 );
15377 buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 );
15378 buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 );
15379 buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 );
15380 buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 );
15381 this.setIndex( indices );
15382 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
15383 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
15384 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
15385 function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {
15386 const segmentWidth = width / gridX;
15387 const segmentHeight = height / gridY;
15388 const widthHalf = width / 2;
15389 const heightHalf = height / 2;
15390 const depthHalf = depth / 2;
15391 const gridX1 = gridX + 1;
15392 const gridY1 = gridY + 1;
15393 let vertexCounter = 0;
15394 let groupCount = 0;
15395 const vector = new Vector3();
15396 for ( let iy = 0; iy < gridY1; iy ++ ) {
15397 const y = iy * segmentHeight - heightHalf;
15398 for ( let ix = 0; ix < gridX1; ix ++ ) {
15399 const x = ix * segmentWidth - widthHalf;
15400 vector[ u ] = x * udir;
15401 vector[ v ] = y * vdir;
15402 vector[ w ] = depthHalf;
15403 vertices.push( vector.x, vector.y, vector.z );
15404 vector[ u ] = 0;
15405 vector[ v ] = 0;
15406 vector[ w ] = depth > 0 ? 1 : - 1;
15407 normals.push( vector.x, vector.y, vector.z );
15408 uvs.push( ix / gridX );
15409 uvs.push( 1 - ( iy / gridY ) );
15410 vertexCounter += 1;
15411 }
15412 }
15413 for ( let iy = 0; iy < gridY; iy ++ ) {
15414 for ( let ix = 0; ix < gridX; ix ++ ) {
15415 const a = numberOfVertices + ix + gridX1 * iy;
15416 const b = numberOfVertices + ix + gridX1 * ( iy + 1 );
15417 const c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );
15418 const d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;
15419 indices.push( a, b, d );
15420 indices.push( b, c, d );
15421 groupCount += 6;
15422 }
15423 }
15424 scope.addGroup( groupStart, groupCount, materialIndex );
15425 groupStart += groupCount;
15426 numberOfVertices += vertexCounter;
15427 }
15428 }
15429 }
15430 function cloneUniforms( src ) {
15431 const dst = {};
15432 for ( const u in src ) {
15433 dst[ u ] = {};
15434 for ( const p in src[ u ] ) {
15435 const property = src[ u ][ p ];
15436 if ( property && ( property.isColor ||
15437 property.isMatrix3 || property.isMatrix4 ||
15438 property.isVector2 || property.isVector3 || property.isVector4 ||
15439 property.isTexture ) ) {
15440 dst[ u ][ p ] = property.clone();
15441 } else if ( Array.isArray( property ) ) {
15442 dst[ u ][ p ] = property.slice();
15443 } else {
15444 dst[ u ][ p ] = property;
15445 }
15446 }
15447 }
15448 return dst;
15449 }
15450 function mergeUniforms( uniforms ) {
15451 const merged = {};
15452 for ( let u = 0; u < uniforms.length; u ++ ) {
15453 const tmp = cloneUniforms( uniforms[ u ] );
15454 for ( const p in tmp ) {
15455 merged[ p ] = tmp[ p ];
15456 }
15457 }
15458 return merged;
15459 }
15460 const UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms };
15461 var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}";
15462 var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}";
15463 function ShaderMaterial( parameters ) {
15464 Material.call( this );
15465 this.type = 'ShaderMaterial';
15466 this.defines = {};
15467 this.uniforms = {};
15468 this.vertexShader = default_vertex;
15469 this.fragmentShader = default_fragment;
15470 this.linewidth = 1;
15471 this.wireframe = false;
15472 this.wireframeLinewidth = 1;
15473 this.fog = false;
15474 this.lights = false;
15475 this.clipping = false;
15476 this.skinning = false;
15477 this.morphTargets = false;
15478 this.morphNormals = false;
15479 this.extensions = {
15480 derivatives: false,
15481 fragDepth: false,
15482 drawBuffers: false,
15483 shaderTextureLOD: false
15484 };
15485 this.defaultAttributeValues = {
15486 'color': [ 1, 1, 1 ],
15487 'uv': [ 0, 0 ],
15488 'uv2': [ 0, 0 ]
15489 };
15490 this.index0AttributeName = undefined;
15491 this.uniformsNeedUpdate = false;
15492 this.glslVersion = null;
15493 if ( parameters !== undefined ) {
15494 if ( parameters.attributes !== undefined ) {
15495 console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );
15496 }
15497 this.setValues( parameters );
15498 }
15499 }
15500 ShaderMaterial.prototype = Object.create( Material.prototype );
15501 ShaderMaterial.prototype.constructor = ShaderMaterial;
15502 ShaderMaterial.prototype.isShaderMaterial = true;
15503 ShaderMaterial.prototype.copy = function ( source ) {
15504 Material.prototype.copy.call( this, source );
15505 this.fragmentShader = source.fragmentShader;
15506 this.vertexShader = source.vertexShader;
15507 this.uniforms = cloneUniforms( source.uniforms );
15508 this.defines = Object.assign( {}, source.defines );
15509 this.wireframe = source.wireframe;
15510 this.wireframeLinewidth = source.wireframeLinewidth;
15511 this.lights = source.lights;
15512 this.clipping = source.clipping;
15513 this.skinning = source.skinning;
15514 this.morphTargets = source.morphTargets;
15515 this.morphNormals = source.morphNormals;
15516 this.extensions = Object.assign( {}, source.extensions );
15517 this.glslVersion = source.glslVersion;
15518 return this;
15519 };
15520 ShaderMaterial.prototype.toJSON = function ( meta ) {
15521 const data = Material.prototype.toJSON.call( this, meta );
15522 data.glslVersion = this.glslVersion;
15523 data.uniforms = {};
15524 for ( const name in this.uniforms ) {
15525 const uniform = this.uniforms[ name ];
15526 const value = uniform.value;
15527 if ( value && value.isTexture ) {
15528 data.uniforms[ name ] = {
15529 type: 't',
15530 value: value.toJSON( meta ).uuid
15531 };
15532 } else if ( value && value.isColor ) {
15533 data.uniforms[ name ] = {
15534 type: 'c',
15535 value: value.getHex()
15536 };
15537 } else if ( value && value.isVector2 ) {
15538 data.uniforms[ name ] = {
15539 type: 'v2',
15540 value: value.toArray()
15541 };
15542 } else if ( value && value.isVector3 ) {
15543 data.uniforms[ name ] = {
15544 type: 'v3',
15545 value: value.toArray()
15546 };
15547 } else if ( value && value.isVector4 ) {
15548 data.uniforms[ name ] = {
15549 type: 'v4',
15550 value: value.toArray()
15551 };
15552 } else if ( value && value.isMatrix3 ) {
15553 data.uniforms[ name ] = {
15554 type: 'm3',
15555 value: value.toArray()
15556 };
15557 } else if ( value && value.isMatrix4 ) {
15558 data.uniforms[ name ] = {
15559 type: 'm4',
15560 value: value.toArray()
15561 };
15562 } else {
15563 data.uniforms[ name ] = {
15564 value: value
15565 };
15566 }
15567 }
15568 if ( Object.keys( this.defines ).length > 0 ) data.defines = this.defines;
15569 data.vertexShader = this.vertexShader;
15570 data.fragmentShader = this.fragmentShader;
15571 const extensions = {};
15572 for ( const key in this.extensions ) {
15573 if ( this.extensions[ key ] === true ) extensions[ key ] = true;
15574 }
15575 if ( Object.keys( extensions ).length > 0 ) data.extensions = extensions;
15576 return data;
15577 };
15578 function Camera() {
15579 Object3D.call( this );
15580 this.type = 'Camera';
15581 this.matrixWorldInverse = new Matrix4();
15582 this.projectionMatrix = new Matrix4();
15583 this.projectionMatrixInverse = new Matrix4();
15584 }
15585 Camera.prototype = Object.assign( Object.create( Object3D.prototype ), {
15586 constructor: Camera,
15587 isCamera: true,
15588 copy: function ( source, recursive ) {
15589 Object3D.prototype.copy.call( this, source, recursive );
15590 this.matrixWorldInverse.copy( source.matrixWorldInverse );
15591 this.projectionMatrix.copy( source.projectionMatrix );
15592 this.projectionMatrixInverse.copy( source.projectionMatrixInverse );
15593 return this;
15594 },
15595 getWorldDirection: function ( target ) {
15596 if ( target === undefined ) {
15597 console.warn( 'THREE.Camera: .getWorldDirection() target is now required' );
15598 target = new Vector3();
15599 }
15600 this.updateMatrixWorld( true );
15601 const e = this.matrixWorld.elements;
15602 return target.set( - e[ 8 ], - e[ 9 ], - e[ 10 ] ).normalize();
15603 },
15604 updateMatrixWorld: function ( force ) {
15605 Object3D.prototype.updateMatrixWorld.call( this, force );
15606 this.matrixWorldInverse.getInverse( this.matrixWorld );
15607 },
15608 updateWorldMatrix: function ( updateParents, updateChildren ) {
15609 Object3D.prototype.updateWorldMatrix.call( this, updateParents, updateChildren );
15610 this.matrixWorldInverse.getInverse( this.matrixWorld );
15611 },
15612 clone: function () {
15613 return new this.constructor().copy( this );
15614 }
15615 } );
15616 function PerspectiveCamera( fov, aspect, near, far ) {
15617 Camera.call( this );
15618 this.type = 'PerspectiveCamera';
15619 this.fov = fov !== undefined ? fov : 50;
15620 this.zoom = 1;
15621 this.near = near !== undefined ? near : 0.1;
15622 this.far = far !== undefined ? far : 2000;
15623 this.focus = 10;
15624 this.aspect = aspect !== undefined ? aspect : 1;
15625 this.view = null;
15626 this.filmGauge = 35;
15627 this.filmOffset = 0;
15628 this.updateProjectionMatrix();
15629 }
15630 PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {
15631 constructor: PerspectiveCamera,
15632 isPerspectiveCamera: true,
15633 copy: function ( source, recursive ) {
15634 Camera.prototype.copy.call( this, source, recursive );
15635 this.fov = source.fov;
15636 this.zoom = source.zoom;
15637 this.near = source.near;
15638 this.far = source.far;
15639 this.focus = source.focus;
15640 this.aspect = source.aspect;
15641 this.view = source.view === null ? null : Object.assign( {}, source.view );
15642 this.filmGauge = source.filmGauge;
15643 this.filmOffset = source.filmOffset;
15644 return this;
15645 },
15646 setFocalLength: function ( focalLength ) {
15647 const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;
15648 this.fov = MathUtils.RAD2DEG * 2 * Math.atan( vExtentSlope );
15649 this.updateProjectionMatrix();
15650 },
15651 getFocalLength: function () {
15652 const vExtentSlope = Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov );
15653 return 0.5 * this.getFilmHeight() / vExtentSlope;
15654 },
15655 getEffectiveFOV: function () {
15656 return MathUtils.RAD2DEG * 2 * Math.atan(
15657 Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom );
15658 },
15659 getFilmWidth: function () {
15660 return this.filmGauge * Math.min( this.aspect, 1 );
15661 },
15662 getFilmHeight: function () {
15663 return this.filmGauge / Math.max( this.aspect, 1 );
15664 },
15665 setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {
15666 this.aspect = fullWidth / fullHeight;
15667 if ( this.view === null ) {
15668 this.view = {
15669 enabled: true,
15670 fullWidth: 1,
15671 fullHeight: 1,
15672 offsetX: 0,
15673 offsetY: 0,
15674 width: 1,
15675 height: 1
15676 };
15677 }
15678 this.view.enabled = true;
15679 this.view.fullWidth = fullWidth;
15680 this.view.fullHeight = fullHeight;
15681 this.view.offsetX = x;
15682 this.view.offsetY = y;
15683 this.view.width = width;
15684 this.view.height = height;
15685 this.updateProjectionMatrix();
15686 },
15687 clearViewOffset: function () {
15688 if ( this.view !== null ) {
15689 this.view.enabled = false;
15690 }
15691 this.updateProjectionMatrix();
15692 },
15693 updateProjectionMatrix: function () {
15694 const near = this.near;
15695 let top = near * Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom;
15696 let height = 2 * top;
15697 let width = this.aspect * height;
15698 let left = - 0.5 * width;
15699 const view = this.view;
15700 if ( this.view !== null && this.view.enabled ) {
15701 const fullWidth = view.fullWidth,
15702 fullHeight = view.fullHeight;
15703 left += view.offsetX * width / fullWidth;
15704 top -= view.offsetY * height / fullHeight;
15705 width *= view.width / fullWidth;
15706 height *= view.height / fullHeight;
15707 }
15708 const skew = this.filmOffset;
15709 if ( skew !== 0 ) left += near * skew / this.getFilmWidth();
15710 this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );
15711 this.projectionMatrixInverse.getInverse( this.projectionMatrix );
15712 },
15713 toJSON: function ( meta ) {
15714 const data = Object3D.prototype.toJSON.call( this, meta );
15715 data.object.fov = this.fov;
15716 data.object.zoom = this.zoom;
15717 data.object.near = this.near;
15718 data.object.far = this.far;
15719 data.object.focus = this.focus;
15720 data.object.aspect = this.aspect;
15721 if ( this.view !== null ) data.object.view = Object.assign( {}, this.view );
15722 data.object.filmGauge = this.filmGauge;
15723 data.object.filmOffset = this.filmOffset;
15724 return data;
15725 }
15726 } );
15727 const fov = 90, aspect = 1;
15728 function CubeCamera( near, far, renderTarget ) {
15729 Object3D.call( this );
15730 this.type = 'CubeCamera';
15731 if ( renderTarget.isWebGLCubeRenderTarget !== true ) {
15732 console.error( 'THREE.CubeCamera: The constructor now expects an instance of WebGLCubeRenderTarget as third parameter.' );
15733 return;
15734 }
15735 this.renderTarget = renderTarget;
15736 const cameraPX = new PerspectiveCamera( fov, aspect, near, far );
15737 cameraPX.layers = this.layers;
15738 cameraPX.up.set( 0, - 1, 0 );
15739 cameraPX.lookAt( new Vector3( 1, 0, 0 ) );
15740 this.add( cameraPX );
15741 const cameraNX = new PerspectiveCamera( fov, aspect, near, far );
15742 cameraNX.layers = this.layers;
15743 cameraNX.up.set( 0, - 1, 0 );
15744 cameraNX.lookAt( new Vector3( - 1, 0, 0 ) );
15745 this.add( cameraNX );
15746 const cameraPY = new PerspectiveCamera( fov, aspect, near, far );
15747 cameraPY.layers = this.layers;
15748 cameraPY.up.set( 0, 0, 1 );
15749 cameraPY.lookAt( new Vector3( 0, 1, 0 ) );
15750 this.add( cameraPY );
15751 const cameraNY = new PerspectiveCamera( fov, aspect, near, far );
15752 cameraNY.layers = this.layers;
15753 cameraNY.up.set( 0, 0, - 1 );
15754 cameraNY.lookAt( new Vector3( 0, - 1, 0 ) );
15755 this.add( cameraNY );
15756 const cameraPZ = new PerspectiveCamera( fov, aspect, near, far );
15757 cameraPZ.layers = this.layers;
15758 cameraPZ.up.set( 0, - 1, 0 );
15759 cameraPZ.lookAt( new Vector3( 0, 0, 1 ) );
15760 this.add( cameraPZ );
15761 const cameraNZ = new PerspectiveCamera( fov, aspect, near, far );
15762 cameraNZ.layers = this.layers;
15763 cameraNZ.up.set( 0, - 1, 0 );
15764 cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );
15765 this.add( cameraNZ );
15766 this.update = function ( renderer, scene ) {
15767 if ( this.parent === null ) this.updateMatrixWorld();
15768 const currentXrEnabled = renderer.xr.enabled;
15769 const currentRenderTarget = renderer.getRenderTarget();
15770 renderer.xr.enabled = false;
15771 const generateMipmaps = renderTarget.texture.generateMipmaps;
15772 renderTarget.texture.generateMipmaps = false;
15773 renderer.setRenderTarget( renderTarget, 0 );
15774 renderer.render( scene, cameraPX );
15775 renderer.setRenderTarget( renderTarget, 1 );
15776 renderer.render( scene, cameraNX );
15777 renderer.setRenderTarget( renderTarget, 2 );
15778 renderer.render( scene, cameraPY );
15779 renderer.setRenderTarget( renderTarget, 3 );
15780 renderer.render( scene, cameraNY );
15781 renderer.setRenderTarget( renderTarget, 4 );
15782 renderer.render( scene, cameraPZ );
15783 renderTarget.texture.generateMipmaps = generateMipmaps;
15784 renderer.setRenderTarget( renderTarget, 5 );
15785 renderer.render( scene, cameraNZ );
15786 renderer.setRenderTarget( currentRenderTarget );
15787 renderer.xr.enabled = currentXrEnabled;
15788 };
15789 this.clear = function ( renderer, color, depth, stencil ) {
15790 const currentRenderTarget = renderer.getRenderTarget();
15791 for ( let i = 0; i < 6; i ++ ) {
15792 renderer.setRenderTarget( renderTarget, i );
15793 renderer.clear( color, depth, stencil );
15794 }
15795 renderer.setRenderTarget( currentRenderTarget );
15796 };
15797 }
15798 CubeCamera.prototype = Object.create( Object3D.prototype );
15799 CubeCamera.prototype.constructor = CubeCamera;
15800 function WebGLCubeRenderTarget( size, options, dummy ) {
15801 if ( Number.isInteger( options ) ) {
15802 console.warn( 'THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )' );
15803 options = dummy;
15804 }
15805 WebGLRenderTarget.call( this, size, size, options );
15806 this.texture.isWebGLCubeRenderTargetTexture = true;
15807 }
15808 WebGLCubeRenderTarget.prototype = Object.create( WebGLRenderTarget.prototype );
15809 WebGLCubeRenderTarget.prototype.constructor = WebGLCubeRenderTarget;
15810 WebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true;
15811 WebGLCubeRenderTarget.prototype.fromEquirectangularTexture = function ( renderer, texture ) {
15812 this.texture.type = texture.type;
15813 this.texture.format = RGBAFormat;
15814 this.texture.encoding = texture.encoding;
15815 this.texture.generateMipmaps = texture.generateMipmaps;
15816 this.texture.minFilter = texture.minFilter;
15817 this.texture.magFilter = texture.magFilter;
15818 const shader = {
15819 uniforms: {
15820 tEquirect: { value: null },
15821 },
15822 vertexShader: `
15823
15824 varying vec3 vWorldDirection;
15825
15826 vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
15827
15828 return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
15829
15830 }
15831
15832 void main() {
15833
15834 vWorldDirection = transformDirection( position, modelMatrix );
15835
15836 #include <begin_vertex>
15837 #include <project_vertex>
15838
15839 }
15840 `,
15841 fragmentShader: `
15842
15843 uniform sampler2D tEquirect;
15844
15845 varying vec3 vWorldDirection;
15846
15847 #include <common>
15848
15849 void main() {
15850
15851 vec3 direction = normalize( vWorldDirection );
15852
15853 vec2 sampleUV = equirectUv( direction );
15854
15855 gl_FragColor = texture2D( tEquirect, sampleUV );
15856
15857 }
15858 `
15859 };
15860 const geometry = new BoxBufferGeometry( 5, 5, 5 );
15861 const material = new ShaderMaterial( {
15862 name: 'CubemapFromEquirect',
15863 uniforms: cloneUniforms( shader.uniforms ),
15864 vertexShader: shader.vertexShader,
15865 fragmentShader: shader.fragmentShader,
15866 side: BackSide,
15867 blending: NoBlending
15868 } );
15869 material.uniforms.tEquirect.value = texture;
15870 const mesh = new Mesh( geometry, material );
15871 const currentMinFilter = texture.minFilter;
15872 if ( texture.minFilter === LinearMipmapLinearFilter ) texture.minFilter = LinearFilter;
15873 const camera = new CubeCamera( 1, 10, this );
15874 camera.update( renderer, mesh );
15875 texture.minFilter = currentMinFilter;
15876 mesh.geometry.dispose();
15877 mesh.material.dispose();
15878 return this;
15879 };
15880 function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {
15881 Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
15882 this.image = { data: data || null, width: width || 1, height: height || 1 };
15883 this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
15884 this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
15885 this.generateMipmaps = false;
15886 this.flipY = false;
15887 this.unpackAlignment = 1;
15888 this.needsUpdate = true;
15889 }
15890 DataTexture.prototype = Object.create( Texture.prototype );
15891 DataTexture.prototype.constructor = DataTexture;
15892 DataTexture.prototype.isDataTexture = true;
15893 const _sphere$1 = new Sphere();
15894 const _vector$5 = new Vector3();
15895 class Frustum {
15896 constructor( p0, p1, p2, p3, p4, p5 ) {
15897 this.planes = [
15898 ( p0 !== undefined ) ? p0 : new Plane(),
15899 ( p1 !== undefined ) ? p1 : new Plane(),
15900 ( p2 !== undefined ) ? p2 : new Plane(),
15901 ( p3 !== undefined ) ? p3 : new Plane(),
15902 ( p4 !== undefined ) ? p4 : new Plane(),
15903 ( p5 !== undefined ) ? p5 : new Plane()
15904 ];
15905 }
15906 set( p0, p1, p2, p3, p4, p5 ) {
15907 const planes = this.planes;
15908 planes[ 0 ].copy( p0 );
15909 planes[ 1 ].copy( p1 );
15910 planes[ 2 ].copy( p2 );
15911 planes[ 3 ].copy( p3 );
15912 planes[ 4 ].copy( p4 );
15913 planes[ 5 ].copy( p5 );
15914 return this;
15915 }
15916 clone() {
15917 return new this.constructor().copy( this );
15918 }
15919 copy( frustum ) {
15920 const planes = this.planes;
15921 for ( let i = 0; i < 6; i ++ ) {
15922 planes[ i ].copy( frustum.planes[ i ] );
15923 }
15924 return this;
15925 }
15926 setFromProjectionMatrix( m ) {
15927 const planes = this.planes;
15928 const me = m.elements;
15929 const me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];
15930 const me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];
15931 const me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];
15932 const me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];
15933 planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();
15934 planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();
15935 planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();
15936 planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();
15937 planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();
15938 planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();
15939 return this;
15940 }
15941 intersectsObject( object ) {
15942 const geometry = object.geometry;
15943 if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
15944 _sphere$1.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld );
15945 return this.intersectsSphere( _sphere$1 );
15946 }
15947 intersectsSprite( sprite ) {
15948 _sphere$1.center.set( 0, 0, 0 );
15949 _sphere$1.radius = 0.7071067811865476;
15950 _sphere$1.applyMatrix4( sprite.matrixWorld );
15951 return this.intersectsSphere( _sphere$1 );
15952 }
15953 intersectsSphere( sphere ) {
15954 const planes = this.planes;
15955 const center = sphere.center;
15956 const negRadius = - sphere.radius;
15957 for ( let i = 0; i < 6; i ++ ) {
15958 const distance = planes[ i ].distanceToPoint( center );
15959 if ( distance < negRadius ) {
15960 return false;
15961 }
15962 }
15963 return true;
15964 }
15965 intersectsBox( box ) {
15966 const planes = this.planes;
15967 for ( let i = 0; i < 6; i ++ ) {
15968 const plane = planes[ i ];
15969 _vector$5.x = plane.normal.x > 0 ? box.max.x : box.min.x;
15970 _vector$5.y = plane.normal.y > 0 ? box.max.y : box.min.y;
15971 _vector$5.z = plane.normal.z > 0 ? box.max.z : box.min.z;
15972 if ( plane.distanceToPoint( _vector$5 ) < 0 ) {
15973 return false;
15974 }
15975 }
15976 return true;
15977 }
15978 containsPoint( point ) {
15979 const planes = this.planes;
15980 for ( let i = 0; i < 6; i ++ ) {
15981 if ( planes[ i ].distanceToPoint( point ) < 0 ) {
15982 return false;
15983 }
15984 }
15985 return true;
15986 }
15987 }
15988 function WebGLAnimation() {
15989 let context = null;
15990 let isAnimating = false;
15991 let animationLoop = null;
15992 let requestId = null;
15993 function onAnimationFrame( time, frame ) {
15994 animationLoop( time, frame );
15995 requestId = context.requestAnimationFrame( onAnimationFrame );
15996 }
15997 return {
15998 start: function () {
15999 if ( isAnimating === true ) return;
16000 if ( animationLoop === null ) return;
16001 requestId = context.requestAnimationFrame( onAnimationFrame );
16002 isAnimating = true;
16003 },
16004 stop: function () {
16005 context.cancelAnimationFrame( requestId );
16006 isAnimating = false;
16007 },
16008 setAnimationLoop: function ( callback ) {
16009 animationLoop = callback;
16010 },
16011 setContext: function ( value ) {
16012 context = value;
16013 }
16014 };
16015 }
16016 function WebGLAttributes( gl, capabilities ) {
16017 const isWebGL2 = capabilities.isWebGL2;
16018 const buffers = new WeakMap();
16019 function createBuffer( attribute, bufferType ) {
16020 const array = attribute.array;
16021 const usage = attribute.usage;
16022 const buffer = gl.createBuffer();
16023 gl.bindBuffer( bufferType, buffer );
16024 gl.bufferData( bufferType, array, usage );
16025 attribute.onUploadCallback();
16026 let type = 5126;
16027 if ( array instanceof Float32Array ) {
16028 type = 5126;
16029 } else if ( array instanceof Float64Array ) {
16030 console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' );
16031 } else if ( array instanceof Uint16Array ) {
16032 type = 5123;
16033 } else if ( array instanceof Int16Array ) {
16034 type = 5122;
16035 } else if ( array instanceof Uint32Array ) {
16036 type = 5125;
16037 } else if ( array instanceof Int32Array ) {
16038 type = 5124;
16039 } else if ( array instanceof Int8Array ) {
16040 type = 5120;
16041 } else if ( array instanceof Uint8Array ) {
16042 type = 5121;
16043 }
16044 return {
16045 buffer: buffer,
16046 type: type,
16047 bytesPerElement: array.BYTES_PER_ELEMENT,
16048 version: attribute.version
16049 };
16050 }
16051 function updateBuffer( buffer, attribute, bufferType ) {
16052 const array = attribute.array;
16053 const updateRange = attribute.updateRange;
16054 gl.bindBuffer( bufferType, buffer );
16055 if ( updateRange.count === - 1 ) {
16056 gl.bufferSubData( bufferType, 0, array );
16057 } else {
16058 if ( isWebGL2 ) {
16059 gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,
16060 array, updateRange.offset, updateRange.count );
16061 } else {
16062 gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,
16063 array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) );
16064 }
16065 updateRange.count = - 1;
16066 }
16067 }
16068 function get( attribute ) {
16069 if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;
16070 return buffers.get( attribute );
16071 }
16072 function remove( attribute ) {
16073 if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;
16074 const data = buffers.get( attribute );
16075 if ( data ) {
16076 gl.deleteBuffer( data.buffer );
16077 buffers.delete( attribute );
16078 }
16079 }
16080 function update( attribute, bufferType ) {
16081 if ( attribute.isGLBufferAttribute ) {
16082 var cached = buffers.get( attribute );
16083 if ( ! cached || cached.version < attribute.version ) {
16084 buffers.set( attribute, {
16085 buffer: attribute.buffer,
16086 type: attribute.type,
16087 bytesPerElement: attribute.elementSize,
16088 version: attribute.version
16089 } );
16090 }
16091 return;
16092 }
16093 if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;
16094 const data = buffers.get( attribute );
16095 if ( data === undefined ) {
16096 buffers.set( attribute, createBuffer( attribute, bufferType ) );
16097 } else if ( data.version < attribute.version ) {
16098 updateBuffer( data.buffer, attribute, bufferType );
16099 data.version = attribute.version;
16100 }
16101 }
16102 return {
16103 get: get,
16104 remove: remove,
16105 update: update
16106 };
16107 }
16108 class PlaneGeometry extends Geometry {
16109 constructor( width, height, widthSegments, heightSegments ) {
16110 super();
16111 this.type = 'PlaneGeometry';
16112 this.parameters = {
16113 width: width,
16114 height: height,
16115 widthSegments: widthSegments,
16116 heightSegments: heightSegments
16117 };
16118 this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );
16119 this.mergeVertices();
16120 }
16121 }
16122 class PlaneBufferGeometry extends BufferGeometry {
16123 constructor( width, height, widthSegments, heightSegments ) {
16124 super();
16125 this.type = 'PlaneBufferGeometry';
16126 this.parameters = {
16127 width: width,
16128 height: height,
16129 widthSegments: widthSegments,
16130 heightSegments: heightSegments
16131 };
16132 width = width || 1;
16133 height = height || 1;
16134 const width_half = width / 2;
16135 const height_half = height / 2;
16136 const gridX = Math.floor( widthSegments ) || 1;
16137 const gridY = Math.floor( heightSegments ) || 1;
16138 const gridX1 = gridX + 1;
16139 const gridY1 = gridY + 1;
16140 const segment_width = width / gridX;
16141 const segment_height = height / gridY;
16142 const indices = [];
16143 const vertices = [];
16144 const normals = [];
16145 const uvs = [];
16146 for ( let iy = 0; iy < gridY1; iy ++ ) {
16147 const y = iy * segment_height - height_half;
16148 for ( let ix = 0; ix < gridX1; ix ++ ) {
16149 const x = ix * segment_width - width_half;
16150 vertices.push( x, - y, 0 );
16151 normals.push( 0, 0, 1 );
16152 uvs.push( ix / gridX );
16153 uvs.push( 1 - ( iy / gridY ) );
16154 }
16155 }
16156 for ( let iy = 0; iy < gridY; iy ++ ) {
16157 for ( let ix = 0; ix < gridX; ix ++ ) {
16158 const a = ix + gridX1 * iy;
16159 const b = ix + gridX1 * ( iy + 1 );
16160 const c = ( ix + 1 ) + gridX1 * ( iy + 1 );
16161 const d = ( ix + 1 ) + gridX1 * iy;
16162 indices.push( a, b, d );
16163 indices.push( b, c, d );
16164 }
16165 }
16166 this.setIndex( indices );
16167 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
16168 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
16169 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
16170 }
16171 }
16172 var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif";
16173 var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif";
16174 var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif";
16175 var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif";
16176 var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif";
16177 var begin_vertex = "vec3 transformed = vec3( position );";
16178 var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif";
16179 var bsdfs = "vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie(float roughness, float NoH) {\n\tfloat invAlpha = 1.0 / roughness;\n\tfloat cos2h = NoH * NoH;\n\tfloat sin2h = max(1.0 - cos2h, 0.0078125);\treturn (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n}\nfloat V_Neubelt(float NoV, float NoL) {\n\treturn saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n}\nvec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 H = normalize( V + L );\n\tfloat dotNH = saturate( dot( N, H ) );\n\treturn specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );\n}\n#endif";
16180 var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif";
16181 var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif";
16182 var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif";
16183 var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif";
16184 var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif";
16185 var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif";
16186 var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif";
16187 var color_pars_vertex = "#if defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvarying vec3 vColor;\n#endif";
16188 var color_vertex = "#if defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvColor = vec3( 1.0 );\n#endif\n#ifdef USE_COLOR\n\tvColor.xyz *= color.xyz;\n#endif\n#ifdef USE_INSTANCING_COLOR\n\tvColor.xyz *= instanceColor.xyz;\n#endif";
16189 var common = "#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}";
16190 var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_maxMipLevel 8.0\n\t#define cubeUV_minMipLevel 4.0\n\t#define cubeUV_maxTileSize 256.0\n\t#define cubeUV_minTileSize 16.0\n\tfloat getFace( vec3 direction ) {\n\t\tvec3 absDirection = abs( direction );\n\t\tfloat face = - 1.0;\n\t\tif ( absDirection.x > absDirection.z ) {\n\t\t\tif ( absDirection.x > absDirection.y )\n\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t} else {\n\t\t\tif ( absDirection.z > absDirection.y )\n\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t}\n\t\treturn face;\n\t}\n\tvec2 getUV( vec3 direction, float face ) {\n\t\tvec2 uv;\n\t\tif ( face == 0.0 ) {\n\t\t\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 1.0 ) {\n\t\t\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n\t\t} else if ( face == 2.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\n\t\t} else if ( face == 3.0 ) {\n\t\t\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 4.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\n\t\t} else {\n\t\t\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\n\t\t}\n\t\treturn 0.5 * ( uv + 1.0 );\n\t}\n\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n\t\tfloat face = getFace( direction );\n\t\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n\t\tmipInt = max( mipInt, cubeUV_minMipLevel );\n\t\tfloat faceSize = exp2( mipInt );\n\t\tfloat texelSize = 1.0 / ( 3.0 * cubeUV_maxTileSize );\n\t\tvec2 uv = getUV( direction, face ) * ( faceSize - 1.0 );\n\t\tvec2 f = fract( uv );\n\t\tuv += 0.5 - f;\n\t\tif ( face > 2.0 ) {\n\t\t\tuv.y += faceSize;\n\t\t\tface -= 3.0;\n\t\t}\n\t\tuv.x += face * faceSize;\n\t\tif ( mipInt < cubeUV_maxMipLevel ) {\n\t\t\tuv.y += 2.0 * cubeUV_maxTileSize;\n\t\t}\n\t\tuv.y += filterInt * 2.0 * cubeUV_minTileSize;\n\t\tuv.x += 3.0 * max( 0.0, cubeUV_maxTileSize - 2.0 * faceSize );\n\t\tuv *= texelSize;\n\t\tvec3 tl = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;\n\t\tuv.x += texelSize;\n\t\tvec3 tr = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;\n\t\tuv.y += texelSize;\n\t\tvec3 br = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;\n\t\tuv.x -= texelSize;\n\t\tvec3 bl = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;\n\t\tvec3 tm = mix( tl, tr, f.x );\n\t\tvec3 bm = mix( bl, br, f.x );\n\t\treturn mix( tm, bm, f.y );\n\t}\n\t#define r0 1.0\n\t#define v0 0.339\n\t#define m0 - 2.0\n\t#define r1 0.8\n\t#define v1 0.276\n\t#define m1 - 1.0\n\t#define r4 0.4\n\t#define v4 0.046\n\t#define m4 2.0\n\t#define r5 0.305\n\t#define v5 0.016\n\t#define m5 3.0\n\t#define r6 0.21\n\t#define v6 0.0038\n\t#define m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= r1 ) {\n\t\t\tmip = ( r0 - roughness ) * ( m1 - m0 ) / ( r0 - r1 ) + m0;\n\t\t} else if ( roughness >= r4 ) {\n\t\t\tmip = ( r1 - roughness ) * ( m4 - m1 ) / ( r1 - r4 ) + m1;\n\t\t} else if ( roughness >= r5 ) {\n\t\t\tmip = ( r4 - roughness ) * ( m5 - m4 ) / ( r4 - r5 ) + m4;\n\t\t} else if ( roughness >= r6 ) {\n\t\t\tmip = ( r5 - roughness ) * ( m6 - m5 ) / ( r5 - r6 ) + m5;\n\t\t} else {\n\t\t\tmip = - 2.0 * log2( 1.16 * roughness );\t\t}\n\t\treturn mip;\n\t}\n\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n\t\tfloat mip = clamp( roughnessToMip( roughness ), m0, cubeUV_maxMipLevel );\n\t\tfloat mipF = fract( mip );\n\t\tfloat mipInt = floor( mip );\n\t\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n\t\tif ( mipF == 0.0 ) {\n\t\t\treturn vec4( color0, 1.0 );\n\t\t} else {\n\t\t\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n\t\t\treturn vec4( mix( color0, color1, mipF ), 1.0 );\n\t\t}\n\t}\n#endif";
16191 var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_INSTANCING\n\tmat3 m = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );\n\ttransformedNormal = m * transformedNormal;\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif";
16192 var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif";
16193 var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif";
16194 var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif";
16195 var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif";
16196 var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );";
16197 var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = clamp( floor( D ) / 255.0, 0.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}";
16198 var envmap_fragment = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\t#ifndef ENVMAP_TYPE_CUBE_UV\n\t\tenvColor = envMapTexelToLinear( envColor );\n\t#endif\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif";
16199 var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif";
16200 var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif";
16201 var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif";
16202 var envmap_vertex = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif";
16203 var fog_vertex = "#ifdef USE_FOG\n\tfogDepth = - mvPosition.z;\n#endif";
16204 var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif";
16205 var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif";
16206 var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif";
16207 var gradientmap_pars_fragment = "#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn texture2D( gradientMap, coord ).rgb;\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}";
16208 var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\treflectedLight.indirectDiffuse += PI * lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n#endif";
16209 var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif";
16210 var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\nvIndirectFront += getAmbientLightIrradiance( ambientLightColor );\nvIndirectFront += getLightProbeIrradiance( lightProbe, geometry );\n#ifdef DOUBLE_SIDED\n\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\n\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry );\n#endif\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif";
16211 var lights_pars_begin = "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif";
16212 var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP )\n\t#ifdef ENVMAP_MODE_REFRACTION\n\t\tuniform float refractionRatio;\n\t#endif\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float roughness, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat sigma = PI * roughness * roughness / ( 1.0 + roughness );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + log2( sigma );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -viewDir, normal );\n\t\t\treflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( roughness, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif";
16213 var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;";
16214 var lights_toon_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct ToonMaterial {\n\tvec3 diffuseColor;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon\n#define Material_LightProbeLOD( material )\t(0)";
16215 var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;";
16216 var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3 diffuseColor;\n\tvec3 specularColor;\n\tfloat specularShininess;\n\tfloat specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)";
16217 var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.specularRoughness = max( roughnessFactor, 0.0525 );material.specularRoughness += geometryRoughness;\nmaterial.specularRoughness = min( material.specularRoughness, 1.0 );\n#ifdef REFLECTIVITY\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#endif\n#ifdef CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheen;\n#endif";
16218 var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat specularRoughness;\n\tvec3 specularColor;\n#ifdef CLEARCOAT\n\tfloat clearcoat;\n\tfloat clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tvec3 sheenColor;\n#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearcoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen(\n\t\t\tmaterial.specularRoughness,\n\t\t\tdirectLight.direction,\n\t\t\tgeometry,\n\t\t\tmaterial.sheenColor\n\t\t);\n\t#else\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness);\n\t#endif\n\treflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\tfloat clearcoatInv = 1.0 - clearcoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearcoatInv * radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}";
16219 var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif";
16220 var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel );\n\t#ifdef CLEARCOAT\n\t\tclearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel );\n\t#endif\n#endif";
16221 var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif";
16222 var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif";
16223 var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif";
16224 var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t\tvarying float vIsPerspective;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif";
16225 var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n\t#else\n\t\tif ( isPerspectiveMatrix( projectionMatrix ) ) {\n\t\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\t\tgl_Position.z *= gl_Position.w;\n\t\t}\n\t#endif\n#endif";
16226 var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif";
16227 var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif";
16228 var map_particle_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n#endif\n#ifdef USE_MAP\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif";
16229 var map_particle_pars_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tuniform mat3 uvTransform;\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif";
16230 var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif";
16231 var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif";
16232 var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\n\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\n\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\n\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\n#endif";
16233 var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\tuniform float morphTargetBaseInfluence;\n\t#ifndef USE_MORPHNORMALS\n\t\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\t\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif";
16234 var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\t\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\t\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\t\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\t\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t#endif\n#endif";
16235 var normal_fragment_begin = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\t#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;";
16236 var normal_fragment_maps = "#ifdef OBJECTSPACE_NORMALMAP\n\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\t#ifdef USE_TANGENT\n\t\tnormal = normalize( vTBN * mapN );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, mapN );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif";
16237 var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tmat3 tsn = mat3( S, T, N );\n\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif";
16238 var clearcoat_normal_fragment_begin = "#ifdef CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif";
16239 var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\t#ifdef USE_TANGENT\n\t\tclearcoatNormal = normalize( vTBN * clearcoatMapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN );\n\t#endif\n#endif";
16240 var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif";
16241 var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nvec4 pack2HalfToRGBA( vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ));\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w);\n}\nvec2 unpackRGBATo2Half( vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}";
16242 var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif";
16243 var project_vertex = "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;";
16244 var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif";
16245 var dithering_pars_fragment = "#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif";
16246 var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif";
16247 var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif";
16248 var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx = texelSize.x;\n\t\t\tfloat dy = texelSize.y;\n\t\t\tvec2 uv = shadowCoord.xy;\n\t\t\tvec2 f = fract( uv * shadowMapSize + 0.5 );\n\t\t\tuv -= f * texelSize;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t f.y )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif";
16249 var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif";
16250 var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0\n\t\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\tvec4 shadowWorldPosition;\n\t#endif\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n#endif";
16251 var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}";
16252 var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif";
16253 var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform highp sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif";
16254 var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif";
16255 var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif";
16256 var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif";
16257 var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif";
16258 var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif";
16259 var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3( 1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108, 1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605, 1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }";
16260 var transmissionmap_fragment = "#ifdef USE_TRANSMISSIONMAP\n\ttotalTransmission *= texture2D( transmissionMap, vUv ).r;\n#endif";
16261 var transmissionmap_pars_fragment = "#ifdef USE_TRANSMISSIONMAP\n\tuniform sampler2D transmissionMap;\n#endif";
16262 var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif";
16263 var uv_pars_vertex = "#ifdef USE_UV\n\t#ifdef UVS_VERTEX_ONLY\n\t\tvec2 vUv;\n\t#else\n\t\tvarying vec2 vUv;\n\t#endif\n\tuniform mat3 uvTransform;\n#endif";
16264 var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif";
16265 var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif";
16266 var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n\tuniform mat3 uv2Transform;\n#endif";
16267 var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif";
16268 var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif";
16269 var background_frag = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}";
16270 var background_vert = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}";
16271 var cube_frag = "#include <envmap_common_pars_fragment>\nuniform float opacity;\nvarying vec3 vWorldDirection;\n#include <cube_uv_reflection_fragment>\nvoid main() {\n\tvec3 vReflect = vWorldDirection;\n\t#include <envmap_fragment>\n\tgl_FragColor = envColor;\n\tgl_FragColor.a *= opacity;\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}";
16272 var cube_vert = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\tgl_Position.z = gl_Position.w;\n}";
16273 var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#endif\n}";
16274 var depth_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvHighPrecisionZW = gl_Position.zw;\n}";
16275 var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}";
16276 var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}";
16277 var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV = equirectUv( direction );\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}";
16278 var equirect_vert = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}";
16279 var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
16280 var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\tvLineDistance = scale * lineDistance;\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}";
16281 var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
16282 var meshbasic_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_ENVMAP\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}";
16283 var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <emissivemap_fragment>\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include <lightmap_fragment>\n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
16284 var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <lights_lambert_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
16285 var meshmatcap_frag = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t\tmatcapColor = matcapTexelToLinear( matcapColor );\n\t#else\n\t\tvec4 matcapColor = vec4( 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
16286 var meshmatcap_vert = "#define MATCAP\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <color_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n\tvViewPosition = - mvPosition.xyz;\n}";
16287 var meshtoon_frag = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <lights_toon_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_toon_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
16288 var meshtoon_vert = "#define TOON\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
16289 var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
16290 var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
16291 var meshphysical_frag = "#define STANDARD\n#ifdef PHYSICAL\n\t#define REFLECTIVITY\n\t#define CLEARCOAT\n\t#define TRANSMISSION\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef TRANSMISSION\n\tuniform float transmission;\n#endif\n#ifdef REFLECTIVITY\n\tuniform float reflectivity;\n#endif\n#ifdef CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheen;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <transmissionmap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <clearcoat_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#ifdef TRANSMISSION\n\t\tfloat totalTransmission = transmission;\n\t#endif\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <clearcoat_normal_fragment_begin>\n\t#include <clearcoat_normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <transmissionmap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#ifdef TRANSMISSION\n\t\tdiffuseColor.a *= saturate( 1. - totalTransmission + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) );\n\t#endif\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
16292 var meshphysical_vert = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
16293 var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}";
16294 var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}";
16295 var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
16296 var points_vert = "uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n}";
16297 var shadow_frag = "uniform vec3 color;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}";
16298 var shadow_vert = "#include <common>\n#include <fog_pars_vertex>\n#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
16299 var sprite_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}";
16300 var sprite_vert = "uniform float rotation;\nuniform vec2 center;\n#include <common>\n#include <uv_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}";
16301 const ShaderChunk = {
16302 alphamap_fragment: alphamap_fragment,
16303 alphamap_pars_fragment: alphamap_pars_fragment,
16304 alphatest_fragment: alphatest_fragment,
16305 aomap_fragment: aomap_fragment,
16306 aomap_pars_fragment: aomap_pars_fragment,
16307 begin_vertex: begin_vertex,
16308 beginnormal_vertex: beginnormal_vertex,
16309 bsdfs: bsdfs,
16310 bumpmap_pars_fragment: bumpmap_pars_fragment,
16311 clipping_planes_fragment: clipping_planes_fragment,
16312 clipping_planes_pars_fragment: clipping_planes_pars_fragment,
16313 clipping_planes_pars_vertex: clipping_planes_pars_vertex,
16314 clipping_planes_vertex: clipping_planes_vertex,
16315 color_fragment: color_fragment,
16316 color_pars_fragment: color_pars_fragment,
16317 color_pars_vertex: color_pars_vertex,
16318 color_vertex: color_vertex,
16319 common: common,
16320 cube_uv_reflection_fragment: cube_uv_reflection_fragment,
16321 defaultnormal_vertex: defaultnormal_vertex,
16322 displacementmap_pars_vertex: displacementmap_pars_vertex,
16323 displacementmap_vertex: displacementmap_vertex,
16324 emissivemap_fragment: emissivemap_fragment,
16325 emissivemap_pars_fragment: emissivemap_pars_fragment,
16326 encodings_fragment: encodings_fragment,
16327 encodings_pars_fragment: encodings_pars_fragment,
16328 envmap_fragment: envmap_fragment,
16329 envmap_common_pars_fragment: envmap_common_pars_fragment,
16330 envmap_pars_fragment: envmap_pars_fragment,
16331 envmap_pars_vertex: envmap_pars_vertex,
16332 envmap_physical_pars_fragment: envmap_physical_pars_fragment,
16333 envmap_vertex: envmap_vertex,
16334 fog_vertex: fog_vertex,
16335 fog_pars_vertex: fog_pars_vertex,
16336 fog_fragment: fog_fragment,
16337 fog_pars_fragment: fog_pars_fragment,
16338 gradientmap_pars_fragment: gradientmap_pars_fragment,
16339 lightmap_fragment: lightmap_fragment,
16340 lightmap_pars_fragment: lightmap_pars_fragment,
16341 lights_lambert_vertex: lights_lambert_vertex,
16342 lights_pars_begin: lights_pars_begin,
16343 lights_toon_fragment: lights_toon_fragment,
16344 lights_toon_pars_fragment: lights_toon_pars_fragment,
16345 lights_phong_fragment: lights_phong_fragment,
16346 lights_phong_pars_fragment: lights_phong_pars_fragment,
16347 lights_physical_fragment: lights_physical_fragment,
16348 lights_physical_pars_fragment: lights_physical_pars_fragment,
16349 lights_fragment_begin: lights_fragment_begin,
16350 lights_fragment_maps: lights_fragment_maps,
16351 lights_fragment_end: lights_fragment_end,
16352 logdepthbuf_fragment: logdepthbuf_fragment,
16353 logdepthbuf_pars_fragment: logdepthbuf_pars_fragment,
16354 logdepthbuf_pars_vertex: logdepthbuf_pars_vertex,
16355 logdepthbuf_vertex: logdepthbuf_vertex,
16356 map_fragment: map_fragment,
16357 map_pars_fragment: map_pars_fragment,
16358 map_particle_fragment: map_particle_fragment,
16359 map_particle_pars_fragment: map_particle_pars_fragment,
16360 metalnessmap_fragment: metalnessmap_fragment,
16361 metalnessmap_pars_fragment: metalnessmap_pars_fragment,
16362 morphnormal_vertex: morphnormal_vertex,
16363 morphtarget_pars_vertex: morphtarget_pars_vertex,
16364 morphtarget_vertex: morphtarget_vertex,
16365 normal_fragment_begin: normal_fragment_begin,
16366 normal_fragment_maps: normal_fragment_maps,
16367 normalmap_pars_fragment: normalmap_pars_fragment,
16368 clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin,
16369 clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps,
16370 clearcoat_pars_fragment: clearcoat_pars_fragment,
16371 packing: packing,
16372 premultiplied_alpha_fragment: premultiplied_alpha_fragment,
16373 project_vertex: project_vertex,
16374 dithering_fragment: dithering_fragment,
16375 dithering_pars_fragment: dithering_pars_fragment,
16376 roughnessmap_fragment: roughnessmap_fragment,
16377 roughnessmap_pars_fragment: roughnessmap_pars_fragment,
16378 shadowmap_pars_fragment: shadowmap_pars_fragment,
16379 shadowmap_pars_vertex: shadowmap_pars_vertex,
16380 shadowmap_vertex: shadowmap_vertex,
16381 shadowmask_pars_fragment: shadowmask_pars_fragment,
16382 skinbase_vertex: skinbase_vertex,
16383 skinning_pars_vertex: skinning_pars_vertex,
16384 skinning_vertex: skinning_vertex,
16385 skinnormal_vertex: skinnormal_vertex,
16386 specularmap_fragment: specularmap_fragment,
16387 specularmap_pars_fragment: specularmap_pars_fragment,
16388 tonemapping_fragment: tonemapping_fragment,
16389 tonemapping_pars_fragment: tonemapping_pars_fragment,
16390 transmissionmap_fragment: transmissionmap_fragment,
16391 transmissionmap_pars_fragment: transmissionmap_pars_fragment,
16392 uv_pars_fragment: uv_pars_fragment,
16393 uv_pars_vertex: uv_pars_vertex,
16394 uv_vertex: uv_vertex,
16395 uv2_pars_fragment: uv2_pars_fragment,
16396 uv2_pars_vertex: uv2_pars_vertex,
16397 uv2_vertex: uv2_vertex,
16398 worldpos_vertex: worldpos_vertex,
16399 background_frag: background_frag,
16400 background_vert: background_vert,
16401 cube_frag: cube_frag,
16402 cube_vert: cube_vert,
16403 depth_frag: depth_frag,
16404 depth_vert: depth_vert,
16405 distanceRGBA_frag: distanceRGBA_frag,
16406 distanceRGBA_vert: distanceRGBA_vert,
16407 equirect_frag: equirect_frag,
16408 equirect_vert: equirect_vert,
16409 linedashed_frag: linedashed_frag,
16410 linedashed_vert: linedashed_vert,
16411 meshbasic_frag: meshbasic_frag,
16412 meshbasic_vert: meshbasic_vert,
16413 meshlambert_frag: meshlambert_frag,
16414 meshlambert_vert: meshlambert_vert,
16415 meshmatcap_frag: meshmatcap_frag,
16416 meshmatcap_vert: meshmatcap_vert,
16417 meshtoon_frag: meshtoon_frag,
16418 meshtoon_vert: meshtoon_vert,
16419 meshphong_frag: meshphong_frag,
16420 meshphong_vert: meshphong_vert,
16421 meshphysical_frag: meshphysical_frag,
16422 meshphysical_vert: meshphysical_vert,
16423 normal_frag: normal_frag,
16424 normal_vert: normal_vert,
16425 points_frag: points_frag,
16426 points_vert: points_vert,
16427 shadow_frag: shadow_frag,
16428 shadow_vert: shadow_vert,
16429 sprite_frag: sprite_frag,
16430 sprite_vert: sprite_vert
16431 };
16432 const UniformsLib = {
16433 common: {
16434 diffuse: { value: new Color( 0xeeeeee ) },
16435 opacity: { value: 1.0 },
16436 map: { value: null },
16437 uvTransform: { value: new Matrix3() },
16438 uv2Transform: { value: new Matrix3() },
16439 alphaMap: { value: null },
16440 },
16441 specularmap: {
16442 specularMap: { value: null },
16443 },
16444 envmap: {
16445 envMap: { value: null },
16446 flipEnvMap: { value: - 1 },
16447 reflectivity: { value: 1.0 },
16448 refractionRatio: { value: 0.98 },
16449 maxMipLevel: { value: 0 }
16450 },
16451 aomap: {
16452 aoMap: { value: null },
16453 aoMapIntensity: { value: 1 }
16454 },
16455 lightmap: {
16456 lightMap: { value: null },
16457 lightMapIntensity: { value: 1 }
16458 },
16459 emissivemap: {
16460 emissiveMap: { value: null }
16461 },
16462 bumpmap: {
16463 bumpMap: { value: null },
16464 bumpScale: { value: 1 }
16465 },
16466 normalmap: {
16467 normalMap: { value: null },
16468 normalScale: { value: new Vector2( 1, 1 ) }
16469 },
16470 displacementmap: {
16471 displacementMap: { value: null },
16472 displacementScale: { value: 1 },
16473 displacementBias: { value: 0 }
16474 },
16475 roughnessmap: {
16476 roughnessMap: { value: null }
16477 },
16478 metalnessmap: {
16479 metalnessMap: { value: null }
16480 },
16481 gradientmap: {
16482 gradientMap: { value: null }
16483 },
16484 fog: {
16485 fogDensity: { value: 0.00025 },
16486 fogNear: { value: 1 },
16487 fogFar: { value: 2000 },
16488 fogColor: { value: new Color( 0xffffff ) }
16489 },
16490 lights: {
16491 ambientLightColor: { value: [] },
16492 lightProbe: { value: [] },
16493 directionalLights: { value: [], properties: {
16494 direction: {},
16495 color: {}
16496 } },
16497 directionalLightShadows: { value: [], properties: {
16498 shadowBias: {},
16499 shadowNormalBias: {},
16500 shadowRadius: {},
16501 shadowMapSize: {}
16502 } },
16503 directionalShadowMap: { value: [] },
16504 directionalShadowMatrix: { value: [] },
16505 spotLights: { value: [], properties: {
16506 color: {},
16507 position: {},
16508 direction: {},
16509 distance: {},
16510 coneCos: {},
16511 penumbraCos: {},
16512 decay: {}
16513 } },
16514 spotLightShadows: { value: [], properties: {
16515 shadowBias: {},
16516 shadowNormalBias: {},
16517 shadowRadius: {},
16518 shadowMapSize: {}
16519 } },
16520 spotShadowMap: { value: [] },
16521 spotShadowMatrix: { value: [] },
16522 pointLights: { value: [], properties: {
16523 color: {},
16524 position: {},
16525 decay: {},
16526 distance: {}
16527 } },
16528 pointLightShadows: { value: [], properties: {
16529 shadowBias: {},
16530 shadowNormalBias: {},
16531 shadowRadius: {},
16532 shadowMapSize: {},
16533 shadowCameraNear: {},
16534 shadowCameraFar: {}
16535 } },
16536 pointShadowMap: { value: [] },
16537 pointShadowMatrix: { value: [] },
16538 hemisphereLights: { value: [], properties: {
16539 direction: {},
16540 skyColor: {},
16541 groundColor: {}
16542 } },
16543 rectAreaLights: { value: [], properties: {
16544 color: {},
16545 position: {},
16546 width: {},
16547 height: {}
16548 } },
16549 ltc_1: { value: null },
16550 ltc_2: { value: null }
16551 },
16552 points: {
16553 diffuse: { value: new Color( 0xeeeeee ) },
16554 opacity: { value: 1.0 },
16555 size: { value: 1.0 },
16556 scale: { value: 1.0 },
16557 map: { value: null },
16558 alphaMap: { value: null },
16559 uvTransform: { value: new Matrix3() }
16560 },
16561 sprite: {
16562 diffuse: { value: new Color( 0xeeeeee ) },
16563 opacity: { value: 1.0 },
16564 center: { value: new Vector2( 0.5, 0.5 ) },
16565 rotation: { value: 0.0 },
16566 map: { value: null },
16567 alphaMap: { value: null },
16568 uvTransform: { value: new Matrix3() }
16569 }
16570 };
16571 const ShaderLib = {
16572 basic: {
16573 uniforms: mergeUniforms( [
16574 UniformsLib.common,
16575 UniformsLib.specularmap,
16576 UniformsLib.envmap,
16577 UniformsLib.aomap,
16578 UniformsLib.lightmap,
16579 UniformsLib.fog
16580 ] ),
16581 vertexShader: ShaderChunk.meshbasic_vert,
16582 fragmentShader: ShaderChunk.meshbasic_frag
16583 },
16584 lambert: {
16585 uniforms: mergeUniforms( [
16586 UniformsLib.common,
16587 UniformsLib.specularmap,
16588 UniformsLib.envmap,
16589 UniformsLib.aomap,
16590 UniformsLib.lightmap,
16591 UniformsLib.emissivemap,
16592 UniformsLib.fog,
16593 UniformsLib.lights,
16594 {
16595 emissive: { value: new Color( 0x000000 ) }
16596 }
16597 ] ),
16598 vertexShader: ShaderChunk.meshlambert_vert,
16599 fragmentShader: ShaderChunk.meshlambert_frag
16600 },
16601 phong: {
16602 uniforms: mergeUniforms( [
16603 UniformsLib.common,
16604 UniformsLib.specularmap,
16605 UniformsLib.envmap,
16606 UniformsLib.aomap,
16607 UniformsLib.lightmap,
16608 UniformsLib.emissivemap,
16609 UniformsLib.bumpmap,
16610 UniformsLib.normalmap,
16611 UniformsLib.displacementmap,
16612 UniformsLib.fog,
16613 UniformsLib.lights,
16614 {
16615 emissive: { value: new Color( 0x000000 ) },
16616 specular: { value: new Color( 0x111111 ) },
16617 shininess: { value: 30 }
16618 }
16619 ] ),
16620 vertexShader: ShaderChunk.meshphong_vert,
16621 fragmentShader: ShaderChunk.meshphong_frag
16622 },
16623 standard: {
16624 uniforms: mergeUniforms( [
16625 UniformsLib.common,
16626 UniformsLib.envmap,
16627 UniformsLib.aomap,
16628 UniformsLib.lightmap,
16629 UniformsLib.emissivemap,
16630 UniformsLib.bumpmap,
16631 UniformsLib.normalmap,
16632 UniformsLib.displacementmap,
16633 UniformsLib.roughnessmap,
16634 UniformsLib.metalnessmap,
16635 UniformsLib.fog,
16636 UniformsLib.lights,
16637 {
16638 emissive: { value: new Color( 0x000000 ) },
16639 roughness: { value: 1.0 },
16640 metalness: { value: 0.0 },
16641 envMapIntensity: { value: 1 }
16642 }
16643 ] ),
16644 vertexShader: ShaderChunk.meshphysical_vert,
16645 fragmentShader: ShaderChunk.meshphysical_frag
16646 },
16647 toon: {
16648 uniforms: mergeUniforms( [
16649 UniformsLib.common,
16650 UniformsLib.aomap,
16651 UniformsLib.lightmap,
16652 UniformsLib.emissivemap,
16653 UniformsLib.bumpmap,
16654 UniformsLib.normalmap,
16655 UniformsLib.displacementmap,
16656 UniformsLib.gradientmap,
16657 UniformsLib.fog,
16658 UniformsLib.lights,
16659 {
16660 emissive: { value: new Color( 0x000000 ) }
16661 }
16662 ] ),
16663 vertexShader: ShaderChunk.meshtoon_vert,
16664 fragmentShader: ShaderChunk.meshtoon_frag
16665 },
16666 matcap: {
16667 uniforms: mergeUniforms( [
16668 UniformsLib.common,
16669 UniformsLib.bumpmap,
16670 UniformsLib.normalmap,
16671 UniformsLib.displacementmap,
16672 UniformsLib.fog,
16673 {
16674 matcap: { value: null }
16675 }
16676 ] ),
16677 vertexShader: ShaderChunk.meshmatcap_vert,
16678 fragmentShader: ShaderChunk.meshmatcap_frag
16679 },
16680 points: {
16681 uniforms: mergeUniforms( [
16682 UniformsLib.points,
16683 UniformsLib.fog
16684 ] ),
16685 vertexShader: ShaderChunk.points_vert,
16686 fragmentShader: ShaderChunk.points_frag
16687 },
16688 dashed: {
16689 uniforms: mergeUniforms( [
16690 UniformsLib.common,
16691 UniformsLib.fog,
16692 {
16693 scale: { value: 1 },
16694 dashSize: { value: 1 },
16695 totalSize: { value: 2 }
16696 }
16697 ] ),
16698 vertexShader: ShaderChunk.linedashed_vert,
16699 fragmentShader: ShaderChunk.linedashed_frag
16700 },
16701 depth: {
16702 uniforms: mergeUniforms( [
16703 UniformsLib.common,
16704 UniformsLib.displacementmap
16705 ] ),
16706 vertexShader: ShaderChunk.depth_vert,
16707 fragmentShader: ShaderChunk.depth_frag
16708 },
16709 normal: {
16710 uniforms: mergeUniforms( [
16711 UniformsLib.common,
16712 UniformsLib.bumpmap,
16713 UniformsLib.normalmap,
16714 UniformsLib.displacementmap,
16715 {
16716 opacity: { value: 1.0 }
16717 }
16718 ] ),
16719 vertexShader: ShaderChunk.normal_vert,
16720 fragmentShader: ShaderChunk.normal_frag
16721 },
16722 sprite: {
16723 uniforms: mergeUniforms( [
16724 UniformsLib.sprite,
16725 UniformsLib.fog
16726 ] ),
16727 vertexShader: ShaderChunk.sprite_vert,
16728 fragmentShader: ShaderChunk.sprite_frag
16729 },
16730 background: {
16731 uniforms: {
16732 uvTransform: { value: new Matrix3() },
16733 t2D: { value: null },
16734 },
16735 vertexShader: ShaderChunk.background_vert,
16736 fragmentShader: ShaderChunk.background_frag
16737 },
16738 cube: {
16739 uniforms: mergeUniforms( [
16740 UniformsLib.envmap,
16741 {
16742 opacity: { value: 1.0 }
16743 }
16744 ] ),
16745 vertexShader: ShaderChunk.cube_vert,
16746 fragmentShader: ShaderChunk.cube_frag
16747 },
16748 equirect: {
16749 uniforms: {
16750 tEquirect: { value: null },
16751 },
16752 vertexShader: ShaderChunk.equirect_vert,
16753 fragmentShader: ShaderChunk.equirect_frag
16754 },
16755 distanceRGBA: {
16756 uniforms: mergeUniforms( [
16757 UniformsLib.common,
16758 UniformsLib.displacementmap,
16759 {
16760 referencePosition: { value: new Vector3() },
16761 nearDistance: { value: 1 },
16762 farDistance: { value: 1000 }
16763 }
16764 ] ),
16765 vertexShader: ShaderChunk.distanceRGBA_vert,
16766 fragmentShader: ShaderChunk.distanceRGBA_frag
16767 },
16768 shadow: {
16769 uniforms: mergeUniforms( [
16770 UniformsLib.lights,
16771 UniformsLib.fog,
16772 {
16773 color: { value: new Color( 0x00000 ) },
16774 opacity: { value: 1.0 }
16775 },
16776 ] ),
16777 vertexShader: ShaderChunk.shadow_vert,
16778 fragmentShader: ShaderChunk.shadow_frag
16779 }
16780 };
16781 ShaderLib.physical = {
16782 uniforms: mergeUniforms( [
16783 ShaderLib.standard.uniforms,
16784 {
16785 clearcoat: { value: 0 },
16786 clearcoatMap: { value: null },
16787 clearcoatRoughness: { value: 0 },
16788 clearcoatRoughnessMap: { value: null },
16789 clearcoatNormalScale: { value: new Vector2( 1, 1 ) },
16790 clearcoatNormalMap: { value: null },
16791 sheen: { value: new Color( 0x000000 ) },
16792 transmission: { value: 0 },
16793 transmissionMap: { value: null },
16794 }
16795 ] ),
16796 vertexShader: ShaderChunk.meshphysical_vert,
16797 fragmentShader: ShaderChunk.meshphysical_frag
16798 };
16799 function WebGLBackground( renderer, cubemaps, state, objects, premultipliedAlpha ) {
16800 const clearColor = new Color( 0x000000 );
16801 let clearAlpha = 0;
16802 let planeMesh;
16803 let boxMesh;
16804 let currentBackground = null;
16805 let currentBackgroundVersion = 0;
16806 let currentTonemapping = null;
16807 function render( renderList, scene, camera, forceClear ) {
16808 let background = scene.isScene === true ? scene.background : null;
16809 if ( background && background.isTexture ) {
16810 background = cubemaps.get( background );
16811 }
16812 const xr = renderer.xr;
16813 const session = xr.getSession && xr.getSession();
16814 if ( session && session.environmentBlendMode === 'additive' ) {
16815 background = null;
16816 }
16817 if ( background === null ) {
16818 setClear( clearColor, clearAlpha );
16819 } else if ( background && background.isColor ) {
16820 setClear( background, 1 );
16821 forceClear = true;
16822 }
16823 if ( renderer.autoClear || forceClear ) {
16824 renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
16825 }
16826 if ( background && ( background.isCubeTexture || background.isWebGLCubeRenderTarget || background.isWebGLCubeRenderTargetTexture || background.mapping === CubeUVReflectionMapping ) ) {
16827 if ( boxMesh === undefined ) {
16828 boxMesh = new Mesh(
16829 new BoxBufferGeometry( 1, 1, 1 ),
16830 new ShaderMaterial( {
16831 name: 'BackgroundCubeMaterial',
16832 uniforms: cloneUniforms( ShaderLib.cube.uniforms ),
16833 vertexShader: ShaderLib.cube.vertexShader,
16834 fragmentShader: ShaderLib.cube.fragmentShader,
16835 side: BackSide,
16836 depthTest: false,
16837 depthWrite: false,
16838 fog: false
16839 } )
16840 );
16841 boxMesh.geometry.deleteAttribute( 'normal' );
16842 boxMesh.geometry.deleteAttribute( 'uv' );
16843 boxMesh.onBeforeRender = function ( renderer, scene, camera ) {
16844 this.matrixWorld.copyPosition( camera.matrixWorld );
16845 };
16846 Object.defineProperty( boxMesh.material, 'envMap', {
16847 get: function () {
16848 return this.uniforms.envMap.value;
16849 }
16850 } );
16851 objects.update( boxMesh );
16852 }
16853 if ( background.isWebGLCubeRenderTarget ) {
16854 background = background.texture;
16855 }
16856 boxMesh.material.uniforms.envMap.value = background;
16857 boxMesh.material.uniforms.flipEnvMap.value = background.isCubeTexture ? - 1 : 1;
16858 if ( currentBackground !== background ||
16859 currentBackgroundVersion !== background.version ||
16860 currentTonemapping !== renderer.toneMapping ) {
16861 boxMesh.material.needsUpdate = true;
16862 currentBackground = background;
16863 currentBackgroundVersion = background.version;
16864 currentTonemapping = renderer.toneMapping;
16865 }
16866 renderList.unshift( boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null );
16867 } else if ( background && background.isTexture ) {
16868 if ( planeMesh === undefined ) {
16869 planeMesh = new Mesh(
16870 new PlaneBufferGeometry( 2, 2 ),
16871 new ShaderMaterial( {
16872 name: 'BackgroundMaterial',
16873 uniforms: cloneUniforms( ShaderLib.background.uniforms ),
16874 vertexShader: ShaderLib.background.vertexShader,
16875 fragmentShader: ShaderLib.background.fragmentShader,
16876 side: FrontSide,
16877 depthTest: false,
16878 depthWrite: false,
16879 fog: false
16880 } )
16881 );
16882 planeMesh.geometry.deleteAttribute( 'normal' );
16883 Object.defineProperty( planeMesh.material, 'map', {
16884 get: function () {
16885 return this.uniforms.t2D.value;
16886 }
16887 } );
16888 objects.update( planeMesh );
16889 }
16890 planeMesh.material.uniforms.t2D.value = background;
16891 if ( background.matrixAutoUpdate === true ) {
16892 background.updateMatrix();
16893 }
16894 planeMesh.material.uniforms.uvTransform.value.copy( background.matrix );
16895 if ( currentBackground !== background ||
16896 currentBackgroundVersion !== background.version ||
16897 currentTonemapping !== renderer.toneMapping ) {
16898 planeMesh.material.needsUpdate = true;
16899 currentBackground = background;
16900 currentBackgroundVersion = background.version;
16901 currentTonemapping = renderer.toneMapping;
16902 }
16903 renderList.unshift( planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null );
16904 }
16905 }
16906 function setClear( color, alpha ) {
16907 state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha );
16908 }
16909 return {
16910 getClearColor: function () {
16911 return clearColor;
16912 },
16913 setClearColor: function ( color, alpha ) {
16914 clearColor.set( color );
16915 clearAlpha = alpha !== undefined ? alpha : 1;
16916 setClear( clearColor, clearAlpha );
16917 },
16918 getClearAlpha: function () {
16919 return clearAlpha;
16920 },
16921 setClearAlpha: function ( alpha ) {
16922 clearAlpha = alpha;
16923 setClear( clearColor, clearAlpha );
16924 },
16925 render: render
16926 };
16927 }
16928 function WebGLBindingStates( gl, extensions, attributes, capabilities ) {
16929 const maxVertexAttributes = gl.getParameter( 34921 );
16930 const extension = capabilities.isWebGL2 ? null : extensions.get( 'OES_vertex_array_object' );
16931 const vaoAvailable = capabilities.isWebGL2 || extension !== null;
16932 const bindingStates = {};
16933 const defaultState = createBindingState( null );
16934 let currentState = defaultState;
16935 function setup( object, material, program, geometry, index ) {
16936 let updateBuffers = false;
16937 if ( vaoAvailable ) {
16938 const state = getBindingState( geometry, program, material );
16939 if ( currentState !== state ) {
16940 currentState = state;
16941 bindVertexArrayObject( currentState.object );
16942 }
16943 updateBuffers = needsUpdate( geometry, index );
16944 if ( updateBuffers ) saveCache( geometry, index );
16945 } else {
16946 const wireframe = ( material.wireframe === true );
16947 if ( currentState.geometry !== geometry.id ||
16948 currentState.program !== program.id ||
16949 currentState.wireframe !== wireframe ) {
16950 currentState.geometry = geometry.id;
16951 currentState.program = program.id;
16952 currentState.wireframe = wireframe;
16953 updateBuffers = true;
16954 }
16955 }
16956 if ( object.isInstancedMesh === true ) {
16957 updateBuffers = true;
16958 }
16959 if ( index !== null ) {
16960 attributes.update( index, 34963 );
16961 }
16962 if ( updateBuffers ) {
16963 setupVertexAttributes( object, material, program, geometry );
16964 if ( index !== null ) {
16965 gl.bindBuffer( 34963, attributes.get( index ).buffer );
16966 }
16967 }
16968 }
16969 function createVertexArrayObject() {
16970 if ( capabilities.isWebGL2 ) return gl.createVertexArray();
16971 return extension.createVertexArrayOES();
16972 }
16973 function bindVertexArrayObject( vao ) {
16974 if ( capabilities.isWebGL2 ) return gl.bindVertexArray( vao );
16975 return extension.bindVertexArrayOES( vao );
16976 }
16977 function deleteVertexArrayObject( vao ) {
16978 if ( capabilities.isWebGL2 ) return gl.deleteVertexArray( vao );
16979 return extension.deleteVertexArrayOES( vao );
16980 }
16981 function getBindingState( geometry, program, material ) {
16982 const wireframe = ( material.wireframe === true );
16983 let programMap = bindingStates[ geometry.id ];
16984 if ( programMap === undefined ) {
16985 programMap = {};
16986 bindingStates[ geometry.id ] = programMap;
16987 }
16988 let stateMap = programMap[ program.id ];
16989 if ( stateMap === undefined ) {
16990 stateMap = {};
16991 programMap[ program.id ] = stateMap;
16992 }
16993 let state = stateMap[ wireframe ];
16994 if ( state === undefined ) {
16995 state = createBindingState( createVertexArrayObject() );
16996 stateMap[ wireframe ] = state;
16997 }
16998 return state;
16999 }
17000 function createBindingState( vao ) {
17001 const newAttributes = [];
17002 const enabledAttributes = [];
17003 const attributeDivisors = [];
17004 for ( let i = 0; i < maxVertexAttributes; i ++ ) {
17005 newAttributes[ i ] = 0;
17006 enabledAttributes[ i ] = 0;
17007 attributeDivisors[ i ] = 0;
17008 }
17009 return {
17010 geometry: null,
17011 program: null,
17012 wireframe: false,
17013 newAttributes: newAttributes,
17014 enabledAttributes: enabledAttributes,
17015 attributeDivisors: attributeDivisors,
17016 object: vao,
17017 attributes: {},
17018 index: null
17019 };
17020 }
17021 function needsUpdate( geometry, index ) {
17022 const cachedAttributes = currentState.attributes;
17023 const geometryAttributes = geometry.attributes;
17024 if ( Object.keys( cachedAttributes ).length !== Object.keys( geometryAttributes ).length ) return true;
17025 for ( const key in geometryAttributes ) {
17026 const cachedAttribute = cachedAttributes[ key ];
17027 const geometryAttribute = geometryAttributes[ key ];
17028 if ( cachedAttribute === undefined ) return true;
17029 if ( cachedAttribute.attribute !== geometryAttribute ) return true;
17030 if ( cachedAttribute.data !== geometryAttribute.data ) return true;
17031 }
17032 if ( currentState.index !== index ) return true;
17033 return false;
17034 }
17035 function saveCache( geometry, index ) {
17036 const cache = {};
17037 const attributes = geometry.attributes;
17038 for ( const key in attributes ) {
17039 const attribute = attributes[ key ];
17040 const data = {};
17041 data.attribute = attribute;
17042 if ( attribute.data ) {
17043 data.data = attribute.data;
17044 }
17045 cache[ key ] = data;
17046 }
17047 currentState.attributes = cache;
17048 currentState.index = index;
17049 }
17050 function initAttributes() {
17051 const newAttributes = currentState.newAttributes;
17052 for ( let i = 0, il = newAttributes.length; i < il; i ++ ) {
17053 newAttributes[ i ] = 0;
17054 }
17055 }
17056 function enableAttribute( attribute ) {
17057 enableAttributeAndDivisor( attribute, 0 );
17058 }
17059 function enableAttributeAndDivisor( attribute, meshPerAttribute ) {
17060 const newAttributes = currentState.newAttributes;
17061 const enabledAttributes = currentState.enabledAttributes;
17062 const attributeDivisors = currentState.attributeDivisors;
17063 newAttributes[ attribute ] = 1;
17064 if ( enabledAttributes[ attribute ] === 0 ) {
17065 gl.enableVertexAttribArray( attribute );
17066 enabledAttributes[ attribute ] = 1;
17067 }
17068 if ( attributeDivisors[ attribute ] !== meshPerAttribute ) {
17069 const extension = capabilities.isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' );
17070 extension[ capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute );
17071 attributeDivisors[ attribute ] = meshPerAttribute;
17072 }
17073 }
17074 function disableUnusedAttributes() {
17075 const newAttributes = currentState.newAttributes;
17076 const enabledAttributes = currentState.enabledAttributes;
17077 for ( let i = 0, il = enabledAttributes.length; i < il; i ++ ) {
17078 if ( enabledAttributes[ i ] !== newAttributes[ i ] ) {
17079 gl.disableVertexAttribArray( i );
17080 enabledAttributes[ i ] = 0;
17081 }
17082 }
17083 }
17084 function vertexAttribPointer( index, size, type, normalized, stride, offset ) {
17085 if ( capabilities.isWebGL2 === true && ( type === 5124 || type === 5125 ) ) {
17086 gl.vertexAttribIPointer( index, size, type, stride, offset );
17087 } else {
17088 gl.vertexAttribPointer( index, size, type, normalized, stride, offset );
17089 }
17090 }
17091 function setupVertexAttributes( object, material, program, geometry ) {
17092 if ( capabilities.isWebGL2 === false && ( object.isInstancedMesh || geometry.isInstancedBufferGeometry ) ) {
17093 if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) return;
17094 }
17095 initAttributes();
17096 const geometryAttributes = geometry.attributes;
17097 const programAttributes = program.getAttributes();
17098 const materialDefaultAttributeValues = material.defaultAttributeValues;
17099 for ( const name in programAttributes ) {
17100 const programAttribute = programAttributes[ name ];
17101 if ( programAttribute >= 0 ) {
17102 const geometryAttribute = geometryAttributes[ name ];
17103 if ( geometryAttribute !== undefined ) {
17104 const normalized = geometryAttribute.normalized;
17105 const size = geometryAttribute.itemSize;
17106 const attribute = attributes.get( geometryAttribute );
17107 if ( attribute === undefined ) continue;
17108 const buffer = attribute.buffer;
17109 const type = attribute.type;
17110 const bytesPerElement = attribute.bytesPerElement;
17111 if ( geometryAttribute.isInterleavedBufferAttribute ) {
17112 const data = geometryAttribute.data;
17113 const stride = data.stride;
17114 const offset = geometryAttribute.offset;
17115 if ( data && data.isInstancedInterleavedBuffer ) {
17116 enableAttributeAndDivisor( programAttribute, data.meshPerAttribute );
17117 if ( geometry._maxInstanceCount === undefined ) {
17118 geometry._maxInstanceCount = data.meshPerAttribute * data.count;
17119 }
17120 } else {
17121 enableAttribute( programAttribute );
17122 }
17123 gl.bindBuffer( 34962, buffer );
17124 vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, offset * bytesPerElement );
17125 } else {
17126 if ( geometryAttribute.isInstancedBufferAttribute ) {
17127 enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute );
17128 if ( geometry._maxInstanceCount === undefined ) {
17129 geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
17130 }
17131 } else {
17132 enableAttribute( programAttribute );
17133 }
17134 gl.bindBuffer( 34962, buffer );
17135 vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 );
17136 }
17137 } else if ( name === 'instanceMatrix' ) {
17138 const attribute = attributes.get( object.instanceMatrix );
17139 if ( attribute === undefined ) continue;
17140 const buffer = attribute.buffer;
17141 const type = attribute.type;
17142 enableAttributeAndDivisor( programAttribute + 0, 1 );
17143 enableAttributeAndDivisor( programAttribute + 1, 1 );
17144 enableAttributeAndDivisor( programAttribute + 2, 1 );
17145 enableAttributeAndDivisor( programAttribute + 3, 1 );
17146 gl.bindBuffer( 34962, buffer );
17147 gl.vertexAttribPointer( programAttribute + 0, 4, type, false, 64, 0 );
17148 gl.vertexAttribPointer( programAttribute + 1, 4, type, false, 64, 16 );
17149 gl.vertexAttribPointer( programAttribute + 2, 4, type, false, 64, 32 );
17150 gl.vertexAttribPointer( programAttribute + 3, 4, type, false, 64, 48 );
17151 } else if ( name === 'instanceColor' ) {
17152 const attribute = attributes.get( object.instanceColor );
17153 if ( attribute === undefined ) continue;
17154 const buffer = attribute.buffer;
17155 const type = attribute.type;
17156 enableAttributeAndDivisor( programAttribute, 1 );
17157 gl.bindBuffer( 34962, buffer );
17158 gl.vertexAttribPointer( programAttribute, 3, type, false, 12, 0 );
17159 } else if ( materialDefaultAttributeValues !== undefined ) {
17160 const value = materialDefaultAttributeValues[ name ];
17161 if ( value !== undefined ) {
17162 switch ( value.length ) {
17163 case 2:
17164 gl.vertexAttrib2fv( programAttribute, value );
17165 break;
17166 case 3:
17167 gl.vertexAttrib3fv( programAttribute, value );
17168 break;
17169 case 4:
17170 gl.vertexAttrib4fv( programAttribute, value );
17171 break;
17172 default:
17173 gl.vertexAttrib1fv( programAttribute, value );
17174 }
17175 }
17176 }
17177 }
17178 }
17179 disableUnusedAttributes();
17180 }
17181 function dispose() {
17182 reset();
17183 for ( const geometryId in bindingStates ) {
17184 const programMap = bindingStates[ geometryId ];
17185 for ( const programId in programMap ) {
17186 const stateMap = programMap[ programId ];
17187 for ( const wireframe in stateMap ) {
17188 deleteVertexArrayObject( stateMap[ wireframe ].object );
17189 delete stateMap[ wireframe ];
17190 }
17191 delete programMap[ programId ];
17192 }
17193 delete bindingStates[ geometryId ];
17194 }
17195 }
17196 function releaseStatesOfGeometry( geometry ) {
17197 if ( bindingStates[ geometry.id ] === undefined ) return;
17198 const programMap = bindingStates[ geometry.id ];
17199 for ( const programId in programMap ) {
17200 const stateMap = programMap[ programId ];
17201 for ( const wireframe in stateMap ) {
17202 deleteVertexArrayObject( stateMap[ wireframe ].object );
17203 delete stateMap[ wireframe ];
17204 }
17205 delete programMap[ programId ];
17206 }
17207 delete bindingStates[ geometry.id ];
17208 }
17209 function releaseStatesOfProgram( program ) {
17210 for ( const geometryId in bindingStates ) {
17211 const programMap = bindingStates[ geometryId ];
17212 if ( programMap[ program.id ] === undefined ) continue;
17213 const stateMap = programMap[ program.id ];
17214 for ( const wireframe in stateMap ) {
17215 deleteVertexArrayObject( stateMap[ wireframe ].object );
17216 delete stateMap[ wireframe ];
17217 }
17218 delete programMap[ program.id ];
17219 }
17220 }
17221 function reset() {
17222 resetDefaultState();
17223 if ( currentState === defaultState ) return;
17224 currentState = defaultState;
17225 bindVertexArrayObject( currentState.object );
17226 }
17227 function resetDefaultState() {
17228 defaultState.geometry = null;
17229 defaultState.program = null;
17230 defaultState.wireframe = false;
17231 }
17232 return {
17233 setup: setup,
17234 reset: reset,
17235 resetDefaultState: resetDefaultState,
17236 dispose: dispose,
17237 releaseStatesOfGeometry: releaseStatesOfGeometry,
17238 releaseStatesOfProgram: releaseStatesOfProgram,
17239 initAttributes: initAttributes,
17240 enableAttribute: enableAttribute,
17241 disableUnusedAttributes: disableUnusedAttributes
17242 };
17243 }
17244 function WebGLBufferRenderer( gl, extensions, info, capabilities ) {
17245 const isWebGL2 = capabilities.isWebGL2;
17246 let mode;
17247 function setMode( value ) {
17248 mode = value;
17249 }
17250 function render( start, count ) {
17251 gl.drawArrays( mode, start, count );
17252 info.update( count, mode, 1 );
17253 }
17254 function renderInstances( start, count, primcount ) {
17255 if ( primcount === 0 ) return;
17256 let extension, methodName;
17257 if ( isWebGL2 ) {
17258 extension = gl;
17259 methodName = 'drawArraysInstanced';
17260 } else {
17261 extension = extensions.get( 'ANGLE_instanced_arrays' );
17262 methodName = 'drawArraysInstancedANGLE';
17263 if ( extension === null ) {
17264 console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
17265 return;
17266 }
17267 }
17268 extension[ methodName ]( mode, start, count, primcount );
17269 info.update( count, mode, primcount );
17270 }
17271 this.setMode = setMode;
17272 this.render = render;
17273 this.renderInstances = renderInstances;
17274 }
17275 function WebGLCapabilities( gl, extensions, parameters ) {
17276 let maxAnisotropy;
17277 function getMaxAnisotropy() {
17278 if ( maxAnisotropy !== undefined ) return maxAnisotropy;
17279 const extension = extensions.get( 'EXT_texture_filter_anisotropic' );
17280 if ( extension !== null ) {
17281 maxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );
17282 } else {
17283 maxAnisotropy = 0;
17284 }
17285 return maxAnisotropy;
17286 }
17287 function getMaxPrecision( precision ) {
17288 if ( precision === 'highp' ) {
17289 if ( gl.getShaderPrecisionFormat( 35633, 36338 ).precision > 0 &&
17290 gl.getShaderPrecisionFormat( 35632, 36338 ).precision > 0 ) {
17291 return 'highp';
17292 }
17293 precision = 'mediump';
17294 }
17295 if ( precision === 'mediump' ) {
17296 if ( gl.getShaderPrecisionFormat( 35633, 36337 ).precision > 0 &&
17297 gl.getShaderPrecisionFormat( 35632, 36337 ).precision > 0 ) {
17298 return 'mediump';
17299 }
17300 }
17301 return 'lowp';
17302 }
17303 const isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext ) ||
17304 ( typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext );
17305 let precision = parameters.precision !== undefined ? parameters.precision : 'highp';
17306 const maxPrecision = getMaxPrecision( precision );
17307 if ( maxPrecision !== precision ) {
17308 console.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );
17309 precision = maxPrecision;
17310 }
17311 const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true;
17312 const maxTextures = gl.getParameter( 34930 );
17313 const maxVertexTextures = gl.getParameter( 35660 );
17314 const maxTextureSize = gl.getParameter( 3379 );
17315 const maxCubemapSize = gl.getParameter( 34076 );
17316 const maxAttributes = gl.getParameter( 34921 );
17317 const maxVertexUniforms = gl.getParameter( 36347 );
17318 const maxVaryings = gl.getParameter( 36348 );
17319 const maxFragmentUniforms = gl.getParameter( 36349 );
17320 const vertexTextures = maxVertexTextures > 0;
17321 const floatFragmentTextures = isWebGL2 || !! extensions.get( 'OES_texture_float' );
17322 const floatVertexTextures = vertexTextures && floatFragmentTextures;
17323 const maxSamples = isWebGL2 ? gl.getParameter( 36183 ) : 0;
17324 return {
17325 isWebGL2: isWebGL2,
17326 getMaxAnisotropy: getMaxAnisotropy,
17327 getMaxPrecision: getMaxPrecision,
17328 precision: precision,
17329 logarithmicDepthBuffer: logarithmicDepthBuffer,
17330 maxTextures: maxTextures,
17331 maxVertexTextures: maxVertexTextures,
17332 maxTextureSize: maxTextureSize,
17333 maxCubemapSize: maxCubemapSize,
17334 maxAttributes: maxAttributes,
17335 maxVertexUniforms: maxVertexUniforms,
17336 maxVaryings: maxVaryings,
17337 maxFragmentUniforms: maxFragmentUniforms,
17338 vertexTextures: vertexTextures,
17339 floatFragmentTextures: floatFragmentTextures,
17340 floatVertexTextures: floatVertexTextures,
17341 maxSamples: maxSamples
17342 };
17343 }
17344 function WebGLClipping( properties ) {
17345 const scope = this;
17346 let globalState = null,
17347 numGlobalPlanes = 0,
17348 localClippingEnabled = false,
17349 renderingShadows = false;
17350 const plane = new Plane(),
17351 viewNormalMatrix = new Matrix3(),
17352 uniform = { value: null, needsUpdate: false };
17353 this.uniform = uniform;
17354 this.numPlanes = 0;
17355 this.numIntersection = 0;
17356 this.init = function ( planes, enableLocalClipping, camera ) {
17357 const enabled =
17358 planes.length !== 0 ||
17359 enableLocalClipping ||
17360 numGlobalPlanes !== 0 ||
17361 localClippingEnabled;
17362 localClippingEnabled = enableLocalClipping;
17363 globalState = projectPlanes( planes, camera, 0 );
17364 numGlobalPlanes = planes.length;
17365 return enabled;
17366 };
17367 this.beginShadows = function () {
17368 renderingShadows = true;
17369 projectPlanes( null );
17370 };
17371 this.endShadows = function () {
17372 renderingShadows = false;
17373 resetGlobalState();
17374 };
17375 this.setState = function ( material, camera, useCache ) {
17376 const planes = material.clippingPlanes,
17377 clipIntersection = material.clipIntersection,
17378 clipShadows = material.clipShadows;
17379 const materialProperties = properties.get( material );
17380 if ( ! localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && ! clipShadows ) {
17381 if ( renderingShadows ) {
17382 projectPlanes( null );
17383 } else {
17384 resetGlobalState();
17385 }
17386 } else {
17387 const nGlobal = renderingShadows ? 0 : numGlobalPlanes,
17388 lGlobal = nGlobal * 4;
17389 let dstArray = materialProperties.clippingState || null;
17390 uniform.value = dstArray;
17391 dstArray = projectPlanes( planes, camera, lGlobal, useCache );
17392 for ( let i = 0; i !== lGlobal; ++ i ) {
17393 dstArray[ i ] = globalState[ i ];
17394 }
17395 materialProperties.clippingState = dstArray;
17396 this.numIntersection = clipIntersection ? this.numPlanes : 0;
17397 this.numPlanes += nGlobal;
17398 }
17399 };
17400 function resetGlobalState() {
17401 if ( uniform.value !== globalState ) {
17402 uniform.value = globalState;
17403 uniform.needsUpdate = numGlobalPlanes > 0;
17404 }
17405 scope.numPlanes = numGlobalPlanes;
17406 scope.numIntersection = 0;
17407 }
17408 function projectPlanes( planes, camera, dstOffset, skipTransform ) {
17409 const nPlanes = planes !== null ? planes.length : 0;
17410 let dstArray = null;
17411 if ( nPlanes !== 0 ) {
17412 dstArray = uniform.value;
17413 if ( skipTransform !== true || dstArray === null ) {
17414 const flatSize = dstOffset + nPlanes * 4,
17415 viewMatrix = camera.matrixWorldInverse;
17416 viewNormalMatrix.getNormalMatrix( viewMatrix );
17417 if ( dstArray === null || dstArray.length < flatSize ) {
17418 dstArray = new Float32Array( flatSize );
17419 }
17420 for ( let i = 0, i4 = dstOffset; i !== nPlanes; ++ i, i4 += 4 ) {
17421 plane.copy( planes[ i ] ).applyMatrix4( viewMatrix, viewNormalMatrix );
17422 plane.normal.toArray( dstArray, i4 );
17423 dstArray[ i4 + 3 ] = plane.constant;
17424 }
17425 }
17426 uniform.value = dstArray;
17427 uniform.needsUpdate = true;
17428 }
17429 scope.numPlanes = nPlanes;
17430 scope.numIntersection = 0;
17431 return dstArray;
17432 }
17433 }
17434 function WebGLCubeMaps( renderer ) {
17435 let cubemaps = new WeakMap();
17436 function mapTextureMapping( texture, mapping ) {
17437 if ( mapping === EquirectangularReflectionMapping ) {
17438 texture.mapping = CubeReflectionMapping;
17439 } else if ( mapping === EquirectangularRefractionMapping ) {
17440 texture.mapping = CubeRefractionMapping;
17441 }
17442 return texture;
17443 }
17444 function get( texture ) {
17445 if ( texture && texture.isTexture ) {
17446 const mapping = texture.mapping;
17447 if ( mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping ) {
17448 if ( cubemaps.has( texture ) ) {
17449 const cubemap = cubemaps.get( texture ).texture;
17450 return mapTextureMapping( cubemap, texture.mapping );
17451 } else {
17452 const image = texture.image;
17453 if ( image && image.height > 0 ) {
17454 const currentRenderList = renderer.getRenderList();
17455 const currentRenderTarget = renderer.getRenderTarget();
17456 const currentRenderState = renderer.getRenderState();
17457 const renderTarget = new WebGLCubeRenderTarget( image.height / 2 );
17458 renderTarget.fromEquirectangularTexture( renderer, texture );
17459 cubemaps.set( texture, renderTarget );
17460 renderer.setRenderTarget( currentRenderTarget );
17461 renderer.setRenderList( currentRenderList );
17462 renderer.setRenderState( currentRenderState );
17463 return mapTextureMapping( renderTarget.texture, texture.mapping );
17464 } else {
17465 return null;
17466 }
17467 }
17468 }
17469 }
17470 return texture;
17471 }
17472 function dispose() {
17473 cubemaps = new WeakMap();
17474 }
17475 return {
17476 get: get,
17477 dispose: dispose
17478 };
17479 }
17480 function WebGLExtensions( gl ) {
17481 const extensions = {};
17482 return {
17483 has: function ( name ) {
17484 if ( extensions[ name ] !== undefined ) {
17485 return extensions[ name ] !== null;
17486 }
17487 let extension;
17488 switch ( name ) {
17489 case 'WEBGL_depth_texture':
17490 extension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );
17491 break;
17492 case 'EXT_texture_filter_anisotropic':
17493 extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );
17494 break;
17495 case 'WEBGL_compressed_texture_s3tc':
17496 extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );
17497 break;
17498 case 'WEBGL_compressed_texture_pvrtc':
17499 extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );
17500 break;
17501 default:
17502 extension = gl.getExtension( name );
17503 }
17504 extensions[ name ] = extension;
17505 return extension !== null;
17506 },
17507 get: function ( name ) {
17508 if ( ! this.has( name ) ) {
17509 console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );
17510 }
17511 return extensions[ name ];
17512 }
17513 };
17514 }
17515 function WebGLGeometries( gl, attributes, info, bindingStates ) {
17516 const geometries = new WeakMap();
17517 const wireframeAttributes = new WeakMap();
17518 function onGeometryDispose( event ) {
17519 const geometry = event.target;
17520 const buffergeometry = geometries.get( geometry );
17521 if ( buffergeometry.index !== null ) {
17522 attributes.remove( buffergeometry.index );
17523 }
17524 for ( const name in buffergeometry.attributes ) {
17525 attributes.remove( buffergeometry.attributes[ name ] );
17526 }
17527 geometry.removeEventListener( 'dispose', onGeometryDispose );
17528 geometries.delete( geometry );
17529 const attribute = wireframeAttributes.get( buffergeometry );
17530 if ( attribute ) {
17531 attributes.remove( attribute );
17532 wireframeAttributes.delete( buffergeometry );
17533 }
17534 bindingStates.releaseStatesOfGeometry( geometry );
17535 if ( geometry.isInstancedBufferGeometry === true ) {
17536 delete geometry._maxInstanceCount;
17537 }
17538 info.memory.geometries --;
17539 }
17540 function get( object, geometry ) {
17541 let buffergeometry = geometries.get( geometry );
17542 if ( buffergeometry ) return buffergeometry;
17543 geometry.addEventListener( 'dispose', onGeometryDispose );
17544 if ( geometry.isBufferGeometry ) {
17545 buffergeometry = geometry;
17546 } else if ( geometry.isGeometry ) {
17547 if ( geometry._bufferGeometry === undefined ) {
17548 geometry._bufferGeometry = new BufferGeometry().setFromObject( object );
17549 }
17550 buffergeometry = geometry._bufferGeometry;
17551 }
17552 geometries.set( geometry, buffergeometry );
17553 info.memory.geometries ++;
17554 return buffergeometry;
17555 }
17556 function update( geometry ) {
17557 const geometryAttributes = geometry.attributes;
17558 for ( const name in geometryAttributes ) {
17559 attributes.update( geometryAttributes[ name ], 34962 );
17560 }
17561 const morphAttributes = geometry.morphAttributes;
17562 for ( const name in morphAttributes ) {
17563 const array = morphAttributes[ name ];
17564 for ( let i = 0, l = array.length; i < l; i ++ ) {
17565 attributes.update( array[ i ], 34962 );
17566 }
17567 }
17568 }
17569 function updateWireframeAttribute( geometry ) {
17570 const indices = [];
17571 const geometryIndex = geometry.index;
17572 const geometryPosition = geometry.attributes.position;
17573 let version = 0;
17574 if ( geometryIndex !== null ) {
17575 const array = geometryIndex.array;
17576 version = geometryIndex.version;
17577 for ( let i = 0, l = array.length; i < l; i += 3 ) {
17578 const a = array[ i + 0 ];
17579 const b = array[ i + 1 ];
17580 const c = array[ i + 2 ];
17581 indices.push( a, b, b, c, c, a );
17582 }
17583 } else {
17584 const array = geometryPosition.array;
17585 version = geometryPosition.version;
17586 for ( let i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {
17587 const a = i + 0;
17588 const b = i + 1;
17589 const c = i + 2;
17590 indices.push( a, b, b, c, c, a );
17591 }
17592 }
17593 const attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );
17594 attribute.version = version;
17595 const previousAttribute = wireframeAttributes.get( geometry );
17596 if ( previousAttribute ) attributes.remove( previousAttribute );
17597 wireframeAttributes.set( geometry, attribute );
17598 }
17599 function getWireframeAttribute( geometry ) {
17600 const currentAttribute = wireframeAttributes.get( geometry );
17601 if ( currentAttribute ) {
17602 const geometryIndex = geometry.index;
17603 if ( geometryIndex !== null ) {
17604 if ( currentAttribute.version < geometryIndex.version ) {
17605 updateWireframeAttribute( geometry );
17606 }
17607 }
17608 } else {
17609 updateWireframeAttribute( geometry );
17610 }
17611 return wireframeAttributes.get( geometry );
17612 }
17613 return {
17614 get: get,
17615 update: update,
17616 getWireframeAttribute: getWireframeAttribute
17617 };
17618 }
17619 function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) {
17620 const isWebGL2 = capabilities.isWebGL2;
17621 let mode;
17622 function setMode( value ) {
17623 mode = value;
17624 }
17625 let type, bytesPerElement;
17626 function setIndex( value ) {
17627 type = value.type;
17628 bytesPerElement = value.bytesPerElement;
17629 }
17630 function render( start, count ) {
17631 gl.drawElements( mode, count, type, start * bytesPerElement );
17632 info.update( count, mode, 1 );
17633 }
17634 function renderInstances( start, count, primcount ) {
17635 if ( primcount === 0 ) return;
17636 let extension, methodName;
17637 if ( isWebGL2 ) {
17638 extension = gl;
17639 methodName = 'drawElementsInstanced';
17640 } else {
17641 extension = extensions.get( 'ANGLE_instanced_arrays' );
17642 methodName = 'drawElementsInstancedANGLE';
17643 if ( extension === null ) {
17644 console.error( 'THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
17645 return;
17646 }
17647 }
17648 extension[ methodName ]( mode, count, type, start * bytesPerElement, primcount );
17649 info.update( count, mode, primcount );
17650 }
17651 this.setMode = setMode;
17652 this.setIndex = setIndex;
17653 this.render = render;
17654 this.renderInstances = renderInstances;
17655 }
17656 function WebGLInfo( gl ) {
17657 const memory = {
17658 geometries: 0,
17659 textures: 0
17660 };
17661 const render = {
17662 frame: 0,
17663 calls: 0,
17664 triangles: 0,
17665 points: 0,
17666 lines: 0
17667 };
17668 function update( count, mode, instanceCount ) {
17669 render.calls ++;
17670 switch ( mode ) {
17671 case 4:
17672 render.triangles += instanceCount * ( count / 3 );
17673 break;
17674 case 1:
17675 render.lines += instanceCount * ( count / 2 );
17676 break;
17677 case 3:
17678 render.lines += instanceCount * ( count - 1 );
17679 break;
17680 case 2:
17681 render.lines += instanceCount * count;
17682 break;
17683 case 0:
17684 render.points += instanceCount * count;
17685 break;
17686 default:
17687 console.error( 'THREE.WebGLInfo: Unknown draw mode:', mode );
17688 break;
17689 }
17690 }
17691 function reset() {
17692 render.frame ++;
17693 render.calls = 0;
17694 render.triangles = 0;
17695 render.points = 0;
17696 render.lines = 0;
17697 }
17698 return {
17699 memory: memory,
17700 render: render,
17701 programs: null,
17702 autoReset: true,
17703 reset: reset,
17704 update: update
17705 };
17706 }
17707 function numericalSort( a, b ) {
17708 return a[ 0 ] - b[ 0 ];
17709 }
17710 function absNumericalSort( a, b ) {
17711 return Math.abs( b[ 1 ] ) - Math.abs( a[ 1 ] );
17712 }
17713 function WebGLMorphtargets( gl ) {
17714 const influencesList = {};
17715 const morphInfluences = new Float32Array( 8 );
17716 const workInfluences = [];
17717 for ( let i = 0; i < 8; i ++ ) {
17718 workInfluences[ i ] = [ i, 0 ];
17719 }
17720 function update( object, geometry, material, program ) {
17721 const objectInfluences = object.morphTargetInfluences;
17722 const length = objectInfluences === undefined ? 0 : objectInfluences.length;
17723 let influences = influencesList[ geometry.id ];
17724 if ( influences === undefined ) {
17725 influences = [];
17726 for ( let i = 0; i < length; i ++ ) {
17727 influences[ i ] = [ i, 0 ];
17728 }
17729 influencesList[ geometry.id ] = influences;
17730 }
17731 for ( let i = 0; i < length; i ++ ) {
17732 const influence = influences[ i ];
17733 influence[ 0 ] = i;
17734 influence[ 1 ] = objectInfluences[ i ];
17735 }
17736 influences.sort( absNumericalSort );
17737 for ( let i = 0; i < 8; i ++ ) {
17738 if ( i < length && influences[ i ][ 1 ] ) {
17739 workInfluences[ i ][ 0 ] = influences[ i ][ 0 ];
17740 workInfluences[ i ][ 1 ] = influences[ i ][ 1 ];
17741 } else {
17742 workInfluences[ i ][ 0 ] = Number.MAX_SAFE_INTEGER;
17743 workInfluences[ i ][ 1 ] = 0;
17744 }
17745 }
17746 workInfluences.sort( numericalSort );
17747 const morphTargets = material.morphTargets && geometry.morphAttributes.position;
17748 const morphNormals = material.morphNormals && geometry.morphAttributes.normal;
17749 let morphInfluencesSum = 0;
17750 for ( let i = 0; i < 8; i ++ ) {
17751 const influence = workInfluences[ i ];
17752 const index = influence[ 0 ];
17753 const value = influence[ 1 ];
17754 if ( index !== Number.MAX_SAFE_INTEGER && value ) {
17755 if ( morphTargets && geometry.getAttribute( 'morphTarget' + i ) !== morphTargets[ index ] ) {
17756 geometry.setAttribute( 'morphTarget' + i, morphTargets[ index ] );
17757 }
17758 if ( morphNormals && geometry.getAttribute( 'morphNormal' + i ) !== morphNormals[ index ] ) {
17759 geometry.setAttribute( 'morphNormal' + i, morphNormals[ index ] );
17760 }
17761 morphInfluences[ i ] = value;
17762 morphInfluencesSum += value;
17763 } else {
17764 if ( morphTargets && geometry.getAttribute( 'morphTarget' + i ) !== undefined ) {
17765 geometry.deleteAttribute( 'morphTarget' + i );
17766 }
17767 if ( morphNormals && geometry.getAttribute( 'morphNormal' + i ) !== undefined ) {
17768 geometry.deleteAttribute( 'morphNormal' + i );
17769 }
17770 morphInfluences[ i ] = 0;
17771 }
17772 }
17773 const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum;
17774 program.getUniforms().setValue( gl, 'morphTargetBaseInfluence', morphBaseInfluence );
17775 program.getUniforms().setValue( gl, 'morphTargetInfluences', morphInfluences );
17776 }
17777 return {
17778 update: update
17779 };
17780 }
17781 function WebGLObjects( gl, geometries, attributes, info ) {
17782 let updateMap = new WeakMap();
17783 function update( object ) {
17784 const frame = info.render.frame;
17785 const geometry = object.geometry;
17786 const buffergeometry = geometries.get( object, geometry );
17787 if ( updateMap.get( buffergeometry ) !== frame ) {
17788 if ( geometry.isGeometry ) {
17789 buffergeometry.updateFromObject( object );
17790 }
17791 geometries.update( buffergeometry );
17792 updateMap.set( buffergeometry, frame );
17793 }
17794 if ( object.isInstancedMesh ) {
17795 attributes.update( object.instanceMatrix, 34962 );
17796 if ( object.instanceColor !== null ) {
17797 attributes.update( object.instanceColor, 34962 );
17798 }
17799 }
17800 return buffergeometry;
17801 }
17802 function dispose() {
17803 updateMap = new WeakMap();
17804 }
17805 return {
17806 update: update,
17807 dispose: dispose
17808 };
17809 }
17810 function CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {
17811 images = images !== undefined ? images : [];
17812 mapping = mapping !== undefined ? mapping : CubeReflectionMapping;
17813 format = format !== undefined ? format : RGBFormat;
17814 Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
17815 this.flipY = false;
17816 }
17817 CubeTexture.prototype = Object.create( Texture.prototype );
17818 CubeTexture.prototype.constructor = CubeTexture;
17819 CubeTexture.prototype.isCubeTexture = true;
17820 Object.defineProperty( CubeTexture.prototype, 'images', {
17821 get: function () {
17822 return this.image;
17823 },
17824 set: function ( value ) {
17825 this.image = value;
17826 }
17827 } );
17828 function DataTexture2DArray( data, width, height, depth ) {
17829 Texture.call( this, null );
17830 this.image = { data: data || null, width: width || 1, height: height || 1, depth: depth || 1 };
17831 this.magFilter = NearestFilter;
17832 this.minFilter = NearestFilter;
17833 this.wrapR = ClampToEdgeWrapping;
17834 this.generateMipmaps = false;
17835 this.flipY = false;
17836 this.needsUpdate = true;
17837 }
17838 DataTexture2DArray.prototype = Object.create( Texture.prototype );
17839 DataTexture2DArray.prototype.constructor = DataTexture2DArray;
17840 DataTexture2DArray.prototype.isDataTexture2DArray = true;
17841 function DataTexture3D( data, width, height, depth ) {
17842 Texture.call( this, null );
17843 this.image = { data: data || null, width: width || 1, height: height || 1, depth: depth || 1 };
17844 this.magFilter = NearestFilter;
17845 this.minFilter = NearestFilter;
17846 this.wrapR = ClampToEdgeWrapping;
17847 this.generateMipmaps = false;
17848 this.flipY = false;
17849 this.needsUpdate = true;
17850 }
17851 DataTexture3D.prototype = Object.create( Texture.prototype );
17852 DataTexture3D.prototype.constructor = DataTexture3D;
17853 DataTexture3D.prototype.isDataTexture3D = true;
17854 const emptyTexture = new Texture();
17855 const emptyTexture2dArray = new DataTexture2DArray();
17856 const emptyTexture3d = new DataTexture3D();
17857 const emptyCubeTexture = new CubeTexture();
17858 const arrayCacheF32 = [];
17859 const arrayCacheI32 = [];
17860 const mat4array = new Float32Array( 16 );
17861 const mat3array = new Float32Array( 9 );
17862 const mat2array = new Float32Array( 4 );
17863 function flatten$1( array, nBlocks, blockSize ) {
17864 const firstElem = array[ 0 ];
17865 if ( firstElem <= 0 || firstElem > 0 ) return array;
17866 const n = nBlocks * blockSize;
17867 let r = arrayCacheF32[ n ];
17868 if ( r === undefined ) {
17869 r = new Float32Array( n );
17870 arrayCacheF32[ n ] = r;
17871 }
17872 if ( nBlocks !== 0 ) {
17873 firstElem.toArray( r, 0 );
17874 for ( let i = 1, offset = 0; i !== nBlocks; ++ i ) {
17875 offset += blockSize;
17876 array[ i ].toArray( r, offset );
17877 }
17878 }
17879 return r;
17880 }
17881 function arraysEqual( a, b ) {
17882 if ( a.length !== b.length ) return false;
17883 for ( let i = 0, l = a.length; i < l; i ++ ) {
17884 if ( a[ i ] !== b[ i ] ) return false;
17885 }
17886 return true;
17887 }
17888 function copyArray( a, b ) {
17889 for ( let i = 0, l = b.length; i < l; i ++ ) {
17890 a[ i ] = b[ i ];
17891 }
17892 }
17893 function allocTexUnits( textures, n ) {
17894 let r = arrayCacheI32[ n ];
17895 if ( r === undefined ) {
17896 r = new Int32Array( n );
17897 arrayCacheI32[ n ] = r;
17898 }
17899 for ( let i = 0; i !== n; ++ i ) {
17900 r[ i ] = textures.allocateTextureUnit();
17901 }
17902 return r;
17903 }
17904 function setValueV1f( gl, v ) {
17905 const cache = this.cache;
17906 if ( cache[ 0 ] === v ) return;
17907 gl.uniform1f( this.addr, v );
17908 cache[ 0 ] = v;
17909 }
17910 function setValueV2f( gl, v ) {
17911 const cache = this.cache;
17912 if ( v.x !== undefined ) {
17913 if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) {
17914 gl.uniform2f( this.addr, v.x, v.y );
17915 cache[ 0 ] = v.x;
17916 cache[ 1 ] = v.y;
17917 }
17918 } else {
17919 if ( arraysEqual( cache, v ) ) return;
17920 gl.uniform2fv( this.addr, v );
17921 copyArray( cache, v );
17922 }
17923 }
17924 function setValueV3f( gl, v ) {
17925 const cache = this.cache;
17926 if ( v.x !== undefined ) {
17927 if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) {
17928 gl.uniform3f( this.addr, v.x, v.y, v.z );
17929 cache[ 0 ] = v.x;
17930 cache[ 1 ] = v.y;
17931 cache[ 2 ] = v.z;
17932 }
17933 } else if ( v.r !== undefined ) {
17934 if ( cache[ 0 ] !== v.r || cache[ 1 ] !== v.g || cache[ 2 ] !== v.b ) {
17935 gl.uniform3f( this.addr, v.r, v.g, v.b );
17936 cache[ 0 ] = v.r;
17937 cache[ 1 ] = v.g;
17938 cache[ 2 ] = v.b;
17939 }
17940 } else {
17941 if ( arraysEqual( cache, v ) ) return;
17942 gl.uniform3fv( this.addr, v );
17943 copyArray( cache, v );
17944 }
17945 }
17946 function setValueV4f( gl, v ) {
17947 const cache = this.cache;
17948 if ( v.x !== undefined ) {
17949 if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) {
17950 gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );
17951 cache[ 0 ] = v.x;
17952 cache[ 1 ] = v.y;
17953 cache[ 2 ] = v.z;
17954 cache[ 3 ] = v.w;
17955 }
17956 } else {
17957 if ( arraysEqual( cache, v ) ) return;
17958 gl.uniform4fv( this.addr, v );
17959 copyArray( cache, v );
17960 }
17961 }
17962 function setValueM2( gl, v ) {
17963 const cache = this.cache;
17964 const elements = v.elements;
17965 if ( elements === undefined ) {
17966 if ( arraysEqual( cache, v ) ) return;
17967 gl.uniformMatrix2fv( this.addr, false, v );
17968 copyArray( cache, v );
17969 } else {
17970 if ( arraysEqual( cache, elements ) ) return;
17971 mat2array.set( elements );
17972 gl.uniformMatrix2fv( this.addr, false, mat2array );
17973 copyArray( cache, elements );
17974 }
17975 }
17976 function setValueM3( gl, v ) {
17977 const cache = this.cache;
17978 const elements = v.elements;
17979 if ( elements === undefined ) {
17980 if ( arraysEqual( cache, v ) ) return;
17981 gl.uniformMatrix3fv( this.addr, false, v );
17982 copyArray( cache, v );
17983 } else {
17984 if ( arraysEqual( cache, elements ) ) return;
17985 mat3array.set( elements );
17986 gl.uniformMatrix3fv( this.addr, false, mat3array );
17987 copyArray( cache, elements );
17988 }
17989 }
17990 function setValueM4( gl, v ) {
17991 const cache = this.cache;
17992 const elements = v.elements;
17993 if ( elements === undefined ) {
17994 if ( arraysEqual( cache, v ) ) return;
17995 gl.uniformMatrix4fv( this.addr, false, v );
17996 copyArray( cache, v );
17997 } else {
17998 if ( arraysEqual( cache, elements ) ) return;
17999 mat4array.set( elements );
18000 gl.uniformMatrix4fv( this.addr, false, mat4array );
18001 copyArray( cache, elements );
18002 }
18003 }
18004 function setValueT1( gl, v, textures ) {
18005 const cache = this.cache;
18006 const unit = textures.allocateTextureUnit();
18007 if ( cache[ 0 ] !== unit ) {
18008 gl.uniform1i( this.addr, unit );
18009 cache[ 0 ] = unit;
18010 }
18011 textures.safeSetTexture2D( v || emptyTexture, unit );
18012 }
18013 function setValueT2DArray1( gl, v, textures ) {
18014 const cache = this.cache;
18015 const unit = textures.allocateTextureUnit();
18016 if ( cache[ 0 ] !== unit ) {
18017 gl.uniform1i( this.addr, unit );
18018 cache[ 0 ] = unit;
18019 }
18020 textures.setTexture2DArray( v || emptyTexture2dArray, unit );
18021 }
18022 function setValueT3D1( gl, v, textures ) {
18023 const cache = this.cache;
18024 const unit = textures.allocateTextureUnit();
18025 if ( cache[ 0 ] !== unit ) {
18026 gl.uniform1i( this.addr, unit );
18027 cache[ 0 ] = unit;
18028 }
18029 textures.setTexture3D( v || emptyTexture3d, unit );
18030 }
18031 function setValueT6( gl, v, textures ) {
18032 const cache = this.cache;
18033 const unit = textures.allocateTextureUnit();
18034 if ( cache[ 0 ] !== unit ) {
18035 gl.uniform1i( this.addr, unit );
18036 cache[ 0 ] = unit;
18037 }
18038 textures.safeSetTextureCube( v || emptyCubeTexture, unit );
18039 }
18040 function setValueV1i( gl, v ) {
18041 const cache = this.cache;
18042 if ( cache[ 0 ] === v ) return;
18043 gl.uniform1i( this.addr, v );
18044 cache[ 0 ] = v;
18045 }
18046 function setValueV2i( gl, v ) {
18047 const cache = this.cache;
18048 if ( arraysEqual( cache, v ) ) return;
18049 gl.uniform2iv( this.addr, v );
18050 copyArray( cache, v );
18051 }
18052 function setValueV3i( gl, v ) {
18053 const cache = this.cache;
18054 if ( arraysEqual( cache, v ) ) return;
18055 gl.uniform3iv( this.addr, v );
18056 copyArray( cache, v );
18057 }
18058 function setValueV4i( gl, v ) {
18059 const cache = this.cache;
18060 if ( arraysEqual( cache, v ) ) return;
18061 gl.uniform4iv( this.addr, v );
18062 copyArray( cache, v );
18063 }
18064 function setValueV1ui( gl, v ) {
18065 const cache = this.cache;
18066 if ( cache[ 0 ] === v ) return;
18067 gl.uniform1ui( this.addr, v );
18068 cache[ 0 ] = v;
18069 }
18070 function getSingularSetter( type ) {
18071 switch ( type ) {
18072 case 0x1406: return setValueV1f;
18073 case 0x8b50: return setValueV2f;
18074 case 0x8b51: return setValueV3f;
18075 case 0x8b52: return setValueV4f;
18076 case 0x8b5a: return setValueM2;
18077 case 0x8b5b: return setValueM3;
18078 case 0x8b5c: return setValueM4;
18079 case 0x1404: case 0x8b56: return setValueV1i;
18080 case 0x8b53: case 0x8b57: return setValueV2i;
18081 case 0x8b54: case 0x8b58: return setValueV3i;
18082 case 0x8b55: case 0x8b59: return setValueV4i;
18083 case 0x1405: return setValueV1ui;
18084 case 0x8b5e:
18085 case 0x8d66:
18086 case 0x8dca:
18087 case 0x8dd2:
18088 case 0x8b62:
18089 return setValueT1;
18090 case 0x8b5f:
18091 case 0x8dcb:
18092 case 0x8dd3:
18093 return setValueT3D1;
18094 case 0x8b60:
18095 case 0x8dcc:
18096 case 0x8dd4:
18097 case 0x8dc5:
18098 return setValueT6;
18099 case 0x8dc1:
18100 case 0x8dcf:
18101 case 0x8dd7:
18102 case 0x8dc4:
18103 return setValueT2DArray1;
18104 }
18105 }
18106 function setValueV1fArray( gl, v ) {
18107 gl.uniform1fv( this.addr, v );
18108 }
18109 function setValueV1iArray( gl, v ) {
18110 gl.uniform1iv( this.addr, v );
18111 }
18112 function setValueV2iArray( gl, v ) {
18113 gl.uniform2iv( this.addr, v );
18114 }
18115 function setValueV3iArray( gl, v ) {
18116 gl.uniform3iv( this.addr, v );
18117 }
18118 function setValueV4iArray( gl, v ) {
18119 gl.uniform4iv( this.addr, v );
18120 }
18121 function setValueV2fArray( gl, v ) {
18122 const data = flatten$1( v, this.size, 2 );
18123 gl.uniform2fv( this.addr, data );
18124 }
18125 function setValueV3fArray( gl, v ) {
18126 const data = flatten$1( v, this.size, 3 );
18127 gl.uniform3fv( this.addr, data );
18128 }
18129 function setValueV4fArray( gl, v ) {
18130 const data = flatten$1( v, this.size, 4 );
18131 gl.uniform4fv( this.addr, data );
18132 }
18133 function setValueM2Array( gl, v ) {
18134 const data = flatten$1( v, this.size, 4 );
18135 gl.uniformMatrix2fv( this.addr, false, data );
18136 }
18137 function setValueM3Array( gl, v ) {
18138 const data = flatten$1( v, this.size, 9 );
18139 gl.uniformMatrix3fv( this.addr, false, data );
18140 }
18141 function setValueM4Array( gl, v ) {
18142 const data = flatten$1( v, this.size, 16 );
18143 gl.uniformMatrix4fv( this.addr, false, data );
18144 }
18145 function setValueT1Array( gl, v, textures ) {
18146 const n = v.length;
18147 const units = allocTexUnits( textures, n );
18148 gl.uniform1iv( this.addr, units );
18149 for ( let i = 0; i !== n; ++ i ) {
18150 textures.safeSetTexture2D( v[ i ] || emptyTexture, units[ i ] );
18151 }
18152 }
18153 function setValueT6Array( gl, v, textures ) {
18154 const n = v.length;
18155 const units = allocTexUnits( textures, n );
18156 gl.uniform1iv( this.addr, units );
18157 for ( let i = 0; i !== n; ++ i ) {
18158 textures.safeSetTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );
18159 }
18160 }
18161 function getPureArraySetter( type ) {
18162 switch ( type ) {
18163 case 0x1406: return setValueV1fArray;
18164 case 0x8b50: return setValueV2fArray;
18165 case 0x8b51: return setValueV3fArray;
18166 case 0x8b52: return setValueV4fArray;
18167 case 0x8b5a: return setValueM2Array;
18168 case 0x8b5b: return setValueM3Array;
18169 case 0x8b5c: return setValueM4Array;
18170 case 0x1404: case 0x8b56: return setValueV1iArray;
18171 case 0x8b53: case 0x8b57: return setValueV2iArray;
18172 case 0x8b54: case 0x8b58: return setValueV3iArray;
18173 case 0x8b55: case 0x8b59: return setValueV4iArray;
18174 case 0x8b5e:
18175 case 0x8d66:
18176 case 0x8dca:
18177 case 0x8dd2:
18178 case 0x8b62:
18179 return setValueT1Array;
18180 case 0x8b60:
18181 case 0x8dcc:
18182 case 0x8dd4:
18183 case 0x8dc5:
18184 return setValueT6Array;
18185 }
18186 }
18187 function SingleUniform( id, activeInfo, addr ) {
18188 this.id = id;
18189 this.addr = addr;
18190 this.cache = [];
18191 this.setValue = getSingularSetter( activeInfo.type );
18192 }
18193 function PureArrayUniform( id, activeInfo, addr ) {
18194 this.id = id;
18195 this.addr = addr;
18196 this.cache = [];
18197 this.size = activeInfo.size;
18198 this.setValue = getPureArraySetter( activeInfo.type );
18199 }
18200 PureArrayUniform.prototype.updateCache = function ( data ) {
18201 const cache = this.cache;
18202 if ( data instanceof Float32Array && cache.length !== data.length ) {
18203 this.cache = new Float32Array( data.length );
18204 }
18205 copyArray( cache, data );
18206 };
18207 function StructuredUniform( id ) {
18208 this.id = id;
18209 this.seq = [];
18210 this.map = {};
18211 }
18212 StructuredUniform.prototype.setValue = function ( gl, value, textures ) {
18213 const seq = this.seq;
18214 for ( let i = 0, n = seq.length; i !== n; ++ i ) {
18215 const u = seq[ i ];
18216 u.setValue( gl, value[ u.id ], textures );
18217 }
18218 };
18219 const RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g;
18220 function addUniform( container, uniformObject ) {
18221 container.seq.push( uniformObject );
18222 container.map[ uniformObject.id ] = uniformObject;
18223 }
18224 function parseUniform( activeInfo, addr, container ) {
18225 const path = activeInfo.name,
18226 pathLength = path.length;
18227 RePathPart.lastIndex = 0;
18228 while ( true ) {
18229 const match = RePathPart.exec( path ),
18230 matchEnd = RePathPart.lastIndex;
18231 let id = match[ 1 ];
18232 const idIsIndex = match[ 2 ] === ']',
18233 subscript = match[ 3 ];
18234 if ( idIsIndex ) id = id | 0;
18235 if ( subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength ) {
18236 addUniform( container, subscript === undefined ?
18237 new SingleUniform( id, activeInfo, addr ) :
18238 new PureArrayUniform( id, activeInfo, addr ) );
18239 break;
18240 } else {
18241 const map = container.map;
18242 let next = map[ id ];
18243 if ( next === undefined ) {
18244 next = new StructuredUniform( id );
18245 addUniform( container, next );
18246 }
18247 container = next;
18248 }
18249 }
18250 }
18251 function WebGLUniforms( gl, program ) {
18252 this.seq = [];
18253 this.map = {};
18254 const n = gl.getProgramParameter( program, 35718 );
18255 for ( let i = 0; i < n; ++ i ) {
18256 const info = gl.getActiveUniform( program, i ),
18257 addr = gl.getUniformLocation( program, info.name );
18258 parseUniform( info, addr, this );
18259 }
18260 }
18261 WebGLUniforms.prototype.setValue = function ( gl, name, value, textures ) {
18262 const u = this.map[ name ];
18263 if ( u !== undefined ) u.setValue( gl, value, textures );
18264 };
18265 WebGLUniforms.prototype.setOptional = function ( gl, object, name ) {
18266 const v = object[ name ];
18267 if ( v !== undefined ) this.setValue( gl, name, v );
18268 };
18269 WebGLUniforms.upload = function ( gl, seq, values, textures ) {
18270 for ( let i = 0, n = seq.length; i !== n; ++ i ) {
18271 const u = seq[ i ],
18272 v = values[ u.id ];
18273 if ( v.needsUpdate !== false ) {
18274 u.setValue( gl, v.value, textures );
18275 }
18276 }
18277 };
18278 WebGLUniforms.seqWithValue = function ( seq, values ) {
18279 const r = [];
18280 for ( let i = 0, n = seq.length; i !== n; ++ i ) {
18281 const u = seq[ i ];
18282 if ( u.id in values ) r.push( u );
18283 }
18284 return r;
18285 };
18286 function WebGLShader( gl, type, string ) {
18287 const shader = gl.createShader( type );
18288 gl.shaderSource( shader, string );
18289 gl.compileShader( shader );
18290 return shader;
18291 }
18292 let programIdCount = 0;
18293 function addLineNumbers( string ) {
18294 const lines = string.split( '\n' );
18295 for ( let i = 0; i < lines.length; i ++ ) {
18296 lines[ i ] = ( i + 1 ) + ': ' + lines[ i ];
18297 }
18298 return lines.join( '\n' );
18299 }
18300 function getEncodingComponents( encoding ) {
18301 switch ( encoding ) {
18302 case LinearEncoding:
18303 return [ 'Linear', '( value )' ];
18304 case sRGBEncoding:
18305 return [ 'sRGB', '( value )' ];
18306 case RGBEEncoding:
18307 return [ 'RGBE', '( value )' ];
18308 case RGBM7Encoding:
18309 return [ 'RGBM', '( value, 7.0 )' ];
18310 case RGBM16Encoding:
18311 return [ 'RGBM', '( value, 16.0 )' ];
18312 case RGBDEncoding:
18313 return [ 'RGBD', '( value, 256.0 )' ];
18314 case GammaEncoding:
18315 return [ 'Gamma', '( value, float( GAMMA_FACTOR ) )' ];
18316 case LogLuvEncoding:
18317 return [ 'LogLuv', '( value )' ];
18318 default:
18319 console.warn( 'THREE.WebGLProgram: Unsupported encoding:', encoding );
18320 return [ 'Linear', '( value )' ];
18321 }
18322 }
18323 function getShaderErrors( gl, shader, type ) {
18324 const status = gl.getShaderParameter( shader, 35713 );
18325 const log = gl.getShaderInfoLog( shader ).trim();
18326 if ( status && log === '' ) return '';
18327 const source = gl.getShaderSource( shader );
18328 return 'THREE.WebGLShader: gl.getShaderInfoLog() ' + type + '\n' + log + addLineNumbers( source );
18329 }
18330 function getTexelDecodingFunction( functionName, encoding ) {
18331 const components = getEncodingComponents( encoding );
18332 return 'vec4 ' + functionName + '( vec4 value ) { return ' + components[ 0 ] + 'ToLinear' + components[ 1 ] + '; }';
18333 }
18334 function getTexelEncodingFunction( functionName, encoding ) {
18335 const components = getEncodingComponents( encoding );
18336 return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[ 0 ] + components[ 1 ] + '; }';
18337 }
18338 function getToneMappingFunction( functionName, toneMapping ) {
18339 let toneMappingName;
18340 switch ( toneMapping ) {
18341 case LinearToneMapping:
18342 toneMappingName = 'Linear';
18343 break;
18344 case ReinhardToneMapping:
18345 toneMappingName = 'Reinhard';
18346 break;
18347 case CineonToneMapping:
18348 toneMappingName = 'OptimizedCineon';
18349 break;
18350 case ACESFilmicToneMapping:
18351 toneMappingName = 'ACESFilmic';
18352 break;
18353 case CustomToneMapping:
18354 toneMappingName = 'Custom';
18355 break;
18356 default:
18357 console.warn( 'THREE.WebGLProgram: Unsupported toneMapping:', toneMapping );
18358 toneMappingName = 'Linear';
18359 }
18360 return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }';
18361 }
18362 function generateExtensions( parameters ) {
18363 const chunks = [
18364 ( parameters.extensionDerivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.tangentSpaceNormalMap || parameters.clearcoatNormalMap || parameters.flatShading || parameters.shaderID === 'physical' ) ? '#extension GL_OES_standard_derivatives : enable' : '',
18365 ( parameters.extensionFragDepth || parameters.logarithmicDepthBuffer ) && parameters.rendererExtensionFragDepth ? '#extension GL_EXT_frag_depth : enable' : '',
18366 ( parameters.extensionDrawBuffers && parameters.rendererExtensionDrawBuffers ) ? '#extension GL_EXT_draw_buffers : require' : '',
18367 ( parameters.extensionShaderTextureLOD || parameters.envMap ) && parameters.rendererExtensionShaderTextureLod ? '#extension GL_EXT_shader_texture_lod : enable' : ''
18368 ];
18369 return chunks.filter( filterEmptyLine ).join( '\n' );
18370 }
18371 function generateDefines( defines ) {
18372 const chunks = [];
18373 for ( const name in defines ) {
18374 const value = defines[ name ];
18375 if ( value === false ) continue;
18376 chunks.push( '#define ' + name + ' ' + value );
18377 }
18378 return chunks.join( '\n' );
18379 }
18380 function fetchAttributeLocations( gl, program ) {
18381 const attributes = {};
18382 const n = gl.getProgramParameter( program, 35721 );
18383 for ( let i = 0; i < n; i ++ ) {
18384 const info = gl.getActiveAttrib( program, i );
18385 const name = info.name;
18386 attributes[ name ] = gl.getAttribLocation( program, name );
18387 }
18388 return attributes;
18389 }
18390 function filterEmptyLine( string ) {
18391 return string !== '';
18392 }
18393 function replaceLightNums( string, parameters ) {
18394 return string
18395 .replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )
18396 .replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )
18397 .replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )
18398 .replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )
18399 .replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights )
18400 .replace( /NUM_DIR_LIGHT_SHADOWS/g, parameters.numDirLightShadows )
18401 .replace( /NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows )
18402 .replace( /NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows );
18403 }
18404 function replaceClippingPlaneNums( string, parameters ) {
18405 return string
18406 .replace( /NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes )
18407 .replace( /UNION_CLIPPING_PLANES/g, ( parameters.numClippingPlanes - parameters.numClipIntersection ) );
18408 }
18409 const includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm;
18410 function resolveIncludes( string ) {
18411 return string.replace( includePattern, includeReplacer );
18412 }
18413 function includeReplacer( match, include ) {
18414 const string = ShaderChunk[ include ];
18415 if ( string === undefined ) {
18416 throw new Error( 'Can not resolve #include <' + include + '>' );
18417 }
18418 return resolveIncludes( string );
18419 }
18420 const deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g;
18421 const unrollLoopPattern = /#pragma unroll_loop_start\s+for\s*\(\s*int\s+i\s*=\s*(\d+)\s*;\s*i\s*<\s*(\d+)\s*;\s*i\s*\+\+\s*\)\s*{([\s\S]+?)}\s+#pragma unroll_loop_end/g;
18422 function unrollLoops( string ) {
18423 return string
18424 .replace( unrollLoopPattern, loopReplacer )
18425 .replace( deprecatedUnrollLoopPattern, deprecatedLoopReplacer );
18426 }
18427 function deprecatedLoopReplacer( match, start, end, snippet ) {
18428 console.warn( 'WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead.' );
18429 return loopReplacer( match, start, end, snippet );
18430 }
18431 function loopReplacer( match, start, end, snippet ) {
18432 let string = '';
18433 for ( let i = parseInt( start ); i < parseInt( end ); i ++ ) {
18434 string += snippet
18435 .replace( /\[\s*i\s*\]/g, '[ ' + i + ' ]' )
18436 .replace( /UNROLLED_LOOP_INDEX/g, i );
18437 }
18438 return string;
18439 }
18440 function generatePrecision( parameters ) {
18441 let precisionstring = "precision " + parameters.precision + " float;\nprecision " + parameters.precision + " int;";
18442 if ( parameters.precision === "highp" ) {
18443 precisionstring += "\n#define HIGH_PRECISION";
18444 } else if ( parameters.precision === "mediump" ) {
18445 precisionstring += "\n#define MEDIUM_PRECISION";
18446 } else if ( parameters.precision === "lowp" ) {
18447 precisionstring += "\n#define LOW_PRECISION";
18448 }
18449 return precisionstring;
18450 }
18451 function generateShadowMapTypeDefine( parameters ) {
18452 let shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
18453 if ( parameters.shadowMapType === PCFShadowMap ) {
18454 shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
18455 } else if ( parameters.shadowMapType === PCFSoftShadowMap ) {
18456 shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
18457 } else if ( parameters.shadowMapType === VSMShadowMap ) {
18458 shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM';
18459 }
18460 return shadowMapTypeDefine;
18461 }
18462 function generateEnvMapTypeDefine( parameters ) {
18463 let envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
18464 if ( parameters.envMap ) {
18465 switch ( parameters.envMapMode ) {
18466 case CubeReflectionMapping:
18467 case CubeRefractionMapping:
18468 envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
18469 break;
18470 case CubeUVReflectionMapping:
18471 case CubeUVRefractionMapping:
18472 envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
18473 break;
18474 }
18475 }
18476 return envMapTypeDefine;
18477 }
18478 function generateEnvMapModeDefine( parameters ) {
18479 let envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
18480 if ( parameters.envMap ) {
18481 switch ( parameters.envMapMode ) {
18482 case CubeRefractionMapping:
18483 case CubeUVRefractionMapping:
18484 envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
18485 break;
18486 }
18487 }
18488 return envMapModeDefine;
18489 }
18490 function generateEnvMapBlendingDefine( parameters ) {
18491 let envMapBlendingDefine = 'ENVMAP_BLENDING_NONE';
18492 if ( parameters.envMap ) {
18493 switch ( parameters.combine ) {
18494 case MultiplyOperation:
18495 envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
18496 break;
18497 case MixOperation:
18498 envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
18499 break;
18500 case AddOperation:
18501 envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
18502 break;
18503 }
18504 }
18505 return envMapBlendingDefine;
18506 }
18507 function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
18508 const gl = renderer.getContext();
18509 const defines = parameters.defines;
18510 let vertexShader = parameters.vertexShader;
18511 let fragmentShader = parameters.fragmentShader;
18512 const shadowMapTypeDefine = generateShadowMapTypeDefine( parameters );
18513 const envMapTypeDefine = generateEnvMapTypeDefine( parameters );
18514 const envMapModeDefine = generateEnvMapModeDefine( parameters );
18515 const envMapBlendingDefine = generateEnvMapBlendingDefine( parameters );
18516 const gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;
18517 const customExtensions = parameters.isWebGL2 ? '' : generateExtensions( parameters );
18518 const customDefines = generateDefines( defines );
18519 const program = gl.createProgram();
18520 let prefixVertex, prefixFragment;
18521 let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + "\n" : '';
18522 if ( parameters.isRawShaderMaterial ) {
18523 prefixVertex = [
18524 customDefines
18525 ].filter( filterEmptyLine ).join( '\n' );
18526 if ( prefixVertex.length > 0 ) {
18527 prefixVertex += '\n';
18528 }
18529 prefixFragment = [
18530 customExtensions,
18531 customDefines
18532 ].filter( filterEmptyLine ).join( '\n' );
18533 if ( prefixFragment.length > 0 ) {
18534 prefixFragment += '\n';
18535 }
18536 } else {
18537 prefixVertex = [
18538 generatePrecision( parameters ),
18539 '#define SHADER_NAME ' + parameters.shaderName,
18540 customDefines,
18541 parameters.instancing ? '#define USE_INSTANCING' : '',
18542 parameters.instancingColor ? '#define USE_INSTANCING_COLOR' : '',
18543 parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',
18544 '#define GAMMA_FACTOR ' + gammaFactorDefine,
18545 '#define MAX_BONES ' + parameters.maxBones,
18546 ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
18547 ( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '',
18548 parameters.map ? '#define USE_MAP' : '',
18549 parameters.envMap ? '#define USE_ENVMAP' : '',
18550 parameters.envMap ? '#define ' + envMapModeDefine : '',
18551 parameters.lightMap ? '#define USE_LIGHTMAP' : '',
18552 parameters.aoMap ? '#define USE_AOMAP' : '',
18553 parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
18554 parameters.bumpMap ? '#define USE_BUMPMAP' : '',
18555 parameters.normalMap ? '#define USE_NORMALMAP' : '',
18556 ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',
18557 ( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '',
18558 parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '',
18559 parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '',
18560 parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
18561 parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',
18562 parameters.specularMap ? '#define USE_SPECULARMAP' : '',
18563 parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
18564 parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
18565 parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
18566 parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',
18567 parameters.vertexTangents ? '#define USE_TANGENT' : '',
18568 parameters.vertexColors ? '#define USE_COLOR' : '',
18569 parameters.vertexUvs ? '#define USE_UV' : '',
18570 parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '',
18571 parameters.flatShading ? '#define FLAT_SHADED' : '',
18572 parameters.skinning ? '#define USE_SKINNING' : '',
18573 parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',
18574 parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
18575 parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',
18576 parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
18577 parameters.flipSided ? '#define FLIP_SIDED' : '',
18578 parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
18579 parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
18580 parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
18581 parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
18582 ( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
18583 'uniform mat4 modelMatrix;',
18584 'uniform mat4 modelViewMatrix;',
18585 'uniform mat4 projectionMatrix;',
18586 'uniform mat4 viewMatrix;',
18587 'uniform mat3 normalMatrix;',
18588 'uniform vec3 cameraPosition;',
18589 'uniform bool isOrthographic;',
18590 '#ifdef USE_INSTANCING',
18591 ' attribute mat4 instanceMatrix;',
18592 '#endif',
18593 '#ifdef USE_INSTANCING_COLOR',
18594 ' attribute vec3 instanceColor;',
18595 '#endif',
18596 'attribute vec3 position;',
18597 'attribute vec3 normal;',
18598 'attribute vec2 uv;',
18599 '#ifdef USE_TANGENT',
18600 ' attribute vec4 tangent;',
18601 '#endif',
18602 '#ifdef USE_COLOR',
18603 ' attribute vec3 color;',
18604 '#endif',
18605 '#ifdef USE_MORPHTARGETS',
18606 ' attribute vec3 morphTarget0;',
18607 ' attribute vec3 morphTarget1;',
18608 ' attribute vec3 morphTarget2;',
18609 ' attribute vec3 morphTarget3;',
18610 ' #ifdef USE_MORPHNORMALS',
18611 ' attribute vec3 morphNormal0;',
18612 ' attribute vec3 morphNormal1;',
18613 ' attribute vec3 morphNormal2;',
18614 ' attribute vec3 morphNormal3;',
18615 ' #else',
18616 ' attribute vec3 morphTarget4;',
18617 ' attribute vec3 morphTarget5;',
18618 ' attribute vec3 morphTarget6;',
18619 ' attribute vec3 morphTarget7;',
18620 ' #endif',
18621 '#endif',
18622 '#ifdef USE_SKINNING',
18623 ' attribute vec4 skinIndex;',
18624 ' attribute vec4 skinWeight;',
18625 '#endif',
18626 '\n'
18627 ].filter( filterEmptyLine ).join( '\n' );
18628 prefixFragment = [
18629 customExtensions,
18630 generatePrecision( parameters ),
18631 '#define SHADER_NAME ' + parameters.shaderName,
18632 customDefines,
18633 parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest + ( parameters.alphaTest % 1 ? '' : '.0' ) : '',
18634 '#define GAMMA_FACTOR ' + gammaFactorDefine,
18635 ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
18636 ( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '',
18637 parameters.map ? '#define USE_MAP' : '',
18638 parameters.matcap ? '#define USE_MATCAP' : '',
18639 parameters.envMap ? '#define USE_ENVMAP' : '',
18640 parameters.envMap ? '#define ' + envMapTypeDefine : '',
18641 parameters.envMap ? '#define ' + envMapModeDefine : '',
18642 parameters.envMap ? '#define ' + envMapBlendingDefine : '',
18643 parameters.lightMap ? '#define USE_LIGHTMAP' : '',
18644 parameters.aoMap ? '#define USE_AOMAP' : '',
18645 parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
18646 parameters.bumpMap ? '#define USE_BUMPMAP' : '',
18647 parameters.normalMap ? '#define USE_NORMALMAP' : '',
18648 ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',
18649 ( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '',
18650 parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '',
18651 parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '',
18652 parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
18653 parameters.specularMap ? '#define USE_SPECULARMAP' : '',
18654 parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
18655 parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
18656 parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
18657 parameters.sheen ? '#define USE_SHEEN' : '',
18658 parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',
18659 parameters.vertexTangents ? '#define USE_TANGENT' : '',
18660 parameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '',
18661 parameters.vertexUvs ? '#define USE_UV' : '',
18662 parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '',
18663 parameters.gradientMap ? '#define USE_GRADIENTMAP' : '',
18664 parameters.flatShading ? '#define FLAT_SHADED' : '',
18665 parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
18666 parameters.flipSided ? '#define FLIP_SIDED' : '',
18667 parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
18668 parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
18669 parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '',
18670 parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '',
18671 parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
18672 ( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
18673 ( ( parameters.extensionShaderTextureLOD || parameters.envMap ) && parameters.rendererExtensionShaderTextureLod ) ? '#define TEXTURE_LOD_EXT' : '',
18674 'uniform mat4 viewMatrix;',
18675 'uniform vec3 cameraPosition;',
18676 'uniform bool isOrthographic;',
18677 ( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '',
18678 ( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '',
18679 ( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( 'toneMapping', parameters.toneMapping ) : '',
18680 parameters.dithering ? '#define DITHERING' : '',
18681 ShaderChunk[ 'encodings_pars_fragment' ],
18682 parameters.map ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',
18683 parameters.matcap ? getTexelDecodingFunction( 'matcapTexelToLinear', parameters.matcapEncoding ) : '',
18684 parameters.envMap ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',
18685 parameters.emissiveMap ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
18686 parameters.lightMap ? getTexelDecodingFunction( 'lightMapTexelToLinear', parameters.lightMapEncoding ) : '',
18687 getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ),
18688 parameters.depthPacking ? '#define DEPTH_PACKING ' + parameters.depthPacking : '',
18689 '\n'
18690 ].filter( filterEmptyLine ).join( '\n' );
18691 }
18692 vertexShader = resolveIncludes( vertexShader );
18693 vertexShader = replaceLightNums( vertexShader, parameters );
18694 vertexShader = replaceClippingPlaneNums( vertexShader, parameters );
18695 fragmentShader = resolveIncludes( fragmentShader );
18696 fragmentShader = replaceLightNums( fragmentShader, parameters );
18697 fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters );
18698 vertexShader = unrollLoops( vertexShader );
18699 fragmentShader = unrollLoops( fragmentShader );
18700 if ( parameters.isWebGL2 && parameters.isRawShaderMaterial !== true ) {
18701 versionString = '#version 300 es\n';
18702 prefixVertex = [
18703 '#define attribute in',
18704 '#define varying out',
18705 '#define texture2D texture'
18706 ].join( '\n' ) + '\n' + prefixVertex;
18707 prefixFragment = [
18708 '#define varying in',
18709 ( parameters.glslVersion === GLSL3 ) ? '' : 'out highp vec4 pc_fragColor;',
18710 ( parameters.glslVersion === GLSL3 ) ? '' : '#define gl_FragColor pc_fragColor',
18711 '#define gl_FragDepthEXT gl_FragDepth',
18712 '#define texture2D texture',
18713 '#define textureCube texture',
18714 '#define texture2DProj textureProj',
18715 '#define texture2DLodEXT textureLod',
18716 '#define texture2DProjLodEXT textureProjLod',
18717 '#define textureCubeLodEXT textureLod',
18718 '#define texture2DGradEXT textureGrad',
18719 '#define texture2DProjGradEXT textureProjGrad',
18720 '#define textureCubeGradEXT textureGrad'
18721 ].join( '\n' ) + '\n' + prefixFragment;
18722 }
18723 const vertexGlsl = versionString + prefixVertex + vertexShader;
18724 const fragmentGlsl = versionString + prefixFragment + fragmentShader;
18725 const glVertexShader = WebGLShader( gl, 35633, vertexGlsl );
18726 const glFragmentShader = WebGLShader( gl, 35632, fragmentGlsl );
18727 gl.attachShader( program, glVertexShader );
18728 gl.attachShader( program, glFragmentShader );
18729 if ( parameters.index0AttributeName !== undefined ) {
18730 gl.bindAttribLocation( program, 0, parameters.index0AttributeName );
18731 } else if ( parameters.morphTargets === true ) {
18732 gl.bindAttribLocation( program, 0, 'position' );
18733 }
18734 gl.linkProgram( program );
18735 if ( renderer.debug.checkShaderErrors ) {
18736 const programLog = gl.getProgramInfoLog( program ).trim();
18737 const vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();
18738 const fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();
18739 let runnable = true;
18740 let haveDiagnostics = true;
18741 if ( gl.getProgramParameter( program, 35714 ) === false ) {
18742 runnable = false;
18743 const vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' );
18744 const fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' );
18745 console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), '35715', gl.getProgramParameter( program, 35715 ), 'gl.getProgramInfoLog', programLog, vertexErrors, fragmentErrors );
18746 } else if ( programLog !== '' ) {
18747 console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
18748 } else if ( vertexLog === '' || fragmentLog === '' ) {
18749 haveDiagnostics = false;
18750 }
18751 if ( haveDiagnostics ) {
18752 this.diagnostics = {
18753 runnable: runnable,
18754 programLog: programLog,
18755 vertexShader: {
18756 log: vertexLog,
18757 prefix: prefixVertex
18758 },
18759 fragmentShader: {
18760 log: fragmentLog,
18761 prefix: prefixFragment
18762 }
18763 };
18764 }
18765 }
18766 gl.deleteShader( glVertexShader );
18767 gl.deleteShader( glFragmentShader );
18768 let cachedUniforms;
18769 this.getUniforms = function () {
18770 if ( cachedUniforms === undefined ) {
18771 cachedUniforms = new WebGLUniforms( gl, program );
18772 }
18773 return cachedUniforms;
18774 };
18775 let cachedAttributes;
18776 this.getAttributes = function () {
18777 if ( cachedAttributes === undefined ) {
18778 cachedAttributes = fetchAttributeLocations( gl, program );
18779 }
18780 return cachedAttributes;
18781 };
18782 this.destroy = function () {
18783 bindingStates.releaseStatesOfProgram( this );
18784 gl.deleteProgram( program );
18785 this.program = undefined;
18786 };
18787 this.name = parameters.shaderName;
18788 this.id = programIdCount ++;
18789 this.cacheKey = cacheKey;
18790 this.usedTimes = 1;
18791 this.program = program;
18792 this.vertexShader = glVertexShader;
18793 this.fragmentShader = glFragmentShader;
18794 return this;
18795 }
18796 function WebGLPrograms( renderer, cubemaps, extensions, capabilities, bindingStates, clipping ) {
18797 const programs = [];
18798 const isWebGL2 = capabilities.isWebGL2;
18799 const logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer;
18800 const floatVertexTextures = capabilities.floatVertexTextures;
18801 const maxVertexUniforms = capabilities.maxVertexUniforms;
18802 const vertexTextures = capabilities.vertexTextures;
18803 let precision = capabilities.precision;
18804 const shaderIDs = {
18805 MeshDepthMaterial: 'depth',
18806 MeshDistanceMaterial: 'distanceRGBA',
18807 MeshNormalMaterial: 'normal',
18808 MeshBasicMaterial: 'basic',
18809 MeshLambertMaterial: 'lambert',
18810 MeshPhongMaterial: 'phong',
18811 MeshToonMaterial: 'toon',
18812 MeshStandardMaterial: 'physical',
18813 MeshPhysicalMaterial: 'physical',
18814 MeshMatcapMaterial: 'matcap',
18815 LineBasicMaterial: 'basic',
18816 LineDashedMaterial: 'dashed',
18817 PointsMaterial: 'points',
18818 ShadowMaterial: 'shadow',
18819 SpriteMaterial: 'sprite'
18820 };
18821 const parameterNames = [
18822 "precision", "isWebGL2", "supportsVertexTextures", "outputEncoding", "instancing", "instancingColor",
18823 "map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding", "envMapCubeUV",
18824 "lightMap", "lightMapEncoding", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "tangentSpaceNormalMap", "clearcoatMap", "clearcoatRoughnessMap", "clearcoatNormalMap", "displacementMap", "specularMap",
18825 "roughnessMap", "metalnessMap", "gradientMap",
18826 "alphaMap", "combine", "vertexColors", "vertexTangents", "vertexUvs", "uvsVertexOnly", "fog", "useFog", "fogExp2",
18827 "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning",
18828 "maxBones", "useVertexTexture", "morphTargets", "morphNormals",
18829 "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha",
18830 "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights",
18831 "numDirLightShadows", "numPointLightShadows", "numSpotLightShadows",
18832 "shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights',
18833 "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering",
18834 "sheen", "transmissionMap"
18835 ];
18836 function getMaxBones( object ) {
18837 const skeleton = object.skeleton;
18838 const bones = skeleton.bones;
18839 if ( floatVertexTextures ) {
18840 return 1024;
18841 } else {
18842 const nVertexUniforms = maxVertexUniforms;
18843 const nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
18844 const maxBones = Math.min( nVertexMatrices, bones.length );
18845 if ( maxBones < bones.length ) {
18846 console.warn( 'THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.' );
18847 return 0;
18848 }
18849 return maxBones;
18850 }
18851 }
18852 function getTextureEncodingFromMap( map ) {
18853 let encoding;
18854 if ( ! map ) {
18855 encoding = LinearEncoding;
18856 } else if ( map.isTexture ) {
18857 encoding = map.encoding;
18858 } else if ( map.isWebGLRenderTarget ) {
18859 console.warn( "THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead." );
18860 encoding = map.texture.encoding;
18861 }
18862 return encoding;
18863 }
18864 function getParameters( material, lights, shadows, scene, object ) {
18865 const fog = scene.fog;
18866 const environment = material.isMeshStandardMaterial ? scene.environment : null;
18867 const envMap = cubemaps.get( material.envMap || environment );
18868 const shaderID = shaderIDs[ material.type ];
18869 const maxBones = object.isSkinnedMesh ? getMaxBones( object ) : 0;
18870 if ( material.precision !== null ) {
18871 precision = capabilities.getMaxPrecision( material.precision );
18872 if ( precision !== material.precision ) {
18873 console.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );
18874 }
18875 }
18876 let vertexShader, fragmentShader;
18877 if ( shaderID ) {
18878 const shader = ShaderLib[ shaderID ];
18879 vertexShader = shader.vertexShader;
18880 fragmentShader = shader.fragmentShader;
18881 } else {
18882 vertexShader = material.vertexShader;
18883 fragmentShader = material.fragmentShader;
18884 }
18885 const currentRenderTarget = renderer.getRenderTarget();
18886 const parameters = {
18887 isWebGL2: isWebGL2,
18888 shaderID: shaderID,
18889 shaderName: material.type,
18890 vertexShader: vertexShader,
18891 fragmentShader: fragmentShader,
18892 defines: material.defines,
18893 isRawShaderMaterial: material.isRawShaderMaterial === true,
18894 glslVersion: material.glslVersion,
18895 precision: precision,
18896 instancing: object.isInstancedMesh === true,
18897 instancingColor: object.isInstancedMesh === true && object.instanceColor !== null,
18898 supportsVertexTextures: vertexTextures,
18899 outputEncoding: ( currentRenderTarget !== null ) ? getTextureEncodingFromMap( currentRenderTarget.texture ) : renderer.outputEncoding,
18900 map: !! material.map,
18901 mapEncoding: getTextureEncodingFromMap( material.map ),
18902 matcap: !! material.matcap,
18903 matcapEncoding: getTextureEncodingFromMap( material.matcap ),
18904 envMap: !! envMap,
18905 envMapMode: envMap && envMap.mapping,
18906 envMapEncoding: getTextureEncodingFromMap( envMap ),
18907 envMapCubeUV: ( !! envMap ) && ( ( envMap.mapping === CubeUVReflectionMapping ) || ( envMap.mapping === CubeUVRefractionMapping ) ),
18908 lightMap: !! material.lightMap,
18909 lightMapEncoding: getTextureEncodingFromMap( material.lightMap ),
18910 aoMap: !! material.aoMap,
18911 emissiveMap: !! material.emissiveMap,
18912 emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap ),
18913 bumpMap: !! material.bumpMap,
18914 normalMap: !! material.normalMap,
18915 objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap,
18916 tangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap,
18917 clearcoatMap: !! material.clearcoatMap,
18918 clearcoatRoughnessMap: !! material.clearcoatRoughnessMap,
18919 clearcoatNormalMap: !! material.clearcoatNormalMap,
18920 displacementMap: !! material.displacementMap,
18921 roughnessMap: !! material.roughnessMap,
18922 metalnessMap: !! material.metalnessMap,
18923 specularMap: !! material.specularMap,
18924 alphaMap: !! material.alphaMap,
18925 gradientMap: !! material.gradientMap,
18926 sheen: !! material.sheen,
18927 transmissionMap: !! material.transmissionMap,
18928 combine: material.combine,
18929 vertexTangents: ( material.normalMap && material.vertexTangents ),
18930 vertexColors: material.vertexColors,
18931 vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatMap || !! material.clearcoatRoughnessMap || !! material.clearcoatNormalMap || !! material.displacementMap || !! material.transmissionMap,
18932 uvsVertexOnly: ! ( !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap || !! material.transmissionMap ) && !! material.displacementMap,
18933 fog: !! fog,
18934 useFog: material.fog,
18935 fogExp2: ( fog && fog.isFogExp2 ),
18936 flatShading: material.flatShading,
18937 sizeAttenuation: material.sizeAttenuation,
18938 logarithmicDepthBuffer: logarithmicDepthBuffer,
18939 skinning: material.skinning && maxBones > 0,
18940 maxBones: maxBones,
18941 useVertexTexture: floatVertexTextures,
18942 morphTargets: material.morphTargets,
18943 morphNormals: material.morphNormals,
18944 maxMorphTargets: renderer.maxMorphTargets,
18945 maxMorphNormals: renderer.maxMorphNormals,
18946 numDirLights: lights.directional.length,
18947 numPointLights: lights.point.length,
18948 numSpotLights: lights.spot.length,
18949 numRectAreaLights: lights.rectArea.length,
18950 numHemiLights: lights.hemi.length,
18951 numDirLightShadows: lights.directionalShadowMap.length,
18952 numPointLightShadows: lights.pointShadowMap.length,
18953 numSpotLightShadows: lights.spotShadowMap.length,
18954 numClippingPlanes: clipping.numPlanes,
18955 numClipIntersection: clipping.numIntersection,
18956 dithering: material.dithering,
18957 shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0,
18958 shadowMapType: renderer.shadowMap.type,
18959 toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping,
18960 physicallyCorrectLights: renderer.physicallyCorrectLights,
18961 premultipliedAlpha: material.premultipliedAlpha,
18962 alphaTest: material.alphaTest,
18963 doubleSided: material.side === DoubleSide,
18964 flipSided: material.side === BackSide,
18965 depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false,
18966 index0AttributeName: material.index0AttributeName,
18967 extensionDerivatives: material.extensions && material.extensions.derivatives,
18968 extensionFragDepth: material.extensions && material.extensions.fragDepth,
18969 extensionDrawBuffers: material.extensions && material.extensions.drawBuffers,
18970 extensionShaderTextureLOD: material.extensions && material.extensions.shaderTextureLOD,
18971 rendererExtensionFragDepth: isWebGL2 || extensions.has( 'EXT_frag_depth' ),
18972 rendererExtensionDrawBuffers: isWebGL2 || extensions.has( 'WEBGL_draw_buffers' ),
18973 rendererExtensionShaderTextureLod: isWebGL2 || extensions.has( 'EXT_shader_texture_lod' ),
18974 customProgramCacheKey: material.customProgramCacheKey()
18975 };
18976 return parameters;
18977 }
18978 function getProgramCacheKey( parameters ) {
18979 const array = [];
18980 if ( parameters.shaderID ) {
18981 array.push( parameters.shaderID );
18982 } else {
18983 array.push( parameters.fragmentShader );
18984 array.push( parameters.vertexShader );
18985 }
18986 if ( parameters.defines !== undefined ) {
18987 for ( const name in parameters.defines ) {
18988 array.push( name );
18989 array.push( parameters.defines[ name ] );
18990 }
18991 }
18992 if ( parameters.isRawShaderMaterial === false ) {
18993 for ( let i = 0; i < parameterNames.length; i ++ ) {
18994 array.push( parameters[ parameterNames[ i ] ] );
18995 }
18996 array.push( renderer.outputEncoding );
18997 array.push( renderer.gammaFactor );
18998 }
18999 array.push( parameters.customProgramCacheKey );
19000 return array.join();
19001 }
19002 function getUniforms( material ) {
19003 const shaderID = shaderIDs[ material.type ];
19004 let uniforms;
19005 if ( shaderID ) {
19006 const shader = ShaderLib[ shaderID ];
19007 uniforms = UniformsUtils.clone( shader.uniforms );
19008 } else {
19009 uniforms = material.uniforms;
19010 }
19011 return uniforms;
19012 }
19013 function acquireProgram( parameters, cacheKey ) {
19014 let program;
19015 for ( let p = 0, pl = programs.length; p < pl; p ++ ) {
19016 const preexistingProgram = programs[ p ];
19017 if ( preexistingProgram.cacheKey === cacheKey ) {
19018 program = preexistingProgram;
19019 ++ program.usedTimes;
19020 break;
19021 }
19022 }
19023 if ( program === undefined ) {
19024 program = new WebGLProgram( renderer, cacheKey, parameters, bindingStates );
19025 programs.push( program );
19026 }
19027 return program;
19028 }
19029 function releaseProgram( program ) {
19030 if ( -- program.usedTimes === 0 ) {
19031 const i = programs.indexOf( program );
19032 programs[ i ] = programs[ programs.length - 1 ];
19033 programs.pop();
19034 program.destroy();
19035 }
19036 }
19037 return {
19038 getParameters: getParameters,
19039 getProgramCacheKey: getProgramCacheKey,
19040 getUniforms: getUniforms,
19041 acquireProgram: acquireProgram,
19042 releaseProgram: releaseProgram,
19043 programs: programs
19044 };
19045 }
19046 function WebGLProperties() {
19047 let properties = new WeakMap();
19048 function get( object ) {
19049 let map = properties.get( object );
19050 if ( map === undefined ) {
19051 map = {};
19052 properties.set( object, map );
19053 }
19054 return map;
19055 }
19056 function remove( object ) {
19057 properties.delete( object );
19058 }
19059 function update( object, key, value ) {
19060 properties.get( object )[ key ] = value;
19061 }
19062 function dispose() {
19063 properties = new WeakMap();
19064 }
19065 return {
19066 get: get,
19067 remove: remove,
19068 update: update,
19069 dispose: dispose
19070 };
19071 }
19072 function painterSortStable( a, b ) {
19073 if ( a.groupOrder !== b.groupOrder ) {
19074 return a.groupOrder - b.groupOrder;
19075 } else if ( a.renderOrder !== b.renderOrder ) {
19076 return a.renderOrder - b.renderOrder;
19077 } else if ( a.program !== b.program ) {
19078 return a.program.id - b.program.id;
19079 } else if ( a.material.id !== b.material.id ) {
19080 return a.material.id - b.material.id;
19081 } else if ( a.z !== b.z ) {
19082 return a.z - b.z;
19083 } else {
19084 return a.id - b.id;
19085 }
19086 }
19087 function reversePainterSortStable( a, b ) {
19088 if ( a.groupOrder !== b.groupOrder ) {
19089 return a.groupOrder - b.groupOrder;
19090 } else if ( a.renderOrder !== b.renderOrder ) {
19091 return a.renderOrder - b.renderOrder;
19092 } else if ( a.z !== b.z ) {
19093 return b.z - a.z;
19094 } else {
19095 return a.id - b.id;
19096 }
19097 }
19098 function WebGLRenderList( properties ) {
19099 const renderItems = [];
19100 let renderItemsIndex = 0;
19101 const opaque = [];
19102 const transparent = [];
19103 const defaultProgram = { id: - 1 };
19104 function init() {
19105 renderItemsIndex = 0;
19106 opaque.length = 0;
19107 transparent.length = 0;
19108 }
19109 function getNextRenderItem( object, geometry, material, groupOrder, z, group ) {
19110 let renderItem = renderItems[ renderItemsIndex ];
19111 const materialProperties = properties.get( material );
19112 if ( renderItem === undefined ) {
19113 renderItem = {
19114 id: object.id,
19115 object: object,
19116 geometry: geometry,
19117 material: material,
19118 program: materialProperties.program || defaultProgram,
19119 groupOrder: groupOrder,
19120 renderOrder: object.renderOrder,
19121 z: z,
19122 group: group
19123 };
19124 renderItems[ renderItemsIndex ] = renderItem;
19125 } else {
19126 renderItem.id = object.id;
19127 renderItem.object = object;
19128 renderItem.geometry = geometry;
19129 renderItem.material = material;
19130 renderItem.program = materialProperties.program || defaultProgram;
19131 renderItem.groupOrder = groupOrder;
19132 renderItem.renderOrder = object.renderOrder;
19133 renderItem.z = z;
19134 renderItem.group = group;
19135 }
19136 renderItemsIndex ++;
19137 return renderItem;
19138 }
19139 function push( object, geometry, material, groupOrder, z, group ) {
19140 const renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group );
19141 ( material.transparent === true ? transparent : opaque ).push( renderItem );
19142 }
19143 function unshift( object, geometry, material, groupOrder, z, group ) {
19144 const renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group );
19145 ( material.transparent === true ? transparent : opaque ).unshift( renderItem );
19146 }
19147 function sort( customOpaqueSort, customTransparentSort ) {
19148 if ( opaque.length > 1 ) opaque.sort( customOpaqueSort || painterSortStable );
19149 if ( transparent.length > 1 ) transparent.sort( customTransparentSort || reversePainterSortStable );
19150 }
19151 function finish() {
19152 for ( let i = renderItemsIndex, il = renderItems.length; i < il; i ++ ) {
19153 const renderItem = renderItems[ i ];
19154 if ( renderItem.id === null ) break;
19155 renderItem.id = null;
19156 renderItem.object = null;
19157 renderItem.geometry = null;
19158 renderItem.material = null;
19159 renderItem.program = null;
19160 renderItem.group = null;
19161 }
19162 }
19163 return {
19164 opaque: opaque,
19165 transparent: transparent,
19166 init: init,
19167 push: push,
19168 unshift: unshift,
19169 finish: finish,
19170 sort: sort
19171 };
19172 }
19173 function WebGLRenderLists( properties ) {
19174 let lists = new WeakMap();
19175 function get( scene, camera ) {
19176 const cameras = lists.get( scene );
19177 let list;
19178 if ( cameras === undefined ) {
19179 list = new WebGLRenderList( properties );
19180 lists.set( scene, new WeakMap() );
19181 lists.get( scene ).set( camera, list );
19182 } else {
19183 list = cameras.get( camera );
19184 if ( list === undefined ) {
19185 list = new WebGLRenderList( properties );
19186 cameras.set( camera, list );
19187 }
19188 }
19189 return list;
19190 }
19191 function dispose() {
19192 lists = new WeakMap();
19193 }
19194 return {
19195 get: get,
19196 dispose: dispose
19197 };
19198 }
19199 function UniformsCache() {
19200 const lights = {};
19201 return {
19202 get: function ( light ) {
19203 if ( lights[ light.id ] !== undefined ) {
19204 return lights[ light.id ];
19205 }
19206 let uniforms;
19207 switch ( light.type ) {
19208 case 'DirectionalLight':
19209 uniforms = {
19210 direction: new Vector3(),
19211 color: new Color()
19212 };
19213 break;
19214 case 'SpotLight':
19215 uniforms = {
19216 position: new Vector3(),
19217 direction: new Vector3(),
19218 color: new Color(),
19219 distance: 0,
19220 coneCos: 0,
19221 penumbraCos: 0,
19222 decay: 0
19223 };
19224 break;
19225 case 'PointLight':
19226 uniforms = {
19227 position: new Vector3(),
19228 color: new Color(),
19229 distance: 0,
19230 decay: 0
19231 };
19232 break;
19233 case 'HemisphereLight':
19234 uniforms = {
19235 direction: new Vector3(),
19236 skyColor: new Color(),
19237 groundColor: new Color()
19238 };
19239 break;
19240 case 'RectAreaLight':
19241 uniforms = {
19242 color: new Color(),
19243 position: new Vector3(),
19244 halfWidth: new Vector3(),
19245 halfHeight: new Vector3()
19246 };
19247 break;
19248 }
19249 lights[ light.id ] = uniforms;
19250 return uniforms;
19251 }
19252 };
19253 }
19254 function ShadowUniformsCache() {
19255 const lights = {};
19256 return {
19257 get: function ( light ) {
19258 if ( lights[ light.id ] !== undefined ) {
19259 return lights[ light.id ];
19260 }
19261 let uniforms;
19262 switch ( light.type ) {
19263 case 'DirectionalLight':
19264 uniforms = {
19265 shadowBias: 0,
19266 shadowNormalBias: 0,
19267 shadowRadius: 1,
19268 shadowMapSize: new Vector2()
19269 };
19270 break;
19271 case 'SpotLight':
19272 uniforms = {
19273 shadowBias: 0,
19274 shadowNormalBias: 0,
19275 shadowRadius: 1,
19276 shadowMapSize: new Vector2()
19277 };
19278 break;
19279 case 'PointLight':
19280 uniforms = {
19281 shadowBias: 0,
19282 shadowNormalBias: 0,
19283 shadowRadius: 1,
19284 shadowMapSize: new Vector2(),
19285 shadowCameraNear: 1,
19286 shadowCameraFar: 1000
19287 };
19288 break;
19289 }
19290 lights[ light.id ] = uniforms;
19291 return uniforms;
19292 }
19293 };
19294 }
19295 let nextVersion = 0;
19296 function shadowCastingLightsFirst( lightA, lightB ) {
19297 return ( lightB.castShadow ? 1 : 0 ) - ( lightA.castShadow ? 1 : 0 );
19298 }
19299 function WebGLLights() {
19300 const cache = new UniformsCache();
19301 const shadowCache = ShadowUniformsCache();
19302 const state = {
19303 version: 0,
19304 hash: {
19305 directionalLength: - 1,
19306 pointLength: - 1,
19307 spotLength: - 1,
19308 rectAreaLength: - 1,
19309 hemiLength: - 1,
19310 numDirectionalShadows: - 1,
19311 numPointShadows: - 1,
19312 numSpotShadows: - 1
19313 },
19314 ambient: [ 0, 0, 0 ],
19315 probe: [],
19316 directional: [],
19317 directionalShadow: [],
19318 directionalShadowMap: [],
19319 directionalShadowMatrix: [],
19320 spot: [],
19321 spotShadow: [],
19322 spotShadowMap: [],
19323 spotShadowMatrix: [],
19324 rectArea: [],
19325 rectAreaLTC1: null,
19326 rectAreaLTC2: null,
19327 point: [],
19328 pointShadow: [],
19329 pointShadowMap: [],
19330 pointShadowMatrix: [],
19331 hemi: []
19332 };
19333 for ( let i = 0; i < 9; i ++ ) state.probe.push( new Vector3() );
19334 const vector3 = new Vector3();
19335 const matrix4 = new Matrix4();
19336 const matrix42 = new Matrix4();
19337 function setup( lights, shadows, camera ) {
19338 let r = 0, g = 0, b = 0;
19339 for ( let i = 0; i < 9; i ++ ) state.probe[ i ].set( 0, 0, 0 );
19340 let directionalLength = 0;
19341 let pointLength = 0;
19342 let spotLength = 0;
19343 let rectAreaLength = 0;
19344 let hemiLength = 0;
19345 let numDirectionalShadows = 0;
19346 let numPointShadows = 0;
19347 let numSpotShadows = 0;
19348 const viewMatrix = camera.matrixWorldInverse;
19349 lights.sort( shadowCastingLightsFirst );
19350 for ( let i = 0, l = lights.length; i < l; i ++ ) {
19351 const light = lights[ i ];
19352 const color = light.color;
19353 const intensity = light.intensity;
19354 const distance = light.distance;
19355 const shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
19356 if ( light.isAmbientLight ) {
19357 r += color.r * intensity;
19358 g += color.g * intensity;
19359 b += color.b * intensity;
19360 } else if ( light.isLightProbe ) {
19361 for ( let j = 0; j < 9; j ++ ) {
19362 state.probe[ j ].addScaledVector( light.sh.coefficients[ j ], intensity );
19363 }
19364 } else if ( light.isDirectionalLight ) {
19365 const uniforms = cache.get( light );
19366 uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
19367 uniforms.direction.setFromMatrixPosition( light.matrixWorld );
19368 vector3.setFromMatrixPosition( light.target.matrixWorld );
19369 uniforms.direction.sub( vector3 );
19370 uniforms.direction.transformDirection( viewMatrix );
19371 if ( light.castShadow ) {
19372 const shadow = light.shadow;
19373 const shadowUniforms = shadowCache.get( light );
19374 shadowUniforms.shadowBias = shadow.bias;
19375 shadowUniforms.shadowNormalBias = shadow.normalBias;
19376 shadowUniforms.shadowRadius = shadow.radius;
19377 shadowUniforms.shadowMapSize = shadow.mapSize;
19378 state.directionalShadow[ directionalLength ] = shadowUniforms;
19379 state.directionalShadowMap[ directionalLength ] = shadowMap;
19380 state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
19381 numDirectionalShadows ++;
19382 }
19383 state.directional[ directionalLength ] = uniforms;
19384 directionalLength ++;
19385 } else if ( light.isSpotLight ) {
19386 const uniforms = cache.get( light );
19387 uniforms.position.setFromMatrixPosition( light.matrixWorld );
19388 uniforms.position.applyMatrix4( viewMatrix );
19389 uniforms.color.copy( color ).multiplyScalar( intensity );
19390 uniforms.distance = distance;
19391 uniforms.direction.setFromMatrixPosition( light.matrixWorld );
19392 vector3.setFromMatrixPosition( light.target.matrixWorld );
19393 uniforms.direction.sub( vector3 );
19394 uniforms.direction.transformDirection( viewMatrix );
19395 uniforms.coneCos = Math.cos( light.angle );
19396 uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
19397 uniforms.decay = light.decay;
19398 if ( light.castShadow ) {
19399 const shadow = light.shadow;
19400 const shadowUniforms = shadowCache.get( light );
19401 shadowUniforms.shadowBias = shadow.bias;
19402 shadowUniforms.shadowNormalBias = shadow.normalBias;
19403 shadowUniforms.shadowRadius = shadow.radius;
19404 shadowUniforms.shadowMapSize = shadow.mapSize;
19405 state.spotShadow[ spotLength ] = shadowUniforms;
19406 state.spotShadowMap[ spotLength ] = shadowMap;
19407 state.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
19408 numSpotShadows ++;
19409 }
19410 state.spot[ spotLength ] = uniforms;
19411 spotLength ++;
19412 } else if ( light.isRectAreaLight ) {
19413 const uniforms = cache.get( light );
19414 uniforms.color.copy( color ).multiplyScalar( intensity );
19415 uniforms.position.setFromMatrixPosition( light.matrixWorld );
19416 uniforms.position.applyMatrix4( viewMatrix );
19417 matrix42.identity();
19418 matrix4.copy( light.matrixWorld );
19419 matrix4.premultiply( viewMatrix );
19420 matrix42.extractRotation( matrix4 );
19421 uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );
19422 uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );
19423 uniforms.halfWidth.applyMatrix4( matrix42 );
19424 uniforms.halfHeight.applyMatrix4( matrix42 );
19425 state.rectArea[ rectAreaLength ] = uniforms;
19426 rectAreaLength ++;
19427 } else if ( light.isPointLight ) {
19428 const uniforms = cache.get( light );
19429 uniforms.position.setFromMatrixPosition( light.matrixWorld );
19430 uniforms.position.applyMatrix4( viewMatrix );
19431 uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
19432 uniforms.distance = light.distance;
19433 uniforms.decay = light.decay;
19434 if ( light.castShadow ) {
19435 const shadow = light.shadow;
19436 const shadowUniforms = shadowCache.get( light );
19437 shadowUniforms.shadowBias = shadow.bias;
19438 shadowUniforms.shadowNormalBias = shadow.normalBias;
19439 shadowUniforms.shadowRadius = shadow.radius;
19440 shadowUniforms.shadowMapSize = shadow.mapSize;
19441 shadowUniforms.shadowCameraNear = shadow.camera.near;
19442 shadowUniforms.shadowCameraFar = shadow.camera.far;
19443 state.pointShadow[ pointLength ] = shadowUniforms;
19444 state.pointShadowMap[ pointLength ] = shadowMap;
19445 state.pointShadowMatrix[ pointLength ] = light.shadow.matrix;
19446 numPointShadows ++;
19447 }
19448 state.point[ pointLength ] = uniforms;
19449 pointLength ++;
19450 } else if ( light.isHemisphereLight ) {
19451 const uniforms = cache.get( light );
19452 uniforms.direction.setFromMatrixPosition( light.matrixWorld );
19453 uniforms.direction.transformDirection( viewMatrix );
19454 uniforms.direction.normalize();
19455 uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
19456 uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
19457 state.hemi[ hemiLength ] = uniforms;
19458 hemiLength ++;
19459 }
19460 }
19461 if ( rectAreaLength > 0 ) {
19462 state.rectAreaLTC1 = UniformsLib.LTC_1;
19463 state.rectAreaLTC2 = UniformsLib.LTC_2;
19464 }
19465 state.ambient[ 0 ] = r;
19466 state.ambient[ 1 ] = g;
19467 state.ambient[ 2 ] = b;
19468 const hash = state.hash;
19469 if ( hash.directionalLength !== directionalLength ||
19470 hash.pointLength !== pointLength ||
19471 hash.spotLength !== spotLength ||
19472 hash.rectAreaLength !== rectAreaLength ||
19473 hash.hemiLength !== hemiLength ||
19474 hash.numDirectionalShadows !== numDirectionalShadows ||
19475 hash.numPointShadows !== numPointShadows ||
19476 hash.numSpotShadows !== numSpotShadows ) {
19477 state.directional.length = directionalLength;
19478 state.spot.length = spotLength;
19479 state.rectArea.length = rectAreaLength;
19480 state.point.length = pointLength;
19481 state.hemi.length = hemiLength;
19482 state.directionalShadow.length = numDirectionalShadows;
19483 state.directionalShadowMap.length = numDirectionalShadows;
19484 state.pointShadow.length = numPointShadows;
19485 state.pointShadowMap.length = numPointShadows;
19486 state.spotShadow.length = numSpotShadows;
19487 state.spotShadowMap.length = numSpotShadows;
19488 state.directionalShadowMatrix.length = numDirectionalShadows;
19489 state.pointShadowMatrix.length = numPointShadows;
19490 state.spotShadowMatrix.length = numSpotShadows;
19491 hash.directionalLength = directionalLength;
19492 hash.pointLength = pointLength;
19493 hash.spotLength = spotLength;
19494 hash.rectAreaLength = rectAreaLength;
19495 hash.hemiLength = hemiLength;
19496 hash.numDirectionalShadows = numDirectionalShadows;
19497 hash.numPointShadows = numPointShadows;
19498 hash.numSpotShadows = numSpotShadows;
19499 state.version = nextVersion ++;
19500 }
19501 }
19502 return {
19503 setup: setup,
19504 state: state
19505 };
19506 }
19507 function WebGLRenderState() {
19508 const lights = new WebGLLights();
19509 const lightsArray = [];
19510 const shadowsArray = [];
19511 function init() {
19512 lightsArray.length = 0;
19513 shadowsArray.length = 0;
19514 }
19515 function pushLight( light ) {
19516 lightsArray.push( light );
19517 }
19518 function pushShadow( shadowLight ) {
19519 shadowsArray.push( shadowLight );
19520 }
19521 function setupLights( camera ) {
19522 lights.setup( lightsArray, shadowsArray, camera );
19523 }
19524 const state = {
19525 lightsArray: lightsArray,
19526 shadowsArray: shadowsArray,
19527 lights: lights
19528 };
19529 return {
19530 init: init,
19531 state: state,
19532 setupLights: setupLights,
19533 pushLight: pushLight,
19534 pushShadow: pushShadow
19535 };
19536 }
19537 function WebGLRenderStates() {
19538 let renderStates = new WeakMap();
19539 function get( scene, camera ) {
19540 let renderState;
19541 if ( renderStates.has( scene ) === false ) {
19542 renderState = new WebGLRenderState();
19543 renderStates.set( scene, new WeakMap() );
19544 renderStates.get( scene ).set( camera, renderState );
19545 } else {
19546 if ( renderStates.get( scene ).has( camera ) === false ) {
19547 renderState = new WebGLRenderState();
19548 renderStates.get( scene ).set( camera, renderState );
19549 } else {
19550 renderState = renderStates.get( scene ).get( camera );
19551 }
19552 }
19553 return renderState;
19554 }
19555 function dispose() {
19556 renderStates = new WeakMap();
19557 }
19558 return {
19559 get: get,
19560 dispose: dispose
19561 };
19562 }
19563 function MeshDepthMaterial( parameters ) {
19564 Material.call( this );
19565 this.type = 'MeshDepthMaterial';
19566 this.depthPacking = BasicDepthPacking;
19567 this.skinning = false;
19568 this.morphTargets = false;
19569 this.map = null;
19570 this.alphaMap = null;
19571 this.displacementMap = null;
19572 this.displacementScale = 1;
19573 this.displacementBias = 0;
19574 this.wireframe = false;
19575 this.wireframeLinewidth = 1;
19576 this.fog = false;
19577 this.setValues( parameters );
19578 }
19579 MeshDepthMaterial.prototype = Object.create( Material.prototype );
19580 MeshDepthMaterial.prototype.constructor = MeshDepthMaterial;
19581 MeshDepthMaterial.prototype.isMeshDepthMaterial = true;
19582 MeshDepthMaterial.prototype.copy = function ( source ) {
19583 Material.prototype.copy.call( this, source );
19584 this.depthPacking = source.depthPacking;
19585 this.skinning = source.skinning;
19586 this.morphTargets = source.morphTargets;
19587 this.map = source.map;
19588 this.alphaMap = source.alphaMap;
19589 this.displacementMap = source.displacementMap;
19590 this.displacementScale = source.displacementScale;
19591 this.displacementBias = source.displacementBias;
19592 this.wireframe = source.wireframe;
19593 this.wireframeLinewidth = source.wireframeLinewidth;
19594 return this;
19595 };
19596 function MeshDistanceMaterial( parameters ) {
19597 Material.call( this );
19598 this.type = 'MeshDistanceMaterial';
19599 this.referencePosition = new Vector3();
19600 this.nearDistance = 1;
19601 this.farDistance = 1000;
19602 this.skinning = false;
19603 this.morphTargets = false;
19604 this.map = null;
19605 this.alphaMap = null;
19606 this.displacementMap = null;
19607 this.displacementScale = 1;
19608 this.displacementBias = 0;
19609 this.fog = false;
19610 this.setValues( parameters );
19611 }
19612 MeshDistanceMaterial.prototype = Object.create( Material.prototype );
19613 MeshDistanceMaterial.prototype.constructor = MeshDistanceMaterial;
19614 MeshDistanceMaterial.prototype.isMeshDistanceMaterial = true;
19615 MeshDistanceMaterial.prototype.copy = function ( source ) {
19616 Material.prototype.copy.call( this, source );
19617 this.referencePosition.copy( source.referencePosition );
19618 this.nearDistance = source.nearDistance;
19619 this.farDistance = source.farDistance;
19620 this.skinning = source.skinning;
19621 this.morphTargets = source.morphTargets;
19622 this.map = source.map;
19623 this.alphaMap = source.alphaMap;
19624 this.displacementMap = source.displacementMap;
19625 this.displacementScale = source.displacementScale;
19626 this.displacementBias = source.displacementBias;
19627 return this;
19628 };
19629 var vsm_frag = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include <packing>\nvoid main() {\n\tfloat mean = 0.0;\n\tfloat squared_mean = 0.0;\n\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy ) / resolution ) );\n\tfor ( float i = -1.0; i < 1.0 ; i += SAMPLE_RATE) {\n\t\t#ifdef HORIZONAL_PASS\n\t\t\tvec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( i, 0.0 ) * radius ) / resolution ) );\n\t\t\tmean += distribution.x;\n\t\t\tsquared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n\t\t#else\n\t\t\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, i ) * radius ) / resolution ) );\n\t\t\tmean += depth;\n\t\t\tsquared_mean += depth * depth;\n\t\t#endif\n\t}\n\tmean = mean * HALF_SAMPLE_RATE;\n\tsquared_mean = squared_mean * HALF_SAMPLE_RATE;\n\tfloat std_dev = sqrt( squared_mean - mean * mean );\n\tgl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}";
19630 var vsm_vert = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}";
19631 function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
19632 let _frustum = new Frustum();
19633 const _shadowMapSize = new Vector2(),
19634 _viewportSize = new Vector2(),
19635 _viewport = new Vector4(),
19636 _depthMaterials = [],
19637 _distanceMaterials = [],
19638 _materialCache = {};
19639 const shadowSide = { 0: BackSide, 1: FrontSide, 2: DoubleSide };
19640 const shadowMaterialVertical = new ShaderMaterial( {
19641 defines: {
19642 SAMPLE_RATE: 2.0 / 8.0,
19643 HALF_SAMPLE_RATE: 1.0 / 8.0
19644 },
19645 uniforms: {
19646 shadow_pass: { value: null },
19647 resolution: { value: new Vector2() },
19648 radius: { value: 4.0 }
19649 },
19650 vertexShader: vsm_vert,
19651 fragmentShader: vsm_frag
19652 } );
19653 const shadowMaterialHorizonal = shadowMaterialVertical.clone();
19654 shadowMaterialHorizonal.defines.HORIZONAL_PASS = 1;
19655 const fullScreenTri = new BufferGeometry();
19656 fullScreenTri.setAttribute(
19657 "position",
19658 new BufferAttribute(
19659 new Float32Array( [ - 1, - 1, 0.5, 3, - 1, 0.5, - 1, 3, 0.5 ] ),
19660 3
19661 )
19662 );
19663 const fullScreenMesh = new Mesh( fullScreenTri, shadowMaterialVertical );
19664 const scope = this;
19665 this.enabled = false;
19666 this.autoUpdate = true;
19667 this.needsUpdate = false;
19668 this.type = PCFShadowMap;
19669 this.render = function ( lights, scene, camera ) {
19670 if ( scope.enabled === false ) return;
19671 if ( scope.autoUpdate === false && scope.needsUpdate === false ) return;
19672 if ( lights.length === 0 ) return;
19673 const currentRenderTarget = _renderer.getRenderTarget();
19674 const activeCubeFace = _renderer.getActiveCubeFace();
19675 const activeMipmapLevel = _renderer.getActiveMipmapLevel();
19676 const _state = _renderer.state;
19677 _state.setBlending( NoBlending );
19678 _state.buffers.color.setClear( 1, 1, 1, 1 );
19679 _state.buffers.depth.setTest( true );
19680 _state.setScissorTest( false );
19681 for ( let i = 0, il = lights.length; i < il; i ++ ) {
19682 const light = lights[ i ];
19683 const shadow = light.shadow;
19684 if ( shadow.autoUpdate === false && shadow.needsUpdate === false ) continue;
19685 if ( shadow === undefined ) {
19686 console.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );
19687 continue;
19688 }
19689 _shadowMapSize.copy( shadow.mapSize );
19690 const shadowFrameExtents = shadow.getFrameExtents();
19691 _shadowMapSize.multiply( shadowFrameExtents );
19692 _viewportSize.copy( shadow.mapSize );
19693 if ( _shadowMapSize.x > maxTextureSize || _shadowMapSize.y > maxTextureSize ) {
19694 if ( _shadowMapSize.x > maxTextureSize ) {
19695 _viewportSize.x = Math.floor( maxTextureSize / shadowFrameExtents.x );
19696 _shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x;
19697 shadow.mapSize.x = _viewportSize.x;
19698 }
19699 if ( _shadowMapSize.y > maxTextureSize ) {
19700 _viewportSize.y = Math.floor( maxTextureSize / shadowFrameExtents.y );
19701 _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y;
19702 shadow.mapSize.y = _viewportSize.y;
19703 }
19704 }
19705 if ( shadow.map === null && ! shadow.isPointLightShadow && this.type === VSMShadowMap ) {
19706 const pars = { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat };
19707 shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );
19708 shadow.map.texture.name = light.name + ".shadowMap";
19709 shadow.mapPass = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );
19710 shadow.camera.updateProjectionMatrix();
19711 }
19712 if ( shadow.map === null ) {
19713 const pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };
19714 shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );
19715 shadow.map.texture.name = light.name + ".shadowMap";
19716 shadow.camera.updateProjectionMatrix();
19717 }
19718 _renderer.setRenderTarget( shadow.map );
19719 _renderer.clear();
19720 const viewportCount = shadow.getViewportCount();
19721 for ( let vp = 0; vp < viewportCount; vp ++ ) {
19722 const viewport = shadow.getViewport( vp );
19723 _viewport.set(
19724 _viewportSize.x * viewport.x,
19725 _viewportSize.y * viewport.y,
19726 _viewportSize.x * viewport.z,
19727 _viewportSize.y * viewport.w
19728 );
19729 _state.viewport( _viewport );
19730 shadow.updateMatrices( light, vp );
19731 _frustum = shadow.getFrustum();
19732 renderObject( scene, camera, shadow.camera, light, this.type );
19733 }
19734 if ( ! shadow.isPointLightShadow && this.type === VSMShadowMap ) {
19735 VSMPass( shadow, camera );
19736 }
19737 shadow.needsUpdate = false;
19738 }
19739 scope.needsUpdate = false;
19740 _renderer.setRenderTarget( currentRenderTarget, activeCubeFace, activeMipmapLevel );
19741 };
19742 function VSMPass( shadow, camera ) {
19743 const geometry = _objects.update( fullScreenMesh );
19744 shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture;
19745 shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize;
19746 shadowMaterialVertical.uniforms.radius.value = shadow.radius;
19747 _renderer.setRenderTarget( shadow.mapPass );
19748 _renderer.clear();
19749 _renderer.renderBufferDirect( camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null );
19750 shadowMaterialHorizonal.uniforms.shadow_pass.value = shadow.mapPass.texture;
19751 shadowMaterialHorizonal.uniforms.resolution.value = shadow.mapSize;
19752 shadowMaterialHorizonal.uniforms.radius.value = shadow.radius;
19753 _renderer.setRenderTarget( shadow.map );
19754 _renderer.clear();
19755 _renderer.renderBufferDirect( camera, null, geometry, shadowMaterialHorizonal, fullScreenMesh, null );
19756 }
19757 function getDepthMaterialVariant( useMorphing, useSkinning, useInstancing ) {
19758 const index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2;
19759 let material = _depthMaterials[ index ];
19760 if ( material === undefined ) {
19761 material = new MeshDepthMaterial( {
19762 depthPacking: RGBADepthPacking,
19763 morphTargets: useMorphing,
19764 skinning: useSkinning
19765 } );
19766 _depthMaterials[ index ] = material;
19767 }
19768 return material;
19769 }
19770 function getDistanceMaterialVariant( useMorphing, useSkinning, useInstancing ) {
19771 const index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2;
19772 let material = _distanceMaterials[ index ];
19773 if ( material === undefined ) {
19774 material = new MeshDistanceMaterial( {
19775 morphTargets: useMorphing,
19776 skinning: useSkinning
19777 } );
19778 _distanceMaterials[ index ] = material;
19779 }
19780 return material;
19781 }
19782 function getDepthMaterial( object, geometry, material, light, shadowCameraNear, shadowCameraFar, type ) {
19783 let result = null;
19784 let getMaterialVariant = getDepthMaterialVariant;
19785 let customMaterial = object.customDepthMaterial;
19786 if ( light.isPointLight === true ) {
19787 getMaterialVariant = getDistanceMaterialVariant;
19788 customMaterial = object.customDistanceMaterial;
19789 }
19790 if ( customMaterial === undefined ) {
19791 let useMorphing = false;
19792 if ( material.morphTargets === true ) {
19793 useMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;
19794 }
19795 let useSkinning = false;
19796 if ( object.isSkinnedMesh === true ) {
19797 if ( material.skinning === true ) {
19798 useSkinning = true;
19799 } else {
19800 console.warn( 'THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:', object );
19801 }
19802 }
19803 const useInstancing = object.isInstancedMesh === true;
19804 result = getMaterialVariant( useMorphing, useSkinning, useInstancing );
19805 } else {
19806 result = customMaterial;
19807 }
19808 if ( _renderer.localClippingEnabled &&
19809 material.clipShadows === true &&
19810 material.clippingPlanes.length !== 0 ) {
19811 const keyA = result.uuid, keyB = material.uuid;
19812 let materialsForVariant = _materialCache[ keyA ];
19813 if ( materialsForVariant === undefined ) {
19814 materialsForVariant = {};
19815 _materialCache[ keyA ] = materialsForVariant;
19816 }
19817 let cachedMaterial = materialsForVariant[ keyB ];
19818 if ( cachedMaterial === undefined ) {
19819 cachedMaterial = result.clone();
19820 materialsForVariant[ keyB ] = cachedMaterial;
19821 }
19822 result = cachedMaterial;
19823 }
19824 result.visible = material.visible;
19825 result.wireframe = material.wireframe;
19826 if ( type === VSMShadowMap ) {
19827 result.side = ( material.shadowSide !== null ) ? material.shadowSide : material.side;
19828 } else {
19829 result.side = ( material.shadowSide !== null ) ? material.shadowSide : shadowSide[ material.side ];
19830 }
19831 result.clipShadows = material.clipShadows;
19832 result.clippingPlanes = material.clippingPlanes;
19833 result.clipIntersection = material.clipIntersection;
19834 result.wireframeLinewidth = material.wireframeLinewidth;
19835 result.linewidth = material.linewidth;
19836 if ( light.isPointLight === true && result.isMeshDistanceMaterial === true ) {
19837 result.referencePosition.setFromMatrixPosition( light.matrixWorld );
19838 result.nearDistance = shadowCameraNear;
19839 result.farDistance = shadowCameraFar;
19840 }
19841 return result;
19842 }
19843 function renderObject( object, camera, shadowCamera, light, type ) {
19844 if ( object.visible === false ) return;
19845 const visible = object.layers.test( camera.layers );
19846 if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {
19847 if ( ( object.castShadow || ( object.receiveShadow && type === VSMShadowMap ) ) && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) {
19848 object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );
19849 const geometry = _objects.update( object );
19850 const material = object.material;
19851 if ( Array.isArray( material ) ) {
19852 const groups = geometry.groups;
19853 for ( let k = 0, kl = groups.length; k < kl; k ++ ) {
19854 const group = groups[ k ];
19855 const groupMaterial = material[ group.materialIndex ];
19856 if ( groupMaterial && groupMaterial.visible ) {
19857 const depthMaterial = getDepthMaterial( object, geometry, groupMaterial, light, shadowCamera.near, shadowCamera.far, type );
19858 _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );
19859 }
19860 }
19861 } else if ( material.visible ) {
19862 const depthMaterial = getDepthMaterial( object, geometry, material, light, shadowCamera.near, shadowCamera.far, type );
19863 _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );
19864 }
19865 }
19866 }
19867 const children = object.children;
19868 for ( let i = 0, l = children.length; i < l; i ++ ) {
19869 renderObject( children[ i ], camera, shadowCamera, light, type );
19870 }
19871 }
19872 }
19873 function WebGLState( gl, extensions, capabilities ) {
19874 const isWebGL2 = capabilities.isWebGL2;
19875 function ColorBuffer() {
19876 let locked = false;
19877 const color = new Vector4();
19878 let currentColorMask = null;
19879 const currentColorClear = new Vector4( 0, 0, 0, 0 );
19880 return {
19881 setMask: function ( colorMask ) {
19882 if ( currentColorMask !== colorMask && ! locked ) {
19883 gl.colorMask( colorMask, colorMask, colorMask, colorMask );
19884 currentColorMask = colorMask;
19885 }
19886 },
19887 setLocked: function ( lock ) {
19888 locked = lock;
19889 },
19890 setClear: function ( r, g, b, a, premultipliedAlpha ) {
19891 if ( premultipliedAlpha === true ) {
19892 r *= a; g *= a; b *= a;
19893 }
19894 color.set( r, g, b, a );
19895 if ( currentColorClear.equals( color ) === false ) {
19896 gl.clearColor( r, g, b, a );
19897 currentColorClear.copy( color );
19898 }
19899 },
19900 reset: function () {
19901 locked = false;
19902 currentColorMask = null;
19903 currentColorClear.set( - 1, 0, 0, 0 );
19904 }
19905 };
19906 }
19907 function DepthBuffer() {
19908 let locked = false;
19909 let currentDepthMask = null;
19910 let currentDepthFunc = null;
19911 let currentDepthClear = null;
19912 return {
19913 setTest: function ( depthTest ) {
19914 if ( depthTest ) {
19915 enable( 2929 );
19916 } else {
19917 disable( 2929 );
19918 }
19919 },
19920 setMask: function ( depthMask ) {
19921 if ( currentDepthMask !== depthMask && ! locked ) {
19922 gl.depthMask( depthMask );
19923 currentDepthMask = depthMask;
19924 }
19925 },
19926 setFunc: function ( depthFunc ) {
19927 if ( currentDepthFunc !== depthFunc ) {
19928 if ( depthFunc ) {
19929 switch ( depthFunc ) {
19930 case NeverDepth:
19931 gl.depthFunc( 512 );
19932 break;
19933 case AlwaysDepth:
19934 gl.depthFunc( 519 );
19935 break;
19936 case LessDepth:
19937 gl.depthFunc( 513 );
19938 break;
19939 case LessEqualDepth:
19940 gl.depthFunc( 515 );
19941 break;
19942 case EqualDepth:
19943 gl.depthFunc( 514 );
19944 break;
19945 case GreaterEqualDepth:
19946 gl.depthFunc( 518 );
19947 break;
19948 case GreaterDepth:
19949 gl.depthFunc( 516 );
19950 break;
19951 case NotEqualDepth:
19952 gl.depthFunc( 517 );
19953 break;
19954 default:
19955 gl.depthFunc( 515 );
19956 }
19957 } else {
19958 gl.depthFunc( 515 );
19959 }
19960 currentDepthFunc = depthFunc;
19961 }
19962 },
19963 setLocked: function ( lock ) {
19964 locked = lock;
19965 },
19966 setClear: function ( depth ) {
19967 if ( currentDepthClear !== depth ) {
19968 gl.clearDepth( depth );
19969 currentDepthClear = depth;
19970 }
19971 },
19972 reset: function () {
19973 locked = false;
19974 currentDepthMask = null;
19975 currentDepthFunc = null;
19976 currentDepthClear = null;
19977 }
19978 };
19979 }
19980 function StencilBuffer() {
19981 let locked = false;
19982 let currentStencilMask = null;
19983 let currentStencilFunc = null;
19984 let currentStencilRef = null;
19985 let currentStencilFuncMask = null;
19986 let currentStencilFail = null;
19987 let currentStencilZFail = null;
19988 let currentStencilZPass = null;
19989 let currentStencilClear = null;
19990 return {
19991 setTest: function ( stencilTest ) {
19992 if ( ! locked ) {
19993 if ( stencilTest ) {
19994 enable( 2960 );
19995 } else {
19996 disable( 2960 );
19997 }
19998 }
19999 },
20000 setMask: function ( stencilMask ) {
20001 if ( currentStencilMask !== stencilMask && ! locked ) {
20002 gl.stencilMask( stencilMask );
20003 currentStencilMask = stencilMask;
20004 }
20005 },
20006 setFunc: function ( stencilFunc, stencilRef, stencilMask ) {
20007 if ( currentStencilFunc !== stencilFunc ||
20008 currentStencilRef !== stencilRef ||
20009 currentStencilFuncMask !== stencilMask ) {
20010 gl.stencilFunc( stencilFunc, stencilRef, stencilMask );
20011 currentStencilFunc = stencilFunc;
20012 currentStencilRef = stencilRef;
20013 currentStencilFuncMask = stencilMask;
20014 }
20015 },
20016 setOp: function ( stencilFail, stencilZFail, stencilZPass ) {
20017 if ( currentStencilFail !== stencilFail ||
20018 currentStencilZFail !== stencilZFail ||
20019 currentStencilZPass !== stencilZPass ) {
20020 gl.stencilOp( stencilFail, stencilZFail, stencilZPass );
20021 currentStencilFail = stencilFail;
20022 currentStencilZFail = stencilZFail;
20023 currentStencilZPass = stencilZPass;
20024 }
20025 },
20026 setLocked: function ( lock ) {
20027 locked = lock;
20028 },
20029 setClear: function ( stencil ) {
20030 if ( currentStencilClear !== stencil ) {
20031 gl.clearStencil( stencil );
20032 currentStencilClear = stencil;
20033 }
20034 },
20035 reset: function () {
20036 locked = false;
20037 currentStencilMask = null;
20038 currentStencilFunc = null;
20039 currentStencilRef = null;
20040 currentStencilFuncMask = null;
20041 currentStencilFail = null;
20042 currentStencilZFail = null;
20043 currentStencilZPass = null;
20044 currentStencilClear = null;
20045 }
20046 };
20047 }
20048 const colorBuffer = new ColorBuffer();
20049 const depthBuffer = new DepthBuffer();
20050 const stencilBuffer = new StencilBuffer();
20051 let enabledCapabilities = {};
20052 let currentProgram = null;
20053 let currentBlendingEnabled = null;
20054 let currentBlending = null;
20055 let currentBlendEquation = null;
20056 let currentBlendSrc = null;
20057 let currentBlendDst = null;
20058 let currentBlendEquationAlpha = null;
20059 let currentBlendSrcAlpha = null;
20060 let currentBlendDstAlpha = null;
20061 let currentPremultipledAlpha = false;
20062 let currentFlipSided = null;
20063 let currentCullFace = null;
20064 let currentLineWidth = null;
20065 let currentPolygonOffsetFactor = null;
20066 let currentPolygonOffsetUnits = null;
20067 const maxTextures = gl.getParameter( 35661 );
20068 let lineWidthAvailable = false;
20069 let version = 0;
20070 const glVersion = gl.getParameter( 7938 );
20071 if ( glVersion.indexOf( 'WebGL' ) !== - 1 ) {
20072 version = parseFloat( /^WebGL\ ([0-9])/.exec( glVersion )[ 1 ] );
20073 lineWidthAvailable = ( version >= 1.0 );
20074 } else if ( glVersion.indexOf( 'OpenGL ES' ) !== - 1 ) {
20075 version = parseFloat( /^OpenGL\ ES\ ([0-9])/.exec( glVersion )[ 1 ] );
20076 lineWidthAvailable = ( version >= 2.0 );
20077 }
20078 let currentTextureSlot = null;
20079 let currentBoundTextures = {};
20080 const currentScissor = new Vector4();
20081 const currentViewport = new Vector4();
20082 function createTexture( type, target, count ) {
20083 const data = new Uint8Array( 4 );
20084 const texture = gl.createTexture();
20085 gl.bindTexture( type, texture );
20086 gl.texParameteri( type, 10241, 9728 );
20087 gl.texParameteri( type, 10240, 9728 );
20088 for ( let i = 0; i < count; i ++ ) {
20089 gl.texImage2D( target + i, 0, 6408, 1, 1, 0, 6408, 5121, data );
20090 }
20091 return texture;
20092 }
20093 const emptyTextures = {};
20094 emptyTextures[ 3553 ] = createTexture( 3553, 3553, 1 );
20095 emptyTextures[ 34067 ] = createTexture( 34067, 34069, 6 );
20096 colorBuffer.setClear( 0, 0, 0, 1 );
20097 depthBuffer.setClear( 1 );
20098 stencilBuffer.setClear( 0 );
20099 enable( 2929 );
20100 depthBuffer.setFunc( LessEqualDepth );
20101 setFlipSided( false );
20102 setCullFace( CullFaceBack );
20103 enable( 2884 );
20104 setBlending( NoBlending );
20105 function enable( id ) {
20106 if ( enabledCapabilities[ id ] !== true ) {
20107 gl.enable( id );
20108 enabledCapabilities[ id ] = true;
20109 }
20110 }
20111 function disable( id ) {
20112 if ( enabledCapabilities[ id ] !== false ) {
20113 gl.disable( id );
20114 enabledCapabilities[ id ] = false;
20115 }
20116 }
20117 function useProgram( program ) {
20118 if ( currentProgram !== program ) {
20119 gl.useProgram( program );
20120 currentProgram = program;
20121 return true;
20122 }
20123 return false;
20124 }
20125 const equationToGL = {
20126 [ AddEquation ]: 32774,
20127 [ SubtractEquation ]: 32778,
20128 [ ReverseSubtractEquation ]: 32779
20129 };
20130 if ( isWebGL2 ) {
20131 equationToGL[ MinEquation ] = 32775;
20132 equationToGL[ MaxEquation ] = 32776;
20133 } else {
20134 const extension = extensions.get( 'EXT_blend_minmax' );
20135 if ( extension !== null ) {
20136 equationToGL[ MinEquation ] = extension.MIN_EXT;
20137 equationToGL[ MaxEquation ] = extension.MAX_EXT;
20138 }
20139 }
20140 const factorToGL = {
20141 [ ZeroFactor ]: 0,
20142 [ OneFactor ]: 1,
20143 [ SrcColorFactor ]: 768,
20144 [ SrcAlphaFactor ]: 770,
20145 [ SrcAlphaSaturateFactor ]: 776,
20146 [ DstColorFactor ]: 774,
20147 [ DstAlphaFactor ]: 772,
20148 [ OneMinusSrcColorFactor ]: 769,
20149 [ OneMinusSrcAlphaFactor ]: 771,
20150 [ OneMinusDstColorFactor ]: 775,
20151 [ OneMinusDstAlphaFactor ]: 773
20152 };
20153 function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {
20154 if ( blending === NoBlending ) {
20155 if ( currentBlendingEnabled ) {
20156 disable( 3042 );
20157 currentBlendingEnabled = false;
20158 }
20159 return;
20160 }
20161 if ( ! currentBlendingEnabled ) {
20162 enable( 3042 );
20163 currentBlendingEnabled = true;
20164 }
20165 if ( blending !== CustomBlending ) {
20166 if ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {
20167 if ( currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation ) {
20168 gl.blendEquation( 32774 );
20169 currentBlendEquation = AddEquation;
20170 currentBlendEquationAlpha = AddEquation;
20171 }
20172 if ( premultipliedAlpha ) {
20173 switch ( blending ) {
20174 case NormalBlending:
20175 gl.blendFuncSeparate( 1, 771, 1, 771 );
20176 break;
20177 case AdditiveBlending:
20178 gl.blendFunc( 1, 1 );
20179 break;
20180 case SubtractiveBlending:
20181 gl.blendFuncSeparate( 0, 0, 769, 771 );
20182 break;
20183 case MultiplyBlending:
20184 gl.blendFuncSeparate( 0, 768, 0, 770 );
20185 break;
20186 default:
20187 console.error( 'THREE.WebGLState: Invalid blending: ', blending );
20188 break;
20189 }
20190 } else {
20191 switch ( blending ) {
20192 case NormalBlending:
20193 gl.blendFuncSeparate( 770, 771, 1, 771 );
20194 break;
20195 case AdditiveBlending:
20196 gl.blendFunc( 770, 1 );
20197 break;
20198 case SubtractiveBlending:
20199 gl.blendFunc( 0, 769 );
20200 break;
20201 case MultiplyBlending:
20202 gl.blendFunc( 0, 768 );
20203 break;
20204 default:
20205 console.error( 'THREE.WebGLState: Invalid blending: ', blending );
20206 break;
20207 }
20208 }
20209 currentBlendSrc = null;
20210 currentBlendDst = null;
20211 currentBlendSrcAlpha = null;
20212 currentBlendDstAlpha = null;
20213 currentBlending = blending;
20214 currentPremultipledAlpha = premultipliedAlpha;
20215 }
20216 return;
20217 }
20218 blendEquationAlpha = blendEquationAlpha || blendEquation;
20219 blendSrcAlpha = blendSrcAlpha || blendSrc;
20220 blendDstAlpha = blendDstAlpha || blendDst;
20221 if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {
20222 gl.blendEquationSeparate( equationToGL[ blendEquation ], equationToGL[ blendEquationAlpha ] );
20223 currentBlendEquation = blendEquation;
20224 currentBlendEquationAlpha = blendEquationAlpha;
20225 }
20226 if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {
20227 gl.blendFuncSeparate( factorToGL[ blendSrc ], factorToGL[ blendDst ], factorToGL[ blendSrcAlpha ], factorToGL[ blendDstAlpha ] );
20228 currentBlendSrc = blendSrc;
20229 currentBlendDst = blendDst;
20230 currentBlendSrcAlpha = blendSrcAlpha;
20231 currentBlendDstAlpha = blendDstAlpha;
20232 }
20233 currentBlending = blending;
20234 currentPremultipledAlpha = null;
20235 }
20236 function setMaterial( material, frontFaceCW ) {
20237 material.side === DoubleSide
20238 ? disable( 2884 )
20239 : enable( 2884 );
20240 let flipSided = ( material.side === BackSide );
20241 if ( frontFaceCW ) flipSided = ! flipSided;
20242 setFlipSided( flipSided );
20243 ( material.blending === NormalBlending && material.transparent === false )
20244 ? setBlending( NoBlending )
20245 : setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha );
20246 depthBuffer.setFunc( material.depthFunc );
20247 depthBuffer.setTest( material.depthTest );
20248 depthBuffer.setMask( material.depthWrite );
20249 colorBuffer.setMask( material.colorWrite );
20250 const stencilWrite = material.stencilWrite;
20251 stencilBuffer.setTest( stencilWrite );
20252 if ( stencilWrite ) {
20253 stencilBuffer.setMask( material.stencilWriteMask );
20254 stencilBuffer.setFunc( material.stencilFunc, material.stencilRef, material.stencilFuncMask );
20255 stencilBuffer.setOp( material.stencilFail, material.stencilZFail, material.stencilZPass );
20256 }
20257 setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
20258 }
20259 function setFlipSided( flipSided ) {
20260 if ( currentFlipSided !== flipSided ) {
20261 if ( flipSided ) {
20262 gl.frontFace( 2304 );
20263 } else {
20264 gl.frontFace( 2305 );
20265 }
20266 currentFlipSided = flipSided;
20267 }
20268 }
20269 function setCullFace( cullFace ) {
20270 if ( cullFace !== CullFaceNone ) {
20271 enable( 2884 );
20272 if ( cullFace !== currentCullFace ) {
20273 if ( cullFace === CullFaceBack ) {
20274 gl.cullFace( 1029 );
20275 } else if ( cullFace === CullFaceFront ) {
20276 gl.cullFace( 1028 );
20277 } else {
20278 gl.cullFace( 1032 );
20279 }
20280 }
20281 } else {
20282 disable( 2884 );
20283 }
20284 currentCullFace = cullFace;
20285 }
20286 function setLineWidth( width ) {
20287 if ( width !== currentLineWidth ) {
20288 if ( lineWidthAvailable ) gl.lineWidth( width );
20289 currentLineWidth = width;
20290 }
20291 }
20292 function setPolygonOffset( polygonOffset, factor, units ) {
20293 if ( polygonOffset ) {
20294 enable( 32823 );
20295 if ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {
20296 gl.polygonOffset( factor, units );
20297 currentPolygonOffsetFactor = factor;
20298 currentPolygonOffsetUnits = units;
20299 }
20300 } else {
20301 disable( 32823 );
20302 }
20303 }
20304 function setScissorTest( scissorTest ) {
20305 if ( scissorTest ) {
20306 enable( 3089 );
20307 } else {
20308 disable( 3089 );
20309 }
20310 }
20311 function activeTexture( webglSlot ) {
20312 if ( webglSlot === undefined ) webglSlot = 33984 + maxTextures - 1;
20313 if ( currentTextureSlot !== webglSlot ) {
20314 gl.activeTexture( webglSlot );
20315 currentTextureSlot = webglSlot;
20316 }
20317 }
20318 function bindTexture( webglType, webglTexture ) {
20319 if ( currentTextureSlot === null ) {
20320 activeTexture();
20321 }
20322 let boundTexture = currentBoundTextures[ currentTextureSlot ];
20323 if ( boundTexture === undefined ) {
20324 boundTexture = { type: undefined, texture: undefined };
20325 currentBoundTextures[ currentTextureSlot ] = boundTexture;
20326 }
20327 if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {
20328 gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );
20329 boundTexture.type = webglType;
20330 boundTexture.texture = webglTexture;
20331 }
20332 }
20333 function unbindTexture() {
20334 const boundTexture = currentBoundTextures[ currentTextureSlot ];
20335 if ( boundTexture !== undefined && boundTexture.type !== undefined ) {
20336 gl.bindTexture( boundTexture.type, null );
20337 boundTexture.type = undefined;
20338 boundTexture.texture = undefined;
20339 }
20340 }
20341 function compressedTexImage2D() {
20342 try {
20343 gl.compressedTexImage2D.apply( gl, arguments );
20344 } catch ( error ) {
20345 console.error( 'THREE.WebGLState:', error );
20346 }
20347 }
20348 function texImage2D() {
20349 try {
20350 gl.texImage2D.apply( gl, arguments );
20351 } catch ( error ) {
20352 console.error( 'THREE.WebGLState:', error );
20353 }
20354 }
20355 function texImage3D() {
20356 try {
20357 gl.texImage3D.apply( gl, arguments );
20358 } catch ( error ) {
20359 console.error( 'THREE.WebGLState:', error );
20360 }
20361 }
20362 function scissor( scissor ) {
20363 if ( currentScissor.equals( scissor ) === false ) {
20364 gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );
20365 currentScissor.copy( scissor );
20366 }
20367 }
20368 function viewport( viewport ) {
20369 if ( currentViewport.equals( viewport ) === false ) {
20370 gl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );
20371 currentViewport.copy( viewport );
20372 }
20373 }
20374 function reset() {
20375 enabledCapabilities = {};
20376 currentTextureSlot = null;
20377 currentBoundTextures = {};
20378 currentProgram = null;
20379 currentBlending = null;
20380 currentFlipSided = null;
20381 currentCullFace = null;
20382 colorBuffer.reset();
20383 depthBuffer.reset();
20384 stencilBuffer.reset();
20385 }
20386 return {
20387 buffers: {
20388 color: colorBuffer,
20389 depth: depthBuffer,
20390 stencil: stencilBuffer
20391 },
20392 enable: enable,
20393 disable: disable,
20394 useProgram: useProgram,
20395 setBlending: setBlending,
20396 setMaterial: setMaterial,
20397 setFlipSided: setFlipSided,
20398 setCullFace: setCullFace,
20399 setLineWidth: setLineWidth,
20400 setPolygonOffset: setPolygonOffset,
20401 setScissorTest: setScissorTest,
20402 activeTexture: activeTexture,
20403 bindTexture: bindTexture,
20404 unbindTexture: unbindTexture,
20405 compressedTexImage2D: compressedTexImage2D,
20406 texImage2D: texImage2D,
20407 texImage3D: texImage3D,
20408 scissor: scissor,
20409 viewport: viewport,
20410 reset: reset
20411 };
20412 }
20413 function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) {
20414 const isWebGL2 = capabilities.isWebGL2;
20415 const maxTextures = capabilities.maxTextures;
20416 const maxCubemapSize = capabilities.maxCubemapSize;
20417 const maxTextureSize = capabilities.maxTextureSize;
20418 const maxSamples = capabilities.maxSamples;
20419 const _videoTextures = new WeakMap();
20420 let _canvas;
20421 let useOffscreenCanvas = false;
20422 try {
20423 useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined'
20424 && ( new OffscreenCanvas( 1, 1 ).getContext( "2d" ) ) !== null;
20425 } catch ( err ) {
20426 }
20427 function createCanvas( width, height ) {
20428 return useOffscreenCanvas ?
20429 new OffscreenCanvas( width, height ) :
20430 document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
20431 }
20432 function resizeImage( image, needsPowerOfTwo, needsNewCanvas, maxSize ) {
20433 let scale = 1;
20434 if ( image.width > maxSize || image.height > maxSize ) {
20435 scale = maxSize / Math.max( image.width, image.height );
20436 }
20437 if ( scale < 1 || needsPowerOfTwo === true ) {
20438 if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
20439 ( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
20440 ( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {
20441 const floor = needsPowerOfTwo ? MathUtils.floorPowerOfTwo : Math.floor;
20442 const width = floor( scale * image.width );
20443 const height = floor( scale * image.height );
20444 if ( _canvas === undefined ) _canvas = createCanvas( width, height );
20445 const canvas = needsNewCanvas ? createCanvas( width, height ) : _canvas;
20446 canvas.width = width;
20447 canvas.height = height;
20448 const context = canvas.getContext( '2d' );
20449 context.drawImage( image, 0, 0, width, height );
20450 console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').' );
20451 return canvas;
20452 } else {
20453 if ( 'data' in image ) {
20454 console.warn( 'THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').' );
20455 }
20456 return image;
20457 }
20458 }
20459 return image;
20460 }
20461 function isPowerOfTwo( image ) {
20462 return MathUtils.isPowerOfTwo( image.width ) && MathUtils.isPowerOfTwo( image.height );
20463 }
20464 function textureNeedsPowerOfTwo( texture ) {
20465 if ( isWebGL2 ) return false;
20466 return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||
20467 ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );
20468 }
20469 function textureNeedsGenerateMipmaps( texture, supportsMips ) {
20470 return texture.generateMipmaps && supportsMips &&
20471 texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;
20472 }
20473 function generateMipmap( target, texture, width, height ) {
20474 _gl.generateMipmap( target );
20475 const textureProperties = properties.get( texture );
20476 textureProperties.__maxMipLevel = Math.log( Math.max( width, height ) ) * Math.LOG2E;
20477 }
20478 function getInternalFormat( internalFormatName, glFormat, glType ) {
20479 if ( isWebGL2 === false ) return glFormat;
20480 if ( internalFormatName !== null ) {
20481 if ( _gl[ internalFormatName ] !== undefined ) return _gl[ internalFormatName ];
20482 console.warn( 'THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\'' );
20483 }
20484 let internalFormat = glFormat;
20485 if ( glFormat === 6403 ) {
20486 if ( glType === 5126 ) internalFormat = 33326;
20487 if ( glType === 5131 ) internalFormat = 33325;
20488 if ( glType === 5121 ) internalFormat = 33321;
20489 }
20490 if ( glFormat === 6407 ) {
20491 if ( glType === 5126 ) internalFormat = 34837;
20492 if ( glType === 5131 ) internalFormat = 34843;
20493 if ( glType === 5121 ) internalFormat = 32849;
20494 }
20495 if ( glFormat === 6408 ) {
20496 if ( glType === 5126 ) internalFormat = 34836;
20497 if ( glType === 5131 ) internalFormat = 34842;
20498 if ( glType === 5121 ) internalFormat = 32856;
20499 }
20500 if ( internalFormat === 33325 || internalFormat === 33326 ||
20501 internalFormat === 34842 || internalFormat === 34836 ) {
20502 extensions.get( 'EXT_color_buffer_float' );
20503 }
20504 return internalFormat;
20505 }
20506 function filterFallback( f ) {
20507 if ( f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter ) {
20508 return 9728;
20509 }
20510 return 9729;
20511 }
20512 function onTextureDispose( event ) {
20513 const texture = event.target;
20514 texture.removeEventListener( 'dispose', onTextureDispose );
20515 deallocateTexture( texture );
20516 if ( texture.isVideoTexture ) {
20517 _videoTextures.delete( texture );
20518 }
20519 info.memory.textures --;
20520 }
20521 function onRenderTargetDispose( event ) {
20522 const renderTarget = event.target;
20523 renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );
20524 deallocateRenderTarget( renderTarget );
20525 info.memory.textures --;
20526 }
20527 function deallocateTexture( texture ) {
20528 const textureProperties = properties.get( texture );
20529 if ( textureProperties.__webglInit === undefined ) return;
20530 _gl.deleteTexture( textureProperties.__webglTexture );
20531 properties.remove( texture );
20532 }
20533 function deallocateRenderTarget( renderTarget ) {
20534 const renderTargetProperties = properties.get( renderTarget );
20535 const textureProperties = properties.get( renderTarget.texture );
20536 if ( ! renderTarget ) return;
20537 if ( textureProperties.__webglTexture !== undefined ) {
20538 _gl.deleteTexture( textureProperties.__webglTexture );
20539 }
20540 if ( renderTarget.depthTexture ) {
20541 renderTarget.depthTexture.dispose();
20542 }
20543 if ( renderTarget.isWebGLCubeRenderTarget ) {
20544 for ( let i = 0; i < 6; i ++ ) {
20545 _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
20546 if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );
20547 }
20548 } else {
20549 _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
20550 if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );
20551 if ( renderTargetProperties.__webglMultisampledFramebuffer ) _gl.deleteFramebuffer( renderTargetProperties.__webglMultisampledFramebuffer );
20552 if ( renderTargetProperties.__webglColorRenderbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglColorRenderbuffer );
20553 if ( renderTargetProperties.__webglDepthRenderbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthRenderbuffer );
20554 }
20555 properties.remove( renderTarget.texture );
20556 properties.remove( renderTarget );
20557 }
20558 let textureUnits = 0;
20559 function resetTextureUnits() {
20560 textureUnits = 0;
20561 }
20562 function allocateTextureUnit() {
20563 const textureUnit = textureUnits;
20564 if ( textureUnit >= maxTextures ) {
20565 console.warn( 'THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures );
20566 }
20567 textureUnits += 1;
20568 return textureUnit;
20569 }
20570 function setTexture2D( texture, slot ) {
20571 const textureProperties = properties.get( texture );
20572 if ( texture.isVideoTexture ) updateVideoTexture( texture );
20573 if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
20574 const image = texture.image;
20575 if ( image === undefined ) {
20576 console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined' );
20577 } else if ( image.complete === false ) {
20578 console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete' );
20579 } else {
20580 uploadTexture( textureProperties, texture, slot );
20581 return;
20582 }
20583 }
20584 state.activeTexture( 33984 + slot );
20585 state.bindTexture( 3553, textureProperties.__webglTexture );
20586 }
20587 function setTexture2DArray( texture, slot ) {
20588 const textureProperties = properties.get( texture );
20589 if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
20590 uploadTexture( textureProperties, texture, slot );
20591 return;
20592 }
20593 state.activeTexture( 33984 + slot );
20594 state.bindTexture( 35866, textureProperties.__webglTexture );
20595 }
20596 function setTexture3D( texture, slot ) {
20597 const textureProperties = properties.get( texture );
20598 if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
20599 uploadTexture( textureProperties, texture, slot );
20600 return;
20601 }
20602 state.activeTexture( 33984 + slot );
20603 state.bindTexture( 32879, textureProperties.__webglTexture );
20604 }
20605 function setTextureCube( texture, slot ) {
20606 if ( texture.image.length !== 6 ) return;
20607 const textureProperties = properties.get( texture );
20608 if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
20609 initTexture( textureProperties, texture );
20610 state.activeTexture( 33984 + slot );
20611 state.bindTexture( 34067, textureProperties.__webglTexture );
20612 _gl.pixelStorei( 37440, texture.flipY );
20613 const isCompressed = ( texture && ( texture.isCompressedTexture || texture.image[ 0 ].isCompressedTexture ) );
20614 const isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );
20615 const cubeImage = [];
20616 for ( let i = 0; i < 6; i ++ ) {
20617 if ( ! isCompressed && ! isDataTexture ) {
20618 cubeImage[ i ] = resizeImage( texture.image[ i ], false, true, maxCubemapSize );
20619 } else {
20620 cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
20621 }
20622 }
20623 const image = cubeImage[ 0 ],
20624 supportsMips = isPowerOfTwo( image ) || isWebGL2,
20625 glFormat = utils.convert( texture.format ),
20626 glType = utils.convert( texture.type ),
20627 glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType );
20628 setTextureParameters( 34067, texture, supportsMips );
20629 let mipmaps;
20630 if ( isCompressed ) {
20631 for ( let i = 0; i < 6; i ++ ) {
20632 mipmaps = cubeImage[ i ].mipmaps;
20633 for ( let j = 0; j < mipmaps.length; j ++ ) {
20634 const mipmap = mipmaps[ j ];
20635 if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {
20636 if ( glFormat !== null ) {
20637 state.compressedTexImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data );
20638 } else {
20639 console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' );
20640 }
20641 } else {
20642 state.texImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
20643 }
20644 }
20645 }
20646 textureProperties.__maxMipLevel = mipmaps.length - 1;
20647 } else {
20648 mipmaps = texture.mipmaps;
20649 for ( let i = 0; i < 6; i ++ ) {
20650 if ( isDataTexture ) {
20651 state.texImage2D( 34069 + i, 0, glInternalFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );
20652 for ( let j = 0; j < mipmaps.length; j ++ ) {
20653 const mipmap = mipmaps[ j ];
20654 const mipmapImage = mipmap.image[ i ].image;
20655 state.texImage2D( 34069 + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data );
20656 }
20657 } else {
20658 state.texImage2D( 34069 + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] );
20659 for ( let j = 0; j < mipmaps.length; j ++ ) {
20660 const mipmap = mipmaps[ j ];
20661 state.texImage2D( 34069 + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[ i ] );
20662 }
20663 }
20664 }
20665 textureProperties.__maxMipLevel = mipmaps.length;
20666 }
20667 if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {
20668 generateMipmap( 34067, texture, image.width, image.height );
20669 }
20670 textureProperties.__version = texture.version;
20671 if ( texture.onUpdate ) texture.onUpdate( texture );
20672 } else {
20673 state.activeTexture( 33984 + slot );
20674 state.bindTexture( 34067, textureProperties.__webglTexture );
20675 }
20676 }
20677 function setTextureCubeDynamic( texture, slot ) {
20678 state.activeTexture( 33984 + slot );
20679 state.bindTexture( 34067, properties.get( texture ).__webglTexture );
20680 }
20681 const wrappingToGL = {
20682 [ RepeatWrapping ]: 10497,
20683 [ ClampToEdgeWrapping ]: 33071,
20684 [ MirroredRepeatWrapping ]: 33648
20685 };
20686 const filterToGL = {
20687 [ NearestFilter ]: 9728,
20688 [ NearestMipmapNearestFilter ]: 9984,
20689 [ NearestMipmapLinearFilter ]: 9986,
20690 [ LinearFilter ]: 9729,
20691 [ LinearMipmapNearestFilter ]: 9985,
20692 [ LinearMipmapLinearFilter ]: 9987
20693 };
20694 function setTextureParameters( textureType, texture, supportsMips ) {
20695 if ( supportsMips ) {
20696 _gl.texParameteri( textureType, 10242, wrappingToGL[ texture.wrapS ] );
20697 _gl.texParameteri( textureType, 10243, wrappingToGL[ texture.wrapT ] );
20698 if ( textureType === 32879 || textureType === 35866 ) {
20699 _gl.texParameteri( textureType, 32882, wrappingToGL[ texture.wrapR ] );
20700 }
20701 _gl.texParameteri( textureType, 10240, filterToGL[ texture.magFilter ] );
20702 _gl.texParameteri( textureType, 10241, filterToGL[ texture.minFilter ] );
20703 } else {
20704 _gl.texParameteri( textureType, 10242, 33071 );
20705 _gl.texParameteri( textureType, 10243, 33071 );
20706 if ( textureType === 32879 || textureType === 35866 ) {
20707 _gl.texParameteri( textureType, 32882, 33071 );
20708 }
20709 if ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {
20710 console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.' );
20711 }
20712 _gl.texParameteri( textureType, 10240, filterFallback( texture.magFilter ) );
20713 _gl.texParameteri( textureType, 10241, filterFallback( texture.minFilter ) );
20714 if ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {
20715 console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.' );
20716 }
20717 }
20718 const extension = extensions.get( 'EXT_texture_filter_anisotropic' );
20719 if ( extension ) {
20720 if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;
20721 if ( texture.type === HalfFloatType && ( isWebGL2 || extensions.get( 'OES_texture_half_float_linear' ) ) === null ) return;
20722 if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {
20723 _gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );
20724 properties.get( texture ).__currentAnisotropy = texture.anisotropy;
20725 }
20726 }
20727 }
20728 function initTexture( textureProperties, texture ) {
20729 if ( textureProperties.__webglInit === undefined ) {
20730 textureProperties.__webglInit = true;
20731 texture.addEventListener( 'dispose', onTextureDispose );
20732 textureProperties.__webglTexture = _gl.createTexture();
20733 info.memory.textures ++;
20734 }
20735 }
20736 function uploadTexture( textureProperties, texture, slot ) {
20737 let textureType = 3553;
20738 if ( texture.isDataTexture2DArray ) textureType = 35866;
20739 if ( texture.isDataTexture3D ) textureType = 32879;
20740 initTexture( textureProperties, texture );
20741 state.activeTexture( 33984 + slot );
20742 state.bindTexture( textureType, textureProperties.__webglTexture );
20743 _gl.pixelStorei( 37440, texture.flipY );
20744 _gl.pixelStorei( 37441, texture.premultiplyAlpha );
20745 _gl.pixelStorei( 3317, texture.unpackAlignment );
20746 const needsPowerOfTwo = textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false;
20747 const image = resizeImage( texture.image, needsPowerOfTwo, false, maxTextureSize );
20748 const supportsMips = isPowerOfTwo( image ) || isWebGL2,
20749 glFormat = utils.convert( texture.format );
20750 let glType = utils.convert( texture.type ),
20751 glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType );
20752 setTextureParameters( textureType, texture, supportsMips );
20753 let mipmap;
20754 const mipmaps = texture.mipmaps;
20755 if ( texture.isDepthTexture ) {
20756 glInternalFormat = 6402;
20757 if ( isWebGL2 ) {
20758 if ( texture.type === FloatType ) {
20759 glInternalFormat = 36012;
20760 } else if ( texture.type === UnsignedIntType ) {
20761 glInternalFormat = 33190;
20762 } else if ( texture.type === UnsignedInt248Type ) {
20763 glInternalFormat = 35056;
20764 } else {
20765 glInternalFormat = 33189;
20766 }
20767 } else {
20768 if ( texture.type === FloatType ) {
20769 console.error( 'WebGLRenderer: Floating point depth texture requires WebGL2.' );
20770 }
20771 }
20772 if ( texture.format === DepthFormat && glInternalFormat === 6402 ) {
20773 if ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {
20774 console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );
20775 texture.type = UnsignedShortType;
20776 glType = utils.convert( texture.type );
20777 }
20778 }
20779 if ( texture.format === DepthStencilFormat && glInternalFormat === 6402 ) {
20780 glInternalFormat = 34041;
20781 if ( texture.type !== UnsignedInt248Type ) {
20782 console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );
20783 texture.type = UnsignedInt248Type;
20784 glType = utils.convert( texture.type );
20785 }
20786 }
20787 state.texImage2D( 3553, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null );
20788 } else if ( texture.isDataTexture ) {
20789 if ( mipmaps.length > 0 && supportsMips ) {
20790 for ( let i = 0, il = mipmaps.length; i < il; i ++ ) {
20791 mipmap = mipmaps[ i ];
20792 state.texImage2D( 3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
20793 }
20794 texture.generateMipmaps = false;
20795 textureProperties.__maxMipLevel = mipmaps.length - 1;
20796 } else {
20797 state.texImage2D( 3553, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data );
20798 textureProperties.__maxMipLevel = 0;
20799 }
20800 } else if ( texture.isCompressedTexture ) {
20801 for ( let i = 0, il = mipmaps.length; i < il; i ++ ) {
20802 mipmap = mipmaps[ i ];
20803 if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {
20804 if ( glFormat !== null ) {
20805 state.compressedTexImage2D( 3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data );
20806 } else {
20807 console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' );
20808 }
20809 } else {
20810 state.texImage2D( 3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
20811 }
20812 }
20813 textureProperties.__maxMipLevel = mipmaps.length - 1;
20814 } else if ( texture.isDataTexture2DArray ) {
20815 state.texImage3D( 35866, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data );
20816 textureProperties.__maxMipLevel = 0;
20817 } else if ( texture.isDataTexture3D ) {
20818 state.texImage3D( 32879, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data );
20819 textureProperties.__maxMipLevel = 0;
20820 } else {
20821 if ( mipmaps.length > 0 && supportsMips ) {
20822 for ( let i = 0, il = mipmaps.length; i < il; i ++ ) {
20823 mipmap = mipmaps[ i ];
20824 state.texImage2D( 3553, i, glInternalFormat, glFormat, glType, mipmap );
20825 }
20826 texture.generateMipmaps = false;
20827 textureProperties.__maxMipLevel = mipmaps.length - 1;
20828 } else {
20829 state.texImage2D( 3553, 0, glInternalFormat, glFormat, glType, image );
20830 textureProperties.__maxMipLevel = 0;
20831 }
20832 }
20833 if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {
20834 generateMipmap( textureType, texture, image.width, image.height );
20835 }
20836 textureProperties.__version = texture.version;
20837 if ( texture.onUpdate ) texture.onUpdate( texture );
20838 }
20839 function setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {
20840 const glFormat = utils.convert( renderTarget.texture.format );
20841 const glType = utils.convert( renderTarget.texture.type );
20842 const glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType );
20843 state.texImage2D( textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
20844 _gl.bindFramebuffer( 36160, framebuffer );
20845 _gl.framebufferTexture2D( 36160, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
20846 _gl.bindFramebuffer( 36160, null );
20847 }
20848 function setupRenderBufferStorage( renderbuffer, renderTarget, isMultisample ) {
20849 _gl.bindRenderbuffer( 36161, renderbuffer );
20850 if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
20851 let glInternalFormat = 33189;
20852 if ( isMultisample ) {
20853 const depthTexture = renderTarget.depthTexture;
20854 if ( depthTexture && depthTexture.isDepthTexture ) {
20855 if ( depthTexture.type === FloatType ) {
20856 glInternalFormat = 36012;
20857 } else if ( depthTexture.type === UnsignedIntType ) {
20858 glInternalFormat = 33190;
20859 }
20860 }
20861 const samples = getRenderTargetSamples( renderTarget );
20862 _gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height );
20863 } else {
20864 _gl.renderbufferStorage( 36161, glInternalFormat, renderTarget.width, renderTarget.height );
20865 }
20866 _gl.framebufferRenderbuffer( 36160, 36096, 36161, renderbuffer );
20867 } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
20868 if ( isMultisample ) {
20869 const samples = getRenderTargetSamples( renderTarget );
20870 _gl.renderbufferStorageMultisample( 36161, samples, 35056, renderTarget.width, renderTarget.height );
20871 } else {
20872 _gl.renderbufferStorage( 36161, 34041, renderTarget.width, renderTarget.height );
20873 }
20874 _gl.framebufferRenderbuffer( 36160, 33306, 36161, renderbuffer );
20875 } else {
20876 const glFormat = utils.convert( renderTarget.texture.format );
20877 const glType = utils.convert( renderTarget.texture.type );
20878 const glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType );
20879 if ( isMultisample ) {
20880 const samples = getRenderTargetSamples( renderTarget );
20881 _gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height );
20882 } else {
20883 _gl.renderbufferStorage( 36161, glInternalFormat, renderTarget.width, renderTarget.height );
20884 }
20885 }
20886 _gl.bindRenderbuffer( 36161, null );
20887 }
20888 function setupDepthTexture( framebuffer, renderTarget ) {
20889 const isCube = ( renderTarget && renderTarget.isWebGLCubeRenderTarget );
20890 if ( isCube ) throw new Error( 'Depth Texture with cube render targets is not supported' );
20891 _gl.bindFramebuffer( 36160, framebuffer );
20892 if ( ! ( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {
20893 throw new Error( 'renderTarget.depthTexture must be an instance of THREE.DepthTexture' );
20894 }
20895 if ( ! properties.get( renderTarget.depthTexture ).__webglTexture ||
20896 renderTarget.depthTexture.image.width !== renderTarget.width ||
20897 renderTarget.depthTexture.image.height !== renderTarget.height ) {
20898 renderTarget.depthTexture.image.width = renderTarget.width;
20899 renderTarget.depthTexture.image.height = renderTarget.height;
20900 renderTarget.depthTexture.needsUpdate = true;
20901 }
20902 setTexture2D( renderTarget.depthTexture, 0 );
20903 const webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;
20904 if ( renderTarget.depthTexture.format === DepthFormat ) {
20905 _gl.framebufferTexture2D( 36160, 36096, 3553, webglDepthTexture, 0 );
20906 } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
20907 _gl.framebufferTexture2D( 36160, 33306, 3553, webglDepthTexture, 0 );
20908 } else {
20909 throw new Error( 'Unknown depthTexture format' );
20910 }
20911 }
20912 function setupDepthRenderbuffer( renderTarget ) {
20913 const renderTargetProperties = properties.get( renderTarget );
20914 const isCube = ( renderTarget.isWebGLCubeRenderTarget === true );
20915 if ( renderTarget.depthTexture ) {
20916 if ( isCube ) throw new Error( 'target.depthTexture not supported in Cube render targets' );
20917 setupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );
20918 } else {
20919 if ( isCube ) {
20920 renderTargetProperties.__webglDepthbuffer = [];
20921 for ( let i = 0; i < 6; i ++ ) {
20922 _gl.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer[ i ] );
20923 renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
20924 setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget, false );
20925 }
20926 } else {
20927 _gl.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer );
20928 renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
20929 setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget, false );
20930 }
20931 }
20932 _gl.bindFramebuffer( 36160, null );
20933 }
20934 function setupRenderTarget( renderTarget ) {
20935 const renderTargetProperties = properties.get( renderTarget );
20936 const textureProperties = properties.get( renderTarget.texture );
20937 renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
20938 textureProperties.__webglTexture = _gl.createTexture();
20939 info.memory.textures ++;
20940 const isCube = ( renderTarget.isWebGLCubeRenderTarget === true );
20941 const isMultisample = ( renderTarget.isWebGLMultisampleRenderTarget === true );
20942 const supportsMips = isPowerOfTwo( renderTarget ) || isWebGL2;
20943 if ( isWebGL2 && renderTarget.texture.format === RGBFormat && ( renderTarget.texture.type === FloatType || renderTarget.texture.type === HalfFloatType ) ) {
20944 renderTarget.texture.format = RGBAFormat;
20945 console.warn( 'THREE.WebGLRenderer: Rendering to textures with RGB format is not supported. Using RGBA format instead.' );
20946 }
20947 if ( isCube ) {
20948 renderTargetProperties.__webglFramebuffer = [];
20949 for ( let i = 0; i < 6; i ++ ) {
20950 renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
20951 }
20952 } else {
20953 renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
20954 if ( isMultisample ) {
20955 if ( isWebGL2 ) {
20956 renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer();
20957 renderTargetProperties.__webglColorRenderbuffer = _gl.createRenderbuffer();
20958 _gl.bindRenderbuffer( 36161, renderTargetProperties.__webglColorRenderbuffer );
20959 const glFormat = utils.convert( renderTarget.texture.format );
20960 const glType = utils.convert( renderTarget.texture.type );
20961 const glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType );
20962 const samples = getRenderTargetSamples( renderTarget );
20963 _gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height );
20964 _gl.bindFramebuffer( 36160, renderTargetProperties.__webglMultisampledFramebuffer );
20965 _gl.framebufferRenderbuffer( 36160, 36064, 36161, renderTargetProperties.__webglColorRenderbuffer );
20966 _gl.bindRenderbuffer( 36161, null );
20967 if ( renderTarget.depthBuffer ) {
20968 renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer();
20969 setupRenderBufferStorage( renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true );
20970 }
20971 _gl.bindFramebuffer( 36160, null );
20972 } else {
20973 console.warn( 'THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.' );
20974 }
20975 }
20976 }
20977 if ( isCube ) {
20978 state.bindTexture( 34067, textureProperties.__webglTexture );
20979 setTextureParameters( 34067, renderTarget.texture, supportsMips );
20980 for ( let i = 0; i < 6; i ++ ) {
20981 setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, 36064, 34069 + i );
20982 }
20983 if ( textureNeedsGenerateMipmaps( renderTarget.texture, supportsMips ) ) {
20984 generateMipmap( 34067, renderTarget.texture, renderTarget.width, renderTarget.height );
20985 }
20986 state.bindTexture( 34067, null );
20987 } else {
20988 state.bindTexture( 3553, textureProperties.__webglTexture );
20989 setTextureParameters( 3553, renderTarget.texture, supportsMips );
20990 setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, 36064, 3553 );
20991 if ( textureNeedsGenerateMipmaps( renderTarget.texture, supportsMips ) ) {
20992 generateMipmap( 3553, renderTarget.texture, renderTarget.width, renderTarget.height );
20993 }
20994 state.bindTexture( 3553, null );
20995 }
20996 if ( renderTarget.depthBuffer ) {
20997 setupDepthRenderbuffer( renderTarget );
20998 }
20999 }
21000 function updateRenderTargetMipmap( renderTarget ) {
21001 const texture = renderTarget.texture;
21002 const supportsMips = isPowerOfTwo( renderTarget ) || isWebGL2;
21003 if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {
21004 const target = renderTarget.isWebGLCubeRenderTarget ? 34067 : 3553;
21005 const webglTexture = properties.get( texture ).__webglTexture;
21006 state.bindTexture( target, webglTexture );
21007 generateMipmap( target, texture, renderTarget.width, renderTarget.height );
21008 state.bindTexture( target, null );
21009 }
21010 }
21011 function updateMultisampleRenderTarget( renderTarget ) {
21012 if ( renderTarget.isWebGLMultisampleRenderTarget ) {
21013 if ( isWebGL2 ) {
21014 const renderTargetProperties = properties.get( renderTarget );
21015 _gl.bindFramebuffer( 36008, renderTargetProperties.__webglMultisampledFramebuffer );
21016 _gl.bindFramebuffer( 36009, renderTargetProperties.__webglFramebuffer );
21017 const width = renderTarget.width;
21018 const height = renderTarget.height;
21019 let mask = 16384;
21020 if ( renderTarget.depthBuffer ) mask |= 256;
21021 if ( renderTarget.stencilBuffer ) mask |= 1024;
21022 _gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, mask, 9728 );
21023 _gl.bindFramebuffer( 36160, renderTargetProperties.__webglMultisampledFramebuffer );
21024 } else {
21025 console.warn( 'THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.' );
21026 }
21027 }
21028 }
21029 function getRenderTargetSamples( renderTarget ) {
21030 return ( isWebGL2 && renderTarget.isWebGLMultisampleRenderTarget ) ?
21031 Math.min( maxSamples, renderTarget.samples ) : 0;
21032 }
21033 function updateVideoTexture( texture ) {
21034 const frame = info.render.frame;
21035 if ( _videoTextures.get( texture ) !== frame ) {
21036 _videoTextures.set( texture, frame );
21037 texture.update();
21038 }
21039 }
21040 let warnedTexture2D = false;
21041 let warnedTextureCube = false;
21042 function safeSetTexture2D( texture, slot ) {
21043 if ( texture && texture.isWebGLRenderTarget ) {
21044 if ( warnedTexture2D === false ) {
21045 console.warn( "THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead." );
21046 warnedTexture2D = true;
21047 }
21048 texture = texture.texture;
21049 }
21050 setTexture2D( texture, slot );
21051 }
21052 function safeSetTextureCube( texture, slot ) {
21053 if ( texture && texture.isWebGLCubeRenderTarget ) {
21054 if ( warnedTextureCube === false ) {
21055 console.warn( "THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead." );
21056 warnedTextureCube = true;
21057 }
21058 texture = texture.texture;
21059 }
21060 if ( ( texture && texture.isCubeTexture ) ||
21061 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
21062 setTextureCube( texture, slot );
21063 } else {
21064 setTextureCubeDynamic( texture, slot );
21065 }
21066 }
21067 this.allocateTextureUnit = allocateTextureUnit;
21068 this.resetTextureUnits = resetTextureUnits;
21069 this.setTexture2D = setTexture2D;
21070 this.setTexture2DArray = setTexture2DArray;
21071 this.setTexture3D = setTexture3D;
21072 this.setTextureCube = setTextureCube;
21073 this.setTextureCubeDynamic = setTextureCubeDynamic;
21074 this.setupRenderTarget = setupRenderTarget;
21075 this.updateRenderTargetMipmap = updateRenderTargetMipmap;
21076 this.updateMultisampleRenderTarget = updateMultisampleRenderTarget;
21077 this.safeSetTexture2D = safeSetTexture2D;
21078 this.safeSetTextureCube = safeSetTextureCube;
21079 }
21080 function WebGLUtils( gl, extensions, capabilities ) {
21081 const isWebGL2 = capabilities.isWebGL2;
21082 function convert( p ) {
21083 let extension;
21084 if ( p === UnsignedByteType ) return 5121;
21085 if ( p === UnsignedShort4444Type ) return 32819;
21086 if ( p === UnsignedShort5551Type ) return 32820;
21087 if ( p === UnsignedShort565Type ) return 33635;
21088 if ( p === ByteType ) return 5120;
21089 if ( p === ShortType ) return 5122;
21090 if ( p === UnsignedShortType ) return 5123;
21091 if ( p === IntType ) return 5124;
21092 if ( p === UnsignedIntType ) return 5125;
21093 if ( p === FloatType ) return 5126;
21094 if ( p === HalfFloatType ) {
21095 if ( isWebGL2 ) return 5131;
21096 extension = extensions.get( 'OES_texture_half_float' );
21097 if ( extension !== null ) {
21098 return extension.HALF_FLOAT_OES;
21099 } else {
21100 return null;
21101 }
21102 }
21103 if ( p === AlphaFormat ) return 6406;
21104 if ( p === RGBFormat ) return 6407;
21105 if ( p === RGBAFormat ) return 6408;
21106 if ( p === LuminanceFormat ) return 6409;
21107 if ( p === LuminanceAlphaFormat ) return 6410;
21108 if ( p === DepthFormat ) return 6402;
21109 if ( p === DepthStencilFormat ) return 34041;
21110 if ( p === RedFormat ) return 6403;
21111 if ( p === RedIntegerFormat ) return 36244;
21112 if ( p === RGFormat ) return 33319;
21113 if ( p === RGIntegerFormat ) return 33320;
21114 if ( p === RGBIntegerFormat ) return 36248;
21115 if ( p === RGBAIntegerFormat ) return 36249;
21116 if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||
21117 p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {
21118 extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
21119 if ( extension !== null ) {
21120 if ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;
21121 if ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;
21122 if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;
21123 if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;
21124 } else {
21125 return null;
21126 }
21127 }
21128 if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||
21129 p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {
21130 extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );
21131 if ( extension !== null ) {
21132 if ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
21133 if ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
21134 if ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
21135 if ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
21136 } else {
21137 return null;
21138 }
21139 }
21140 if ( p === RGB_ETC1_Format ) {
21141 extension = extensions.get( 'WEBGL_compressed_texture_etc1' );
21142 if ( extension !== null ) {
21143 return extension.COMPRESSED_RGB_ETC1_WEBGL;
21144 } else {
21145 return null;
21146 }
21147 }
21148 if ( p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format ) {
21149 extension = extensions.get( 'WEBGL_compressed_texture_etc' );
21150 if ( extension !== null ) {
21151 if ( p === RGB_ETC2_Format ) return extension.COMPRESSED_RGB8_ETC2;
21152 if ( p === RGBA_ETC2_EAC_Format ) return extension.COMPRESSED_RGBA8_ETC2_EAC;
21153 }
21154 }
21155 if ( p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format ||
21156 p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format ||
21157 p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format ||
21158 p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format ||
21159 p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format ||
21160 p === SRGB8_ALPHA8_ASTC_4x4_Format || p === SRGB8_ALPHA8_ASTC_5x4_Format || p === SRGB8_ALPHA8_ASTC_5x5_Format ||
21161 p === SRGB8_ALPHA8_ASTC_6x5_Format || p === SRGB8_ALPHA8_ASTC_6x6_Format || p === SRGB8_ALPHA8_ASTC_8x5_Format ||
21162 p === SRGB8_ALPHA8_ASTC_8x6_Format || p === SRGB8_ALPHA8_ASTC_8x8_Format || p === SRGB8_ALPHA8_ASTC_10x5_Format ||
21163 p === SRGB8_ALPHA8_ASTC_10x6_Format || p === SRGB8_ALPHA8_ASTC_10x8_Format || p === SRGB8_ALPHA8_ASTC_10x10_Format ||
21164 p === SRGB8_ALPHA8_ASTC_12x10_Format || p === SRGB8_ALPHA8_ASTC_12x12_Format ) {
21165 extension = extensions.get( 'WEBGL_compressed_texture_astc' );
21166 if ( extension !== null ) {
21167 return p;
21168 } else {
21169 return null;
21170 }
21171 }
21172 if ( p === RGBA_BPTC_Format ) {
21173 extension = extensions.get( 'EXT_texture_compression_bptc' );
21174 if ( extension !== null ) {
21175 return p;
21176 } else {
21177 return null;
21178 }
21179 }
21180 if ( p === UnsignedInt248Type ) {
21181 if ( isWebGL2 ) return 34042;
21182 extension = extensions.get( 'WEBGL_depth_texture' );
21183 if ( extension !== null ) {
21184 return extension.UNSIGNED_INT_24_8_WEBGL;
21185 } else {
21186 return null;
21187 }
21188 }
21189 }
21190 return { convert: convert };
21191 }
21192 function ArrayCamera( array ) {
21193 PerspectiveCamera.call( this );
21194 this.cameras = array || [];
21195 }
21196 ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototype ), {
21197 constructor: ArrayCamera,
21198 isArrayCamera: true
21199 } );
21200 function Group() {
21201 Object3D.call( this );
21202 this.type = 'Group';
21203 }
21204 Group.prototype = Object.assign( Object.create( Object3D.prototype ), {
21205 constructor: Group,
21206 isGroup: true
21207 } );
21208 function WebXRController() {
21209 this._targetRay = null;
21210 this._grip = null;
21211 this._hand = null;
21212 }
21213 Object.assign( WebXRController.prototype, {
21214 constructor: WebXRController,
21215 getHandSpace: function () {
21216 if ( this._hand === null ) {
21217 this._hand = new Group();
21218 this._hand.matrixAutoUpdate = false;
21219 this._hand.visible = false;
21220 this._hand.joints = [];
21221 this._hand.inputState = { pinching: false };
21222 if ( window.XRHand ) {
21223 for ( let i = 0; i <= window.XRHand.LITTLE_PHALANX_TIP; i ++ ) {
21224 const joint = new Group();
21225 joint.matrixAutoUpdate = false;
21226 joint.visible = false;
21227 this._hand.joints.push( joint );
21228 this._hand.add( joint );
21229 }
21230 }
21231 }
21232 return this._hand;
21233 },
21234 getTargetRaySpace: function () {
21235 if ( this._targetRay === null ) {
21236 this._targetRay = new Group();
21237 this._targetRay.matrixAutoUpdate = false;
21238 this._targetRay.visible = false;
21239 }
21240 return this._targetRay;
21241 },
21242 getGripSpace: function () {
21243 if ( this._grip === null ) {
21244 this._grip = new Group();
21245 this._grip.matrixAutoUpdate = false;
21246 this._grip.visible = false;
21247 }
21248 return this._grip;
21249 },
21250 dispatchEvent: function ( event ) {
21251 if ( this._targetRay !== null ) {
21252 this._targetRay.dispatchEvent( event );
21253 }
21254 if ( this._grip !== null ) {
21255 this._grip.dispatchEvent( event );
21256 }
21257 if ( this._hand !== null ) {
21258 this._hand.dispatchEvent( event );
21259 }
21260 return this;
21261 },
21262 disconnect: function ( inputSource ) {
21263 this.dispatchEvent( { type: 'disconnected', data: inputSource } );
21264 if ( this._targetRay !== null ) {
21265 this._targetRay.visible = false;
21266 }
21267 if ( this._grip !== null ) {
21268 this._grip.visible = false;
21269 }
21270 if ( this._hand !== null ) {
21271 this._hand.visible = false;
21272 }
21273 return this;
21274 },
21275 update: function ( inputSource, frame, referenceSpace ) {
21276 let inputPose = null;
21277 let gripPose = null;
21278 let handPose = null;
21279 const targetRay = this._targetRay;
21280 const grip = this._grip;
21281 const hand = this._hand;
21282 if ( inputSource ) {
21283 if ( hand && inputSource.hand ) {
21284 handPose = true;
21285 for ( let i = 0; i <= window.XRHand.LITTLE_PHALANX_TIP; i ++ ) {
21286 if ( inputSource.hand[ i ] ) {
21287 const jointPose = frame.getJointPose( inputSource.hand[ i ], referenceSpace );
21288 const joint = hand.joints[ i ];
21289 if ( jointPose !== null ) {
21290 joint.matrix.fromArray( jointPose.transform.matrix );
21291 joint.matrix.decompose( joint.position, joint.rotation, joint.scale );
21292 joint.jointRadius = jointPose.radius;
21293 }
21294 joint.visible = jointPose !== null;
21295 const indexTip = hand.joints[ window.XRHand.INDEX_PHALANX_TIP ];
21296 const thumbTip = hand.joints[ window.XRHand.THUMB_PHALANX_TIP ];
21297 const distance = indexTip.position.distanceTo( thumbTip.position );
21298 const distanceToPinch = 0.02;
21299 const threshold = 0.005;
21300 if ( hand.inputState.pinching && distance > distanceToPinch + threshold ) {
21301 hand.inputState.pinching = false;
21302 this.dispatchEvent( {
21303 type: "pinchend",
21304 handedness: inputSource.handedness,
21305 target: this
21306 } );
21307 } else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) {
21308 hand.inputState.pinching = true;
21309 this.dispatchEvent( {
21310 type: "pinchstart",
21311 handedness: inputSource.handedness,
21312 target: this
21313 } );
21314 }
21315 }
21316 }
21317 } else {
21318 if ( targetRay !== null ) {
21319 inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace );
21320 if ( inputPose !== null ) {
21321 targetRay.matrix.fromArray( inputPose.transform.matrix );
21322 targetRay.matrix.decompose( targetRay.position, targetRay.rotation, targetRay.scale );
21323 }
21324 }
21325 if ( grip !== null && inputSource.gripSpace ) {
21326 gripPose = frame.getPose( inputSource.gripSpace, referenceSpace );
21327 if ( gripPose !== null ) {
21328 grip.matrix.fromArray( gripPose.transform.matrix );
21329 grip.matrix.decompose( grip.position, grip.rotation, grip.scale );
21330 }
21331 }
21332 }
21333 }
21334 if ( targetRay !== null ) {
21335 targetRay.visible = ( inputPose !== null );
21336 }
21337 if ( grip !== null ) {
21338 grip.visible = ( gripPose !== null );
21339 }
21340 if ( hand !== null ) {
21341 hand.visible = ( handPose !== null );
21342 }
21343 return this;
21344 }
21345 } );
21346 function WebXRManager( renderer, gl ) {
21347 const scope = this;
21348 let session = null;
21349 let framebufferScaleFactor = 1.0;
21350 let referenceSpace = null;
21351 let referenceSpaceType = 'local-floor';
21352 let pose = null;
21353 const controllers = [];
21354 const inputSourcesMap = new Map();
21355 const cameraL = new PerspectiveCamera();
21356 cameraL.layers.enable( 1 );
21357 cameraL.viewport = new Vector4();
21358 const cameraR = new PerspectiveCamera();
21359 cameraR.layers.enable( 2 );
21360 cameraR.viewport = new Vector4();
21361 const cameras = [ cameraL, cameraR ];
21362 const cameraVR = new ArrayCamera();
21363 cameraVR.layers.enable( 1 );
21364 cameraVR.layers.enable( 2 );
21365 let _currentDepthNear = null;
21366 let _currentDepthFar = null;
21367 this.enabled = false;
21368 this.isPresenting = false;
21369 this.getController = function ( index ) {
21370 let controller = controllers[ index ];
21371 if ( controller === undefined ) {
21372 controller = new WebXRController();
21373 controllers[ index ] = controller;
21374 }
21375 return controller.getTargetRaySpace();
21376 };
21377 this.getControllerGrip = function ( index ) {
21378 let controller = controllers[ index ];
21379 if ( controller === undefined ) {
21380 controller = new WebXRController();
21381 controllers[ index ] = controller;
21382 }
21383 return controller.getGripSpace();
21384 };
21385 this.getHand = function ( index ) {
21386 let controller = controllers[ index ];
21387 if ( controller === undefined ) {
21388 controller = new WebXRController();
21389 controllers[ index ] = controller;
21390 }
21391 return controller.getHandSpace();
21392 };
21393 function onSessionEvent( event ) {
21394 const controller = inputSourcesMap.get( event.inputSource );
21395 if ( controller ) {
21396 controller.dispatchEvent( { type: event.type } );
21397 }
21398 }
21399 function onSessionEnd() {
21400 inputSourcesMap.forEach( function ( controller, inputSource ) {
21401 controller.disconnect( inputSource );
21402 } );
21403 inputSourcesMap.clear();
21404 renderer.setFramebuffer( null );
21405 renderer.setRenderTarget( renderer.getRenderTarget() );
21406 animation.stop();
21407 scope.isPresenting = false;
21408 scope.dispatchEvent( { type: 'sessionend' } );
21409 }
21410 function onRequestReferenceSpace( value ) {
21411 referenceSpace = value;
21412 animation.setContext( session );
21413 animation.start();
21414 scope.isPresenting = true;
21415 scope.dispatchEvent( { type: 'sessionstart' } );
21416 }
21417 this.setFramebufferScaleFactor = function ( value ) {
21418 framebufferScaleFactor = value;
21419 if ( scope.isPresenting === true ) {
21420 console.warn( 'THREE.WebXRManager: Cannot change framebuffer scale while presenting.' );
21421 }
21422 };
21423 this.setReferenceSpaceType = function ( value ) {
21424 referenceSpaceType = value;
21425 if ( scope.isPresenting === true ) {
21426 console.warn( 'THREE.WebXRManager: Cannot change reference space type while presenting.' );
21427 }
21428 };
21429 this.getReferenceSpace = function () {
21430 return referenceSpace;
21431 };
21432 this.getSession = function () {
21433 return session;
21434 };
21435 this.setSession = function ( value ) {
21436 session = value;
21437 if ( session !== null ) {
21438 session.addEventListener( 'select', onSessionEvent );
21439 session.addEventListener( 'selectstart', onSessionEvent );
21440 session.addEventListener( 'selectend', onSessionEvent );
21441 session.addEventListener( 'squeeze', onSessionEvent );
21442 session.addEventListener( 'squeezestart', onSessionEvent );
21443 session.addEventListener( 'squeezeend', onSessionEvent );
21444 session.addEventListener( 'end', onSessionEnd );
21445 const attributes = gl.getContextAttributes();
21446 if ( attributes.xrCompatible !== true ) {
21447 gl.makeXRCompatible();
21448 }
21449 const layerInit = {
21450 antialias: attributes.antialias,
21451 alpha: attributes.alpha,
21452 depth: attributes.depth,
21453 stencil: attributes.stencil,
21454 framebufferScaleFactor: framebufferScaleFactor
21455 };
21456 const baseLayer = new XRWebGLLayer( session, gl, layerInit );
21457 session.updateRenderState( { baseLayer: baseLayer } );
21458 session.requestReferenceSpace( referenceSpaceType ).then( onRequestReferenceSpace );
21459 session.addEventListener( 'inputsourceschange', updateInputSources );
21460 }
21461 };
21462 function updateInputSources( event ) {
21463 const inputSources = session.inputSources;
21464 for ( let i = 0; i < controllers.length; i ++ ) {
21465 inputSourcesMap.set( inputSources[ i ], controllers[ i ] );
21466 }
21467 for ( let i = 0; i < event.removed.length; i ++ ) {
21468 const inputSource = event.removed[ i ];
21469 const controller = inputSourcesMap.get( inputSource );
21470 if ( controller ) {
21471 controller.dispatchEvent( { type: 'disconnected', data: inputSource } );
21472 inputSourcesMap.delete( inputSource );
21473 }
21474 }
21475 for ( let i = 0; i < event.added.length; i ++ ) {
21476 const inputSource = event.added[ i ];
21477 const controller = inputSourcesMap.get( inputSource );
21478 if ( controller ) {
21479 controller.dispatchEvent( { type: 'connected', data: inputSource } );
21480 }
21481 }
21482 }
21483 const cameraLPos = new Vector3();
21484 const cameraRPos = new Vector3();
21485 function setProjectionFromUnion( camera, cameraL, cameraR ) {
21486 cameraLPos.setFromMatrixPosition( cameraL.matrixWorld );
21487 cameraRPos.setFromMatrixPosition( cameraR.matrixWorld );
21488 const ipd = cameraLPos.distanceTo( cameraRPos );
21489 const projL = cameraL.projectionMatrix.elements;
21490 const projR = cameraR.projectionMatrix.elements;
21491 const near = projL[ 14 ] / ( projL[ 10 ] - 1 );
21492 const far = projL[ 14 ] / ( projL[ 10 ] + 1 );
21493 const topFov = ( projL[ 9 ] + 1 ) / projL[ 5 ];
21494 const bottomFov = ( projL[ 9 ] - 1 ) / projL[ 5 ];
21495 const leftFov = ( projL[ 8 ] - 1 ) / projL[ 0 ];
21496 const rightFov = ( projR[ 8 ] + 1 ) / projR[ 0 ];
21497 const left = near * leftFov;
21498 const right = near * rightFov;
21499 const zOffset = ipd / ( - leftFov + rightFov );
21500 const xOffset = zOffset * - leftFov;
21501 cameraL.matrixWorld.decompose( camera.position, camera.quaternion, camera.scale );
21502 camera.translateX( xOffset );
21503 camera.translateZ( zOffset );
21504 camera.matrixWorld.compose( camera.position, camera.quaternion, camera.scale );
21505 camera.matrixWorldInverse.getInverse( camera.matrixWorld );
21506 const near2 = near + zOffset;
21507 const far2 = far + zOffset;
21508 const left2 = left - xOffset;
21509 const right2 = right + ( ipd - xOffset );
21510 const top2 = topFov * far / far2 * near2;
21511 const bottom2 = bottomFov * far / far2 * near2;
21512 camera.projectionMatrix.makePerspective( left2, right2, top2, bottom2, near2, far2 );
21513 }
21514 function updateCamera( camera, parent ) {
21515 if ( parent === null ) {
21516 camera.matrixWorld.copy( camera.matrix );
21517 } else {
21518 camera.matrixWorld.multiplyMatrices( parent.matrixWorld, camera.matrix );
21519 }
21520 camera.matrixWorldInverse.getInverse( camera.matrixWorld );
21521 }
21522 this.getCamera = function ( camera ) {
21523 cameraVR.near = cameraR.near = cameraL.near = camera.near;
21524 cameraVR.far = cameraR.far = cameraL.far = camera.far;
21525 if ( _currentDepthNear !== cameraVR.near || _currentDepthFar !== cameraVR.far ) {
21526 session.updateRenderState( {
21527 depthNear: cameraVR.near,
21528 depthFar: cameraVR.far
21529 } );
21530 _currentDepthNear = cameraVR.near;
21531 _currentDepthFar = cameraVR.far;
21532 }
21533 const parent = camera.parent;
21534 const cameras = cameraVR.cameras;
21535 updateCamera( cameraVR, parent );
21536 for ( let i = 0; i < cameras.length; i ++ ) {
21537 updateCamera( cameras[ i ], parent );
21538 }
21539 camera.matrixWorld.copy( cameraVR.matrixWorld );
21540 const children = camera.children;
21541 for ( let i = 0, l = children.length; i < l; i ++ ) {
21542 children[ i ].updateMatrixWorld( true );
21543 }
21544 if ( cameras.length === 2 ) {
21545 setProjectionFromUnion( cameraVR, cameraL, cameraR );
21546 } else {
21547 cameraVR.projectionMatrix.copy( cameraL.projectionMatrix );
21548 }
21549 return cameraVR;
21550 };
21551 let onAnimationFrameCallback = null;
21552 function onAnimationFrame( time, frame ) {
21553 pose = frame.getViewerPose( referenceSpace );
21554 if ( pose !== null ) {
21555 const views = pose.views;
21556 const baseLayer = session.renderState.baseLayer;
21557 renderer.setFramebuffer( baseLayer.framebuffer );
21558 let cameraVRNeedsUpdate = false;
21559 if ( views.length !== cameraVR.cameras.length ) {
21560 cameraVR.cameras.length = 0;
21561 cameraVRNeedsUpdate = true;
21562 }
21563 for ( let i = 0; i < views.length; i ++ ) {
21564 const view = views[ i ];
21565 const viewport = baseLayer.getViewport( view );
21566 const camera = cameras[ i ];
21567 camera.matrix.fromArray( view.transform.matrix );
21568 camera.projectionMatrix.fromArray( view.projectionMatrix );
21569 camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );
21570 if ( i === 0 ) {
21571 cameraVR.matrix.copy( camera.matrix );
21572 }
21573 if ( cameraVRNeedsUpdate === true ) {
21574 cameraVR.cameras.push( camera );
21575 }
21576 }
21577 }
21578 const inputSources = session.inputSources;
21579 for ( let i = 0; i < controllers.length; i ++ ) {
21580 const controller = controllers[ i ];
21581 const inputSource = inputSources[ i ];
21582 controller.update( inputSource, frame, referenceSpace );
21583 }
21584 if ( onAnimationFrameCallback ) onAnimationFrameCallback( time, frame );
21585 }
21586 const animation = new WebGLAnimation();
21587 animation.setAnimationLoop( onAnimationFrame );
21588 this.setAnimationLoop = function ( callback ) {
21589 onAnimationFrameCallback = callback;
21590 };
21591 this.dispose = function () {};
21592 }
21593 Object.assign( WebXRManager.prototype, EventDispatcher.prototype );
21594 function WebGLMaterials( properties ) {
21595 function refreshFogUniforms( uniforms, fog ) {
21596 uniforms.fogColor.value.copy( fog.color );
21597 if ( fog.isFog ) {
21598 uniforms.fogNear.value = fog.near;
21599 uniforms.fogFar.value = fog.far;
21600 } else if ( fog.isFogExp2 ) {
21601 uniforms.fogDensity.value = fog.density;
21602 }
21603 }
21604 function refreshMaterialUniforms( uniforms, material, pixelRatio, height ) {
21605 if ( material.isMeshBasicMaterial ) {
21606 refreshUniformsCommon( uniforms, material );
21607 } else if ( material.isMeshLambertMaterial ) {
21608 refreshUniformsCommon( uniforms, material );
21609 refreshUniformsLambert( uniforms, material );
21610 } else if ( material.isMeshToonMaterial ) {
21611 refreshUniformsCommon( uniforms, material );
21612 refreshUniformsToon( uniforms, material );
21613 } else if ( material.isMeshPhongMaterial ) {
21614 refreshUniformsCommon( uniforms, material );
21615 refreshUniformsPhong( uniforms, material );
21616 } else if ( material.isMeshStandardMaterial ) {
21617 refreshUniformsCommon( uniforms, material );
21618 if ( material.isMeshPhysicalMaterial ) {
21619 refreshUniformsPhysical( uniforms, material );
21620 } else {
21621 refreshUniformsStandard( uniforms, material );
21622 }
21623 } else if ( material.isMeshMatcapMaterial ) {
21624 refreshUniformsCommon( uniforms, material );
21625 refreshUniformsMatcap( uniforms, material );
21626 } else if ( material.isMeshDepthMaterial ) {
21627 refreshUniformsCommon( uniforms, material );
21628 refreshUniformsDepth( uniforms, material );
21629 } else if ( material.isMeshDistanceMaterial ) {
21630 refreshUniformsCommon( uniforms, material );
21631 refreshUniformsDistance( uniforms, material );
21632 } else if ( material.isMeshNormalMaterial ) {
21633 refreshUniformsCommon( uniforms, material );
21634 refreshUniformsNormal( uniforms, material );
21635 } else if ( material.isLineBasicMaterial ) {
21636 refreshUniformsLine( uniforms, material );
21637 if ( material.isLineDashedMaterial ) {
21638 refreshUniformsDash( uniforms, material );
21639 }
21640 } else if ( material.isPointsMaterial ) {
21641 refreshUniformsPoints( uniforms, material, pixelRatio, height );
21642 } else if ( material.isSpriteMaterial ) {
21643 refreshUniformsSprites( uniforms, material );
21644 } else if ( material.isShadowMaterial ) {
21645 uniforms.color.value.copy( material.color );
21646 uniforms.opacity.value = material.opacity;
21647 } else if ( material.isShaderMaterial ) {
21648 material.uniformsNeedUpdate = false;
21649 }
21650 }
21651 function refreshUniformsCommon( uniforms, material ) {
21652 uniforms.opacity.value = material.opacity;
21653 if ( material.color ) {
21654 uniforms.diffuse.value.copy( material.color );
21655 }
21656 if ( material.emissive ) {
21657 uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
21658 }
21659 if ( material.map ) {
21660 uniforms.map.value = material.map;
21661 }
21662 if ( material.alphaMap ) {
21663 uniforms.alphaMap.value = material.alphaMap;
21664 }
21665 if ( material.specularMap ) {
21666 uniforms.specularMap.value = material.specularMap;
21667 }
21668 const envMap = properties.get( material ).envMap;
21669 if ( envMap ) {
21670 uniforms.envMap.value = envMap;
21671 uniforms.flipEnvMap.value = envMap.isCubeTexture ? - 1 : 1;
21672 uniforms.reflectivity.value = material.reflectivity;
21673 uniforms.refractionRatio.value = material.refractionRatio;
21674 const maxMipLevel = properties.get( envMap ).__maxMipLevel;
21675 if ( maxMipLevel !== undefined ) {
21676 uniforms.maxMipLevel.value = maxMipLevel;
21677 }
21678 }
21679 if ( material.lightMap ) {
21680 uniforms.lightMap.value = material.lightMap;
21681 uniforms.lightMapIntensity.value = material.lightMapIntensity;
21682 }
21683 if ( material.aoMap ) {
21684 uniforms.aoMap.value = material.aoMap;
21685 uniforms.aoMapIntensity.value = material.aoMapIntensity;
21686 }
21687 let uvScaleMap;
21688 if ( material.map ) {
21689 uvScaleMap = material.map;
21690 } else if ( material.specularMap ) {
21691 uvScaleMap = material.specularMap;
21692 } else if ( material.displacementMap ) {
21693 uvScaleMap = material.displacementMap;
21694 } else if ( material.normalMap ) {
21695 uvScaleMap = material.normalMap;
21696 } else if ( material.bumpMap ) {
21697 uvScaleMap = material.bumpMap;
21698 } else if ( material.roughnessMap ) {
21699 uvScaleMap = material.roughnessMap;
21700 } else if ( material.metalnessMap ) {
21701 uvScaleMap = material.metalnessMap;
21702 } else if ( material.alphaMap ) {
21703 uvScaleMap = material.alphaMap;
21704 } else if ( material.emissiveMap ) {
21705 uvScaleMap = material.emissiveMap;
21706 } else if ( material.clearcoatMap ) {
21707 uvScaleMap = material.clearcoatMap;
21708 } else if ( material.clearcoatNormalMap ) {
21709 uvScaleMap = material.clearcoatNormalMap;
21710 } else if ( material.clearcoatRoughnessMap ) {
21711 uvScaleMap = material.clearcoatRoughnessMap;
21712 }
21713 if ( uvScaleMap !== undefined ) {
21714 if ( uvScaleMap.isWebGLRenderTarget ) {
21715 uvScaleMap = uvScaleMap.texture;
21716 }
21717 if ( uvScaleMap.matrixAutoUpdate === true ) {
21718 uvScaleMap.updateMatrix();
21719 }
21720 uniforms.uvTransform.value.copy( uvScaleMap.matrix );
21721 }
21722 let uv2ScaleMap;
21723 if ( material.aoMap ) {
21724 uv2ScaleMap = material.aoMap;
21725 } else if ( material.lightMap ) {
21726 uv2ScaleMap = material.lightMap;
21727 }
21728 if ( uv2ScaleMap !== undefined ) {
21729 if ( uv2ScaleMap.isWebGLRenderTarget ) {
21730 uv2ScaleMap = uv2ScaleMap.texture;
21731 }
21732 if ( uv2ScaleMap.matrixAutoUpdate === true ) {
21733 uv2ScaleMap.updateMatrix();
21734 }
21735 uniforms.uv2Transform.value.copy( uv2ScaleMap.matrix );
21736 }
21737 }
21738 function refreshUniformsLine( uniforms, material ) {
21739 uniforms.diffuse.value.copy( material.color );
21740 uniforms.opacity.value = material.opacity;
21741 }
21742 function refreshUniformsDash( uniforms, material ) {
21743 uniforms.dashSize.value = material.dashSize;
21744 uniforms.totalSize.value = material.dashSize + material.gapSize;
21745 uniforms.scale.value = material.scale;
21746 }
21747 function refreshUniformsPoints( uniforms, material, pixelRatio, height ) {
21748 uniforms.diffuse.value.copy( material.color );
21749 uniforms.opacity.value = material.opacity;
21750 uniforms.size.value = material.size * pixelRatio;
21751 uniforms.scale.value = height * 0.5;
21752 if ( material.map ) {
21753 uniforms.map.value = material.map;
21754 }
21755 if ( material.alphaMap ) {
21756 uniforms.alphaMap.value = material.alphaMap;
21757 }
21758 let uvScaleMap;
21759 if ( material.map ) {
21760 uvScaleMap = material.map;
21761 } else if ( material.alphaMap ) {
21762 uvScaleMap = material.alphaMap;
21763 }
21764 if ( uvScaleMap !== undefined ) {
21765 if ( uvScaleMap.matrixAutoUpdate === true ) {
21766 uvScaleMap.updateMatrix();
21767 }
21768 uniforms.uvTransform.value.copy( uvScaleMap.matrix );
21769 }
21770 }
21771 function refreshUniformsSprites( uniforms, material ) {
21772 uniforms.diffuse.value.copy( material.color );
21773 uniforms.opacity.value = material.opacity;
21774 uniforms.rotation.value = material.rotation;
21775 if ( material.map ) {
21776 uniforms.map.value = material.map;
21777 }
21778 if ( material.alphaMap ) {
21779 uniforms.alphaMap.value = material.alphaMap;
21780 }
21781 let uvScaleMap;
21782 if ( material.map ) {
21783 uvScaleMap = material.map;
21784 } else if ( material.alphaMap ) {
21785 uvScaleMap = material.alphaMap;
21786 }
21787 if ( uvScaleMap !== undefined ) {
21788 if ( uvScaleMap.matrixAutoUpdate === true ) {
21789 uvScaleMap.updateMatrix();
21790 }
21791 uniforms.uvTransform.value.copy( uvScaleMap.matrix );
21792 }
21793 }
21794 function refreshUniformsLambert( uniforms, material ) {
21795 if ( material.emissiveMap ) {
21796 uniforms.emissiveMap.value = material.emissiveMap;
21797 }
21798 }
21799 function refreshUniformsPhong( uniforms, material ) {
21800 uniforms.specular.value.copy( material.specular );
21801 uniforms.shininess.value = Math.max( material.shininess, 1e-4 );
21802 if ( material.emissiveMap ) {
21803 uniforms.emissiveMap.value = material.emissiveMap;
21804 }
21805 if ( material.bumpMap ) {
21806 uniforms.bumpMap.value = material.bumpMap;
21807 uniforms.bumpScale.value = material.bumpScale;
21808 if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
21809 }
21810 if ( material.normalMap ) {
21811 uniforms.normalMap.value = material.normalMap;
21812 uniforms.normalScale.value.copy( material.normalScale );
21813 if ( material.side === BackSide ) uniforms.normalScale.value.negate();
21814 }
21815 if ( material.displacementMap ) {
21816 uniforms.displacementMap.value = material.displacementMap;
21817 uniforms.displacementScale.value = material.displacementScale;
21818 uniforms.displacementBias.value = material.displacementBias;
21819 }
21820 }
21821 function refreshUniformsToon( uniforms, material ) {
21822 if ( material.gradientMap ) {
21823 uniforms.gradientMap.value = material.gradientMap;
21824 }
21825 if ( material.emissiveMap ) {
21826 uniforms.emissiveMap.value = material.emissiveMap;
21827 }
21828 if ( material.bumpMap ) {
21829 uniforms.bumpMap.value = material.bumpMap;
21830 uniforms.bumpScale.value = material.bumpScale;
21831 if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
21832 }
21833 if ( material.normalMap ) {
21834 uniforms.normalMap.value = material.normalMap;
21835 uniforms.normalScale.value.copy( material.normalScale );
21836 if ( material.side === BackSide ) uniforms.normalScale.value.negate();
21837 }
21838 if ( material.displacementMap ) {
21839 uniforms.displacementMap.value = material.displacementMap;
21840 uniforms.displacementScale.value = material.displacementScale;
21841 uniforms.displacementBias.value = material.displacementBias;
21842 }
21843 }
21844 function refreshUniformsStandard( uniforms, material ) {
21845 uniforms.roughness.value = material.roughness;
21846 uniforms.metalness.value = material.metalness;
21847 if ( material.roughnessMap ) {
21848 uniforms.roughnessMap.value = material.roughnessMap;
21849 }
21850 if ( material.metalnessMap ) {
21851 uniforms.metalnessMap.value = material.metalnessMap;
21852 }
21853 if ( material.emissiveMap ) {
21854 uniforms.emissiveMap.value = material.emissiveMap;
21855 }
21856 if ( material.bumpMap ) {
21857 uniforms.bumpMap.value = material.bumpMap;
21858 uniforms.bumpScale.value = material.bumpScale;
21859 if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
21860 }
21861 if ( material.normalMap ) {
21862 uniforms.normalMap.value = material.normalMap;
21863 uniforms.normalScale.value.copy( material.normalScale );
21864 if ( material.side === BackSide ) uniforms.normalScale.value.negate();
21865 }
21866 if ( material.displacementMap ) {
21867 uniforms.displacementMap.value = material.displacementMap;
21868 uniforms.displacementScale.value = material.displacementScale;
21869 uniforms.displacementBias.value = material.displacementBias;
21870 }
21871 const envMap = properties.get( material ).envMap;
21872 if ( envMap ) {
21873 uniforms.envMapIntensity.value = material.envMapIntensity;
21874 }
21875 }
21876 function refreshUniformsPhysical( uniforms, material ) {
21877 refreshUniformsStandard( uniforms, material );
21878 uniforms.reflectivity.value = material.reflectivity;
21879 uniforms.clearcoat.value = material.clearcoat;
21880 uniforms.clearcoatRoughness.value = material.clearcoatRoughness;
21881 if ( material.sheen ) uniforms.sheen.value.copy( material.sheen );
21882 if ( material.clearcoatMap ) {
21883 uniforms.clearcoatMap.value = material.clearcoatMap;
21884 }
21885 if ( material.clearcoatRoughnessMap ) {
21886 uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap;
21887 }
21888 if ( material.clearcoatNormalMap ) {
21889 uniforms.clearcoatNormalScale.value.copy( material.clearcoatNormalScale );
21890 uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap;
21891 if ( material.side === BackSide ) {
21892 uniforms.clearcoatNormalScale.value.negate();
21893 }
21894 }
21895 uniforms.transmission.value = material.transmission;
21896 if ( material.transmissionMap ) {
21897 uniforms.transmissionMap.value = material.transmissionMap;
21898 }
21899 }
21900 function refreshUniformsMatcap( uniforms, material ) {
21901 if ( material.matcap ) {
21902 uniforms.matcap.value = material.matcap;
21903 }
21904 if ( material.bumpMap ) {
21905 uniforms.bumpMap.value = material.bumpMap;
21906 uniforms.bumpScale.value = material.bumpScale;
21907 if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
21908 }
21909 if ( material.normalMap ) {
21910 uniforms.normalMap.value = material.normalMap;
21911 uniforms.normalScale.value.copy( material.normalScale );
21912 if ( material.side === BackSide ) uniforms.normalScale.value.negate();
21913 }
21914 if ( material.displacementMap ) {
21915 uniforms.displacementMap.value = material.displacementMap;
21916 uniforms.displacementScale.value = material.displacementScale;
21917 uniforms.displacementBias.value = material.displacementBias;
21918 }
21919 }
21920 function refreshUniformsDepth( uniforms, material ) {
21921 if ( material.displacementMap ) {
21922 uniforms.displacementMap.value = material.displacementMap;
21923 uniforms.displacementScale.value = material.displacementScale;
21924 uniforms.displacementBias.value = material.displacementBias;
21925 }
21926 }
21927 function refreshUniformsDistance( uniforms, material ) {
21928 if ( material.displacementMap ) {
21929 uniforms.displacementMap.value = material.displacementMap;
21930 uniforms.displacementScale.value = material.displacementScale;
21931 uniforms.displacementBias.value = material.displacementBias;
21932 }
21933 uniforms.referencePosition.value.copy( material.referencePosition );
21934 uniforms.nearDistance.value = material.nearDistance;
21935 uniforms.farDistance.value = material.farDistance;
21936 }
21937 function refreshUniformsNormal( uniforms, material ) {
21938 if ( material.bumpMap ) {
21939 uniforms.bumpMap.value = material.bumpMap;
21940 uniforms.bumpScale.value = material.bumpScale;
21941 if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
21942 }
21943 if ( material.normalMap ) {
21944 uniforms.normalMap.value = material.normalMap;
21945 uniforms.normalScale.value.copy( material.normalScale );
21946 if ( material.side === BackSide ) uniforms.normalScale.value.negate();
21947 }
21948 if ( material.displacementMap ) {
21949 uniforms.displacementMap.value = material.displacementMap;
21950 uniforms.displacementScale.value = material.displacementScale;
21951 uniforms.displacementBias.value = material.displacementBias;
21952 }
21953 }
21954 return {
21955 refreshFogUniforms: refreshFogUniforms,
21956 refreshMaterialUniforms: refreshMaterialUniforms
21957 };
21958 }
21959 function WebGLRenderer( parameters ) {
21960 parameters = parameters || {};
21961 const _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),
21962 _context = parameters.context !== undefined ? parameters.context : null,
21963 _alpha = parameters.alpha !== undefined ? parameters.alpha : false,
21964 _depth = parameters.depth !== undefined ? parameters.depth : true,
21965 _stencil = parameters.stencil !== undefined ? parameters.stencil : true,
21966 _antialias = parameters.antialias !== undefined ? parameters.antialias : false,
21967 _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
21968 _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
21969 _powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default',
21970 _failIfMajorPerformanceCaveat = parameters.failIfMajorPerformanceCaveat !== undefined ? parameters.failIfMajorPerformanceCaveat : false;
21971 let currentRenderList = null;
21972 let currentRenderState = null;
21973 this.domElement = _canvas;
21974 this.debug = {
21975 checkShaderErrors: true
21976 };
21977 this.autoClear = true;
21978 this.autoClearColor = true;
21979 this.autoClearDepth = true;
21980 this.autoClearStencil = true;
21981 this.sortObjects = true;
21982 this.clippingPlanes = [];
21983 this.localClippingEnabled = false;
21984 this.gammaFactor = 2.0;
21985 this.outputEncoding = LinearEncoding;
21986 this.physicallyCorrectLights = false;
21987 this.toneMapping = NoToneMapping;
21988 this.toneMappingExposure = 1.0;
21989 this.maxMorphTargets = 8;
21990 this.maxMorphNormals = 4;
21991 const _this = this;
21992 let _isContextLost = false;
21993 let _framebuffer = null;
21994 let _currentActiveCubeFace = 0;
21995 let _currentActiveMipmapLevel = 0;
21996 let _currentRenderTarget = null;
21997 let _currentFramebuffer = null;
21998 let _currentMaterialId = - 1;
21999 let _currentCamera = null;
22000 let _currentArrayCamera = null;
22001 const _currentViewport = new Vector4();
22002 const _currentScissor = new Vector4();
22003 let _currentScissorTest = null;
22004 let _width = _canvas.width;
22005 let _height = _canvas.height;
22006 let _pixelRatio = 1;
22007 let _opaqueSort = null;
22008 let _transparentSort = null;
22009 const _viewport = new Vector4( 0, 0, _width, _height );
22010 const _scissor = new Vector4( 0, 0, _width, _height );
22011 let _scissorTest = false;
22012 const _frustum = new Frustum();
22013 let _clippingEnabled = false;
22014 let _localClippingEnabled = false;
22015 const _projScreenMatrix = new Matrix4();
22016 const _vector3 = new Vector3();
22017 const _emptyScene = { background: null, fog: null, environment: null, overrideMaterial: null, isScene: true };
22018 function getTargetPixelRatio() {
22019 return _currentRenderTarget === null ? _pixelRatio : 1;
22020 }
22021 let _gl = _context;
22022 function getContext( contextNames, contextAttributes ) {
22023 for ( let i = 0; i < contextNames.length; i ++ ) {
22024 const contextName = contextNames[ i ];
22025 const context = _canvas.getContext( contextName, contextAttributes );
22026 if ( context !== null ) return context;
22027 }
22028 return null;
22029 }
22030 try {
22031 const contextAttributes = {
22032 alpha: _alpha,
22033 depth: _depth,
22034 stencil: _stencil,
22035 antialias: _antialias,
22036 premultipliedAlpha: _premultipliedAlpha,
22037 preserveDrawingBuffer: _preserveDrawingBuffer,
22038 powerPreference: _powerPreference,
22039 failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat
22040 };
22041 _canvas.addEventListener( 'webglcontextlost', onContextLost, false );
22042 _canvas.addEventListener( 'webglcontextrestored', onContextRestore, false );
22043 if ( _gl === null ) {
22044 const contextNames = [ 'webgl2', 'webgl', 'experimental-webgl' ];
22045 if ( _this.isWebGL1Renderer === true ) {
22046 contextNames.shift();
22047 }
22048 _gl = getContext( contextNames, contextAttributes );
22049 if ( _gl === null ) {
22050 if ( getContext( contextNames ) ) {
22051 throw new Error( 'Error creating WebGL context with your selected attributes.' );
22052 } else {
22053 throw new Error( 'Error creating WebGL context.' );
22054 }
22055 }
22056 }
22057 if ( _gl.getShaderPrecisionFormat === undefined ) {
22058 _gl.getShaderPrecisionFormat = function () {
22059 return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };
22060 };
22061 }
22062 } catch ( error ) {
22063 console.error( 'THREE.WebGLRenderer: ' + error.message );
22064 throw error;
22065 }
22066 let extensions, capabilities, state, info;
22067 let properties, textures, cubemaps, attributes, geometries, objects;
22068 let programCache, materials, renderLists, renderStates, clipping;
22069 let background, morphtargets, bufferRenderer, indexedBufferRenderer;
22070 let utils, bindingStates;
22071 function initGLContext() {
22072 extensions = new WebGLExtensions( _gl );
22073 capabilities = new WebGLCapabilities( _gl, extensions, parameters );
22074 if ( capabilities.isWebGL2 === false ) {
22075 extensions.get( 'WEBGL_depth_texture' );
22076 extensions.get( 'OES_texture_float' );
22077 extensions.get( 'OES_texture_half_float' );
22078 extensions.get( 'OES_texture_half_float_linear' );
22079 extensions.get( 'OES_standard_derivatives' );
22080 extensions.get( 'OES_element_index_uint' );
22081 extensions.get( 'OES_vertex_array_object' );
22082 extensions.get( 'ANGLE_instanced_arrays' );
22083 }
22084 extensions.get( 'OES_texture_float_linear' );
22085 utils = new WebGLUtils( _gl, extensions, capabilities );
22086 state = new WebGLState( _gl, extensions, capabilities );
22087 state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() );
22088 state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() );
22089 info = new WebGLInfo();
22090 properties = new WebGLProperties();
22091 textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info );
22092 cubemaps = new WebGLCubeMaps( _this );
22093 attributes = new WebGLAttributes( _gl, capabilities );
22094 bindingStates = new WebGLBindingStates( _gl, extensions, attributes, capabilities );
22095 geometries = new WebGLGeometries( _gl, attributes, info, bindingStates );
22096 objects = new WebGLObjects( _gl, geometries, attributes, info );
22097 morphtargets = new WebGLMorphtargets( _gl );
22098 clipping = new WebGLClipping( properties );
22099 programCache = new WebGLPrograms( _this, cubemaps, extensions, capabilities, bindingStates, clipping );
22100 materials = new WebGLMaterials( properties );
22101 renderLists = new WebGLRenderLists( properties );
22102 renderStates = new WebGLRenderStates();
22103 background = new WebGLBackground( _this, cubemaps, state, objects, _premultipliedAlpha );
22104 bufferRenderer = new WebGLBufferRenderer( _gl, extensions, info, capabilities );
22105 indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info, capabilities );
22106 info.programs = programCache.programs;
22107 _this.capabilities = capabilities;
22108 _this.extensions = extensions;
22109 _this.properties = properties;
22110 _this.renderLists = renderLists;
22111 _this.state = state;
22112 _this.info = info;
22113 }
22114 initGLContext();
22115 const xr = new WebXRManager( _this, _gl );
22116 this.xr = xr;
22117 const shadowMap = new WebGLShadowMap( _this, objects, capabilities.maxTextureSize );
22118 this.shadowMap = shadowMap;
22119 this.getContext = function () {
22120 return _gl;
22121 };
22122 this.getContextAttributes = function () {
22123 return _gl.getContextAttributes();
22124 };
22125 this.forceContextLoss = function () {
22126 const extension = extensions.get( 'WEBGL_lose_context' );
22127 if ( extension ) extension.loseContext();
22128 };
22129 this.forceContextRestore = function () {
22130 const extension = extensions.get( 'WEBGL_lose_context' );
22131 if ( extension ) extension.restoreContext();
22132 };
22133 this.getPixelRatio = function () {
22134 return _pixelRatio;
22135 };
22136 this.setPixelRatio = function ( value ) {
22137 if ( value === undefined ) return;
22138 _pixelRatio = value;
22139 this.setSize( _width, _height, false );
22140 };
22141 this.getSize = function ( target ) {
22142 if ( target === undefined ) {
22143 console.warn( 'WebGLRenderer: .getsize() now requires a Vector2 as an argument' );
22144 target = new Vector2();
22145 }
22146 return target.set( _width, _height );
22147 };
22148 this.setSize = function ( width, height, updateStyle ) {
22149 if ( xr.isPresenting ) {
22150 console.warn( 'THREE.WebGLRenderer: Can\'t change size while VR device is presenting.' );
22151 return;
22152 }
22153 _width = width;
22154 _height = height;
22155 _canvas.width = Math.floor( width * _pixelRatio );
22156 _canvas.height = Math.floor( height * _pixelRatio );
22157 if ( updateStyle !== false ) {
22158 _canvas.style.width = width + 'px';
22159 _canvas.style.height = height + 'px';
22160 }
22161 this.setViewport( 0, 0, width, height );
22162 };
22163 this.getDrawingBufferSize = function ( target ) {
22164 if ( target === undefined ) {
22165 console.warn( 'WebGLRenderer: .getdrawingBufferSize() now requires a Vector2 as an argument' );
22166 target = new Vector2();
22167 }
22168 return target.set( _width * _pixelRatio, _height * _pixelRatio ).floor();
22169 };
22170 this.setDrawingBufferSize = function ( width, height, pixelRatio ) {
22171 _width = width;
22172 _height = height;
22173 _pixelRatio = pixelRatio;
22174 _canvas.width = Math.floor( width * pixelRatio );
22175 _canvas.height = Math.floor( height * pixelRatio );
22176 this.setViewport( 0, 0, width, height );
22177 };
22178 this.getCurrentViewport = function ( target ) {
22179 if ( target === undefined ) {
22180 console.warn( 'WebGLRenderer: .getCurrentViewport() now requires a Vector4 as an argument' );
22181 target = new Vector4();
22182 }
22183 return target.copy( _currentViewport );
22184 };
22185 this.getViewport = function ( target ) {
22186 return target.copy( _viewport );
22187 };
22188 this.setViewport = function ( x, y, width, height ) {
22189 if ( x.isVector4 ) {
22190 _viewport.set( x.x, x.y, x.z, x.w );
22191 } else {
22192 _viewport.set( x, y, width, height );
22193 }
22194 state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() );
22195 };
22196 this.getScissor = function ( target ) {
22197 return target.copy( _scissor );
22198 };
22199 this.setScissor = function ( x, y, width, height ) {
22200 if ( x.isVector4 ) {
22201 _scissor.set( x.x, x.y, x.z, x.w );
22202 } else {
22203 _scissor.set( x, y, width, height );
22204 }
22205 state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() );
22206 };
22207 this.getScissorTest = function () {
22208 return _scissorTest;
22209 };
22210 this.setScissorTest = function ( boolean ) {
22211 state.setScissorTest( _scissorTest = boolean );
22212 };
22213 this.setOpaqueSort = function ( method ) {
22214 _opaqueSort = method;
22215 };
22216 this.setTransparentSort = function ( method ) {
22217 _transparentSort = method;
22218 };
22219 this.getClearColor = function () {
22220 return background.getClearColor();
22221 };
22222 this.setClearColor = function () {
22223 background.setClearColor.apply( background, arguments );
22224 };
22225 this.getClearAlpha = function () {
22226 return background.getClearAlpha();
22227 };
22228 this.setClearAlpha = function () {
22229 background.setClearAlpha.apply( background, arguments );
22230 };
22231 this.clear = function ( color, depth, stencil ) {
22232 let bits = 0;
22233 if ( color === undefined || color ) bits |= 16384;
22234 if ( depth === undefined || depth ) bits |= 256;
22235 if ( stencil === undefined || stencil ) bits |= 1024;
22236 _gl.clear( bits );
22237 };
22238 this.clearColor = function () {
22239 this.clear( true, false, false );
22240 };
22241 this.clearDepth = function () {
22242 this.clear( false, true, false );
22243 };
22244 this.clearStencil = function () {
22245 this.clear( false, false, true );
22246 };
22247 this.dispose = function () {
22248 _canvas.removeEventListener( 'webglcontextlost', onContextLost, false );
22249 _canvas.removeEventListener( 'webglcontextrestored', onContextRestore, false );
22250 renderLists.dispose();
22251 renderStates.dispose();
22252 properties.dispose();
22253 cubemaps.dispose();
22254 objects.dispose();
22255 bindingStates.dispose();
22256 xr.dispose();
22257 animation.stop();
22258 };
22259 function onContextLost( event ) {
22260 event.preventDefault();
22261 console.log( 'THREE.WebGLRenderer: Context Lost.' );
22262 _isContextLost = true;
22263 }
22264 function onContextRestore( ) {
22265 console.log( 'THREE.WebGLRenderer: Context Restored.' );
22266 _isContextLost = false;
22267 initGLContext();
22268 }
22269 function onMaterialDispose( event ) {
22270 const material = event.target;
22271 material.removeEventListener( 'dispose', onMaterialDispose );
22272 deallocateMaterial( material );
22273 }
22274 function deallocateMaterial( material ) {
22275 releaseMaterialProgramReference( material );
22276 properties.remove( material );
22277 }
22278 function releaseMaterialProgramReference( material ) {
22279 const programInfo = properties.get( material ).program;
22280 if ( programInfo !== undefined ) {
22281 programCache.releaseProgram( programInfo );
22282 }
22283 }
22284 function renderObjectImmediate( object, program ) {
22285 object.render( function ( object ) {
22286 _this.renderBufferImmediate( object, program );
22287 } );
22288 }
22289 this.renderBufferImmediate = function ( object, program ) {
22290 bindingStates.initAttributes();
22291 const buffers = properties.get( object );
22292 if ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();
22293 if ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();
22294 if ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();
22295 if ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();
22296 const programAttributes = program.getAttributes();
22297 if ( object.hasPositions ) {
22298 _gl.bindBuffer( 34962, buffers.position );
22299 _gl.bufferData( 34962, object.positionArray, 35048 );
22300 bindingStates.enableAttribute( programAttributes.position );
22301 _gl.vertexAttribPointer( programAttributes.position, 3, 5126, false, 0, 0 );
22302 }
22303 if ( object.hasNormals ) {
22304 _gl.bindBuffer( 34962, buffers.normal );
22305 _gl.bufferData( 34962, object.normalArray, 35048 );
22306 bindingStates.enableAttribute( programAttributes.normal );
22307 _gl.vertexAttribPointer( programAttributes.normal, 3, 5126, false, 0, 0 );
22308 }
22309 if ( object.hasUvs ) {
22310 _gl.bindBuffer( 34962, buffers.uv );
22311 _gl.bufferData( 34962, object.uvArray, 35048 );
22312 bindingStates.enableAttribute( programAttributes.uv );
22313 _gl.vertexAttribPointer( programAttributes.uv, 2, 5126, false, 0, 0 );
22314 }
22315 if ( object.hasColors ) {
22316 _gl.bindBuffer( 34962, buffers.color );
22317 _gl.bufferData( 34962, object.colorArray, 35048 );
22318 bindingStates.enableAttribute( programAttributes.color );
22319 _gl.vertexAttribPointer( programAttributes.color, 3, 5126, false, 0, 0 );
22320 }
22321 bindingStates.disableUnusedAttributes();
22322 _gl.drawArrays( 4, 0, object.count );
22323 object.count = 0;
22324 };
22325 this.renderBufferDirect = function ( camera, scene, geometry, material, object, group ) {
22326 if ( scene === null ) scene = _emptyScene;
22327 const frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );
22328 const program = setProgram( camera, scene, material, object );
22329 state.setMaterial( material, frontFaceCW );
22330 let index = geometry.index;
22331 const position = geometry.attributes.position;
22332 if ( index === null ) {
22333 if ( position === undefined || position.count === 0 ) return;
22334 } else if ( index.count === 0 ) {
22335 return;
22336 }
22337 let rangeFactor = 1;
22338 if ( material.wireframe === true ) {
22339 index = geometries.getWireframeAttribute( geometry );
22340 rangeFactor = 2;
22341 }
22342 if ( material.morphTargets || material.morphNormals ) {
22343 morphtargets.update( object, geometry, material, program );
22344 }
22345 bindingStates.setup( object, material, program, geometry, index );
22346 let attribute;
22347 let renderer = bufferRenderer;
22348 if ( index !== null ) {
22349 attribute = attributes.get( index );
22350 renderer = indexedBufferRenderer;
22351 renderer.setIndex( attribute );
22352 }
22353 const dataCount = ( index !== null ) ? index.count : position.count;
22354 const rangeStart = geometry.drawRange.start * rangeFactor;
22355 const rangeCount = geometry.drawRange.count * rangeFactor;
22356 const groupStart = group !== null ? group.start * rangeFactor : 0;
22357 const groupCount = group !== null ? group.count * rangeFactor : Infinity;
22358 const drawStart = Math.max( rangeStart, groupStart );
22359 const drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
22360 const drawCount = Math.max( 0, drawEnd - drawStart + 1 );
22361 if ( drawCount === 0 ) return;
22362 if ( object.isMesh ) {
22363 if ( material.wireframe === true ) {
22364 state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
22365 renderer.setMode( 1 );
22366 } else {
22367 renderer.setMode( 4 );
22368 }
22369 } else if ( object.isLine ) {
22370 let lineWidth = material.linewidth;
22371 if ( lineWidth === undefined ) lineWidth = 1;
22372 state.setLineWidth( lineWidth * getTargetPixelRatio() );
22373 if ( object.isLineSegments ) {
22374 renderer.setMode( 1 );
22375 } else if ( object.isLineLoop ) {
22376 renderer.setMode( 2 );
22377 } else {
22378 renderer.setMode( 3 );
22379 }
22380 } else if ( object.isPoints ) {
22381 renderer.setMode( 0 );
22382 } else if ( object.isSprite ) {
22383 renderer.setMode( 4 );
22384 }
22385 if ( object.isInstancedMesh ) {
22386 renderer.renderInstances( drawStart, drawCount, object.count );
22387 } else if ( geometry.isInstancedBufferGeometry ) {
22388 const instanceCount = Math.min( geometry.instanceCount, geometry._maxInstanceCount );
22389 renderer.renderInstances( drawStart, drawCount, instanceCount );
22390 } else {
22391 renderer.render( drawStart, drawCount );
22392 }
22393 };
22394 this.compile = function ( scene, camera ) {
22395 currentRenderState = renderStates.get( scene, camera );
22396 currentRenderState.init();
22397 scene.traverse( function ( object ) {
22398 if ( object.isLight ) {
22399 currentRenderState.pushLight( object );
22400 if ( object.castShadow ) {
22401 currentRenderState.pushShadow( object );
22402 }
22403 }
22404 } );
22405 currentRenderState.setupLights( camera );
22406 const compiled = new WeakMap();
22407 scene.traverse( function ( object ) {
22408 const material = object.material;
22409 if ( material ) {
22410 if ( Array.isArray( material ) ) {
22411 for ( let i = 0; i < material.length; i ++ ) {
22412 const material2 = material[ i ];
22413 if ( compiled.has( material2 ) === false ) {
22414 initMaterial( material2, scene, object );
22415 compiled.set( material2 );
22416 }
22417 }
22418 } else if ( compiled.has( material ) === false ) {
22419 initMaterial( material, scene, object );
22420 compiled.set( material );
22421 }
22422 }
22423 } );
22424 };
22425 let onAnimationFrameCallback = null;
22426 function onAnimationFrame( time ) {
22427 if ( xr.isPresenting ) return;
22428 if ( onAnimationFrameCallback ) onAnimationFrameCallback( time );
22429 }
22430 const animation = new WebGLAnimation();
22431 animation.setAnimationLoop( onAnimationFrame );
22432 if ( typeof window !== 'undefined' ) animation.setContext( window );
22433 this.setAnimationLoop = function ( callback ) {
22434 onAnimationFrameCallback = callback;
22435 xr.setAnimationLoop( callback );
22436 ( callback === null ) ? animation.stop() : animation.start();
22437 };
22438 this.render = function ( scene, camera ) {
22439 let renderTarget, forceClear;
22440 if ( arguments[ 2 ] !== undefined ) {
22441 console.warn( 'THREE.WebGLRenderer.render(): the renderTarget argument has been removed. Use .setRenderTarget() instead.' );
22442 renderTarget = arguments[ 2 ];
22443 }
22444 if ( arguments[ 3 ] !== undefined ) {
22445 console.warn( 'THREE.WebGLRenderer.render(): the forceClear argument has been removed. Use .clear() instead.' );
22446 forceClear = arguments[ 3 ];
22447 }
22448 if ( camera !== undefined && camera.isCamera !== true ) {
22449 console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
22450 return;
22451 }
22452 if ( _isContextLost === true ) return;
22453 bindingStates.resetDefaultState();
22454 _currentMaterialId = - 1;
22455 _currentCamera = null;
22456 if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
22457 if ( camera.parent === null ) camera.updateMatrixWorld();
22458 if ( xr.enabled === true && xr.isPresenting === true ) {
22459 camera = xr.getCamera( camera );
22460 }
22461 if ( scene.isScene === true ) scene.onBeforeRender( _this, scene, camera, renderTarget || _currentRenderTarget );
22462 currentRenderState = renderStates.get( scene, camera );
22463 currentRenderState.init();
22464 _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
22465 _frustum.setFromProjectionMatrix( _projScreenMatrix );
22466 _localClippingEnabled = this.localClippingEnabled;
22467 _clippingEnabled = clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
22468 currentRenderList = renderLists.get( scene, camera );
22469 currentRenderList.init();
22470 projectObject( scene, camera, 0, _this.sortObjects );
22471 currentRenderList.finish();
22472 if ( _this.sortObjects === true ) {
22473 currentRenderList.sort( _opaqueSort, _transparentSort );
22474 }
22475 if ( _clippingEnabled === true ) clipping.beginShadows();
22476 const shadowsArray = currentRenderState.state.shadowsArray;
22477 shadowMap.render( shadowsArray, scene, camera );
22478 currentRenderState.setupLights( camera );
22479 if ( _clippingEnabled === true ) clipping.endShadows();
22480 if ( this.info.autoReset === true ) this.info.reset();
22481 if ( renderTarget !== undefined ) {
22482 this.setRenderTarget( renderTarget );
22483 }
22484 background.render( currentRenderList, scene, camera, forceClear );
22485 const opaqueObjects = currentRenderList.opaque;
22486 const transparentObjects = currentRenderList.transparent;
22487 if ( opaqueObjects.length > 0 ) renderObjects( opaqueObjects, scene, camera );
22488 if ( transparentObjects.length > 0 ) renderObjects( transparentObjects, scene, camera );
22489 if ( scene.isScene === true ) scene.onAfterRender( _this, scene, camera );
22490 if ( _currentRenderTarget !== null ) {
22491 textures.updateRenderTargetMipmap( _currentRenderTarget );
22492 textures.updateMultisampleRenderTarget( _currentRenderTarget );
22493 }
22494 state.buffers.depth.setTest( true );
22495 state.buffers.depth.setMask( true );
22496 state.buffers.color.setMask( true );
22497 state.setPolygonOffset( false );
22498 currentRenderList = null;
22499 currentRenderState = null;
22500 };
22501 function projectObject( object, camera, groupOrder, sortObjects ) {
22502 if ( object.visible === false ) return;
22503 const visible = object.layers.test( camera.layers );
22504 if ( visible ) {
22505 if ( object.isGroup ) {
22506 groupOrder = object.renderOrder;
22507 } else if ( object.isLOD ) {
22508 if ( object.autoUpdate === true ) object.update( camera );
22509 } else if ( object.isLight ) {
22510 currentRenderState.pushLight( object );
22511 if ( object.castShadow ) {
22512 currentRenderState.pushShadow( object );
22513 }
22514 } else if ( object.isSprite ) {
22515 if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
22516 if ( sortObjects ) {
22517 _vector3.setFromMatrixPosition( object.matrixWorld )
22518 .applyMatrix4( _projScreenMatrix );
22519 }
22520 const geometry = objects.update( object );
22521 const material = object.material;
22522 if ( material.visible ) {
22523 currentRenderList.push( object, geometry, material, groupOrder, _vector3.z, null );
22524 }
22525 }
22526 } else if ( object.isImmediateRenderObject ) {
22527 if ( sortObjects ) {
22528 _vector3.setFromMatrixPosition( object.matrixWorld )
22529 .applyMatrix4( _projScreenMatrix );
22530 }
22531 currentRenderList.push( object, null, object.material, groupOrder, _vector3.z, null );
22532 } else if ( object.isMesh || object.isLine || object.isPoints ) {
22533 if ( object.isSkinnedMesh ) {
22534 if ( object.skeleton.frame !== info.render.frame ) {
22535 object.skeleton.update();
22536 object.skeleton.frame = info.render.frame;
22537 }
22538 }
22539 if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
22540 if ( sortObjects ) {
22541 _vector3.setFromMatrixPosition( object.matrixWorld )
22542 .applyMatrix4( _projScreenMatrix );
22543 }
22544 const geometry = objects.update( object );
22545 const material = object.material;
22546 if ( Array.isArray( material ) ) {
22547 const groups = geometry.groups;
22548 for ( let i = 0, l = groups.length; i < l; i ++ ) {
22549 const group = groups[ i ];
22550 const groupMaterial = material[ group.materialIndex ];
22551 if ( groupMaterial && groupMaterial.visible ) {
22552 currentRenderList.push( object, geometry, groupMaterial, groupOrder, _vector3.z, group );
22553 }
22554 }
22555 } else if ( material.visible ) {
22556 currentRenderList.push( object, geometry, material, groupOrder, _vector3.z, null );
22557 }
22558 }
22559 }
22560 }
22561 const children = object.children;
22562 for ( let i = 0, l = children.length; i < l; i ++ ) {
22563 projectObject( children[ i ], camera, groupOrder, sortObjects );
22564 }
22565 }
22566 function renderObjects( renderList, scene, camera ) {
22567 const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null;
22568 for ( let i = 0, l = renderList.length; i < l; i ++ ) {
22569 const renderItem = renderList[ i ];
22570 const object = renderItem.object;
22571 const geometry = renderItem.geometry;
22572 const material = overrideMaterial === null ? renderItem.material : overrideMaterial;
22573 const group = renderItem.group;
22574 if ( camera.isArrayCamera ) {
22575 _currentArrayCamera = camera;
22576 const cameras = camera.cameras;
22577 for ( let j = 0, jl = cameras.length; j < jl; j ++ ) {
22578 const camera2 = cameras[ j ];
22579 if ( object.layers.test( camera2.layers ) ) {
22580 state.viewport( _currentViewport.copy( camera2.viewport ) );
22581 currentRenderState.setupLights( camera2 );
22582 renderObject( object, scene, camera2, geometry, material, group );
22583 }
22584 }
22585 } else {
22586 _currentArrayCamera = null;
22587 renderObject( object, scene, camera, geometry, material, group );
22588 }
22589 }
22590 }
22591 function renderObject( object, scene, camera, geometry, material, group ) {
22592 object.onBeforeRender( _this, scene, camera, geometry, material, group );
22593 currentRenderState = renderStates.get( scene, _currentArrayCamera || camera );
22594 object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
22595 object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
22596 if ( object.isImmediateRenderObject ) {
22597 const program = setProgram( camera, scene, material, object );
22598 state.setMaterial( material );
22599 bindingStates.reset();
22600 renderObjectImmediate( object, program );
22601 } else {
22602 _this.renderBufferDirect( camera, scene, geometry, material, object, group );
22603 }
22604 object.onAfterRender( _this, scene, camera, geometry, material, group );
22605 currentRenderState = renderStates.get( scene, _currentArrayCamera || camera );
22606 }
22607 function initMaterial( material, scene, object ) {
22608 if ( scene.isScene !== true ) scene = _emptyScene;
22609 const materialProperties = properties.get( material );
22610 const lights = currentRenderState.state.lights;
22611 const shadowsArray = currentRenderState.state.shadowsArray;
22612 const lightsStateVersion = lights.state.version;
22613 const parameters = programCache.getParameters( material, lights.state, shadowsArray, scene, object );
22614 const programCacheKey = programCache.getProgramCacheKey( parameters );
22615 let program = materialProperties.program;
22616 let programChange = true;
22617 if ( program === undefined ) {
22618 material.addEventListener( 'dispose', onMaterialDispose );
22619 } else if ( program.cacheKey !== programCacheKey ) {
22620 releaseMaterialProgramReference( material );
22621 } else if ( materialProperties.lightsStateVersion !== lightsStateVersion ) {
22622 programChange = false;
22623 } else if ( parameters.shaderID !== undefined ) {
22624 const environment = material.isMeshStandardMaterial ? scene.environment : null;
22625 materialProperties.envMap = cubemaps.get( material.envMap || environment );
22626 return;
22627 } else {
22628 programChange = false;
22629 }
22630 if ( programChange ) {
22631 parameters.uniforms = programCache.getUniforms( material );
22632 material.onBeforeCompile( parameters, _this );
22633 program = programCache.acquireProgram( parameters, programCacheKey );
22634 materialProperties.program = program;
22635 materialProperties.uniforms = parameters.uniforms;
22636 materialProperties.outputEncoding = parameters.outputEncoding;
22637 }
22638 const uniforms = materialProperties.uniforms;
22639 if ( ! material.isShaderMaterial &&
22640 ! material.isRawShaderMaterial ||
22641 material.clipping === true ) {
22642 materialProperties.numClippingPlanes = clipping.numPlanes;
22643 materialProperties.numIntersection = clipping.numIntersection;
22644 uniforms.clippingPlanes = clipping.uniform;
22645 }
22646 materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null;
22647 materialProperties.fog = scene.fog;
22648 materialProperties.envMap = cubemaps.get( material.envMap || materialProperties.environment );
22649 materialProperties.needsLights = materialNeedsLights( material );
22650 materialProperties.lightsStateVersion = lightsStateVersion;
22651 if ( materialProperties.needsLights ) {
22652 uniforms.ambientLightColor.value = lights.state.ambient;
22653 uniforms.lightProbe.value = lights.state.probe;
22654 uniforms.directionalLights.value = lights.state.directional;
22655 uniforms.directionalLightShadows.value = lights.state.directionalShadow;
22656 uniforms.spotLights.value = lights.state.spot;
22657 uniforms.spotLightShadows.value = lights.state.spotShadow;
22658 uniforms.rectAreaLights.value = lights.state.rectArea;
22659 uniforms.ltc_1.value = lights.state.rectAreaLTC1;
22660 uniforms.ltc_2.value = lights.state.rectAreaLTC2;
22661 uniforms.pointLights.value = lights.state.point;
22662 uniforms.pointLightShadows.value = lights.state.pointShadow;
22663 uniforms.hemisphereLights.value = lights.state.hemi;
22664 uniforms.directionalShadowMap.value = lights.state.directionalShadowMap;
22665 uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix;
22666 uniforms.spotShadowMap.value = lights.state.spotShadowMap;
22667 uniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix;
22668 uniforms.pointShadowMap.value = lights.state.pointShadowMap;
22669 uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix;
22670 }
22671 const progUniforms = materialProperties.program.getUniforms();
22672 const uniformsList = WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
22673 materialProperties.uniformsList = uniformsList;
22674 }
22675 function setProgram( camera, scene, material, object ) {
22676 if ( scene.isScene !== true ) scene = _emptyScene;
22677 textures.resetTextureUnits();
22678 const fog = scene.fog;
22679 const environment = material.isMeshStandardMaterial ? scene.environment : null;
22680 const encoding = ( _currentRenderTarget === null ) ? _this.outputEncoding : _currentRenderTarget.texture.encoding;
22681 const envMap = cubemaps.get( material.envMap || environment );
22682 const materialProperties = properties.get( material );
22683 const lights = currentRenderState.state.lights;
22684 if ( _clippingEnabled === true ) {
22685 if ( _localClippingEnabled === true || camera !== _currentCamera ) {
22686 const useCache =
22687 camera === _currentCamera &&
22688 material.id === _currentMaterialId;
22689 clipping.setState( material, camera, useCache );
22690 }
22691 }
22692 if ( material.version === materialProperties.__version ) {
22693 if ( material.fog && materialProperties.fog !== fog ) {
22694 initMaterial( material, scene, object );
22695 } else if ( materialProperties.environment !== environment ) {
22696 initMaterial( material, scene, object );
22697 } else if ( materialProperties.needsLights && ( materialProperties.lightsStateVersion !== lights.state.version ) ) {
22698 initMaterial( material, scene, object );
22699 } else if ( materialProperties.numClippingPlanes !== undefined &&
22700 ( materialProperties.numClippingPlanes !== clipping.numPlanes ||
22701 materialProperties.numIntersection !== clipping.numIntersection ) ) {
22702 initMaterial( material, scene, object );
22703 } else if ( materialProperties.outputEncoding !== encoding ) {
22704 initMaterial( material, scene, object );
22705 } else if ( materialProperties.envMap !== envMap ) {
22706 initMaterial( material, scene, object );
22707 }
22708 } else {
22709 initMaterial( material, scene, object );
22710 materialProperties.__version = material.version;
22711 }
22712 let refreshProgram = false;
22713 let refreshMaterial = false;
22714 let refreshLights = false;
22715 const program = materialProperties.program,
22716 p_uniforms = program.getUniforms(),
22717 m_uniforms = materialProperties.uniforms;
22718 if ( state.useProgram( program.program ) ) {
22719 refreshProgram = true;
22720 refreshMaterial = true;
22721 refreshLights = true;
22722 }
22723 if ( material.id !== _currentMaterialId ) {
22724 _currentMaterialId = material.id;
22725 refreshMaterial = true;
22726 }
22727 if ( refreshProgram || _currentCamera !== camera ) {
22728 p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
22729 if ( capabilities.logarithmicDepthBuffer ) {
22730 p_uniforms.setValue( _gl, 'logDepthBufFC',
22731 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
22732 }
22733 if ( _currentCamera !== camera ) {
22734 _currentCamera = camera;
22735 refreshMaterial = true;
22736 refreshLights = true;
22737 }
22738 if ( material.isShaderMaterial ||
22739 material.isMeshPhongMaterial ||
22740 material.isMeshToonMaterial ||
22741 material.isMeshStandardMaterial ||
22742 material.envMap ) {
22743 const uCamPos = p_uniforms.map.cameraPosition;
22744 if ( uCamPos !== undefined ) {
22745 uCamPos.setValue( _gl,
22746 _vector3.setFromMatrixPosition( camera.matrixWorld ) );
22747 }
22748 }
22749 if ( material.isMeshPhongMaterial ||
22750 material.isMeshToonMaterial ||
22751 material.isMeshLambertMaterial ||
22752 material.isMeshBasicMaterial ||
22753 material.isMeshStandardMaterial ||
22754 material.isShaderMaterial ) {
22755 p_uniforms.setValue( _gl, 'isOrthographic', camera.isOrthographicCamera === true );
22756 }
22757 if ( material.isMeshPhongMaterial ||
22758 material.isMeshToonMaterial ||
22759 material.isMeshLambertMaterial ||
22760 material.isMeshBasicMaterial ||
22761 material.isMeshStandardMaterial ||
22762 material.isShaderMaterial ||
22763 material.isShadowMaterial ||
22764 material.skinning ) {
22765 p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
22766 }
22767 }
22768 if ( material.skinning ) {
22769 p_uniforms.setOptional( _gl, object, 'bindMatrix' );
22770 p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
22771 const skeleton = object.skeleton;
22772 if ( skeleton ) {
22773 const bones = skeleton.bones;
22774 if ( capabilities.floatVertexTextures ) {
22775 if ( skeleton.boneTexture === undefined ) {
22776 let size = Math.sqrt( bones.length * 4 );
22777 size = MathUtils.ceilPowerOfTwo( size );
22778 size = Math.max( size, 4 );
22779 const boneMatrices = new Float32Array( size * size * 4 );
22780 boneMatrices.set( skeleton.boneMatrices );
22781 const boneTexture = new DataTexture( boneMatrices, size, size, RGBAFormat, FloatType );
22782 skeleton.boneMatrices = boneMatrices;
22783 skeleton.boneTexture = boneTexture;
22784 skeleton.boneTextureSize = size;
22785 }
22786 p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture, textures );
22787 p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
22788 } else {
22789 p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
22790 }
22791 }
22792 }
22793 if ( refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow ) {
22794 materialProperties.receiveShadow = object.receiveShadow;
22795 p_uniforms.setValue( _gl, 'receiveShadow', object.receiveShadow );
22796 }
22797 if ( refreshMaterial ) {
22798 p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
22799 if ( materialProperties.needsLights ) {
22800 markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
22801 }
22802 if ( fog && material.fog ) {
22803 materials.refreshFogUniforms( m_uniforms, fog );
22804 }
22805 materials.refreshMaterialUniforms( m_uniforms, material, _pixelRatio, _height );
22806 WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
22807 }
22808 if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {
22809 WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
22810 material.uniformsNeedUpdate = false;
22811 }
22812 if ( material.isSpriteMaterial ) {
22813 p_uniforms.setValue( _gl, 'center', object.center );
22814 }
22815 p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
22816 p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
22817 p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
22818 return program;
22819 }
22820 function markUniformsLightsNeedsUpdate( uniforms, value ) {
22821 uniforms.ambientLightColor.needsUpdate = value;
22822 uniforms.lightProbe.needsUpdate = value;
22823 uniforms.directionalLights.needsUpdate = value;
22824 uniforms.directionalLightShadows.needsUpdate = value;
22825 uniforms.pointLights.needsUpdate = value;
22826 uniforms.pointLightShadows.needsUpdate = value;
22827 uniforms.spotLights.needsUpdate = value;
22828 uniforms.spotLightShadows.needsUpdate = value;
22829 uniforms.rectAreaLights.needsUpdate = value;
22830 uniforms.hemisphereLights.needsUpdate = value;
22831 }
22832 function materialNeedsLights( material ) {
22833 return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial ||
22834 material.isMeshStandardMaterial || material.isShadowMaterial ||
22835 ( material.isShaderMaterial && material.lights === true );
22836 }
22837 this.setFramebuffer = function ( value ) {
22838 if ( _framebuffer !== value && _currentRenderTarget === null ) _gl.bindFramebuffer( 36160, value );
22839 _framebuffer = value;
22840 };
22841 this.getActiveCubeFace = function () {
22842 return _currentActiveCubeFace;
22843 };
22844 this.getActiveMipmapLevel = function () {
22845 return _currentActiveMipmapLevel;
22846 };
22847 this.getRenderList = function () {
22848 return currentRenderList;
22849 };
22850 this.setRenderList = function ( renderList ) {
22851 currentRenderList = renderList;
22852 };
22853 this.getRenderState = function () {
22854 return currentRenderState;
22855 };
22856 this.setRenderState = function ( renderState ) {
22857 currentRenderState = renderState;
22858 };
22859 this.getRenderTarget = function () {
22860 return _currentRenderTarget;
22861 };
22862 this.setRenderTarget = function ( renderTarget, activeCubeFace = 0, activeMipmapLevel = 0 ) {
22863 _currentRenderTarget = renderTarget;
22864 _currentActiveCubeFace = activeCubeFace;
22865 _currentActiveMipmapLevel = activeMipmapLevel;
22866 if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
22867 textures.setupRenderTarget( renderTarget );
22868 }
22869 let framebuffer = _framebuffer;
22870 let isCube = false;
22871 if ( renderTarget ) {
22872 const __webglFramebuffer = properties.get( renderTarget ).__webglFramebuffer;
22873 if ( renderTarget.isWebGLCubeRenderTarget ) {
22874 framebuffer = __webglFramebuffer[ activeCubeFace ];
22875 isCube = true;
22876 } else if ( renderTarget.isWebGLMultisampleRenderTarget ) {
22877 framebuffer = properties.get( renderTarget ).__webglMultisampledFramebuffer;
22878 } else {
22879 framebuffer = __webglFramebuffer;
22880 }
22881 _currentViewport.copy( renderTarget.viewport );
22882 _currentScissor.copy( renderTarget.scissor );
22883 _currentScissorTest = renderTarget.scissorTest;
22884 } else {
22885 _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor();
22886 _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor();
22887 _currentScissorTest = _scissorTest;
22888 }
22889 if ( _currentFramebuffer !== framebuffer ) {
22890 _gl.bindFramebuffer( 36160, framebuffer );
22891 _currentFramebuffer = framebuffer;
22892 }
22893 state.viewport( _currentViewport );
22894 state.scissor( _currentScissor );
22895 state.setScissorTest( _currentScissorTest );
22896 if ( isCube ) {
22897 const textureProperties = properties.get( renderTarget.texture );
22898 _gl.framebufferTexture2D( 36160, 36064, 34069 + activeCubeFace, textureProperties.__webglTexture, activeMipmapLevel );
22899 }
22900 };
22901 this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer, activeCubeFaceIndex ) {
22902 if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
22903 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
22904 return;
22905 }
22906 let framebuffer = properties.get( renderTarget ).__webglFramebuffer;
22907 if ( renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined ) {
22908 framebuffer = framebuffer[ activeCubeFaceIndex ];
22909 }
22910 if ( framebuffer ) {
22911 let restore = false;
22912 if ( framebuffer !== _currentFramebuffer ) {
22913 _gl.bindFramebuffer( 36160, framebuffer );
22914 restore = true;
22915 }
22916 try {
22917 const texture = renderTarget.texture;
22918 const textureFormat = texture.format;
22919 const textureType = texture.type;
22920 if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( 35739 ) ) {
22921 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );
22922 return;
22923 }
22924 if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( 35738 ) &&
22925 ! ( textureType === FloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) &&
22926 ! ( textureType === HalfFloatType && ( capabilities.isWebGL2 ? extensions.get( 'EXT_color_buffer_float' ) : extensions.get( 'EXT_color_buffer_half_float' ) ) ) ) {
22927 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
22928 return;
22929 }
22930 if ( _gl.checkFramebufferStatus( 36160 ) === 36053 ) {
22931 if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {
22932 _gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
22933 }
22934 } else {
22935 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );
22936 }
22937 } finally {
22938 if ( restore ) {
22939 _gl.bindFramebuffer( 36160, _currentFramebuffer );
22940 }
22941 }
22942 }
22943 };
22944 this.copyFramebufferToTexture = function ( position, texture, level ) {
22945 if ( level === undefined ) level = 0;
22946 const levelScale = Math.pow( 2, - level );
22947 const width = Math.floor( texture.image.width * levelScale );
22948 const height = Math.floor( texture.image.height * levelScale );
22949 const glFormat = utils.convert( texture.format );
22950 textures.setTexture2D( texture, 0 );
22951 _gl.copyTexImage2D( 3553, level, glFormat, position.x, position.y, width, height, 0 );
22952 state.unbindTexture();
22953 };
22954 this.copyTextureToTexture = function ( position, srcTexture, dstTexture, level ) {
22955 if ( level === undefined ) level = 0;
22956 const width = srcTexture.image.width;
22957 const height = srcTexture.image.height;
22958 const glFormat = utils.convert( dstTexture.format );
22959 const glType = utils.convert( dstTexture.type );
22960 textures.setTexture2D( dstTexture, 0 );
22961 _gl.pixelStorei( 37440, dstTexture.flipY );
22962 _gl.pixelStorei( 37441, dstTexture.premultiplyAlpha );
22963 _gl.pixelStorei( 3317, dstTexture.unpackAlignment );
22964 if ( srcTexture.isDataTexture ) {
22965 _gl.texSubImage2D( 3553, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data );
22966 } else {
22967 if ( srcTexture.isCompressedTexture ) {
22968 _gl.compressedTexSubImage2D( 3553, level, position.x, position.y, srcTexture.mipmaps[ 0 ].width, srcTexture.mipmaps[ 0 ].height, glFormat, srcTexture.mipmaps[ 0 ].data );
22969 } else {
22970 _gl.texSubImage2D( 3553, level, position.x, position.y, glFormat, glType, srcTexture.image );
22971 }
22972 }
22973 if ( level === 0 && dstTexture.generateMipmaps ) _gl.generateMipmap( 3553 );
22974 state.unbindTexture();
22975 };
22976 this.initTexture = function ( texture ) {
22977 textures.setTexture2D( texture, 0 );
22978 state.unbindTexture();
22979 };
22980 if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
22981 __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) );
22982 }
22983 }
22984 function WebGL1Renderer( parameters ) {
22985 WebGLRenderer.call( this, parameters );
22986 }
22987 WebGL1Renderer.prototype = Object.assign( Object.create( WebGLRenderer.prototype ), {
22988 constructor: WebGL1Renderer,
22989 isWebGL1Renderer: true
22990 } );
22991 class FogExp2 {
22992 constructor( color, density ) {
22993 Object.defineProperty( this, 'isFogExp2', { value: true } );
22994 this.name = '';
22995 this.color = new Color( color );
22996 this.density = ( density !== undefined ) ? density : 0.00025;
22997 }
22998 clone() {
22999 return new FogExp2( this.color, this.density );
23000 }
23001 toJSON( ) {
23002 return {
23003 type: 'FogExp2',
23004 color: this.color.getHex(),
23005 density: this.density
23006 };
23007 }
23008 }
23009 class Fog {
23010 constructor( color, near, far ) {
23011 Object.defineProperty( this, 'isFog', { value: true } );
23012 this.name = '';
23013 this.color = new Color( color );
23014 this.near = ( near !== undefined ) ? near : 1;
23015 this.far = ( far !== undefined ) ? far : 1000;
23016 }
23017 clone() {
23018 return new Fog( this.color, this.near, this.far );
23019 }
23020 toJSON( ) {
23021 return {
23022 type: 'Fog',
23023 color: this.color.getHex(),
23024 near: this.near,
23025 far: this.far
23026 };
23027 }
23028 }
23029 class Scene extends Object3D {
23030 constructor() {
23031 super();
23032 Object.defineProperty( this, 'isScene', { value: true } );
23033 this.type = 'Scene';
23034 this.background = null;
23035 this.environment = null;
23036 this.fog = null;
23037 this.overrideMaterial = null;
23038 this.autoUpdate = true;
23039 if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
23040 __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) );
23041 }
23042 }
23043 copy( source, recursive ) {
23044 super.copy( source, recursive );
23045 if ( source.background !== null ) this.background = source.background.clone();
23046 if ( source.environment !== null ) this.environment = source.environment.clone();
23047 if ( source.fog !== null ) this.fog = source.fog.clone();
23048 if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
23049 this.autoUpdate = source.autoUpdate;
23050 this.matrixAutoUpdate = source.matrixAutoUpdate;
23051 return this;
23052 }
23053 toJSON( meta ) {
23054 const data = super.toJSON( meta );
23055 if ( this.background !== null ) data.object.background = this.background.toJSON( meta );
23056 if ( this.environment !== null ) data.object.environment = this.environment.toJSON( meta );
23057 if ( this.fog !== null ) data.object.fog = this.fog.toJSON();
23058 return data;
23059 }
23060 }
23061 function InterleavedBuffer( array, stride ) {
23062 this.array = array;
23063 this.stride = stride;
23064 this.count = array !== undefined ? array.length / stride : 0;
23065 this.usage = StaticDrawUsage;
23066 this.updateRange = { offset: 0, count: - 1 };
23067 this.version = 0;
23068 this.uuid = MathUtils.generateUUID();
23069 }
23070 Object.defineProperty( InterleavedBuffer.prototype, 'needsUpdate', {
23071 set: function ( value ) {
23072 if ( value === true ) this.version ++;
23073 }
23074 } );
23075 Object.assign( InterleavedBuffer.prototype, {
23076 isInterleavedBuffer: true,
23077 onUploadCallback: function () {},
23078 setUsage: function ( value ) {
23079 this.usage = value;
23080 return this;
23081 },
23082 copy: function ( source ) {
23083 this.array = new source.array.constructor( source.array );
23084 this.count = source.count;
23085 this.stride = source.stride;
23086 this.usage = source.usage;
23087 return this;
23088 },
23089 copyAt: function ( index1, attribute, index2 ) {
23090 index1 *= this.stride;
23091 index2 *= attribute.stride;
23092 for ( let i = 0, l = this.stride; i < l; i ++ ) {
23093 this.array[ index1 + i ] = attribute.array[ index2 + i ];
23094 }
23095 return this;
23096 },
23097 set: function ( value, offset ) {
23098 if ( offset === undefined ) offset = 0;
23099 this.array.set( value, offset );
23100 return this;
23101 },
23102 clone: function ( data ) {
23103 if ( data.arrayBuffers === undefined ) {
23104 data.arrayBuffers = {};
23105 }
23106 if ( this.array.buffer._uuid === undefined ) {
23107 this.array.buffer._uuid = MathUtils.generateUUID();
23108 }
23109 if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) {
23110 data.arrayBuffers[ this.array.buffer._uuid ] = this.array.slice( 0 ).buffer;
23111 }
23112 const array = new this.array.constructor( data.arrayBuffers[ this.array.buffer._uuid ] );
23113 const ib = new InterleavedBuffer( array, this.stride );
23114 ib.setUsage( this.usage );
23115 return ib;
23116 },
23117 onUpload: function ( callback ) {
23118 this.onUploadCallback = callback;
23119 return this;
23120 },
23121 toJSON: function ( data ) {
23122 if ( data.arrayBuffers === undefined ) {
23123 data.arrayBuffers = {};
23124 }
23125 if ( this.array.buffer._uuid === undefined ) {
23126 this.array.buffer._uuid = MathUtils.generateUUID();
23127 }
23128 if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) {
23129 data.arrayBuffers[ this.array.buffer._uuid ] = Array.prototype.slice.call( new Uint32Array( this.array.buffer ) );
23130 }
23131 return {
23132 uuid: this.uuid,
23133 buffer: this.array.buffer._uuid,
23134 type: this.array.constructor.name,
23135 stride: this.stride
23136 };
23137 }
23138 } );
23139 const _vector$6 = new Vector3();
23140 function InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {
23141 this.name = '';
23142 this.data = interleavedBuffer;
23143 this.itemSize = itemSize;
23144 this.offset = offset;
23145 this.normalized = normalized === true;
23146 }
23147 Object.defineProperties( InterleavedBufferAttribute.prototype, {
23148 count: {
23149 get: function () {
23150 return this.data.count;
23151 }
23152 },
23153 array: {
23154 get: function () {
23155 return this.data.array;
23156 }
23157 },
23158 needsUpdate: {
23159 set: function ( value ) {
23160 this.data.needsUpdate = value;
23161 }
23162 }
23163 } );
23164 Object.assign( InterleavedBufferAttribute.prototype, {
23165 isInterleavedBufferAttribute: true,
23166 applyMatrix4: function ( m ) {
23167 for ( let i = 0, l = this.data.count; i < l; i ++ ) {
23168 _vector$6.x = this.getX( i );
23169 _vector$6.y = this.getY( i );
23170 _vector$6.z = this.getZ( i );
23171 _vector$6.applyMatrix4( m );
23172 this.setXYZ( i, _vector$6.x, _vector$6.y, _vector$6.z );
23173 }
23174 return this;
23175 },
23176 setX: function ( index, x ) {
23177 this.data.array[ index * this.data.stride + this.offset ] = x;
23178 return this;
23179 },
23180 setY: function ( index, y ) {
23181 this.data.array[ index * this.data.stride + this.offset + 1 ] = y;
23182 return this;
23183 },
23184 setZ: function ( index, z ) {
23185 this.data.array[ index * this.data.stride + this.offset + 2 ] = z;
23186 return this;
23187 },
23188 setW: function ( index, w ) {
23189 this.data.array[ index * this.data.stride + this.offset + 3 ] = w;
23190 return this;
23191 },
23192 getX: function ( index ) {
23193 return this.data.array[ index * this.data.stride + this.offset ];
23194 },
23195 getY: function ( index ) {
23196 return this.data.array[ index * this.data.stride + this.offset + 1 ];
23197 },
23198 getZ: function ( index ) {
23199 return this.data.array[ index * this.data.stride + this.offset + 2 ];
23200 },
23201 getW: function ( index ) {
23202 return this.data.array[ index * this.data.stride + this.offset + 3 ];
23203 },
23204 setXY: function ( index, x, y ) {
23205 index = index * this.data.stride + this.offset;
23206 this.data.array[ index + 0 ] = x;
23207 this.data.array[ index + 1 ] = y;
23208 return this;
23209 },
23210 setXYZ: function ( index, x, y, z ) {
23211 index = index * this.data.stride + this.offset;
23212 this.data.array[ index + 0 ] = x;
23213 this.data.array[ index + 1 ] = y;
23214 this.data.array[ index + 2 ] = z;
23215 return this;
23216 },
23217 setXYZW: function ( index, x, y, z, w ) {
23218 index = index * this.data.stride + this.offset;
23219 this.data.array[ index + 0 ] = x;
23220 this.data.array[ index + 1 ] = y;
23221 this.data.array[ index + 2 ] = z;
23222 this.data.array[ index + 3 ] = w;
23223 return this;
23224 },
23225 clone: function ( data ) {
23226 if ( data === undefined ) {
23227 console.log( 'THREE.InterleavedBufferAttribute.clone(): Cloning an interlaved buffer attribute will deinterleave buffer data.' );
23228 const array = [];
23229 for ( let i = 0; i < this.count; i ++ ) {
23230 const index = i * this.data.stride + this.offset;
23231 for ( let j = 0; j < this.itemSize; j ++ ) {
23232 array.push( this.data.array[ index + j ] );
23233 }
23234 }
23235 return new BufferAttribute( new this.array.constructor( array ), this.itemSize, this.normalized );
23236 } else {
23237 if ( data.interleavedBuffers === undefined ) {
23238 data.interleavedBuffers = {};
23239 }
23240 if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) {
23241 data.interleavedBuffers[ this.data.uuid ] = this.data.clone( data );
23242 }
23243 return new InterleavedBufferAttribute( data.interleavedBuffers[ this.data.uuid ], this.itemSize, this.offset, this.normalized );
23244 }
23245 },
23246 toJSON: function ( data ) {
23247 if ( data === undefined ) {
23248 console.log( 'THREE.InterleavedBufferAttribute.toJSON(): Serializing an interlaved buffer attribute will deinterleave buffer data.' );
23249 const array = [];
23250 for ( let i = 0; i < this.count; i ++ ) {
23251 const index = i * this.data.stride + this.offset;
23252 for ( let j = 0; j < this.itemSize; j ++ ) {
23253 array.push( this.data.array[ index + j ] );
23254 }
23255 }
23256 return {
23257 itemSize: this.itemSize,
23258 type: this.array.constructor.name,
23259 array: array,
23260 normalized: this.normalized
23261 };
23262 } else {
23263 if ( data.interleavedBuffers === undefined ) {
23264 data.interleavedBuffers = {};
23265 }
23266 if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) {
23267 data.interleavedBuffers[ this.data.uuid ] = this.data.toJSON( data );
23268 }
23269 return {
23270 isInterleavedBufferAttribute: true,
23271 itemSize: this.itemSize,
23272 data: this.data.uuid,
23273 offset: this.offset,
23274 normalized: this.normalized
23275 };
23276 }
23277 }
23278 } );
23279 function SpriteMaterial( parameters ) {
23280 Material.call( this );
23281 this.type = 'SpriteMaterial';
23282 this.color = new Color( 0xffffff );
23283 this.map = null;
23284 this.alphaMap = null;
23285 this.rotation = 0;
23286 this.sizeAttenuation = true;
23287 this.transparent = true;
23288 this.setValues( parameters );
23289 }
23290 SpriteMaterial.prototype = Object.create( Material.prototype );
23291 SpriteMaterial.prototype.constructor = SpriteMaterial;
23292 SpriteMaterial.prototype.isSpriteMaterial = true;
23293 SpriteMaterial.prototype.copy = function ( source ) {
23294 Material.prototype.copy.call( this, source );
23295 this.color.copy( source.color );
23296 this.map = source.map;
23297 this.alphaMap = source.alphaMap;
23298 this.rotation = source.rotation;
23299 this.sizeAttenuation = source.sizeAttenuation;
23300 return this;
23301 };
23302 let _geometry;
23303 const _intersectPoint = new Vector3();
23304 const _worldScale = new Vector3();
23305 const _mvPosition = new Vector3();
23306 const _alignedPosition = new Vector2();
23307 const _rotatedPosition = new Vector2();
23308 const _viewWorldMatrix = new Matrix4();
23309 const _vA$1 = new Vector3();
23310 const _vB$1 = new Vector3();
23311 const _vC$1 = new Vector3();
23312 const _uvA$1 = new Vector2();
23313 const _uvB$1 = new Vector2();
23314 const _uvC$1 = new Vector2();
23315 function Sprite( material ) {
23316 Object3D.call( this );
23317 this.type = 'Sprite';
23318 if ( _geometry === undefined ) {
23319 _geometry = new BufferGeometry();
23320 const float32Array = new Float32Array( [
23321 - 0.5, - 0.5, 0, 0, 0,
23322 0.5, - 0.5, 0, 1, 0,
23323 0.5, 0.5, 0, 1, 1,
23324 - 0.5, 0.5, 0, 0, 1
23325 ] );
23326 const interleavedBuffer = new InterleavedBuffer( float32Array, 5 );
23327 _geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] );
23328 _geometry.setAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) );
23329 _geometry.setAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) );
23330 }
23331 this.geometry = _geometry;
23332 this.material = ( material !== undefined ) ? material : new SpriteMaterial();
23333 this.center = new Vector2( 0.5, 0.5 );
23334 }
23335 Sprite.prototype = Object.assign( Object.create( Object3D.prototype ), {
23336 constructor: Sprite,
23337 isSprite: true,
23338 raycast: function ( raycaster, intersects ) {
23339 if ( raycaster.camera === null ) {
23340 console.error( 'THREE.Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.' );
23341 }
23342 _worldScale.setFromMatrixScale( this.matrixWorld );
23343 _viewWorldMatrix.copy( raycaster.camera.matrixWorld );
23344 this.modelViewMatrix.multiplyMatrices( raycaster.camera.matrixWorldInverse, this.matrixWorld );
23345 _mvPosition.setFromMatrixPosition( this.modelViewMatrix );
23346 if ( raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false ) {
23347 _worldScale.multiplyScalar( - _mvPosition.z );
23348 }
23349 const rotation = this.material.rotation;
23350 let sin, cos;
23351 if ( rotation !== 0 ) {
23352 cos = Math.cos( rotation );
23353 sin = Math.sin( rotation );
23354 }
23355 const center = this.center;
23356 transformVertex( _vA$1.set( - 0.5, - 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );
23357 transformVertex( _vB$1.set( 0.5, - 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );
23358 transformVertex( _vC$1.set( 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );
23359 _uvA$1.set( 0, 0 );
23360 _uvB$1.set( 1, 0 );
23361 _uvC$1.set( 1, 1 );
23362 let intersect = raycaster.ray.intersectTriangle( _vA$1, _vB$1, _vC$1, false, _intersectPoint );
23363 if ( intersect === null ) {
23364 transformVertex( _vB$1.set( - 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );
23365 _uvB$1.set( 0, 1 );
23366 intersect = raycaster.ray.intersectTriangle( _vA$1, _vC$1, _vB$1, false, _intersectPoint );
23367 if ( intersect === null ) {
23368 return;
23369 }
23370 }
23371 const distance = raycaster.ray.origin.distanceTo( _intersectPoint );
23372 if ( distance < raycaster.near || distance > raycaster.far ) return;
23373 intersects.push( {
23374 distance: distance,
23375 point: _intersectPoint.clone(),
23376 uv: Triangle.getUV( _intersectPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2() ),
23377 face: null,
23378 object: this
23379 } );
23380 },
23381 copy: function ( source ) {
23382 Object3D.prototype.copy.call( this, source );
23383 if ( source.center !== undefined ) this.center.copy( source.center );
23384 this.material = source.material;
23385 return this;
23386 }
23387 } );
23388 function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) {
23389 _alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale );
23390 if ( sin !== undefined ) {
23391 _rotatedPosition.x = ( cos * _alignedPosition.x ) - ( sin * _alignedPosition.y );
23392 _rotatedPosition.y = ( sin * _alignedPosition.x ) + ( cos * _alignedPosition.y );
23393 } else {
23394 _rotatedPosition.copy( _alignedPosition );
23395 }
23396 vertexPosition.copy( mvPosition );
23397 vertexPosition.x += _rotatedPosition.x;
23398 vertexPosition.y += _rotatedPosition.y;
23399 vertexPosition.applyMatrix4( _viewWorldMatrix );
23400 }
23401 const _v1$4 = new Vector3();
23402 const _v2$2 = new Vector3();
23403 function LOD() {
23404 Object3D.call( this );
23405 this._currentLevel = 0;
23406 this.type = 'LOD';
23407 Object.defineProperties( this, {
23408 levels: {
23409 enumerable: true,
23410 value: []
23411 }
23412 } );
23413 this.autoUpdate = true;
23414 }
23415 LOD.prototype = Object.assign( Object.create( Object3D.prototype ), {
23416 constructor: LOD,
23417 isLOD: true,
23418 copy: function ( source ) {
23419 Object3D.prototype.copy.call( this, source, false );
23420 const levels = source.levels;
23421 for ( let i = 0, l = levels.length; i < l; i ++ ) {
23422 const level = levels[ i ];
23423 this.addLevel( level.object.clone(), level.distance );
23424 }
23425 this.autoUpdate = source.autoUpdate;
23426 return this;
23427 },
23428 addLevel: function ( object, distance ) {
23429 if ( distance === undefined ) distance = 0;
23430 distance = Math.abs( distance );
23431 const levels = this.levels;
23432 let l;
23433 for ( l = 0; l < levels.length; l ++ ) {
23434 if ( distance < levels[ l ].distance ) {
23435 break;
23436 }
23437 }
23438 levels.splice( l, 0, { distance: distance, object: object } );
23439 this.add( object );
23440 return this;
23441 },
23442 getCurrentLevel: function () {
23443 return this._currentLevel;
23444 },
23445 getObjectForDistance: function ( distance ) {
23446 const levels = this.levels;
23447 if ( levels.length > 0 ) {
23448 let i, l;
23449 for ( i = 1, l = levels.length; i < l; i ++ ) {
23450 if ( distance < levels[ i ].distance ) {
23451 break;
23452 }
23453 }
23454 return levels[ i - 1 ].object;
23455 }
23456 return null;
23457 },
23458 raycast: function ( raycaster, intersects ) {
23459 const levels = this.levels;
23460 if ( levels.length > 0 ) {
23461 _v1$4.setFromMatrixPosition( this.matrixWorld );
23462 const distance = raycaster.ray.origin.distanceTo( _v1$4 );
23463 this.getObjectForDistance( distance ).raycast( raycaster, intersects );
23464 }
23465 },
23466 update: function ( camera ) {
23467 const levels = this.levels;
23468 if ( levels.length > 1 ) {
23469 _v1$4.setFromMatrixPosition( camera.matrixWorld );
23470 _v2$2.setFromMatrixPosition( this.matrixWorld );
23471 const distance = _v1$4.distanceTo( _v2$2 ) / camera.zoom;
23472 levels[ 0 ].object.visible = true;
23473 let i, l;
23474 for ( i = 1, l = levels.length; i < l; i ++ ) {
23475 if ( distance >= levels[ i ].distance ) {
23476 levels[ i - 1 ].object.visible = false;
23477 levels[ i ].object.visible = true;
23478 } else {
23479 break;
23480 }
23481 }
23482 this._currentLevel = i - 1;
23483 for ( ; i < l; i ++ ) {
23484 levels[ i ].object.visible = false;
23485 }
23486 }
23487 },
23488 toJSON: function ( meta ) {
23489 const data = Object3D.prototype.toJSON.call( this, meta );
23490 if ( this.autoUpdate === false ) data.object.autoUpdate = false;
23491 data.object.levels = [];
23492 const levels = this.levels;
23493 for ( let i = 0, l = levels.length; i < l; i ++ ) {
23494 const level = levels[ i ];
23495 data.object.levels.push( {
23496 object: level.object.uuid,
23497 distance: level.distance
23498 } );
23499 }
23500 return data;
23501 }
23502 } );
23503 function SkinnedMesh( geometry, material ) {
23504 if ( geometry && geometry.isGeometry ) {
23505 console.error( 'THREE.SkinnedMesh no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );
23506 }
23507 Mesh.call( this, geometry, material );
23508 this.type = 'SkinnedMesh';
23509 this.bindMode = 'attached';
23510 this.bindMatrix = new Matrix4();
23511 this.bindMatrixInverse = new Matrix4();
23512 }
23513 SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
23514 constructor: SkinnedMesh,
23515 isSkinnedMesh: true,
23516 copy: function ( source ) {
23517 Mesh.prototype.copy.call( this, source );
23518 this.bindMode = source.bindMode;
23519 this.bindMatrix.copy( source.bindMatrix );
23520 this.bindMatrixInverse.copy( source.bindMatrixInverse );
23521 this.skeleton = source.skeleton;
23522 return this;
23523 },
23524 bind: function ( skeleton, bindMatrix ) {
23525 this.skeleton = skeleton;
23526 if ( bindMatrix === undefined ) {
23527 this.updateMatrixWorld( true );
23528 this.skeleton.calculateInverses();
23529 bindMatrix = this.matrixWorld;
23530 }
23531 this.bindMatrix.copy( bindMatrix );
23532 this.bindMatrixInverse.getInverse( bindMatrix );
23533 },
23534 pose: function () {
23535 this.skeleton.pose();
23536 },
23537 normalizeSkinWeights: function () {
23538 const vector = new Vector4();
23539 const skinWeight = this.geometry.attributes.skinWeight;
23540 for ( let i = 0, l = skinWeight.count; i < l; i ++ ) {
23541 vector.x = skinWeight.getX( i );
23542 vector.y = skinWeight.getY( i );
23543 vector.z = skinWeight.getZ( i );
23544 vector.w = skinWeight.getW( i );
23545 const scale = 1.0 / vector.manhattanLength();
23546 if ( scale !== Infinity ) {
23547 vector.multiplyScalar( scale );
23548 } else {
23549 vector.set( 1, 0, 0, 0 );
23550 }
23551 skinWeight.setXYZW( i, vector.x, vector.y, vector.z, vector.w );
23552 }
23553 },
23554 updateMatrixWorld: function ( force ) {
23555 Mesh.prototype.updateMatrixWorld.call( this, force );
23556 if ( this.bindMode === 'attached' ) {
23557 this.bindMatrixInverse.getInverse( this.matrixWorld );
23558 } else if ( this.bindMode === 'detached' ) {
23559 this.bindMatrixInverse.getInverse( this.bindMatrix );
23560 } else {
23561 console.warn( 'THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode );
23562 }
23563 },
23564 boneTransform: ( function () {
23565 const basePosition = new Vector3();
23566 const skinIndex = new Vector4();
23567 const skinWeight = new Vector4();
23568 const vector = new Vector3();
23569 const matrix = new Matrix4();
23570 return function ( index, target ) {
23571 const skeleton = this.skeleton;
23572 const geometry = this.geometry;
23573 skinIndex.fromBufferAttribute( geometry.attributes.skinIndex, index );
23574 skinWeight.fromBufferAttribute( geometry.attributes.skinWeight, index );
23575 basePosition.fromBufferAttribute( geometry.attributes.position, index ).applyMatrix4( this.bindMatrix );
23576 target.set( 0, 0, 0 );
23577 for ( let i = 0; i < 4; i ++ ) {
23578 const weight = skinWeight.getComponent( i );
23579 if ( weight !== 0 ) {
23580 const boneIndex = skinIndex.getComponent( i );
23581 matrix.multiplyMatrices( skeleton.bones[ boneIndex ].matrixWorld, skeleton.boneInverses[ boneIndex ] );
23582 target.addScaledVector( vector.copy( basePosition ).applyMatrix4( matrix ), weight );
23583 }
23584 }
23585 return target.applyMatrix4( this.bindMatrixInverse );
23586 };
23587 }() )
23588 } );
23589 const _offsetMatrix = new Matrix4();
23590 const _identityMatrix = new Matrix4();
23591 function Skeleton( bones, boneInverses ) {
23592 bones = bones || [];
23593 this.bones = bones.slice( 0 );
23594 this.boneMatrices = new Float32Array( this.bones.length * 16 );
23595 this.frame = - 1;
23596 if ( boneInverses === undefined ) {
23597 this.calculateInverses();
23598 } else {
23599 if ( this.bones.length === boneInverses.length ) {
23600 this.boneInverses = boneInverses.slice( 0 );
23601 } else {
23602 console.warn( 'THREE.Skeleton boneInverses is the wrong length.' );
23603 this.boneInverses = [];
23604 for ( let i = 0, il = this.bones.length; i < il; i ++ ) {
23605 this.boneInverses.push( new Matrix4() );
23606 }
23607 }
23608 }
23609 }
23610 Object.assign( Skeleton.prototype, {
23611 calculateInverses: function () {
23612 this.boneInverses = [];
23613 for ( let i = 0, il = this.bones.length; i < il; i ++ ) {
23614 const inverse = new Matrix4();
23615 if ( this.bones[ i ] ) {
23616 inverse.getInverse( this.bones[ i ].matrixWorld );
23617 }
23618 this.boneInverses.push( inverse );
23619 }
23620 },
23621 pose: function () {
23622 for ( let i = 0, il = this.bones.length; i < il; i ++ ) {
23623 const bone = this.bones[ i ];
23624 if ( bone ) {
23625 bone.matrixWorld.getInverse( this.boneInverses[ i ] );
23626 }
23627 }
23628 for ( let i = 0, il = this.bones.length; i < il; i ++ ) {
23629 const bone = this.bones[ i ];
23630 if ( bone ) {
23631 if ( bone.parent && bone.parent.isBone ) {
23632 bone.matrix.getInverse( bone.parent.matrixWorld );
23633 bone.matrix.multiply( bone.matrixWorld );
23634 } else {
23635 bone.matrix.copy( bone.matrixWorld );
23636 }
23637 bone.matrix.decompose( bone.position, bone.quaternion, bone.scale );
23638 }
23639 }
23640 },
23641 update: function () {
23642 const bones = this.bones;
23643 const boneInverses = this.boneInverses;
23644 const boneMatrices = this.boneMatrices;
23645 const boneTexture = this.boneTexture;
23646 for ( let i = 0, il = bones.length; i < il; i ++ ) {
23647 const matrix = bones[ i ] ? bones[ i ].matrixWorld : _identityMatrix;
23648 _offsetMatrix.multiplyMatrices( matrix, boneInverses[ i ] );
23649 _offsetMatrix.toArray( boneMatrices, i * 16 );
23650 }
23651 if ( boneTexture !== undefined ) {
23652 boneTexture.needsUpdate = true;
23653 }
23654 },
23655 clone: function () {
23656 return new Skeleton( this.bones, this.boneInverses );
23657 },
23658 getBoneByName: function ( name ) {
23659 for ( let i = 0, il = this.bones.length; i < il; i ++ ) {
23660 const bone = this.bones[ i ];
23661 if ( bone.name === name ) {
23662 return bone;
23663 }
23664 }
23665 return undefined;
23666 },
23667 dispose: function ( ) {
23668 if ( this.boneTexture ) {
23669 this.boneTexture.dispose();
23670 this.boneTexture = undefined;
23671 }
23672 }
23673 } );
23674 function Bone() {
23675 Object3D.call( this );
23676 this.type = 'Bone';
23677 }
23678 Bone.prototype = Object.assign( Object.create( Object3D.prototype ), {
23679 constructor: Bone,
23680 isBone: true
23681 } );
23682 const _instanceLocalMatrix = new Matrix4();
23683 const _instanceWorldMatrix = new Matrix4();
23684 const _instanceIntersects = [];
23685 const _mesh = new Mesh();
23686 function InstancedMesh( geometry, material, count ) {
23687 Mesh.call( this, geometry, material );
23688 this.instanceMatrix = new BufferAttribute( new Float32Array( count * 16 ), 16 );
23689 this.instanceColor = null;
23690 this.count = count;
23691 this.frustumCulled = false;
23692 }
23693 InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
23694 constructor: InstancedMesh,
23695 isInstancedMesh: true,
23696 copy: function ( source ) {
23697 Mesh.prototype.copy.call( this, source );
23698 this.instanceMatrix.copy( source.instanceMatrix );
23699 this.count = source.count;
23700 return this;
23701 },
23702 setColorAt: function ( index, color ) {
23703 if ( this.instanceColor === null ) {
23704 this.instanceColor = new BufferAttribute( new Float32Array( this.count * 3 ), 3 );
23705 }
23706 color.toArray( this.instanceColor.array, index * 3 );
23707 },
23708 getMatrixAt: function ( index, matrix ) {
23709 matrix.fromArray( this.instanceMatrix.array, index * 16 );
23710 },
23711 raycast: function ( raycaster, intersects ) {
23712 const matrixWorld = this.matrixWorld;
23713 const raycastTimes = this.count;
23714 _mesh.geometry = this.geometry;
23715 _mesh.material = this.material;
23716 if ( _mesh.material === undefined ) return;
23717 for ( let instanceId = 0; instanceId < raycastTimes; instanceId ++ ) {
23718 this.getMatrixAt( instanceId, _instanceLocalMatrix );
23719 _instanceWorldMatrix.multiplyMatrices( matrixWorld, _instanceLocalMatrix );
23720 _mesh.matrixWorld = _instanceWorldMatrix;
23721 _mesh.raycast( raycaster, _instanceIntersects );
23722 for ( let i = 0, l = _instanceIntersects.length; i < l; i ++ ) {
23723 const intersect = _instanceIntersects[ i ];
23724 intersect.instanceId = instanceId;
23725 intersect.object = this;
23726 intersects.push( intersect );
23727 }
23728 _instanceIntersects.length = 0;
23729 }
23730 },
23731 setMatrixAt: function ( index, matrix ) {
23732 matrix.toArray( this.instanceMatrix.array, index * 16 );
23733 },
23734 updateMorphTargets: function () {
23735 }
23736 } );
23737 function LineBasicMaterial( parameters ) {
23738 Material.call( this );
23739 this.type = 'LineBasicMaterial';
23740 this.color = new Color( 0xffffff );
23741 this.linewidth = 1;
23742 this.linecap = 'round';
23743 this.linejoin = 'round';
23744 this.morphTargets = false;
23745 this.setValues( parameters );
23746 }
23747 LineBasicMaterial.prototype = Object.create( Material.prototype );
23748 LineBasicMaterial.prototype.constructor = LineBasicMaterial;
23749 LineBasicMaterial.prototype.isLineBasicMaterial = true;
23750 LineBasicMaterial.prototype.copy = function ( source ) {
23751 Material.prototype.copy.call( this, source );
23752 this.color.copy( source.color );
23753 this.linewidth = source.linewidth;
23754 this.linecap = source.linecap;
23755 this.linejoin = source.linejoin;
23756 this.morphTargets = source.morphTargets;
23757 return this;
23758 };
23759 const _start = new Vector3();
23760 const _end = new Vector3();
23761 const _inverseMatrix$1 = new Matrix4();
23762 const _ray$1 = new Ray();
23763 const _sphere$2 = new Sphere();
23764 function Line( geometry, material, mode ) {
23765 if ( mode === 1 ) {
23766 console.error( 'THREE.Line: parameter THREE.LinePieces no longer supported. Use THREE.LineSegments instead.' );
23767 }
23768 Object3D.call( this );
23769 this.type = 'Line';
23770 this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
23771 this.material = material !== undefined ? material : new LineBasicMaterial();
23772 this.updateMorphTargets();
23773 }
23774 Line.prototype = Object.assign( Object.create( Object3D.prototype ), {
23775 constructor: Line,
23776 isLine: true,
23777 copy: function ( source ) {
23778 Object3D.prototype.copy.call( this, source );
23779 this.material = source.material;
23780 this.geometry = source.geometry;
23781 return this;
23782 },
23783 computeLineDistances: function () {
23784 const geometry = this.geometry;
23785 if ( geometry.isBufferGeometry ) {
23786 if ( geometry.index === null ) {
23787 const positionAttribute = geometry.attributes.position;
23788 const lineDistances = [ 0 ];
23789 for ( let i = 1, l = positionAttribute.count; i < l; i ++ ) {
23790 _start.fromBufferAttribute( positionAttribute, i - 1 );
23791 _end.fromBufferAttribute( positionAttribute, i );
23792 lineDistances[ i ] = lineDistances[ i - 1 ];
23793 lineDistances[ i ] += _start.distanceTo( _end );
23794 }
23795 geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) );
23796 } else {
23797 console.warn( 'THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' );
23798 }
23799 } else if ( geometry.isGeometry ) {
23800 const vertices = geometry.vertices;
23801 const lineDistances = geometry.lineDistances;
23802 lineDistances[ 0 ] = 0;
23803 for ( let i = 1, l = vertices.length; i < l; i ++ ) {
23804 lineDistances[ i ] = lineDistances[ i - 1 ];
23805 lineDistances[ i ] += vertices[ i - 1 ].distanceTo( vertices[ i ] );
23806 }
23807 }
23808 return this;
23809 },
23810 raycast: function ( raycaster, intersects ) {
23811 const geometry = this.geometry;
23812 const matrixWorld = this.matrixWorld;
23813 const threshold = raycaster.params.Line.threshold;
23814 if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
23815 _sphere$2.copy( geometry.boundingSphere );
23816 _sphere$2.applyMatrix4( matrixWorld );
23817 _sphere$2.radius += threshold;
23818 if ( raycaster.ray.intersectsSphere( _sphere$2 ) === false ) return;
23819 _inverseMatrix$1.getInverse( matrixWorld );
23820 _ray$1.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$1 );
23821 const localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
23822 const localThresholdSq = localThreshold * localThreshold;
23823 const vStart = new Vector3();
23824 const vEnd = new Vector3();
23825 const interSegment = new Vector3();
23826 const interRay = new Vector3();
23827 const step = ( this && this.isLineSegments ) ? 2 : 1;
23828 if ( geometry.isBufferGeometry ) {
23829 const index = geometry.index;
23830 const attributes = geometry.attributes;
23831 const positions = attributes.position.array;
23832 if ( index !== null ) {
23833 const indices = index.array;
23834 for ( let i = 0, l = indices.length - 1; i < l; i += step ) {
23835 const a = indices[ i ];
23836 const b = indices[ i + 1 ];
23837 vStart.fromArray( positions, a * 3 );
23838 vEnd.fromArray( positions, b * 3 );
23839 const distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
23840 if ( distSq > localThresholdSq ) continue;
23841 interRay.applyMatrix4( this.matrixWorld );
23842 const distance = raycaster.ray.origin.distanceTo( interRay );
23843 if ( distance < raycaster.near || distance > raycaster.far ) continue;
23844 intersects.push( {
23845 distance: distance,
23846 point: interSegment.clone().applyMatrix4( this.matrixWorld ),
23847 index: i,
23848 face: null,
23849 faceIndex: null,
23850 object: this
23851 } );
23852 }
23853 } else {
23854 for ( let i = 0, l = positions.length / 3 - 1; i < l; i += step ) {
23855 vStart.fromArray( positions, 3 * i );
23856 vEnd.fromArray( positions, 3 * i + 3 );
23857 const distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
23858 if ( distSq > localThresholdSq ) continue;
23859 interRay.applyMatrix4( this.matrixWorld );
23860 const distance = raycaster.ray.origin.distanceTo( interRay );
23861 if ( distance < raycaster.near || distance > raycaster.far ) continue;
23862 intersects.push( {
23863 distance: distance,
23864 point: interSegment.clone().applyMatrix4( this.matrixWorld ),
23865 index: i,
23866 face: null,
23867 faceIndex: null,
23868 object: this
23869 } );
23870 }
23871 }
23872 } else if ( geometry.isGeometry ) {
23873 const vertices = geometry.vertices;
23874 const nbVertices = vertices.length;
23875 for ( let i = 0; i < nbVertices - 1; i += step ) {
23876 const distSq = _ray$1.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
23877 if ( distSq > localThresholdSq ) continue;
23878 interRay.applyMatrix4( this.matrixWorld );
23879 const distance = raycaster.ray.origin.distanceTo( interRay );
23880 if ( distance < raycaster.near || distance > raycaster.far ) continue;
23881 intersects.push( {
23882 distance: distance,
23883 point: interSegment.clone().applyMatrix4( this.matrixWorld ),
23884 index: i,
23885 face: null,
23886 faceIndex: null,
23887 object: this
23888 } );
23889 }
23890 }
23891 },
23892 updateMorphTargets: function () {
23893 const geometry = this.geometry;
23894 if ( geometry.isBufferGeometry ) {
23895 const morphAttributes = geometry.morphAttributes;
23896 const keys = Object.keys( morphAttributes );
23897 if ( keys.length > 0 ) {
23898 const morphAttribute = morphAttributes[ keys[ 0 ] ];
23899 if ( morphAttribute !== undefined ) {
23900 this.morphTargetInfluences = [];
23901 this.morphTargetDictionary = {};
23902 for ( let m = 0, ml = morphAttribute.length; m < ml; m ++ ) {
23903 const name = morphAttribute[ m ].name || String( m );
23904 this.morphTargetInfluences.push( 0 );
23905 this.morphTargetDictionary[ name ] = m;
23906 }
23907 }
23908 }
23909 } else {
23910 const morphTargets = geometry.morphTargets;
23911 if ( morphTargets !== undefined && morphTargets.length > 0 ) {
23912 console.error( 'THREE.Line.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.' );
23913 }
23914 }
23915 }
23916 } );
23917 const _start$1 = new Vector3();
23918 const _end$1 = new Vector3();
23919 function LineSegments( geometry, material ) {
23920 Line.call( this, geometry, material );
23921 this.type = 'LineSegments';
23922 }
23923 LineSegments.prototype = Object.assign( Object.create( Line.prototype ), {
23924 constructor: LineSegments,
23925 isLineSegments: true,
23926 computeLineDistances: function () {
23927 const geometry = this.geometry;
23928 if ( geometry.isBufferGeometry ) {
23929 if ( geometry.index === null ) {
23930 const positionAttribute = geometry.attributes.position;
23931 const lineDistances = [];
23932 for ( let i = 0, l = positionAttribute.count; i < l; i += 2 ) {
23933 _start$1.fromBufferAttribute( positionAttribute, i );
23934 _end$1.fromBufferAttribute( positionAttribute, i + 1 );
23935 lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ];
23936 lineDistances[ i + 1 ] = lineDistances[ i ] + _start$1.distanceTo( _end$1 );
23937 }
23938 geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) );
23939 } else {
23940 console.warn( 'THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' );
23941 }
23942 } else if ( geometry.isGeometry ) {
23943 const vertices = geometry.vertices;
23944 const lineDistances = geometry.lineDistances;
23945 for ( let i = 0, l = vertices.length; i < l; i += 2 ) {
23946 _start$1.copy( vertices[ i ] );
23947 _end$1.copy( vertices[ i + 1 ] );
23948 lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ];
23949 lineDistances[ i + 1 ] = lineDistances[ i ] + _start$1.distanceTo( _end$1 );
23950 }
23951 }
23952 return this;
23953 }
23954 } );
23955 function LineLoop( geometry, material ) {
23956 Line.call( this, geometry, material );
23957 this.type = 'LineLoop';
23958 }
23959 LineLoop.prototype = Object.assign( Object.create( Line.prototype ), {
23960 constructor: LineLoop,
23961 isLineLoop: true,
23962 } );
23963 function PointsMaterial( parameters ) {
23964 Material.call( this );
23965 this.type = 'PointsMaterial';
23966 this.color = new Color( 0xffffff );
23967 this.map = null;
23968 this.alphaMap = null;
23969 this.size = 1;
23970 this.sizeAttenuation = true;
23971 this.morphTargets = false;
23972 this.setValues( parameters );
23973 }
23974 PointsMaterial.prototype = Object.create( Material.prototype );
23975 PointsMaterial.prototype.constructor = PointsMaterial;
23976 PointsMaterial.prototype.isPointsMaterial = true;
23977 PointsMaterial.prototype.copy = function ( source ) {
23978 Material.prototype.copy.call( this, source );
23979 this.color.copy( source.color );
23980 this.map = source.map;
23981 this.alphaMap = source.alphaMap;
23982 this.size = source.size;
23983 this.sizeAttenuation = source.sizeAttenuation;
23984 this.morphTargets = source.morphTargets;
23985 return this;
23986 };
23987 const _inverseMatrix$2 = new Matrix4();
23988 const _ray$2 = new Ray();
23989 const _sphere$3 = new Sphere();
23990 const _position$1 = new Vector3();
23991 function Points( geometry, material ) {
23992 Object3D.call( this );
23993 this.type = 'Points';
23994 this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
23995 this.material = material !== undefined ? material : new PointsMaterial();
23996 this.updateMorphTargets();
23997 }
23998 Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
23999 constructor: Points,
24000 isPoints: true,
24001 copy: function ( source ) {
24002 Object3D.prototype.copy.call( this, source );
24003 this.material = source.material;
24004 this.geometry = source.geometry;
24005 return this;
24006 },
24007 raycast: function ( raycaster, intersects ) {
24008 const geometry = this.geometry;
24009 const matrixWorld = this.matrixWorld;
24010 const threshold = raycaster.params.Points.threshold;
24011 if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
24012 _sphere$3.copy( geometry.boundingSphere );
24013 _sphere$3.applyMatrix4( matrixWorld );
24014 _sphere$3.radius += threshold;
24015 if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) return;
24016 _inverseMatrix$2.getInverse( matrixWorld );
24017 _ray$2.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$2 );
24018 const localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
24019 const localThresholdSq = localThreshold * localThreshold;
24020 if ( geometry.isBufferGeometry ) {
24021 const index = geometry.index;
24022 const attributes = geometry.attributes;
24023 const positions = attributes.position.array;
24024 if ( index !== null ) {
24025 const indices = index.array;
24026 for ( let i = 0, il = indices.length; i < il; i ++ ) {
24027 const a = indices[ i ];
24028 _position$1.fromArray( positions, a * 3 );
24029 testPoint( _position$1, a, localThresholdSq, matrixWorld, raycaster, intersects, this );
24030 }
24031 } else {
24032 for ( let i = 0, l = positions.length / 3; i < l; i ++ ) {
24033 _position$1.fromArray( positions, i * 3 );
24034 testPoint( _position$1, i, localThresholdSq, matrixWorld, raycaster, intersects, this );
24035 }
24036 }
24037 } else {
24038 const vertices = geometry.vertices;
24039 for ( let i = 0, l = vertices.length; i < l; i ++ ) {
24040 testPoint( vertices[ i ], i, localThresholdSq, matrixWorld, raycaster, intersects, this );
24041 }
24042 }
24043 },
24044 updateMorphTargets: function () {
24045 const geometry = this.geometry;
24046 if ( geometry.isBufferGeometry ) {
24047 const morphAttributes = geometry.morphAttributes;
24048 const keys = Object.keys( morphAttributes );
24049 if ( keys.length > 0 ) {
24050 const morphAttribute = morphAttributes[ keys[ 0 ] ];
24051 if ( morphAttribute !== undefined ) {
24052 this.morphTargetInfluences = [];
24053 this.morphTargetDictionary = {};
24054 for ( let m = 0, ml = morphAttribute.length; m < ml; m ++ ) {
24055 const name = morphAttribute[ m ].name || String( m );
24056 this.morphTargetInfluences.push( 0 );
24057 this.morphTargetDictionary[ name ] = m;
24058 }
24059 }
24060 }
24061 } else {
24062 const morphTargets = geometry.morphTargets;
24063 if ( morphTargets !== undefined && morphTargets.length > 0 ) {
24064 console.error( 'THREE.Points.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.' );
24065 }
24066 }
24067 }
24068 } );
24069 function testPoint( point, index, localThresholdSq, matrixWorld, raycaster, intersects, object ) {
24070 const rayPointDistanceSq = _ray$2.distanceSqToPoint( point );
24071 if ( rayPointDistanceSq < localThresholdSq ) {
24072 const intersectPoint = new Vector3();
24073 _ray$2.closestPointToPoint( point, intersectPoint );
24074 intersectPoint.applyMatrix4( matrixWorld );
24075 const distance = raycaster.ray.origin.distanceTo( intersectPoint );
24076 if ( distance < raycaster.near || distance > raycaster.far ) return;
24077 intersects.push( {
24078 distance: distance,
24079 distanceToRay: Math.sqrt( rayPointDistanceSq ),
24080 point: intersectPoint,
24081 index: index,
24082 face: null,
24083 object: object
24084 } );
24085 }
24086 }
24087 function VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
24088 Texture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
24089 this.format = format !== undefined ? format : RGBFormat;
24090 this.minFilter = minFilter !== undefined ? minFilter : LinearFilter;
24091 this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
24092 this.generateMipmaps = false;
24093 const scope = this;
24094 function updateVideo() {
24095 scope.needsUpdate = true;
24096 video.requestVideoFrameCallback( updateVideo );
24097 }
24098 if ( 'requestVideoFrameCallback' in video ) {
24099 video.requestVideoFrameCallback( updateVideo );
24100 }
24101 }
24102 VideoTexture.prototype = Object.assign( Object.create( Texture.prototype ), {
24103 constructor: VideoTexture,
24104 isVideoTexture: true,
24105 update: function () {
24106 const video = this.image;
24107 const hasVideoFrameCallback = 'requestVideoFrameCallback' in video;
24108 if ( hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA ) {
24109 this.needsUpdate = true;
24110 }
24111 }
24112 } );
24113 function CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {
24114 Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
24115 this.image = { width: width, height: height };
24116 this.mipmaps = mipmaps;
24117 this.flipY = false;
24118 this.generateMipmaps = false;
24119 }
24120 CompressedTexture.prototype = Object.create( Texture.prototype );
24121 CompressedTexture.prototype.constructor = CompressedTexture;
24122 CompressedTexture.prototype.isCompressedTexture = true;
24123 function CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
24124 Texture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
24125 this.needsUpdate = true;
24126 }
24127 CanvasTexture.prototype = Object.create( Texture.prototype );
24128 CanvasTexture.prototype.constructor = CanvasTexture;
24129 CanvasTexture.prototype.isCanvasTexture = true;
24130 function DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {
24131 format = format !== undefined ? format : DepthFormat;
24132 if ( format !== DepthFormat && format !== DepthStencilFormat ) {
24133 throw new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' );
24134 }
24135 if ( type === undefined && format === DepthFormat ) type = UnsignedShortType;
24136 if ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;
24137 Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
24138 this.image = { width: width, height: height };
24139 this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
24140 this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
24141 this.flipY = false;
24142 this.generateMipmaps = false;
24143 }
24144 DepthTexture.prototype = Object.create( Texture.prototype );
24145 DepthTexture.prototype.constructor = DepthTexture;
24146 DepthTexture.prototype.isDepthTexture = true;
24147 class WireframeGeometry extends BufferGeometry {
24148 constructor( geometry ) {
24149 super();
24150 this.type = 'WireframeGeometry';
24151 const vertices = [];
24152 const edge = [ 0, 0 ], edges = {};
24153 const keys = [ 'a', 'b', 'c' ];
24154 if ( geometry && geometry.isGeometry ) {
24155 const faces = geometry.faces;
24156 for ( let i = 0, l = faces.length; i < l; i ++ ) {
24157 const face = faces[ i ];
24158 for ( let j = 0; j < 3; j ++ ) {
24159 const edge1 = face[ keys[ j ] ];
24160 const edge2 = face[ keys[ ( j + 1 ) % 3 ] ];
24161 edge[ 0 ] = Math.min( edge1, edge2 );
24162 edge[ 1 ] = Math.max( edge1, edge2 );
24163 const key = edge[ 0 ] + ',' + edge[ 1 ];
24164 if ( edges[ key ] === undefined ) {
24165 edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };
24166 }
24167 }
24168 }
24169 for ( const key in edges ) {
24170 const e = edges[ key ];
24171 let vertex = geometry.vertices[ e.index1 ];
24172 vertices.push( vertex.x, vertex.y, vertex.z );
24173 vertex = geometry.vertices[ e.index2 ];
24174 vertices.push( vertex.x, vertex.y, vertex.z );
24175 }
24176 } else if ( geometry && geometry.isBufferGeometry ) {
24177 const vertex = new Vector3();
24178 if ( geometry.index !== null ) {
24179 const position = geometry.attributes.position;
24180 const indices = geometry.index;
24181 let groups = geometry.groups;
24182 if ( groups.length === 0 ) {
24183 groups = [ { start: 0, count: indices.count, materialIndex: 0 } ];
24184 }
24185 for ( let o = 0, ol = groups.length; o < ol; ++ o ) {
24186 const group = groups[ o ];
24187 const start = group.start;
24188 const count = group.count;
24189 for ( let i = start, l = ( start + count ); i < l; i += 3 ) {
24190 for ( let j = 0; j < 3; j ++ ) {
24191 const edge1 = indices.getX( i + j );
24192 const edge2 = indices.getX( i + ( j + 1 ) % 3 );
24193 edge[ 0 ] = Math.min( edge1, edge2 );
24194 edge[ 1 ] = Math.max( edge1, edge2 );
24195 const key = edge[ 0 ] + ',' + edge[ 1 ];
24196 if ( edges[ key ] === undefined ) {
24197 edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };
24198 }
24199 }
24200 }
24201 }
24202 for ( const key in edges ) {
24203 const e = edges[ key ];
24204 vertex.fromBufferAttribute( position, e.index1 );
24205 vertices.push( vertex.x, vertex.y, vertex.z );
24206 vertex.fromBufferAttribute( position, e.index2 );
24207 vertices.push( vertex.x, vertex.y, vertex.z );
24208 }
24209 } else {
24210 const position = geometry.attributes.position;
24211 for ( let i = 0, l = ( position.count / 3 ); i < l; i ++ ) {
24212 for ( let j = 0; j < 3; j ++ ) {
24213 const index1 = 3 * i + j;
24214 vertex.fromBufferAttribute( position, index1 );
24215 vertices.push( vertex.x, vertex.y, vertex.z );
24216 const index2 = 3 * i + ( ( j + 1 ) % 3 );
24217 vertex.fromBufferAttribute( position, index2 );
24218 vertices.push( vertex.x, vertex.y, vertex.z );
24219 }
24220 }
24221 }
24222 }
24223 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
24224 }
24225 }
24226 function ParametricGeometry( func, slices, stacks ) {
24227 Geometry.call( this );
24228 this.type = 'ParametricGeometry';
24229 this.parameters = {
24230 func: func,
24231 slices: slices,
24232 stacks: stacks
24233 };
24234 this.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );
24235 this.mergeVertices();
24236 }
24237 ParametricGeometry.prototype = Object.create( Geometry.prototype );
24238 ParametricGeometry.prototype.constructor = ParametricGeometry;
24239 function ParametricBufferGeometry( func, slices, stacks ) {
24240 BufferGeometry.call( this );
24241 this.type = 'ParametricBufferGeometry';
24242 this.parameters = {
24243 func: func,
24244 slices: slices,
24245 stacks: stacks
24246 };
24247 const indices = [];
24248 const vertices = [];
24249 const normals = [];
24250 const uvs = [];
24251 const EPS = 0.00001;
24252 const normal = new Vector3();
24253 const p0 = new Vector3(), p1 = new Vector3();
24254 const pu = new Vector3(), pv = new Vector3();
24255 if ( func.length < 3 ) {
24256 console.error( 'THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.' );
24257 }
24258 const sliceCount = slices + 1;
24259 for ( let i = 0; i <= stacks; i ++ ) {
24260 const v = i / stacks;
24261 for ( let j = 0; j <= slices; j ++ ) {
24262 const u = j / slices;
24263 func( u, v, p0 );
24264 vertices.push( p0.x, p0.y, p0.z );
24265 if ( u - EPS >= 0 ) {
24266 func( u - EPS, v, p1 );
24267 pu.subVectors( p0, p1 );
24268 } else {
24269 func( u + EPS, v, p1 );
24270 pu.subVectors( p1, p0 );
24271 }
24272 if ( v - EPS >= 0 ) {
24273 func( u, v - EPS, p1 );
24274 pv.subVectors( p0, p1 );
24275 } else {
24276 func( u, v + EPS, p1 );
24277 pv.subVectors( p1, p0 );
24278 }
24279 normal.crossVectors( pu, pv ).normalize();
24280 normals.push( normal.x, normal.y, normal.z );
24281 uvs.push( u, v );
24282 }
24283 }
24284 for ( let i = 0; i < stacks; i ++ ) {
24285 for ( let j = 0; j < slices; j ++ ) {
24286 const a = i * sliceCount + j;
24287 const b = i * sliceCount + j + 1;
24288 const c = ( i + 1 ) * sliceCount + j + 1;
24289 const d = ( i + 1 ) * sliceCount + j;
24290 indices.push( a, b, d );
24291 indices.push( b, c, d );
24292 }
24293 }
24294 this.setIndex( indices );
24295 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
24296 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
24297 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
24298 }
24299 ParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
24300 ParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;
24301 class PolyhedronGeometry extends Geometry {
24302 constructor( vertices, indices, radius, detail ) {
24303 super();
24304 this.type = 'PolyhedronGeometry';
24305 this.parameters = {
24306 vertices: vertices,
24307 indices: indices,
24308 radius: radius,
24309 detail: detail
24310 };
24311 this.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );
24312 this.mergeVertices();
24313 }
24314 }
24315 class PolyhedronBufferGeometry extends BufferGeometry {
24316 constructor( vertices, indices, radius, detail ) {
24317 super();
24318 this.type = 'PolyhedronBufferGeometry';
24319 this.parameters = {
24320 vertices: vertices,
24321 indices: indices,
24322 radius: radius,
24323 detail: detail
24324 };
24325 radius = radius || 1;
24326 detail = detail || 0;
24327 const vertexBuffer = [];
24328 const uvBuffer = [];
24329 subdivide( detail );
24330 applyRadius( radius );
24331 generateUVs();
24332 this.setAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );
24333 this.setAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );
24334 this.setAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );
24335 if ( detail === 0 ) {
24336 this.computeVertexNormals();
24337 } else {
24338 this.normalizeNormals();
24339 }
24340 function subdivide( detail ) {
24341 const a = new Vector3();
24342 const b = new Vector3();
24343 const c = new Vector3();
24344 for ( let i = 0; i < indices.length; i += 3 ) {
24345 getVertexByIndex( indices[ i + 0 ], a );
24346 getVertexByIndex( indices[ i + 1 ], b );
24347 getVertexByIndex( indices[ i + 2 ], c );
24348 subdivideFace( a, b, c, detail );
24349 }
24350 }
24351 function subdivideFace( a, b, c, detail ) {
24352 const cols = Math.pow( 2, detail );
24353 const v = [];
24354 for ( let i = 0; i <= cols; i ++ ) {
24355 v[ i ] = [];
24356 const aj = a.clone().lerp( c, i / cols );
24357 const bj = b.clone().lerp( c, i / cols );
24358 const rows = cols - i;
24359 for ( let j = 0; j <= rows; j ++ ) {
24360 if ( j === 0 && i === cols ) {
24361 v[ i ][ j ] = aj;
24362 } else {
24363 v[ i ][ j ] = aj.clone().lerp( bj, j / rows );
24364 }
24365 }
24366 }
24367 for ( let i = 0; i < cols; i ++ ) {
24368 for ( let j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {
24369 const k = Math.floor( j / 2 );
24370 if ( j % 2 === 0 ) {
24371 pushVertex( v[ i ][ k + 1 ] );
24372 pushVertex( v[ i + 1 ][ k ] );
24373 pushVertex( v[ i ][ k ] );
24374 } else {
24375 pushVertex( v[ i ][ k + 1 ] );
24376 pushVertex( v[ i + 1 ][ k + 1 ] );
24377 pushVertex( v[ i + 1 ][ k ] );
24378 }
24379 }
24380 }
24381 }
24382 function applyRadius( radius ) {
24383 const vertex = new Vector3();
24384 for ( let i = 0; i < vertexBuffer.length; i += 3 ) {
24385 vertex.x = vertexBuffer[ i + 0 ];
24386 vertex.y = vertexBuffer[ i + 1 ];
24387 vertex.z = vertexBuffer[ i + 2 ];
24388 vertex.normalize().multiplyScalar( radius );
24389 vertexBuffer[ i + 0 ] = vertex.x;
24390 vertexBuffer[ i + 1 ] = vertex.y;
24391 vertexBuffer[ i + 2 ] = vertex.z;
24392 }
24393 }
24394 function generateUVs() {
24395 const vertex = new Vector3();
24396 for ( let i = 0; i < vertexBuffer.length; i += 3 ) {
24397 vertex.x = vertexBuffer[ i + 0 ];
24398 vertex.y = vertexBuffer[ i + 1 ];
24399 vertex.z = vertexBuffer[ i + 2 ];
24400 const u = azimuth( vertex ) / 2 / Math.PI + 0.5;
24401 const v = inclination( vertex ) / Math.PI + 0.5;
24402 uvBuffer.push( u, 1 - v );
24403 }
24404 correctUVs();
24405 correctSeam();
24406 }
24407 function correctSeam() {
24408 for ( let i = 0; i < uvBuffer.length; i += 6 ) {
24409 const x0 = uvBuffer[ i + 0 ];
24410 const x1 = uvBuffer[ i + 2 ];
24411 const x2 = uvBuffer[ i + 4 ];
24412 const max = Math.max( x0, x1, x2 );
24413 const min = Math.min( x0, x1, x2 );
24414 if ( max > 0.9 && min < 0.1 ) {
24415 if ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;
24416 if ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;
24417 if ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;
24418 }
24419 }
24420 }
24421 function pushVertex( vertex ) {
24422 vertexBuffer.push( vertex.x, vertex.y, vertex.z );
24423 }
24424 function getVertexByIndex( index, vertex ) {
24425 const stride = index * 3;
24426 vertex.x = vertices[ stride + 0 ];
24427 vertex.y = vertices[ stride + 1 ];
24428 vertex.z = vertices[ stride + 2 ];
24429 }
24430 function correctUVs() {
24431 const a = new Vector3();
24432 const b = new Vector3();
24433 const c = new Vector3();
24434 const centroid = new Vector3();
24435 const uvA = new Vector2();
24436 const uvB = new Vector2();
24437 const uvC = new Vector2();
24438 for ( let i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {
24439 a.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );
24440 b.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );
24441 c.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );
24442 uvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );
24443 uvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );
24444 uvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );
24445 centroid.copy( a ).add( b ).add( c ).divideScalar( 3 );
24446 const azi = azimuth( centroid );
24447 correctUV( uvA, j + 0, a, azi );
24448 correctUV( uvB, j + 2, b, azi );
24449 correctUV( uvC, j + 4, c, azi );
24450 }
24451 }
24452 function correctUV( uv, stride, vector, azimuth ) {
24453 if ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {
24454 uvBuffer[ stride ] = uv.x - 1;
24455 }
24456 if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {
24457 uvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;
24458 }
24459 }
24460 function azimuth( vector ) {
24461 return Math.atan2( vector.z, - vector.x );
24462 }
24463 function inclination( vector ) {
24464 return Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );
24465 }
24466 }
24467 }
24468 class TetrahedronGeometry extends Geometry {
24469 constructor( radius, detail ) {
24470 super();
24471 this.type = 'TetrahedronGeometry';
24472 this.parameters = {
24473 radius: radius,
24474 detail: detail
24475 };
24476 this.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );
24477 this.mergeVertices();
24478 }
24479 }
24480 class TetrahedronBufferGeometry extends PolyhedronBufferGeometry {
24481 constructor( radius, detail ) {
24482 const vertices = [
24483 1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1
24484 ];
24485 const indices = [
24486 2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1
24487 ];
24488 super( vertices, indices, radius, detail );
24489 this.type = 'TetrahedronBufferGeometry';
24490 this.parameters = {
24491 radius: radius,
24492 detail: detail
24493 };
24494 }
24495 }
24496 class OctahedronGeometry extends Geometry {
24497 constructor( radius, detail ) {
24498 super();
24499 this.type = 'OctahedronGeometry';
24500 this.parameters = {
24501 radius: radius,
24502 detail: detail
24503 };
24504 this.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );
24505 this.mergeVertices();
24506 }
24507 }
24508 class OctahedronBufferGeometry extends PolyhedronBufferGeometry {
24509 constructor( radius, detail ) {
24510 const vertices = [
24511 1, 0, 0, - 1, 0, 0, 0, 1, 0,
24512 0, - 1, 0, 0, 0, 1, 0, 0, - 1
24513 ];
24514 const indices = [
24515 0, 2, 4, 0, 4, 3, 0, 3, 5,
24516 0, 5, 2, 1, 2, 5, 1, 5, 3,
24517 1, 3, 4, 1, 4, 2
24518 ];
24519 super( vertices, indices, radius, detail );
24520 this.type = 'OctahedronBufferGeometry';
24521 this.parameters = {
24522 radius: radius,
24523 detail: detail
24524 };
24525 }
24526 }
24527 class IcosahedronGeometry extends Geometry {
24528 constructor( radius, detail ) {
24529 super();
24530 this.type = 'IcosahedronGeometry';
24531 this.parameters = {
24532 radius: radius,
24533 detail: detail
24534 };
24535 this.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );
24536 this.mergeVertices();
24537 }
24538 }
24539 class IcosahedronBufferGeometry extends PolyhedronBufferGeometry {
24540 constructor( radius, detail ) {
24541 const t = ( 1 + Math.sqrt( 5 ) ) / 2;
24542 const vertices = [
24543 - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,
24544 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,
24545 t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1
24546 ];
24547 const indices = [
24548 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,
24549 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,
24550 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,
24551 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1
24552 ];
24553 super( vertices, indices, radius, detail );
24554 this.type = 'IcosahedronBufferGeometry';
24555 this.parameters = {
24556 radius: radius,
24557 detail: detail
24558 };
24559 }
24560 }
24561 class DodecahedronGeometry extends Geometry {
24562 constructor( radius, detail ) {
24563 super();
24564 this.type = 'DodecahedronGeometry';
24565 this.parameters = {
24566 radius: radius,
24567 detail: detail
24568 };
24569 this.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );
24570 this.mergeVertices();
24571 }
24572 }
24573 class DodecahedronBufferGeometry extends PolyhedronBufferGeometry {
24574 constructor( radius, detail ) {
24575 const t = ( 1 + Math.sqrt( 5 ) ) / 2;
24576 const r = 1 / t;
24577 const vertices = [
24578 - 1, - 1, - 1, - 1, - 1, 1,
24579 - 1, 1, - 1, - 1, 1, 1,
24580 1, - 1, - 1, 1, - 1, 1,
24581 1, 1, - 1, 1, 1, 1,
24582 0, - r, - t, 0, - r, t,
24583 0, r, - t, 0, r, t,
24584 - r, - t, 0, - r, t, 0,
24585 r, - t, 0, r, t, 0,
24586 - t, 0, - r, t, 0, - r,
24587 - t, 0, r, t, 0, r
24588 ];
24589 const indices = [
24590 3, 11, 7, 3, 7, 15, 3, 15, 13,
24591 7, 19, 17, 7, 17, 6, 7, 6, 15,
24592 17, 4, 8, 17, 8, 10, 17, 10, 6,
24593 8, 0, 16, 8, 16, 2, 8, 2, 10,
24594 0, 12, 1, 0, 1, 18, 0, 18, 16,
24595 6, 10, 2, 6, 2, 13, 6, 13, 15,
24596 2, 16, 18, 2, 18, 3, 2, 3, 13,
24597 18, 1, 9, 18, 9, 11, 18, 11, 3,
24598 4, 14, 12, 4, 12, 0, 4, 0, 8,
24599 11, 9, 5, 11, 5, 19, 11, 19, 7,
24600 19, 5, 14, 19, 14, 4, 19, 4, 17,
24601 1, 12, 14, 1, 14, 5, 1, 5, 9
24602 ];
24603 super( vertices, indices, radius, detail );
24604 this.type = 'DodecahedronBufferGeometry';
24605 this.parameters = {
24606 radius: radius,
24607 detail: detail
24608 };
24609 }
24610 }
24611 class TubeGeometry extends Geometry {
24612 constructor( path, tubularSegments, radius, radialSegments, closed, taper ) {
24613 super();
24614 this.type = 'TubeGeometry';
24615 this.parameters = {
24616 path: path,
24617 tubularSegments: tubularSegments,
24618 radius: radius,
24619 radialSegments: radialSegments,
24620 closed: closed
24621 };
24622 if ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );
24623 const bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );
24624 this.tangents = bufferGeometry.tangents;
24625 this.normals = bufferGeometry.normals;
24626 this.binormals = bufferGeometry.binormals;
24627 this.fromBufferGeometry( bufferGeometry );
24628 this.mergeVertices();
24629 }
24630 }
24631 class TubeBufferGeometry extends BufferGeometry {
24632 constructor( path, tubularSegments, radius, radialSegments, closed ) {
24633 super();
24634 this.type = 'TubeBufferGeometry';
24635 this.parameters = {
24636 path: path,
24637 tubularSegments: tubularSegments,
24638 radius: radius,
24639 radialSegments: radialSegments,
24640 closed: closed
24641 };
24642 tubularSegments = tubularSegments || 64;
24643 radius = radius || 1;
24644 radialSegments = radialSegments || 8;
24645 closed = closed || false;
24646 const frames = path.computeFrenetFrames( tubularSegments, closed );
24647 this.tangents = frames.tangents;
24648 this.normals = frames.normals;
24649 this.binormals = frames.binormals;
24650 const vertex = new Vector3();
24651 const normal = new Vector3();
24652 const uv = new Vector2();
24653 let P = new Vector3();
24654 const vertices = [];
24655 const normals = [];
24656 const uvs = [];
24657 const indices = [];
24658 generateBufferData();
24659 this.setIndex( indices );
24660 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
24661 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
24662 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
24663 function generateBufferData() {
24664 for ( let i = 0; i < tubularSegments; i ++ ) {
24665 generateSegment( i );
24666 }
24667 generateSegment( ( closed === false ) ? tubularSegments : 0 );
24668 generateUVs();
24669 generateIndices();
24670 }
24671 function generateSegment( i ) {
24672 P = path.getPointAt( i / tubularSegments, P );
24673 const N = frames.normals[ i ];
24674 const B = frames.binormals[ i ];
24675 for ( let j = 0; j <= radialSegments; j ++ ) {
24676 const v = j / radialSegments * Math.PI * 2;
24677 const sin = Math.sin( v );
24678 const cos = - Math.cos( v );
24679 normal.x = ( cos * N.x + sin * B.x );
24680 normal.y = ( cos * N.y + sin * B.y );
24681 normal.z = ( cos * N.z + sin * B.z );
24682 normal.normalize();
24683 normals.push( normal.x, normal.y, normal.z );
24684 vertex.x = P.x + radius * normal.x;
24685 vertex.y = P.y + radius * normal.y;
24686 vertex.z = P.z + radius * normal.z;
24687 vertices.push( vertex.x, vertex.y, vertex.z );
24688 }
24689 }
24690 function generateIndices() {
24691 for ( let j = 1; j <= tubularSegments; j ++ ) {
24692 for ( let i = 1; i <= radialSegments; i ++ ) {
24693 const a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );
24694 const b = ( radialSegments + 1 ) * j + ( i - 1 );
24695 const c = ( radialSegments + 1 ) * j + i;
24696 const d = ( radialSegments + 1 ) * ( j - 1 ) + i;
24697 indices.push( a, b, d );
24698 indices.push( b, c, d );
24699 }
24700 }
24701 }
24702 function generateUVs() {
24703 for ( let i = 0; i <= tubularSegments; i ++ ) {
24704 for ( let j = 0; j <= radialSegments; j ++ ) {
24705 uv.x = i / tubularSegments;
24706 uv.y = j / radialSegments;
24707 uvs.push( uv.x, uv.y );
24708 }
24709 }
24710 }
24711 }
24712 toJSON() {
24713 const data = BufferGeometry.prototype.toJSON.call( this );
24714 data.path = this.parameters.path.toJSON();
24715 return data;
24716 }
24717 }
24718 class TorusKnotGeometry extends Geometry {
24719 constructor( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {
24720 super();
24721 this.type = 'TorusKnotGeometry';
24722 this.parameters = {
24723 radius: radius,
24724 tube: tube,
24725 tubularSegments: tubularSegments,
24726 radialSegments: radialSegments,
24727 p: p,
24728 q: q
24729 };
24730 if ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );
24731 this.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );
24732 this.mergeVertices();
24733 }
24734 }
24735 class TorusKnotBufferGeometry extends BufferGeometry {
24736 constructor( radius, tube, tubularSegments, radialSegments, p, q ) {
24737 super();
24738 this.type = 'TorusKnotBufferGeometry';
24739 this.parameters = {
24740 radius: radius,
24741 tube: tube,
24742 tubularSegments: tubularSegments,
24743 radialSegments: radialSegments,
24744 p: p,
24745 q: q
24746 };
24747 radius = radius || 1;
24748 tube = tube || 0.4;
24749 tubularSegments = Math.floor( tubularSegments ) || 64;
24750 radialSegments = Math.floor( radialSegments ) || 8;
24751 p = p || 2;
24752 q = q || 3;
24753 const indices = [];
24754 const vertices = [];
24755 const normals = [];
24756 const uvs = [];
24757 const vertex = new Vector3();
24758 const normal = new Vector3();
24759 const P1 = new Vector3();
24760 const P2 = new Vector3();
24761 const B = new Vector3();
24762 const T = new Vector3();
24763 const N = new Vector3();
24764 for ( let i = 0; i <= tubularSegments; ++ i ) {
24765 const u = i / tubularSegments * p * Math.PI * 2;
24766 calculatePositionOnCurve( u, p, q, radius, P1 );
24767 calculatePositionOnCurve( u + 0.01, p, q, radius, P2 );
24768 T.subVectors( P2, P1 );
24769 N.addVectors( P2, P1 );
24770 B.crossVectors( T, N );
24771 N.crossVectors( B, T );
24772 B.normalize();
24773 N.normalize();
24774 for ( let j = 0; j <= radialSegments; ++ j ) {
24775 const v = j / radialSegments * Math.PI * 2;
24776 const cx = - tube * Math.cos( v );
24777 const cy = tube * Math.sin( v );
24778 vertex.x = P1.x + ( cx * N.x + cy * B.x );
24779 vertex.y = P1.y + ( cx * N.y + cy * B.y );
24780 vertex.z = P1.z + ( cx * N.z + cy * B.z );
24781 vertices.push( vertex.x, vertex.y, vertex.z );
24782 normal.subVectors( vertex, P1 ).normalize();
24783 normals.push( normal.x, normal.y, normal.z );
24784 uvs.push( i / tubularSegments );
24785 uvs.push( j / radialSegments );
24786 }
24787 }
24788 for ( let j = 1; j <= tubularSegments; j ++ ) {
24789 for ( let i = 1; i <= radialSegments; i ++ ) {
24790 const a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );
24791 const b = ( radialSegments + 1 ) * j + ( i - 1 );
24792 const c = ( radialSegments + 1 ) * j + i;
24793 const d = ( radialSegments + 1 ) * ( j - 1 ) + i;
24794 indices.push( a, b, d );
24795 indices.push( b, c, d );
24796 }
24797 }
24798 this.setIndex( indices );
24799 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
24800 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
24801 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
24802 function calculatePositionOnCurve( u, p, q, radius, position ) {
24803 const cu = Math.cos( u );
24804 const su = Math.sin( u );
24805 const quOverP = q / p * u;
24806 const cs = Math.cos( quOverP );
24807 position.x = radius * ( 2 + cs ) * 0.5 * cu;
24808 position.y = radius * ( 2 + cs ) * su * 0.5;
24809 position.z = radius * Math.sin( quOverP ) * 0.5;
24810 }
24811 }
24812 }
24813 class TorusGeometry extends Geometry {
24814 constructor( radius, tube, radialSegments, tubularSegments, arc ) {
24815 super();
24816 this.type = 'TorusGeometry';
24817 this.parameters = {
24818 radius: radius,
24819 tube: tube,
24820 radialSegments: radialSegments,
24821 tubularSegments: tubularSegments,
24822 arc: arc
24823 };
24824 this.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );
24825 this.mergeVertices();
24826 }
24827 }
24828 class TorusBufferGeometry extends BufferGeometry {
24829 constructor( radius, tube, radialSegments, tubularSegments, arc ) {
24830 super();
24831 this.type = 'TorusBufferGeometry';
24832 this.parameters = {
24833 radius: radius,
24834 tube: tube,
24835 radialSegments: radialSegments,
24836 tubularSegments: tubularSegments,
24837 arc: arc
24838 };
24839 radius = radius || 1;
24840 tube = tube || 0.4;
24841 radialSegments = Math.floor( radialSegments ) || 8;
24842 tubularSegments = Math.floor( tubularSegments ) || 6;
24843 arc = arc || Math.PI * 2;
24844 const indices = [];
24845 const vertices = [];
24846 const normals = [];
24847 const uvs = [];
24848 const center = new Vector3();
24849 const vertex = new Vector3();
24850 const normal = new Vector3();
24851 for ( let j = 0; j <= radialSegments; j ++ ) {
24852 for ( let i = 0; i <= tubularSegments; i ++ ) {
24853 const u = i / tubularSegments * arc;
24854 const v = j / radialSegments * Math.PI * 2;
24855 vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );
24856 vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );
24857 vertex.z = tube * Math.sin( v );
24858 vertices.push( vertex.x, vertex.y, vertex.z );
24859 center.x = radius * Math.cos( u );
24860 center.y = radius * Math.sin( u );
24861 normal.subVectors( vertex, center ).normalize();
24862 normals.push( normal.x, normal.y, normal.z );
24863 uvs.push( i / tubularSegments );
24864 uvs.push( j / radialSegments );
24865 }
24866 }
24867 for ( let j = 1; j <= radialSegments; j ++ ) {
24868 for ( let i = 1; i <= tubularSegments; i ++ ) {
24869 const a = ( tubularSegments + 1 ) * j + i - 1;
24870 const b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;
24871 const c = ( tubularSegments + 1 ) * ( j - 1 ) + i;
24872 const d = ( tubularSegments + 1 ) * j + i;
24873 indices.push( a, b, d );
24874 indices.push( b, c, d );
24875 }
24876 }
24877 this.setIndex( indices );
24878 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
24879 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
24880 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
24881 }
24882 }
24883 const Earcut = {
24884 triangulate: function ( data, holeIndices, dim ) {
24885 dim = dim || 2;
24886 const hasHoles = holeIndices && holeIndices.length;
24887 const outerLen = hasHoles ? holeIndices[ 0 ] * dim : data.length;
24888 let outerNode = linkedList( data, 0, outerLen, dim, true );
24889 const triangles = [];
24890 if ( ! outerNode || outerNode.next === outerNode.prev ) return triangles;
24891 let minX, minY, maxX, maxY, x, y, invSize;
24892 if ( hasHoles ) outerNode = eliminateHoles( data, holeIndices, outerNode, dim );
24893 if ( data.length > 80 * dim ) {
24894 minX = maxX = data[ 0 ];
24895 minY = maxY = data[ 1 ];
24896 for ( let i = dim; i < outerLen; i += dim ) {
24897 x = data[ i ];
24898 y = data[ i + 1 ];
24899 if ( x < minX ) minX = x;
24900 if ( y < minY ) minY = y;
24901 if ( x > maxX ) maxX = x;
24902 if ( y > maxY ) maxY = y;
24903 }
24904 invSize = Math.max( maxX - minX, maxY - minY );
24905 invSize = invSize !== 0 ? 1 / invSize : 0;
24906 }
24907 earcutLinked( outerNode, triangles, dim, minX, minY, invSize );
24908 return triangles;
24909 }
24910 };
24911 function linkedList( data, start, end, dim, clockwise ) {
24912 let i, last;
24913 if ( clockwise === ( signedArea( data, start, end, dim ) > 0 ) ) {
24914 for ( i = start; i < end; i += dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last );
24915 } else {
24916 for ( i = end - dim; i >= start; i -= dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last );
24917 }
24918 if ( last && equals( last, last.next ) ) {
24919 removeNode( last );
24920 last = last.next;
24921 }
24922 return last;
24923 }
24924 function filterPoints( start, end ) {
24925 if ( ! start ) return start;
24926 if ( ! end ) end = start;
24927 let p = start,
24928 again;
24929 do {
24930 again = false;
24931 if ( ! p.steiner && ( equals( p, p.next ) || area( p.prev, p, p.next ) === 0 ) ) {
24932 removeNode( p );
24933 p = end = p.prev;
24934 if ( p === p.next ) break;
24935 again = true;
24936 } else {
24937 p = p.next;
24938 }
24939 } while ( again || p !== end );
24940 return end;
24941 }
24942 function earcutLinked( ear, triangles, dim, minX, minY, invSize, pass ) {
24943 if ( ! ear ) return;
24944 if ( ! pass && invSize ) indexCurve( ear, minX, minY, invSize );
24945 let stop = ear,
24946 prev, next;
24947 while ( ear.prev !== ear.next ) {
24948 prev = ear.prev;
24949 next = ear.next;
24950 if ( invSize ? isEarHashed( ear, minX, minY, invSize ) : isEar( ear ) ) {
24951 triangles.push( prev.i / dim );
24952 triangles.push( ear.i / dim );
24953 triangles.push( next.i / dim );
24954 removeNode( ear );
24955 ear = next.next;
24956 stop = next.next;
24957 continue;
24958 }
24959 ear = next;
24960 if ( ear === stop ) {
24961 if ( ! pass ) {
24962 earcutLinked( filterPoints( ear ), triangles, dim, minX, minY, invSize, 1 );
24963 } else if ( pass === 1 ) {
24964 ear = cureLocalIntersections( filterPoints( ear ), triangles, dim );
24965 earcutLinked( ear, triangles, dim, minX, minY, invSize, 2 );
24966 } else if ( pass === 2 ) {
24967 splitEarcut( ear, triangles, dim, minX, minY, invSize );
24968 }
24969 break;
24970 }
24971 }
24972 }
24973 function isEar( ear ) {
24974 const a = ear.prev,
24975 b = ear,
24976 c = ear.next;
24977 if ( area( a, b, c ) >= 0 ) return false;
24978 let p = ear.next.next;
24979 while ( p !== ear.prev ) {
24980 if ( pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) &&
24981 area( p.prev, p, p.next ) >= 0 ) return false;
24982 p = p.next;
24983 }
24984 return true;
24985 }
24986 function isEarHashed( ear, minX, minY, invSize ) {
24987 const a = ear.prev,
24988 b = ear,
24989 c = ear.next;
24990 if ( area( a, b, c ) >= 0 ) return false;
24991 const minTX = a.x < b.x ? ( a.x < c.x ? a.x : c.x ) : ( b.x < c.x ? b.x : c.x ),
24992 minTY = a.y < b.y ? ( a.y < c.y ? a.y : c.y ) : ( b.y < c.y ? b.y : c.y ),
24993 maxTX = a.x > b.x ? ( a.x > c.x ? a.x : c.x ) : ( b.x > c.x ? b.x : c.x ),
24994 maxTY = a.y > b.y ? ( a.y > c.y ? a.y : c.y ) : ( b.y > c.y ? b.y : c.y );
24995 const minZ = zOrder( minTX, minTY, minX, minY, invSize ),
24996 maxZ = zOrder( maxTX, maxTY, minX, minY, invSize );
24997 let p = ear.prevZ,
24998 n = ear.nextZ;
24999 while ( p && p.z >= minZ && n && n.z <= maxZ ) {
25000 if ( p !== ear.prev && p !== ear.next &&
25001 pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) &&
25002 area( p.prev, p, p.next ) >= 0 ) return false;
25003 p = p.prevZ;
25004 if ( n !== ear.prev && n !== ear.next &&
25005 pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y ) &&
25006 area( n.prev, n, n.next ) >= 0 ) return false;
25007 n = n.nextZ;
25008 }
25009 while ( p && p.z >= minZ ) {
25010 if ( p !== ear.prev && p !== ear.next &&
25011 pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) &&
25012 area( p.prev, p, p.next ) >= 0 ) return false;
25013 p = p.prevZ;
25014 }
25015 while ( n && n.z <= maxZ ) {
25016 if ( n !== ear.prev && n !== ear.next &&
25017 pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y ) &&
25018 area( n.prev, n, n.next ) >= 0 ) return false;
25019 n = n.nextZ;
25020 }
25021 return true;
25022 }
25023 function cureLocalIntersections( start, triangles, dim ) {
25024 let p = start;
25025 do {
25026 const a = p.prev,
25027 b = p.next.next;
25028 if ( ! equals( a, b ) && intersects( a, p, p.next, b ) && locallyInside( a, b ) && locallyInside( b, a ) ) {
25029 triangles.push( a.i / dim );
25030 triangles.push( p.i / dim );
25031 triangles.push( b.i / dim );
25032 removeNode( p );
25033 removeNode( p.next );
25034 p = start = b;
25035 }
25036 p = p.next;
25037 } while ( p !== start );
25038 return filterPoints( p );
25039 }
25040 function splitEarcut( start, triangles, dim, minX, minY, invSize ) {
25041 let a = start;
25042 do {
25043 let b = a.next.next;
25044 while ( b !== a.prev ) {
25045 if ( a.i !== b.i && isValidDiagonal( a, b ) ) {
25046 let c = splitPolygon( a, b );
25047 a = filterPoints( a, a.next );
25048 c = filterPoints( c, c.next );
25049 earcutLinked( a, triangles, dim, minX, minY, invSize );
25050 earcutLinked( c, triangles, dim, minX, minY, invSize );
25051 return;
25052 }
25053 b = b.next;
25054 }
25055 a = a.next;
25056 } while ( a !== start );
25057 }
25058 function eliminateHoles( data, holeIndices, outerNode, dim ) {
25059 const queue = [];
25060 let i, len, start, end, list;
25061 for ( i = 0, len = holeIndices.length; i < len; i ++ ) {
25062 start = holeIndices[ i ] * dim;
25063 end = i < len - 1 ? holeIndices[ i + 1 ] * dim : data.length;
25064 list = linkedList( data, start, end, dim, false );
25065 if ( list === list.next ) list.steiner = true;
25066 queue.push( getLeftmost( list ) );
25067 }
25068 queue.sort( compareX );
25069 for ( i = 0; i < queue.length; i ++ ) {
25070 eliminateHole( queue[ i ], outerNode );
25071 outerNode = filterPoints( outerNode, outerNode.next );
25072 }
25073 return outerNode;
25074 }
25075 function compareX( a, b ) {
25076 return a.x - b.x;
25077 }
25078 function eliminateHole( hole, outerNode ) {
25079 outerNode = findHoleBridge( hole, outerNode );
25080 if ( outerNode ) {
25081 const b = splitPolygon( outerNode, hole );
25082 filterPoints( outerNode, outerNode.next );
25083 filterPoints( b, b.next );
25084 }
25085 }
25086 function findHoleBridge( hole, outerNode ) {
25087 let p = outerNode;
25088 const hx = hole.x;
25089 const hy = hole.y;
25090 let qx = - Infinity, m;
25091 do {
25092 if ( hy <= p.y && hy >= p.next.y && p.next.y !== p.y ) {
25093 const x = p.x + ( hy - p.y ) * ( p.next.x - p.x ) / ( p.next.y - p.y );
25094 if ( x <= hx && x > qx ) {
25095 qx = x;
25096 if ( x === hx ) {
25097 if ( hy === p.y ) return p;
25098 if ( hy === p.next.y ) return p.next;
25099 }
25100 m = p.x < p.next.x ? p : p.next;
25101 }
25102 }
25103 p = p.next;
25104 } while ( p !== outerNode );
25105 if ( ! m ) return null;
25106 if ( hx === qx ) return m;
25107 const stop = m,
25108 mx = m.x,
25109 my = m.y;
25110 let tanMin = Infinity, tan;
25111 p = m;
25112 do {
25113 if ( hx >= p.x && p.x >= mx && hx !== p.x &&
25114 pointInTriangle( hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y ) ) {
25115 tan = Math.abs( hy - p.y ) / ( hx - p.x );
25116 if ( locallyInside( p, hole ) && ( tan < tanMin || ( tan === tanMin && ( p.x > m.x || ( p.x === m.x && sectorContainsSector( m, p ) ) ) ) ) ) {
25117 m = p;
25118 tanMin = tan;
25119 }
25120 }
25121 p = p.next;
25122 } while ( p !== stop );
25123 return m;
25124 }
25125 function sectorContainsSector( m, p ) {
25126 return area( m.prev, m, p.prev ) < 0 && area( p.next, m, m.next ) < 0;
25127 }
25128 function indexCurve( start, minX, minY, invSize ) {
25129 let p = start;
25130 do {
25131 if ( p.z === null ) p.z = zOrder( p.x, p.y, minX, minY, invSize );
25132 p.prevZ = p.prev;
25133 p.nextZ = p.next;
25134 p = p.next;
25135 } while ( p !== start );
25136 p.prevZ.nextZ = null;
25137 p.prevZ = null;
25138 sortLinked( p );
25139 }
25140 function sortLinked( list ) {
25141 let i, p, q, e, tail, numMerges, pSize, qSize,
25142 inSize = 1;
25143 do {
25144 p = list;
25145 list = null;
25146 tail = null;
25147 numMerges = 0;
25148 while ( p ) {
25149 numMerges ++;
25150 q = p;
25151 pSize = 0;
25152 for ( i = 0; i < inSize; i ++ ) {
25153 pSize ++;
25154 q = q.nextZ;
25155 if ( ! q ) break;
25156 }
25157 qSize = inSize;
25158 while ( pSize > 0 || ( qSize > 0 && q ) ) {
25159 if ( pSize !== 0 && ( qSize === 0 || ! q || p.z <= q.z ) ) {
25160 e = p;
25161 p = p.nextZ;
25162 pSize --;
25163 } else {
25164 e = q;
25165 q = q.nextZ;
25166 qSize --;
25167 }
25168 if ( tail ) tail.nextZ = e;
25169 else list = e;
25170 e.prevZ = tail;
25171 tail = e;
25172 }
25173 p = q;
25174 }
25175 tail.nextZ = null;
25176 inSize *= 2;
25177 } while ( numMerges > 1 );
25178 return list;
25179 }
25180 function zOrder( x, y, minX, minY, invSize ) {
25181 x = 32767 * ( x - minX ) * invSize;
25182 y = 32767 * ( y - minY ) * invSize;
25183 x = ( x | ( x << 8 ) ) & 0x00FF00FF;
25184 x = ( x | ( x << 4 ) ) & 0x0F0F0F0F;
25185 x = ( x | ( x << 2 ) ) & 0x33333333;
25186 x = ( x | ( x << 1 ) ) & 0x55555555;
25187 y = ( y | ( y << 8 ) ) & 0x00FF00FF;
25188 y = ( y | ( y << 4 ) ) & 0x0F0F0F0F;
25189 y = ( y | ( y << 2 ) ) & 0x33333333;
25190 y = ( y | ( y << 1 ) ) & 0x55555555;
25191 return x | ( y << 1 );
25192 }
25193 function getLeftmost( start ) {
25194 let p = start,
25195 leftmost = start;
25196 do {
25197 if ( p.x < leftmost.x || ( p.x === leftmost.x && p.y < leftmost.y ) ) leftmost = p;
25198 p = p.next;
25199 } while ( p !== start );
25200 return leftmost;
25201 }
25202 function pointInTriangle( ax, ay, bx, by, cx, cy, px, py ) {
25203 return ( cx - px ) * ( ay - py ) - ( ax - px ) * ( cy - py ) >= 0 &&
25204 ( ax - px ) * ( by - py ) - ( bx - px ) * ( ay - py ) >= 0 &&
25205 ( bx - px ) * ( cy - py ) - ( cx - px ) * ( by - py ) >= 0;
25206 }
25207 function isValidDiagonal( a, b ) {
25208 return a.next.i !== b.i && a.prev.i !== b.i && ! intersectsPolygon( a, b ) &&
25209 ( locallyInside( a, b ) && locallyInside( b, a ) && middleInside( a, b ) &&
25210 ( area( a.prev, a, b.prev ) || area( a, b.prev, b ) ) ||
25211 equals( a, b ) && area( a.prev, a, a.next ) > 0 && area( b.prev, b, b.next ) > 0 );
25212 }
25213 function area( p, q, r ) {
25214 return ( q.y - p.y ) * ( r.x - q.x ) - ( q.x - p.x ) * ( r.y - q.y );
25215 }
25216 function equals( p1, p2 ) {
25217 return p1.x === p2.x && p1.y === p2.y;
25218 }
25219 function intersects( p1, q1, p2, q2 ) {
25220 const o1 = sign( area( p1, q1, p2 ) );
25221 const o2 = sign( area( p1, q1, q2 ) );
25222 const o3 = sign( area( p2, q2, p1 ) );
25223 const o4 = sign( area( p2, q2, q1 ) );
25224 if ( o1 !== o2 && o3 !== o4 ) return true;
25225 if ( o1 === 0 && onSegment( p1, p2, q1 ) ) return true;
25226 if ( o2 === 0 && onSegment( p1, q2, q1 ) ) return true;
25227 if ( o3 === 0 && onSegment( p2, p1, q2 ) ) return true;
25228 if ( o4 === 0 && onSegment( p2, q1, q2 ) ) return true;
25229 return false;
25230 }
25231 function onSegment( p, q, r ) {
25232 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 );
25233 }
25234 function sign( num ) {
25235 return num > 0 ? 1 : num < 0 ? - 1 : 0;
25236 }
25237 function intersectsPolygon( a, b ) {
25238 let p = a;
25239 do {
25240 if ( p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&
25241 intersects( p, p.next, a, b ) ) return true;
25242 p = p.next;
25243 } while ( p !== a );
25244 return false;
25245 }
25246 function locallyInside( a, b ) {
25247 return area( a.prev, a, a.next ) < 0 ?
25248 area( a, b, a.next ) >= 0 && area( a, a.prev, b ) >= 0 :
25249 area( a, b, a.prev ) < 0 || area( a, a.next, b ) < 0;
25250 }
25251 function middleInside( a, b ) {
25252 let p = a,
25253 inside = false;
25254 const px = ( a.x + b.x ) / 2,
25255 py = ( a.y + b.y ) / 2;
25256 do {
25257 if ( ( ( p.y > py ) !== ( p.next.y > py ) ) && p.next.y !== p.y &&
25258 ( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) )
25259 inside = ! inside;
25260 p = p.next;
25261 } while ( p !== a );
25262 return inside;
25263 }
25264 function splitPolygon( a, b ) {
25265 const a2 = new Node( a.i, a.x, a.y ),
25266 b2 = new Node( b.i, b.x, b.y ),
25267 an = a.next,
25268 bp = b.prev;
25269 a.next = b;
25270 b.prev = a;
25271 a2.next = an;
25272 an.prev = a2;
25273 b2.next = a2;
25274 a2.prev = b2;
25275 bp.next = b2;
25276 b2.prev = bp;
25277 return b2;
25278 }
25279 function insertNode( i, x, y, last ) {
25280 const p = new Node( i, x, y );
25281 if ( ! last ) {
25282 p.prev = p;
25283 p.next = p;
25284 } else {
25285 p.next = last.next;
25286 p.prev = last;
25287 last.next.prev = p;
25288 last.next = p;
25289 }
25290 return p;
25291 }
25292 function removeNode( p ) {
25293 p.next.prev = p.prev;
25294 p.prev.next = p.next;
25295 if ( p.prevZ ) p.prevZ.nextZ = p.nextZ;
25296 if ( p.nextZ ) p.nextZ.prevZ = p.prevZ;
25297 }
25298 function Node( i, x, y ) {
25299 this.i = i;
25300 this.x = x;
25301 this.y = y;
25302 this.prev = null;
25303 this.next = null;
25304 this.z = null;
25305 this.prevZ = null;
25306 this.nextZ = null;
25307 this.steiner = false;
25308 }
25309 function signedArea( data, start, end, dim ) {
25310 let sum = 0;
25311 for ( let i = start, j = end - dim; i < end; i += dim ) {
25312 sum += ( data[ j ] - data[ i ] ) * ( data[ i + 1 ] + data[ j + 1 ] );
25313 j = i;
25314 }
25315 return sum;
25316 }
25317 const ShapeUtils = {
25318 area: function ( contour ) {
25319 const n = contour.length;
25320 let a = 0.0;
25321 for ( let p = n - 1, q = 0; q < n; p = q ++ ) {
25322 a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;
25323 }
25324 return a * 0.5;
25325 },
25326 isClockWise: function ( pts ) {
25327 return ShapeUtils.area( pts ) < 0;
25328 },
25329 triangulateShape: function ( contour, holes ) {
25330 const vertices = [];
25331 const holeIndices = [];
25332 const faces = [];
25333 removeDupEndPts( contour );
25334 addContour( vertices, contour );
25335 let holeIndex = contour.length;
25336 holes.forEach( removeDupEndPts );
25337 for ( let i = 0; i < holes.length; i ++ ) {
25338 holeIndices.push( holeIndex );
25339 holeIndex += holes[ i ].length;
25340 addContour( vertices, holes[ i ] );
25341 }
25342 const triangles = Earcut.triangulate( vertices, holeIndices );
25343 for ( let i = 0; i < triangles.length; i += 3 ) {
25344 faces.push( triangles.slice( i, i + 3 ) );
25345 }
25346 return faces;
25347 }
25348 };
25349 function removeDupEndPts( points ) {
25350 const l = points.length;
25351 if ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {
25352 points.pop();
25353 }
25354 }
25355 function addContour( vertices, contour ) {
25356 for ( let i = 0; i < contour.length; i ++ ) {
25357 vertices.push( contour[ i ].x );
25358 vertices.push( contour[ i ].y );
25359 }
25360 }
25361 class ExtrudeGeometry extends Geometry {
25362 constructor( shapes, options ) {
25363 super();
25364 this.type = 'ExtrudeGeometry';
25365 this.parameters = {
25366 shapes: shapes,
25367 options: options
25368 };
25369 this.fromBufferGeometry( new ExtrudeBufferGeometry( shapes, options ) );
25370 this.mergeVertices();
25371 }
25372 toJSON() {
25373 const data = super.toJSON();
25374 const shapes = this.parameters.shapes;
25375 const options = this.parameters.options;
25376 return toJSON( shapes, options, data );
25377 }
25378 }
25379 class ExtrudeBufferGeometry extends BufferGeometry {
25380 constructor( shapes, options ) {
25381 super();
25382 this.type = 'ExtrudeBufferGeometry';
25383 this.parameters = {
25384 shapes: shapes,
25385 options: options
25386 };
25387 shapes = Array.isArray( shapes ) ? shapes : [ shapes ];
25388 const scope = this;
25389 const verticesArray = [];
25390 const uvArray = [];
25391 for ( let i = 0, l = shapes.length; i < l; i ++ ) {
25392 const shape = shapes[ i ];
25393 addShape( shape );
25394 }
25395 this.setAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) );
25396 this.setAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) );
25397 this.computeVertexNormals();
25398 function addShape( shape ) {
25399 const placeholder = [];
25400 const curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
25401 const steps = options.steps !== undefined ? options.steps : 1;
25402 let depth = options.depth !== undefined ? options.depth : 100;
25403 let bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true;
25404 let bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6;
25405 let bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2;
25406 let bevelOffset = options.bevelOffset !== undefined ? options.bevelOffset : 0;
25407 let bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
25408 const extrudePath = options.extrudePath;
25409 const uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator;
25410 if ( options.amount !== undefined ) {
25411 console.warn( 'THREE.ExtrudeBufferGeometry: amount has been renamed to depth.' );
25412 depth = options.amount;
25413 }
25414 let extrudePts, extrudeByPath = false;
25415 let splineTube, binormal, normal, position2;
25416 if ( extrudePath ) {
25417 extrudePts = extrudePath.getSpacedPoints( steps );
25418 extrudeByPath = true;
25419 bevelEnabled = false;
25420 splineTube = extrudePath.computeFrenetFrames( steps, false );
25421 binormal = new Vector3();
25422 normal = new Vector3();
25423 position2 = new Vector3();
25424 }
25425 if ( ! bevelEnabled ) {
25426 bevelSegments = 0;
25427 bevelThickness = 0;
25428 bevelSize = 0;
25429 bevelOffset = 0;
25430 }
25431 const shapePoints = shape.extractPoints( curveSegments );
25432 let vertices = shapePoints.shape;
25433 const holes = shapePoints.holes;
25434 const reverse = ! ShapeUtils.isClockWise( vertices );
25435 if ( reverse ) {
25436 vertices = vertices.reverse();
25437 for ( let h = 0, hl = holes.length; h < hl; h ++ ) {
25438 const ahole = holes[ h ];
25439 if ( ShapeUtils.isClockWise( ahole ) ) {
25440 holes[ h ] = ahole.reverse();
25441 }
25442 }
25443 }
25444 const faces = ShapeUtils.triangulateShape( vertices, holes );
25445 const contour = vertices;
25446 for ( let h = 0, hl = holes.length; h < hl; h ++ ) {
25447 const ahole = holes[ h ];
25448 vertices = vertices.concat( ahole );
25449 }
25450 function scalePt2( pt, vec, size ) {
25451 if ( ! vec ) console.error( "THREE.ExtrudeGeometry: vec does not exist" );
25452 return vec.clone().multiplyScalar( size ).add( pt );
25453 }
25454 const vlen = vertices.length, flen = faces.length;
25455 function getBevelVec( inPt, inPrev, inNext ) {
25456 let v_trans_x, v_trans_y, shrink_by;
25457 const v_prev_x = inPt.x - inPrev.x,
25458 v_prev_y = inPt.y - inPrev.y;
25459 const v_next_x = inNext.x - inPt.x,
25460 v_next_y = inNext.y - inPt.y;
25461 const v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );
25462 const collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );
25463 if ( Math.abs( collinear0 ) > Number.EPSILON ) {
25464 const v_prev_len = Math.sqrt( v_prev_lensq );
25465 const v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );
25466 const ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );
25467 const ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );
25468 const ptNextShift_x = ( inNext.x - v_next_y / v_next_len );
25469 const ptNextShift_y = ( inNext.y + v_next_x / v_next_len );
25470 const sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -
25471 ( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /
25472 ( v_prev_x * v_next_y - v_prev_y * v_next_x );
25473 v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );
25474 v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );
25475 const v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );
25476 if ( v_trans_lensq <= 2 ) {
25477 return new Vector2( v_trans_x, v_trans_y );
25478 } else {
25479 shrink_by = Math.sqrt( v_trans_lensq / 2 );
25480 }
25481 } else {
25482 let direction_eq = false;
25483 if ( v_prev_x > Number.EPSILON ) {
25484 if ( v_next_x > Number.EPSILON ) {
25485 direction_eq = true;
25486 }
25487 } else {
25488 if ( v_prev_x < - Number.EPSILON ) {
25489 if ( v_next_x < - Number.EPSILON ) {
25490 direction_eq = true;
25491 }
25492 } else {
25493 if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {
25494 direction_eq = true;
25495 }
25496 }
25497 }
25498 if ( direction_eq ) {
25499 v_trans_x = - v_prev_y;
25500 v_trans_y = v_prev_x;
25501 shrink_by = Math.sqrt( v_prev_lensq );
25502 } else {
25503 v_trans_x = v_prev_x;
25504 v_trans_y = v_prev_y;
25505 shrink_by = Math.sqrt( v_prev_lensq / 2 );
25506 }
25507 }
25508 return new Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );
25509 }
25510 const contourMovements = [];
25511 for ( let i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
25512 if ( j === il ) j = 0;
25513 if ( k === il ) k = 0;
25514 contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );
25515 }
25516 const holesMovements = [];
25517 let oneHoleMovements, verticesMovements = contourMovements.concat();
25518 for ( let h = 0, hl = holes.length; h < hl; h ++ ) {
25519 const ahole = holes[ h ];
25520 oneHoleMovements = [];
25521 for ( let i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
25522 if ( j === il ) j = 0;
25523 if ( k === il ) k = 0;
25524 oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );
25525 }
25526 holesMovements.push( oneHoleMovements );
25527 verticesMovements = verticesMovements.concat( oneHoleMovements );
25528 }
25529 for ( let b = 0; b < bevelSegments; b ++ ) {
25530 const t = b / bevelSegments;
25531 const z = bevelThickness * Math.cos( t * Math.PI / 2 );
25532 const bs = bevelSize * Math.sin( t * Math.PI / 2 ) + bevelOffset;
25533 for ( let i = 0, il = contour.length; i < il; i ++ ) {
25534 const vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
25535 v( vert.x, vert.y, - z );
25536 }
25537 for ( let h = 0, hl = holes.length; h < hl; h ++ ) {
25538 const ahole = holes[ h ];
25539 oneHoleMovements = holesMovements[ h ];
25540 for ( let i = 0, il = ahole.length; i < il; i ++ ) {
25541 const vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
25542 v( vert.x, vert.y, - z );
25543 }
25544 }
25545 }
25546 const bs = bevelSize + bevelOffset;
25547 for ( let i = 0; i < vlen; i ++ ) {
25548 const vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
25549 if ( ! extrudeByPath ) {
25550 v( vert.x, vert.y, 0 );
25551 } else {
25552 normal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );
25553 binormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );
25554 position2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );
25555 v( position2.x, position2.y, position2.z );
25556 }
25557 }
25558 for ( let s = 1; s <= steps; s ++ ) {
25559 for ( let i = 0; i < vlen; i ++ ) {
25560 const vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
25561 if ( ! extrudeByPath ) {
25562 v( vert.x, vert.y, depth / steps * s );
25563 } else {
25564 normal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );
25565 binormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );
25566 position2.copy( extrudePts[ s ] ).add( normal ).add( binormal );
25567 v( position2.x, position2.y, position2.z );
25568 }
25569 }
25570 }
25571 for ( let b = bevelSegments - 1; b >= 0; b -- ) {
25572 const t = b / bevelSegments;
25573 const z = bevelThickness * Math.cos( t * Math.PI / 2 );
25574 const bs = bevelSize * Math.sin( t * Math.PI / 2 ) + bevelOffset;
25575 for ( let i = 0, il = contour.length; i < il; i ++ ) {
25576 const vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
25577 v( vert.x, vert.y, depth + z );
25578 }
25579 for ( let h = 0, hl = holes.length; h < hl; h ++ ) {
25580 const ahole = holes[ h ];
25581 oneHoleMovements = holesMovements[ h ];
25582 for ( let i = 0, il = ahole.length; i < il; i ++ ) {
25583 const vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
25584 if ( ! extrudeByPath ) {
25585 v( vert.x, vert.y, depth + z );
25586 } else {
25587 v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );
25588 }
25589 }
25590 }
25591 }
25592 buildLidFaces();
25593 buildSideFaces();
25594 function buildLidFaces() {
25595 const start = verticesArray.length / 3;
25596 if ( bevelEnabled ) {
25597 let layer = 0;
25598 let offset = vlen * layer;
25599 for ( let i = 0; i < flen; i ++ ) {
25600 const face = faces[ i ];
25601 f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );
25602 }
25603 layer = steps + bevelSegments * 2;
25604 offset = vlen * layer;
25605 for ( let i = 0; i < flen; i ++ ) {
25606 const face = faces[ i ];
25607 f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );
25608 }
25609 } else {
25610 for ( let i = 0; i < flen; i ++ ) {
25611 const face = faces[ i ];
25612 f3( face[ 2 ], face[ 1 ], face[ 0 ] );
25613 }
25614 for ( let i = 0; i < flen; i ++ ) {
25615 const face = faces[ i ];
25616 f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );
25617 }
25618 }
25619 scope.addGroup( start, verticesArray.length / 3 - start, 0 );
25620 }
25621 function buildSideFaces() {
25622 const start = verticesArray.length / 3;
25623 let layeroffset = 0;
25624 sidewalls( contour, layeroffset );
25625 layeroffset += contour.length;
25626 for ( let h = 0, hl = holes.length; h < hl; h ++ ) {
25627 const ahole = holes[ h ];
25628 sidewalls( ahole, layeroffset );
25629 layeroffset += ahole.length;
25630 }
25631 scope.addGroup( start, verticesArray.length / 3 - start, 1 );
25632 }
25633 function sidewalls( contour, layeroffset ) {
25634 let i = contour.length;
25635 while ( -- i >= 0 ) {
25636 const j = i;
25637 let k = i - 1;
25638 if ( k < 0 ) k = contour.length - 1;
25639 for ( let s = 0, sl = ( steps + bevelSegments * 2 ); s < sl; s ++ ) {
25640 const slen1 = vlen * s;
25641 const slen2 = vlen * ( s + 1 );
25642 const a = layeroffset + j + slen1,
25643 b = layeroffset + k + slen1,
25644 c = layeroffset + k + slen2,
25645 d = layeroffset + j + slen2;
25646 f4( a, b, c, d );
25647 }
25648 }
25649 }
25650 function v( x, y, z ) {
25651 placeholder.push( x );
25652 placeholder.push( y );
25653 placeholder.push( z );
25654 }
25655 function f3( a, b, c ) {
25656 addVertex( a );
25657 addVertex( b );
25658 addVertex( c );
25659 const nextIndex = verticesArray.length / 3;
25660 const uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
25661 addUV( uvs[ 0 ] );
25662 addUV( uvs[ 1 ] );
25663 addUV( uvs[ 2 ] );
25664 }
25665 function f4( a, b, c, d ) {
25666 addVertex( a );
25667 addVertex( b );
25668 addVertex( d );
25669 addVertex( b );
25670 addVertex( c );
25671 addVertex( d );
25672 const nextIndex = verticesArray.length / 3;
25673 const uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
25674 addUV( uvs[ 0 ] );
25675 addUV( uvs[ 1 ] );
25676 addUV( uvs[ 3 ] );
25677 addUV( uvs[ 1 ] );
25678 addUV( uvs[ 2 ] );
25679 addUV( uvs[ 3 ] );
25680 }
25681 function addVertex( index ) {
25682 verticesArray.push( placeholder[ index * 3 + 0 ] );
25683 verticesArray.push( placeholder[ index * 3 + 1 ] );
25684 verticesArray.push( placeholder[ index * 3 + 2 ] );
25685 }
25686 function addUV( vector2 ) {
25687 uvArray.push( vector2.x );
25688 uvArray.push( vector2.y );
25689 }
25690 }
25691 }
25692 toJSON() {
25693 const data = BufferGeometry.prototype.toJSON.call( this );
25694 const shapes = this.parameters.shapes;
25695 const options = this.parameters.options;
25696 return toJSON( shapes, options, data );
25697 }
25698 }
25699 const WorldUVGenerator = {
25700 generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) {
25701 const a_x = vertices[ indexA * 3 ];
25702 const a_y = vertices[ indexA * 3 + 1 ];
25703 const b_x = vertices[ indexB * 3 ];
25704 const b_y = vertices[ indexB * 3 + 1 ];
25705 const c_x = vertices[ indexC * 3 ];
25706 const c_y = vertices[ indexC * 3 + 1 ];
25707 return [
25708 new Vector2( a_x, a_y ),
25709 new Vector2( b_x, b_y ),
25710 new Vector2( c_x, c_y )
25711 ];
25712 },
25713 generateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) {
25714 const a_x = vertices[ indexA * 3 ];
25715 const a_y = vertices[ indexA * 3 + 1 ];
25716 const a_z = vertices[ indexA * 3 + 2 ];
25717 const b_x = vertices[ indexB * 3 ];
25718 const b_y = vertices[ indexB * 3 + 1 ];
25719 const b_z = vertices[ indexB * 3 + 2 ];
25720 const c_x = vertices[ indexC * 3 ];
25721 const c_y = vertices[ indexC * 3 + 1 ];
25722 const c_z = vertices[ indexC * 3 + 2 ];
25723 const d_x = vertices[ indexD * 3 ];
25724 const d_y = vertices[ indexD * 3 + 1 ];
25725 const d_z = vertices[ indexD * 3 + 2 ];
25726 if ( Math.abs( a_y - b_y ) < 0.01 ) {
25727 return [
25728 new Vector2( a_x, 1 - a_z ),
25729 new Vector2( b_x, 1 - b_z ),
25730 new Vector2( c_x, 1 - c_z ),
25731 new Vector2( d_x, 1 - d_z )
25732 ];
25733 } else {
25734 return [
25735 new Vector2( a_y, 1 - a_z ),
25736 new Vector2( b_y, 1 - b_z ),
25737 new Vector2( c_y, 1 - c_z ),
25738 new Vector2( d_y, 1 - d_z )
25739 ];
25740 }
25741 }
25742 };
25743 function toJSON( shapes, options, data ) {
25744 data.shapes = [];
25745 if ( Array.isArray( shapes ) ) {
25746 for ( let i = 0, l = shapes.length; i < l; i ++ ) {
25747 const shape = shapes[ i ];
25748 data.shapes.push( shape.uuid );
25749 }
25750 } else {
25751 data.shapes.push( shapes.uuid );
25752 }
25753 if ( options.extrudePath !== undefined ) data.options.extrudePath = options.extrudePath.toJSON();
25754 return data;
25755 }
25756 class TextGeometry extends Geometry {
25757 constructor( text, parameters ) {
25758 super();
25759 this.type = 'TextGeometry';
25760 this.parameters = {
25761 text: text,
25762 parameters: parameters
25763 };
25764 this.fromBufferGeometry( new TextBufferGeometry( text, parameters ) );
25765 this.mergeVertices();
25766 }
25767 }
25768 class TextBufferGeometry extends ExtrudeBufferGeometry {
25769 constructor( text, parameters ) {
25770 parameters = parameters || {};
25771 const font = parameters.font;
25772 if ( ! ( font && font.isFont ) ) {
25773 console.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );
25774 return new Geometry();
25775 }
25776 const shapes = font.generateShapes( text, parameters.size );
25777 parameters.depth = parameters.height !== undefined ? parameters.height : 50;
25778 if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;
25779 if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;
25780 if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;
25781 super( shapes, parameters );
25782 this.type = 'TextBufferGeometry';
25783 }
25784 }
25785 class SphereGeometry extends Geometry {
25786 constructor( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
25787 super();
25788 this.type = 'SphereGeometry';
25789 this.parameters = {
25790 radius: radius,
25791 widthSegments: widthSegments,
25792 heightSegments: heightSegments,
25793 phiStart: phiStart,
25794 phiLength: phiLength,
25795 thetaStart: thetaStart,
25796 thetaLength: thetaLength
25797 };
25798 this.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );
25799 this.mergeVertices();
25800 }
25801 }
25802 class SphereBufferGeometry extends BufferGeometry {
25803 constructor( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
25804 super();
25805 this.type = 'SphereBufferGeometry';
25806 this.parameters = {
25807 radius: radius,
25808 widthSegments: widthSegments,
25809 heightSegments: heightSegments,
25810 phiStart: phiStart,
25811 phiLength: phiLength,
25812 thetaStart: thetaStart,
25813 thetaLength: thetaLength
25814 };
25815 radius = radius || 1;
25816 widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );
25817 heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );
25818 phiStart = phiStart !== undefined ? phiStart : 0;
25819 phiLength = phiLength !== undefined ? phiLength : Math.PI * 2;
25820 thetaStart = thetaStart !== undefined ? thetaStart : 0;
25821 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI;
25822 const thetaEnd = Math.min( thetaStart + thetaLength, Math.PI );
25823 let index = 0;
25824 const grid = [];
25825 const vertex = new Vector3();
25826 const normal = new Vector3();
25827 const indices = [];
25828 const vertices = [];
25829 const normals = [];
25830 const uvs = [];
25831 for ( let iy = 0; iy <= heightSegments; iy ++ ) {
25832 const verticesRow = [];
25833 const v = iy / heightSegments;
25834 let uOffset = 0;
25835 if ( iy == 0 && thetaStart == 0 ) {
25836 uOffset = 0.5 / widthSegments;
25837 } else if ( iy == heightSegments && thetaEnd == Math.PI ) {
25838 uOffset = - 0.5 / widthSegments;
25839 }
25840 for ( let ix = 0; ix <= widthSegments; ix ++ ) {
25841 const u = ix / widthSegments;
25842 vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
25843 vertex.y = radius * Math.cos( thetaStart + v * thetaLength );
25844 vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
25845 vertices.push( vertex.x, vertex.y, vertex.z );
25846 normal.copy( vertex ).normalize();
25847 normals.push( normal.x, normal.y, normal.z );
25848 uvs.push( u + uOffset, 1 - v );
25849 verticesRow.push( index ++ );
25850 }
25851 grid.push( verticesRow );
25852 }
25853 for ( let iy = 0; iy < heightSegments; iy ++ ) {
25854 for ( let ix = 0; ix < widthSegments; ix ++ ) {
25855 const a = grid[ iy ][ ix + 1 ];
25856 const b = grid[ iy ][ ix ];
25857 const c = grid[ iy + 1 ][ ix ];
25858 const d = grid[ iy + 1 ][ ix + 1 ];
25859 if ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );
25860 if ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );
25861 }
25862 }
25863 this.setIndex( indices );
25864 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
25865 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
25866 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
25867 }
25868 }
25869 class RingGeometry extends Geometry {
25870 constructor( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
25871 super();
25872 this.type = 'RingGeometry';
25873 this.parameters = {
25874 innerRadius: innerRadius,
25875 outerRadius: outerRadius,
25876 thetaSegments: thetaSegments,
25877 phiSegments: phiSegments,
25878 thetaStart: thetaStart,
25879 thetaLength: thetaLength
25880 };
25881 this.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );
25882 this.mergeVertices();
25883 }
25884 }
25885 class RingBufferGeometry extends BufferGeometry {
25886 constructor( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
25887 super();
25888 this.type = 'RingBufferGeometry';
25889 this.parameters = {
25890 innerRadius: innerRadius,
25891 outerRadius: outerRadius,
25892 thetaSegments: thetaSegments,
25893 phiSegments: phiSegments,
25894 thetaStart: thetaStart,
25895 thetaLength: thetaLength
25896 };
25897 innerRadius = innerRadius || 0.5;
25898 outerRadius = outerRadius || 1;
25899 thetaStart = thetaStart !== undefined ? thetaStart : 0;
25900 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
25901 thetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;
25902 phiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;
25903 const indices = [];
25904 const vertices = [];
25905 const normals = [];
25906 const uvs = [];
25907 let radius = innerRadius;
25908 const radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );
25909 const vertex = new Vector3();
25910 const uv = new Vector2();
25911 for ( let j = 0; j <= phiSegments; j ++ ) {
25912 for ( let i = 0; i <= thetaSegments; i ++ ) {
25913 const segment = thetaStart + i / thetaSegments * thetaLength;
25914 vertex.x = radius * Math.cos( segment );
25915 vertex.y = radius * Math.sin( segment );
25916 vertices.push( vertex.x, vertex.y, vertex.z );
25917 normals.push( 0, 0, 1 );
25918 uv.x = ( vertex.x / outerRadius + 1 ) / 2;
25919 uv.y = ( vertex.y / outerRadius + 1 ) / 2;
25920 uvs.push( uv.x, uv.y );
25921 }
25922 radius += radiusStep;
25923 }
25924 for ( let j = 0; j < phiSegments; j ++ ) {
25925 const thetaSegmentLevel = j * ( thetaSegments + 1 );
25926 for ( let i = 0; i < thetaSegments; i ++ ) {
25927 const segment = i + thetaSegmentLevel;
25928 const a = segment;
25929 const b = segment + thetaSegments + 1;
25930 const c = segment + thetaSegments + 2;
25931 const d = segment + 1;
25932 indices.push( a, b, d );
25933 indices.push( b, c, d );
25934 }
25935 }
25936 this.setIndex( indices );
25937 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
25938 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
25939 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
25940 }
25941 }
25942 class LatheGeometry extends Geometry {
25943 constructor( points, segments, phiStart, phiLength ) {
25944 super();
25945 this.type = 'LatheGeometry';
25946 this.parameters = {
25947 points: points,
25948 segments: segments,
25949 phiStart: phiStart,
25950 phiLength: phiLength
25951 };
25952 this.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );
25953 this.mergeVertices();
25954 }
25955 }
25956 class LatheBufferGeometry extends BufferGeometry {
25957 constructor( points, segments, phiStart, phiLength ) {
25958 super();
25959 this.type = 'LatheBufferGeometry';
25960 this.parameters = {
25961 points: points,
25962 segments: segments,
25963 phiStart: phiStart,
25964 phiLength: phiLength
25965 };
25966 segments = Math.floor( segments ) || 12;
25967 phiStart = phiStart || 0;
25968 phiLength = phiLength || Math.PI * 2;
25969 phiLength = MathUtils.clamp( phiLength, 0, Math.PI * 2 );
25970 const indices = [];
25971 const vertices = [];
25972 const uvs = [];
25973 const inverseSegments = 1.0 / segments;
25974 const vertex = new Vector3();
25975 const uv = new Vector2();
25976 for ( let i = 0; i <= segments; i ++ ) {
25977 const phi = phiStart + i * inverseSegments * phiLength;
25978 const sin = Math.sin( phi );
25979 const cos = Math.cos( phi );
25980 for ( let j = 0; j <= ( points.length - 1 ); j ++ ) {
25981 vertex.x = points[ j ].x * sin;
25982 vertex.y = points[ j ].y;
25983 vertex.z = points[ j ].x * cos;
25984 vertices.push( vertex.x, vertex.y, vertex.z );
25985 uv.x = i / segments;
25986 uv.y = j / ( points.length - 1 );
25987 uvs.push( uv.x, uv.y );
25988 }
25989 }
25990 for ( let i = 0; i < segments; i ++ ) {
25991 for ( let j = 0; j < ( points.length - 1 ); j ++ ) {
25992 const base = j + i * points.length;
25993 const a = base;
25994 const b = base + points.length;
25995 const c = base + points.length + 1;
25996 const d = base + 1;
25997 indices.push( a, b, d );
25998 indices.push( b, c, d );
25999 }
26000 }
26001 this.setIndex( indices );
26002 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
26003 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
26004 this.computeVertexNormals();
26005 if ( phiLength === Math.PI * 2 ) {
26006 const normals = this.attributes.normal.array;
26007 const n1 = new Vector3();
26008 const n2 = new Vector3();
26009 const n = new Vector3();
26010 const base = segments * points.length * 3;
26011 for ( let i = 0, j = 0; i < points.length; i ++, j += 3 ) {
26012 n1.x = normals[ j + 0 ];
26013 n1.y = normals[ j + 1 ];
26014 n1.z = normals[ j + 2 ];
26015 n2.x = normals[ base + j + 0 ];
26016 n2.y = normals[ base + j + 1 ];
26017 n2.z = normals[ base + j + 2 ];
26018 n.addVectors( n1, n2 ).normalize();
26019 normals[ j + 0 ] = normals[ base + j + 0 ] = n.x;
26020 normals[ j + 1 ] = normals[ base + j + 1 ] = n.y;
26021 normals[ j + 2 ] = normals[ base + j + 2 ] = n.z;
26022 }
26023 }
26024 }
26025 }
26026 class ShapeGeometry extends Geometry {
26027 constructor( shapes, curveSegments ) {
26028 super();
26029 this.type = 'ShapeGeometry';
26030 if ( typeof curveSegments === 'object' ) {
26031 console.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );
26032 curveSegments = curveSegments.curveSegments;
26033 }
26034 this.parameters = {
26035 shapes: shapes,
26036 curveSegments: curveSegments
26037 };
26038 this.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );
26039 this.mergeVertices();
26040 }
26041 toJSON() {
26042 const data = Geometry.prototype.toJSON.call( this );
26043 const shapes = this.parameters.shapes;
26044 return toJSON$1( shapes, data );
26045 }
26046 }
26047 class ShapeBufferGeometry extends BufferGeometry {
26048 constructor( shapes, curveSegments ) {
26049 super();
26050 this.type = 'ShapeBufferGeometry';
26051 this.parameters = {
26052 shapes: shapes,
26053 curveSegments: curveSegments
26054 };
26055 curveSegments = curveSegments || 12;
26056 const indices = [];
26057 const vertices = [];
26058 const normals = [];
26059 const uvs = [];
26060 let groupStart = 0;
26061 let groupCount = 0;
26062 if ( Array.isArray( shapes ) === false ) {
26063 addShape( shapes );
26064 } else {
26065 for ( let i = 0; i < shapes.length; i ++ ) {
26066 addShape( shapes[ i ] );
26067 this.addGroup( groupStart, groupCount, i );
26068 groupStart += groupCount;
26069 groupCount = 0;
26070 }
26071 }
26072 this.setIndex( indices );
26073 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
26074 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
26075 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
26076 function addShape( shape ) {
26077 const indexOffset = vertices.length / 3;
26078 const points = shape.extractPoints( curveSegments );
26079 let shapeVertices = points.shape;
26080 const shapeHoles = points.holes;
26081 if ( ShapeUtils.isClockWise( shapeVertices ) === false ) {
26082 shapeVertices = shapeVertices.reverse();
26083 }
26084 for ( let i = 0, l = shapeHoles.length; i < l; i ++ ) {
26085 const shapeHole = shapeHoles[ i ];
26086 if ( ShapeUtils.isClockWise( shapeHole ) === true ) {
26087 shapeHoles[ i ] = shapeHole.reverse();
26088 }
26089 }
26090 const faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );
26091 for ( let i = 0, l = shapeHoles.length; i < l; i ++ ) {
26092 const shapeHole = shapeHoles[ i ];
26093 shapeVertices = shapeVertices.concat( shapeHole );
26094 }
26095 for ( let i = 0, l = shapeVertices.length; i < l; i ++ ) {
26096 const vertex = shapeVertices[ i ];
26097 vertices.push( vertex.x, vertex.y, 0 );
26098 normals.push( 0, 0, 1 );
26099 uvs.push( vertex.x, vertex.y );
26100 }
26101 for ( let i = 0, l = faces.length; i < l; i ++ ) {
26102 const face = faces[ i ];
26103 const a = face[ 0 ] + indexOffset;
26104 const b = face[ 1 ] + indexOffset;
26105 const c = face[ 2 ] + indexOffset;
26106 indices.push( a, b, c );
26107 groupCount += 3;
26108 }
26109 }
26110 }
26111 toJSON() {
26112 const data = BufferGeometry.prototype.toJSON.call( this );
26113 const shapes = this.parameters.shapes;
26114 return toJSON$1( shapes, data );
26115 }
26116 }
26117 function toJSON$1( shapes, data ) {
26118 data.shapes = [];
26119 if ( Array.isArray( shapes ) ) {
26120 for ( let i = 0, l = shapes.length; i < l; i ++ ) {
26121 const shape = shapes[ i ];
26122 data.shapes.push( shape.uuid );
26123 }
26124 } else {
26125 data.shapes.push( shapes.uuid );
26126 }
26127 return data;
26128 }
26129 class EdgesGeometry extends BufferGeometry {
26130 constructor( geometry, thresholdAngle ) {
26131 super();
26132 this.type = 'EdgesGeometry';
26133 this.parameters = {
26134 thresholdAngle: thresholdAngle
26135 };
26136 thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;
26137 const vertices = [];
26138 const thresholdDot = Math.cos( MathUtils.DEG2RAD * thresholdAngle );
26139 const edge = [ 0, 0 ], edges = {};
26140 let edge1, edge2, key;
26141 const keys = [ 'a', 'b', 'c' ];
26142 let geometry2;
26143 if ( geometry.isBufferGeometry ) {
26144 geometry2 = new Geometry();
26145 geometry2.fromBufferGeometry( geometry );
26146 } else {
26147 geometry2 = geometry.clone();
26148 }
26149 geometry2.mergeVertices();
26150 geometry2.computeFaceNormals();
26151 const sourceVertices = geometry2.vertices;
26152 const faces = geometry2.faces;
26153 for ( let i = 0, l = faces.length; i < l; i ++ ) {
26154 const face = faces[ i ];
26155 for ( let j = 0; j < 3; j ++ ) {
26156 edge1 = face[ keys[ j ] ];
26157 edge2 = face[ keys[ ( j + 1 ) % 3 ] ];
26158 edge[ 0 ] = Math.min( edge1, edge2 );
26159 edge[ 1 ] = Math.max( edge1, edge2 );
26160 key = edge[ 0 ] + ',' + edge[ 1 ];
26161 if ( edges[ key ] === undefined ) {
26162 edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined };
26163 } else {
26164 edges[ key ].face2 = i;
26165 }
26166 }
26167 }
26168 for ( key in edges ) {
26169 const e = edges[ key ];
26170 if ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) {
26171 let vertex = sourceVertices[ e.index1 ];
26172 vertices.push( vertex.x, vertex.y, vertex.z );
26173 vertex = sourceVertices[ e.index2 ];
26174 vertices.push( vertex.x, vertex.y, vertex.z );
26175 }
26176 }
26177 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
26178 }
26179 }
26180 class CylinderGeometry extends Geometry {
26181 constructor( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
26182 super();
26183 this.type = 'CylinderGeometry';
26184 this.parameters = {
26185 radiusTop: radiusTop,
26186 radiusBottom: radiusBottom,
26187 height: height,
26188 radialSegments: radialSegments,
26189 heightSegments: heightSegments,
26190 openEnded: openEnded,
26191 thetaStart: thetaStart,
26192 thetaLength: thetaLength
26193 };
26194 this.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );
26195 this.mergeVertices();
26196 }
26197 }
26198 class CylinderBufferGeometry extends BufferGeometry {
26199 constructor( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
26200 super();
26201 this.type = 'CylinderBufferGeometry';
26202 this.parameters = {
26203 radiusTop: radiusTop,
26204 radiusBottom: radiusBottom,
26205 height: height,
26206 radialSegments: radialSegments,
26207 heightSegments: heightSegments,
26208 openEnded: openEnded,
26209 thetaStart: thetaStart,
26210 thetaLength: thetaLength
26211 };
26212 const scope = this;
26213 radiusTop = radiusTop !== undefined ? radiusTop : 1;
26214 radiusBottom = radiusBottom !== undefined ? radiusBottom : 1;
26215 height = height || 1;
26216 radialSegments = Math.floor( radialSegments ) || 8;
26217 heightSegments = Math.floor( heightSegments ) || 1;
26218 openEnded = openEnded !== undefined ? openEnded : false;
26219 thetaStart = thetaStart !== undefined ? thetaStart : 0.0;
26220 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
26221 const indices = [];
26222 const vertices = [];
26223 const normals = [];
26224 const uvs = [];
26225 let index = 0;
26226 const indexArray = [];
26227 const halfHeight = height / 2;
26228 let groupStart = 0;
26229 generateTorso();
26230 if ( openEnded === false ) {
26231 if ( radiusTop > 0 ) generateCap( true );
26232 if ( radiusBottom > 0 ) generateCap( false );
26233 }
26234 this.setIndex( indices );
26235 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
26236 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
26237 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
26238 function generateTorso() {
26239 const normal = new Vector3();
26240 const vertex = new Vector3();
26241 let groupCount = 0;
26242 const slope = ( radiusBottom - radiusTop ) / height;
26243 for ( let y = 0; y <= heightSegments; y ++ ) {
26244 const indexRow = [];
26245 const v = y / heightSegments;
26246 const radius = v * ( radiusBottom - radiusTop ) + radiusTop;
26247 for ( let x = 0; x <= radialSegments; x ++ ) {
26248 const u = x / radialSegments;
26249 const theta = u * thetaLength + thetaStart;
26250 const sinTheta = Math.sin( theta );
26251 const cosTheta = Math.cos( theta );
26252 vertex.x = radius * sinTheta;
26253 vertex.y = - v * height + halfHeight;
26254 vertex.z = radius * cosTheta;
26255 vertices.push( vertex.x, vertex.y, vertex.z );
26256 normal.set( sinTheta, slope, cosTheta ).normalize();
26257 normals.push( normal.x, normal.y, normal.z );
26258 uvs.push( u, 1 - v );
26259 indexRow.push( index ++ );
26260 }
26261 indexArray.push( indexRow );
26262 }
26263 for ( let x = 0; x < radialSegments; x ++ ) {
26264 for ( let y = 0; y < heightSegments; y ++ ) {
26265 const a = indexArray[ y ][ x ];
26266 const b = indexArray[ y + 1 ][ x ];
26267 const c = indexArray[ y + 1 ][ x + 1 ];
26268 const d = indexArray[ y ][ x + 1 ];
26269 indices.push( a, b, d );
26270 indices.push( b, c, d );
26271 groupCount += 6;
26272 }
26273 }
26274 scope.addGroup( groupStart, groupCount, 0 );
26275 groupStart += groupCount;
26276 }
26277 function generateCap( top ) {
26278 const centerIndexStart = index;
26279 const uv = new Vector2();
26280 const vertex = new Vector3();
26281 let groupCount = 0;
26282 const radius = ( top === true ) ? radiusTop : radiusBottom;
26283 const sign = ( top === true ) ? 1 : - 1;
26284 for ( let x = 1; x <= radialSegments; x ++ ) {
26285 vertices.push( 0, halfHeight * sign, 0 );
26286 normals.push( 0, sign, 0 );
26287 uvs.push( 0.5, 0.5 );
26288 index ++;
26289 }
26290 const centerIndexEnd = index;
26291 for ( let x = 0; x <= radialSegments; x ++ ) {
26292 const u = x / radialSegments;
26293 const theta = u * thetaLength + thetaStart;
26294 const cosTheta = Math.cos( theta );
26295 const sinTheta = Math.sin( theta );
26296 vertex.x = radius * sinTheta;
26297 vertex.y = halfHeight * sign;
26298 vertex.z = radius * cosTheta;
26299 vertices.push( vertex.x, vertex.y, vertex.z );
26300 normals.push( 0, sign, 0 );
26301 uv.x = ( cosTheta * 0.5 ) + 0.5;
26302 uv.y = ( sinTheta * 0.5 * sign ) + 0.5;
26303 uvs.push( uv.x, uv.y );
26304 index ++;
26305 }
26306 for ( let x = 0; x < radialSegments; x ++ ) {
26307 const c = centerIndexStart + x;
26308 const i = centerIndexEnd + x;
26309 if ( top === true ) {
26310 indices.push( i, i + 1, c );
26311 } else {
26312 indices.push( i + 1, i, c );
26313 }
26314 groupCount += 3;
26315 }
26316 scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );
26317 groupStart += groupCount;
26318 }
26319 }
26320 }
26321 class ConeGeometry extends CylinderGeometry {
26322 constructor( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
26323 super( 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );
26324 this.type = 'ConeGeometry';
26325 this.parameters = {
26326 radius: radius,
26327 height: height,
26328 radialSegments: radialSegments,
26329 heightSegments: heightSegments,
26330 openEnded: openEnded,
26331 thetaStart: thetaStart,
26332 thetaLength: thetaLength
26333 };
26334 }
26335 }
26336 class ConeBufferGeometry extends CylinderBufferGeometry {
26337 constructor( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
26338 super( 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );
26339 this.type = 'ConeBufferGeometry';
26340 this.parameters = {
26341 radius: radius,
26342 height: height,
26343 radialSegments: radialSegments,
26344 heightSegments: heightSegments,
26345 openEnded: openEnded,
26346 thetaStart: thetaStart,
26347 thetaLength: thetaLength
26348 };
26349 }
26350 }
26351 class CircleGeometry extends Geometry {
26352 constructor( radius, segments, thetaStart, thetaLength ) {
26353 super();
26354 this.type = 'CircleGeometry';
26355 this.parameters = {
26356 radius: radius,
26357 segments: segments,
26358 thetaStart: thetaStart,
26359 thetaLength: thetaLength
26360 };
26361 this.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );
26362 this.mergeVertices();
26363 }
26364 }
26365 class CircleBufferGeometry extends BufferGeometry {
26366 constructor( radius, segments, thetaStart, thetaLength ) {
26367 super();
26368 this.type = 'CircleBufferGeometry';
26369 this.parameters = {
26370 radius: radius,
26371 segments: segments,
26372 thetaStart: thetaStart,
26373 thetaLength: thetaLength
26374 };
26375 radius = radius || 1;
26376 segments = segments !== undefined ? Math.max( 3, segments ) : 8;
26377 thetaStart = thetaStart !== undefined ? thetaStart : 0;
26378 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
26379 const indices = [];
26380 const vertices = [];
26381 const normals = [];
26382 const uvs = [];
26383 const vertex = new Vector3();
26384 const uv = new Vector2();
26385 vertices.push( 0, 0, 0 );
26386 normals.push( 0, 0, 1 );
26387 uvs.push( 0.5, 0.5 );
26388 for ( let s = 0, i = 3; s <= segments; s ++, i += 3 ) {
26389 const segment = thetaStart + s / segments * thetaLength;
26390 vertex.x = radius * Math.cos( segment );
26391 vertex.y = radius * Math.sin( segment );
26392 vertices.push( vertex.x, vertex.y, vertex.z );
26393 normals.push( 0, 0, 1 );
26394 uv.x = ( vertices[ i ] / radius + 1 ) / 2;
26395 uv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;
26396 uvs.push( uv.x, uv.y );
26397 }
26398 for ( let i = 1; i <= segments; i ++ ) {
26399 indices.push( i, i + 1, 0 );
26400 }
26401 this.setIndex( indices );
26402 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
26403 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
26404 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
26405 }
26406 }
26407 var Geometries = Object.freeze({
26408 __proto__: null,
26409 WireframeGeometry: WireframeGeometry,
26410 ParametricGeometry: ParametricGeometry,
26411 ParametricBufferGeometry: ParametricBufferGeometry,
26412 TetrahedronGeometry: TetrahedronGeometry,
26413 TetrahedronBufferGeometry: TetrahedronBufferGeometry,
26414 OctahedronGeometry: OctahedronGeometry,
26415 OctahedronBufferGeometry: OctahedronBufferGeometry,
26416 IcosahedronGeometry: IcosahedronGeometry,
26417 IcosahedronBufferGeometry: IcosahedronBufferGeometry,
26418 DodecahedronGeometry: DodecahedronGeometry,
26419 DodecahedronBufferGeometry: DodecahedronBufferGeometry,
26420 PolyhedronGeometry: PolyhedronGeometry,
26421 PolyhedronBufferGeometry: PolyhedronBufferGeometry,
26422 TubeGeometry: TubeGeometry,
26423 TubeBufferGeometry: TubeBufferGeometry,
26424 TorusKnotGeometry: TorusKnotGeometry,
26425 TorusKnotBufferGeometry: TorusKnotBufferGeometry,
26426 TorusGeometry: TorusGeometry,
26427 TorusBufferGeometry: TorusBufferGeometry,
26428 TextGeometry: TextGeometry,
26429 TextBufferGeometry: TextBufferGeometry,
26430 SphereGeometry: SphereGeometry,
26431 SphereBufferGeometry: SphereBufferGeometry,
26432 RingGeometry: RingGeometry,
26433 RingBufferGeometry: RingBufferGeometry,
26434 PlaneGeometry: PlaneGeometry,
26435 PlaneBufferGeometry: PlaneBufferGeometry,
26436 LatheGeometry: LatheGeometry,
26437 LatheBufferGeometry: LatheBufferGeometry,
26438 ShapeGeometry: ShapeGeometry,
26439 ShapeBufferGeometry: ShapeBufferGeometry,
26440 ExtrudeGeometry: ExtrudeGeometry,
26441 ExtrudeBufferGeometry: ExtrudeBufferGeometry,
26442 EdgesGeometry: EdgesGeometry,
26443 ConeGeometry: ConeGeometry,
26444 ConeBufferGeometry: ConeBufferGeometry,
26445 CylinderGeometry: CylinderGeometry,
26446 CylinderBufferGeometry: CylinderBufferGeometry,
26447 CircleGeometry: CircleGeometry,
26448 CircleBufferGeometry: CircleBufferGeometry,
26449 BoxGeometry: BoxGeometry,
26450 BoxBufferGeometry: BoxBufferGeometry
26451 });
26452 function ShadowMaterial( parameters ) {
26453 Material.call( this );
26454 this.type = 'ShadowMaterial';
26455 this.color = new Color( 0x000000 );
26456 this.transparent = true;
26457 this.setValues( parameters );
26458 }
26459 ShadowMaterial.prototype = Object.create( Material.prototype );
26460 ShadowMaterial.prototype.constructor = ShadowMaterial;
26461 ShadowMaterial.prototype.isShadowMaterial = true;
26462 ShadowMaterial.prototype.copy = function ( source ) {
26463 Material.prototype.copy.call( this, source );
26464 this.color.copy( source.color );
26465 return this;
26466 };
26467 function RawShaderMaterial( parameters ) {
26468 ShaderMaterial.call( this, parameters );
26469 this.type = 'RawShaderMaterial';
26470 }
26471 RawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );
26472 RawShaderMaterial.prototype.constructor = RawShaderMaterial;
26473 RawShaderMaterial.prototype.isRawShaderMaterial = true;
26474 function MeshStandardMaterial( parameters ) {
26475 Material.call( this );
26476 this.defines = { 'STANDARD': '' };
26477 this.type = 'MeshStandardMaterial';
26478 this.color = new Color( 0xffffff );
26479 this.roughness = 1.0;
26480 this.metalness = 0.0;
26481 this.map = null;
26482 this.lightMap = null;
26483 this.lightMapIntensity = 1.0;
26484 this.aoMap = null;
26485 this.aoMapIntensity = 1.0;
26486 this.emissive = new Color( 0x000000 );
26487 this.emissiveIntensity = 1.0;
26488 this.emissiveMap = null;
26489 this.bumpMap = null;
26490 this.bumpScale = 1;
26491 this.normalMap = null;
26492 this.normalMapType = TangentSpaceNormalMap;
26493 this.normalScale = new Vector2( 1, 1 );
26494 this.displacementMap = null;
26495 this.displacementScale = 1;
26496 this.displacementBias = 0;
26497 this.roughnessMap = null;
26498 this.metalnessMap = null;
26499 this.alphaMap = null;
26500 this.envMap = null;
26501 this.envMapIntensity = 1.0;
26502 this.refractionRatio = 0.98;
26503 this.wireframe = false;
26504 this.wireframeLinewidth = 1;
26505 this.wireframeLinecap = 'round';
26506 this.wireframeLinejoin = 'round';
26507 this.skinning = false;
26508 this.morphTargets = false;
26509 this.morphNormals = false;
26510 this.vertexTangents = false;
26511 this.setValues( parameters );
26512 }
26513 MeshStandardMaterial.prototype = Object.create( Material.prototype );
26514 MeshStandardMaterial.prototype.constructor = MeshStandardMaterial;
26515 MeshStandardMaterial.prototype.isMeshStandardMaterial = true;
26516 MeshStandardMaterial.prototype.copy = function ( source ) {
26517 Material.prototype.copy.call( this, source );
26518 this.defines = { 'STANDARD': '' };
26519 this.color.copy( source.color );
26520 this.roughness = source.roughness;
26521 this.metalness = source.metalness;
26522 this.map = source.map;
26523 this.lightMap = source.lightMap;
26524 this.lightMapIntensity = source.lightMapIntensity;
26525 this.aoMap = source.aoMap;
26526 this.aoMapIntensity = source.aoMapIntensity;
26527 this.emissive.copy( source.emissive );
26528 this.emissiveMap = source.emissiveMap;
26529 this.emissiveIntensity = source.emissiveIntensity;
26530 this.bumpMap = source.bumpMap;
26531 this.bumpScale = source.bumpScale;
26532 this.normalMap = source.normalMap;
26533 this.normalMapType = source.normalMapType;
26534 this.normalScale.copy( source.normalScale );
26535 this.displacementMap = source.displacementMap;
26536 this.displacementScale = source.displacementScale;
26537 this.displacementBias = source.displacementBias;
26538 this.roughnessMap = source.roughnessMap;
26539 this.metalnessMap = source.metalnessMap;
26540 this.alphaMap = source.alphaMap;
26541 this.envMap = source.envMap;
26542 this.envMapIntensity = source.envMapIntensity;
26543 this.refractionRatio = source.refractionRatio;
26544 this.wireframe = source.wireframe;
26545 this.wireframeLinewidth = source.wireframeLinewidth;
26546 this.wireframeLinecap = source.wireframeLinecap;
26547 this.wireframeLinejoin = source.wireframeLinejoin;
26548 this.skinning = source.skinning;
26549 this.morphTargets = source.morphTargets;
26550 this.morphNormals = source.morphNormals;
26551 this.vertexTangents = source.vertexTangents;
26552 return this;
26553 };
26554 function MeshPhysicalMaterial( parameters ) {
26555 MeshStandardMaterial.call( this );
26556 this.defines = {
26557 'STANDARD': '',
26558 'PHYSICAL': ''
26559 };
26560 this.type = 'MeshPhysicalMaterial';
26561 this.clearcoat = 0.0;
26562 this.clearcoatMap = null;
26563 this.clearcoatRoughness = 0.0;
26564 this.clearcoatRoughnessMap = null;
26565 this.clearcoatNormalScale = new Vector2( 1, 1 );
26566 this.clearcoatNormalMap = null;
26567 this.reflectivity = 0.5;
26568 this.sheen = null;
26569 this.transmission = 0.0;
26570 this.transmissionMap = null;
26571 this.setValues( parameters );
26572 }
26573 MeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );
26574 MeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;
26575 MeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;
26576 MeshPhysicalMaterial.prototype.copy = function ( source ) {
26577 MeshStandardMaterial.prototype.copy.call( this, source );
26578 this.defines = {
26579 'STANDARD': '',
26580 'PHYSICAL': ''
26581 };
26582 this.clearcoat = source.clearcoat;
26583 this.clearcoatMap = source.clearcoatMap;
26584 this.clearcoatRoughness = source.clearcoatRoughness;
26585 this.clearcoatRoughnessMap = source.clearcoatRoughnessMap;
26586 this.clearcoatNormalMap = source.clearcoatNormalMap;
26587 this.clearcoatNormalScale.copy( source.clearcoatNormalScale );
26588 this.reflectivity = source.reflectivity;
26589 if ( source.sheen ) {
26590 this.sheen = ( this.sheen || new Color() ).copy( source.sheen );
26591 } else {
26592 this.sheen = null;
26593 }
26594 this.transmission = source.transmission;
26595 this.transmissionMap = source.transmissionMap;
26596 return this;
26597 };
26598 function MeshPhongMaterial( parameters ) {
26599 Material.call( this );
26600 this.type = 'MeshPhongMaterial';
26601 this.color = new Color( 0xffffff );
26602 this.specular = new Color( 0x111111 );
26603 this.shininess = 30;
26604 this.map = null;
26605 this.lightMap = null;
26606 this.lightMapIntensity = 1.0;
26607 this.aoMap = null;
26608 this.aoMapIntensity = 1.0;
26609 this.emissive = new Color( 0x000000 );
26610 this.emissiveIntensity = 1.0;
26611 this.emissiveMap = null;
26612 this.bumpMap = null;
26613 this.bumpScale = 1;
26614 this.normalMap = null;
26615 this.normalMapType = TangentSpaceNormalMap;
26616 this.normalScale = new Vector2( 1, 1 );
26617 this.displacementMap = null;
26618 this.displacementScale = 1;
26619 this.displacementBias = 0;
26620 this.specularMap = null;
26621 this.alphaMap = null;
26622 this.envMap = null;
26623 this.combine = MultiplyOperation;
26624 this.reflectivity = 1;
26625 this.refractionRatio = 0.98;
26626 this.wireframe = false;
26627 this.wireframeLinewidth = 1;
26628 this.wireframeLinecap = 'round';
26629 this.wireframeLinejoin = 'round';
26630 this.skinning = false;
26631 this.morphTargets = false;
26632 this.morphNormals = false;
26633 this.setValues( parameters );
26634 }
26635 MeshPhongMaterial.prototype = Object.create( Material.prototype );
26636 MeshPhongMaterial.prototype.constructor = MeshPhongMaterial;
26637 MeshPhongMaterial.prototype.isMeshPhongMaterial = true;
26638 MeshPhongMaterial.prototype.copy = function ( source ) {
26639 Material.prototype.copy.call( this, source );
26640 this.color.copy( source.color );
26641 this.specular.copy( source.specular );
26642 this.shininess = source.shininess;
26643 this.map = source.map;
26644 this.lightMap = source.lightMap;
26645 this.lightMapIntensity = source.lightMapIntensity;
26646 this.aoMap = source.aoMap;
26647 this.aoMapIntensity = source.aoMapIntensity;
26648 this.emissive.copy( source.emissive );
26649 this.emissiveMap = source.emissiveMap;
26650 this.emissiveIntensity = source.emissiveIntensity;
26651 this.bumpMap = source.bumpMap;
26652 this.bumpScale = source.bumpScale;
26653 this.normalMap = source.normalMap;
26654 this.normalMapType = source.normalMapType;
26655 this.normalScale.copy( source.normalScale );
26656 this.displacementMap = source.displacementMap;
26657 this.displacementScale = source.displacementScale;
26658 this.displacementBias = source.displacementBias;
26659 this.specularMap = source.specularMap;
26660 this.alphaMap = source.alphaMap;
26661 this.envMap = source.envMap;
26662 this.combine = source.combine;
26663 this.reflectivity = source.reflectivity;
26664 this.refractionRatio = source.refractionRatio;
26665 this.wireframe = source.wireframe;
26666 this.wireframeLinewidth = source.wireframeLinewidth;
26667 this.wireframeLinecap = source.wireframeLinecap;
26668 this.wireframeLinejoin = source.wireframeLinejoin;
26669 this.skinning = source.skinning;
26670 this.morphTargets = source.morphTargets;
26671 this.morphNormals = source.morphNormals;
26672 return this;
26673 };
26674 function MeshToonMaterial( parameters ) {
26675 Material.call( this );
26676 this.defines = { 'TOON': '' };
26677 this.type = 'MeshToonMaterial';
26678 this.color = new Color( 0xffffff );
26679 this.map = null;
26680 this.gradientMap = null;
26681 this.lightMap = null;
26682 this.lightMapIntensity = 1.0;
26683 this.aoMap = null;
26684 this.aoMapIntensity = 1.0;
26685 this.emissive = new Color( 0x000000 );
26686 this.emissiveIntensity = 1.0;
26687 this.emissiveMap = null;
26688 this.bumpMap = null;
26689 this.bumpScale = 1;
26690 this.normalMap = null;
26691 this.normalMapType = TangentSpaceNormalMap;
26692 this.normalScale = new Vector2( 1, 1 );
26693 this.displacementMap = null;
26694 this.displacementScale = 1;
26695 this.displacementBias = 0;
26696 this.alphaMap = null;
26697 this.wireframe = false;
26698 this.wireframeLinewidth = 1;
26699 this.wireframeLinecap = 'round';
26700 this.wireframeLinejoin = 'round';
26701 this.skinning = false;
26702 this.morphTargets = false;
26703 this.morphNormals = false;
26704 this.setValues( parameters );
26705 }
26706 MeshToonMaterial.prototype = Object.create( Material.prototype );
26707 MeshToonMaterial.prototype.constructor = MeshToonMaterial;
26708 MeshToonMaterial.prototype.isMeshToonMaterial = true;
26709 MeshToonMaterial.prototype.copy = function ( source ) {
26710 Material.prototype.copy.call( this, source );
26711 this.color.copy( source.color );
26712 this.map = source.map;
26713 this.gradientMap = source.gradientMap;
26714 this.lightMap = source.lightMap;
26715 this.lightMapIntensity = source.lightMapIntensity;
26716 this.aoMap = source.aoMap;
26717 this.aoMapIntensity = source.aoMapIntensity;
26718 this.emissive.copy( source.emissive );
26719 this.emissiveMap = source.emissiveMap;
26720 this.emissiveIntensity = source.emissiveIntensity;
26721 this.bumpMap = source.bumpMap;
26722 this.bumpScale = source.bumpScale;
26723 this.normalMap = source.normalMap;
26724 this.normalMapType = source.normalMapType;
26725 this.normalScale.copy( source.normalScale );
26726 this.displacementMap = source.displacementMap;
26727 this.displacementScale = source.displacementScale;
26728 this.displacementBias = source.displacementBias;
26729 this.alphaMap = source.alphaMap;
26730 this.wireframe = source.wireframe;
26731 this.wireframeLinewidth = source.wireframeLinewidth;
26732 this.wireframeLinecap = source.wireframeLinecap;
26733 this.wireframeLinejoin = source.wireframeLinejoin;
26734 this.skinning = source.skinning;
26735 this.morphTargets = source.morphTargets;
26736 this.morphNormals = source.morphNormals;
26737 return this;
26738 };
26739 function MeshNormalMaterial( parameters ) {
26740 Material.call( this );
26741 this.type = 'MeshNormalMaterial';
26742 this.bumpMap = null;
26743 this.bumpScale = 1;
26744 this.normalMap = null;
26745 this.normalMapType = TangentSpaceNormalMap;
26746 this.normalScale = new Vector2( 1, 1 );
26747 this.displacementMap = null;
26748 this.displacementScale = 1;
26749 this.displacementBias = 0;
26750 this.wireframe = false;
26751 this.wireframeLinewidth = 1;
26752 this.fog = false;
26753 this.skinning = false;
26754 this.morphTargets = false;
26755 this.morphNormals = false;
26756 this.setValues( parameters );
26757 }
26758 MeshNormalMaterial.prototype = Object.create( Material.prototype );
26759 MeshNormalMaterial.prototype.constructor = MeshNormalMaterial;
26760 MeshNormalMaterial.prototype.isMeshNormalMaterial = true;
26761 MeshNormalMaterial.prototype.copy = function ( source ) {
26762 Material.prototype.copy.call( this, source );
26763 this.bumpMap = source.bumpMap;
26764 this.bumpScale = source.bumpScale;
26765 this.normalMap = source.normalMap;
26766 this.normalMapType = source.normalMapType;
26767 this.normalScale.copy( source.normalScale );
26768 this.displacementMap = source.displacementMap;
26769 this.displacementScale = source.displacementScale;
26770 this.displacementBias = source.displacementBias;
26771 this.wireframe = source.wireframe;
26772 this.wireframeLinewidth = source.wireframeLinewidth;
26773 this.skinning = source.skinning;
26774 this.morphTargets = source.morphTargets;
26775 this.morphNormals = source.morphNormals;
26776 return this;
26777 };
26778 function MeshLambertMaterial( parameters ) {
26779 Material.call( this );
26780 this.type = 'MeshLambertMaterial';
26781 this.color = new Color( 0xffffff );
26782 this.map = null;
26783 this.lightMap = null;
26784 this.lightMapIntensity = 1.0;
26785 this.aoMap = null;
26786 this.aoMapIntensity = 1.0;
26787 this.emissive = new Color( 0x000000 );
26788 this.emissiveIntensity = 1.0;
26789 this.emissiveMap = null;
26790 this.specularMap = null;
26791 this.alphaMap = null;
26792 this.envMap = null;
26793 this.combine = MultiplyOperation;
26794 this.reflectivity = 1;
26795 this.refractionRatio = 0.98;
26796 this.wireframe = false;
26797 this.wireframeLinewidth = 1;
26798 this.wireframeLinecap = 'round';
26799 this.wireframeLinejoin = 'round';
26800 this.skinning = false;
26801 this.morphTargets = false;
26802 this.morphNormals = false;
26803 this.setValues( parameters );
26804 }
26805 MeshLambertMaterial.prototype = Object.create( Material.prototype );
26806 MeshLambertMaterial.prototype.constructor = MeshLambertMaterial;
26807 MeshLambertMaterial.prototype.isMeshLambertMaterial = true;
26808 MeshLambertMaterial.prototype.copy = function ( source ) {
26809 Material.prototype.copy.call( this, source );
26810 this.color.copy( source.color );
26811 this.map = source.map;
26812 this.lightMap = source.lightMap;
26813 this.lightMapIntensity = source.lightMapIntensity;
26814 this.aoMap = source.aoMap;
26815 this.aoMapIntensity = source.aoMapIntensity;
26816 this.emissive.copy( source.emissive );
26817 this.emissiveMap = source.emissiveMap;
26818 this.emissiveIntensity = source.emissiveIntensity;
26819 this.specularMap = source.specularMap;
26820 this.alphaMap = source.alphaMap;
26821 this.envMap = source.envMap;
26822 this.combine = source.combine;
26823 this.reflectivity = source.reflectivity;
26824 this.refractionRatio = source.refractionRatio;
26825 this.wireframe = source.wireframe;
26826 this.wireframeLinewidth = source.wireframeLinewidth;
26827 this.wireframeLinecap = source.wireframeLinecap;
26828 this.wireframeLinejoin = source.wireframeLinejoin;
26829 this.skinning = source.skinning;
26830 this.morphTargets = source.morphTargets;
26831 this.morphNormals = source.morphNormals;
26832 return this;
26833 };
26834 function MeshMatcapMaterial( parameters ) {
26835 Material.call( this );
26836 this.defines = { 'MATCAP': '' };
26837 this.type = 'MeshMatcapMaterial';
26838 this.color = new Color( 0xffffff );
26839 this.matcap = null;
26840 this.map = null;
26841 this.bumpMap = null;
26842 this.bumpScale = 1;
26843 this.normalMap = null;
26844 this.normalMapType = TangentSpaceNormalMap;
26845 this.normalScale = new Vector2( 1, 1 );
26846 this.displacementMap = null;
26847 this.displacementScale = 1;
26848 this.displacementBias = 0;
26849 this.alphaMap = null;
26850 this.skinning = false;
26851 this.morphTargets = false;
26852 this.morphNormals = false;
26853 this.setValues( parameters );
26854 }
26855 MeshMatcapMaterial.prototype = Object.create( Material.prototype );
26856 MeshMatcapMaterial.prototype.constructor = MeshMatcapMaterial;
26857 MeshMatcapMaterial.prototype.isMeshMatcapMaterial = true;
26858 MeshMatcapMaterial.prototype.copy = function ( source ) {
26859 Material.prototype.copy.call( this, source );
26860 this.defines = { 'MATCAP': '' };
26861 this.color.copy( source.color );
26862 this.matcap = source.matcap;
26863 this.map = source.map;
26864 this.bumpMap = source.bumpMap;
26865 this.bumpScale = source.bumpScale;
26866 this.normalMap = source.normalMap;
26867 this.normalMapType = source.normalMapType;
26868 this.normalScale.copy( source.normalScale );
26869 this.displacementMap = source.displacementMap;
26870 this.displacementScale = source.displacementScale;
26871 this.displacementBias = source.displacementBias;
26872 this.alphaMap = source.alphaMap;
26873 this.skinning = source.skinning;
26874 this.morphTargets = source.morphTargets;
26875 this.morphNormals = source.morphNormals;
26876 return this;
26877 };
26878 function LineDashedMaterial( parameters ) {
26879 LineBasicMaterial.call( this );
26880 this.type = 'LineDashedMaterial';
26881 this.scale = 1;
26882 this.dashSize = 3;
26883 this.gapSize = 1;
26884 this.setValues( parameters );
26885 }
26886 LineDashedMaterial.prototype = Object.create( LineBasicMaterial.prototype );
26887 LineDashedMaterial.prototype.constructor = LineDashedMaterial;
26888 LineDashedMaterial.prototype.isLineDashedMaterial = true;
26889 LineDashedMaterial.prototype.copy = function ( source ) {
26890 LineBasicMaterial.prototype.copy.call( this, source );
26891 this.scale = source.scale;
26892 this.dashSize = source.dashSize;
26893 this.gapSize = source.gapSize;
26894 return this;
26895 };
26896 var Materials = Object.freeze({
26897 __proto__: null,
26898 ShadowMaterial: ShadowMaterial,
26899 SpriteMaterial: SpriteMaterial,
26900 RawShaderMaterial: RawShaderMaterial,
26901 ShaderMaterial: ShaderMaterial,
26902 PointsMaterial: PointsMaterial,
26903 MeshPhysicalMaterial: MeshPhysicalMaterial,
26904 MeshStandardMaterial: MeshStandardMaterial,
26905 MeshPhongMaterial: MeshPhongMaterial,
26906 MeshToonMaterial: MeshToonMaterial,
26907 MeshNormalMaterial: MeshNormalMaterial,
26908 MeshLambertMaterial: MeshLambertMaterial,
26909 MeshDepthMaterial: MeshDepthMaterial,
26910 MeshDistanceMaterial: MeshDistanceMaterial,
26911 MeshBasicMaterial: MeshBasicMaterial,
26912 MeshMatcapMaterial: MeshMatcapMaterial,
26913 LineDashedMaterial: LineDashedMaterial,
26914 LineBasicMaterial: LineBasicMaterial,
26915 Material: Material
26916 });
26917 const AnimationUtils = {
26918 arraySlice: function ( array, from, to ) {
26919 if ( AnimationUtils.isTypedArray( array ) ) {
26920 return new array.constructor( array.subarray( from, to !== undefined ? to : array.length ) );
26921 }
26922 return array.slice( from, to );
26923 },
26924 convertArray: function ( array, type, forceClone ) {
26925 if ( ! array ||
26926 ! forceClone && array.constructor === type ) return array;
26927 if ( typeof type.BYTES_PER_ELEMENT === 'number' ) {
26928 return new type( array );
26929 }
26930 return Array.prototype.slice.call( array );
26931 },
26932 isTypedArray: function ( object ) {
26933 return ArrayBuffer.isView( object ) &&
26934 ! ( object instanceof DataView );
26935 },
26936 getKeyframeOrder: function ( times ) {
26937 function compareTime( i, j ) {
26938 return times[ i ] - times[ j ];
26939 }
26940 const n = times.length;
26941 const result = new Array( n );
26942 for ( let i = 0; i !== n; ++ i ) result[ i ] = i;
26943 result.sort( compareTime );
26944 return result;
26945 },
26946 sortedArray: function ( values, stride, order ) {
26947 const nValues = values.length;
26948 const result = new values.constructor( nValues );
26949 for ( let i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {
26950 const srcOffset = order[ i ] * stride;
26951 for ( let j = 0; j !== stride; ++ j ) {
26952 result[ dstOffset ++ ] = values[ srcOffset + j ];
26953 }
26954 }
26955 return result;
26956 },
26957 flattenJSON: function ( jsonKeys, times, values, valuePropertyName ) {
26958 let i = 1, key = jsonKeys[ 0 ];
26959 while ( key !== undefined && key[ valuePropertyName ] === undefined ) {
26960 key = jsonKeys[ i ++ ];
26961 }
26962 if ( key === undefined ) return;
26963 let value = key[ valuePropertyName ];
26964 if ( value === undefined ) return;
26965 if ( Array.isArray( value ) ) {
26966 do {
26967 value = key[ valuePropertyName ];
26968 if ( value !== undefined ) {
26969 times.push( key.time );
26970 values.push.apply( values, value );
26971 }
26972 key = jsonKeys[ i ++ ];
26973 } while ( key !== undefined );
26974 } else if ( value.toArray !== undefined ) {
26975 do {
26976 value = key[ valuePropertyName ];
26977 if ( value !== undefined ) {
26978 times.push( key.time );
26979 value.toArray( values, values.length );
26980 }
26981 key = jsonKeys[ i ++ ];
26982 } while ( key !== undefined );
26983 } else {
26984 do {
26985 value = key[ valuePropertyName ];
26986 if ( value !== undefined ) {
26987 times.push( key.time );
26988 values.push( value );
26989 }
26990 key = jsonKeys[ i ++ ];
26991 } while ( key !== undefined );
26992 }
26993 },
26994 subclip: function ( sourceClip, name, startFrame, endFrame, fps ) {
26995 fps = fps || 30;
26996 const clip = sourceClip.clone();
26997 clip.name = name;
26998 const tracks = [];
26999 for ( let i = 0; i < clip.tracks.length; ++ i ) {
27000 const track = clip.tracks[ i ];
27001 const valueSize = track.getValueSize();
27002 const times = [];
27003 const values = [];
27004 for ( let j = 0; j < track.times.length; ++ j ) {
27005 const frame = track.times[ j ] * fps;
27006 if ( frame < startFrame || frame >= endFrame ) continue;
27007 times.push( track.times[ j ] );
27008 for ( let k = 0; k < valueSize; ++ k ) {
27009 values.push( track.values[ j * valueSize + k ] );
27010 }
27011 }
27012 if ( times.length === 0 ) continue;
27013 track.times = AnimationUtils.convertArray( times, track.times.constructor );
27014 track.values = AnimationUtils.convertArray( values, track.values.constructor );
27015 tracks.push( track );
27016 }
27017 clip.tracks = tracks;
27018 let minStartTime = Infinity;
27019 for ( let i = 0; i < clip.tracks.length; ++ i ) {
27020 if ( minStartTime > clip.tracks[ i ].times[ 0 ] ) {
27021 minStartTime = clip.tracks[ i ].times[ 0 ];
27022 }
27023 }
27024 for ( let i = 0; i < clip.tracks.length; ++ i ) {
27025 clip.tracks[ i ].shift( - 1 * minStartTime );
27026 }
27027 clip.resetDuration();
27028 return clip;
27029 },
27030 makeClipAdditive: function ( targetClip, referenceFrame, referenceClip, fps ) {
27031 if ( referenceFrame === undefined ) referenceFrame = 0;
27032 if ( referenceClip === undefined ) referenceClip = targetClip;
27033 if ( fps === undefined || fps <= 0 ) fps = 30;
27034 const numTracks = targetClip.tracks.length;
27035 const referenceTime = referenceFrame / fps;
27036 for ( let i = 0; i < numTracks; ++ i ) {
27037 const referenceTrack = referenceClip.tracks[ i ];
27038 const referenceTrackType = referenceTrack.ValueTypeName;
27039 if ( referenceTrackType === 'bool' || referenceTrackType === 'string' ) continue;
27040 const targetTrack = targetClip.tracks.find( function ( track ) {
27041 return track.name === referenceTrack.name
27042 && track.ValueTypeName === referenceTrackType;
27043 } );
27044 if ( targetTrack === undefined ) continue;
27045 let referenceOffset = 0;
27046 const referenceValueSize = referenceTrack.getValueSize();
27047 if ( referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) {
27048 referenceOffset = referenceValueSize / 3;
27049 }
27050 let targetOffset = 0;
27051 const targetValueSize = targetTrack.getValueSize();
27052 if ( targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) {
27053 targetOffset = targetValueSize / 3;
27054 }
27055 const lastIndex = referenceTrack.times.length - 1;
27056 let referenceValue;
27057 if ( referenceTime <= referenceTrack.times[ 0 ] ) {
27058 const startIndex = referenceOffset;
27059 const endIndex = referenceValueSize - referenceOffset;
27060 referenceValue = AnimationUtils.arraySlice( referenceTrack.values, startIndex, endIndex );
27061 } else if ( referenceTime >= referenceTrack.times[ lastIndex ] ) {
27062 const startIndex = lastIndex * referenceValueSize + referenceOffset;
27063 const endIndex = startIndex + referenceValueSize - referenceOffset;
27064 referenceValue = AnimationUtils.arraySlice( referenceTrack.values, startIndex, endIndex );
27065 } else {
27066 const interpolant = referenceTrack.createInterpolant();
27067 const startIndex = referenceOffset;
27068 const endIndex = referenceValueSize - referenceOffset;
27069 interpolant.evaluate( referenceTime );
27070 referenceValue = AnimationUtils.arraySlice( interpolant.resultBuffer, startIndex, endIndex );
27071 }
27072 if ( referenceTrackType === 'quaternion' ) {
27073 const referenceQuat = new Quaternion().fromArray( referenceValue ).normalize().conjugate();
27074 referenceQuat.toArray( referenceValue );
27075 }
27076 const numTimes = targetTrack.times.length;
27077 for ( let j = 0; j < numTimes; ++ j ) {
27078 const valueStart = j * targetValueSize + targetOffset;
27079 if ( referenceTrackType === 'quaternion' ) {
27080 Quaternion.multiplyQuaternionsFlat(
27081 targetTrack.values,
27082 valueStart,
27083 referenceValue,
27084 0,
27085 targetTrack.values,
27086 valueStart
27087 );
27088 } else {
27089 const valueEnd = targetValueSize - targetOffset * 2;
27090 for ( let k = 0; k < valueEnd; ++ k ) {
27091 targetTrack.values[ valueStart + k ] -= referenceValue[ k ];
27092 }
27093 }
27094 }
27095 }
27096 targetClip.blendMode = AdditiveAnimationBlendMode;
27097 return targetClip;
27098 }
27099 };
27100 function Interpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
27101 this.parameterPositions = parameterPositions;
27102 this._cachedIndex = 0;
27103 this.resultBuffer = resultBuffer !== undefined ?
27104 resultBuffer : new sampleValues.constructor( sampleSize );
27105 this.sampleValues = sampleValues;
27106 this.valueSize = sampleSize;
27107 }
27108 Object.assign( Interpolant.prototype, {
27109 evaluate: function ( t ) {
27110 const pp = this.parameterPositions;
27111 let i1 = this._cachedIndex,
27112 t1 = pp[ i1 ],
27113 t0 = pp[ i1 - 1 ];
27114 validate_interval: {
27115 seek: {
27116 let right;
27117 linear_scan: {
27118 forward_scan: if ( ! ( t < t1 ) ) {
27119 for ( let giveUpAt = i1 + 2; ; ) {
27120 if ( t1 === undefined ) {
27121 if ( t < t0 ) break forward_scan;
27122 i1 = pp.length;
27123 this._cachedIndex = i1;
27124 return this.afterEnd_( i1 - 1, t, t0 );
27125 }
27126 if ( i1 === giveUpAt ) break;
27127 t0 = t1;
27128 t1 = pp[ ++ i1 ];
27129 if ( t < t1 ) {
27130 break seek;
27131 }
27132 }
27133 right = pp.length;
27134 break linear_scan;
27135 }
27136 if ( ! ( t >= t0 ) ) {
27137 const t1global = pp[ 1 ];
27138 if ( t < t1global ) {
27139 i1 = 2;
27140 t0 = t1global;
27141 }
27142 for ( let giveUpAt = i1 - 2; ; ) {
27143 if ( t0 === undefined ) {
27144 this._cachedIndex = 0;
27145 return this.beforeStart_( 0, t, t1 );
27146 }
27147 if ( i1 === giveUpAt ) break;
27148 t1 = t0;
27149 t0 = pp[ -- i1 - 1 ];
27150 if ( t >= t0 ) {
27151 break seek;
27152 }
27153 }
27154 right = i1;
27155 i1 = 0;
27156 break linear_scan;
27157 }
27158 break validate_interval;
27159 }
27160 while ( i1 < right ) {
27161 const mid = ( i1 + right ) >>> 1;
27162 if ( t < pp[ mid ] ) {
27163 right = mid;
27164 } else {
27165 i1 = mid + 1;
27166 }
27167 }
27168 t1 = pp[ i1 ];
27169 t0 = pp[ i1 - 1 ];
27170 if ( t0 === undefined ) {
27171 this._cachedIndex = 0;
27172 return this.beforeStart_( 0, t, t1 );
27173 }
27174 if ( t1 === undefined ) {
27175 i1 = pp.length;
27176 this._cachedIndex = i1;
27177 return this.afterEnd_( i1 - 1, t0, t );
27178 }
27179 }
27180 this._cachedIndex = i1;
27181 this.intervalChanged_( i1, t0, t1 );
27182 }
27183 return this.interpolate_( i1, t0, t, t1 );
27184 },
27185 settings: null,
27186 DefaultSettings_: {},
27187 getSettings_: function () {
27188 return this.settings || this.DefaultSettings_;
27189 },
27190 copySampleValue_: function ( index ) {
27191 const result = this.resultBuffer,
27192 values = this.sampleValues,
27193 stride = this.valueSize,
27194 offset = index * stride;
27195 for ( let i = 0; i !== stride; ++ i ) {
27196 result[ i ] = values[ offset + i ];
27197 }
27198 return result;
27199 },
27200 interpolate_: function ( ) {
27201 throw new Error( 'call to abstract method' );
27202 },
27203 intervalChanged_: function ( ) {
27204 }
27205 } );
27206 Object.assign( Interpolant.prototype, {
27207 beforeStart_: Interpolant.prototype.copySampleValue_,
27208 afterEnd_: Interpolant.prototype.copySampleValue_,
27209 } );
27210 function CubicInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
27211 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
27212 this._weightPrev = - 0;
27213 this._offsetPrev = - 0;
27214 this._weightNext = - 0;
27215 this._offsetNext = - 0;
27216 }
27217 CubicInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
27218 constructor: CubicInterpolant,
27219 DefaultSettings_: {
27220 endingStart: ZeroCurvatureEnding,
27221 endingEnd: ZeroCurvatureEnding
27222 },
27223 intervalChanged_: function ( i1, t0, t1 ) {
27224 const pp = this.parameterPositions;
27225 let iPrev = i1 - 2,
27226 iNext = i1 + 1,
27227 tPrev = pp[ iPrev ],
27228 tNext = pp[ iNext ];
27229 if ( tPrev === undefined ) {
27230 switch ( this.getSettings_().endingStart ) {
27231 case ZeroSlopeEnding:
27232 iPrev = i1;
27233 tPrev = 2 * t0 - t1;
27234 break;
27235 case WrapAroundEnding:
27236 iPrev = pp.length - 2;
27237 tPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];
27238 break;
27239 default:
27240 iPrev = i1;
27241 tPrev = t1;
27242 }
27243 }
27244 if ( tNext === undefined ) {
27245 switch ( this.getSettings_().endingEnd ) {
27246 case ZeroSlopeEnding:
27247 iNext = i1;
27248 tNext = 2 * t1 - t0;
27249 break;
27250 case WrapAroundEnding:
27251 iNext = 1;
27252 tNext = t1 + pp[ 1 ] - pp[ 0 ];
27253 break;
27254 default:
27255 iNext = i1 - 1;
27256 tNext = t0;
27257 }
27258 }
27259 const halfDt = ( t1 - t0 ) * 0.5,
27260 stride = this.valueSize;
27261 this._weightPrev = halfDt / ( t0 - tPrev );
27262 this._weightNext = halfDt / ( tNext - t1 );
27263 this._offsetPrev = iPrev * stride;
27264 this._offsetNext = iNext * stride;
27265 },
27266 interpolate_: function ( i1, t0, t, t1 ) {
27267 const result = this.resultBuffer,
27268 values = this.sampleValues,
27269 stride = this.valueSize,
27270 o1 = i1 * stride, o0 = o1 - stride,
27271 oP = this._offsetPrev, oN = this._offsetNext,
27272 wP = this._weightPrev, wN = this._weightNext,
27273 p = ( t - t0 ) / ( t1 - t0 ),
27274 pp = p * p,
27275 ppp = pp * p;
27276 const sP = - wP * ppp + 2 * wP * pp - wP * p;
27277 const s0 = ( 1 + wP ) * ppp + ( - 1.5 - 2 * wP ) * pp + ( - 0.5 + wP ) * p + 1;
27278 const s1 = ( - 1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;
27279 const sN = wN * ppp - wN * pp;
27280 for ( let i = 0; i !== stride; ++ i ) {
27281 result[ i ] =
27282 sP * values[ oP + i ] +
27283 s0 * values[ o0 + i ] +
27284 s1 * values[ o1 + i ] +
27285 sN * values[ oN + i ];
27286 }
27287 return result;
27288 }
27289 } );
27290 function LinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
27291 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
27292 }
27293 LinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
27294 constructor: LinearInterpolant,
27295 interpolate_: function ( i1, t0, t, t1 ) {
27296 const result = this.resultBuffer,
27297 values = this.sampleValues,
27298 stride = this.valueSize,
27299 offset1 = i1 * stride,
27300 offset0 = offset1 - stride,
27301 weight1 = ( t - t0 ) / ( t1 - t0 ),
27302 weight0 = 1 - weight1;
27303 for ( let i = 0; i !== stride; ++ i ) {
27304 result[ i ] =
27305 values[ offset0 + i ] * weight0 +
27306 values[ offset1 + i ] * weight1;
27307 }
27308 return result;
27309 }
27310 } );
27311 function DiscreteInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
27312 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
27313 }
27314 DiscreteInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
27315 constructor: DiscreteInterpolant,
27316 interpolate_: function ( i1 ) {
27317 return this.copySampleValue_( i1 - 1 );
27318 }
27319 } );
27320 function KeyframeTrack( name, times, values, interpolation ) {
27321 if ( name === undefined ) throw new Error( 'THREE.KeyframeTrack: track name is undefined' );
27322 if ( times === undefined || times.length === 0 ) throw new Error( 'THREE.KeyframeTrack: no keyframes in track named ' + name );
27323 this.name = name;
27324 this.times = AnimationUtils.convertArray( times, this.TimeBufferType );
27325 this.values = AnimationUtils.convertArray( values, this.ValueBufferType );
27326 this.setInterpolation( interpolation || this.DefaultInterpolation );
27327 }
27328 Object.assign( KeyframeTrack, {
27329 toJSON: function ( track ) {
27330 const trackType = track.constructor;
27331 let json;
27332 if ( trackType.toJSON !== undefined ) {
27333 json = trackType.toJSON( track );
27334 } else {
27335 json = {
27336 'name': track.name,
27337 'times': AnimationUtils.convertArray( track.times, Array ),
27338 'values': AnimationUtils.convertArray( track.values, Array )
27339 };
27340 const interpolation = track.getInterpolation();
27341 if ( interpolation !== track.DefaultInterpolation ) {
27342 json.interpolation = interpolation;
27343 }
27344 }
27345 json.type = track.ValueTypeName;
27346 return json;
27347 }
27348 } );
27349 Object.assign( KeyframeTrack.prototype, {
27350 constructor: KeyframeTrack,
27351 TimeBufferType: Float32Array,
27352 ValueBufferType: Float32Array,
27353 DefaultInterpolation: InterpolateLinear,
27354 InterpolantFactoryMethodDiscrete: function ( result ) {
27355 return new DiscreteInterpolant( this.times, this.values, this.getValueSize(), result );
27356 },
27357 InterpolantFactoryMethodLinear: function ( result ) {
27358 return new LinearInterpolant( this.times, this.values, this.getValueSize(), result );
27359 },
27360 InterpolantFactoryMethodSmooth: function ( result ) {
27361 return new CubicInterpolant( this.times, this.values, this.getValueSize(), result );
27362 },
27363 setInterpolation: function ( interpolation ) {
27364 let factoryMethod;
27365 switch ( interpolation ) {
27366 case InterpolateDiscrete:
27367 factoryMethod = this.InterpolantFactoryMethodDiscrete;
27368 break;
27369 case InterpolateLinear:
27370 factoryMethod = this.InterpolantFactoryMethodLinear;
27371 break;
27372 case InterpolateSmooth:
27373 factoryMethod = this.InterpolantFactoryMethodSmooth;
27374 break;
27375 }
27376 if ( factoryMethod === undefined ) {
27377 const message = "unsupported interpolation for " +
27378 this.ValueTypeName + " keyframe track named " + this.name;
27379 if ( this.createInterpolant === undefined ) {
27380 if ( interpolation !== this.DefaultInterpolation ) {
27381 this.setInterpolation( this.DefaultInterpolation );
27382 } else {
27383 throw new Error( message );
27384 }
27385 }
27386 console.warn( 'THREE.KeyframeTrack:', message );
27387 return this;
27388 }
27389 this.createInterpolant = factoryMethod;
27390 return this;
27391 },
27392 getInterpolation: function () {
27393 switch ( this.createInterpolant ) {
27394 case this.InterpolantFactoryMethodDiscrete:
27395 return InterpolateDiscrete;
27396 case this.InterpolantFactoryMethodLinear:
27397 return InterpolateLinear;
27398 case this.InterpolantFactoryMethodSmooth:
27399 return InterpolateSmooth;
27400 }
27401 },
27402 getValueSize: function () {
27403 return this.values.length / this.times.length;
27404 },
27405 shift: function ( timeOffset ) {
27406 if ( timeOffset !== 0.0 ) {
27407 const times = this.times;
27408 for ( let i = 0, n = times.length; i !== n; ++ i ) {
27409 times[ i ] += timeOffset;
27410 }
27411 }
27412 return this;
27413 },
27414 scale: function ( timeScale ) {
27415 if ( timeScale !== 1.0 ) {
27416 const times = this.times;
27417 for ( let i = 0, n = times.length; i !== n; ++ i ) {
27418 times[ i ] *= timeScale;
27419 }
27420 }
27421 return this;
27422 },
27423 trim: function ( startTime, endTime ) {
27424 const times = this.times,
27425 nKeys = times.length;
27426 let from = 0,
27427 to = nKeys - 1;
27428 while ( from !== nKeys && times[ from ] < startTime ) {
27429 ++ from;
27430 }
27431 while ( to !== - 1 && times[ to ] > endTime ) {
27432 -- to;
27433 }
27434 ++ to;
27435 if ( from !== 0 || to !== nKeys ) {
27436 if ( from >= to ) {
27437 to = Math.max( to, 1 );
27438 from = to - 1;
27439 }
27440 const stride = this.getValueSize();
27441 this.times = AnimationUtils.arraySlice( times, from, to );
27442 this.values = AnimationUtils.arraySlice( this.values, from * stride, to * stride );
27443 }
27444 return this;
27445 },
27446 validate: function () {
27447 let valid = true;
27448 const valueSize = this.getValueSize();
27449 if ( valueSize - Math.floor( valueSize ) !== 0 ) {
27450 console.error( 'THREE.KeyframeTrack: Invalid value size in track.', this );
27451 valid = false;
27452 }
27453 const times = this.times,
27454 values = this.values,
27455 nKeys = times.length;
27456 if ( nKeys === 0 ) {
27457 console.error( 'THREE.KeyframeTrack: Track is empty.', this );
27458 valid = false;
27459 }
27460 let prevTime = null;
27461 for ( let i = 0; i !== nKeys; i ++ ) {
27462 const currTime = times[ i ];
27463 if ( typeof currTime === 'number' && isNaN( currTime ) ) {
27464 console.error( 'THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime );
27465 valid = false;
27466 break;
27467 }
27468 if ( prevTime !== null && prevTime > currTime ) {
27469 console.error( 'THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime );
27470 valid = false;
27471 break;
27472 }
27473 prevTime = currTime;
27474 }
27475 if ( values !== undefined ) {
27476 if ( AnimationUtils.isTypedArray( values ) ) {
27477 for ( let i = 0, n = values.length; i !== n; ++ i ) {
27478 const value = values[ i ];
27479 if ( isNaN( value ) ) {
27480 console.error( 'THREE.KeyframeTrack: Value is not a valid number.', this, i, value );
27481 valid = false;
27482 break;
27483 }
27484 }
27485 }
27486 }
27487 return valid;
27488 },
27489 optimize: function () {
27490 const times = AnimationUtils.arraySlice( this.times ),
27491 values = AnimationUtils.arraySlice( this.values ),
27492 stride = this.getValueSize(),
27493 smoothInterpolation = this.getInterpolation() === InterpolateSmooth,
27494 lastIndex = times.length - 1;
27495 let writeIndex = 1;
27496 for ( let i = 1; i < lastIndex; ++ i ) {
27497 let keep = false;
27498 const time = times[ i ];
27499 const timeNext = times[ i + 1 ];
27500 if ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {
27501 if ( ! smoothInterpolation ) {
27502 const offset = i * stride,
27503 offsetP = offset - stride,
27504 offsetN = offset + stride;
27505 for ( let j = 0; j !== stride; ++ j ) {
27506 const value = values[ offset + j ];
27507 if ( value !== values[ offsetP + j ] ||
27508 value !== values[ offsetN + j ] ) {
27509 keep = true;
27510 break;
27511 }
27512 }
27513 } else {
27514 keep = true;
27515 }
27516 }
27517 if ( keep ) {
27518 if ( i !== writeIndex ) {
27519 times[ writeIndex ] = times[ i ];
27520 const readOffset = i * stride,
27521 writeOffset = writeIndex * stride;
27522 for ( let j = 0; j !== stride; ++ j ) {
27523 values[ writeOffset + j ] = values[ readOffset + j ];
27524 }
27525 }
27526 ++ writeIndex;
27527 }
27528 }
27529 if ( lastIndex > 0 ) {
27530 times[ writeIndex ] = times[ lastIndex ];
27531 for ( let readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j ) {
27532 values[ writeOffset + j ] = values[ readOffset + j ];
27533 }
27534 ++ writeIndex;
27535 }
27536 if ( writeIndex !== times.length ) {
27537 this.times = AnimationUtils.arraySlice( times, 0, writeIndex );
27538 this.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );
27539 } else {
27540 this.times = times;
27541 this.values = values;
27542 }
27543 return this;
27544 },
27545 clone: function () {
27546 const times = AnimationUtils.arraySlice( this.times, 0 );
27547 const values = AnimationUtils.arraySlice( this.values, 0 );
27548 const TypedKeyframeTrack = this.constructor;
27549 const track = new TypedKeyframeTrack( this.name, times, values );
27550 track.createInterpolant = this.createInterpolant;
27551 return track;
27552 }
27553 } );
27554 function BooleanKeyframeTrack( name, times, values ) {
27555 KeyframeTrack.call( this, name, times, values );
27556 }
27557 BooleanKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
27558 constructor: BooleanKeyframeTrack,
27559 ValueTypeName: 'bool',
27560 ValueBufferType: Array,
27561 DefaultInterpolation: InterpolateDiscrete,
27562 InterpolantFactoryMethodLinear: undefined,
27563 InterpolantFactoryMethodSmooth: undefined
27564 } );
27565 function ColorKeyframeTrack( name, times, values, interpolation ) {
27566 KeyframeTrack.call( this, name, times, values, interpolation );
27567 }
27568 ColorKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
27569 constructor: ColorKeyframeTrack,
27570 ValueTypeName: 'color'
27571 } );
27572 function NumberKeyframeTrack( name, times, values, interpolation ) {
27573 KeyframeTrack.call( this, name, times, values, interpolation );
27574 }
27575 NumberKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
27576 constructor: NumberKeyframeTrack,
27577 ValueTypeName: 'number'
27578 } );
27579 function QuaternionLinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
27580 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
27581 }
27582 QuaternionLinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
27583 constructor: QuaternionLinearInterpolant,
27584 interpolate_: function ( i1, t0, t, t1 ) {
27585 const result = this.resultBuffer,
27586 values = this.sampleValues,
27587 stride = this.valueSize,
27588 alpha = ( t - t0 ) / ( t1 - t0 );
27589 let offset = i1 * stride;
27590 for ( let end = offset + stride; offset !== end; offset += 4 ) {
27591 Quaternion.slerpFlat( result, 0, values, offset - stride, values, offset, alpha );
27592 }
27593 return result;
27594 }
27595 } );
27596 function QuaternionKeyframeTrack( name, times, values, interpolation ) {
27597 KeyframeTrack.call( this, name, times, values, interpolation );
27598 }
27599 QuaternionKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
27600 constructor: QuaternionKeyframeTrack,
27601 ValueTypeName: 'quaternion',
27602 DefaultInterpolation: InterpolateLinear,
27603 InterpolantFactoryMethodLinear: function ( result ) {
27604 return new QuaternionLinearInterpolant( this.times, this.values, this.getValueSize(), result );
27605 },
27606 InterpolantFactoryMethodSmooth: undefined
27607 } );
27608 function StringKeyframeTrack( name, times, values, interpolation ) {
27609 KeyframeTrack.call( this, name, times, values, interpolation );
27610 }
27611 StringKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
27612 constructor: StringKeyframeTrack,
27613 ValueTypeName: 'string',
27614 ValueBufferType: Array,
27615 DefaultInterpolation: InterpolateDiscrete,
27616 InterpolantFactoryMethodLinear: undefined,
27617 InterpolantFactoryMethodSmooth: undefined
27618 } );
27619 function VectorKeyframeTrack( name, times, values, interpolation ) {
27620 KeyframeTrack.call( this, name, times, values, interpolation );
27621 }
27622 VectorKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
27623 constructor: VectorKeyframeTrack,
27624 ValueTypeName: 'vector'
27625 } );
27626 function AnimationClip( name, duration, tracks, blendMode ) {
27627 this.name = name;
27628 this.tracks = tracks;
27629 this.duration = ( duration !== undefined ) ? duration : - 1;
27630 this.blendMode = ( blendMode !== undefined ) ? blendMode : NormalAnimationBlendMode;
27631 this.uuid = MathUtils.generateUUID();
27632 if ( this.duration < 0 ) {
27633 this.resetDuration();
27634 }
27635 }
27636 function getTrackTypeForValueTypeName( typeName ) {
27637 switch ( typeName.toLowerCase() ) {
27638 case 'scalar':
27639 case 'double':
27640 case 'float':
27641 case 'number':
27642 case 'integer':
27643 return NumberKeyframeTrack;
27644 case 'vector':
27645 case 'vector2':
27646 case 'vector3':
27647 case 'vector4':
27648 return VectorKeyframeTrack;
27649 case 'color':
27650 return ColorKeyframeTrack;
27651 case 'quaternion':
27652 return QuaternionKeyframeTrack;
27653 case 'bool':
27654 case 'boolean':
27655 return BooleanKeyframeTrack;
27656 case 'string':
27657 return StringKeyframeTrack;
27658 }
27659 throw new Error( 'THREE.KeyframeTrack: Unsupported typeName: ' + typeName );
27660 }
27661 function parseKeyframeTrack( json ) {
27662 if ( json.type === undefined ) {
27663 throw new Error( 'THREE.KeyframeTrack: track type undefined, can not parse' );
27664 }
27665 const trackType = getTrackTypeForValueTypeName( json.type );
27666 if ( json.times === undefined ) {
27667 const times = [], values = [];
27668 AnimationUtils.flattenJSON( json.keys, times, values, 'value' );
27669 json.times = times;
27670 json.values = values;
27671 }
27672 if ( trackType.parse !== undefined ) {
27673 return trackType.parse( json );
27674 } else {
27675 return new trackType( json.name, json.times, json.values, json.interpolation );
27676 }
27677 }
27678 Object.assign( AnimationClip, {
27679 parse: function ( json ) {
27680 const tracks = [],
27681 jsonTracks = json.tracks,
27682 frameTime = 1.0 / ( json.fps || 1.0 );
27683 for ( let i = 0, n = jsonTracks.length; i !== n; ++ i ) {
27684 tracks.push( parseKeyframeTrack( jsonTracks[ i ] ).scale( frameTime ) );
27685 }
27686 return new AnimationClip( json.name, json.duration, tracks, json.blendMode );
27687 },
27688 toJSON: function ( clip ) {
27689 const tracks = [],
27690 clipTracks = clip.tracks;
27691 const json = {
27692 'name': clip.name,
27693 'duration': clip.duration,
27694 'tracks': tracks,
27695 'uuid': clip.uuid,
27696 'blendMode': clip.blendMode
27697 };
27698 for ( let i = 0, n = clipTracks.length; i !== n; ++ i ) {
27699 tracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );
27700 }
27701 return json;
27702 },
27703 CreateFromMorphTargetSequence: function ( name, morphTargetSequence, fps, noLoop ) {
27704 const numMorphTargets = morphTargetSequence.length;
27705 const tracks = [];
27706 for ( let i = 0; i < numMorphTargets; i ++ ) {
27707 let times = [];
27708 let values = [];
27709 times.push(
27710 ( i + numMorphTargets - 1 ) % numMorphTargets,
27711 i,
27712 ( i + 1 ) % numMorphTargets );
27713 values.push( 0, 1, 0 );
27714 const order = AnimationUtils.getKeyframeOrder( times );
27715 times = AnimationUtils.sortedArray( times, 1, order );
27716 values = AnimationUtils.sortedArray( values, 1, order );
27717 if ( ! noLoop && times[ 0 ] === 0 ) {
27718 times.push( numMorphTargets );
27719 values.push( values[ 0 ] );
27720 }
27721 tracks.push(
27722 new NumberKeyframeTrack(
27723 '.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',
27724 times, values
27725 ).scale( 1.0 / fps ) );
27726 }
27727 return new AnimationClip( name, - 1, tracks );
27728 },
27729 findByName: function ( objectOrClipArray, name ) {
27730 let clipArray = objectOrClipArray;
27731 if ( ! Array.isArray( objectOrClipArray ) ) {
27732 const o = objectOrClipArray;
27733 clipArray = o.geometry && o.geometry.animations || o.animations;
27734 }
27735 for ( let i = 0; i < clipArray.length; i ++ ) {
27736 if ( clipArray[ i ].name === name ) {
27737 return clipArray[ i ];
27738 }
27739 }
27740 return null;
27741 },
27742 CreateClipsFromMorphTargetSequences: function ( morphTargets, fps, noLoop ) {
27743 const animationToMorphTargets = {};
27744 const pattern = /^([\w-]*?)([\d]+)$/;
27745 for ( let i = 0, il = morphTargets.length; i < il; i ++ ) {
27746 const morphTarget = morphTargets[ i ];
27747 const parts = morphTarget.name.match( pattern );
27748 if ( parts && parts.length > 1 ) {
27749 const name = parts[ 1 ];
27750 let animationMorphTargets = animationToMorphTargets[ name ];
27751 if ( ! animationMorphTargets ) {
27752 animationToMorphTargets[ name ] = animationMorphTargets = [];
27753 }
27754 animationMorphTargets.push( morphTarget );
27755 }
27756 }
27757 const clips = [];
27758 for ( const name in animationToMorphTargets ) {
27759 clips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );
27760 }
27761 return clips;
27762 },
27763 parseAnimation: function ( animation, bones ) {
27764 if ( ! animation ) {
27765 console.error( 'THREE.AnimationClip: No animation in JSONLoader data.' );
27766 return null;
27767 }
27768 const addNonemptyTrack = function ( trackType, trackName, animationKeys, propertyName, destTracks ) {
27769 if ( animationKeys.length !== 0 ) {
27770 const times = [];
27771 const values = [];
27772 AnimationUtils.flattenJSON( animationKeys, times, values, propertyName );
27773 if ( times.length !== 0 ) {
27774 destTracks.push( new trackType( trackName, times, values ) );
27775 }
27776 }
27777 };
27778 const tracks = [];
27779 const clipName = animation.name || 'default';
27780 const fps = animation.fps || 30;
27781 const blendMode = animation.blendMode;
27782 let duration = animation.length || - 1;
27783 const hierarchyTracks = animation.hierarchy || [];
27784 for ( let h = 0; h < hierarchyTracks.length; h ++ ) {
27785 const animationKeys = hierarchyTracks[ h ].keys;
27786 if ( ! animationKeys || animationKeys.length === 0 ) continue;
27787 if ( animationKeys[ 0 ].morphTargets ) {
27788 const morphTargetNames = {};
27789 let k;
27790 for ( k = 0; k < animationKeys.length; k ++ ) {
27791 if ( animationKeys[ k ].morphTargets ) {
27792 for ( let m = 0; m < animationKeys[ k ].morphTargets.length; m ++ ) {
27793 morphTargetNames[ animationKeys[ k ].morphTargets[ m ] ] = - 1;
27794 }
27795 }
27796 }
27797 for ( const morphTargetName in morphTargetNames ) {
27798 const times = [];
27799 const values = [];
27800 for ( let m = 0; m !== animationKeys[ k ].morphTargets.length; ++ m ) {
27801 const animationKey = animationKeys[ k ];
27802 times.push( animationKey.time );
27803 values.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );
27804 }
27805 tracks.push( new NumberKeyframeTrack( '.morphTargetInfluence[' + morphTargetName + ']', times, values ) );
27806 }
27807 duration = morphTargetNames.length * ( fps || 1.0 );
27808 } else {
27809 const boneName = '.bones[' + bones[ h ].name + ']';
27810 addNonemptyTrack(
27811 VectorKeyframeTrack, boneName + '.position',
27812 animationKeys, 'pos', tracks );
27813 addNonemptyTrack(
27814 QuaternionKeyframeTrack, boneName + '.quaternion',
27815 animationKeys, 'rot', tracks );
27816 addNonemptyTrack(
27817 VectorKeyframeTrack, boneName + '.scale',
27818 animationKeys, 'scl', tracks );
27819 }
27820 }
27821 if ( tracks.length === 0 ) {
27822 return null;
27823 }
27824 const clip = new AnimationClip( clipName, duration, tracks, blendMode );
27825 return clip;
27826 }
27827 } );
27828 Object.assign( AnimationClip.prototype, {
27829 resetDuration: function () {
27830 const tracks = this.tracks;
27831 let duration = 0;
27832 for ( let i = 0, n = tracks.length; i !== n; ++ i ) {
27833 const track = this.tracks[ i ];
27834 duration = Math.max( duration, track.times[ track.times.length - 1 ] );
27835 }
27836 this.duration = duration;
27837 return this;
27838 },
27839 trim: function () {
27840 for ( let i = 0; i < this.tracks.length; i ++ ) {
27841 this.tracks[ i ].trim( 0, this.duration );
27842 }
27843 return this;
27844 },
27845 validate: function () {
27846 let valid = true;
27847 for ( let i = 0; i < this.tracks.length; i ++ ) {
27848 valid = valid && this.tracks[ i ].validate();
27849 }
27850 return valid;
27851 },
27852 optimize: function () {
27853 for ( let i = 0; i < this.tracks.length; i ++ ) {
27854 this.tracks[ i ].optimize();
27855 }
27856 return this;
27857 },
27858 clone: function () {
27859 const tracks = [];
27860 for ( let i = 0; i < this.tracks.length; i ++ ) {
27861 tracks.push( this.tracks[ i ].clone() );
27862 }
27863 return new AnimationClip( this.name, this.duration, tracks, this.blendMode );
27864 }
27865 } );
27866 const Cache = {
27867 enabled: false,
27868 files: {},
27869 add: function ( key, file ) {
27870 if ( this.enabled === false ) return;
27871 this.files[ key ] = file;
27872 },
27873 get: function ( key ) {
27874 if ( this.enabled === false ) return;
27875 return this.files[ key ];
27876 },
27877 remove: function ( key ) {
27878 delete this.files[ key ];
27879 },
27880 clear: function () {
27881 this.files = {};
27882 }
27883 };
27884 function LoadingManager( onLoad, onProgress, onError ) {
27885 const scope = this;
27886 let isLoading = false;
27887 let itemsLoaded = 0;
27888 let itemsTotal = 0;
27889 let urlModifier = undefined;
27890 const handlers = [];
27891 this.onStart = undefined;
27892 this.onLoad = onLoad;
27893 this.onProgress = onProgress;
27894 this.onError = onError;
27895 this.itemStart = function ( url ) {
27896 itemsTotal ++;
27897 if ( isLoading === false ) {
27898 if ( scope.onStart !== undefined ) {
27899 scope.onStart( url, itemsLoaded, itemsTotal );
27900 }
27901 }
27902 isLoading = true;
27903 };
27904 this.itemEnd = function ( url ) {
27905 itemsLoaded ++;
27906 if ( scope.onProgress !== undefined ) {
27907 scope.onProgress( url, itemsLoaded, itemsTotal );
27908 }
27909 if ( itemsLoaded === itemsTotal ) {
27910 isLoading = false;
27911 if ( scope.onLoad !== undefined ) {
27912 scope.onLoad();
27913 }
27914 }
27915 };
27916 this.itemError = function ( url ) {
27917 if ( scope.onError !== undefined ) {
27918 scope.onError( url );
27919 }
27920 };
27921 this.resolveURL = function ( url ) {
27922 if ( urlModifier ) {
27923 return urlModifier( url );
27924 }
27925 return url;
27926 };
27927 this.setURLModifier = function ( transform ) {
27928 urlModifier = transform;
27929 return this;
27930 };
27931 this.addHandler = function ( regex, loader ) {
27932 handlers.push( regex, loader );
27933 return this;
27934 };
27935 this.removeHandler = function ( regex ) {
27936 const index = handlers.indexOf( regex );
27937 if ( index !== - 1 ) {
27938 handlers.splice( index, 2 );
27939 }
27940 return this;
27941 };
27942 this.getHandler = function ( file ) {
27943 for ( let i = 0, l = handlers.length; i < l; i += 2 ) {
27944 const regex = handlers[ i ];
27945 const loader = handlers[ i + 1 ];
27946 if ( regex.global ) regex.lastIndex = 0;
27947 if ( regex.test( file ) ) {
27948 return loader;
27949 }
27950 }
27951 return null;
27952 };
27953 }
27954 const DefaultLoadingManager = new LoadingManager();
27955 function Loader( manager ) {
27956 this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
27957 this.crossOrigin = 'anonymous';
27958 this.path = '';
27959 this.resourcePath = '';
27960 this.requestHeader = {};
27961 }
27962 Object.assign( Loader.prototype, {
27963 load: function ( ) {},
27964 loadAsync: function ( url, onProgress ) {
27965 const scope = this;
27966 return new Promise( function ( resolve, reject ) {
27967 scope.load( url, resolve, onProgress, reject );
27968 } );
27969 },
27970 parse: function ( ) {},
27971 setCrossOrigin: function ( crossOrigin ) {
27972 this.crossOrigin = crossOrigin;
27973 return this;
27974 },
27975 setPath: function ( path ) {
27976 this.path = path;
27977 return this;
27978 },
27979 setResourcePath: function ( resourcePath ) {
27980 this.resourcePath = resourcePath;
27981 return this;
27982 },
27983 setRequestHeader: function ( requestHeader ) {
27984 this.requestHeader = requestHeader;
27985 return this;
27986 }
27987 } );
27988 const loading = {};
27989 function FileLoader( manager ) {
27990 Loader.call( this, manager );
27991 }
27992 FileLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
27993 constructor: FileLoader,
27994 load: function ( url, onLoad, onProgress, onError ) {
27995 if ( url === undefined ) url = '';
27996 if ( this.path !== undefined ) url = this.path + url;
27997 url = this.manager.resolveURL( url );
27998 const scope = this;
27999 const cached = Cache.get( url );
28000 if ( cached !== undefined ) {
28001 scope.manager.itemStart( url );
28002 setTimeout( function () {
28003 if ( onLoad ) onLoad( cached );
28004 scope.manager.itemEnd( url );
28005 }, 0 );
28006 return cached;
28007 }
28008 if ( loading[ url ] !== undefined ) {
28009 loading[ url ].push( {
28010 onLoad: onLoad,
28011 onProgress: onProgress,
28012 onError: onError
28013 } );
28014 return;
28015 }
28016 const dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
28017 const dataUriRegexResult = url.match( dataUriRegex );
28018 let request;
28019 if ( dataUriRegexResult ) {
28020 const mimeType = dataUriRegexResult[ 1 ];
28021 const isBase64 = !! dataUriRegexResult[ 2 ];
28022 let data = dataUriRegexResult[ 3 ];
28023 data = decodeURIComponent( data );
28024 if ( isBase64 ) data = atob( data );
28025 try {
28026 let response;
28027 const responseType = ( this.responseType || '' ).toLowerCase();
28028 switch ( responseType ) {
28029 case 'arraybuffer':
28030 case 'blob':
28031 const view = new Uint8Array( data.length );
28032 for ( let i = 0; i < data.length; i ++ ) {
28033 view[ i ] = data.charCodeAt( i );
28034 }
28035 if ( responseType === 'blob' ) {
28036 response = new Blob( [ view.buffer ], { type: mimeType } );
28037 } else {
28038 response = view.buffer;
28039 }
28040 break;
28041 case 'document':
28042 const parser = new DOMParser();
28043 response = parser.parseFromString( data, mimeType );
28044 break;
28045 case 'json':
28046 response = JSON.parse( data );
28047 break;
28048 default:
28049 response = data;
28050 break;
28051 }
28052 setTimeout( function () {
28053 if ( onLoad ) onLoad( response );
28054 scope.manager.itemEnd( url );
28055 }, 0 );
28056 } catch ( error ) {
28057 setTimeout( function () {
28058 if ( onError ) onError( error );
28059 scope.manager.itemError( url );
28060 scope.manager.itemEnd( url );
28061 }, 0 );
28062 }
28063 } else {
28064 loading[ url ] = [];
28065 loading[ url ].push( {
28066 onLoad: onLoad,
28067 onProgress: onProgress,
28068 onError: onError
28069 } );
28070 request = new XMLHttpRequest();
28071 request.open( 'GET', url, true );
28072 request.addEventListener( 'load', function ( event ) {
28073 const response = this.response;
28074 const callbacks = loading[ url ];
28075 delete loading[ url ];
28076 if ( this.status === 200 || this.status === 0 ) {
28077 if ( this.status === 0 ) console.warn( 'THREE.FileLoader: HTTP Status 0 received.' );
28078 Cache.add( url, response );
28079 for ( let i = 0, il = callbacks.length; i < il; i ++ ) {
28080 const callback = callbacks[ i ];
28081 if ( callback.onLoad ) callback.onLoad( response );
28082 }
28083 scope.manager.itemEnd( url );
28084 } else {
28085 for ( let i = 0, il = callbacks.length; i < il; i ++ ) {
28086 const callback = callbacks[ i ];
28087 if ( callback.onError ) callback.onError( event );
28088 }
28089 scope.manager.itemError( url );
28090 scope.manager.itemEnd( url );
28091 }
28092 }, false );
28093 request.addEventListener( 'progress', function ( event ) {
28094 const callbacks = loading[ url ];
28095 for ( let i = 0, il = callbacks.length; i < il; i ++ ) {
28096 const callback = callbacks[ i ];
28097 if ( callback.onProgress ) callback.onProgress( event );
28098 }
28099 }, false );
28100 request.addEventListener( 'error', function ( event ) {
28101 const callbacks = loading[ url ];
28102 delete loading[ url ];
28103 for ( let i = 0, il = callbacks.length; i < il; i ++ ) {
28104 const callback = callbacks[ i ];
28105 if ( callback.onError ) callback.onError( event );
28106 }
28107 scope.manager.itemError( url );
28108 scope.manager.itemEnd( url );
28109 }, false );
28110 request.addEventListener( 'abort', function ( event ) {
28111 const callbacks = loading[ url ];
28112 delete loading[ url ];
28113 for ( let i = 0, il = callbacks.length; i < il; i ++ ) {
28114 const callback = callbacks[ i ];
28115 if ( callback.onError ) callback.onError( event );
28116 }
28117 scope.manager.itemError( url );
28118 scope.manager.itemEnd( url );
28119 }, false );
28120 if ( this.responseType !== undefined ) request.responseType = this.responseType;
28121 if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;
28122 if ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );
28123 for ( const header in this.requestHeader ) {
28124 request.setRequestHeader( header, this.requestHeader[ header ] );
28125 }
28126 request.send( null );
28127 }
28128 scope.manager.itemStart( url );
28129 return request;
28130 },
28131 setResponseType: function ( value ) {
28132 this.responseType = value;
28133 return this;
28134 },
28135 setWithCredentials: function ( value ) {
28136 this.withCredentials = value;
28137 return this;
28138 },
28139 setMimeType: function ( value ) {
28140 this.mimeType = value;
28141 return this;
28142 }
28143 } );
28144 function AnimationLoader( manager ) {
28145 Loader.call( this, manager );
28146 }
28147 AnimationLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
28148 constructor: AnimationLoader,
28149 load: function ( url, onLoad, onProgress, onError ) {
28150 const scope = this;
28151 const loader = new FileLoader( scope.manager );
28152 loader.setPath( scope.path );
28153 loader.setRequestHeader( scope.requestHeader );
28154 loader.load( url, function ( text ) {
28155 try {
28156 onLoad( scope.parse( JSON.parse( text ) ) );
28157 } catch ( e ) {
28158 if ( onError ) {
28159 onError( e );
28160 } else {
28161 console.error( e );
28162 }
28163 scope.manager.itemError( url );
28164 }
28165 }, onProgress, onError );
28166 },
28167 parse: function ( json ) {
28168 const animations = [];
28169 for ( let i = 0; i < json.length; i ++ ) {
28170 const clip = AnimationClip.parse( json[ i ] );
28171 animations.push( clip );
28172 }
28173 return animations;
28174 }
28175 } );
28176 function CompressedTextureLoader( manager ) {
28177 Loader.call( this, manager );
28178 }
28179 CompressedTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
28180 constructor: CompressedTextureLoader,
28181 load: function ( url, onLoad, onProgress, onError ) {
28182 const scope = this;
28183 const images = [];
28184 const texture = new CompressedTexture();
28185 texture.image = images;
28186 const loader = new FileLoader( this.manager );
28187 loader.setPath( this.path );
28188 loader.setResponseType( 'arraybuffer' );
28189 loader.setRequestHeader( this.requestHeader );
28190 let loaded = 0;
28191 function loadTexture( i ) {
28192 loader.load( url[ i ], function ( buffer ) {
28193 const texDatas = scope.parse( buffer, true );
28194 images[ i ] = {
28195 width: texDatas.width,
28196 height: texDatas.height,
28197 format: texDatas.format,
28198 mipmaps: texDatas.mipmaps
28199 };
28200 loaded += 1;
28201 if ( loaded === 6 ) {
28202 if ( texDatas.mipmapCount === 1 )
28203 texture.minFilter = LinearFilter;
28204 texture.format = texDatas.format;
28205 texture.needsUpdate = true;
28206 if ( onLoad ) onLoad( texture );
28207 }
28208 }, onProgress, onError );
28209 }
28210 if ( Array.isArray( url ) ) {
28211 for ( let i = 0, il = url.length; i < il; ++ i ) {
28212 loadTexture( i );
28213 }
28214 } else {
28215 loader.load( url, function ( buffer ) {
28216 const texDatas = scope.parse( buffer, true );
28217 if ( texDatas.isCubemap ) {
28218 const faces = texDatas.mipmaps.length / texDatas.mipmapCount;
28219 for ( let f = 0; f < faces; f ++ ) {
28220 images[ f ] = { mipmaps: [] };
28221 for ( let i = 0; i < texDatas.mipmapCount; i ++ ) {
28222 images[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );
28223 images[ f ].format = texDatas.format;
28224 images[ f ].width = texDatas.width;
28225 images[ f ].height = texDatas.height;
28226 }
28227 }
28228 } else {
28229 texture.image.width = texDatas.width;
28230 texture.image.height = texDatas.height;
28231 texture.mipmaps = texDatas.mipmaps;
28232 }
28233 if ( texDatas.mipmapCount === 1 ) {
28234 texture.minFilter = LinearFilter;
28235 }
28236 texture.format = texDatas.format;
28237 texture.needsUpdate = true;
28238 if ( onLoad ) onLoad( texture );
28239 }, onProgress, onError );
28240 }
28241 return texture;
28242 }
28243 } );
28244 function ImageLoader( manager ) {
28245 Loader.call( this, manager );
28246 }
28247 ImageLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
28248 constructor: ImageLoader,
28249 load: function ( url, onLoad, onProgress, onError ) {
28250 if ( this.path !== undefined ) url = this.path + url;
28251 url = this.manager.resolveURL( url );
28252 const scope = this;
28253 const cached = Cache.get( url );
28254 if ( cached !== undefined ) {
28255 scope.manager.itemStart( url );
28256 setTimeout( function () {
28257 if ( onLoad ) onLoad( cached );
28258 scope.manager.itemEnd( url );
28259 }, 0 );
28260 return cached;
28261 }
28262 const image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );
28263 function onImageLoad() {
28264 image.removeEventListener( 'load', onImageLoad, false );
28265 image.removeEventListener( 'error', onImageError, false );
28266 Cache.add( url, this );
28267 if ( onLoad ) onLoad( this );
28268 scope.manager.itemEnd( url );
28269 }
28270 function onImageError( event ) {
28271 image.removeEventListener( 'load', onImageLoad, false );
28272 image.removeEventListener( 'error', onImageError, false );
28273 if ( onError ) onError( event );
28274 scope.manager.itemError( url );
28275 scope.manager.itemEnd( url );
28276 }
28277 image.addEventListener( 'load', onImageLoad, false );
28278 image.addEventListener( 'error', onImageError, false );
28279 if ( url.substr( 0, 5 ) !== 'data:' ) {
28280 if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;
28281 }
28282 scope.manager.itemStart( url );
28283 image.src = url;
28284 return image;
28285 }
28286 } );
28287 function CubeTextureLoader( manager ) {
28288 Loader.call( this, manager );
28289 }
28290 CubeTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
28291 constructor: CubeTextureLoader,
28292 load: function ( urls, onLoad, onProgress, onError ) {
28293 const texture = new CubeTexture();
28294 const loader = new ImageLoader( this.manager );
28295 loader.setCrossOrigin( this.crossOrigin );
28296 loader.setPath( this.path );
28297 let loaded = 0;
28298 function loadTexture( i ) {
28299 loader.load( urls[ i ], function ( image ) {
28300 texture.images[ i ] = image;
28301 loaded ++;
28302 if ( loaded === 6 ) {
28303 texture.needsUpdate = true;
28304 if ( onLoad ) onLoad( texture );
28305 }
28306 }, undefined, onError );
28307 }
28308 for ( let i = 0; i < urls.length; ++ i ) {
28309 loadTexture( i );
28310 }
28311 return texture;
28312 }
28313 } );
28314 function DataTextureLoader( manager ) {
28315 Loader.call( this, manager );
28316 }
28317 DataTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
28318 constructor: DataTextureLoader,
28319 load: function ( url, onLoad, onProgress, onError ) {
28320 const scope = this;
28321 const texture = new DataTexture();
28322 const loader = new FileLoader( this.manager );
28323 loader.setResponseType( 'arraybuffer' );
28324 loader.setRequestHeader( this.requestHeader );
28325 loader.setPath( this.path );
28326 loader.load( url, function ( buffer ) {
28327 const texData = scope.parse( buffer );
28328 if ( ! texData ) return;
28329 if ( texData.image !== undefined ) {
28330 texture.image = texData.image;
28331 } else if ( texData.data !== undefined ) {
28332 texture.image.width = texData.width;
28333 texture.image.height = texData.height;
28334 texture.image.data = texData.data;
28335 }
28336 texture.wrapS = texData.wrapS !== undefined ? texData.wrapS : ClampToEdgeWrapping;
28337 texture.wrapT = texData.wrapT !== undefined ? texData.wrapT : ClampToEdgeWrapping;
28338 texture.magFilter = texData.magFilter !== undefined ? texData.magFilter : LinearFilter;
28339 texture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearFilter;
28340 texture.anisotropy = texData.anisotropy !== undefined ? texData.anisotropy : 1;
28341 if ( texData.format !== undefined ) {
28342 texture.format = texData.format;
28343 }
28344 if ( texData.type !== undefined ) {
28345 texture.type = texData.type;
28346 }
28347 if ( texData.mipmaps !== undefined ) {
28348 texture.mipmaps = texData.mipmaps;
28349 texture.minFilter = LinearMipmapLinearFilter;
28350 }
28351 if ( texData.mipmapCount === 1 ) {
28352 texture.minFilter = LinearFilter;
28353 }
28354 texture.needsUpdate = true;
28355 if ( onLoad ) onLoad( texture, texData );
28356 }, onProgress, onError );
28357 return texture;
28358 }
28359 } );
28360 function TextureLoader( manager ) {
28361 Loader.call( this, manager );
28362 }
28363 TextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
28364 constructor: TextureLoader,
28365 load: function ( url, onLoad, onProgress, onError ) {
28366 const texture = new Texture();
28367 const loader = new ImageLoader( this.manager );
28368 loader.setCrossOrigin( this.crossOrigin );
28369 loader.setPath( this.path );
28370 loader.load( url, function ( image ) {
28371 texture.image = image;
28372 const isJPEG = url.search( /\.jpe?g($|\?)/i ) > 0 || url.search( /^data\:image\/jpeg/ ) === 0;
28373 texture.format = isJPEG ? RGBFormat : RGBAFormat;
28374 texture.needsUpdate = true;
28375 if ( onLoad !== undefined ) {
28376 onLoad( texture );
28377 }
28378 }, onProgress, onError );
28379 return texture;
28380 }
28381 } );
28382 function Curve() {
28383 this.type = 'Curve';
28384 this.arcLengthDivisions = 200;
28385 }
28386 Object.assign( Curve.prototype, {
28387 getPoint: function ( ) {
28388 console.warn( 'THREE.Curve: .getPoint() not implemented.' );
28389 return null;
28390 },
28391 getPointAt: function ( u, optionalTarget ) {
28392 const t = this.getUtoTmapping( u );
28393 return this.getPoint( t, optionalTarget );
28394 },
28395 getPoints: function ( divisions ) {
28396 if ( divisions === undefined ) divisions = 5;
28397 const points = [];
28398 for ( let d = 0; d <= divisions; d ++ ) {
28399 points.push( this.getPoint( d / divisions ) );
28400 }
28401 return points;
28402 },
28403 getSpacedPoints: function ( divisions ) {
28404 if ( divisions === undefined ) divisions = 5;
28405 const points = [];
28406 for ( let d = 0; d <= divisions; d ++ ) {
28407 points.push( this.getPointAt( d / divisions ) );
28408 }
28409 return points;
28410 },
28411 getLength: function () {
28412 const lengths = this.getLengths();
28413 return lengths[ lengths.length - 1 ];
28414 },
28415 getLengths: function ( divisions ) {
28416 if ( divisions === undefined ) divisions = this.arcLengthDivisions;
28417 if ( this.cacheArcLengths &&
28418 ( this.cacheArcLengths.length === divisions + 1 ) &&
28419 ! this.needsUpdate ) {
28420 return this.cacheArcLengths;
28421 }
28422 this.needsUpdate = false;
28423 const cache = [];
28424 let current, last = this.getPoint( 0 );
28425 let sum = 0;
28426 cache.push( 0 );
28427 for ( let p = 1; p <= divisions; p ++ ) {
28428 current = this.getPoint( p / divisions );
28429 sum += current.distanceTo( last );
28430 cache.push( sum );
28431 last = current;
28432 }
28433 this.cacheArcLengths = cache;
28434 return cache;
28435 },
28436 updateArcLengths: function () {
28437 this.needsUpdate = true;
28438 this.getLengths();
28439 },
28440 getUtoTmapping: function ( u, distance ) {
28441 const arcLengths = this.getLengths();
28442 let i = 0;
28443 const il = arcLengths.length;
28444 let targetArcLength;
28445 if ( distance ) {
28446 targetArcLength = distance;
28447 } else {
28448 targetArcLength = u * arcLengths[ il - 1 ];
28449 }
28450 let low = 0, high = il - 1, comparison;
28451 while ( low <= high ) {
28452 i = Math.floor( low + ( high - low ) / 2 );
28453 comparison = arcLengths[ i ] - targetArcLength;
28454 if ( comparison < 0 ) {
28455 low = i + 1;
28456 } else if ( comparison > 0 ) {
28457 high = i - 1;
28458 } else {
28459 high = i;
28460 break;
28461 }
28462 }
28463 i = high;
28464 if ( arcLengths[ i ] === targetArcLength ) {
28465 return i / ( il - 1 );
28466 }
28467 const lengthBefore = arcLengths[ i ];
28468 const lengthAfter = arcLengths[ i + 1 ];
28469 const segmentLength = lengthAfter - lengthBefore;
28470 const segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;
28471 const t = ( i + segmentFraction ) / ( il - 1 );
28472 return t;
28473 },
28474 getTangent: function ( t, optionalTarget ) {
28475 const delta = 0.0001;
28476 let t1 = t - delta;
28477 let t2 = t + delta;
28478 if ( t1 < 0 ) t1 = 0;
28479 if ( t2 > 1 ) t2 = 1;
28480 const pt1 = this.getPoint( t1 );
28481 const pt2 = this.getPoint( t2 );
28482 const tangent = optionalTarget || ( ( pt1.isVector2 ) ? new Vector2() : new Vector3() );
28483 tangent.copy( pt2 ).sub( pt1 ).normalize();
28484 return tangent;
28485 },
28486 getTangentAt: function ( u, optionalTarget ) {
28487 const t = this.getUtoTmapping( u );
28488 return this.getTangent( t, optionalTarget );
28489 },
28490 computeFrenetFrames: function ( segments, closed ) {
28491 const normal = new Vector3();
28492 const tangents = [];
28493 const normals = [];
28494 const binormals = [];
28495 const vec = new Vector3();
28496 const mat = new Matrix4();
28497 for ( let i = 0; i <= segments; i ++ ) {
28498 const u = i / segments;
28499 tangents[ i ] = this.getTangentAt( u, new Vector3() );
28500 tangents[ i ].normalize();
28501 }
28502 normals[ 0 ] = new Vector3();
28503 binormals[ 0 ] = new Vector3();
28504 let min = Number.MAX_VALUE;
28505 const tx = Math.abs( tangents[ 0 ].x );
28506 const ty = Math.abs( tangents[ 0 ].y );
28507 const tz = Math.abs( tangents[ 0 ].z );
28508 if ( tx <= min ) {
28509 min = tx;
28510 normal.set( 1, 0, 0 );
28511 }
28512 if ( ty <= min ) {
28513 min = ty;
28514 normal.set( 0, 1, 0 );
28515 }
28516 if ( tz <= min ) {
28517 normal.set( 0, 0, 1 );
28518 }
28519 vec.crossVectors( tangents[ 0 ], normal ).normalize();
28520 normals[ 0 ].crossVectors( tangents[ 0 ], vec );
28521 binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );
28522 for ( let i = 1; i <= segments; i ++ ) {
28523 normals[ i ] = normals[ i - 1 ].clone();
28524 binormals[ i ] = binormals[ i - 1 ].clone();
28525 vec.crossVectors( tangents[ i - 1 ], tangents[ i ] );
28526 if ( vec.length() > Number.EPSILON ) {
28527 vec.normalize();
28528 const theta = Math.acos( MathUtils.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) );
28529 normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );
28530 }
28531 binormals[ i ].crossVectors( tangents[ i ], normals[ i ] );
28532 }
28533 if ( closed === true ) {
28534 let theta = Math.acos( MathUtils.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );
28535 theta /= segments;
28536 if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {
28537 theta = - theta;
28538 }
28539 for ( let i = 1; i <= segments; i ++ ) {
28540 normals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );
28541 binormals[ i ].crossVectors( tangents[ i ], normals[ i ] );
28542 }
28543 }
28544 return {
28545 tangents: tangents,
28546 normals: normals,
28547 binormals: binormals
28548 };
28549 },
28550 clone: function () {
28551 return new this.constructor().copy( this );
28552 },
28553 copy: function ( source ) {
28554 this.arcLengthDivisions = source.arcLengthDivisions;
28555 return this;
28556 },
28557 toJSON: function () {
28558 const data = {
28559 metadata: {
28560 version: 4.5,
28561 type: 'Curve',
28562 generator: 'Curve.toJSON'
28563 }
28564 };
28565 data.arcLengthDivisions = this.arcLengthDivisions;
28566 data.type = this.type;
28567 return data;
28568 },
28569 fromJSON: function ( json ) {
28570 this.arcLengthDivisions = json.arcLengthDivisions;
28571 return this;
28572 }
28573 } );
28574 function EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
28575 Curve.call( this );
28576 this.type = 'EllipseCurve';
28577 this.aX = aX || 0;
28578 this.aY = aY || 0;
28579 this.xRadius = xRadius || 1;
28580 this.yRadius = yRadius || 1;
28581 this.aStartAngle = aStartAngle || 0;
28582 this.aEndAngle = aEndAngle || 2 * Math.PI;
28583 this.aClockwise = aClockwise || false;
28584 this.aRotation = aRotation || 0;
28585 }
28586 EllipseCurve.prototype = Object.create( Curve.prototype );
28587 EllipseCurve.prototype.constructor = EllipseCurve;
28588 EllipseCurve.prototype.isEllipseCurve = true;
28589 EllipseCurve.prototype.getPoint = function ( t, optionalTarget ) {
28590 const point = optionalTarget || new Vector2();
28591 const twoPi = Math.PI * 2;
28592 let deltaAngle = this.aEndAngle - this.aStartAngle;
28593 const samePoints = Math.abs( deltaAngle ) < Number.EPSILON;
28594 while ( deltaAngle < 0 ) deltaAngle += twoPi;
28595 while ( deltaAngle > twoPi ) deltaAngle -= twoPi;
28596 if ( deltaAngle < Number.EPSILON ) {
28597 if ( samePoints ) {
28598 deltaAngle = 0;
28599 } else {
28600 deltaAngle = twoPi;
28601 }
28602 }
28603 if ( this.aClockwise === true && ! samePoints ) {
28604 if ( deltaAngle === twoPi ) {
28605 deltaAngle = - twoPi;
28606 } else {
28607 deltaAngle = deltaAngle - twoPi;
28608 }
28609 }
28610 const angle = this.aStartAngle + t * deltaAngle;
28611 let x = this.aX + this.xRadius * Math.cos( angle );
28612 let y = this.aY + this.yRadius * Math.sin( angle );
28613 if ( this.aRotation !== 0 ) {
28614 const cos = Math.cos( this.aRotation );
28615 const sin = Math.sin( this.aRotation );
28616 const tx = x - this.aX;
28617 const ty = y - this.aY;
28618 x = tx * cos - ty * sin + this.aX;
28619 y = tx * sin + ty * cos + this.aY;
28620 }
28621 return point.set( x, y );
28622 };
28623 EllipseCurve.prototype.copy = function ( source ) {
28624 Curve.prototype.copy.call( this, source );
28625 this.aX = source.aX;
28626 this.aY = source.aY;
28627 this.xRadius = source.xRadius;
28628 this.yRadius = source.yRadius;
28629 this.aStartAngle = source.aStartAngle;
28630 this.aEndAngle = source.aEndAngle;
28631 this.aClockwise = source.aClockwise;
28632 this.aRotation = source.aRotation;
28633 return this;
28634 };
28635 EllipseCurve.prototype.toJSON = function () {
28636 const data = Curve.prototype.toJSON.call( this );
28637 data.aX = this.aX;
28638 data.aY = this.aY;
28639 data.xRadius = this.xRadius;
28640 data.yRadius = this.yRadius;
28641 data.aStartAngle = this.aStartAngle;
28642 data.aEndAngle = this.aEndAngle;
28643 data.aClockwise = this.aClockwise;
28644 data.aRotation = this.aRotation;
28645 return data;
28646 };
28647 EllipseCurve.prototype.fromJSON = function ( json ) {
28648 Curve.prototype.fromJSON.call( this, json );
28649 this.aX = json.aX;
28650 this.aY = json.aY;
28651 this.xRadius = json.xRadius;
28652 this.yRadius = json.yRadius;
28653 this.aStartAngle = json.aStartAngle;
28654 this.aEndAngle = json.aEndAngle;
28655 this.aClockwise = json.aClockwise;
28656 this.aRotation = json.aRotation;
28657 return this;
28658 };
28659 function ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
28660 EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
28661 this.type = 'ArcCurve';
28662 }
28663 ArcCurve.prototype = Object.create( EllipseCurve.prototype );
28664 ArcCurve.prototype.constructor = ArcCurve;
28665 ArcCurve.prototype.isArcCurve = true;
28666 function CubicPoly() {
28667 let c0 = 0, c1 = 0, c2 = 0, c3 = 0;
28668 function init( x0, x1, t0, t1 ) {
28669 c0 = x0;
28670 c1 = t0;
28671 c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;
28672 c3 = 2 * x0 - 2 * x1 + t0 + t1;
28673 }
28674 return {
28675 initCatmullRom: function ( x0, x1, x2, x3, tension ) {
28676 init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );
28677 },
28678 initNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {
28679 let t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;
28680 let t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;
28681 t1 *= dt1;
28682 t2 *= dt1;
28683 init( x1, x2, t1, t2 );
28684 },
28685 calc: function ( t ) {
28686 const t2 = t * t;
28687 const t3 = t2 * t;
28688 return c0 + c1 * t + c2 * t2 + c3 * t3;
28689 }
28690 };
28691 }
28692 const tmp = new Vector3();
28693 const px = new CubicPoly(), py = new CubicPoly(), pz = new CubicPoly();
28694 function CatmullRomCurve3( points, closed, curveType, tension ) {
28695 Curve.call( this );
28696 this.type = 'CatmullRomCurve3';
28697 this.points = points || [];
28698 this.closed = closed || false;
28699 this.curveType = curveType || 'centripetal';
28700 this.tension = ( tension !== undefined ) ? tension : 0.5;
28701 }
28702 CatmullRomCurve3.prototype = Object.create( Curve.prototype );
28703 CatmullRomCurve3.prototype.constructor = CatmullRomCurve3;
28704 CatmullRomCurve3.prototype.isCatmullRomCurve3 = true;
28705 CatmullRomCurve3.prototype.getPoint = function ( t, optionalTarget ) {
28706 const point = optionalTarget || new Vector3();
28707 const points = this.points;
28708 const l = points.length;
28709 const p = ( l - ( this.closed ? 0 : 1 ) ) * t;
28710 let intPoint = Math.floor( p );
28711 let weight = p - intPoint;
28712 if ( this.closed ) {
28713 intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / l ) + 1 ) * l;
28714 } else if ( weight === 0 && intPoint === l - 1 ) {
28715 intPoint = l - 2;
28716 weight = 1;
28717 }
28718 let p0, p3;
28719 if ( this.closed || intPoint > 0 ) {
28720 p0 = points[ ( intPoint - 1 ) % l ];
28721 } else {
28722 tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );
28723 p0 = tmp;
28724 }
28725 const p1 = points[ intPoint % l ];
28726 const p2 = points[ ( intPoint + 1 ) % l ];
28727 if ( this.closed || intPoint + 2 < l ) {
28728 p3 = points[ ( intPoint + 2 ) % l ];
28729 } else {
28730 tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );
28731 p3 = tmp;
28732 }
28733 if ( this.curveType === 'centripetal' || this.curveType === 'chordal' ) {
28734 const pow = this.curveType === 'chordal' ? 0.5 : 0.25;
28735 let dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );
28736 let dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );
28737 let dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );
28738 if ( dt1 < 1e-4 ) dt1 = 1.0;
28739 if ( dt0 < 1e-4 ) dt0 = dt1;
28740 if ( dt2 < 1e-4 ) dt2 = dt1;
28741 px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );
28742 py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );
28743 pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );
28744 } else if ( this.curveType === 'catmullrom' ) {
28745 px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, this.tension );
28746 py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, this.tension );
28747 pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, this.tension );
28748 }
28749 point.set(
28750 px.calc( weight ),
28751 py.calc( weight ),
28752 pz.calc( weight )
28753 );
28754 return point;
28755 };
28756 CatmullRomCurve3.prototype.copy = function ( source ) {
28757 Curve.prototype.copy.call( this, source );
28758 this.points = [];
28759 for ( let i = 0, l = source.points.length; i < l; i ++ ) {
28760 const point = source.points[ i ];
28761 this.points.push( point.clone() );
28762 }
28763 this.closed = source.closed;
28764 this.curveType = source.curveType;
28765 this.tension = source.tension;
28766 return this;
28767 };
28768 CatmullRomCurve3.prototype.toJSON = function () {
28769 const data = Curve.prototype.toJSON.call( this );
28770 data.points = [];
28771 for ( let i = 0, l = this.points.length; i < l; i ++ ) {
28772 const point = this.points[ i ];
28773 data.points.push( point.toArray() );
28774 }
28775 data.closed = this.closed;
28776 data.curveType = this.curveType;
28777 data.tension = this.tension;
28778 return data;
28779 };
28780 CatmullRomCurve3.prototype.fromJSON = function ( json ) {
28781 Curve.prototype.fromJSON.call( this, json );
28782 this.points = [];
28783 for ( let i = 0, l = json.points.length; i < l; i ++ ) {
28784 const point = json.points[ i ];
28785 this.points.push( new Vector3().fromArray( point ) );
28786 }
28787 this.closed = json.closed;
28788 this.curveType = json.curveType;
28789 this.tension = json.tension;
28790 return this;
28791 };
28792 function CatmullRom( t, p0, p1, p2, p3 ) {
28793 const v0 = ( p2 - p0 ) * 0.5;
28794 const v1 = ( p3 - p1 ) * 0.5;
28795 const t2 = t * t;
28796 const t3 = t * t2;
28797 return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
28798 }
28799 function QuadraticBezierP0( t, p ) {
28800 const k = 1 - t;
28801 return k * k * p;
28802 }
28803 function QuadraticBezierP1( t, p ) {
28804 return 2 * ( 1 - t ) * t * p;
28805 }
28806 function QuadraticBezierP2( t, p ) {
28807 return t * t * p;
28808 }
28809 function QuadraticBezier( t, p0, p1, p2 ) {
28810 return QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +
28811 QuadraticBezierP2( t, p2 );
28812 }
28813 function CubicBezierP0( t, p ) {
28814 const k = 1 - t;
28815 return k * k * k * p;
28816 }
28817 function CubicBezierP1( t, p ) {
28818 const k = 1 - t;
28819 return 3 * k * k * t * p;
28820 }
28821 function CubicBezierP2( t, p ) {
28822 return 3 * ( 1 - t ) * t * t * p;
28823 }
28824 function CubicBezierP3( t, p ) {
28825 return t * t * t * p;
28826 }
28827 function CubicBezier( t, p0, p1, p2, p3 ) {
28828 return CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +
28829 CubicBezierP3( t, p3 );
28830 }
28831 function CubicBezierCurve( v0, v1, v2, v3 ) {
28832 Curve.call( this );
28833 this.type = 'CubicBezierCurve';
28834 this.v0 = v0 || new Vector2();
28835 this.v1 = v1 || new Vector2();
28836 this.v2 = v2 || new Vector2();
28837 this.v3 = v3 || new Vector2();
28838 }
28839 CubicBezierCurve.prototype = Object.create( Curve.prototype );
28840 CubicBezierCurve.prototype.constructor = CubicBezierCurve;
28841 CubicBezierCurve.prototype.isCubicBezierCurve = true;
28842 CubicBezierCurve.prototype.getPoint = function ( t, optionalTarget ) {
28843 const point = optionalTarget || new Vector2();
28844 const v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;
28845 point.set(
28846 CubicBezier( t, v0.x, v1.x, v2.x, v3.x ),
28847 CubicBezier( t, v0.y, v1.y, v2.y, v3.y )
28848 );
28849 return point;
28850 };
28851 CubicBezierCurve.prototype.copy = function ( source ) {
28852 Curve.prototype.copy.call( this, source );
28853 this.v0.copy( source.v0 );
28854 this.v1.copy( source.v1 );
28855 this.v2.copy( source.v2 );
28856 this.v3.copy( source.v3 );
28857 return this;
28858 };
28859 CubicBezierCurve.prototype.toJSON = function () {
28860 const data = Curve.prototype.toJSON.call( this );
28861 data.v0 = this.v0.toArray();
28862 data.v1 = this.v1.toArray();
28863 data.v2 = this.v2.toArray();
28864 data.v3 = this.v3.toArray();
28865 return data;
28866 };
28867 CubicBezierCurve.prototype.fromJSON = function ( json ) {
28868 Curve.prototype.fromJSON.call( this, json );
28869 this.v0.fromArray( json.v0 );
28870 this.v1.fromArray( json.v1 );
28871 this.v2.fromArray( json.v2 );
28872 this.v3.fromArray( json.v3 );
28873 return this;
28874 };
28875 function CubicBezierCurve3( v0, v1, v2, v3 ) {
28876 Curve.call( this );
28877 this.type = 'CubicBezierCurve3';
28878 this.v0 = v0 || new Vector3();
28879 this.v1 = v1 || new Vector3();
28880 this.v2 = v2 || new Vector3();
28881 this.v3 = v3 || new Vector3();
28882 }
28883 CubicBezierCurve3.prototype = Object.create( Curve.prototype );
28884 CubicBezierCurve3.prototype.constructor = CubicBezierCurve3;
28885 CubicBezierCurve3.prototype.isCubicBezierCurve3 = true;
28886 CubicBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) {
28887 const point = optionalTarget || new Vector3();
28888 const v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;
28889 point.set(
28890 CubicBezier( t, v0.x, v1.x, v2.x, v3.x ),
28891 CubicBezier( t, v0.y, v1.y, v2.y, v3.y ),
28892 CubicBezier( t, v0.z, v1.z, v2.z, v3.z )
28893 );
28894 return point;
28895 };
28896 CubicBezierCurve3.prototype.copy = function ( source ) {
28897 Curve.prototype.copy.call( this, source );
28898 this.v0.copy( source.v0 );
28899 this.v1.copy( source.v1 );
28900 this.v2.copy( source.v2 );
28901 this.v3.copy( source.v3 );
28902 return this;
28903 };
28904 CubicBezierCurve3.prototype.toJSON = function () {
28905 const data = Curve.prototype.toJSON.call( this );
28906 data.v0 = this.v0.toArray();
28907 data.v1 = this.v1.toArray();
28908 data.v2 = this.v2.toArray();
28909 data.v3 = this.v3.toArray();
28910 return data;
28911 };
28912 CubicBezierCurve3.prototype.fromJSON = function ( json ) {
28913 Curve.prototype.fromJSON.call( this, json );
28914 this.v0.fromArray( json.v0 );
28915 this.v1.fromArray( json.v1 );
28916 this.v2.fromArray( json.v2 );
28917 this.v3.fromArray( json.v3 );
28918 return this;
28919 };
28920 function LineCurve( v1, v2 ) {
28921 Curve.call( this );
28922 this.type = 'LineCurve';
28923 this.v1 = v1 || new Vector2();
28924 this.v2 = v2 || new Vector2();
28925 }
28926 LineCurve.prototype = Object.create( Curve.prototype );
28927 LineCurve.prototype.constructor = LineCurve;
28928 LineCurve.prototype.isLineCurve = true;
28929 LineCurve.prototype.getPoint = function ( t, optionalTarget ) {
28930 const point = optionalTarget || new Vector2();
28931 if ( t === 1 ) {
28932 point.copy( this.v2 );
28933 } else {
28934 point.copy( this.v2 ).sub( this.v1 );
28935 point.multiplyScalar( t ).add( this.v1 );
28936 }
28937 return point;
28938 };
28939 LineCurve.prototype.getPointAt = function ( u, optionalTarget ) {
28940 return this.getPoint( u, optionalTarget );
28941 };
28942 LineCurve.prototype.getTangent = function ( t, optionalTarget ) {
28943 const tangent = optionalTarget || new Vector2();
28944 tangent.copy( this.v2 ).sub( this.v1 ).normalize();
28945 return tangent;
28946 };
28947 LineCurve.prototype.copy = function ( source ) {
28948 Curve.prototype.copy.call( this, source );
28949 this.v1.copy( source.v1 );
28950 this.v2.copy( source.v2 );
28951 return this;
28952 };
28953 LineCurve.prototype.toJSON = function () {
28954 const data = Curve.prototype.toJSON.call( this );
28955 data.v1 = this.v1.toArray();
28956 data.v2 = this.v2.toArray();
28957 return data;
28958 };
28959 LineCurve.prototype.fromJSON = function ( json ) {
28960 Curve.prototype.fromJSON.call( this, json );
28961 this.v1.fromArray( json.v1 );
28962 this.v2.fromArray( json.v2 );
28963 return this;
28964 };
28965 function LineCurve3( v1, v2 ) {
28966 Curve.call( this );
28967 this.type = 'LineCurve3';
28968 this.v1 = v1 || new Vector3();
28969 this.v2 = v2 || new Vector3();
28970 }
28971 LineCurve3.prototype = Object.create( Curve.prototype );
28972 LineCurve3.prototype.constructor = LineCurve3;
28973 LineCurve3.prototype.isLineCurve3 = true;
28974 LineCurve3.prototype.getPoint = function ( t, optionalTarget ) {
28975 const point = optionalTarget || new Vector3();
28976 if ( t === 1 ) {
28977 point.copy( this.v2 );
28978 } else {
28979 point.copy( this.v2 ).sub( this.v1 );
28980 point.multiplyScalar( t ).add( this.v1 );
28981 }
28982 return point;
28983 };
28984 LineCurve3.prototype.getPointAt = function ( u, optionalTarget ) {
28985 return this.getPoint( u, optionalTarget );
28986 };
28987 LineCurve3.prototype.copy = function ( source ) {
28988 Curve.prototype.copy.call( this, source );
28989 this.v1.copy( source.v1 );
28990 this.v2.copy( source.v2 );
28991 return this;
28992 };
28993 LineCurve3.prototype.toJSON = function () {
28994 const data = Curve.prototype.toJSON.call( this );
28995 data.v1 = this.v1.toArray();
28996 data.v2 = this.v2.toArray();
28997 return data;
28998 };
28999 LineCurve3.prototype.fromJSON = function ( json ) {
29000 Curve.prototype.fromJSON.call( this, json );
29001 this.v1.fromArray( json.v1 );
29002 this.v2.fromArray( json.v2 );
29003 return this;
29004 };
29005 function QuadraticBezierCurve( v0, v1, v2 ) {
29006 Curve.call( this );
29007 this.type = 'QuadraticBezierCurve';
29008 this.v0 = v0 || new Vector2();
29009 this.v1 = v1 || new Vector2();
29010 this.v2 = v2 || new Vector2();
29011 }
29012 QuadraticBezierCurve.prototype = Object.create( Curve.prototype );
29013 QuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;
29014 QuadraticBezierCurve.prototype.isQuadraticBezierCurve = true;
29015 QuadraticBezierCurve.prototype.getPoint = function ( t, optionalTarget ) {
29016 const point = optionalTarget || new Vector2();
29017 const v0 = this.v0, v1 = this.v1, v2 = this.v2;
29018 point.set(
29019 QuadraticBezier( t, v0.x, v1.x, v2.x ),
29020 QuadraticBezier( t, v0.y, v1.y, v2.y )
29021 );
29022 return point;
29023 };
29024 QuadraticBezierCurve.prototype.copy = function ( source ) {
29025 Curve.prototype.copy.call( this, source );
29026 this.v0.copy( source.v0 );
29027 this.v1.copy( source.v1 );
29028 this.v2.copy( source.v2 );
29029 return this;
29030 };
29031 QuadraticBezierCurve.prototype.toJSON = function () {
29032 const data = Curve.prototype.toJSON.call( this );
29033 data.v0 = this.v0.toArray();
29034 data.v1 = this.v1.toArray();
29035 data.v2 = this.v2.toArray();
29036 return data;
29037 };
29038 QuadraticBezierCurve.prototype.fromJSON = function ( json ) {
29039 Curve.prototype.fromJSON.call( this, json );
29040 this.v0.fromArray( json.v0 );
29041 this.v1.fromArray( json.v1 );
29042 this.v2.fromArray( json.v2 );
29043 return this;
29044 };
29045 function QuadraticBezierCurve3( v0, v1, v2 ) {
29046 Curve.call( this );
29047 this.type = 'QuadraticBezierCurve3';
29048 this.v0 = v0 || new Vector3();
29049 this.v1 = v1 || new Vector3();
29050 this.v2 = v2 || new Vector3();
29051 }
29052 QuadraticBezierCurve3.prototype = Object.create( Curve.prototype );
29053 QuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;
29054 QuadraticBezierCurve3.prototype.isQuadraticBezierCurve3 = true;
29055 QuadraticBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) {
29056 const point = optionalTarget || new Vector3();
29057 const v0 = this.v0, v1 = this.v1, v2 = this.v2;
29058 point.set(
29059 QuadraticBezier( t, v0.x, v1.x, v2.x ),
29060 QuadraticBezier( t, v0.y, v1.y, v2.y ),
29061 QuadraticBezier( t, v0.z, v1.z, v2.z )
29062 );
29063 return point;
29064 };
29065 QuadraticBezierCurve3.prototype.copy = function ( source ) {
29066 Curve.prototype.copy.call( this, source );
29067 this.v0.copy( source.v0 );
29068 this.v1.copy( source.v1 );
29069 this.v2.copy( source.v2 );
29070 return this;
29071 };
29072 QuadraticBezierCurve3.prototype.toJSON = function () {
29073 const data = Curve.prototype.toJSON.call( this );
29074 data.v0 = this.v0.toArray();
29075 data.v1 = this.v1.toArray();
29076 data.v2 = this.v2.toArray();
29077 return data;
29078 };
29079 QuadraticBezierCurve3.prototype.fromJSON = function ( json ) {
29080 Curve.prototype.fromJSON.call( this, json );
29081 this.v0.fromArray( json.v0 );
29082 this.v1.fromArray( json.v1 );
29083 this.v2.fromArray( json.v2 );
29084 return this;
29085 };
29086 function SplineCurve( points ) {
29087 Curve.call( this );
29088 this.type = 'SplineCurve';
29089 this.points = points || [];
29090 }
29091 SplineCurve.prototype = Object.create( Curve.prototype );
29092 SplineCurve.prototype.constructor = SplineCurve;
29093 SplineCurve.prototype.isSplineCurve = true;
29094 SplineCurve.prototype.getPoint = function ( t, optionalTarget ) {
29095 const point = optionalTarget || new Vector2();
29096 const points = this.points;
29097 const p = ( points.length - 1 ) * t;
29098 const intPoint = Math.floor( p );
29099 const weight = p - intPoint;
29100 const p0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];
29101 const p1 = points[ intPoint ];
29102 const p2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];
29103 const p3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];
29104 point.set(
29105 CatmullRom( weight, p0.x, p1.x, p2.x, p3.x ),
29106 CatmullRom( weight, p0.y, p1.y, p2.y, p3.y )
29107 );
29108 return point;
29109 };
29110 SplineCurve.prototype.copy = function ( source ) {
29111 Curve.prototype.copy.call( this, source );
29112 this.points = [];
29113 for ( let i = 0, l = source.points.length; i < l; i ++ ) {
29114 const point = source.points[ i ];
29115 this.points.push( point.clone() );
29116 }
29117 return this;
29118 };
29119 SplineCurve.prototype.toJSON = function () {
29120 const data = Curve.prototype.toJSON.call( this );
29121 data.points = [];
29122 for ( let i = 0, l = this.points.length; i < l; i ++ ) {
29123 const point = this.points[ i ];
29124 data.points.push( point.toArray() );
29125 }
29126 return data;
29127 };
29128 SplineCurve.prototype.fromJSON = function ( json ) {
29129 Curve.prototype.fromJSON.call( this, json );
29130 this.points = [];
29131 for ( let i = 0, l = json.points.length; i < l; i ++ ) {
29132 const point = json.points[ i ];
29133 this.points.push( new Vector2().fromArray( point ) );
29134 }
29135 return this;
29136 };
29137 var Curves = Object.freeze({
29138 __proto__: null,
29139 ArcCurve: ArcCurve,
29140 CatmullRomCurve3: CatmullRomCurve3,
29141 CubicBezierCurve: CubicBezierCurve,
29142 CubicBezierCurve3: CubicBezierCurve3,
29143 EllipseCurve: EllipseCurve,
29144 LineCurve: LineCurve,
29145 LineCurve3: LineCurve3,
29146 QuadraticBezierCurve: QuadraticBezierCurve,
29147 QuadraticBezierCurve3: QuadraticBezierCurve3,
29148 SplineCurve: SplineCurve
29149 });
29150 function CurvePath() {
29151 Curve.call( this );
29152 this.type = 'CurvePath';
29153 this.curves = [];
29154 this.autoClose = false;
29155 }
29156 CurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {
29157 constructor: CurvePath,
29158 add: function ( curve ) {
29159 this.curves.push( curve );
29160 },
29161 closePath: function () {
29162 const startPoint = this.curves[ 0 ].getPoint( 0 );
29163 const endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );
29164 if ( ! startPoint.equals( endPoint ) ) {
29165 this.curves.push( new LineCurve( endPoint, startPoint ) );
29166 }
29167 },
29168 getPoint: function ( t ) {
29169 const d = t * this.getLength();
29170 const curveLengths = this.getCurveLengths();
29171 let i = 0;
29172 while ( i < curveLengths.length ) {
29173 if ( curveLengths[ i ] >= d ) {
29174 const diff = curveLengths[ i ] - d;
29175 const curve = this.curves[ i ];
29176 const segmentLength = curve.getLength();
29177 const u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;
29178 return curve.getPointAt( u );
29179 }
29180 i ++;
29181 }
29182 return null;
29183 },
29184 getLength: function () {
29185 const lens = this.getCurveLengths();
29186 return lens[ lens.length - 1 ];
29187 },
29188 updateArcLengths: function () {
29189 this.needsUpdate = true;
29190 this.cacheLengths = null;
29191 this.getCurveLengths();
29192 },
29193 getCurveLengths: function () {
29194 if ( this.cacheLengths && this.cacheLengths.length === this.curves.length ) {
29195 return this.cacheLengths;
29196 }
29197 const lengths = [];
29198 let sums = 0;
29199 for ( let i = 0, l = this.curves.length; i < l; i ++ ) {
29200 sums += this.curves[ i ].getLength();
29201 lengths.push( sums );
29202 }
29203 this.cacheLengths = lengths;
29204 return lengths;
29205 },
29206 getSpacedPoints: function ( divisions ) {
29207 if ( divisions === undefined ) divisions = 40;
29208 const points = [];
29209 for ( let i = 0; i <= divisions; i ++ ) {
29210 points.push( this.getPoint( i / divisions ) );
29211 }
29212 if ( this.autoClose ) {
29213 points.push( points[ 0 ] );
29214 }
29215 return points;
29216 },
29217 getPoints: function ( divisions ) {
29218 divisions = divisions || 12;
29219 const points = [];
29220 let last;
29221 for ( let i = 0, curves = this.curves; i < curves.length; i ++ ) {
29222 const curve = curves[ i ];
29223 const resolution = ( curve && curve.isEllipseCurve ) ? divisions * 2
29224 : ( curve && ( curve.isLineCurve || curve.isLineCurve3 ) ) ? 1
29225 : ( curve && curve.isSplineCurve ) ? divisions * curve.points.length
29226 : divisions;
29227 const pts = curve.getPoints( resolution );
29228 for ( let j = 0; j < pts.length; j ++ ) {
29229 const point = pts[ j ];
29230 if ( last && last.equals( point ) ) continue;
29231 points.push( point );
29232 last = point;
29233 }
29234 }
29235 if ( this.autoClose && points.length > 1 && ! points[ points.length - 1 ].equals( points[ 0 ] ) ) {
29236 points.push( points[ 0 ] );
29237 }
29238 return points;
29239 },
29240 copy: function ( source ) {
29241 Curve.prototype.copy.call( this, source );
29242 this.curves = [];
29243 for ( let i = 0, l = source.curves.length; i < l; i ++ ) {
29244 const curve = source.curves[ i ];
29245 this.curves.push( curve.clone() );
29246 }
29247 this.autoClose = source.autoClose;
29248 return this;
29249 },
29250 toJSON: function () {
29251 const data = Curve.prototype.toJSON.call( this );
29252 data.autoClose = this.autoClose;
29253 data.curves = [];
29254 for ( let i = 0, l = this.curves.length; i < l; i ++ ) {
29255 const curve = this.curves[ i ];
29256 data.curves.push( curve.toJSON() );
29257 }
29258 return data;
29259 },
29260 fromJSON: function ( json ) {
29261 Curve.prototype.fromJSON.call( this, json );
29262 this.autoClose = json.autoClose;
29263 this.curves = [];
29264 for ( let i = 0, l = json.curves.length; i < l; i ++ ) {
29265 const curve = json.curves[ i ];
29266 this.curves.push( new Curves[ curve.type ]().fromJSON( curve ) );
29267 }
29268 return this;
29269 }
29270 } );
29271 function Path( points ) {
29272 CurvePath.call( this );
29273 this.type = 'Path';
29274 this.currentPoint = new Vector2();
29275 if ( points ) {
29276 this.setFromPoints( points );
29277 }
29278 }
29279 Path.prototype = Object.assign( Object.create( CurvePath.prototype ), {
29280 constructor: Path,
29281 setFromPoints: function ( points ) {
29282 this.moveTo( points[ 0 ].x, points[ 0 ].y );
29283 for ( let i = 1, l = points.length; i < l; i ++ ) {
29284 this.lineTo( points[ i ].x, points[ i ].y );
29285 }
29286 return this;
29287 },
29288 moveTo: function ( x, y ) {
29289 this.currentPoint.set( x, y );
29290 return this;
29291 },
29292 lineTo: function ( x, y ) {
29293 const curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );
29294 this.curves.push( curve );
29295 this.currentPoint.set( x, y );
29296 return this;
29297 },
29298 quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {
29299 const curve = new QuadraticBezierCurve(
29300 this.currentPoint.clone(),
29301 new Vector2( aCPx, aCPy ),
29302 new Vector2( aX, aY )
29303 );
29304 this.curves.push( curve );
29305 this.currentPoint.set( aX, aY );
29306 return this;
29307 },
29308 bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {
29309 const curve = new CubicBezierCurve(
29310 this.currentPoint.clone(),
29311 new Vector2( aCP1x, aCP1y ),
29312 new Vector2( aCP2x, aCP2y ),
29313 new Vector2( aX, aY )
29314 );
29315 this.curves.push( curve );
29316 this.currentPoint.set( aX, aY );
29317 return this;
29318 },
29319 splineThru: function ( pts ) {
29320 const npts = [ this.currentPoint.clone() ].concat( pts );
29321 const curve = new SplineCurve( npts );
29322 this.curves.push( curve );
29323 this.currentPoint.copy( pts[ pts.length - 1 ] );
29324 return this;
29325 },
29326 arc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
29327 const x0 = this.currentPoint.x;
29328 const y0 = this.currentPoint.y;
29329 this.absarc( aX + x0, aY + y0, aRadius,
29330 aStartAngle, aEndAngle, aClockwise );
29331 return this;
29332 },
29333 absarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
29334 this.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
29335 return this;
29336 },
29337 ellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
29338 const x0 = this.currentPoint.x;
29339 const y0 = this.currentPoint.y;
29340 this.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );
29341 return this;
29342 },
29343 absellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
29344 const curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );
29345 if ( this.curves.length > 0 ) {
29346 const firstPoint = curve.getPoint( 0 );
29347 if ( ! firstPoint.equals( this.currentPoint ) ) {
29348 this.lineTo( firstPoint.x, firstPoint.y );
29349 }
29350 }
29351 this.curves.push( curve );
29352 const lastPoint = curve.getPoint( 1 );
29353 this.currentPoint.copy( lastPoint );
29354 return this;
29355 },
29356 copy: function ( source ) {
29357 CurvePath.prototype.copy.call( this, source );
29358 this.currentPoint.copy( source.currentPoint );
29359 return this;
29360 },
29361 toJSON: function () {
29362 const data = CurvePath.prototype.toJSON.call( this );
29363 data.currentPoint = this.currentPoint.toArray();
29364 return data;
29365 },
29366 fromJSON: function ( json ) {
29367 CurvePath.prototype.fromJSON.call( this, json );
29368 this.currentPoint.fromArray( json.currentPoint );
29369 return this;
29370 }
29371 } );
29372 function Shape( points ) {
29373 Path.call( this, points );
29374 this.uuid = MathUtils.generateUUID();
29375 this.type = 'Shape';
29376 this.holes = [];
29377 }
29378 Shape.prototype = Object.assign( Object.create( Path.prototype ), {
29379 constructor: Shape,
29380 getPointsHoles: function ( divisions ) {
29381 const holesPts = [];
29382 for ( let i = 0, l = this.holes.length; i < l; i ++ ) {
29383 holesPts[ i ] = this.holes[ i ].getPoints( divisions );
29384 }
29385 return holesPts;
29386 },
29387 extractPoints: function ( divisions ) {
29388 return {
29389 shape: this.getPoints( divisions ),
29390 holes: this.getPointsHoles( divisions )
29391 };
29392 },
29393 copy: function ( source ) {
29394 Path.prototype.copy.call( this, source );
29395 this.holes = [];
29396 for ( let i = 0, l = source.holes.length; i < l; i ++ ) {
29397 const hole = source.holes[ i ];
29398 this.holes.push( hole.clone() );
29399 }
29400 return this;
29401 },
29402 toJSON: function () {
29403 const data = Path.prototype.toJSON.call( this );
29404 data.uuid = this.uuid;
29405 data.holes = [];
29406 for ( let i = 0, l = this.holes.length; i < l; i ++ ) {
29407 const hole = this.holes[ i ];
29408 data.holes.push( hole.toJSON() );
29409 }
29410 return data;
29411 },
29412 fromJSON: function ( json ) {
29413 Path.prototype.fromJSON.call( this, json );
29414 this.uuid = json.uuid;
29415 this.holes = [];
29416 for ( let i = 0, l = json.holes.length; i < l; i ++ ) {
29417 const hole = json.holes[ i ];
29418 this.holes.push( new Path().fromJSON( hole ) );
29419 }
29420 return this;
29421 }
29422 } );
29423 function Light( color, intensity ) {
29424 Object3D.call( this );
29425 this.type = 'Light';
29426 this.color = new Color( color );
29427 this.intensity = intensity !== undefined ? intensity : 1;
29428 this.receiveShadow = undefined;
29429 }
29430 Light.prototype = Object.assign( Object.create( Object3D.prototype ), {
29431 constructor: Light,
29432 isLight: true,
29433 copy: function ( source ) {
29434 Object3D.prototype.copy.call( this, source );
29435 this.color.copy( source.color );
29436 this.intensity = source.intensity;
29437 return this;
29438 },
29439 toJSON: function ( meta ) {
29440 const data = Object3D.prototype.toJSON.call( this, meta );
29441 data.object.color = this.color.getHex();
29442 data.object.intensity = this.intensity;
29443 if ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();
29444 if ( this.distance !== undefined ) data.object.distance = this.distance;
29445 if ( this.angle !== undefined ) data.object.angle = this.angle;
29446 if ( this.decay !== undefined ) data.object.decay = this.decay;
29447 if ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;
29448 if ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();
29449 return data;
29450 }
29451 } );
29452 function HemisphereLight( skyColor, groundColor, intensity ) {
29453 Light.call( this, skyColor, intensity );
29454 this.type = 'HemisphereLight';
29455 this.castShadow = undefined;
29456 this.position.copy( Object3D.DefaultUp );
29457 this.updateMatrix();
29458 this.groundColor = new Color( groundColor );
29459 }
29460 HemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {
29461 constructor: HemisphereLight,
29462 isHemisphereLight: true,
29463 copy: function ( source ) {
29464 Light.prototype.copy.call( this, source );
29465 this.groundColor.copy( source.groundColor );
29466 return this;
29467 }
29468 } );
29469 function LightShadow( camera ) {
29470 this.camera = camera;
29471 this.bias = 0;
29472 this.normalBias = 0;
29473 this.radius = 1;
29474 this.mapSize = new Vector2( 512, 512 );
29475 this.map = null;
29476 this.mapPass = null;
29477 this.matrix = new Matrix4();
29478 this.autoUpdate = true;
29479 this.needsUpdate = false;
29480 this._frustum = new Frustum();
29481 this._frameExtents = new Vector2( 1, 1 );
29482 this._viewportCount = 1;
29483 this._viewports = [
29484 new Vector4( 0, 0, 1, 1 )
29485 ];
29486 }
29487 Object.assign( LightShadow.prototype, {
29488 _projScreenMatrix: new Matrix4(),
29489 _lightPositionWorld: new Vector3(),
29490 _lookTarget: new Vector3(),
29491 getViewportCount: function () {
29492 return this._viewportCount;
29493 },
29494 getFrustum: function () {
29495 return this._frustum;
29496 },
29497 updateMatrices: function ( light ) {
29498 const shadowCamera = this.camera,
29499 shadowMatrix = this.matrix,
29500 projScreenMatrix = this._projScreenMatrix,
29501 lookTarget = this._lookTarget,
29502 lightPositionWorld = this._lightPositionWorld;
29503 lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
29504 shadowCamera.position.copy( lightPositionWorld );
29505 lookTarget.setFromMatrixPosition( light.target.matrixWorld );
29506 shadowCamera.lookAt( lookTarget );
29507 shadowCamera.updateMatrixWorld();
29508 projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
29509 this._frustum.setFromProjectionMatrix( projScreenMatrix );
29510 shadowMatrix.set(
29511 0.5, 0.0, 0.0, 0.5,
29512 0.0, 0.5, 0.0, 0.5,
29513 0.0, 0.0, 0.5, 0.5,
29514 0.0, 0.0, 0.0, 1.0
29515 );
29516 shadowMatrix.multiply( shadowCamera.projectionMatrix );
29517 shadowMatrix.multiply( shadowCamera.matrixWorldInverse );
29518 },
29519 getViewport: function ( viewportIndex ) {
29520 return this._viewports[ viewportIndex ];
29521 },
29522 getFrameExtents: function () {
29523 return this._frameExtents;
29524 },
29525 copy: function ( source ) {
29526 this.camera = source.camera.clone();
29527 this.bias = source.bias;
29528 this.radius = source.radius;
29529 this.mapSize.copy( source.mapSize );
29530 return this;
29531 },
29532 clone: function () {
29533 return new this.constructor().copy( this );
29534 },
29535 toJSON: function () {
29536 const object = {};
29537 if ( this.bias !== 0 ) object.bias = this.bias;
29538 if ( this.normalBias !== 0 ) object.normalBias = this.normalBias;
29539 if ( this.radius !== 1 ) object.radius = this.radius;
29540 if ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();
29541 object.camera = this.camera.toJSON( false ).object;
29542 delete object.camera.matrix;
29543 return object;
29544 }
29545 } );
29546 function SpotLightShadow() {
29547 LightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );
29548 }
29549 SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
29550 constructor: SpotLightShadow,
29551 isSpotLightShadow: true,
29552 updateMatrices: function ( light ) {
29553 const camera = this.camera;
29554 const fov = MathUtils.RAD2DEG * 2 * light.angle;
29555 const aspect = this.mapSize.width / this.mapSize.height;
29556 const far = light.distance || camera.far;
29557 if ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {
29558 camera.fov = fov;
29559 camera.aspect = aspect;
29560 camera.far = far;
29561 camera.updateProjectionMatrix();
29562 }
29563 LightShadow.prototype.updateMatrices.call( this, light );
29564 }
29565 } );
29566 function SpotLight( color, intensity, distance, angle, penumbra, decay ) {
29567 Light.call( this, color, intensity );
29568 this.type = 'SpotLight';
29569 this.position.copy( Object3D.DefaultUp );
29570 this.updateMatrix();
29571 this.target = new Object3D();
29572 Object.defineProperty( this, 'power', {
29573 get: function () {
29574 return this.intensity * Math.PI;
29575 },
29576 set: function ( power ) {
29577 this.intensity = power / Math.PI;
29578 }
29579 } );
29580 this.distance = ( distance !== undefined ) ? distance : 0;
29581 this.angle = ( angle !== undefined ) ? angle : Math.PI / 3;
29582 this.penumbra = ( penumbra !== undefined ) ? penumbra : 0;
29583 this.decay = ( decay !== undefined ) ? decay : 1;
29584 this.shadow = new SpotLightShadow();
29585 }
29586 SpotLight.prototype = Object.assign( Object.create( Light.prototype ), {
29587 constructor: SpotLight,
29588 isSpotLight: true,
29589 copy: function ( source ) {
29590 Light.prototype.copy.call( this, source );
29591 this.distance = source.distance;
29592 this.angle = source.angle;
29593 this.penumbra = source.penumbra;
29594 this.decay = source.decay;
29595 this.target = source.target.clone();
29596 this.shadow = source.shadow.clone();
29597 return this;
29598 }
29599 } );
29600 function PointLightShadow() {
29601 LightShadow.call( this, new PerspectiveCamera( 90, 1, 0.5, 500 ) );
29602 this._frameExtents = new Vector2( 4, 2 );
29603 this._viewportCount = 6;
29604 this._viewports = [
29605 new Vector4( 2, 1, 1, 1 ),
29606 new Vector4( 0, 1, 1, 1 ),
29607 new Vector4( 3, 1, 1, 1 ),
29608 new Vector4( 1, 1, 1, 1 ),
29609 new Vector4( 3, 0, 1, 1 ),
29610 new Vector4( 1, 0, 1, 1 )
29611 ];
29612 this._cubeDirections = [
29613 new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),
29614 new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )
29615 ];
29616 this._cubeUps = [
29617 new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),
29618 new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 )
29619 ];
29620 }
29621 PointLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
29622 constructor: PointLightShadow,
29623 isPointLightShadow: true,
29624 updateMatrices: function ( light, viewportIndex ) {
29625 if ( viewportIndex === undefined ) viewportIndex = 0;
29626 const camera = this.camera,
29627 shadowMatrix = this.matrix,
29628 lightPositionWorld = this._lightPositionWorld,
29629 lookTarget = this._lookTarget,
29630 projScreenMatrix = this._projScreenMatrix;
29631 lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
29632 camera.position.copy( lightPositionWorld );
29633 lookTarget.copy( camera.position );
29634 lookTarget.add( this._cubeDirections[ viewportIndex ] );
29635 camera.up.copy( this._cubeUps[ viewportIndex ] );
29636 camera.lookAt( lookTarget );
29637 camera.updateMatrixWorld();
29638 shadowMatrix.makeTranslation( - lightPositionWorld.x, - lightPositionWorld.y, - lightPositionWorld.z );
29639 projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
29640 this._frustum.setFromProjectionMatrix( projScreenMatrix );
29641 }
29642 } );
29643 function PointLight( color, intensity, distance, decay ) {
29644 Light.call( this, color, intensity );
29645 this.type = 'PointLight';
29646 Object.defineProperty( this, 'power', {
29647 get: function () {
29648 return this.intensity * 4 * Math.PI;
29649 },
29650 set: function ( power ) {
29651 this.intensity = power / ( 4 * Math.PI );
29652 }
29653 } );
29654 this.distance = ( distance !== undefined ) ? distance : 0;
29655 this.decay = ( decay !== undefined ) ? decay : 1;
29656 this.shadow = new PointLightShadow();
29657 }
29658 PointLight.prototype = Object.assign( Object.create( Light.prototype ), {
29659 constructor: PointLight,
29660 isPointLight: true,
29661 copy: function ( source ) {
29662 Light.prototype.copy.call( this, source );
29663 this.distance = source.distance;
29664 this.decay = source.decay;
29665 this.shadow = source.shadow.clone();
29666 return this;
29667 }
29668 } );
29669 function OrthographicCamera( left, right, top, bottom, near, far ) {
29670 Camera.call( this );
29671 this.type = 'OrthographicCamera';
29672 this.zoom = 1;
29673 this.view = null;
29674 this.left = ( left !== undefined ) ? left : - 1;
29675 this.right = ( right !== undefined ) ? right : 1;
29676 this.top = ( top !== undefined ) ? top : 1;
29677 this.bottom = ( bottom !== undefined ) ? bottom : - 1;
29678 this.near = ( near !== undefined ) ? near : 0.1;
29679 this.far = ( far !== undefined ) ? far : 2000;
29680 this.updateProjectionMatrix();
29681 }
29682 OrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {
29683 constructor: OrthographicCamera,
29684 isOrthographicCamera: true,
29685 copy: function ( source, recursive ) {
29686 Camera.prototype.copy.call( this, source, recursive );
29687 this.left = source.left;
29688 this.right = source.right;
29689 this.top = source.top;
29690 this.bottom = source.bottom;
29691 this.near = source.near;
29692 this.far = source.far;
29693 this.zoom = source.zoom;
29694 this.view = source.view === null ? null : Object.assign( {}, source.view );
29695 return this;
29696 },
29697 setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {
29698 if ( this.view === null ) {
29699 this.view = {
29700 enabled: true,
29701 fullWidth: 1,
29702 fullHeight: 1,
29703 offsetX: 0,
29704 offsetY: 0,
29705 width: 1,
29706 height: 1
29707 };
29708 }
29709 this.view.enabled = true;
29710 this.view.fullWidth = fullWidth;
29711 this.view.fullHeight = fullHeight;
29712 this.view.offsetX = x;
29713 this.view.offsetY = y;
29714 this.view.width = width;
29715 this.view.height = height;
29716 this.updateProjectionMatrix();
29717 },
29718 clearViewOffset: function () {
29719 if ( this.view !== null ) {
29720 this.view.enabled = false;
29721 }
29722 this.updateProjectionMatrix();
29723 },
29724 updateProjectionMatrix: function () {
29725 const dx = ( this.right - this.left ) / ( 2 * this.zoom );
29726 const dy = ( this.top - this.bottom ) / ( 2 * this.zoom );
29727 const cx = ( this.right + this.left ) / 2;
29728 const cy = ( this.top + this.bottom ) / 2;
29729 let left = cx - dx;
29730 let right = cx + dx;
29731 let top = cy + dy;
29732 let bottom = cy - dy;
29733 if ( this.view !== null && this.view.enabled ) {
29734 const scaleW = ( this.right - this.left ) / this.view.fullWidth / this.zoom;
29735 const scaleH = ( this.top - this.bottom ) / this.view.fullHeight / this.zoom;
29736 left += scaleW * this.view.offsetX;
29737 right = left + scaleW * this.view.width;
29738 top -= scaleH * this.view.offsetY;
29739 bottom = top - scaleH * this.view.height;
29740 }
29741 this.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );
29742 this.projectionMatrixInverse.getInverse( this.projectionMatrix );
29743 },
29744 toJSON: function ( meta ) {
29745 const data = Object3D.prototype.toJSON.call( this, meta );
29746 data.object.zoom = this.zoom;
29747 data.object.left = this.left;
29748 data.object.right = this.right;
29749 data.object.top = this.top;
29750 data.object.bottom = this.bottom;
29751 data.object.near = this.near;
29752 data.object.far = this.far;
29753 if ( this.view !== null ) data.object.view = Object.assign( {}, this.view );
29754 return data;
29755 }
29756 } );
29757 function DirectionalLightShadow() {
29758 LightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );
29759 }
29760 DirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
29761 constructor: DirectionalLightShadow,
29762 isDirectionalLightShadow: true,
29763 updateMatrices: function ( light ) {
29764 LightShadow.prototype.updateMatrices.call( this, light );
29765 }
29766 } );
29767 function DirectionalLight( color, intensity ) {
29768 Light.call( this, color, intensity );
29769 this.type = 'DirectionalLight';
29770 this.position.copy( Object3D.DefaultUp );
29771 this.updateMatrix();
29772 this.target = new Object3D();
29773 this.shadow = new DirectionalLightShadow();
29774 }
29775 DirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {
29776 constructor: DirectionalLight,
29777 isDirectionalLight: true,
29778 copy: function ( source ) {
29779 Light.prototype.copy.call( this, source );
29780 this.target = source.target.clone();
29781 this.shadow = source.shadow.clone();
29782 return this;
29783 }
29784 } );
29785 function AmbientLight( color, intensity ) {
29786 Light.call( this, color, intensity );
29787 this.type = 'AmbientLight';
29788 this.castShadow = undefined;
29789 }
29790 AmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {
29791 constructor: AmbientLight,
29792 isAmbientLight: true
29793 } );
29794 function RectAreaLight( color, intensity, width, height ) {
29795 Light.call( this, color, intensity );
29796 this.type = 'RectAreaLight';
29797 this.width = ( width !== undefined ) ? width : 10;
29798 this.height = ( height !== undefined ) ? height : 10;
29799 }
29800 RectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), {
29801 constructor: RectAreaLight,
29802 isRectAreaLight: true,
29803 copy: function ( source ) {
29804 Light.prototype.copy.call( this, source );
29805 this.width = source.width;
29806 this.height = source.height;
29807 return this;
29808 },
29809 toJSON: function ( meta ) {
29810 const data = Light.prototype.toJSON.call( this, meta );
29811 data.object.width = this.width;
29812 data.object.height = this.height;
29813 return data;
29814 }
29815 } );
29816 class SphericalHarmonics3 {
29817 constructor() {
29818 Object.defineProperty( this, 'isSphericalHarmonics3', { value: true } );
29819 this.coefficients = [];
29820 for ( let i = 0; i < 9; i ++ ) {
29821 this.coefficients.push( new Vector3() );
29822 }
29823 }
29824 set( coefficients ) {
29825 for ( let i = 0; i < 9; i ++ ) {
29826 this.coefficients[ i ].copy( coefficients[ i ] );
29827 }
29828 return this;
29829 }
29830 zero() {
29831 for ( let i = 0; i < 9; i ++ ) {
29832 this.coefficients[ i ].set( 0, 0, 0 );
29833 }
29834 return this;
29835 }
29836 getAt( normal, target ) {
29837 const x = normal.x, y = normal.y, z = normal.z;
29838 const coeff = this.coefficients;
29839 target.copy( coeff[ 0 ] ).multiplyScalar( 0.282095 );
29840 target.addScaledVector( coeff[ 1 ], 0.488603 * y );
29841 target.addScaledVector( coeff[ 2 ], 0.488603 * z );
29842 target.addScaledVector( coeff[ 3 ], 0.488603 * x );
29843 target.addScaledVector( coeff[ 4 ], 1.092548 * ( x * y ) );
29844 target.addScaledVector( coeff[ 5 ], 1.092548 * ( y * z ) );
29845 target.addScaledVector( coeff[ 6 ], 0.315392 * ( 3.0 * z * z - 1.0 ) );
29846 target.addScaledVector( coeff[ 7 ], 1.092548 * ( x * z ) );
29847 target.addScaledVector( coeff[ 8 ], 0.546274 * ( x * x - y * y ) );
29848 return target;
29849 }
29850 getIrradianceAt( normal, target ) {
29851 const x = normal.x, y = normal.y, z = normal.z;
29852 const coeff = this.coefficients;
29853 target.copy( coeff[ 0 ] ).multiplyScalar( 0.886227 );
29854 target.addScaledVector( coeff[ 1 ], 2.0 * 0.511664 * y );
29855 target.addScaledVector( coeff[ 2 ], 2.0 * 0.511664 * z );
29856 target.addScaledVector( coeff[ 3 ], 2.0 * 0.511664 * x );
29857 target.addScaledVector( coeff[ 4 ], 2.0 * 0.429043 * x * y );
29858 target.addScaledVector( coeff[ 5 ], 2.0 * 0.429043 * y * z );
29859 target.addScaledVector( coeff[ 6 ], 0.743125 * z * z - 0.247708 );
29860 target.addScaledVector( coeff[ 7 ], 2.0 * 0.429043 * x * z );
29861 target.addScaledVector( coeff[ 8 ], 0.429043 * ( x * x - y * y ) );
29862 return target;
29863 }
29864 add( sh ) {
29865 for ( let i = 0; i < 9; i ++ ) {
29866 this.coefficients[ i ].add( sh.coefficients[ i ] );
29867 }
29868 return this;
29869 }
29870 addScaledSH( sh, s ) {
29871 for ( let i = 0; i < 9; i ++ ) {
29872 this.coefficients[ i ].addScaledVector( sh.coefficients[ i ], s );
29873 }
29874 return this;
29875 }
29876 scale( s ) {
29877 for ( let i = 0; i < 9; i ++ ) {
29878 this.coefficients[ i ].multiplyScalar( s );
29879 }
29880 return this;
29881 }
29882 lerp( sh, alpha ) {
29883 for ( let i = 0; i < 9; i ++ ) {
29884 this.coefficients[ i ].lerp( sh.coefficients[ i ], alpha );
29885 }
29886 return this;
29887 }
29888 equals( sh ) {
29889 for ( let i = 0; i < 9; i ++ ) {
29890 if ( ! this.coefficients[ i ].equals( sh.coefficients[ i ] ) ) {
29891 return false;
29892 }
29893 }
29894 return true;
29895 }
29896 copy( sh ) {
29897 return this.set( sh.coefficients );
29898 }
29899 clone() {
29900 return new this.constructor().copy( this );
29901 }
29902 fromArray( array, offset ) {
29903 if ( offset === undefined ) offset = 0;
29904 const coefficients = this.coefficients;
29905 for ( let i = 0; i < 9; i ++ ) {
29906 coefficients[ i ].fromArray( array, offset + ( i * 3 ) );
29907 }
29908 return this;
29909 }
29910 toArray( array, offset ) {
29911 if ( array === undefined ) array = [];
29912 if ( offset === undefined ) offset = 0;
29913 const coefficients = this.coefficients;
29914 for ( let i = 0; i < 9; i ++ ) {
29915 coefficients[ i ].toArray( array, offset + ( i * 3 ) );
29916 }
29917 return array;
29918 }
29919 static getBasisAt( normal, shBasis ) {
29920 const x = normal.x, y = normal.y, z = normal.z;
29921 shBasis[ 0 ] = 0.282095;
29922 shBasis[ 1 ] = 0.488603 * y;
29923 shBasis[ 2 ] = 0.488603 * z;
29924 shBasis[ 3 ] = 0.488603 * x;
29925 shBasis[ 4 ] = 1.092548 * x * y;
29926 shBasis[ 5 ] = 1.092548 * y * z;
29927 shBasis[ 6 ] = 0.315392 * ( 3 * z * z - 1 );
29928 shBasis[ 7 ] = 1.092548 * x * z;
29929 shBasis[ 8 ] = 0.546274 * ( x * x - y * y );
29930 }
29931 }
29932 function LightProbe( sh, intensity ) {
29933 Light.call( this, undefined, intensity );
29934 this.type = 'LightProbe';
29935 this.sh = ( sh !== undefined ) ? sh : new SphericalHarmonics3();
29936 }
29937 LightProbe.prototype = Object.assign( Object.create( Light.prototype ), {
29938 constructor: LightProbe,
29939 isLightProbe: true,
29940 copy: function ( source ) {
29941 Light.prototype.copy.call( this, source );
29942 this.sh.copy( source.sh );
29943 return this;
29944 },
29945 fromJSON: function ( json ) {
29946 this.intensity = json.intensity;
29947 this.sh.fromArray( json.sh );
29948 return this;
29949 },
29950 toJSON: function ( meta ) {
29951 const data = Light.prototype.toJSON.call( this, meta );
29952 data.object.sh = this.sh.toArray();
29953 return data;
29954 }
29955 } );
29956 function MaterialLoader( manager ) {
29957 Loader.call( this, manager );
29958 this.textures = {};
29959 }
29960 MaterialLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
29961 constructor: MaterialLoader,
29962 load: function ( url, onLoad, onProgress, onError ) {
29963 const scope = this;
29964 const loader = new FileLoader( scope.manager );
29965 loader.setPath( scope.path );
29966 loader.setRequestHeader( scope.requestHeader );
29967 loader.load( url, function ( text ) {
29968 try {
29969 onLoad( scope.parse( JSON.parse( text ) ) );
29970 } catch ( e ) {
29971 if ( onError ) {
29972 onError( e );
29973 } else {
29974 console.error( e );
29975 }
29976 scope.manager.itemError( url );
29977 }
29978 }, onProgress, onError );
29979 },
29980 parse: function ( json ) {
29981 const textures = this.textures;
29982 function getTexture( name ) {
29983 if ( textures[ name ] === undefined ) {
29984 console.warn( 'THREE.MaterialLoader: Undefined texture', name );
29985 }
29986 return textures[ name ];
29987 }
29988 const material = new Materials[ json.type ]();
29989 if ( json.uuid !== undefined ) material.uuid = json.uuid;
29990 if ( json.name !== undefined ) material.name = json.name;
29991 if ( json.color !== undefined ) material.color.setHex( json.color );
29992 if ( json.roughness !== undefined ) material.roughness = json.roughness;
29993 if ( json.metalness !== undefined ) material.metalness = json.metalness;
29994 if ( json.sheen !== undefined ) material.sheen = new Color().setHex( json.sheen );
29995 if ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );
29996 if ( json.specular !== undefined ) material.specular.setHex( json.specular );
29997 if ( json.shininess !== undefined ) material.shininess = json.shininess;
29998 if ( json.clearcoat !== undefined ) material.clearcoat = json.clearcoat;
29999 if ( json.clearcoatRoughness !== undefined ) material.clearcoatRoughness = json.clearcoatRoughness;
30000 if ( json.fog !== undefined ) material.fog = json.fog;
30001 if ( json.flatShading !== undefined ) material.flatShading = json.flatShading;
30002 if ( json.blending !== undefined ) material.blending = json.blending;
30003 if ( json.combine !== undefined ) material.combine = json.combine;
30004 if ( json.side !== undefined ) material.side = json.side;
30005 if ( json.opacity !== undefined ) material.opacity = json.opacity;
30006 if ( json.transparent !== undefined ) material.transparent = json.transparent;
30007 if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;
30008 if ( json.depthTest !== undefined ) material.depthTest = json.depthTest;
30009 if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;
30010 if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;
30011 if ( json.stencilWrite !== undefined ) material.stencilWrite = json.stencilWrite;
30012 if ( json.stencilWriteMask !== undefined ) material.stencilWriteMask = json.stencilWriteMask;
30013 if ( json.stencilFunc !== undefined ) material.stencilFunc = json.stencilFunc;
30014 if ( json.stencilRef !== undefined ) material.stencilRef = json.stencilRef;
30015 if ( json.stencilFuncMask !== undefined ) material.stencilFuncMask = json.stencilFuncMask;
30016 if ( json.stencilFail !== undefined ) material.stencilFail = json.stencilFail;
30017 if ( json.stencilZFail !== undefined ) material.stencilZFail = json.stencilZFail;
30018 if ( json.stencilZPass !== undefined ) material.stencilZPass = json.stencilZPass;
30019 if ( json.wireframe !== undefined ) material.wireframe = json.wireframe;
30020 if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;
30021 if ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;
30022 if ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;
30023 if ( json.rotation !== undefined ) material.rotation = json.rotation;
30024 if ( json.linewidth !== 1 ) material.linewidth = json.linewidth;
30025 if ( json.dashSize !== undefined ) material.dashSize = json.dashSize;
30026 if ( json.gapSize !== undefined ) material.gapSize = json.gapSize;
30027 if ( json.scale !== undefined ) material.scale = json.scale;
30028 if ( json.polygonOffset !== undefined ) material.polygonOffset = json.polygonOffset;
30029 if ( json.polygonOffsetFactor !== undefined ) material.polygonOffsetFactor = json.polygonOffsetFactor;
30030 if ( json.polygonOffsetUnits !== undefined ) material.polygonOffsetUnits = json.polygonOffsetUnits;
30031 if ( json.skinning !== undefined ) material.skinning = json.skinning;
30032 if ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;
30033 if ( json.morphNormals !== undefined ) material.morphNormals = json.morphNormals;
30034 if ( json.dithering !== undefined ) material.dithering = json.dithering;
30035 if ( json.vertexTangents !== undefined ) material.vertexTangents = json.vertexTangents;
30036 if ( json.visible !== undefined ) material.visible = json.visible;
30037 if ( json.toneMapped !== undefined ) material.toneMapped = json.toneMapped;
30038 if ( json.userData !== undefined ) material.userData = json.userData;
30039 if ( json.vertexColors !== undefined ) {
30040 if ( typeof json.vertexColors === 'number' ) {
30041 material.vertexColors = ( json.vertexColors > 0 ) ? true : false;
30042 } else {
30043 material.vertexColors = json.vertexColors;
30044 }
30045 }
30046 if ( json.uniforms !== undefined ) {
30047 for ( const name in json.uniforms ) {
30048 const uniform = json.uniforms[ name ];
30049 material.uniforms[ name ] = {};
30050 switch ( uniform.type ) {
30051 case 't':
30052 material.uniforms[ name ].value = getTexture( uniform.value );
30053 break;
30054 case 'c':
30055 material.uniforms[ name ].value = new Color().setHex( uniform.value );
30056 break;
30057 case 'v2':
30058 material.uniforms[ name ].value = new Vector2().fromArray( uniform.value );
30059 break;
30060 case 'v3':
30061 material.uniforms[ name ].value = new Vector3().fromArray( uniform.value );
30062 break;
30063 case 'v4':
30064 material.uniforms[ name ].value = new Vector4().fromArray( uniform.value );
30065 break;
30066 case 'm3':
30067 material.uniforms[ name ].value = new Matrix3().fromArray( uniform.value );
30068 break;
30069 case 'm4':
30070 material.uniforms[ name ].value = new Matrix4().fromArray( uniform.value );
30071 break;
30072 default:
30073 material.uniforms[ name ].value = uniform.value;
30074 }
30075 }
30076 }
30077 if ( json.defines !== undefined ) material.defines = json.defines;
30078 if ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;
30079 if ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;
30080 if ( json.extensions !== undefined ) {
30081 for ( const key in json.extensions ) {
30082 material.extensions[ key ] = json.extensions[ key ];
30083 }
30084 }
30085 if ( json.shading !== undefined ) material.flatShading = json.shading === 1;
30086 if ( json.size !== undefined ) material.size = json.size;
30087 if ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;
30088 if ( json.map !== undefined ) material.map = getTexture( json.map );
30089 if ( json.matcap !== undefined ) material.matcap = getTexture( json.matcap );
30090 if ( json.alphaMap !== undefined ) material.alphaMap = getTexture( json.alphaMap );
30091 if ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );
30092 if ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;
30093 if ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );
30094 if ( json.normalMapType !== undefined ) material.normalMapType = json.normalMapType;
30095 if ( json.normalScale !== undefined ) {
30096 let normalScale = json.normalScale;
30097 if ( Array.isArray( normalScale ) === false ) {
30098 normalScale = [ normalScale, normalScale ];
30099 }
30100 material.normalScale = new Vector2().fromArray( normalScale );
30101 }
30102 if ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );
30103 if ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;
30104 if ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;
30105 if ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );
30106 if ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );
30107 if ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );
30108 if ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;
30109 if ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );
30110 if ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );
30111 if ( json.envMapIntensity !== undefined ) material.envMapIntensity = json.envMapIntensity;
30112 if ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;
30113 if ( json.refractionRatio !== undefined ) material.refractionRatio = json.refractionRatio;
30114 if ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );
30115 if ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;
30116 if ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );
30117 if ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;
30118 if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );
30119 if ( json.clearcoatMap !== undefined ) material.clearcoatMap = getTexture( json.clearcoatMap );
30120 if ( json.clearcoatRoughnessMap !== undefined ) material.clearcoatRoughnessMap = getTexture( json.clearcoatRoughnessMap );
30121 if ( json.clearcoatNormalMap !== undefined ) material.clearcoatNormalMap = getTexture( json.clearcoatNormalMap );
30122 if ( json.clearcoatNormalScale !== undefined ) material.clearcoatNormalScale = new Vector2().fromArray( json.clearcoatNormalScale );
30123 if ( json.transmission !== undefined ) material.transmission = json.transmission;
30124 if ( json.transmissionMap !== undefined ) material.transmissionMap = getTexture( json.transmissionMap );
30125 return material;
30126 },
30127 setTextures: function ( value ) {
30128 this.textures = value;
30129 return this;
30130 }
30131 } );
30132 const LoaderUtils = {
30133 decodeText: function ( array ) {
30134 if ( typeof TextDecoder !== 'undefined' ) {
30135 return new TextDecoder().decode( array );
30136 }
30137 let s = '';
30138 for ( let i = 0, il = array.length; i < il; i ++ ) {
30139 s += String.fromCharCode( array[ i ] );
30140 }
30141 try {
30142 return decodeURIComponent( escape( s ) );
30143 } catch ( e ) {
30144 return s;
30145 }
30146 },
30147 extractUrlBase: function ( url ) {
30148 const index = url.lastIndexOf( '/' );
30149 if ( index === - 1 ) return './';
30150 return url.substr( 0, index + 1 );
30151 }
30152 };
30153 function InstancedBufferGeometry() {
30154 BufferGeometry.call( this );
30155 this.type = 'InstancedBufferGeometry';
30156 this.instanceCount = Infinity;
30157 }
30158 InstancedBufferGeometry.prototype = Object.assign( Object.create( BufferGeometry.prototype ), {
30159 constructor: InstancedBufferGeometry,
30160 isInstancedBufferGeometry: true,
30161 copy: function ( source ) {
30162 BufferGeometry.prototype.copy.call( this, source );
30163 this.instanceCount = source.instanceCount;
30164 return this;
30165 },
30166 clone: function () {
30167 return new this.constructor().copy( this );
30168 },
30169 toJSON: function () {
30170 const data = BufferGeometry.prototype.toJSON.call( this );
30171 data.instanceCount = this.instanceCount;
30172 data.isInstancedBufferGeometry = true;
30173 return data;
30174 }
30175 } );
30176 function InstancedBufferAttribute( array, itemSize, normalized, meshPerAttribute ) {
30177 if ( typeof ( normalized ) === 'number' ) {
30178 meshPerAttribute = normalized;
30179 normalized = false;
30180 console.error( 'THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.' );
30181 }
30182 BufferAttribute.call( this, array, itemSize, normalized );
30183 this.meshPerAttribute = meshPerAttribute || 1;
30184 }
30185 InstancedBufferAttribute.prototype = Object.assign( Object.create( BufferAttribute.prototype ), {
30186 constructor: InstancedBufferAttribute,
30187 isInstancedBufferAttribute: true,
30188 copy: function ( source ) {
30189 BufferAttribute.prototype.copy.call( this, source );
30190 this.meshPerAttribute = source.meshPerAttribute;
30191 return this;
30192 },
30193 toJSON: function () {
30194 const data = BufferAttribute.prototype.toJSON.call( this );
30195 data.meshPerAttribute = this.meshPerAttribute;
30196 data.isInstancedBufferAttribute = true;
30197 return data;
30198 }
30199 } );
30200 function BufferGeometryLoader( manager ) {
30201 Loader.call( this, manager );
30202 }
30203 BufferGeometryLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
30204 constructor: BufferGeometryLoader,
30205 load: function ( url, onLoad, onProgress, onError ) {
30206 const scope = this;
30207 const loader = new FileLoader( scope.manager );
30208 loader.setPath( scope.path );
30209 loader.setRequestHeader( scope.requestHeader );
30210 loader.load( url, function ( text ) {
30211 try {
30212 onLoad( scope.parse( JSON.parse( text ) ) );
30213 } catch ( e ) {
30214 if ( onError ) {
30215 onError( e );
30216 } else {
30217 console.error( e );
30218 }
30219 scope.manager.itemError( url );
30220 }
30221 }, onProgress, onError );
30222 },
30223 parse: function ( json ) {
30224 const interleavedBufferMap = {};
30225 const arrayBufferMap = {};
30226 function getInterleavedBuffer( json, uuid ) {
30227 if ( interleavedBufferMap[ uuid ] !== undefined ) return interleavedBufferMap[ uuid ];
30228 const interleavedBuffers = json.interleavedBuffers;
30229 const interleavedBuffer = interleavedBuffers[ uuid ];
30230 const buffer = getArrayBuffer( json, interleavedBuffer.buffer );
30231 const array = new TYPED_ARRAYS[ interleavedBuffer.type ]( buffer );
30232 const ib = new InterleavedBuffer( array, interleavedBuffer.stride );
30233 ib.uuid = interleavedBuffer.uuid;
30234 interleavedBufferMap[ uuid ] = ib;
30235 return ib;
30236 }
30237 function getArrayBuffer( json, uuid ) {
30238 if ( arrayBufferMap[ uuid ] !== undefined ) return arrayBufferMap[ uuid ];
30239 const arrayBuffers = json.arrayBuffers;
30240 const arrayBuffer = arrayBuffers[ uuid ];
30241 const ab = new Uint32Array( arrayBuffer ).buffer;
30242 arrayBufferMap[ uuid ] = ab;
30243 return ab;
30244 }
30245 const geometry = json.isInstancedBufferGeometry ? new InstancedBufferGeometry() : new BufferGeometry();
30246 const index = json.data.index;
30247 if ( index !== undefined ) {
30248 const typedArray = new TYPED_ARRAYS[ index.type ]( index.array );
30249 geometry.setIndex( new BufferAttribute( typedArray, 1 ) );
30250 }
30251 const attributes = json.data.attributes;
30252 for ( const key in attributes ) {
30253 const attribute = attributes[ key ];
30254 let bufferAttribute;
30255 if ( attribute.isInterleavedBufferAttribute ) {
30256 const interleavedBuffer = getInterleavedBuffer( json.data, attribute.data );
30257 bufferAttribute = new InterleavedBufferAttribute( interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized );
30258 } else {
30259 const typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );
30260 const bufferAttributeConstr = attribute.isInstancedBufferAttribute ? InstancedBufferAttribute : BufferAttribute;
30261 bufferAttribute = new bufferAttributeConstr( typedArray, attribute.itemSize, attribute.normalized );
30262 }
30263 if ( attribute.name !== undefined ) bufferAttribute.name = attribute.name;
30264 geometry.setAttribute( key, bufferAttribute );
30265 }
30266 const morphAttributes = json.data.morphAttributes;
30267 if ( morphAttributes ) {
30268 for ( const key in morphAttributes ) {
30269 const attributeArray = morphAttributes[ key ];
30270 const array = [];
30271 for ( let i = 0, il = attributeArray.length; i < il; i ++ ) {
30272 const attribute = attributeArray[ i ];
30273 let bufferAttribute;
30274 if ( attribute.isInterleavedBufferAttribute ) {
30275 const interleavedBuffer = getInterleavedBuffer( json.data, attribute.data );
30276 bufferAttribute = new InterleavedBufferAttribute( interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized );
30277 } else {
30278 const typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );
30279 bufferAttribute = new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized );
30280 }
30281 if ( attribute.name !== undefined ) bufferAttribute.name = attribute.name;
30282 array.push( bufferAttribute );
30283 }
30284 geometry.morphAttributes[ key ] = array;
30285 }
30286 }
30287 const morphTargetsRelative = json.data.morphTargetsRelative;
30288 if ( morphTargetsRelative ) {
30289 geometry.morphTargetsRelative = true;
30290 }
30291 const groups = json.data.groups || json.data.drawcalls || json.data.offsets;
30292 if ( groups !== undefined ) {
30293 for ( let i = 0, n = groups.length; i !== n; ++ i ) {
30294 const group = groups[ i ];
30295 geometry.addGroup( group.start, group.count, group.materialIndex );
30296 }
30297 }
30298 const boundingSphere = json.data.boundingSphere;
30299 if ( boundingSphere !== undefined ) {
30300 const center = new Vector3();
30301 if ( boundingSphere.center !== undefined ) {
30302 center.fromArray( boundingSphere.center );
30303 }
30304 geometry.boundingSphere = new Sphere( center, boundingSphere.radius );
30305 }
30306 if ( json.name ) geometry.name = json.name;
30307 if ( json.userData ) geometry.userData = json.userData;
30308 return geometry;
30309 }
30310 } );
30311 const TYPED_ARRAYS = {
30312 Int8Array: Int8Array,
30313 Uint8Array: Uint8Array,
30314 Uint8ClampedArray: typeof Uint8ClampedArray !== 'undefined' ? Uint8ClampedArray : Uint8Array,
30315 Int16Array: Int16Array,
30316 Uint16Array: Uint16Array,
30317 Int32Array: Int32Array,
30318 Uint32Array: Uint32Array,
30319 Float32Array: Float32Array,
30320 Float64Array: Float64Array
30321 };
30322 function ObjectLoader( manager ) {
30323 Loader.call( this, manager );
30324 }
30325 ObjectLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
30326 constructor: ObjectLoader,
30327 load: function ( url, onLoad, onProgress, onError ) {
30328 const scope = this;
30329 const path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path;
30330 this.resourcePath = this.resourcePath || path;
30331 const loader = new FileLoader( scope.manager );
30332 loader.setPath( this.path );
30333 loader.setRequestHeader( this.requestHeader );
30334 loader.load( url, function ( text ) {
30335 let json = null;
30336 try {
30337 json = JSON.parse( text );
30338 } catch ( error ) {
30339 if ( onError !== undefined ) onError( error );
30340 console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message );
30341 return;
30342 }
30343 const metadata = json.metadata;
30344 if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {
30345 console.error( 'THREE.ObjectLoader: Can\'t load ' + url );
30346 return;
30347 }
30348 scope.parse( json, onLoad );
30349 }, onProgress, onError );
30350 },
30351 parse: function ( json, onLoad ) {
30352 const shapes = this.parseShape( json.shapes );
30353 const geometries = this.parseGeometries( json.geometries, shapes );
30354 const images = this.parseImages( json.images, function () {
30355 if ( onLoad !== undefined ) onLoad( object );
30356 } );
30357 const textures = this.parseTextures( json.textures, images );
30358 const materials = this.parseMaterials( json.materials, textures );
30359 const object = this.parseObject( json.object, geometries, materials );
30360 if ( json.animations ) {
30361 object.animations = this.parseAnimations( json.animations );
30362 }
30363 if ( json.images === undefined || json.images.length === 0 ) {
30364 if ( onLoad !== undefined ) onLoad( object );
30365 }
30366 return object;
30367 },
30368 parseShape: function ( json ) {
30369 const shapes = {};
30370 if ( json !== undefined ) {
30371 for ( let i = 0, l = json.length; i < l; i ++ ) {
30372 const shape = new Shape().fromJSON( json[ i ] );
30373 shapes[ shape.uuid ] = shape;
30374 }
30375 }
30376 return shapes;
30377 },
30378 parseGeometries: function ( json, shapes ) {
30379 const geometries = {};
30380 let geometryShapes;
30381 if ( json !== undefined ) {
30382 const bufferGeometryLoader = new BufferGeometryLoader();
30383 for ( let i = 0, l = json.length; i < l; i ++ ) {
30384 let geometry;
30385 const data = json[ i ];
30386 switch ( data.type ) {
30387 case 'PlaneGeometry':
30388 case 'PlaneBufferGeometry':
30389 geometry = new Geometries[ data.type ](
30390 data.width,
30391 data.height,
30392 data.widthSegments,
30393 data.heightSegments
30394 );
30395 break;
30396 case 'BoxGeometry':
30397 case 'BoxBufferGeometry':
30398 case 'CubeGeometry':
30399 geometry = new Geometries[ data.type ](
30400 data.width,
30401 data.height,
30402 data.depth,
30403 data.widthSegments,
30404 data.heightSegments,
30405 data.depthSegments
30406 );
30407 break;
30408 case 'CircleGeometry':
30409 case 'CircleBufferGeometry':
30410 geometry = new Geometries[ data.type ](
30411 data.radius,
30412 data.segments,
30413 data.thetaStart,
30414 data.thetaLength
30415 );
30416 break;
30417 case 'CylinderGeometry':
30418 case 'CylinderBufferGeometry':
30419 geometry = new Geometries[ data.type ](
30420 data.radiusTop,
30421 data.radiusBottom,
30422 data.height,
30423 data.radialSegments,
30424 data.heightSegments,
30425 data.openEnded,
30426 data.thetaStart,
30427 data.thetaLength
30428 );
30429 break;
30430 case 'ConeGeometry':
30431 case 'ConeBufferGeometry':
30432 geometry = new Geometries[ data.type ](
30433 data.radius,
30434 data.height,
30435 data.radialSegments,
30436 data.heightSegments,
30437 data.openEnded,
30438 data.thetaStart,
30439 data.thetaLength
30440 );
30441 break;
30442 case 'SphereGeometry':
30443 case 'SphereBufferGeometry':
30444 geometry = new Geometries[ data.type ](
30445 data.radius,
30446 data.widthSegments,
30447 data.heightSegments,
30448 data.phiStart,
30449 data.phiLength,
30450 data.thetaStart,
30451 data.thetaLength
30452 );
30453 break;
30454 case 'DodecahedronGeometry':
30455 case 'DodecahedronBufferGeometry':
30456 case 'IcosahedronGeometry':
30457 case 'IcosahedronBufferGeometry':
30458 case 'OctahedronGeometry':
30459 case 'OctahedronBufferGeometry':
30460 case 'TetrahedronGeometry':
30461 case 'TetrahedronBufferGeometry':
30462 geometry = new Geometries[ data.type ](
30463 data.radius,
30464 data.detail
30465 );
30466 break;
30467 case 'RingGeometry':
30468 case 'RingBufferGeometry':
30469 geometry = new Geometries[ data.type ](
30470 data.innerRadius,
30471 data.outerRadius,
30472 data.thetaSegments,
30473 data.phiSegments,
30474 data.thetaStart,
30475 data.thetaLength
30476 );
30477 break;
30478 case 'TorusGeometry':
30479 case 'TorusBufferGeometry':
30480 geometry = new Geometries[ data.type ](
30481 data.radius,
30482 data.tube,
30483 data.radialSegments,
30484 data.tubularSegments,
30485 data.arc
30486 );
30487 break;
30488 case 'TorusKnotGeometry':
30489 case 'TorusKnotBufferGeometry':
30490 geometry = new Geometries[ data.type ](
30491 data.radius,
30492 data.tube,
30493 data.tubularSegments,
30494 data.radialSegments,
30495 data.p,
30496 data.q
30497 );
30498 break;
30499 case 'TubeGeometry':
30500 case 'TubeBufferGeometry':
30501 geometry = new Geometries[ data.type ](
30502 new Curves[ data.path.type ]().fromJSON( data.path ),
30503 data.tubularSegments,
30504 data.radius,
30505 data.radialSegments,
30506 data.closed
30507 );
30508 break;
30509 case 'LatheGeometry':
30510 case 'LatheBufferGeometry':
30511 geometry = new Geometries[ data.type ](
30512 data.points,
30513 data.segments,
30514 data.phiStart,
30515 data.phiLength
30516 );
30517 break;
30518 case 'PolyhedronGeometry':
30519 case 'PolyhedronBufferGeometry':
30520 geometry = new Geometries[ data.type ](
30521 data.vertices,
30522 data.indices,
30523 data.radius,
30524 data.details
30525 );
30526 break;
30527 case 'ShapeGeometry':
30528 case 'ShapeBufferGeometry':
30529 geometryShapes = [];
30530 for ( let j = 0, jl = data.shapes.length; j < jl; j ++ ) {
30531 const shape = shapes[ data.shapes[ j ] ];
30532 geometryShapes.push( shape );
30533 }
30534 geometry = new Geometries[ data.type ](
30535 geometryShapes,
30536 data.curveSegments
30537 );
30538 break;
30539 case 'ExtrudeGeometry':
30540 case 'ExtrudeBufferGeometry':
30541 geometryShapes = [];
30542 for ( let j = 0, jl = data.shapes.length; j < jl; j ++ ) {
30543 const shape = shapes[ data.shapes[ j ] ];
30544 geometryShapes.push( shape );
30545 }
30546 const extrudePath = data.options.extrudePath;
30547 if ( extrudePath !== undefined ) {
30548 data.options.extrudePath = new Curves[ extrudePath.type ]().fromJSON( extrudePath );
30549 }
30550 geometry = new Geometries[ data.type ](
30551 geometryShapes,
30552 data.options
30553 );
30554 break;
30555 case 'BufferGeometry':
30556 case 'InstancedBufferGeometry':
30557 geometry = bufferGeometryLoader.parse( data );
30558 break;
30559 case 'Geometry':
30560 console.error( 'THREE.ObjectLoader: Loading "Geometry" is not supported anymore.' );
30561 break;
30562 default:
30563 console.warn( 'THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"' );
30564 continue;
30565 }
30566 geometry.uuid = data.uuid;
30567 if ( data.name !== undefined ) geometry.name = data.name;
30568 if ( geometry.isBufferGeometry === true && data.userData !== undefined ) geometry.userData = data.userData;
30569 geometries[ data.uuid ] = geometry;
30570 }
30571 }
30572 return geometries;
30573 },
30574 parseMaterials: function ( json, textures ) {
30575 const cache = {};
30576 const materials = {};
30577 if ( json !== undefined ) {
30578 const loader = new MaterialLoader();
30579 loader.setTextures( textures );
30580 for ( let i = 0, l = json.length; i < l; i ++ ) {
30581 const data = json[ i ];
30582 if ( data.type === 'MultiMaterial' ) {
30583 const array = [];
30584 for ( let j = 0; j < data.materials.length; j ++ ) {
30585 const material = data.materials[ j ];
30586 if ( cache[ material.uuid ] === undefined ) {
30587 cache[ material.uuid ] = loader.parse( material );
30588 }
30589 array.push( cache[ material.uuid ] );
30590 }
30591 materials[ data.uuid ] = array;
30592 } else {
30593 if ( cache[ data.uuid ] === undefined ) {
30594 cache[ data.uuid ] = loader.parse( data );
30595 }
30596 materials[ data.uuid ] = cache[ data.uuid ];
30597 }
30598 }
30599 }
30600 return materials;
30601 },
30602 parseAnimations: function ( json ) {
30603 const animations = [];
30604 for ( let i = 0; i < json.length; i ++ ) {
30605 const data = json[ i ];
30606 const clip = AnimationClip.parse( data );
30607 if ( data.uuid !== undefined ) clip.uuid = data.uuid;
30608 animations.push( clip );
30609 }
30610 return animations;
30611 },
30612 parseImages: function ( json, onLoad ) {
30613 const scope = this;
30614 const images = {};
30615 let loader;
30616 function loadImage( url ) {
30617 scope.manager.itemStart( url );
30618 return loader.load( url, function () {
30619 scope.manager.itemEnd( url );
30620 }, undefined, function () {
30621 scope.manager.itemError( url );
30622 scope.manager.itemEnd( url );
30623 } );
30624 }
30625 if ( json !== undefined && json.length > 0 ) {
30626 const manager = new LoadingManager( onLoad );
30627 loader = new ImageLoader( manager );
30628 loader.setCrossOrigin( this.crossOrigin );
30629 for ( let i = 0, il = json.length; i < il; i ++ ) {
30630 const image = json[ i ];
30631 const url = image.url;
30632 if ( Array.isArray( url ) ) {
30633 images[ image.uuid ] = [];
30634 for ( let j = 0, jl = url.length; j < jl; j ++ ) {
30635 const currentUrl = url[ j ];
30636 const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( currentUrl ) ? currentUrl : scope.resourcePath + currentUrl;
30637 images[ image.uuid ].push( loadImage( path ) );
30638 }
30639 } else {
30640 const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.resourcePath + image.url;
30641 images[ image.uuid ] = loadImage( path );
30642 }
30643 }
30644 }
30645 return images;
30646 },
30647 parseTextures: function ( json, images ) {
30648 function parseConstant( value, type ) {
30649 if ( typeof value === 'number' ) return value;
30650 console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );
30651 return type[ value ];
30652 }
30653 const textures = {};
30654 if ( json !== undefined ) {
30655 for ( let i = 0, l = json.length; i < l; i ++ ) {
30656 const data = json[ i ];
30657 if ( data.image === undefined ) {
30658 console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid );
30659 }
30660 if ( images[ data.image ] === undefined ) {
30661 console.warn( 'THREE.ObjectLoader: Undefined image', data.image );
30662 }
30663 let texture;
30664 if ( Array.isArray( images[ data.image ] ) ) {
30665 texture = new CubeTexture( images[ data.image ] );
30666 } else {
30667 texture = new Texture( images[ data.image ] );
30668 }
30669 texture.needsUpdate = true;
30670 texture.uuid = data.uuid;
30671 if ( data.name !== undefined ) texture.name = data.name;
30672 if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING );
30673 if ( data.offset !== undefined ) texture.offset.fromArray( data.offset );
30674 if ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );
30675 if ( data.center !== undefined ) texture.center.fromArray( data.center );
30676 if ( data.rotation !== undefined ) texture.rotation = data.rotation;
30677 if ( data.wrap !== undefined ) {
30678 texture.wrapS = parseConstant( data.wrap[ 0 ], TEXTURE_WRAPPING );
30679 texture.wrapT = parseConstant( data.wrap[ 1 ], TEXTURE_WRAPPING );
30680 }
30681 if ( data.format !== undefined ) texture.format = data.format;
30682 if ( data.type !== undefined ) texture.type = data.type;
30683 if ( data.encoding !== undefined ) texture.encoding = data.encoding;
30684 if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER );
30685 if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER );
30686 if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;
30687 if ( data.flipY !== undefined ) texture.flipY = data.flipY;
30688 if ( data.premultiplyAlpha !== undefined ) texture.premultiplyAlpha = data.premultiplyAlpha;
30689 if ( data.unpackAlignment !== undefined ) texture.unpackAlignment = data.unpackAlignment;
30690 textures[ data.uuid ] = texture;
30691 }
30692 }
30693 return textures;
30694 },
30695 parseObject: function ( data, geometries, materials ) {
30696 let object;
30697 function getGeometry( name ) {
30698 if ( geometries[ name ] === undefined ) {
30699 console.warn( 'THREE.ObjectLoader: Undefined geometry', name );
30700 }
30701 return geometries[ name ];
30702 }
30703 function getMaterial( name ) {
30704 if ( name === undefined ) return undefined;
30705 if ( Array.isArray( name ) ) {
30706 const array = [];
30707 for ( let i = 0, l = name.length; i < l; i ++ ) {
30708 const uuid = name[ i ];
30709 if ( materials[ uuid ] === undefined ) {
30710 console.warn( 'THREE.ObjectLoader: Undefined material', uuid );
30711 }
30712 array.push( materials[ uuid ] );
30713 }
30714 return array;
30715 }
30716 if ( materials[ name ] === undefined ) {
30717 console.warn( 'THREE.ObjectLoader: Undefined material', name );
30718 }
30719 return materials[ name ];
30720 }
30721 let geometry, material;
30722 switch ( data.type ) {
30723 case 'Scene':
30724 object = new Scene();
30725 if ( data.background !== undefined ) {
30726 if ( Number.isInteger( data.background ) ) {
30727 object.background = new Color( data.background );
30728 }
30729 }
30730 if ( data.fog !== undefined ) {
30731 if ( data.fog.type === 'Fog' ) {
30732 object.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );
30733 } else if ( data.fog.type === 'FogExp2' ) {
30734 object.fog = new FogExp2( data.fog.color, data.fog.density );
30735 }
30736 }
30737 break;
30738 case 'PerspectiveCamera':
30739 object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );
30740 if ( data.focus !== undefined ) object.focus = data.focus;
30741 if ( data.zoom !== undefined ) object.zoom = data.zoom;
30742 if ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;
30743 if ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;
30744 if ( data.view !== undefined ) object.view = Object.assign( {}, data.view );
30745 break;
30746 case 'OrthographicCamera':
30747 object = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );
30748 if ( data.zoom !== undefined ) object.zoom = data.zoom;
30749 if ( data.view !== undefined ) object.view = Object.assign( {}, data.view );
30750 break;
30751 case 'AmbientLight':
30752 object = new AmbientLight( data.color, data.intensity );
30753 break;
30754 case 'DirectionalLight':
30755 object = new DirectionalLight( data.color, data.intensity );
30756 break;
30757 case 'PointLight':
30758 object = new PointLight( data.color, data.intensity, data.distance, data.decay );
30759 break;
30760 case 'RectAreaLight':
30761 object = new RectAreaLight( data.color, data.intensity, data.width, data.height );
30762 break;
30763 case 'SpotLight':
30764 object = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );
30765 break;
30766 case 'HemisphereLight':
30767 object = new HemisphereLight( data.color, data.groundColor, data.intensity );
30768 break;
30769 case 'LightProbe':
30770 object = new LightProbe().fromJSON( data );
30771 break;
30772 case 'SkinnedMesh':
30773 console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.' );
30774 case 'Mesh':
30775 geometry = getGeometry( data.geometry );
30776 material = getMaterial( data.material );
30777 object = new Mesh( geometry, material );
30778 break;
30779 case 'InstancedMesh':
30780 geometry = getGeometry( data.geometry );
30781 material = getMaterial( data.material );
30782 const count = data.count;
30783 const instanceMatrix = data.instanceMatrix;
30784 object = new InstancedMesh( geometry, material, count );
30785 object.instanceMatrix = new BufferAttribute( new Float32Array( instanceMatrix.array ), 16 );
30786 break;
30787 case 'LOD':
30788 object = new LOD();
30789 break;
30790 case 'Line':
30791 object = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );
30792 break;
30793 case 'LineLoop':
30794 object = new LineLoop( getGeometry( data.geometry ), getMaterial( data.material ) );
30795 break;
30796 case 'LineSegments':
30797 object = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );
30798 break;
30799 case 'PointCloud':
30800 case 'Points':
30801 object = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );
30802 break;
30803 case 'Sprite':
30804 object = new Sprite( getMaterial( data.material ) );
30805 break;
30806 case 'Group':
30807 object = new Group();
30808 break;
30809 default:
30810 object = new Object3D();
30811 }
30812 object.uuid = data.uuid;
30813 if ( data.name !== undefined ) object.name = data.name;
30814 if ( data.matrix !== undefined ) {
30815 object.matrix.fromArray( data.matrix );
30816 if ( data.matrixAutoUpdate !== undefined ) object.matrixAutoUpdate = data.matrixAutoUpdate;
30817 if ( object.matrixAutoUpdate ) object.matrix.decompose( object.position, object.quaternion, object.scale );
30818 } else {
30819 if ( data.position !== undefined ) object.position.fromArray( data.position );
30820 if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );
30821 if ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );
30822 if ( data.scale !== undefined ) object.scale.fromArray( data.scale );
30823 }
30824 if ( data.castShadow !== undefined ) object.castShadow = data.castShadow;
30825 if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;
30826 if ( data.shadow ) {
30827 if ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;
30828 if ( data.shadow.normalBias !== undefined ) object.shadow.normalBias = data.shadow.normalBias;
30829 if ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;
30830 if ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );
30831 if ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );
30832 }
30833 if ( data.visible !== undefined ) object.visible = data.visible;
30834 if ( data.frustumCulled !== undefined ) object.frustumCulled = data.frustumCulled;
30835 if ( data.renderOrder !== undefined ) object.renderOrder = data.renderOrder;
30836 if ( data.userData !== undefined ) object.userData = data.userData;
30837 if ( data.layers !== undefined ) object.layers.mask = data.layers;
30838 if ( data.children !== undefined ) {
30839 const children = data.children;
30840 for ( let i = 0; i < children.length; i ++ ) {
30841 object.add( this.parseObject( children[ i ], geometries, materials ) );
30842 }
30843 }
30844 if ( data.type === 'LOD' ) {
30845 if ( data.autoUpdate !== undefined ) object.autoUpdate = data.autoUpdate;
30846 const levels = data.levels;
30847 for ( let l = 0; l < levels.length; l ++ ) {
30848 const level = levels[ l ];
30849 const child = object.getObjectByProperty( 'uuid', level.object );
30850 if ( child !== undefined ) {
30851 object.addLevel( child, level.distance );
30852 }
30853 }
30854 }
30855 return object;
30856 }
30857 } );
30858 const TEXTURE_MAPPING = {
30859 UVMapping: UVMapping,
30860 CubeReflectionMapping: CubeReflectionMapping,
30861 CubeRefractionMapping: CubeRefractionMapping,
30862 EquirectangularReflectionMapping: EquirectangularReflectionMapping,
30863 EquirectangularRefractionMapping: EquirectangularRefractionMapping,
30864 CubeUVReflectionMapping: CubeUVReflectionMapping,
30865 CubeUVRefractionMapping: CubeUVRefractionMapping
30866 };
30867 const TEXTURE_WRAPPING = {
30868 RepeatWrapping: RepeatWrapping,
30869 ClampToEdgeWrapping: ClampToEdgeWrapping,
30870 MirroredRepeatWrapping: MirroredRepeatWrapping
30871 };
30872 const TEXTURE_FILTER = {
30873 NearestFilter: NearestFilter,
30874 NearestMipmapNearestFilter: NearestMipmapNearestFilter,
30875 NearestMipmapLinearFilter: NearestMipmapLinearFilter,
30876 LinearFilter: LinearFilter,
30877 LinearMipmapNearestFilter: LinearMipmapNearestFilter,
30878 LinearMipmapLinearFilter: LinearMipmapLinearFilter
30879 };
30880 function ImageBitmapLoader( manager ) {
30881 if ( typeof createImageBitmap === 'undefined' ) {
30882 console.warn( 'THREE.ImageBitmapLoader: createImageBitmap() not supported.' );
30883 }
30884 if ( typeof fetch === 'undefined' ) {
30885 console.warn( 'THREE.ImageBitmapLoader: fetch() not supported.' );
30886 }
30887 Loader.call( this, manager );
30888 this.options = { premultiplyAlpha: 'none' };
30889 }
30890 ImageBitmapLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
30891 constructor: ImageBitmapLoader,
30892 isImageBitmapLoader: true,
30893 setOptions: function setOptions( options ) {
30894 this.options = options;
30895 return this;
30896 },
30897 load: function ( url, onLoad, onProgress, onError ) {
30898 if ( url === undefined ) url = '';
30899 if ( this.path !== undefined ) url = this.path + url;
30900 url = this.manager.resolveURL( url );
30901 const scope = this;
30902 const cached = Cache.get( url );
30903 if ( cached !== undefined ) {
30904 scope.manager.itemStart( url );
30905 setTimeout( function () {
30906 if ( onLoad ) onLoad( cached );
30907 scope.manager.itemEnd( url );
30908 }, 0 );
30909 return cached;
30910 }
30911 fetch( url ).then( function ( res ) {
30912 return res.blob();
30913 } ).then( function ( blob ) {
30914 return createImageBitmap( blob, scope.options );
30915 } ).then( function ( imageBitmap ) {
30916 Cache.add( url, imageBitmap );
30917 if ( onLoad ) onLoad( imageBitmap );
30918 scope.manager.itemEnd( url );
30919 } ).catch( function ( e ) {
30920 if ( onError ) onError( e );
30921 scope.manager.itemError( url );
30922 scope.manager.itemEnd( url );
30923 } );
30924 scope.manager.itemStart( url );
30925 }
30926 } );
30927 function ShapePath() {
30928 this.type = 'ShapePath';
30929 this.color = new Color();
30930 this.subPaths = [];
30931 this.currentPath = null;
30932 }
30933 Object.assign( ShapePath.prototype, {
30934 moveTo: function ( x, y ) {
30935 this.currentPath = new Path();
30936 this.subPaths.push( this.currentPath );
30937 this.currentPath.moveTo( x, y );
30938 return this;
30939 },
30940 lineTo: function ( x, y ) {
30941 this.currentPath.lineTo( x, y );
30942 return this;
30943 },
30944 quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {
30945 this.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );
30946 return this;
30947 },
30948 bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {
30949 this.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );
30950 return this;
30951 },
30952 splineThru: function ( pts ) {
30953 this.currentPath.splineThru( pts );
30954 return this;
30955 },
30956 toShapes: function ( isCCW, noHoles ) {
30957 function toShapesNoHoles( inSubpaths ) {
30958 const shapes = [];
30959 for ( let i = 0, l = inSubpaths.length; i < l; i ++ ) {
30960 const tmpPath = inSubpaths[ i ];
30961 const tmpShape = new Shape();
30962 tmpShape.curves = tmpPath.curves;
30963 shapes.push( tmpShape );
30964 }
30965 return shapes;
30966 }
30967 function isPointInsidePolygon( inPt, inPolygon ) {
30968 const polyLen = inPolygon.length;
30969 let inside = false;
30970 for ( let p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {
30971 let edgeLowPt = inPolygon[ p ];
30972 let edgeHighPt = inPolygon[ q ];
30973 let edgeDx = edgeHighPt.x - edgeLowPt.x;
30974 let edgeDy = edgeHighPt.y - edgeLowPt.y;
30975 if ( Math.abs( edgeDy ) > Number.EPSILON ) {
30976 if ( edgeDy < 0 ) {
30977 edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;
30978 edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;
30979 }
30980 if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue;
30981 if ( inPt.y === edgeLowPt.y ) {
30982 if ( inPt.x === edgeLowPt.x ) return true;
30983 } else {
30984 const perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );
30985 if ( perpEdge === 0 ) return true;
30986 if ( perpEdge < 0 ) continue;
30987 inside = ! inside;
30988 }
30989 } else {
30990 if ( inPt.y !== edgeLowPt.y ) continue;
30991 if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||
30992 ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true;
30993 }
30994 }
30995 return inside;
30996 }
30997 const isClockWise = ShapeUtils.isClockWise;
30998 const subPaths = this.subPaths;
30999 if ( subPaths.length === 0 ) return [];
31000 if ( noHoles === true ) return toShapesNoHoles( subPaths );
31001 let solid, tmpPath, tmpShape;
31002 const shapes = [];
31003 if ( subPaths.length === 1 ) {
31004 tmpPath = subPaths[ 0 ];
31005 tmpShape = new Shape();
31006 tmpShape.curves = tmpPath.curves;
31007 shapes.push( tmpShape );
31008 return shapes;
31009 }
31010 let holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );
31011 holesFirst = isCCW ? ! holesFirst : holesFirst;
31012 const betterShapeHoles = [];
31013 const newShapes = [];
31014 let newShapeHoles = [];
31015 let mainIdx = 0;
31016 let tmpPoints;
31017 newShapes[ mainIdx ] = undefined;
31018 newShapeHoles[ mainIdx ] = [];
31019 for ( let i = 0, l = subPaths.length; i < l; i ++ ) {
31020 tmpPath = subPaths[ i ];
31021 tmpPoints = tmpPath.getPoints();
31022 solid = isClockWise( tmpPoints );
31023 solid = isCCW ? ! solid : solid;
31024 if ( solid ) {
31025 if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++;
31026 newShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };
31027 newShapes[ mainIdx ].s.curves = tmpPath.curves;
31028 if ( holesFirst ) mainIdx ++;
31029 newShapeHoles[ mainIdx ] = [];
31030 } else {
31031 newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );
31032 }
31033 }
31034 if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths );
31035 if ( newShapes.length > 1 ) {
31036 let ambiguous = false;
31037 const toChange = [];
31038 for ( let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {
31039 betterShapeHoles[ sIdx ] = [];
31040 }
31041 for ( let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {
31042 const sho = newShapeHoles[ sIdx ];
31043 for ( let hIdx = 0; hIdx < sho.length; hIdx ++ ) {
31044 const ho = sho[ hIdx ];
31045 let hole_unassigned = true;
31046 for ( let s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {
31047 if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {
31048 if ( sIdx !== s2Idx ) toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );
31049 if ( hole_unassigned ) {
31050 hole_unassigned = false;
31051 betterShapeHoles[ s2Idx ].push( ho );
31052 } else {
31053 ambiguous = true;
31054 }
31055 }
31056 }
31057 if ( hole_unassigned ) {
31058 betterShapeHoles[ sIdx ].push( ho );
31059 }
31060 }
31061 }
31062 if ( toChange.length > 0 ) {
31063 if ( ! ambiguous ) newShapeHoles = betterShapeHoles;
31064 }
31065 }
31066 let tmpHoles;
31067 for ( let i = 0, il = newShapes.length; i < il; i ++ ) {
31068 tmpShape = newShapes[ i ].s;
31069 shapes.push( tmpShape );
31070 tmpHoles = newShapeHoles[ i ];
31071 for ( let j = 0, jl = tmpHoles.length; j < jl; j ++ ) {
31072 tmpShape.holes.push( tmpHoles[ j ].h );
31073 }
31074 }
31075 return shapes;
31076 }
31077 } );
31078 function Font( data ) {
31079 this.type = 'Font';
31080 this.data = data;
31081 }
31082 Object.assign( Font.prototype, {
31083 isFont: true,
31084 generateShapes: function ( text, size ) {
31085 if ( size === undefined ) size = 100;
31086 const shapes = [];
31087 const paths = createPaths( text, size, this.data );
31088 for ( let p = 0, pl = paths.length; p < pl; p ++ ) {
31089 Array.prototype.push.apply( shapes, paths[ p ].toShapes() );
31090 }
31091 return shapes;
31092 }
31093 } );
31094 function createPaths( text, size, data ) {
31095 const chars = Array.from ? Array.from( text ) : String( text ).split( '' );
31096 const scale = size / data.resolution;
31097 const line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;
31098 const paths = [];
31099 let offsetX = 0, offsetY = 0;
31100 for ( let i = 0; i < chars.length; i ++ ) {
31101 const char = chars[ i ];
31102 if ( char === '\n' ) {
31103 offsetX = 0;
31104 offsetY -= line_height;
31105 } else {
31106 const ret = createPath( char, scale, offsetX, offsetY, data );
31107 offsetX += ret.offsetX;
31108 paths.push( ret.path );
31109 }
31110 }
31111 return paths;
31112 }
31113 function createPath( char, scale, offsetX, offsetY, data ) {
31114 const glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
31115 if ( ! glyph ) {
31116 console.error( 'THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.' );
31117 return;
31118 }
31119 const path = new ShapePath();
31120 let x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2;
31121 if ( glyph.o ) {
31122 const outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
31123 for ( let i = 0, l = outline.length; i < l; ) {
31124 const action = outline[ i ++ ];
31125 switch ( action ) {
31126 case 'm':
31127 x = outline[ i ++ ] * scale + offsetX;
31128 y = outline[ i ++ ] * scale + offsetY;
31129 path.moveTo( x, y );
31130 break;
31131 case 'l':
31132 x = outline[ i ++ ] * scale + offsetX;
31133 y = outline[ i ++ ] * scale + offsetY;
31134 path.lineTo( x, y );
31135 break;
31136 case 'q':
31137 cpx = outline[ i ++ ] * scale + offsetX;
31138 cpy = outline[ i ++ ] * scale + offsetY;
31139 cpx1 = outline[ i ++ ] * scale + offsetX;
31140 cpy1 = outline[ i ++ ] * scale + offsetY;
31141 path.quadraticCurveTo( cpx1, cpy1, cpx, cpy );
31142 break;
31143 case 'b':
31144 cpx = outline[ i ++ ] * scale + offsetX;
31145 cpy = outline[ i ++ ] * scale + offsetY;
31146 cpx1 = outline[ i ++ ] * scale + offsetX;
31147 cpy1 = outline[ i ++ ] * scale + offsetY;
31148 cpx2 = outline[ i ++ ] * scale + offsetX;
31149 cpy2 = outline[ i ++ ] * scale + offsetY;
31150 path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );
31151 break;
31152 }
31153 }
31154 }
31155 return { offsetX: glyph.ha * scale, path: path };
31156 }
31157 function FontLoader( manager ) {
31158 Loader.call( this, manager );
31159 }
31160 FontLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
31161 constructor: FontLoader,
31162 load: function ( url, onLoad, onProgress, onError ) {
31163 const scope = this;
31164 const loader = new FileLoader( this.manager );
31165 loader.setPath( this.path );
31166 loader.setRequestHeader( this.requestHeader );
31167 loader.load( url, function ( text ) {
31168 let json;
31169 try {
31170 json = JSON.parse( text );
31171 } catch ( e ) {
31172 console.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );
31173 json = JSON.parse( text.substring( 65, text.length - 2 ) );
31174 }
31175 const font = scope.parse( json );
31176 if ( onLoad ) onLoad( font );
31177 }, onProgress, onError );
31178 },
31179 parse: function ( json ) {
31180 return new Font( json );
31181 }
31182 } );
31183 let _context;
31184 const AudioContext = {
31185 getContext: function () {
31186 if ( _context === undefined ) {
31187 _context = new ( window.AudioContext || window.webkitAudioContext )();
31188 }
31189 return _context;
31190 },
31191 setContext: function ( value ) {
31192 _context = value;
31193 }
31194 };
31195 function AudioLoader( manager ) {
31196 Loader.call( this, manager );
31197 }
31198 AudioLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
31199 constructor: AudioLoader,
31200 load: function ( url, onLoad, onProgress, onError ) {
31201 const scope = this;
31202 const loader = new FileLoader( scope.manager );
31203 loader.setResponseType( 'arraybuffer' );
31204 loader.setPath( scope.path );
31205 loader.setRequestHeader( scope.requestHeader );
31206 loader.load( url, function ( buffer ) {
31207 try {
31208 const bufferCopy = buffer.slice( 0 );
31209 const context = AudioContext.getContext();
31210 context.decodeAudioData( bufferCopy, function ( audioBuffer ) {
31211 onLoad( audioBuffer );
31212 } );
31213 } catch ( e ) {
31214 if ( onError ) {
31215 onError( e );
31216 } else {
31217 console.error( e );
31218 }
31219 scope.manager.itemError( url );
31220 }
31221 }, onProgress, onError );
31222 }
31223 } );
31224 function HemisphereLightProbe( skyColor, groundColor, intensity ) {
31225 LightProbe.call( this, undefined, intensity );
31226 const color1 = new Color().set( skyColor );
31227 const color2 = new Color().set( groundColor );
31228 const sky = new Vector3( color1.r, color1.g, color1.b );
31229 const ground = new Vector3( color2.r, color2.g, color2.b );
31230 const c0 = Math.sqrt( Math.PI );
31231 const c1 = c0 * Math.sqrt( 0.75 );
31232 this.sh.coefficients[ 0 ].copy( sky ).add( ground ).multiplyScalar( c0 );
31233 this.sh.coefficients[ 1 ].copy( sky ).sub( ground ).multiplyScalar( c1 );
31234 }
31235 HemisphereLightProbe.prototype = Object.assign( Object.create( LightProbe.prototype ), {
31236 constructor: HemisphereLightProbe,
31237 isHemisphereLightProbe: true,
31238 copy: function ( source ) {
31239 LightProbe.prototype.copy.call( this, source );
31240 return this;
31241 },
31242 toJSON: function ( meta ) {
31243 const data = LightProbe.prototype.toJSON.call( this, meta );
31244 return data;
31245 }
31246 } );
31247 function AmbientLightProbe( color, intensity ) {
31248 LightProbe.call( this, undefined, intensity );
31249 const color1 = new Color().set( color );
31250 this.sh.coefficients[ 0 ].set( color1.r, color1.g, color1.b ).multiplyScalar( 2 * Math.sqrt( Math.PI ) );
31251 }
31252 AmbientLightProbe.prototype = Object.assign( Object.create( LightProbe.prototype ), {
31253 constructor: AmbientLightProbe,
31254 isAmbientLightProbe: true,
31255 copy: function ( source ) {
31256 LightProbe.prototype.copy.call( this, source );
31257 return this;
31258 },
31259 toJSON: function ( meta ) {
31260 const data = LightProbe.prototype.toJSON.call( this, meta );
31261 return data;
31262 }
31263 } );
31264 const _eyeRight = new Matrix4();
31265 const _eyeLeft = new Matrix4();
31266 function StereoCamera() {
31267 this.type = 'StereoCamera';
31268 this.aspect = 1;
31269 this.eyeSep = 0.064;
31270 this.cameraL = new PerspectiveCamera();
31271 this.cameraL.layers.enable( 1 );
31272 this.cameraL.matrixAutoUpdate = false;
31273 this.cameraR = new PerspectiveCamera();
31274 this.cameraR.layers.enable( 2 );
31275 this.cameraR.matrixAutoUpdate = false;
31276 this._cache = {
31277 focus: null,
31278 fov: null,
31279 aspect: null,
31280 near: null,
31281 far: null,
31282 zoom: null,
31283 eyeSep: null
31284 };
31285 }
31286 Object.assign( StereoCamera.prototype, {
31287 update: function ( camera ) {
31288 const cache = this._cache;
31289 const needsUpdate = cache.focus !== camera.focus || cache.fov !== camera.fov ||
31290 cache.aspect !== camera.aspect * this.aspect || cache.near !== camera.near ||
31291 cache.far !== camera.far || cache.zoom !== camera.zoom || cache.eyeSep !== this.eyeSep;
31292 if ( needsUpdate ) {
31293 cache.focus = camera.focus;
31294 cache.fov = camera.fov;
31295 cache.aspect = camera.aspect * this.aspect;
31296 cache.near = camera.near;
31297 cache.far = camera.far;
31298 cache.zoom = camera.zoom;
31299 cache.eyeSep = this.eyeSep;
31300 const projectionMatrix = camera.projectionMatrix.clone();
31301 const eyeSepHalf = cache.eyeSep / 2;
31302 const eyeSepOnProjection = eyeSepHalf * cache.near / cache.focus;
31303 const ymax = ( cache.near * Math.tan( MathUtils.DEG2RAD * cache.fov * 0.5 ) ) / cache.zoom;
31304 let xmin, xmax;
31305 _eyeLeft.elements[ 12 ] = - eyeSepHalf;
31306 _eyeRight.elements[ 12 ] = eyeSepHalf;
31307 xmin = - ymax * cache.aspect + eyeSepOnProjection;
31308 xmax = ymax * cache.aspect + eyeSepOnProjection;
31309 projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin );
31310 projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
31311 this.cameraL.projectionMatrix.copy( projectionMatrix );
31312 xmin = - ymax * cache.aspect - eyeSepOnProjection;
31313 xmax = ymax * cache.aspect - eyeSepOnProjection;
31314 projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin );
31315 projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
31316 this.cameraR.projectionMatrix.copy( projectionMatrix );
31317 }
31318 this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeLeft );
31319 this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeRight );
31320 }
31321 } );
31322 class Clock {
31323 constructor( autoStart ) {
31324 this.autoStart = ( autoStart !== undefined ) ? autoStart : true;
31325 this.startTime = 0;
31326 this.oldTime = 0;
31327 this.elapsedTime = 0;
31328 this.running = false;
31329 }
31330 start() {
31331 this.startTime = ( typeof performance === 'undefined' ? Date : performance ).now();
31332 this.oldTime = this.startTime;
31333 this.elapsedTime = 0;
31334 this.running = true;
31335 }
31336 stop() {
31337 this.getElapsedTime();
31338 this.running = false;
31339 this.autoStart = false;
31340 }
31341 getElapsedTime() {
31342 this.getDelta();
31343 return this.elapsedTime;
31344 }
31345 getDelta() {
31346 let diff = 0;
31347 if ( this.autoStart && ! this.running ) {
31348 this.start();
31349 return 0;
31350 }
31351 if ( this.running ) {
31352 const newTime = ( typeof performance === 'undefined' ? Date : performance ).now();
31353 diff = ( newTime - this.oldTime ) / 1000;
31354 this.oldTime = newTime;
31355 this.elapsedTime += diff;
31356 }
31357 return diff;
31358 }
31359 }
31360 const _position$2 = new Vector3();
31361 const _quaternion$3 = new Quaternion();
31362 const _scale$1 = new Vector3();
31363 const _orientation = new Vector3();
31364 class AudioListener extends Object3D {
31365 constructor() {
31366 super();
31367 this.type = 'AudioListener';
31368 this.context = AudioContext.getContext();
31369 this.gain = this.context.createGain();
31370 this.gain.connect( this.context.destination );
31371 this.filter = null;
31372 this.timeDelta = 0;
31373 this._clock = new Clock();
31374 }
31375 getInput() {
31376 return this.gain;
31377 }
31378 removeFilter() {
31379 if ( this.filter !== null ) {
31380 this.gain.disconnect( this.filter );
31381 this.filter.disconnect( this.context.destination );
31382 this.gain.connect( this.context.destination );
31383 this.filter = null;
31384 }
31385 return this;
31386 }
31387 getFilter() {
31388 return this.filter;
31389 }
31390 setFilter( value ) {
31391 if ( this.filter !== null ) {
31392 this.gain.disconnect( this.filter );
31393 this.filter.disconnect( this.context.destination );
31394 } else {
31395 this.gain.disconnect( this.context.destination );
31396 }
31397 this.filter = value;
31398 this.gain.connect( this.filter );
31399 this.filter.connect( this.context.destination );
31400 return this;
31401 }
31402 getMasterVolume() {
31403 return this.gain.gain.value;
31404 }
31405 setMasterVolume( value ) {
31406 this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );
31407 return this;
31408 }
31409 updateMatrixWorld( force ) {
31410 super.updateMatrixWorld( force );
31411 const listener = this.context.listener;
31412 const up = this.up;
31413 this.timeDelta = this._clock.getDelta();
31414 this.matrixWorld.decompose( _position$2, _quaternion$3, _scale$1 );
31415 _orientation.set( 0, 0, - 1 ).applyQuaternion( _quaternion$3 );
31416 if ( listener.positionX ) {
31417 const endTime = this.context.currentTime + this.timeDelta;
31418 listener.positionX.linearRampToValueAtTime( _position$2.x, endTime );
31419 listener.positionY.linearRampToValueAtTime( _position$2.y, endTime );
31420 listener.positionZ.linearRampToValueAtTime( _position$2.z, endTime );
31421 listener.forwardX.linearRampToValueAtTime( _orientation.x, endTime );
31422 listener.forwardY.linearRampToValueAtTime( _orientation.y, endTime );
31423 listener.forwardZ.linearRampToValueAtTime( _orientation.z, endTime );
31424 listener.upX.linearRampToValueAtTime( up.x, endTime );
31425 listener.upY.linearRampToValueAtTime( up.y, endTime );
31426 listener.upZ.linearRampToValueAtTime( up.z, endTime );
31427 } else {
31428 listener.setPosition( _position$2.x, _position$2.y, _position$2.z );
31429 listener.setOrientation( _orientation.x, _orientation.y, _orientation.z, up.x, up.y, up.z );
31430 }
31431 }
31432 }
31433 class Audio extends Object3D {
31434 constructor( listener ) {
31435 super();
31436 this.type = 'Audio';
31437 this.listener = listener;
31438 this.context = listener.context;
31439 this.gain = this.context.createGain();
31440 this.gain.connect( listener.getInput() );
31441 this.autoplay = false;
31442 this.buffer = null;
31443 this.detune = 0;
31444 this.loop = false;
31445 this.loopStart = 0;
31446 this.loopEnd = 0;
31447 this.offset = 0;
31448 this.duration = undefined;
31449 this.playbackRate = 1;
31450 this.isPlaying = false;
31451 this.hasPlaybackControl = true;
31452 this.source = null;
31453 this.sourceType = 'empty';
31454 this._startedAt = 0;
31455 this._progress = 0;
31456 this._connected = false;
31457 this.filters = [];
31458 }
31459 getOutput() {
31460 return this.gain;
31461 }
31462 setNodeSource( audioNode ) {
31463 this.hasPlaybackControl = false;
31464 this.sourceType = 'audioNode';
31465 this.source = audioNode;
31466 this.connect();
31467 return this;
31468 }
31469 setMediaElementSource( mediaElement ) {
31470 this.hasPlaybackControl = false;
31471 this.sourceType = 'mediaNode';
31472 this.source = this.context.createMediaElementSource( mediaElement );
31473 this.connect();
31474 return this;
31475 }
31476 setMediaStreamSource( mediaStream ) {
31477 this.hasPlaybackControl = false;
31478 this.sourceType = 'mediaStreamNode';
31479 this.source = this.context.createMediaStreamSource( mediaStream );
31480 this.connect();
31481 return this;
31482 }
31483 setBuffer( audioBuffer ) {
31484 this.buffer = audioBuffer;
31485 this.sourceType = 'buffer';
31486 if ( this.autoplay ) this.play();
31487 return this;
31488 }
31489 play( delay ) {
31490 if ( delay === undefined ) delay = 0;
31491 if ( this.isPlaying === true ) {
31492 console.warn( 'THREE.Audio: Audio is already playing.' );
31493 return;
31494 }
31495 if ( this.hasPlaybackControl === false ) {
31496 console.warn( 'THREE.Audio: this Audio has no playback control.' );
31497 return;
31498 }
31499 this._startedAt = this.context.currentTime + delay;
31500 const source = this.context.createBufferSource();
31501 source.buffer = this.buffer;
31502 source.loop = this.loop;
31503 source.loopStart = this.loopStart;
31504 source.loopEnd = this.loopEnd;
31505 source.onended = this.onEnded.bind( this );
31506 source.start( this._startedAt, this._progress + this.offset, this.duration );
31507 this.isPlaying = true;
31508 this.source = source;
31509 this.setDetune( this.detune );
31510 this.setPlaybackRate( this.playbackRate );
31511 return this.connect();
31512 }
31513 pause() {
31514 if ( this.hasPlaybackControl === false ) {
31515 console.warn( 'THREE.Audio: this Audio has no playback control.' );
31516 return;
31517 }
31518 if ( this.isPlaying === true ) {
31519 this._progress += Math.max( this.context.currentTime - this._startedAt, 0 ) * this.playbackRate;
31520 if ( this.loop === true ) {
31521 this._progress = this._progress % ( this.duration || this.buffer.duration );
31522 }
31523 this.source.stop();
31524 this.source.onended = null;
31525 this.isPlaying = false;
31526 }
31527 return this;
31528 }
31529 stop() {
31530 if ( this.hasPlaybackControl === false ) {
31531 console.warn( 'THREE.Audio: this Audio has no playback control.' );
31532 return;
31533 }
31534 this._progress = 0;
31535 this.source.stop();
31536 this.source.onended = null;
31537 this.isPlaying = false;
31538 return this;
31539 }
31540 connect() {
31541 if ( this.filters.length > 0 ) {
31542 this.source.connect( this.filters[ 0 ] );
31543 for ( let i = 1, l = this.filters.length; i < l; i ++ ) {
31544 this.filters[ i - 1 ].connect( this.filters[ i ] );
31545 }
31546 this.filters[ this.filters.length - 1 ].connect( this.getOutput() );
31547 } else {
31548 this.source.connect( this.getOutput() );
31549 }
31550 this._connected = true;
31551 return this;
31552 }
31553 disconnect() {
31554 if ( this.filters.length > 0 ) {
31555 this.source.disconnect( this.filters[ 0 ] );
31556 for ( let i = 1, l = this.filters.length; i < l; i ++ ) {
31557 this.filters[ i - 1 ].disconnect( this.filters[ i ] );
31558 }
31559 this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );
31560 } else {
31561 this.source.disconnect( this.getOutput() );
31562 }
31563 this._connected = false;
31564 return this;
31565 }
31566 getFilters() {
31567 return this.filters;
31568 }
31569 setFilters( value ) {
31570 if ( ! value ) value = [];
31571 if ( this._connected === true ) {
31572 this.disconnect();
31573 this.filters = value;
31574 this.connect();
31575 } else {
31576 this.filters = value;
31577 }
31578 return this;
31579 }
31580 setDetune( value ) {
31581 this.detune = value;
31582 if ( this.source.detune === undefined ) return;
31583 if ( this.isPlaying === true ) {
31584 this.source.detune.setTargetAtTime( this.detune, this.context.currentTime, 0.01 );
31585 }
31586 return this;
31587 }
31588 getDetune() {
31589 return this.detune;
31590 }
31591 getFilter() {
31592 return this.getFilters()[ 0 ];
31593 }
31594 setFilter( filter ) {
31595 return this.setFilters( filter ? [ filter ] : [] );
31596 }
31597 setPlaybackRate( value ) {
31598 if ( this.hasPlaybackControl === false ) {
31599 console.warn( 'THREE.Audio: this Audio has no playback control.' );
31600 return;
31601 }
31602 this.playbackRate = value;
31603 if ( this.isPlaying === true ) {
31604 this.source.playbackRate.setTargetAtTime( this.playbackRate, this.context.currentTime, 0.01 );
31605 }
31606 return this;
31607 }
31608 getPlaybackRate() {
31609 return this.playbackRate;
31610 }
31611 onEnded() {
31612 this.isPlaying = false;
31613 }
31614 getLoop() {
31615 if ( this.hasPlaybackControl === false ) {
31616 console.warn( 'THREE.Audio: this Audio has no playback control.' );
31617 return false;
31618 }
31619 return this.loop;
31620 }
31621 setLoop( value ) {
31622 if ( this.hasPlaybackControl === false ) {
31623 console.warn( 'THREE.Audio: this Audio has no playback control.' );
31624 return;
31625 }
31626 this.loop = value;
31627 if ( this.isPlaying === true ) {
31628 this.source.loop = this.loop;
31629 }
31630 return this;
31631 }
31632 setLoopStart( value ) {
31633 this.loopStart = value;
31634 return this;
31635 }
31636 setLoopEnd( value ) {
31637 this.loopEnd = value;
31638 return this;
31639 }
31640 getVolume() {
31641 return this.gain.gain.value;
31642 }
31643 setVolume( value ) {
31644 this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );
31645 return this;
31646 }
31647 }
31648 const _position$3 = new Vector3();
31649 const _quaternion$4 = new Quaternion();
31650 const _scale$2 = new Vector3();
31651 const _orientation$1 = new Vector3();
31652 class PositionalAudio extends Audio {
31653 constructor( listener ) {
31654 super( listener );
31655 this.panner = this.context.createPanner();
31656 this.panner.panningModel = 'HRTF';
31657 this.panner.connect( this.gain );
31658 }
31659 getOutput() {
31660 return this.panner;
31661 }
31662 getRefDistance() {
31663 return this.panner.refDistance;
31664 }
31665 setRefDistance( value ) {
31666 this.panner.refDistance = value;
31667 return this;
31668 }
31669 getRolloffFactor() {
31670 return this.panner.rolloffFactor;
31671 }
31672 setRolloffFactor( value ) {
31673 this.panner.rolloffFactor = value;
31674 return this;
31675 }
31676 getDistanceModel() {
31677 return this.panner.distanceModel;
31678 }
31679 setDistanceModel( value ) {
31680 this.panner.distanceModel = value;
31681 return this;
31682 }
31683 getMaxDistance() {
31684 return this.panner.maxDistance;
31685 }
31686 setMaxDistance( value ) {
31687 this.panner.maxDistance = value;
31688 return this;
31689 }
31690 setDirectionalCone( coneInnerAngle, coneOuterAngle, coneOuterGain ) {
31691 this.panner.coneInnerAngle = coneInnerAngle;
31692 this.panner.coneOuterAngle = coneOuterAngle;
31693 this.panner.coneOuterGain = coneOuterGain;
31694 return this;
31695 }
31696 updateMatrixWorld( force ) {
31697 super.updateMatrixWorld( force );
31698 if ( this.hasPlaybackControl === true && this.isPlaying === false ) return;
31699 this.matrixWorld.decompose( _position$3, _quaternion$4, _scale$2 );
31700 _orientation$1.set( 0, 0, 1 ).applyQuaternion( _quaternion$4 );
31701 const panner = this.panner;
31702 if ( panner.positionX ) {
31703 const endTime = this.context.currentTime + this.listener.timeDelta;
31704 panner.positionX.linearRampToValueAtTime( _position$3.x, endTime );
31705 panner.positionY.linearRampToValueAtTime( _position$3.y, endTime );
31706 panner.positionZ.linearRampToValueAtTime( _position$3.z, endTime );
31707 panner.orientationX.linearRampToValueAtTime( _orientation$1.x, endTime );
31708 panner.orientationY.linearRampToValueAtTime( _orientation$1.y, endTime );
31709 panner.orientationZ.linearRampToValueAtTime( _orientation$1.z, endTime );
31710 } else {
31711 panner.setPosition( _position$3.x, _position$3.y, _position$3.z );
31712 panner.setOrientation( _orientation$1.x, _orientation$1.y, _orientation$1.z );
31713 }
31714 }
31715 }
31716 class AudioAnalyser {
31717 constructor( audio, fftSize ) {
31718 this.analyser = audio.context.createAnalyser();
31719 this.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;
31720 this.data = new Uint8Array( this.analyser.frequencyBinCount );
31721 audio.getOutput().connect( this.analyser );
31722 }
31723 getFrequencyData() {
31724 this.analyser.getByteFrequencyData( this.data );
31725 return this.data;
31726 }
31727 getAverageFrequency() {
31728 let value = 0;
31729 const data = this.getFrequencyData();
31730 for ( let i = 0; i < data.length; i ++ ) {
31731 value += data[ i ];
31732 }
31733 return value / data.length;
31734 }
31735 }
31736 function PropertyMixer( binding, typeName, valueSize ) {
31737 this.binding = binding;
31738 this.valueSize = valueSize;
31739 let mixFunction,
31740 mixFunctionAdditive,
31741 setIdentity;
31742 switch ( typeName ) {
31743 case 'quaternion':
31744 mixFunction = this._slerp;
31745 mixFunctionAdditive = this._slerpAdditive;
31746 setIdentity = this._setAdditiveIdentityQuaternion;
31747 this.buffer = new Float64Array( valueSize * 6 );
31748 this._workIndex = 5;
31749 break;
31750 case 'string':
31751 case 'bool':
31752 mixFunction = this._select;
31753 mixFunctionAdditive = this._select;
31754 setIdentity = this._setAdditiveIdentityOther;
31755 this.buffer = new Array( valueSize * 5 );
31756 break;
31757 default:
31758 mixFunction = this._lerp;
31759 mixFunctionAdditive = this._lerpAdditive;
31760 setIdentity = this._setAdditiveIdentityNumeric;
31761 this.buffer = new Float64Array( valueSize * 5 );
31762 }
31763 this._mixBufferRegion = mixFunction;
31764 this._mixBufferRegionAdditive = mixFunctionAdditive;
31765 this._setIdentity = setIdentity;
31766 this._origIndex = 3;
31767 this._addIndex = 4;
31768 this.cumulativeWeight = 0;
31769 this.cumulativeWeightAdditive = 0;
31770 this.useCount = 0;
31771 this.referenceCount = 0;
31772 }
31773 Object.assign( PropertyMixer.prototype, {
31774 accumulate: function ( accuIndex, weight ) {
31775 const buffer = this.buffer,
31776 stride = this.valueSize,
31777 offset = accuIndex * stride + stride;
31778 let currentWeight = this.cumulativeWeight;
31779 if ( currentWeight === 0 ) {
31780 for ( let i = 0; i !== stride; ++ i ) {
31781 buffer[ offset + i ] = buffer[ i ];
31782 }
31783 currentWeight = weight;
31784 } else {
31785 currentWeight += weight;
31786 const mix = weight / currentWeight;
31787 this._mixBufferRegion( buffer, offset, 0, mix, stride );
31788 }
31789 this.cumulativeWeight = currentWeight;
31790 },
31791 accumulateAdditive: function ( weight ) {
31792 const buffer = this.buffer,
31793 stride = this.valueSize,
31794 offset = stride * this._addIndex;
31795 if ( this.cumulativeWeightAdditive === 0 ) {
31796 this._setIdentity();
31797 }
31798 this._mixBufferRegionAdditive( buffer, offset, 0, weight, stride );
31799 this.cumulativeWeightAdditive += weight;
31800 },
31801 apply: function ( accuIndex ) {
31802 const stride = this.valueSize,
31803 buffer = this.buffer,
31804 offset = accuIndex * stride + stride,
31805 weight = this.cumulativeWeight,
31806 weightAdditive = this.cumulativeWeightAdditive,
31807 binding = this.binding;
31808 this.cumulativeWeight = 0;
31809 this.cumulativeWeightAdditive = 0;
31810 if ( weight < 1 ) {
31811 const originalValueOffset = stride * this._origIndex;
31812 this._mixBufferRegion(
31813 buffer, offset, originalValueOffset, 1 - weight, stride );
31814 }
31815 if ( weightAdditive > 0 ) {
31816 this._mixBufferRegionAdditive( buffer, offset, this._addIndex * stride, 1, stride );
31817 }
31818 for ( let i = stride, e = stride + stride; i !== e; ++ i ) {
31819 if ( buffer[ i ] !== buffer[ i + stride ] ) {
31820 binding.setValue( buffer, offset );
31821 break;
31822 }
31823 }
31824 },
31825 saveOriginalState: function () {
31826 const binding = this.binding;
31827 const buffer = this.buffer,
31828 stride = this.valueSize,
31829 originalValueOffset = stride * this._origIndex;
31830 binding.getValue( buffer, originalValueOffset );
31831 for ( let i = stride, e = originalValueOffset; i !== e; ++ i ) {
31832 buffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];
31833 }
31834 this._setIdentity();
31835 this.cumulativeWeight = 0;
31836 this.cumulativeWeightAdditive = 0;
31837 },
31838 restoreOriginalState: function () {
31839 const originalValueOffset = this.valueSize * 3;
31840 this.binding.setValue( this.buffer, originalValueOffset );
31841 },
31842 _setAdditiveIdentityNumeric: function () {
31843 const startIndex = this._addIndex * this.valueSize;
31844 const endIndex = startIndex + this.valueSize;
31845 for ( let i = startIndex; i < endIndex; i ++ ) {
31846 this.buffer[ i ] = 0;
31847 }
31848 },
31849 _setAdditiveIdentityQuaternion: function () {
31850 this._setAdditiveIdentityNumeric();
31851 this.buffer[ this._addIndex * this.valueSize + 3 ] = 1;
31852 },
31853 _setAdditiveIdentityOther: function () {
31854 const startIndex = this._origIndex * this.valueSize;
31855 const targetIndex = this._addIndex * this.valueSize;
31856 for ( let i = 0; i < this.valueSize; i ++ ) {
31857 this.buffer[ targetIndex + i ] = this.buffer[ startIndex + i ];
31858 }
31859 },
31860 _select: function ( buffer, dstOffset, srcOffset, t, stride ) {
31861 if ( t >= 0.5 ) {
31862 for ( let i = 0; i !== stride; ++ i ) {
31863 buffer[ dstOffset + i ] = buffer[ srcOffset + i ];
31864 }
31865 }
31866 },
31867 _slerp: function ( buffer, dstOffset, srcOffset, t ) {
31868 Quaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t );
31869 },
31870 _slerpAdditive: function ( buffer, dstOffset, srcOffset, t, stride ) {
31871 const workOffset = this._workIndex * stride;
31872 Quaternion.multiplyQuaternionsFlat( buffer, workOffset, buffer, dstOffset, buffer, srcOffset );
31873 Quaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t );
31874 },
31875 _lerp: function ( buffer, dstOffset, srcOffset, t, stride ) {
31876 const s = 1 - t;
31877 for ( let i = 0; i !== stride; ++ i ) {
31878 const j = dstOffset + i;
31879 buffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;
31880 }
31881 },
31882 _lerpAdditive: function ( buffer, dstOffset, srcOffset, t, stride ) {
31883 for ( let i = 0; i !== stride; ++ i ) {
31884 const j = dstOffset + i;
31885 buffer[ j ] = buffer[ j ] + buffer[ srcOffset + i ] * t;
31886 }
31887 }
31888 } );
31889 const _RESERVED_CHARS_RE = '\\[\\]\\.:\\/';
31890 const _reservedRe = new RegExp( '[' + _RESERVED_CHARS_RE + ']', 'g' );
31891 const _wordChar = '[^' + _RESERVED_CHARS_RE + ']';
31892 const _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace( '\\.', '' ) + ']';
31893 const _directoryRe = /((?:WC+[\/:])*)/.source.replace( 'WC', _wordChar );
31894 const _nodeRe = /(WCOD+)?/.source.replace( 'WCOD', _wordCharOrDot );
31895 const _objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace( 'WC', _wordChar );
31896 const _propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace( 'WC', _wordChar );
31897 const _trackRe = new RegExp( ''
31898 + '^'
31899 + _directoryRe
31900 + _nodeRe
31901 + _objectRe
31902 + _propertyRe
31903 + '$'
31904 );
31905 const _supportedObjectNames = [ 'material', 'materials', 'bones' ];
31906 function Composite( targetGroup, path, optionalParsedPath ) {
31907 const parsedPath = optionalParsedPath || PropertyBinding.parseTrackName( path );
31908 this._targetGroup = targetGroup;
31909 this._bindings = targetGroup.subscribe_( path, parsedPath );
31910 }
31911 Object.assign( Composite.prototype, {
31912 getValue: function ( array, offset ) {
31913 this.bind();
31914 const firstValidIndex = this._targetGroup.nCachedObjects_,
31915 binding = this._bindings[ firstValidIndex ];
31916 if ( binding !== undefined ) binding.getValue( array, offset );
31917 },
31918 setValue: function ( array, offset ) {
31919 const bindings = this._bindings;
31920 for ( let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {
31921 bindings[ i ].setValue( array, offset );
31922 }
31923 },
31924 bind: function () {
31925 const bindings = this._bindings;
31926 for ( let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {
31927 bindings[ i ].bind();
31928 }
31929 },
31930 unbind: function () {
31931 const bindings = this._bindings;
31932 for ( let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {
31933 bindings[ i ].unbind();
31934 }
31935 }
31936 } );
31937 function PropertyBinding( rootNode, path, parsedPath ) {
31938 this.path = path;
31939 this.parsedPath = parsedPath || PropertyBinding.parseTrackName( path );
31940 this.node = PropertyBinding.findNode( rootNode, this.parsedPath.nodeName ) || rootNode;
31941 this.rootNode = rootNode;
31942 }
31943 Object.assign( PropertyBinding, {
31944 Composite: Composite,
31945 create: function ( root, path, parsedPath ) {
31946 if ( ! ( root && root.isAnimationObjectGroup ) ) {
31947 return new PropertyBinding( root, path, parsedPath );
31948 } else {
31949 return new PropertyBinding.Composite( root, path, parsedPath );
31950 }
31951 },
31952 sanitizeNodeName: function ( name ) {
31953 return name.replace( /\s/g, '_' ).replace( _reservedRe, '' );
31954 },
31955 parseTrackName: function ( trackName ) {
31956 const matches = _trackRe.exec( trackName );
31957 if ( ! matches ) {
31958 throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName );
31959 }
31960 const results = {
31961 nodeName: matches[ 2 ],
31962 objectName: matches[ 3 ],
31963 objectIndex: matches[ 4 ],
31964 propertyName: matches[ 5 ],
31965 propertyIndex: matches[ 6 ]
31966 };
31967 const lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' );
31968 if ( lastDot !== undefined && lastDot !== - 1 ) {
31969 const objectName = results.nodeName.substring( lastDot + 1 );
31970 if ( _supportedObjectNames.indexOf( objectName ) !== - 1 ) {
31971 results.nodeName = results.nodeName.substring( 0, lastDot );
31972 results.objectName = objectName;
31973 }
31974 }
31975 if ( results.propertyName === null || results.propertyName.length === 0 ) {
31976 throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName );
31977 }
31978 return results;
31979 },
31980 findNode: function ( root, nodeName ) {
31981 if ( ! nodeName || nodeName === "" || nodeName === "." || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) {
31982 return root;
31983 }
31984 if ( root.skeleton ) {
31985 const bone = root.skeleton.getBoneByName( nodeName );
31986 if ( bone !== undefined ) {
31987 return bone;
31988 }
31989 }
31990 if ( root.children ) {
31991 const searchNodeSubtree = function ( children ) {
31992 for ( let i = 0; i < children.length; i ++ ) {
31993 const childNode = children[ i ];
31994 if ( childNode.name === nodeName || childNode.uuid === nodeName ) {
31995 return childNode;
31996 }
31997 const result = searchNodeSubtree( childNode.children );
31998 if ( result ) return result;
31999 }
32000 return null;
32001 };
32002 const subTreeNode = searchNodeSubtree( root.children );
32003 if ( subTreeNode ) {
32004 return subTreeNode;
32005 }
32006 }
32007 return null;
32008 }
32009 } );
32010 Object.assign( PropertyBinding.prototype, {
32011 _getValue_unavailable: function () {},
32012 _setValue_unavailable: function () {},
32013 BindingType: {
32014 Direct: 0,
32015 EntireArray: 1,
32016 ArrayElement: 2,
32017 HasFromToArray: 3
32018 },
32019 Versioning: {
32020 None: 0,
32021 NeedsUpdate: 1,
32022 MatrixWorldNeedsUpdate: 2
32023 },
32024 GetterByBindingType: [
32025 function getValue_direct( buffer, offset ) {
32026 buffer[ offset ] = this.node[ this.propertyName ];
32027 },
32028 function getValue_array( buffer, offset ) {
32029 const source = this.resolvedProperty;
32030 for ( let i = 0, n = source.length; i !== n; ++ i ) {
32031 buffer[ offset ++ ] = source[ i ];
32032 }
32033 },
32034 function getValue_arrayElement( buffer, offset ) {
32035 buffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];
32036 },
32037 function getValue_toArray( buffer, offset ) {
32038 this.resolvedProperty.toArray( buffer, offset );
32039 }
32040 ],
32041 SetterByBindingTypeAndVersioning: [
32042 [
32043 function setValue_direct( buffer, offset ) {
32044 this.targetObject[ this.propertyName ] = buffer[ offset ];
32045 },
32046 function setValue_direct_setNeedsUpdate( buffer, offset ) {
32047 this.targetObject[ this.propertyName ] = buffer[ offset ];
32048 this.targetObject.needsUpdate = true;
32049 },
32050 function setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {
32051 this.targetObject[ this.propertyName ] = buffer[ offset ];
32052 this.targetObject.matrixWorldNeedsUpdate = true;
32053 }
32054 ], [
32055 function setValue_array( buffer, offset ) {
32056 const dest = this.resolvedProperty;
32057 for ( let i = 0, n = dest.length; i !== n; ++ i ) {
32058 dest[ i ] = buffer[ offset ++ ];
32059 }
32060 },
32061 function setValue_array_setNeedsUpdate( buffer, offset ) {
32062 const dest = this.resolvedProperty;
32063 for ( let i = 0, n = dest.length; i !== n; ++ i ) {
32064 dest[ i ] = buffer[ offset ++ ];
32065 }
32066 this.targetObject.needsUpdate = true;
32067 },
32068 function setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {
32069 const dest = this.resolvedProperty;
32070 for ( let i = 0, n = dest.length; i !== n; ++ i ) {
32071 dest[ i ] = buffer[ offset ++ ];
32072 }
32073 this.targetObject.matrixWorldNeedsUpdate = true;
32074 }
32075 ], [
32076 function setValue_arrayElement( buffer, offset ) {
32077 this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
32078 },
32079 function setValue_arrayElement_setNeedsUpdate( buffer, offset ) {
32080 this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
32081 this.targetObject.needsUpdate = true;
32082 },
32083 function setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {
32084 this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
32085 this.targetObject.matrixWorldNeedsUpdate = true;
32086 }
32087 ], [
32088 function setValue_fromArray( buffer, offset ) {
32089 this.resolvedProperty.fromArray( buffer, offset );
32090 },
32091 function setValue_fromArray_setNeedsUpdate( buffer, offset ) {
32092 this.resolvedProperty.fromArray( buffer, offset );
32093 this.targetObject.needsUpdate = true;
32094 },
32095 function setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {
32096 this.resolvedProperty.fromArray( buffer, offset );
32097 this.targetObject.matrixWorldNeedsUpdate = true;
32098 }
32099 ]
32100 ],
32101 getValue: function getValue_unbound( targetArray, offset ) {
32102 this.bind();
32103 this.getValue( targetArray, offset );
32104 },
32105 setValue: function getValue_unbound( sourceArray, offset ) {
32106 this.bind();
32107 this.setValue( sourceArray, offset );
32108 },
32109 bind: function () {
32110 let targetObject = this.node;
32111 const parsedPath = this.parsedPath;
32112 const objectName = parsedPath.objectName;
32113 const propertyName = parsedPath.propertyName;
32114 let propertyIndex = parsedPath.propertyIndex;
32115 if ( ! targetObject ) {
32116 targetObject = PropertyBinding.findNode( this.rootNode, parsedPath.nodeName ) || this.rootNode;
32117 this.node = targetObject;
32118 }
32119 this.getValue = this._getValue_unavailable;
32120 this.setValue = this._setValue_unavailable;
32121 if ( ! targetObject ) {
32122 console.error( 'THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.' );
32123 return;
32124 }
32125 if ( objectName ) {
32126 let objectIndex = parsedPath.objectIndex;
32127 switch ( objectName ) {
32128 case 'materials':
32129 if ( ! targetObject.material ) {
32130 console.error( 'THREE.PropertyBinding: Can not bind to material as node does not have a material.', this );
32131 return;
32132 }
32133 if ( ! targetObject.material.materials ) {
32134 console.error( 'THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.', this );
32135 return;
32136 }
32137 targetObject = targetObject.material.materials;
32138 break;
32139 case 'bones':
32140 if ( ! targetObject.skeleton ) {
32141 console.error( 'THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.', this );
32142 return;
32143 }
32144 targetObject = targetObject.skeleton.bones;
32145 for ( let i = 0; i < targetObject.length; i ++ ) {
32146 if ( targetObject[ i ].name === objectIndex ) {
32147 objectIndex = i;
32148 break;
32149 }
32150 }
32151 break;
32152 default:
32153 if ( targetObject[ objectName ] === undefined ) {
32154 console.error( 'THREE.PropertyBinding: Can not bind to objectName of node undefined.', this );
32155 return;
32156 }
32157 targetObject = targetObject[ objectName ];
32158 }
32159 if ( objectIndex !== undefined ) {
32160 if ( targetObject[ objectIndex ] === undefined ) {
32161 console.error( 'THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject );
32162 return;
32163 }
32164 targetObject = targetObject[ objectIndex ];
32165 }
32166 }
32167 const nodeProperty = targetObject[ propertyName ];
32168 if ( nodeProperty === undefined ) {
32169 const nodeName = parsedPath.nodeName;
32170 console.error( 'THREE.PropertyBinding: Trying to update property for track: ' + nodeName +
32171 '.' + propertyName + ' but it wasn\'t found.', targetObject );
32172 return;
32173 }
32174 let versioning = this.Versioning.None;
32175 this.targetObject = targetObject;
32176 if ( targetObject.needsUpdate !== undefined ) {
32177 versioning = this.Versioning.NeedsUpdate;
32178 } else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) {
32179 versioning = this.Versioning.MatrixWorldNeedsUpdate;
32180 }
32181 let bindingType = this.BindingType.Direct;
32182 if ( propertyIndex !== undefined ) {
32183 if ( propertyName === "morphTargetInfluences" ) {
32184 if ( ! targetObject.geometry ) {
32185 console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.', this );
32186 return;
32187 }
32188 if ( targetObject.geometry.isBufferGeometry ) {
32189 if ( ! targetObject.geometry.morphAttributes ) {
32190 console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this );
32191 return;
32192 }
32193 if ( targetObject.morphTargetDictionary[ propertyIndex ] !== undefined ) {
32194 propertyIndex = targetObject.morphTargetDictionary[ propertyIndex ];
32195 }
32196 } else {
32197 console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences on THREE.Geometry. Use THREE.BufferGeometry instead.', this );
32198 return;
32199 }
32200 }
32201 bindingType = this.BindingType.ArrayElement;
32202 this.resolvedProperty = nodeProperty;
32203 this.propertyIndex = propertyIndex;
32204 } else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {
32205 bindingType = this.BindingType.HasFromToArray;
32206 this.resolvedProperty = nodeProperty;
32207 } else if ( Array.isArray( nodeProperty ) ) {
32208 bindingType = this.BindingType.EntireArray;
32209 this.resolvedProperty = nodeProperty;
32210 } else {
32211 this.propertyName = propertyName;
32212 }
32213 this.getValue = this.GetterByBindingType[ bindingType ];
32214 this.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];
32215 },
32216 unbind: function () {
32217 this.node = null;
32218 this.getValue = this._getValue_unbound;
32219 this.setValue = this._setValue_unbound;
32220 }
32221 } );
32222 Object.assign( PropertyBinding.prototype, {
32223 _getValue_unbound: PropertyBinding.prototype.getValue,
32224 _setValue_unbound: PropertyBinding.prototype.setValue,
32225 } );
32226 function AnimationObjectGroup() {
32227 this.uuid = MathUtils.generateUUID();
32228 this._objects = Array.prototype.slice.call( arguments );
32229 this.nCachedObjects_ = 0;
32230 const indices = {};
32231 this._indicesByUUID = indices;
32232 for ( let i = 0, n = arguments.length; i !== n; ++ i ) {
32233 indices[ arguments[ i ].uuid ] = i;
32234 }
32235 this._paths = [];
32236 this._parsedPaths = [];
32237 this._bindings = [];
32238 this._bindingsIndicesByPath = {};
32239 const scope = this;
32240 this.stats = {
32241 objects: {
32242 get total() {
32243 return scope._objects.length;
32244 },
32245 get inUse() {
32246 return this.total - scope.nCachedObjects_;
32247 }
32248 },
32249 get bindingsPerObject() {
32250 return scope._bindings.length;
32251 }
32252 };
32253 }
32254 Object.assign( AnimationObjectGroup.prototype, {
32255 isAnimationObjectGroup: true,
32256 add: function () {
32257 const objects = this._objects,
32258 indicesByUUID = this._indicesByUUID,
32259 paths = this._paths,
32260 parsedPaths = this._parsedPaths,
32261 bindings = this._bindings,
32262 nBindings = bindings.length;
32263 let knownObject = undefined,
32264 nObjects = objects.length,
32265 nCachedObjects = this.nCachedObjects_;
32266 for ( let i = 0, n = arguments.length; i !== n; ++ i ) {
32267 const object = arguments[ i ],
32268 uuid = object.uuid;
32269 let index = indicesByUUID[ uuid ];
32270 if ( index === undefined ) {
32271 index = nObjects ++;
32272 indicesByUUID[ uuid ] = index;
32273 objects.push( object );
32274 for ( let j = 0, m = nBindings; j !== m; ++ j ) {
32275 bindings[ j ].push( new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ) );
32276 }
32277 } else if ( index < nCachedObjects ) {
32278 knownObject = objects[ index ];
32279 const firstActiveIndex = -- nCachedObjects,
32280 lastCachedObject = objects[ firstActiveIndex ];
32281 indicesByUUID[ lastCachedObject.uuid ] = index;
32282 objects[ index ] = lastCachedObject;
32283 indicesByUUID[ uuid ] = firstActiveIndex;
32284 objects[ firstActiveIndex ] = object;
32285 for ( let j = 0, m = nBindings; j !== m; ++ j ) {
32286 const bindingsForPath = bindings[ j ],
32287 lastCached = bindingsForPath[ firstActiveIndex ];
32288 let binding = bindingsForPath[ index ];
32289 bindingsForPath[ index ] = lastCached;
32290 if ( binding === undefined ) {
32291 binding = new PropertyBinding( object, paths[ j ], parsedPaths[ j ] );
32292 }
32293 bindingsForPath[ firstActiveIndex ] = binding;
32294 }
32295 } else if ( objects[ index ] !== knownObject ) {
32296 console.error( 'THREE.AnimationObjectGroup: Different objects with the same UUID ' +
32297 'detected. Clean the caches or recreate your infrastructure when reloading scenes.' );
32298 }
32299 }
32300 this.nCachedObjects_ = nCachedObjects;
32301 },
32302 remove: function () {
32303 const objects = this._objects,
32304 indicesByUUID = this._indicesByUUID,
32305 bindings = this._bindings,
32306 nBindings = bindings.length;
32307 let nCachedObjects = this.nCachedObjects_;
32308 for ( let i = 0, n = arguments.length; i !== n; ++ i ) {
32309 const object = arguments[ i ],
32310 uuid = object.uuid,
32311 index = indicesByUUID[ uuid ];
32312 if ( index !== undefined && index >= nCachedObjects ) {
32313 const lastCachedIndex = nCachedObjects ++,
32314 firstActiveObject = objects[ lastCachedIndex ];
32315 indicesByUUID[ firstActiveObject.uuid ] = index;
32316 objects[ index ] = firstActiveObject;
32317 indicesByUUID[ uuid ] = lastCachedIndex;
32318 objects[ lastCachedIndex ] = object;
32319 for ( let j = 0, m = nBindings; j !== m; ++ j ) {
32320 const bindingsForPath = bindings[ j ],
32321 firstActive = bindingsForPath[ lastCachedIndex ],
32322 binding = bindingsForPath[ index ];
32323 bindingsForPath[ index ] = firstActive;
32324 bindingsForPath[ lastCachedIndex ] = binding;
32325 }
32326 }
32327 }
32328 this.nCachedObjects_ = nCachedObjects;
32329 },
32330 uncache: function () {
32331 const objects = this._objects,
32332 indicesByUUID = this._indicesByUUID,
32333 bindings = this._bindings,
32334 nBindings = bindings.length;
32335 let nCachedObjects = this.nCachedObjects_,
32336 nObjects = objects.length;
32337 for ( let i = 0, n = arguments.length; i !== n; ++ i ) {
32338 const object = arguments[ i ],
32339 uuid = object.uuid,
32340 index = indicesByUUID[ uuid ];
32341 if ( index !== undefined ) {
32342 delete indicesByUUID[ uuid ];
32343 if ( index < nCachedObjects ) {
32344 const firstActiveIndex = -- nCachedObjects,
32345 lastCachedObject = objects[ firstActiveIndex ],
32346 lastIndex = -- nObjects,
32347 lastObject = objects[ lastIndex ];
32348 indicesByUUID[ lastCachedObject.uuid ] = index;
32349 objects[ index ] = lastCachedObject;
32350 indicesByUUID[ lastObject.uuid ] = firstActiveIndex;
32351 objects[ firstActiveIndex ] = lastObject;
32352 objects.pop();
32353 for ( let j = 0, m = nBindings; j !== m; ++ j ) {
32354 const bindingsForPath = bindings[ j ],
32355 lastCached = bindingsForPath[ firstActiveIndex ],
32356 last = bindingsForPath[ lastIndex ];
32357 bindingsForPath[ index ] = lastCached;
32358 bindingsForPath[ firstActiveIndex ] = last;
32359 bindingsForPath.pop();
32360 }
32361 } else {
32362 const lastIndex = -- nObjects,
32363 lastObject = objects[ lastIndex ];
32364 indicesByUUID[ lastObject.uuid ] = index;
32365 objects[ index ] = lastObject;
32366 objects.pop();
32367 for ( let j = 0, m = nBindings; j !== m; ++ j ) {
32368 const bindingsForPath = bindings[ j ];
32369 bindingsForPath[ index ] = bindingsForPath[ lastIndex ];
32370 bindingsForPath.pop();
32371 }
32372 }
32373 }
32374 }
32375 this.nCachedObjects_ = nCachedObjects;
32376 },
32377 subscribe_: function ( path, parsedPath ) {
32378 const indicesByPath = this._bindingsIndicesByPath;
32379 let index = indicesByPath[ path ];
32380 const bindings = this._bindings;
32381 if ( index !== undefined ) return bindings[ index ];
32382 const paths = this._paths,
32383 parsedPaths = this._parsedPaths,
32384 objects = this._objects,
32385 nObjects = objects.length,
32386 nCachedObjects = this.nCachedObjects_,
32387 bindingsForPath = new Array( nObjects );
32388 index = bindings.length;
32389 indicesByPath[ path ] = index;
32390 paths.push( path );
32391 parsedPaths.push( parsedPath );
32392 bindings.push( bindingsForPath );
32393 for ( let i = nCachedObjects, n = objects.length; i !== n; ++ i ) {
32394 const object = objects[ i ];
32395 bindingsForPath[ i ] = new PropertyBinding( object, path, parsedPath );
32396 }
32397 return bindingsForPath;
32398 },
32399 unsubscribe_: function ( path ) {
32400 const indicesByPath = this._bindingsIndicesByPath,
32401 index = indicesByPath[ path ];
32402 if ( index !== undefined ) {
32403 const paths = this._paths,
32404 parsedPaths = this._parsedPaths,
32405 bindings = this._bindings,
32406 lastBindingsIndex = bindings.length - 1,
32407 lastBindings = bindings[ lastBindingsIndex ],
32408 lastBindingsPath = path[ lastBindingsIndex ];
32409 indicesByPath[ lastBindingsPath ] = index;
32410 bindings[ index ] = lastBindings;
32411 bindings.pop();
32412 parsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];
32413 parsedPaths.pop();
32414 paths[ index ] = paths[ lastBindingsIndex ];
32415 paths.pop();
32416 }
32417 }
32418 } );
32419 class AnimationAction {
32420 constructor( mixer, clip, localRoot, blendMode ) {
32421 this._mixer = mixer;
32422 this._clip = clip;
32423 this._localRoot = localRoot || null;
32424 this.blendMode = blendMode || clip.blendMode;
32425 const tracks = clip.tracks,
32426 nTracks = tracks.length,
32427 interpolants = new Array( nTracks );
32428 const interpolantSettings = {
32429 endingStart: ZeroCurvatureEnding,
32430 endingEnd: ZeroCurvatureEnding
32431 };
32432 for ( let i = 0; i !== nTracks; ++ i ) {
32433 const interpolant = tracks[ i ].createInterpolant( null );
32434 interpolants[ i ] = interpolant;
32435 interpolant.settings = interpolantSettings;
32436 }
32437 this._interpolantSettings = interpolantSettings;
32438 this._interpolants = interpolants;
32439 this._propertyBindings = new Array( nTracks );
32440 this._cacheIndex = null;
32441 this._byClipCacheIndex = null;
32442 this._timeScaleInterpolant = null;
32443 this._weightInterpolant = null;
32444 this.loop = LoopRepeat;
32445 this._loopCount = - 1;
32446 this._startTime = null;
32447 this.time = 0;
32448 this.timeScale = 1;
32449 this._effectiveTimeScale = 1;
32450 this.weight = 1;
32451 this._effectiveWeight = 1;
32452 this.repetitions = Infinity;
32453 this.paused = false;
32454 this.enabled = true;
32455 this.clampWhenFinished = false;
32456 this.zeroSlopeAtStart = true;
32457 this.zeroSlopeAtEnd = true;
32458 }
32459 play() {
32460 this._mixer._activateAction( this );
32461 return this;
32462 }
32463 stop() {
32464 this._mixer._deactivateAction( this );
32465 return this.reset();
32466 }
32467 reset() {
32468 this.paused = false;
32469 this.enabled = true;
32470 this.time = 0;
32471 this._loopCount = - 1;
32472 this._startTime = null;
32473 return this.stopFading().stopWarping();
32474 }
32475 isRunning() {
32476 return this.enabled && ! this.paused && this.timeScale !== 0 &&
32477 this._startTime === null && this._mixer._isActiveAction( this );
32478 }
32479 isScheduled() {
32480 return this._mixer._isActiveAction( this );
32481 }
32482 startAt( time ) {
32483 this._startTime = time;
32484 return this;
32485 }
32486 setLoop( mode, repetitions ) {
32487 this.loop = mode;
32488 this.repetitions = repetitions;
32489 return this;
32490 }
32491 setEffectiveWeight( weight ) {
32492 this.weight = weight;
32493 this._effectiveWeight = this.enabled ? weight : 0;
32494 return this.stopFading();
32495 }
32496 getEffectiveWeight() {
32497 return this._effectiveWeight;
32498 }
32499 fadeIn( duration ) {
32500 return this._scheduleFading( duration, 0, 1 );
32501 }
32502 fadeOut( duration ) {
32503 return this._scheduleFading( duration, 1, 0 );
32504 }
32505 crossFadeFrom( fadeOutAction, duration, warp ) {
32506 fadeOutAction.fadeOut( duration );
32507 this.fadeIn( duration );
32508 if ( warp ) {
32509 const fadeInDuration = this._clip.duration,
32510 fadeOutDuration = fadeOutAction._clip.duration,
32511 startEndRatio = fadeOutDuration / fadeInDuration,
32512 endStartRatio = fadeInDuration / fadeOutDuration;
32513 fadeOutAction.warp( 1.0, startEndRatio, duration );
32514 this.warp( endStartRatio, 1.0, duration );
32515 }
32516 return this;
32517 }
32518 crossFadeTo( fadeInAction, duration, warp ) {
32519 return fadeInAction.crossFadeFrom( this, duration, warp );
32520 }
32521 stopFading() {
32522 const weightInterpolant = this._weightInterpolant;
32523 if ( weightInterpolant !== null ) {
32524 this._weightInterpolant = null;
32525 this._mixer._takeBackControlInterpolant( weightInterpolant );
32526 }
32527 return this;
32528 }
32529 setEffectiveTimeScale( timeScale ) {
32530 this.timeScale = timeScale;
32531 this._effectiveTimeScale = this.paused ? 0 : timeScale;
32532 return this.stopWarping();
32533 }
32534 getEffectiveTimeScale() {
32535 return this._effectiveTimeScale;
32536 }
32537 setDuration( duration ) {
32538 this.timeScale = this._clip.duration / duration;
32539 return this.stopWarping();
32540 }
32541 syncWith( action ) {
32542 this.time = action.time;
32543 this.timeScale = action.timeScale;
32544 return this.stopWarping();
32545 }
32546 halt( duration ) {
32547 return this.warp( this._effectiveTimeScale, 0, duration );
32548 }
32549 warp( startTimeScale, endTimeScale, duration ) {
32550 const mixer = this._mixer,
32551 now = mixer.time,
32552 timeScale = this.timeScale;
32553 let interpolant = this._timeScaleInterpolant;
32554 if ( interpolant === null ) {
32555 interpolant = mixer._lendControlInterpolant();
32556 this._timeScaleInterpolant = interpolant;
32557 }
32558 const times = interpolant.parameterPositions,
32559 values = interpolant.sampleValues;
32560 times[ 0 ] = now;
32561 times[ 1 ] = now + duration;
32562 values[ 0 ] = startTimeScale / timeScale;
32563 values[ 1 ] = endTimeScale / timeScale;
32564 return this;
32565 }
32566 stopWarping() {
32567 const timeScaleInterpolant = this._timeScaleInterpolant;
32568 if ( timeScaleInterpolant !== null ) {
32569 this._timeScaleInterpolant = null;
32570 this._mixer._takeBackControlInterpolant( timeScaleInterpolant );
32571 }
32572 return this;
32573 }
32574 getMixer() {
32575 return this._mixer;
32576 }
32577 getClip() {
32578 return this._clip;
32579 }
32580 getRoot() {
32581 return this._localRoot || this._mixer._root;
32582 }
32583 _update( time, deltaTime, timeDirection, accuIndex ) {
32584 if ( ! this.enabled ) {
32585 this._updateWeight( time );
32586 return;
32587 }
32588 const startTime = this._startTime;
32589 if ( startTime !== null ) {
32590 const timeRunning = ( time - startTime ) * timeDirection;
32591 if ( timeRunning < 0 || timeDirection === 0 ) {
32592 return;
32593 }
32594 this._startTime = null;
32595 deltaTime = timeDirection * timeRunning;
32596 }
32597 deltaTime *= this._updateTimeScale( time );
32598 const clipTime = this._updateTime( deltaTime );
32599 const weight = this._updateWeight( time );
32600 if ( weight > 0 ) {
32601 const interpolants = this._interpolants;
32602 const propertyMixers = this._propertyBindings;
32603 switch ( this.blendMode ) {
32604 case AdditiveAnimationBlendMode:
32605 for ( let j = 0, m = interpolants.length; j !== m; ++ j ) {
32606 interpolants[ j ].evaluate( clipTime );
32607 propertyMixers[ j ].accumulateAdditive( weight );
32608 }
32609 break;
32610 case NormalAnimationBlendMode:
32611 default:
32612 for ( let j = 0, m = interpolants.length; j !== m; ++ j ) {
32613 interpolants[ j ].evaluate( clipTime );
32614 propertyMixers[ j ].accumulate( accuIndex, weight );
32615 }
32616 }
32617 }
32618 }
32619 _updateWeight( time ) {
32620 let weight = 0;
32621 if ( this.enabled ) {
32622 weight = this.weight;
32623 const interpolant = this._weightInterpolant;
32624 if ( interpolant !== null ) {
32625 const interpolantValue = interpolant.evaluate( time )[ 0 ];
32626 weight *= interpolantValue;
32627 if ( time > interpolant.parameterPositions[ 1 ] ) {
32628 this.stopFading();
32629 if ( interpolantValue === 0 ) {
32630 this.enabled = false;
32631 }
32632 }
32633 }
32634 }
32635 this._effectiveWeight = weight;
32636 return weight;
32637 }
32638 _updateTimeScale( time ) {
32639 let timeScale = 0;
32640 if ( ! this.paused ) {
32641 timeScale = this.timeScale;
32642 const interpolant = this._timeScaleInterpolant;
32643 if ( interpolant !== null ) {
32644 const interpolantValue = interpolant.evaluate( time )[ 0 ];
32645 timeScale *= interpolantValue;
32646 if ( time > interpolant.parameterPositions[ 1 ] ) {
32647 this.stopWarping();
32648 if ( timeScale === 0 ) {
32649 this.paused = true;
32650 } else {
32651 this.timeScale = timeScale;
32652 }
32653 }
32654 }
32655 }
32656 this._effectiveTimeScale = timeScale;
32657 return timeScale;
32658 }
32659 _updateTime( deltaTime ) {
32660 const duration = this._clip.duration;
32661 const loop = this.loop;
32662 let time = this.time + deltaTime;
32663 let loopCount = this._loopCount;
32664 const pingPong = ( loop === LoopPingPong );
32665 if ( deltaTime === 0 ) {
32666 if ( loopCount === - 1 ) return time;
32667 return ( pingPong && ( loopCount & 1 ) === 1 ) ? duration - time : time;
32668 }
32669 if ( loop === LoopOnce ) {
32670 if ( loopCount === - 1 ) {
32671 this._loopCount = 0;
32672 this._setEndings( true, true, false );
32673 }
32674 handle_stop: {
32675 if ( time >= duration ) {
32676 time = duration;
32677 } else if ( time < 0 ) {
32678 time = 0;
32679 } else {
32680 this.time = time;
32681 break handle_stop;
32682 }
32683 if ( this.clampWhenFinished ) this.paused = true;
32684 else this.enabled = false;
32685 this.time = time;
32686 this._mixer.dispatchEvent( {
32687 type: 'finished', action: this,
32688 direction: deltaTime < 0 ? - 1 : 1
32689 } );
32690 }
32691 } else {
32692 if ( loopCount === - 1 ) {
32693 if ( deltaTime >= 0 ) {
32694 loopCount = 0;
32695 this._setEndings( true, this.repetitions === 0, pingPong );
32696 } else {
32697 this._setEndings( this.repetitions === 0, true, pingPong );
32698 }
32699 }
32700 if ( time >= duration || time < 0 ) {
32701 const loopDelta = Math.floor( time / duration );
32702 time -= duration * loopDelta;
32703 loopCount += Math.abs( loopDelta );
32704 const pending = this.repetitions - loopCount;
32705 if ( pending <= 0 ) {
32706 if ( this.clampWhenFinished ) this.paused = true;
32707 else this.enabled = false;
32708 time = deltaTime > 0 ? duration : 0;
32709 this.time = time;
32710 this._mixer.dispatchEvent( {
32711 type: 'finished', action: this,
32712 direction: deltaTime > 0 ? 1 : - 1
32713 } );
32714 } else {
32715 if ( pending === 1 ) {
32716 const atStart = deltaTime < 0;
32717 this._setEndings( atStart, ! atStart, pingPong );
32718 } else {
32719 this._setEndings( false, false, pingPong );
32720 }
32721 this._loopCount = loopCount;
32722 this.time = time;
32723 this._mixer.dispatchEvent( {
32724 type: 'loop', action: this, loopDelta: loopDelta
32725 } );
32726 }
32727 } else {
32728 this.time = time;
32729 }
32730 if ( pingPong && ( loopCount & 1 ) === 1 ) {
32731 return duration - time;
32732 }
32733 }
32734 return time;
32735 }
32736 _setEndings( atStart, atEnd, pingPong ) {
32737 const settings = this._interpolantSettings;
32738 if ( pingPong ) {
32739 settings.endingStart = ZeroSlopeEnding;
32740 settings.endingEnd = ZeroSlopeEnding;
32741 } else {
32742 if ( atStart ) {
32743 settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding;
32744 } else {
32745 settings.endingStart = WrapAroundEnding;
32746 }
32747 if ( atEnd ) {
32748 settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding;
32749 } else {
32750 settings.endingEnd = WrapAroundEnding;
32751 }
32752 }
32753 }
32754 _scheduleFading( duration, weightNow, weightThen ) {
32755 const mixer = this._mixer, now = mixer.time;
32756 let interpolant = this._weightInterpolant;
32757 if ( interpolant === null ) {
32758 interpolant = mixer._lendControlInterpolant();
32759 this._weightInterpolant = interpolant;
32760 }
32761 const times = interpolant.parameterPositions,
32762 values = interpolant.sampleValues;
32763 times[ 0 ] = now;
32764 values[ 0 ] = weightNow;
32765 times[ 1 ] = now + duration;
32766 values[ 1 ] = weightThen;
32767 return this;
32768 }
32769 }
32770 function AnimationMixer( root ) {
32771 this._root = root;
32772 this._initMemoryManager();
32773 this._accuIndex = 0;
32774 this.time = 0;
32775 this.timeScale = 1.0;
32776 }
32777 AnimationMixer.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
32778 constructor: AnimationMixer,
32779 _bindAction: function ( action, prototypeAction ) {
32780 const root = action._localRoot || this._root,
32781 tracks = action._clip.tracks,
32782 nTracks = tracks.length,
32783 bindings = action._propertyBindings,
32784 interpolants = action._interpolants,
32785 rootUuid = root.uuid,
32786 bindingsByRoot = this._bindingsByRootAndName;
32787 let bindingsByName = bindingsByRoot[ rootUuid ];
32788 if ( bindingsByName === undefined ) {
32789 bindingsByName = {};
32790 bindingsByRoot[ rootUuid ] = bindingsByName;
32791 }
32792 for ( let i = 0; i !== nTracks; ++ i ) {
32793 const track = tracks[ i ],
32794 trackName = track.name;
32795 let binding = bindingsByName[ trackName ];
32796 if ( binding !== undefined ) {
32797 bindings[ i ] = binding;
32798 } else {
32799 binding = bindings[ i ];
32800 if ( binding !== undefined ) {
32801 if ( binding._cacheIndex === null ) {
32802 ++ binding.referenceCount;
32803 this._addInactiveBinding( binding, rootUuid, trackName );
32804 }
32805 continue;
32806 }
32807 const path = prototypeAction && prototypeAction.
32808 _propertyBindings[ i ].binding.parsedPath;
32809 binding = new PropertyMixer(
32810 PropertyBinding.create( root, trackName, path ),
32811 track.ValueTypeName, track.getValueSize() );
32812 ++ binding.referenceCount;
32813 this._addInactiveBinding( binding, rootUuid, trackName );
32814 bindings[ i ] = binding;
32815 }
32816 interpolants[ i ].resultBuffer = binding.buffer;
32817 }
32818 },
32819 _activateAction: function ( action ) {
32820 if ( ! this._isActiveAction( action ) ) {
32821 if ( action._cacheIndex === null ) {
32822 const rootUuid = ( action._localRoot || this._root ).uuid,
32823 clipUuid = action._clip.uuid,
32824 actionsForClip = this._actionsByClip[ clipUuid ];
32825 this._bindAction( action,
32826 actionsForClip && actionsForClip.knownActions[ 0 ] );
32827 this._addInactiveAction( action, clipUuid, rootUuid );
32828 }
32829 const bindings = action._propertyBindings;
32830 for ( let i = 0, n = bindings.length; i !== n; ++ i ) {
32831 const binding = bindings[ i ];
32832 if ( binding.useCount ++ === 0 ) {
32833 this._lendBinding( binding );
32834 binding.saveOriginalState();
32835 }
32836 }
32837 this._lendAction( action );
32838 }
32839 },
32840 _deactivateAction: function ( action ) {
32841 if ( this._isActiveAction( action ) ) {
32842 const bindings = action._propertyBindings;
32843 for ( let i = 0, n = bindings.length; i !== n; ++ i ) {
32844 const binding = bindings[ i ];
32845 if ( -- binding.useCount === 0 ) {
32846 binding.restoreOriginalState();
32847 this._takeBackBinding( binding );
32848 }
32849 }
32850 this._takeBackAction( action );
32851 }
32852 },
32853 _initMemoryManager: function () {
32854 this._actions = [];
32855 this._nActiveActions = 0;
32856 this._actionsByClip = {};
32857 this._bindings = [];
32858 this._nActiveBindings = 0;
32859 this._bindingsByRootAndName = {};
32860 this._controlInterpolants = [];
32861 this._nActiveControlInterpolants = 0;
32862 const scope = this;
32863 this.stats = {
32864 actions: {
32865 get total() {
32866 return scope._actions.length;
32867 },
32868 get inUse() {
32869 return scope._nActiveActions;
32870 }
32871 },
32872 bindings: {
32873 get total() {
32874 return scope._bindings.length;
32875 },
32876 get inUse() {
32877 return scope._nActiveBindings;
32878 }
32879 },
32880 controlInterpolants: {
32881 get total() {
32882 return scope._controlInterpolants.length;
32883 },
32884 get inUse() {
32885 return scope._nActiveControlInterpolants;
32886 }
32887 }
32888 };
32889 },
32890 _isActiveAction: function ( action ) {
32891 const index = action._cacheIndex;
32892 return index !== null && index < this._nActiveActions;
32893 },
32894 _addInactiveAction: function ( action, clipUuid, rootUuid ) {
32895 const actions = this._actions,
32896 actionsByClip = this._actionsByClip;
32897 let actionsForClip = actionsByClip[ clipUuid ];
32898 if ( actionsForClip === undefined ) {
32899 actionsForClip = {
32900 knownActions: [ action ],
32901 actionByRoot: {}
32902 };
32903 action._byClipCacheIndex = 0;
32904 actionsByClip[ clipUuid ] = actionsForClip;
32905 } else {
32906 const knownActions = actionsForClip.knownActions;
32907 action._byClipCacheIndex = knownActions.length;
32908 knownActions.push( action );
32909 }
32910 action._cacheIndex = actions.length;
32911 actions.push( action );
32912 actionsForClip.actionByRoot[ rootUuid ] = action;
32913 },
32914 _removeInactiveAction: function ( action ) {
32915 const actions = this._actions,
32916 lastInactiveAction = actions[ actions.length - 1 ],
32917 cacheIndex = action._cacheIndex;
32918 lastInactiveAction._cacheIndex = cacheIndex;
32919 actions[ cacheIndex ] = lastInactiveAction;
32920 actions.pop();
32921 action._cacheIndex = null;
32922 const clipUuid = action._clip.uuid,
32923 actionsByClip = this._actionsByClip,
32924 actionsForClip = actionsByClip[ clipUuid ],
32925 knownActionsForClip = actionsForClip.knownActions,
32926 lastKnownAction =
32927 knownActionsForClip[ knownActionsForClip.length - 1 ],
32928 byClipCacheIndex = action._byClipCacheIndex;
32929 lastKnownAction._byClipCacheIndex = byClipCacheIndex;
32930 knownActionsForClip[ byClipCacheIndex ] = lastKnownAction;
32931 knownActionsForClip.pop();
32932 action._byClipCacheIndex = null;
32933 const actionByRoot = actionsForClip.actionByRoot,
32934 rootUuid = ( action._localRoot || this._root ).uuid;
32935 delete actionByRoot[ rootUuid ];
32936 if ( knownActionsForClip.length === 0 ) {
32937 delete actionsByClip[ clipUuid ];
32938 }
32939 this._removeInactiveBindingsForAction( action );
32940 },
32941 _removeInactiveBindingsForAction: function ( action ) {
32942 const bindings = action._propertyBindings;
32943 for ( let i = 0, n = bindings.length; i !== n; ++ i ) {
32944 const binding = bindings[ i ];
32945 if ( -- binding.referenceCount === 0 ) {
32946 this._removeInactiveBinding( binding );
32947 }
32948 }
32949 },
32950 _lendAction: function ( action ) {
32951 const actions = this._actions,
32952 prevIndex = action._cacheIndex,
32953 lastActiveIndex = this._nActiveActions ++,
32954 firstInactiveAction = actions[ lastActiveIndex ];
32955 action._cacheIndex = lastActiveIndex;
32956 actions[ lastActiveIndex ] = action;
32957 firstInactiveAction._cacheIndex = prevIndex;
32958 actions[ prevIndex ] = firstInactiveAction;
32959 },
32960 _takeBackAction: function ( action ) {
32961 const actions = this._actions,
32962 prevIndex = action._cacheIndex,
32963 firstInactiveIndex = -- this._nActiveActions,
32964 lastActiveAction = actions[ firstInactiveIndex ];
32965 action._cacheIndex = firstInactiveIndex;
32966 actions[ firstInactiveIndex ] = action;
32967 lastActiveAction._cacheIndex = prevIndex;
32968 actions[ prevIndex ] = lastActiveAction;
32969 },
32970 _addInactiveBinding: function ( binding, rootUuid, trackName ) {
32971 const bindingsByRoot = this._bindingsByRootAndName,
32972 bindings = this._bindings;
32973 let bindingByName = bindingsByRoot[ rootUuid ];
32974 if ( bindingByName === undefined ) {
32975 bindingByName = {};
32976 bindingsByRoot[ rootUuid ] = bindingByName;
32977 }
32978 bindingByName[ trackName ] = binding;
32979 binding._cacheIndex = bindings.length;
32980 bindings.push( binding );
32981 },
32982 _removeInactiveBinding: function ( binding ) {
32983 const bindings = this._bindings,
32984 propBinding = binding.binding,
32985 rootUuid = propBinding.rootNode.uuid,
32986 trackName = propBinding.path,
32987 bindingsByRoot = this._bindingsByRootAndName,
32988 bindingByName = bindingsByRoot[ rootUuid ],
32989 lastInactiveBinding = bindings[ bindings.length - 1 ],
32990 cacheIndex = binding._cacheIndex;
32991 lastInactiveBinding._cacheIndex = cacheIndex;
32992 bindings[ cacheIndex ] = lastInactiveBinding;
32993 bindings.pop();
32994 delete bindingByName[ trackName ];
32995 if ( Object.keys( bindingByName ).length === 0 ) {
32996 delete bindingsByRoot[ rootUuid ];
32997 }
32998 },
32999 _lendBinding: function ( binding ) {
33000 const bindings = this._bindings,
33001 prevIndex = binding._cacheIndex,
33002 lastActiveIndex = this._nActiveBindings ++,
33003 firstInactiveBinding = bindings[ lastActiveIndex ];
33004 binding._cacheIndex = lastActiveIndex;
33005 bindings[ lastActiveIndex ] = binding;
33006 firstInactiveBinding._cacheIndex = prevIndex;
33007 bindings[ prevIndex ] = firstInactiveBinding;
33008 },
33009 _takeBackBinding: function ( binding ) {
33010 const bindings = this._bindings,
33011 prevIndex = binding._cacheIndex,
33012 firstInactiveIndex = -- this._nActiveBindings,
33013 lastActiveBinding = bindings[ firstInactiveIndex ];
33014 binding._cacheIndex = firstInactiveIndex;
33015 bindings[ firstInactiveIndex ] = binding;
33016 lastActiveBinding._cacheIndex = prevIndex;
33017 bindings[ prevIndex ] = lastActiveBinding;
33018 },
33019 _lendControlInterpolant: function () {
33020 const interpolants = this._controlInterpolants,
33021 lastActiveIndex = this._nActiveControlInterpolants ++;
33022 let interpolant = interpolants[ lastActiveIndex ];
33023 if ( interpolant === undefined ) {
33024 interpolant = new LinearInterpolant(
33025 new Float32Array( 2 ), new Float32Array( 2 ),
33026 1, this._controlInterpolantsResultBuffer );
33027 interpolant.__cacheIndex = lastActiveIndex;
33028 interpolants[ lastActiveIndex ] = interpolant;
33029 }
33030 return interpolant;
33031 },
33032 _takeBackControlInterpolant: function ( interpolant ) {
33033 const interpolants = this._controlInterpolants,
33034 prevIndex = interpolant.__cacheIndex,
33035 firstInactiveIndex = -- this._nActiveControlInterpolants,
33036 lastActiveInterpolant = interpolants[ firstInactiveIndex ];
33037 interpolant.__cacheIndex = firstInactiveIndex;
33038 interpolants[ firstInactiveIndex ] = interpolant;
33039 lastActiveInterpolant.__cacheIndex = prevIndex;
33040 interpolants[ prevIndex ] = lastActiveInterpolant;
33041 },
33042 _controlInterpolantsResultBuffer: new Float32Array( 1 ),
33043 clipAction: function ( clip, optionalRoot, blendMode ) {
33044 const root = optionalRoot || this._root,
33045 rootUuid = root.uuid;
33046 let clipObject = typeof clip === 'string' ? AnimationClip.findByName( root, clip ) : clip;
33047 const clipUuid = clipObject !== null ? clipObject.uuid : clip;
33048 const actionsForClip = this._actionsByClip[ clipUuid ];
33049 let prototypeAction = null;
33050 if ( blendMode === undefined ) {
33051 if ( clipObject !== null ) {
33052 blendMode = clipObject.blendMode;
33053 } else {
33054 blendMode = NormalAnimationBlendMode;
33055 }
33056 }
33057 if ( actionsForClip !== undefined ) {
33058 const existingAction = actionsForClip.actionByRoot[ rootUuid ];
33059 if ( existingAction !== undefined && existingAction.blendMode === blendMode ) {
33060 return existingAction;
33061 }
33062 prototypeAction = actionsForClip.knownActions[ 0 ];
33063 if ( clipObject === null )
33064 clipObject = prototypeAction._clip;
33065 }
33066 if ( clipObject === null ) return null;
33067 const newAction = new AnimationAction( this, clipObject, optionalRoot, blendMode );
33068 this._bindAction( newAction, prototypeAction );
33069 this._addInactiveAction( newAction, clipUuid, rootUuid );
33070 return newAction;
33071 },
33072 existingAction: function ( clip, optionalRoot ) {
33073 const root = optionalRoot || this._root,
33074 rootUuid = root.uuid,
33075 clipObject = typeof clip === 'string' ?
33076 AnimationClip.findByName( root, clip ) : clip,
33077 clipUuid = clipObject ? clipObject.uuid : clip,
33078 actionsForClip = this._actionsByClip[ clipUuid ];
33079 if ( actionsForClip !== undefined ) {
33080 return actionsForClip.actionByRoot[ rootUuid ] || null;
33081 }
33082 return null;
33083 },
33084 stopAllAction: function () {
33085 const actions = this._actions,
33086 nActions = this._nActiveActions;
33087 for ( let i = nActions - 1; i >= 0; -- i ) {
33088 actions[ i ].stop();
33089 }
33090 return this;
33091 },
33092 update: function ( deltaTime ) {
33093 deltaTime *= this.timeScale;
33094 const actions = this._actions,
33095 nActions = this._nActiveActions,
33096 time = this.time += deltaTime,
33097 timeDirection = Math.sign( deltaTime ),
33098 accuIndex = this._accuIndex ^= 1;
33099 for ( let i = 0; i !== nActions; ++ i ) {
33100 const action = actions[ i ];
33101 action._update( time, deltaTime, timeDirection, accuIndex );
33102 }
33103 const bindings = this._bindings,
33104 nBindings = this._nActiveBindings;
33105 for ( let i = 0; i !== nBindings; ++ i ) {
33106 bindings[ i ].apply( accuIndex );
33107 }
33108 return this;
33109 },
33110 setTime: function ( timeInSeconds ) {
33111 this.time = 0;
33112 for ( let i = 0; i < this._actions.length; i ++ ) {
33113 this._actions[ i ].time = 0;
33114 }
33115 return this.update( timeInSeconds );
33116 },
33117 getRoot: function () {
33118 return this._root;
33119 },
33120 uncacheClip: function ( clip ) {
33121 const actions = this._actions,
33122 clipUuid = clip.uuid,
33123 actionsByClip = this._actionsByClip,
33124 actionsForClip = actionsByClip[ clipUuid ];
33125 if ( actionsForClip !== undefined ) {
33126 const actionsToRemove = actionsForClip.knownActions;
33127 for ( let i = 0, n = actionsToRemove.length; i !== n; ++ i ) {
33128 const action = actionsToRemove[ i ];
33129 this._deactivateAction( action );
33130 const cacheIndex = action._cacheIndex,
33131 lastInactiveAction = actions[ actions.length - 1 ];
33132 action._cacheIndex = null;
33133 action._byClipCacheIndex = null;
33134 lastInactiveAction._cacheIndex = cacheIndex;
33135 actions[ cacheIndex ] = lastInactiveAction;
33136 actions.pop();
33137 this._removeInactiveBindingsForAction( action );
33138 }
33139 delete actionsByClip[ clipUuid ];
33140 }
33141 },
33142 uncacheRoot: function ( root ) {
33143 const rootUuid = root.uuid,
33144 actionsByClip = this._actionsByClip;
33145 for ( const clipUuid in actionsByClip ) {
33146 const actionByRoot = actionsByClip[ clipUuid ].actionByRoot,
33147 action = actionByRoot[ rootUuid ];
33148 if ( action !== undefined ) {
33149 this._deactivateAction( action );
33150 this._removeInactiveAction( action );
33151 }
33152 }
33153 const bindingsByRoot = this._bindingsByRootAndName,
33154 bindingByName = bindingsByRoot[ rootUuid ];
33155 if ( bindingByName !== undefined ) {
33156 for ( const trackName in bindingByName ) {
33157 const binding = bindingByName[ trackName ];
33158 binding.restoreOriginalState();
33159 this._removeInactiveBinding( binding );
33160 }
33161 }
33162 },
33163 uncacheAction: function ( clip, optionalRoot ) {
33164 const action = this.existingAction( clip, optionalRoot );
33165 if ( action !== null ) {
33166 this._deactivateAction( action );
33167 this._removeInactiveAction( action );
33168 }
33169 }
33170 } );
33171 class Uniform {
33172 constructor( value ) {
33173 if ( typeof value === 'string' ) {
33174 console.warn( 'THREE.Uniform: Type parameter is no longer needed.' );
33175 value = arguments[ 1 ];
33176 }
33177 this.value = value;
33178 }
33179 clone() {
33180 return new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );
33181 }
33182 }
33183 function InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {
33184 InterleavedBuffer.call( this, array, stride );
33185 this.meshPerAttribute = meshPerAttribute || 1;
33186 }
33187 InstancedInterleavedBuffer.prototype = Object.assign( Object.create( InterleavedBuffer.prototype ), {
33188 constructor: InstancedInterleavedBuffer,
33189 isInstancedInterleavedBuffer: true,
33190 copy: function ( source ) {
33191 InterleavedBuffer.prototype.copy.call( this, source );
33192 this.meshPerAttribute = source.meshPerAttribute;
33193 return this;
33194 },
33195 clone: function ( data ) {
33196 const ib = InterleavedBuffer.prototype.clone.call( this, data );
33197 ib.meshPerAttribute = this.meshPerAttribute;
33198 return ib;
33199 },
33200 toJSON: function ( data ) {
33201 const json = InterleavedBuffer.prototype.toJSON.call( this, data );
33202 json.isInstancedInterleavedBuffer = true;
33203 json.meshPerAttribute = this.meshPerAttribute;
33204 return json;
33205 }
33206 } );
33207 function GLBufferAttribute( buffer, type, itemSize, elementSize, count ) {
33208 this.buffer = buffer;
33209 this.type = type;
33210 this.itemSize = itemSize;
33211 this.elementSize = elementSize;
33212 this.count = count;
33213 this.version = 0;
33214 }
33215 Object.defineProperty( GLBufferAttribute.prototype, 'needsUpdate', {
33216 set: function ( value ) {
33217 if ( value === true ) this.version ++;
33218 }
33219 } );
33220 Object.assign( GLBufferAttribute.prototype, {
33221 isGLBufferAttribute: true,
33222 setBuffer: function ( buffer ) {
33223 this.buffer = buffer;
33224 return this;
33225 },
33226 setType: function ( type, elementSize ) {
33227 this.type = type;
33228 this.elementSize = elementSize;
33229 return this;
33230 },
33231 setItemSize: function ( itemSize ) {
33232 this.itemSize = itemSize;
33233 return this;
33234 },
33235 setCount: function ( count ) {
33236 this.count = count;
33237 return this;
33238 },
33239 } );
33240 function Raycaster( origin, direction, near, far ) {
33241 this.ray = new Ray( origin, direction );
33242 this.near = near || 0;
33243 this.far = far || Infinity;
33244 this.camera = null;
33245 this.layers = new Layers();
33246 this.params = {
33247 Mesh: {},
33248 Line: { threshold: 1 },
33249 LOD: {},
33250 Points: { threshold: 1 },
33251 Sprite: {}
33252 };
33253 Object.defineProperties( this.params, {
33254 PointCloud: {
33255 get: function () {
33256 console.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );
33257 return this.Points;
33258 }
33259 }
33260 } );
33261 }
33262 function ascSort( a, b ) {
33263 return a.distance - b.distance;
33264 }
33265 function intersectObject( object, raycaster, intersects, recursive ) {
33266 if ( object.layers.test( raycaster.layers ) ) {
33267 object.raycast( raycaster, intersects );
33268 }
33269 if ( recursive === true ) {
33270 const children = object.children;
33271 for ( let i = 0, l = children.length; i < l; i ++ ) {
33272 intersectObject( children[ i ], raycaster, intersects, true );
33273 }
33274 }
33275 }
33276 Object.assign( Raycaster.prototype, {
33277 set: function ( origin, direction ) {
33278 this.ray.set( origin, direction );
33279 },
33280 setFromCamera: function ( coords, camera ) {
33281 if ( ( camera && camera.isPerspectiveCamera ) ) {
33282 this.ray.origin.setFromMatrixPosition( camera.matrixWorld );
33283 this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();
33284 this.camera = camera;
33285 } else if ( ( camera && camera.isOrthographicCamera ) ) {
33286 this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera );
33287 this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );
33288 this.camera = camera;
33289 } else {
33290 console.error( 'THREE.Raycaster: Unsupported camera type.' );
33291 }
33292 },
33293 intersectObject: function ( object, recursive, optionalTarget ) {
33294 const intersects = optionalTarget || [];
33295 intersectObject( object, this, intersects, recursive );
33296 intersects.sort( ascSort );
33297 return intersects;
33298 },
33299 intersectObjects: function ( objects, recursive, optionalTarget ) {
33300 const intersects = optionalTarget || [];
33301 if ( Array.isArray( objects ) === false ) {
33302 console.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );
33303 return intersects;
33304 }
33305 for ( let i = 0, l = objects.length; i < l; i ++ ) {
33306 intersectObject( objects[ i ], this, intersects, recursive );
33307 }
33308 intersects.sort( ascSort );
33309 return intersects;
33310 }
33311 } );
33312 class Spherical {
33313 constructor( radius = 1, phi = 0, theta = 0 ) {
33314 this.radius = radius;
33315 this.phi = phi;
33316 this.theta = theta;
33317 return this;
33318 }
33319 set( radius, phi, theta ) {
33320 this.radius = radius;
33321 this.phi = phi;
33322 this.theta = theta;
33323 return this;
33324 }
33325 clone() {
33326 return new this.constructor().copy( this );
33327 }
33328 copy( other ) {
33329 this.radius = other.radius;
33330 this.phi = other.phi;
33331 this.theta = other.theta;
33332 return this;
33333 }
33334 makeSafe() {
33335 const EPS = 0.000001;
33336 this.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );
33337 return this;
33338 }
33339 setFromVector3( v ) {
33340 return this.setFromCartesianCoords( v.x, v.y, v.z );
33341 }
33342 setFromCartesianCoords( x, y, z ) {
33343 this.radius = Math.sqrt( x * x + y * y + z * z );
33344 if ( this.radius === 0 ) {
33345 this.theta = 0;
33346 this.phi = 0;
33347 } else {
33348 this.theta = Math.atan2( x, z );
33349 this.phi = Math.acos( MathUtils.clamp( y / this.radius, - 1, 1 ) );
33350 }
33351 return this;
33352 }
33353 }
33354 class Cylindrical {
33355 constructor( radius, theta, y ) {
33356 this.radius = ( radius !== undefined ) ? radius : 1.0;
33357 this.theta = ( theta !== undefined ) ? theta : 0;
33358 this.y = ( y !== undefined ) ? y : 0;
33359 return this;
33360 }
33361 set( radius, theta, y ) {
33362 this.radius = radius;
33363 this.theta = theta;
33364 this.y = y;
33365 return this;
33366 }
33367 clone() {
33368 return new this.constructor().copy( this );
33369 }
33370 copy( other ) {
33371 this.radius = other.radius;
33372 this.theta = other.theta;
33373 this.y = other.y;
33374 return this;
33375 }
33376 setFromVector3( v ) {
33377 return this.setFromCartesianCoords( v.x, v.y, v.z );
33378 }
33379 setFromCartesianCoords( x, y, z ) {
33380 this.radius = Math.sqrt( x * x + z * z );
33381 this.theta = Math.atan2( x, z );
33382 this.y = y;
33383 return this;
33384 }
33385 }
33386 const _vector$7 = new Vector2();
33387 class Box2 {
33388 constructor( min, max ) {
33389 Object.defineProperty( this, 'isBox2', { value: true } );
33390 this.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );
33391 this.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );
33392 }
33393 set( min, max ) {
33394 this.min.copy( min );
33395 this.max.copy( max );
33396 return this;
33397 }
33398 setFromPoints( points ) {
33399 this.makeEmpty();
33400 for ( let i = 0, il = points.length; i < il; i ++ ) {
33401 this.expandByPoint( points[ i ] );
33402 }
33403 return this;
33404 }
33405 setFromCenterAndSize( center, size ) {
33406 const halfSize = _vector$7.copy( size ).multiplyScalar( 0.5 );
33407 this.min.copy( center ).sub( halfSize );
33408 this.max.copy( center ).add( halfSize );
33409 return this;
33410 }
33411 clone() {
33412 return new this.constructor().copy( this );
33413 }
33414 copy( box ) {
33415 this.min.copy( box.min );
33416 this.max.copy( box.max );
33417 return this;
33418 }
33419 makeEmpty() {
33420 this.min.x = this.min.y = + Infinity;
33421 this.max.x = this.max.y = - Infinity;
33422 return this;
33423 }
33424 isEmpty() {
33425 return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );
33426 }
33427 getCenter( target ) {
33428 if ( target === undefined ) {
33429 console.warn( 'THREE.Box2: .getCenter() target is now required' );
33430 target = new Vector2();
33431 }
33432 return this.isEmpty() ? target.set( 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
33433 }
33434 getSize( target ) {
33435 if ( target === undefined ) {
33436 console.warn( 'THREE.Box2: .getSize() target is now required' );
33437 target = new Vector2();
33438 }
33439 return this.isEmpty() ? target.set( 0, 0 ) : target.subVectors( this.max, this.min );
33440 }
33441 expandByPoint( point ) {
33442 this.min.min( point );
33443 this.max.max( point );
33444 return this;
33445 }
33446 expandByVector( vector ) {
33447 this.min.sub( vector );
33448 this.max.add( vector );
33449 return this;
33450 }
33451 expandByScalar( scalar ) {
33452 this.min.addScalar( - scalar );
33453 this.max.addScalar( scalar );
33454 return this;
33455 }
33456 containsPoint( point ) {
33457 return point.x < this.min.x || point.x > this.max.x ||
33458 point.y < this.min.y || point.y > this.max.y ? false : true;
33459 }
33460 containsBox( box ) {
33461 return this.min.x <= box.min.x && box.max.x <= this.max.x &&
33462 this.min.y <= box.min.y && box.max.y <= this.max.y;
33463 }
33464 getParameter( point, target ) {
33465 if ( target === undefined ) {
33466 console.warn( 'THREE.Box2: .getParameter() target is now required' );
33467 target = new Vector2();
33468 }
33469 return target.set(
33470 ( point.x - this.min.x ) / ( this.max.x - this.min.x ),
33471 ( point.y - this.min.y ) / ( this.max.y - this.min.y )
33472 );
33473 }
33474 intersectsBox( box ) {
33475 return box.max.x < this.min.x || box.min.x > this.max.x ||
33476 box.max.y < this.min.y || box.min.y > this.max.y ? false : true;
33477 }
33478 clampPoint( point, target ) {
33479 if ( target === undefined ) {
33480 console.warn( 'THREE.Box2: .clampPoint() target is now required' );
33481 target = new Vector2();
33482 }
33483 return target.copy( point ).clamp( this.min, this.max );
33484 }
33485 distanceToPoint( point ) {
33486 const clampedPoint = _vector$7.copy( point ).clamp( this.min, this.max );
33487 return clampedPoint.sub( point ).length();
33488 }
33489 intersect( box ) {
33490 this.min.max( box.min );
33491 this.max.min( box.max );
33492 return this;
33493 }
33494 union( box ) {
33495 this.min.min( box.min );
33496 this.max.max( box.max );
33497 return this;
33498 }
33499 translate( offset ) {
33500 this.min.add( offset );
33501 this.max.add( offset );
33502 return this;
33503 }
33504 equals( box ) {
33505 return box.min.equals( this.min ) && box.max.equals( this.max );
33506 }
33507 }
33508 const _startP = new Vector3();
33509 const _startEnd = new Vector3();
33510 class Line3 {
33511 constructor( start, end ) {
33512 this.start = ( start !== undefined ) ? start : new Vector3();
33513 this.end = ( end !== undefined ) ? end : new Vector3();
33514 }
33515 set( start, end ) {
33516 this.start.copy( start );
33517 this.end.copy( end );
33518 return this;
33519 }
33520 clone() {
33521 return new this.constructor().copy( this );
33522 }
33523 copy( line ) {
33524 this.start.copy( line.start );
33525 this.end.copy( line.end );
33526 return this;
33527 }
33528 getCenter( target ) {
33529 if ( target === undefined ) {
33530 console.warn( 'THREE.Line3: .getCenter() target is now required' );
33531 target = new Vector3();
33532 }
33533 return target.addVectors( this.start, this.end ).multiplyScalar( 0.5 );
33534 }
33535 delta( target ) {
33536 if ( target === undefined ) {
33537 console.warn( 'THREE.Line3: .delta() target is now required' );
33538 target = new Vector3();
33539 }
33540 return target.subVectors( this.end, this.start );
33541 }
33542 distanceSq() {
33543 return this.start.distanceToSquared( this.end );
33544 }
33545 distance() {
33546 return this.start.distanceTo( this.end );
33547 }
33548 at( t, target ) {
33549 if ( target === undefined ) {
33550 console.warn( 'THREE.Line3: .at() target is now required' );
33551 target = new Vector3();
33552 }
33553 return this.delta( target ).multiplyScalar( t ).add( this.start );
33554 }
33555 closestPointToPointParameter( point, clampToLine ) {
33556 _startP.subVectors( point, this.start );
33557 _startEnd.subVectors( this.end, this.start );
33558 const startEnd2 = _startEnd.dot( _startEnd );
33559 const startEnd_startP = _startEnd.dot( _startP );
33560 let t = startEnd_startP / startEnd2;
33561 if ( clampToLine ) {
33562 t = MathUtils.clamp( t, 0, 1 );
33563 }
33564 return t;
33565 }
33566 closestPointToPoint( point, clampToLine, target ) {
33567 const t = this.closestPointToPointParameter( point, clampToLine );
33568 if ( target === undefined ) {
33569 console.warn( 'THREE.Line3: .closestPointToPoint() target is now required' );
33570 target = new Vector3();
33571 }
33572 return this.delta( target ).multiplyScalar( t ).add( this.start );
33573 }
33574 applyMatrix4( matrix ) {
33575 this.start.applyMatrix4( matrix );
33576 this.end.applyMatrix4( matrix );
33577 return this;
33578 }
33579 equals( line ) {
33580 return line.start.equals( this.start ) && line.end.equals( this.end );
33581 }
33582 }
33583 function ImmediateRenderObject( material ) {
33584 Object3D.call( this );
33585 this.material = material;
33586 this.render = function ( ) {};
33587 this.hasPositions = false;
33588 this.hasNormals = false;
33589 this.hasColors = false;
33590 this.hasUvs = false;
33591 this.positionArray = null;
33592 this.normalArray = null;
33593 this.colorArray = null;
33594 this.uvArray = null;
33595 this.count = 0;
33596 }
33597 ImmediateRenderObject.prototype = Object.create( Object3D.prototype );
33598 ImmediateRenderObject.prototype.constructor = ImmediateRenderObject;
33599 ImmediateRenderObject.prototype.isImmediateRenderObject = true;
33600 const _vector$8 = new Vector3();
33601 class SpotLightHelper extends Object3D {
33602 constructor( light, color ) {
33603 super();
33604 this.light = light;
33605 this.light.updateMatrixWorld();
33606 this.matrix = light.matrixWorld;
33607 this.matrixAutoUpdate = false;
33608 this.color = color;
33609 const geometry = new BufferGeometry();
33610 const positions = [
33611 0, 0, 0, 0, 0, 1,
33612 0, 0, 0, 1, 0, 1,
33613 0, 0, 0, - 1, 0, 1,
33614 0, 0, 0, 0, 1, 1,
33615 0, 0, 0, 0, - 1, 1
33616 ];
33617 for ( let i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {
33618 const p1 = ( i / l ) * Math.PI * 2;
33619 const p2 = ( j / l ) * Math.PI * 2;
33620 positions.push(
33621 Math.cos( p1 ), Math.sin( p1 ), 1,
33622 Math.cos( p2 ), Math.sin( p2 ), 1
33623 );
33624 }
33625 geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
33626 const material = new LineBasicMaterial( { fog: false, toneMapped: false } );
33627 this.cone = new LineSegments( geometry, material );
33628 this.add( this.cone );
33629 this.update();
33630 }
33631 dispose() {
33632 this.cone.geometry.dispose();
33633 this.cone.material.dispose();
33634 }
33635 update() {
33636 this.light.updateMatrixWorld();
33637 const coneLength = this.light.distance ? this.light.distance : 1000;
33638 const coneWidth = coneLength * Math.tan( this.light.angle );
33639 this.cone.scale.set( coneWidth, coneWidth, coneLength );
33640 _vector$8.setFromMatrixPosition( this.light.target.matrixWorld );
33641 this.cone.lookAt( _vector$8 );
33642 if ( this.color !== undefined ) {
33643 this.cone.material.color.set( this.color );
33644 } else {
33645 this.cone.material.color.copy( this.light.color );
33646 }
33647 }
33648 }
33649 const _vector$9 = new Vector3();
33650 const _boneMatrix = new Matrix4();
33651 const _matrixWorldInv = new Matrix4();
33652 class SkeletonHelper extends LineSegments {
33653 constructor( object ) {
33654 const bones = getBoneList( object );
33655 const geometry = new BufferGeometry();
33656 const vertices = [];
33657 const colors = [];
33658 const color1 = new Color( 0, 0, 1 );
33659 const color2 = new Color( 0, 1, 0 );
33660 for ( let i = 0; i < bones.length; i ++ ) {
33661 const bone = bones[ i ];
33662 if ( bone.parent && bone.parent.isBone ) {
33663 vertices.push( 0, 0, 0 );
33664 vertices.push( 0, 0, 0 );
33665 colors.push( color1.r, color1.g, color1.b );
33666 colors.push( color2.r, color2.g, color2.b );
33667 }
33668 }
33669 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
33670 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
33671 const material = new LineBasicMaterial( { vertexColors: true, depthTest: false, depthWrite: false, toneMapped: false, transparent: true } );
33672 super( geometry, material );
33673 this.type = 'SkeletonHelper';
33674 this.isSkeletonHelper = true;
33675 this.root = object;
33676 this.bones = bones;
33677 this.matrix = object.matrixWorld;
33678 this.matrixAutoUpdate = false;
33679 }
33680 updateMatrixWorld( force ) {
33681 const bones = this.bones;
33682 const geometry = this.geometry;
33683 const position = geometry.getAttribute( 'position' );
33684 _matrixWorldInv.getInverse( this.root.matrixWorld );
33685 for ( let i = 0, j = 0; i < bones.length; i ++ ) {
33686 const bone = bones[ i ];
33687 if ( bone.parent && bone.parent.isBone ) {
33688 _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.matrixWorld );
33689 _vector$9.setFromMatrixPosition( _boneMatrix );
33690 position.setXYZ( j, _vector$9.x, _vector$9.y, _vector$9.z );
33691 _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.parent.matrixWorld );
33692 _vector$9.setFromMatrixPosition( _boneMatrix );
33693 position.setXYZ( j + 1, _vector$9.x, _vector$9.y, _vector$9.z );
33694 j += 2;
33695 }
33696 }
33697 geometry.getAttribute( 'position' ).needsUpdate = true;
33698 super.updateMatrixWorld( force );
33699 }
33700 }
33701 function getBoneList( object ) {
33702 const boneList = [];
33703 if ( object && object.isBone ) {
33704 boneList.push( object );
33705 }
33706 for ( let i = 0; i < object.children.length; i ++ ) {
33707 boneList.push.apply( boneList, getBoneList( object.children[ i ] ) );
33708 }
33709 return boneList;
33710 }
33711 class PointLightHelper extends Mesh {
33712 constructor( light, sphereSize, color ) {
33713 const geometry = new SphereBufferGeometry( sphereSize, 4, 2 );
33714 const material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } );
33715 super( geometry, material );
33716 this.light = light;
33717 this.light.updateMatrixWorld();
33718 this.color = color;
33719 this.type = 'PointLightHelper';
33720 this.matrix = this.light.matrixWorld;
33721 this.matrixAutoUpdate = false;
33722 this.update();
33723 }
33724 dispose() {
33725 this.geometry.dispose();
33726 this.material.dispose();
33727 }
33728 update() {
33729 if ( this.color !== undefined ) {
33730 this.material.color.set( this.color );
33731 } else {
33732 this.material.color.copy( this.light.color );
33733 }
33734 }
33735 }
33736 const _vector$a = new Vector3();
33737 const _color1 = new Color();
33738 const _color2 = new Color();
33739 class HemisphereLightHelper extends Object3D {
33740 constructor( light, size, color ) {
33741 super();
33742 this.light = light;
33743 this.light.updateMatrixWorld();
33744 this.matrix = light.matrixWorld;
33745 this.matrixAutoUpdate = false;
33746 this.color = color;
33747 const geometry = new OctahedronBufferGeometry( size );
33748 geometry.rotateY( Math.PI * 0.5 );
33749 this.material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } );
33750 if ( this.color === undefined ) this.material.vertexColors = true;
33751 const position = geometry.getAttribute( 'position' );
33752 const colors = new Float32Array( position.count * 3 );
33753 geometry.setAttribute( 'color', new BufferAttribute( colors, 3 ) );
33754 this.add( new Mesh( geometry, this.material ) );
33755 this.update();
33756 }
33757 dispose() {
33758 this.children[ 0 ].geometry.dispose();
33759 this.children[ 0 ].material.dispose();
33760 }
33761 update() {
33762 const mesh = this.children[ 0 ];
33763 if ( this.color !== undefined ) {
33764 this.material.color.set( this.color );
33765 } else {
33766 const colors = mesh.geometry.getAttribute( 'color' );
33767 _color1.copy( this.light.color );
33768 _color2.copy( this.light.groundColor );
33769 for ( let i = 0, l = colors.count; i < l; i ++ ) {
33770 const color = ( i < ( l / 2 ) ) ? _color1 : _color2;
33771 colors.setXYZ( i, color.r, color.g, color.b );
33772 }
33773 colors.needsUpdate = true;
33774 }
33775 mesh.lookAt( _vector$a.setFromMatrixPosition( this.light.matrixWorld ).negate() );
33776 }
33777 }
33778 class GridHelper extends LineSegments {
33779 constructor( size, divisions, color1, color2 ) {
33780 size = size || 10;
33781 divisions = divisions || 10;
33782 color1 = new Color( color1 !== undefined ? color1 : 0x444444 );
33783 color2 = new Color( color2 !== undefined ? color2 : 0x888888 );
33784 const center = divisions / 2;
33785 const step = size / divisions;
33786 const halfSize = size / 2;
33787 const vertices = [], colors = [];
33788 for ( let i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {
33789 vertices.push( - halfSize, 0, k, halfSize, 0, k );
33790 vertices.push( k, 0, - halfSize, k, 0, halfSize );
33791 const color = i === center ? color1 : color2;
33792 color.toArray( colors, j ); j += 3;
33793 color.toArray( colors, j ); j += 3;
33794 color.toArray( colors, j ); j += 3;
33795 color.toArray( colors, j ); j += 3;
33796 }
33797 const geometry = new BufferGeometry();
33798 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
33799 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
33800 const material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } );
33801 super( geometry, material );
33802 this.type = 'GridHelper';
33803 }
33804 }
33805 class PolarGridHelper extends LineSegments {
33806 constructor( radius, radials, circles, divisions, color1, color2 ) {
33807 radius = radius || 10;
33808 radials = radials || 16;
33809 circles = circles || 8;
33810 divisions = divisions || 64;
33811 color1 = new Color( color1 !== undefined ? color1 : 0x444444 );
33812 color2 = new Color( color2 !== undefined ? color2 : 0x888888 );
33813 const vertices = [];
33814 const colors = [];
33815 for ( let i = 0; i <= radials; i ++ ) {
33816 const v = ( i / radials ) * ( Math.PI * 2 );
33817 const x = Math.sin( v ) * radius;
33818 const z = Math.cos( v ) * radius;
33819 vertices.push( 0, 0, 0 );
33820 vertices.push( x, 0, z );
33821 const color = ( i & 1 ) ? color1 : color2;
33822 colors.push( color.r, color.g, color.b );
33823 colors.push( color.r, color.g, color.b );
33824 }
33825 for ( let i = 0; i <= circles; i ++ ) {
33826 const color = ( i & 1 ) ? color1 : color2;
33827 const r = radius - ( radius / circles * i );
33828 for ( let j = 0; j < divisions; j ++ ) {
33829 let v = ( j / divisions ) * ( Math.PI * 2 );
33830 let x = Math.sin( v ) * r;
33831 let z = Math.cos( v ) * r;
33832 vertices.push( x, 0, z );
33833 colors.push( color.r, color.g, color.b );
33834 v = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );
33835 x = Math.sin( v ) * r;
33836 z = Math.cos( v ) * r;
33837 vertices.push( x, 0, z );
33838 colors.push( color.r, color.g, color.b );
33839 }
33840 }
33841 const geometry = new BufferGeometry();
33842 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
33843 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
33844 const material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } );
33845 super( geometry, material );
33846 this.type = 'PolarGridHelper';
33847 }
33848 }
33849 const _v1$5 = new Vector3();
33850 const _v2$3 = new Vector3();
33851 const _v3$1 = new Vector3();
33852 class DirectionalLightHelper extends Object3D {
33853 constructor( light, size, color ) {
33854 super();
33855 this.light = light;
33856 this.light.updateMatrixWorld();
33857 this.matrix = light.matrixWorld;
33858 this.matrixAutoUpdate = false;
33859 this.color = color;
33860 if ( size === undefined ) size = 1;
33861 let geometry = new BufferGeometry();
33862 geometry.setAttribute( 'position', new Float32BufferAttribute( [
33863 - size, size, 0,
33864 size, size, 0,
33865 size, - size, 0,
33866 - size, - size, 0,
33867 - size, size, 0
33868 ], 3 ) );
33869 const material = new LineBasicMaterial( { fog: false, toneMapped: false } );
33870 this.lightPlane = new Line( geometry, material );
33871 this.add( this.lightPlane );
33872 geometry = new BufferGeometry();
33873 geometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );
33874 this.targetLine = new Line( geometry, material );
33875 this.add( this.targetLine );
33876 this.update();
33877 }
33878 dispose() {
33879 this.lightPlane.geometry.dispose();
33880 this.lightPlane.material.dispose();
33881 this.targetLine.geometry.dispose();
33882 this.targetLine.material.dispose();
33883 }
33884 update() {
33885 _v1$5.setFromMatrixPosition( this.light.matrixWorld );
33886 _v2$3.setFromMatrixPosition( this.light.target.matrixWorld );
33887 _v3$1.subVectors( _v2$3, _v1$5 );
33888 this.lightPlane.lookAt( _v2$3 );
33889 if ( this.color !== undefined ) {
33890 this.lightPlane.material.color.set( this.color );
33891 this.targetLine.material.color.set( this.color );
33892 } else {
33893 this.lightPlane.material.color.copy( this.light.color );
33894 this.targetLine.material.color.copy( this.light.color );
33895 }
33896 this.targetLine.lookAt( _v2$3 );
33897 this.targetLine.scale.z = _v3$1.length();
33898 }
33899 }
33900 const _vector$b = new Vector3();
33901 const _camera = new Camera();
33902 class CameraHelper extends LineSegments {
33903 constructor( camera ) {
33904 const geometry = new BufferGeometry();
33905 const material = new LineBasicMaterial( { color: 0xffffff, vertexColors: true, toneMapped: false } );
33906 const vertices = [];
33907 const colors = [];
33908 const pointMap = {};
33909 const colorFrustum = new Color( 0xffaa00 );
33910 const colorCone = new Color( 0xff0000 );
33911 const colorUp = new Color( 0x00aaff );
33912 const colorTarget = new Color( 0xffffff );
33913 const colorCross = new Color( 0x333333 );
33914 addLine( 'n1', 'n2', colorFrustum );
33915 addLine( 'n2', 'n4', colorFrustum );
33916 addLine( 'n4', 'n3', colorFrustum );
33917 addLine( 'n3', 'n1', colorFrustum );
33918 addLine( 'f1', 'f2', colorFrustum );
33919 addLine( 'f2', 'f4', colorFrustum );
33920 addLine( 'f4', 'f3', colorFrustum );
33921 addLine( 'f3', 'f1', colorFrustum );
33922 addLine( 'n1', 'f1', colorFrustum );
33923 addLine( 'n2', 'f2', colorFrustum );
33924 addLine( 'n3', 'f3', colorFrustum );
33925 addLine( 'n4', 'f4', colorFrustum );
33926 addLine( 'p', 'n1', colorCone );
33927 addLine( 'p', 'n2', colorCone );
33928 addLine( 'p', 'n3', colorCone );
33929 addLine( 'p', 'n4', colorCone );
33930 addLine( 'u1', 'u2', colorUp );
33931 addLine( 'u2', 'u3', colorUp );
33932 addLine( 'u3', 'u1', colorUp );
33933 addLine( 'c', 't', colorTarget );
33934 addLine( 'p', 'c', colorCross );
33935 addLine( 'cn1', 'cn2', colorCross );
33936 addLine( 'cn3', 'cn4', colorCross );
33937 addLine( 'cf1', 'cf2', colorCross );
33938 addLine( 'cf3', 'cf4', colorCross );
33939 function addLine( a, b, color ) {
33940 addPoint( a, color );
33941 addPoint( b, color );
33942 }
33943 function addPoint( id, color ) {
33944 vertices.push( 0, 0, 0 );
33945 colors.push( color.r, color.g, color.b );
33946 if ( pointMap[ id ] === undefined ) {
33947 pointMap[ id ] = [];
33948 }
33949 pointMap[ id ].push( ( vertices.length / 3 ) - 1 );
33950 }
33951 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
33952 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
33953 super( geometry, material );
33954 this.type = 'CameraHelper';
33955 this.camera = camera;
33956 if ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();
33957 this.matrix = camera.matrixWorld;
33958 this.matrixAutoUpdate = false;
33959 this.pointMap = pointMap;
33960 this.update();
33961 }
33962 update() {
33963 const geometry = this.geometry;
33964 const pointMap = this.pointMap;
33965 const w = 1, h = 1;
33966 _camera.projectionMatrixInverse.copy( this.camera.projectionMatrixInverse );
33967 setPoint( 'c', pointMap, geometry, _camera, 0, 0, - 1 );
33968 setPoint( 't', pointMap, geometry, _camera, 0, 0, 1 );
33969 setPoint( 'n1', pointMap, geometry, _camera, - w, - h, - 1 );
33970 setPoint( 'n2', pointMap, geometry, _camera, w, - h, - 1 );
33971 setPoint( 'n3', pointMap, geometry, _camera, - w, h, - 1 );
33972 setPoint( 'n4', pointMap, geometry, _camera, w, h, - 1 );
33973 setPoint( 'f1', pointMap, geometry, _camera, - w, - h, 1 );
33974 setPoint( 'f2', pointMap, geometry, _camera, w, - h, 1 );
33975 setPoint( 'f3', pointMap, geometry, _camera, - w, h, 1 );
33976 setPoint( 'f4', pointMap, geometry, _camera, w, h, 1 );
33977 setPoint( 'u1', pointMap, geometry, _camera, w * 0.7, h * 1.1, - 1 );
33978 setPoint( 'u2', pointMap, geometry, _camera, - w * 0.7, h * 1.1, - 1 );
33979 setPoint( 'u3', pointMap, geometry, _camera, 0, h * 2, - 1 );
33980 setPoint( 'cf1', pointMap, geometry, _camera, - w, 0, 1 );
33981 setPoint( 'cf2', pointMap, geometry, _camera, w, 0, 1 );
33982 setPoint( 'cf3', pointMap, geometry, _camera, 0, - h, 1 );
33983 setPoint( 'cf4', pointMap, geometry, _camera, 0, h, 1 );
33984 setPoint( 'cn1', pointMap, geometry, _camera, - w, 0, - 1 );
33985 setPoint( 'cn2', pointMap, geometry, _camera, w, 0, - 1 );
33986 setPoint( 'cn3', pointMap, geometry, _camera, 0, - h, - 1 );
33987 setPoint( 'cn4', pointMap, geometry, _camera, 0, h, - 1 );
33988 geometry.getAttribute( 'position' ).needsUpdate = true;
33989 }
33990 }
33991 function setPoint( point, pointMap, geometry, camera, x, y, z ) {
33992 _vector$b.set( x, y, z ).unproject( camera );
33993 const points = pointMap[ point ];
33994 if ( points !== undefined ) {
33995 const position = geometry.getAttribute( 'position' );
33996 for ( let i = 0, l = points.length; i < l; i ++ ) {
33997 position.setXYZ( points[ i ], _vector$b.x, _vector$b.y, _vector$b.z );
33998 }
33999 }
34000 }
34001 const _box$3 = new Box3();
34002 class BoxHelper extends LineSegments {
34003 constructor( object, color = 0xffff00 ) {
34004 const indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );
34005 const positions = new Float32Array( 8 * 3 );
34006 const geometry = new BufferGeometry();
34007 geometry.setIndex( new BufferAttribute( indices, 1 ) );
34008 geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );
34009 super( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
34010 this.object = object;
34011 this.type = 'BoxHelper';
34012 this.matrixAutoUpdate = false;
34013 this.update();
34014 }
34015 update( object ) {
34016 if ( object !== undefined ) {
34017 console.warn( 'THREE.BoxHelper: .update() has no longer arguments.' );
34018 }
34019 if ( this.object !== undefined ) {
34020 _box$3.setFromObject( this.object );
34021 }
34022 if ( _box$3.isEmpty() ) return;
34023 const min = _box$3.min;
34024 const max = _box$3.max;
34025 const position = this.geometry.attributes.position;
34026 const array = position.array;
34027 array[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;
34028 array[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;
34029 array[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;
34030 array[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;
34031 array[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;
34032 array[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;
34033 array[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;
34034 array[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;
34035 position.needsUpdate = true;
34036 this.geometry.computeBoundingSphere();
34037 }
34038 setFromObject( object ) {
34039 this.object = object;
34040 this.update();
34041 return this;
34042 }
34043 copy( source ) {
34044 LineSegments.prototype.copy.call( this, source );
34045 this.object = source.object;
34046 return this;
34047 }
34048 }
34049 class Box3Helper extends LineSegments {
34050 constructor( box, color = 0xffff00 ) {
34051 const indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );
34052 const positions = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 1, - 1, 1, - 1, - 1 ];
34053 const geometry = new BufferGeometry();
34054 geometry.setIndex( new BufferAttribute( indices, 1 ) );
34055 geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
34056 super( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
34057 this.box = box;
34058 this.type = 'Box3Helper';
34059 this.geometry.computeBoundingSphere();
34060 }
34061 updateMatrixWorld( force ) {
34062 const box = this.box;
34063 if ( box.isEmpty() ) return;
34064 box.getCenter( this.position );
34065 box.getSize( this.scale );
34066 this.scale.multiplyScalar( 0.5 );
34067 super.updateMatrixWorld( force );
34068 }
34069 }
34070 class PlaneHelper extends Line {
34071 constructor( plane, size, hex ) {
34072 const color = ( hex !== undefined ) ? hex : 0xffff00;
34073 const positions = [ 1, - 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 ];
34074 const geometry = new BufferGeometry();
34075 geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
34076 geometry.computeBoundingSphere();
34077 super( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
34078 this.type = 'PlaneHelper';
34079 this.plane = plane;
34080 this.size = ( size === undefined ) ? 1 : size;
34081 const positions2 = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, - 1, 1, 1, - 1, 1 ];
34082 const geometry2 = new BufferGeometry();
34083 geometry2.setAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) );
34084 geometry2.computeBoundingSphere();
34085 this.add( new Mesh( geometry2, new MeshBasicMaterial( { color: color, opacity: 0.2, transparent: true, depthWrite: false, toneMapped: false } ) ) );
34086 }
34087 updateMatrixWorld( force ) {
34088 let scale = - this.plane.constant;
34089 if ( Math.abs( scale ) < 1e-8 ) scale = 1e-8;
34090 this.scale.set( 0.5 * this.size, 0.5 * this.size, scale );
34091 this.children[ 0 ].material.side = ( scale < 0 ) ? BackSide : FrontSide;
34092 this.lookAt( this.plane.normal );
34093 super.updateMatrixWorld( force );
34094 }
34095 }
34096 const _axis = new Vector3();
34097 let _lineGeometry, _coneGeometry;
34098 class ArrowHelper extends Object3D {
34099 constructor( dir, origin, length, color, headLength, headWidth ) {
34100 super();
34101 this.type = 'ArrowHelper';
34102 if ( dir === undefined ) dir = new Vector3( 0, 0, 1 );
34103 if ( origin === undefined ) origin = new Vector3( 0, 0, 0 );
34104 if ( length === undefined ) length = 1;
34105 if ( color === undefined ) color = 0xffff00;
34106 if ( headLength === undefined ) headLength = 0.2 * length;
34107 if ( headWidth === undefined ) headWidth = 0.2 * headLength;
34108 if ( _lineGeometry === undefined ) {
34109 _lineGeometry = new BufferGeometry();
34110 _lineGeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );
34111 _coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );
34112 _coneGeometry.translate( 0, - 0.5, 0 );
34113 }
34114 this.position.copy( origin );
34115 this.line = new Line( _lineGeometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
34116 this.line.matrixAutoUpdate = false;
34117 this.add( this.line );
34118 this.cone = new Mesh( _coneGeometry, new MeshBasicMaterial( { color: color, toneMapped: false } ) );
34119 this.cone.matrixAutoUpdate = false;
34120 this.add( this.cone );
34121 this.setDirection( dir );
34122 this.setLength( length, headLength, headWidth );
34123 }
34124 setDirection( dir ) {
34125 if ( dir.y > 0.99999 ) {
34126 this.quaternion.set( 0, 0, 0, 1 );
34127 } else if ( dir.y < - 0.99999 ) {
34128 this.quaternion.set( 1, 0, 0, 0 );
34129 } else {
34130 _axis.set( dir.z, 0, - dir.x ).normalize();
34131 const radians = Math.acos( dir.y );
34132 this.quaternion.setFromAxisAngle( _axis, radians );
34133 }
34134 }
34135 setLength( length, headLength, headWidth ) {
34136 if ( headLength === undefined ) headLength = 0.2 * length;
34137 if ( headWidth === undefined ) headWidth = 0.2 * headLength;
34138 this.line.scale.set( 1, Math.max( 0.0001, length - headLength ), 1 );
34139 this.line.updateMatrix();
34140 this.cone.scale.set( headWidth, headLength, headWidth );
34141 this.cone.position.y = length;
34142 this.cone.updateMatrix();
34143 }
34144 setColor( color ) {
34145 this.line.material.color.set( color );
34146 this.cone.material.color.set( color );
34147 }
34148 copy( source ) {
34149 super.copy( source, false );
34150 this.line.copy( source.line );
34151 this.cone.copy( source.cone );
34152 return this;
34153 }
34154 }
34155 class AxesHelper extends LineSegments {
34156 constructor( size = 1 ) {
34157 const vertices = [
34158 0, 0, 0, size, 0, 0,
34159 0, 0, 0, 0, size, 0,
34160 0, 0, 0, 0, 0, size
34161 ];
34162 const colors = [
34163 1, 0, 0, 1, 0.6, 0,
34164 0, 1, 0, 0.6, 1, 0,
34165 0, 0, 1, 0, 0.6, 1
34166 ];
34167 const geometry = new BufferGeometry();
34168 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
34169 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
34170 const material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } );
34171 super( geometry, material );
34172 this.type = 'AxesHelper';
34173 }
34174 }
34175 const LOD_MIN = 4;
34176 const LOD_MAX = 8;
34177 const SIZE_MAX = Math.pow( 2, LOD_MAX );
34178 const EXTRA_LOD_SIGMA = [ 0.125, 0.215, 0.35, 0.446, 0.526, 0.582 ];
34179 const TOTAL_LODS = LOD_MAX - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length;
34180 const MAX_SAMPLES = 20;
34181 const ENCODINGS = {
34182 [ LinearEncoding ]: 0,
34183 [ sRGBEncoding ]: 1,
34184 [ RGBEEncoding ]: 2,
34185 [ RGBM7Encoding ]: 3,
34186 [ RGBM16Encoding ]: 4,
34187 [ RGBDEncoding ]: 5,
34188 [ GammaEncoding ]: 6
34189 };
34190 const _flatCamera = new OrthographicCamera();
34191 const { _lodPlanes, _sizeLods, _sigmas } = _createPlanes();
34192 let _oldTarget = null;
34193 const PHI = ( 1 + Math.sqrt( 5 ) ) / 2;
34194 const INV_PHI = 1 / PHI;
34195 const _axisDirections = [
34196 new Vector3( 1, 1, 1 ),
34197 new Vector3( - 1, 1, 1 ),
34198 new Vector3( 1, 1, - 1 ),
34199 new Vector3( - 1, 1, - 1 ),
34200 new Vector3( 0, PHI, INV_PHI ),
34201 new Vector3( 0, PHI, - INV_PHI ),
34202 new Vector3( INV_PHI, 0, PHI ),
34203 new Vector3( - INV_PHI, 0, PHI ),
34204 new Vector3( PHI, INV_PHI, 0 ),
34205 new Vector3( - PHI, INV_PHI, 0 ) ];
34206 class PMREMGenerator {
34207 constructor( renderer ) {
34208 this._renderer = renderer;
34209 this._pingPongRenderTarget = null;
34210 this._blurMaterial = _getBlurShader( MAX_SAMPLES );
34211 this._equirectShader = null;
34212 this._cubemapShader = null;
34213 this._compileMaterial( this._blurMaterial );
34214 }
34215 fromScene( scene, sigma = 0, near = 0.1, far = 100 ) {
34216 _oldTarget = this._renderer.getRenderTarget();
34217 const cubeUVRenderTarget = this._allocateTargets();
34218 this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget );
34219 if ( sigma > 0 ) {
34220 this._blur( cubeUVRenderTarget, 0, 0, sigma );
34221 }
34222 this._applyPMREM( cubeUVRenderTarget );
34223 this._cleanup( cubeUVRenderTarget );
34224 return cubeUVRenderTarget;
34225 }
34226 fromEquirectangular( equirectangular ) {
34227 return this._fromTexture( equirectangular );
34228 }
34229 fromCubemap( cubemap ) {
34230 return this._fromTexture( cubemap );
34231 }
34232 compileCubemapShader() {
34233 if ( this._cubemapShader === null ) {
34234 this._cubemapShader = _getCubemapShader();
34235 this._compileMaterial( this._cubemapShader );
34236 }
34237 }
34238 compileEquirectangularShader() {
34239 if ( this._equirectShader === null ) {
34240 this._equirectShader = _getEquirectShader();
34241 this._compileMaterial( this._equirectShader );
34242 }
34243 }
34244 dispose() {
34245 this._blurMaterial.dispose();
34246 if ( this._cubemapShader !== null ) this._cubemapShader.dispose();
34247 if ( this._equirectShader !== null ) this._equirectShader.dispose();
34248 for ( let i = 0; i < _lodPlanes.length; i ++ ) {
34249 _lodPlanes[ i ].dispose();
34250 }
34251 }
34252 _cleanup( outputTarget ) {
34253 this._pingPongRenderTarget.dispose();
34254 this._renderer.setRenderTarget( _oldTarget );
34255 outputTarget.scissorTest = false;
34256 _setViewport( outputTarget, 0, 0, outputTarget.width, outputTarget.height );
34257 }
34258 _fromTexture( texture ) {
34259 _oldTarget = this._renderer.getRenderTarget();
34260 const cubeUVRenderTarget = this._allocateTargets( texture );
34261 this._textureToCubeUV( texture, cubeUVRenderTarget );
34262 this._applyPMREM( cubeUVRenderTarget );
34263 this._cleanup( cubeUVRenderTarget );
34264 return cubeUVRenderTarget;
34265 }
34266 _allocateTargets( texture ) {
34267 const params = {
34268 magFilter: NearestFilter,
34269 minFilter: NearestFilter,
34270 generateMipmaps: false,
34271 type: UnsignedByteType,
34272 format: RGBEFormat,
34273 encoding: _isLDR( texture ) ? texture.encoding : RGBEEncoding,
34274 depthBuffer: false
34275 };
34276 const cubeUVRenderTarget = _createRenderTarget( params );
34277 cubeUVRenderTarget.depthBuffer = texture ? false : true;
34278 this._pingPongRenderTarget = _createRenderTarget( params );
34279 return cubeUVRenderTarget;
34280 }
34281 _compileMaterial( material ) {
34282 const tmpMesh = new Mesh( _lodPlanes[ 0 ], material );
34283 this._renderer.compile( tmpMesh, _flatCamera );
34284 }
34285 _sceneToCubeUV( scene, near, far, cubeUVRenderTarget ) {
34286 const fov = 90;
34287 const aspect = 1;
34288 const cubeCamera = new PerspectiveCamera( fov, aspect, near, far );
34289 const upSign = [ 1, - 1, 1, 1, 1, 1 ];
34290 const forwardSign = [ 1, 1, 1, - 1, - 1, - 1 ];
34291 const renderer = this._renderer;
34292 const outputEncoding = renderer.outputEncoding;
34293 const toneMapping = renderer.toneMapping;
34294 const clearColor = renderer.getClearColor();
34295 const clearAlpha = renderer.getClearAlpha();
34296 renderer.toneMapping = NoToneMapping;
34297 renderer.outputEncoding = LinearEncoding;
34298 let background = scene.background;
34299 if ( background && background.isColor ) {
34300 background.convertSRGBToLinear();
34301 const maxComponent = Math.max( background.r, background.g, background.b );
34302 const fExp = Math.min( Math.max( Math.ceil( Math.log2( maxComponent ) ), - 128.0 ), 127.0 );
34303 background = background.multiplyScalar( Math.pow( 2.0, - fExp ) );
34304 const alpha = ( fExp + 128.0 ) / 255.0;
34305 renderer.setClearColor( background, alpha );
34306 scene.background = null;
34307 }
34308 for ( let i = 0; i < 6; i ++ ) {
34309 const col = i % 3;
34310 if ( col == 0 ) {
34311 cubeCamera.up.set( 0, upSign[ i ], 0 );
34312 cubeCamera.lookAt( forwardSign[ i ], 0, 0 );
34313 } else if ( col == 1 ) {
34314 cubeCamera.up.set( 0, 0, upSign[ i ] );
34315 cubeCamera.lookAt( 0, forwardSign[ i ], 0 );
34316 } else {
34317 cubeCamera.up.set( 0, upSign[ i ], 0 );
34318 cubeCamera.lookAt( 0, 0, forwardSign[ i ] );
34319 }
34320 _setViewport( cubeUVRenderTarget,
34321 col * SIZE_MAX, i > 2 ? SIZE_MAX : 0, SIZE_MAX, SIZE_MAX );
34322 renderer.setRenderTarget( cubeUVRenderTarget );
34323 renderer.render( scene, cubeCamera );
34324 }
34325 renderer.toneMapping = toneMapping;
34326 renderer.outputEncoding = outputEncoding;
34327 renderer.setClearColor( clearColor, clearAlpha );
34328 }
34329 _textureToCubeUV( texture, cubeUVRenderTarget ) {
34330 const renderer = this._renderer;
34331 if ( texture.isCubeTexture ) {
34332 if ( this._cubemapShader == null ) {
34333 this._cubemapShader = _getCubemapShader();
34334 }
34335 } else {
34336 if ( this._equirectShader == null ) {
34337 this._equirectShader = _getEquirectShader();
34338 }
34339 }
34340 const material = texture.isCubeTexture ? this._cubemapShader : this._equirectShader;
34341 const mesh = new Mesh( _lodPlanes[ 0 ], material );
34342 const uniforms = material.uniforms;
34343 uniforms[ 'envMap' ].value = texture;
34344 if ( ! texture.isCubeTexture ) {
34345 uniforms[ 'texelSize' ].value.set( 1.0 / texture.image.width, 1.0 / texture.image.height );
34346 }
34347 uniforms[ 'inputEncoding' ].value = ENCODINGS[ texture.encoding ];
34348 uniforms[ 'outputEncoding' ].value = ENCODINGS[ cubeUVRenderTarget.texture.encoding ];
34349 _setViewport( cubeUVRenderTarget, 0, 0, 3 * SIZE_MAX, 2 * SIZE_MAX );
34350 renderer.setRenderTarget( cubeUVRenderTarget );
34351 renderer.render( mesh, _flatCamera );
34352 }
34353 _applyPMREM( cubeUVRenderTarget ) {
34354 const renderer = this._renderer;
34355 const autoClear = renderer.autoClear;
34356 renderer.autoClear = false;
34357 for ( let i = 1; i < TOTAL_LODS; i ++ ) {
34358 const sigma = Math.sqrt( _sigmas[ i ] * _sigmas[ i ] - _sigmas[ i - 1 ] * _sigmas[ i - 1 ] );
34359 const poleAxis = _axisDirections[ ( i - 1 ) % _axisDirections.length ];
34360 this._blur( cubeUVRenderTarget, i - 1, i, sigma, poleAxis );
34361 }
34362 renderer.autoClear = autoClear;
34363 }
34364 _blur( cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis ) {
34365 const pingPongRenderTarget = this._pingPongRenderTarget;
34366 this._halfBlur(
34367 cubeUVRenderTarget,
34368 pingPongRenderTarget,
34369 lodIn,
34370 lodOut,
34371 sigma,
34372 'latitudinal',
34373 poleAxis );
34374 this._halfBlur(
34375 pingPongRenderTarget,
34376 cubeUVRenderTarget,
34377 lodOut,
34378 lodOut,
34379 sigma,
34380 'longitudinal',
34381 poleAxis );
34382 }
34383 _halfBlur( targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis ) {
34384 const renderer = this._renderer;
34385 const blurMaterial = this._blurMaterial;
34386 if ( direction !== 'latitudinal' && direction !== 'longitudinal' ) {
34387 console.error(
34388 'blur direction must be either latitudinal or longitudinal!' );
34389 }
34390 const STANDARD_DEVIATIONS = 3;
34391 const blurMesh = new Mesh( _lodPlanes[ lodOut ], blurMaterial );
34392 const blurUniforms = blurMaterial.uniforms;
34393 const pixels = _sizeLods[ lodIn ] - 1;
34394 const radiansPerPixel = isFinite( sigmaRadians ) ? Math.PI / ( 2 * pixels ) : 2 * Math.PI / ( 2 * MAX_SAMPLES - 1 );
34395 const sigmaPixels = sigmaRadians / radiansPerPixel;
34396 const samples = isFinite( sigmaRadians ) ? 1 + Math.floor( STANDARD_DEVIATIONS * sigmaPixels ) : MAX_SAMPLES;
34397 if ( samples > MAX_SAMPLES ) {
34398 console.warn( `sigmaRadians, ${
34399 sigmaRadians}, is too large and will clip, as it requested ${
34400 samples} samples when the maximum is set to ${MAX_SAMPLES}` );
34401 }
34402 const weights = [];
34403 let sum = 0;
34404 for ( let i = 0; i < MAX_SAMPLES; ++ i ) {
34405 const x = i / sigmaPixels;
34406 const weight = Math.exp( - x * x / 2 );
34407 weights.push( weight );
34408 if ( i == 0 ) {
34409 sum += weight;
34410 } else if ( i < samples ) {
34411 sum += 2 * weight;
34412 }
34413 }
34414 for ( let i = 0; i < weights.length; i ++ ) {
34415 weights[ i ] = weights[ i ] / sum;
34416 }
34417 blurUniforms[ 'envMap' ].value = targetIn.texture;
34418 blurUniforms[ 'samples' ].value = samples;
34419 blurUniforms[ 'weights' ].value = weights;
34420 blurUniforms[ 'latitudinal' ].value = direction === 'latitudinal';
34421 if ( poleAxis ) {
34422 blurUniforms[ 'poleAxis' ].value = poleAxis;
34423 }
34424 blurUniforms[ 'dTheta' ].value = radiansPerPixel;
34425 blurUniforms[ 'mipInt' ].value = LOD_MAX - lodIn;
34426 blurUniforms[ 'inputEncoding' ].value = ENCODINGS[ targetIn.texture.encoding ];
34427 blurUniforms[ 'outputEncoding' ].value = ENCODINGS[ targetIn.texture.encoding ];
34428 const outputSize = _sizeLods[ lodOut ];
34429 const x = 3 * Math.max( 0, SIZE_MAX - 2 * outputSize );
34430 const y = ( lodOut === 0 ? 0 : 2 * SIZE_MAX ) + 2 * outputSize * ( lodOut > LOD_MAX - LOD_MIN ? lodOut - LOD_MAX + LOD_MIN : 0 );
34431 _setViewport( targetOut, x, y, 3 * outputSize, 2 * outputSize );
34432 renderer.setRenderTarget( targetOut );
34433 renderer.render( blurMesh, _flatCamera );
34434 }
34435 }
34436 function _isLDR( texture ) {
34437 if ( texture === undefined || texture.type !== UnsignedByteType ) return false;
34438 return texture.encoding === LinearEncoding || texture.encoding === sRGBEncoding || texture.encoding === GammaEncoding;
34439 }
34440 function _createPlanes() {
34441 const _lodPlanes = [];
34442 const _sizeLods = [];
34443 const _sigmas = [];
34444 let lod = LOD_MAX;
34445 for ( let i = 0; i < TOTAL_LODS; i ++ ) {
34446 const sizeLod = Math.pow( 2, lod );
34447 _sizeLods.push( sizeLod );
34448 let sigma = 1.0 / sizeLod;
34449 if ( i > LOD_MAX - LOD_MIN ) {
34450 sigma = EXTRA_LOD_SIGMA[ i - LOD_MAX + LOD_MIN - 1 ];
34451 } else if ( i == 0 ) {
34452 sigma = 0;
34453 }
34454 _sigmas.push( sigma );
34455 const texelSize = 1.0 / ( sizeLod - 1 );
34456 const min = - texelSize / 2;
34457 const max = 1 + texelSize / 2;
34458 const uv1 = [ min, min, max, min, max, max, min, min, max, max, min, max ];
34459 const cubeFaces = 6;
34460 const vertices = 6;
34461 const positionSize = 3;
34462 const uvSize = 2;
34463 const faceIndexSize = 1;
34464 const position = new Float32Array( positionSize * vertices * cubeFaces );
34465 const uv = new Float32Array( uvSize * vertices * cubeFaces );
34466 const faceIndex = new Float32Array( faceIndexSize * vertices * cubeFaces );
34467 for ( let face = 0; face < cubeFaces; face ++ ) {
34468 const x = ( face % 3 ) * 2 / 3 - 1;
34469 const y = face > 2 ? 0 : - 1;
34470 const coordinates = [
34471 x, y, 0,
34472 x + 2 / 3, y, 0,
34473 x + 2 / 3, y + 1, 0,
34474 x, y, 0,
34475 x + 2 / 3, y + 1, 0,
34476 x, y + 1, 0
34477 ];
34478 position.set( coordinates, positionSize * vertices * face );
34479 uv.set( uv1, uvSize * vertices * face );
34480 const fill = [ face, face, face, face, face, face ];
34481 faceIndex.set( fill, faceIndexSize * vertices * face );
34482 }
34483 const planes = new BufferGeometry();
34484 planes.setAttribute( 'position', new BufferAttribute( position, positionSize ) );
34485 planes.setAttribute( 'uv', new BufferAttribute( uv, uvSize ) );
34486 planes.setAttribute( 'faceIndex', new BufferAttribute( faceIndex, faceIndexSize ) );
34487 _lodPlanes.push( planes );
34488 if ( lod > LOD_MIN ) {
34489 lod --;
34490 }
34491 }
34492 return { _lodPlanes, _sizeLods, _sigmas };
34493 }
34494 function _createRenderTarget( params ) {
34495 const cubeUVRenderTarget = new WebGLRenderTarget( 3 * SIZE_MAX, 3 * SIZE_MAX, params );
34496 cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping;
34497 cubeUVRenderTarget.texture.name = 'PMREM.cubeUv';
34498 cubeUVRenderTarget.scissorTest = true;
34499 return cubeUVRenderTarget;
34500 }
34501 function _setViewport( target, x, y, width, height ) {
34502 target.viewport.set( x, y, width, height );
34503 target.scissor.set( x, y, width, height );
34504 }
34505 function _getBlurShader( maxSamples ) {
34506 const weights = new Float32Array( maxSamples );
34507 const poleAxis = new Vector3( 0, 1, 0 );
34508 const shaderMaterial = new RawShaderMaterial( {
34509 name: 'SphericalGaussianBlur',
34510 defines: { 'n': maxSamples },
34511 uniforms: {
34512 'envMap': { value: null },
34513 'samples': { value: 1 },
34514 'weights': { value: weights },
34515 'latitudinal': { value: false },
34516 'dTheta': { value: 0 },
34517 'mipInt': { value: 0 },
34518 'poleAxis': { value: poleAxis },
34519 'inputEncoding': { value: ENCODINGS[ LinearEncoding ] },
34520 'outputEncoding': { value: ENCODINGS[ LinearEncoding ] }
34521 },
34522 vertexShader: _getCommonVertexShader(),
34523 fragmentShader: `
34524
34525 precision mediump float;
34526 precision mediump int;
34527
34528 varying vec3 vOutputDirection;
34529
34530 uniform sampler2D envMap;
34531 uniform int samples;
34532 uniform float weights[ n ];
34533 uniform bool latitudinal;
34534 uniform float dTheta;
34535 uniform float mipInt;
34536 uniform vec3 poleAxis;
34537
34538 ${ _getEncodings() }
34539
34540 #define ENVMAP_TYPE_CUBE_UV
34541 #include <cube_uv_reflection_fragment>
34542
34543 vec3 getSample( float theta, vec3 axis ) {
34544
34545 float cosTheta = cos( theta );
34546 // Rodrigues' axis-angle rotation
34547 vec3 sampleDirection = vOutputDirection * cosTheta
34548 + cross( axis, vOutputDirection ) * sin( theta )
34549 + axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta );
34550
34551 return bilinearCubeUV( envMap, sampleDirection, mipInt );
34552
34553 }
34554
34555 void main() {
34556
34557 vec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection );
34558
34559 if ( all( equal( axis, vec3( 0.0 ) ) ) ) {
34560
34561 axis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x );
34562
34563 }
34564
34565 axis = normalize( axis );
34566
34567 gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
34568 gl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis );
34569
34570 for ( int i = 1; i < n; i++ ) {
34571
34572 if ( i >= samples ) {
34573
34574 break;
34575
34576 }
34577
34578 float theta = dTheta * float( i );
34579 gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis );
34580 gl_FragColor.rgb += weights[ i ] * getSample( theta, axis );
34581
34582 }
34583
34584 gl_FragColor = linearToOutputTexel( gl_FragColor );
34585
34586 }
34587 `,
34588 blending: NoBlending,
34589 depthTest: false,
34590 depthWrite: false
34591 } );
34592 return shaderMaterial;
34593 }
34594 function _getEquirectShader() {
34595 const texelSize = new Vector2( 1, 1 );
34596 const shaderMaterial = new RawShaderMaterial( {
34597 name: 'EquirectangularToCubeUV',
34598 uniforms: {
34599 'envMap': { value: null },
34600 'texelSize': { value: texelSize },
34601 'inputEncoding': { value: ENCODINGS[ LinearEncoding ] },
34602 'outputEncoding': { value: ENCODINGS[ LinearEncoding ] }
34603 },
34604 vertexShader: _getCommonVertexShader(),
34605 fragmentShader: `
34606
34607 precision mediump float;
34608 precision mediump int;
34609
34610 varying vec3 vOutputDirection;
34611
34612 uniform sampler2D envMap;
34613 uniform vec2 texelSize;
34614
34615 ${ _getEncodings() }
34616
34617 #include <common>
34618
34619 void main() {
34620
34621 gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
34622
34623 vec3 outputDirection = normalize( vOutputDirection );
34624 vec2 uv = equirectUv( outputDirection );
34625
34626 vec2 f = fract( uv / texelSize - 0.5 );
34627 uv -= f * texelSize;
34628 vec3 tl = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;
34629 uv.x += texelSize.x;
34630 vec3 tr = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;
34631 uv.y += texelSize.y;
34632 vec3 br = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;
34633 uv.x -= texelSize.x;
34634 vec3 bl = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;
34635
34636 vec3 tm = mix( tl, tr, f.x );
34637 vec3 bm = mix( bl, br, f.x );
34638 gl_FragColor.rgb = mix( tm, bm, f.y );
34639
34640 gl_FragColor = linearToOutputTexel( gl_FragColor );
34641
34642 }
34643 `,
34644 blending: NoBlending,
34645 depthTest: false,
34646 depthWrite: false
34647 } );
34648 return shaderMaterial;
34649 }
34650 function _getCubemapShader() {
34651 const shaderMaterial = new RawShaderMaterial( {
34652 name: 'CubemapToCubeUV',
34653 uniforms: {
34654 'envMap': { value: null },
34655 'inputEncoding': { value: ENCODINGS[ LinearEncoding ] },
34656 'outputEncoding': { value: ENCODINGS[ LinearEncoding ] }
34657 },
34658 vertexShader: _getCommonVertexShader(),
34659 fragmentShader: `
34660
34661 precision mediump float;
34662 precision mediump int;
34663
34664 varying vec3 vOutputDirection;
34665
34666 uniform samplerCube envMap;
34667
34668 ${ _getEncodings() }
34669
34670 void main() {
34671
34672 gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
34673 gl_FragColor.rgb = envMapTexelToLinear( textureCube( envMap, vec3( - vOutputDirection.x, vOutputDirection.yz ) ) ).rgb;
34674 gl_FragColor = linearToOutputTexel( gl_FragColor );
34675
34676 }
34677 `,
34678 blending: NoBlending,
34679 depthTest: false,
34680 depthWrite: false
34681 } );
34682 return shaderMaterial;
34683 }
34684 function _getCommonVertexShader() {
34685 return `
34686
34687 precision mediump float;
34688 precision mediump int;
34689
34690 attribute vec3 position;
34691 attribute vec2 uv;
34692 attribute float faceIndex;
34693
34694 varying vec3 vOutputDirection;
34695
34696 // RH coordinate system; PMREM face-indexing convention
34697 vec3 getDirection( vec2 uv, float face ) {
34698
34699 uv = 2.0 * uv - 1.0;
34700
34701 vec3 direction = vec3( uv, 1.0 );
34702
34703 if ( face == 0.0 ) {
34704
34705 direction = direction.zyx; // ( 1, v, u ) pos x
34706
34707 } else if ( face == 1.0 ) {
34708
34709 direction = direction.xzy;
34710 direction.xz *= -1.0; // ( -u, 1, -v ) pos y
34711
34712 } else if ( face == 2.0 ) {
34713
34714 direction.x *= -1.0; // ( -u, v, 1 ) pos z
34715
34716 } else if ( face == 3.0 ) {
34717
34718 direction = direction.zyx;
34719 direction.xz *= -1.0; // ( -1, v, -u ) neg x
34720
34721 } else if ( face == 4.0 ) {
34722
34723 direction = direction.xzy;
34724 direction.xy *= -1.0; // ( -u, -1, v ) neg y
34725
34726 } else if ( face == 5.0 ) {
34727
34728 direction.z *= -1.0; // ( u, v, -1 ) neg z
34729
34730 }
34731
34732 return direction;
34733
34734 }
34735
34736 void main() {
34737
34738 vOutputDirection = getDirection( uv, faceIndex );
34739 gl_Position = vec4( position, 1.0 );
34740
34741 }
34742 `;
34743 }
34744 function _getEncodings() {
34745 return `
34746
34747 uniform int inputEncoding;
34748 uniform int outputEncoding;
34749
34750 #include <encodings_pars_fragment>
34751
34752 vec4 inputTexelToLinear( vec4 value ) {
34753
34754 if ( inputEncoding == 0 ) {
34755
34756 return value;
34757
34758 } else if ( inputEncoding == 1 ) {
34759
34760 return sRGBToLinear( value );
34761
34762 } else if ( inputEncoding == 2 ) {
34763
34764 return RGBEToLinear( value );
34765
34766 } else if ( inputEncoding == 3 ) {
34767
34768 return RGBMToLinear( value, 7.0 );
34769
34770 } else if ( inputEncoding == 4 ) {
34771
34772 return RGBMToLinear( value, 16.0 );
34773
34774 } else if ( inputEncoding == 5 ) {
34775
34776 return RGBDToLinear( value, 256.0 );
34777
34778 } else {
34779
34780 return GammaToLinear( value, 2.2 );
34781
34782 }
34783
34784 }
34785
34786 vec4 linearToOutputTexel( vec4 value ) {
34787
34788 if ( outputEncoding == 0 ) {
34789
34790 return value;
34791
34792 } else if ( outputEncoding == 1 ) {
34793
34794 return LinearTosRGB( value );
34795
34796 } else if ( outputEncoding == 2 ) {
34797
34798 return LinearToRGBE( value );
34799
34800 } else if ( outputEncoding == 3 ) {
34801
34802 return LinearToRGBM( value, 7.0 );
34803
34804 } else if ( outputEncoding == 4 ) {
34805
34806 return LinearToRGBM( value, 16.0 );
34807
34808 } else if ( outputEncoding == 5 ) {
34809
34810 return LinearToRGBD( value, 256.0 );
34811
34812 } else {
34813
34814 return LinearToGamma( value, 2.2 );
34815
34816 }
34817
34818 }
34819
34820 vec4 envMapTexelToLinear( vec4 color ) {
34821
34822 return inputTexelToLinear( color );
34823
34824 }
34825 `;
34826 }
34827 function Face4( a, b, c, d, normal, color, materialIndex ) {
34828 console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );
34829 return new Face3( a, b, c, normal, color, materialIndex );
34830 }
34831 const LineStrip = 0;
34832 const LinePieces = 1;
34833 const NoColors = 0;
34834 const FaceColors = 1;
34835 const VertexColors = 2;
34836 function MeshFaceMaterial( materials ) {
34837 console.warn( 'THREE.MeshFaceMaterial has been removed. Use an Array instead.' );
34838 return materials;
34839 }
34840 function MultiMaterial( materials ) {
34841 if ( materials === undefined ) materials = [];
34842 console.warn( 'THREE.MultiMaterial has been removed. Use an Array instead.' );
34843 materials.isMultiMaterial = true;
34844 materials.materials = materials;
34845 materials.clone = function () {
34846 return materials.slice();
34847 };
34848 return materials;
34849 }
34850 function PointCloud( geometry, material ) {
34851 console.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );
34852 return new Points( geometry, material );
34853 }
34854 function Particle( material ) {
34855 console.warn( 'THREE.Particle has been renamed to THREE.Sprite.' );
34856 return new Sprite( material );
34857 }
34858 function ParticleSystem( geometry, material ) {
34859 console.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );
34860 return new Points( geometry, material );
34861 }
34862 function PointCloudMaterial( parameters ) {
34863 console.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );
34864 return new PointsMaterial( parameters );
34865 }
34866 function ParticleBasicMaterial( parameters ) {
34867 console.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );
34868 return new PointsMaterial( parameters );
34869 }
34870 function ParticleSystemMaterial( parameters ) {
34871 console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );
34872 return new PointsMaterial( parameters );
34873 }
34874 function Vertex( x, y, z ) {
34875 console.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );
34876 return new Vector3( x, y, z );
34877 }
34878 function DynamicBufferAttribute( array, itemSize ) {
34879 console.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setUsage( THREE.DynamicDrawUsage ) instead.' );
34880 return new BufferAttribute( array, itemSize ).setUsage( DynamicDrawUsage );
34881 }
34882 function Int8Attribute( array, itemSize ) {
34883 console.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' );
34884 return new Int8BufferAttribute( array, itemSize );
34885 }
34886 function Uint8Attribute( array, itemSize ) {
34887 console.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' );
34888 return new Uint8BufferAttribute( array, itemSize );
34889 }
34890 function Uint8ClampedAttribute( array, itemSize ) {
34891 console.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' );
34892 return new Uint8ClampedBufferAttribute( array, itemSize );
34893 }
34894 function Int16Attribute( array, itemSize ) {
34895 console.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' );
34896 return new Int16BufferAttribute( array, itemSize );
34897 }
34898 function Uint16Attribute( array, itemSize ) {
34899 console.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' );
34900 return new Uint16BufferAttribute( array, itemSize );
34901 }
34902 function Int32Attribute( array, itemSize ) {
34903 console.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' );
34904 return new Int32BufferAttribute( array, itemSize );
34905 }
34906 function Uint32Attribute( array, itemSize ) {
34907 console.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' );
34908 return new Uint32BufferAttribute( array, itemSize );
34909 }
34910 function Float32Attribute( array, itemSize ) {
34911 console.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' );
34912 return new Float32BufferAttribute( array, itemSize );
34913 }
34914 function Float64Attribute( array, itemSize ) {
34915 console.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' );
34916 return new Float64BufferAttribute( array, itemSize );
34917 }
34918 Curve.create = function ( construct, getPoint ) {
34919 console.log( 'THREE.Curve.create() has been deprecated' );
34920 construct.prototype = Object.create( Curve.prototype );
34921 construct.prototype.constructor = construct;
34922 construct.prototype.getPoint = getPoint;
34923 return construct;
34924 };
34925 Object.assign( CurvePath.prototype, {
34926 createPointsGeometry: function ( divisions ) {
34927 console.warn( 'THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' );
34928 const pts = this.getPoints( divisions );
34929 return this.createGeometry( pts );
34930 },
34931 createSpacedPointsGeometry: function ( divisions ) {
34932 console.warn( 'THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' );
34933 const pts = this.getSpacedPoints( divisions );
34934 return this.createGeometry( pts );
34935 },
34936 createGeometry: function ( points ) {
34937 console.warn( 'THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' );
34938 const geometry = new Geometry();
34939 for ( let i = 0, l = points.length; i < l; i ++ ) {
34940 const point = points[ i ];
34941 geometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );
34942 }
34943 return geometry;
34944 }
34945 } );
34946 Object.assign( Path.prototype, {
34947 fromPoints: function ( points ) {
34948 console.warn( 'THREE.Path: .fromPoints() has been renamed to .setFromPoints().' );
34949 return this.setFromPoints( points );
34950 }
34951 } );
34952 function ClosedSplineCurve3( points ) {
34953 console.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );
34954 CatmullRomCurve3.call( this, points );
34955 this.type = 'catmullrom';
34956 this.closed = true;
34957 }
34958 ClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );
34959 function SplineCurve3( points ) {
34960 console.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );
34961 CatmullRomCurve3.call( this, points );
34962 this.type = 'catmullrom';
34963 }
34964 SplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );
34965 function Spline( points ) {
34966 console.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' );
34967 CatmullRomCurve3.call( this, points );
34968 this.type = 'catmullrom';
34969 }
34970 Spline.prototype = Object.create( CatmullRomCurve3.prototype );
34971 Object.assign( Spline.prototype, {
34972 initFromArray: function ( ) {
34973 console.error( 'THREE.Spline: .initFromArray() has been removed.' );
34974 },
34975 getControlPointsArray: function ( ) {
34976 console.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );
34977 },
34978 reparametrizeByArcLength: function ( ) {
34979 console.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );
34980 }
34981 } );
34982 function AxisHelper( size ) {
34983 console.warn( 'THREE.AxisHelper has been renamed to THREE.AxesHelper.' );
34984 return new AxesHelper( size );
34985 }
34986 function BoundingBoxHelper( object, color ) {
34987 console.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' );
34988 return new BoxHelper( object, color );
34989 }
34990 function EdgesHelper( object, hex ) {
34991 console.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );
34992 return new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );
34993 }
34994 GridHelper.prototype.setColors = function () {
34995 console.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );
34996 };
34997 SkeletonHelper.prototype.update = function () {
34998 console.error( 'THREE.SkeletonHelper: update() no longer needs to be called.' );
34999 };
35000 function WireframeHelper( object, hex ) {
35001 console.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );
35002 return new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );
35003 }
35004 Object.assign( Loader.prototype, {
35005 extractUrlBase: function ( url ) {
35006 console.warn( 'THREE.Loader: .extractUrlBase() has been deprecated. Use THREE.LoaderUtils.extractUrlBase() instead.' );
35007 return LoaderUtils.extractUrlBase( url );
35008 }
35009 } );
35010 Loader.Handlers = {
35011 add: function ( ) {
35012 console.error( 'THREE.Loader: Handlers.add() has been removed. Use LoadingManager.addHandler() instead.' );
35013 },
35014 get: function ( ) {
35015 console.error( 'THREE.Loader: Handlers.get() has been removed. Use LoadingManager.getHandler() instead.' );
35016 }
35017 };
35018 function XHRLoader( manager ) {
35019 console.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' );
35020 return new FileLoader( manager );
35021 }
35022 function BinaryTextureLoader( manager ) {
35023 console.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' );
35024 return new DataTextureLoader( manager );
35025 }
35026 Object.assign( ObjectLoader.prototype, {
35027 setTexturePath: function ( value ) {
35028 console.warn( 'THREE.ObjectLoader: .setTexturePath() has been renamed to .setResourcePath().' );
35029 return this.setResourcePath( value );
35030 }
35031 } );
35032 Object.assign( Box2.prototype, {
35033 center: function ( optionalTarget ) {
35034 console.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );
35035 return this.getCenter( optionalTarget );
35036 },
35037 empty: function () {
35038 console.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );
35039 return this.isEmpty();
35040 },
35041 isIntersectionBox: function ( box ) {
35042 console.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );
35043 return this.intersectsBox( box );
35044 },
35045 size: function ( optionalTarget ) {
35046 console.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );
35047 return this.getSize( optionalTarget );
35048 }
35049 } );
35050 Object.assign( Box3.prototype, {
35051 center: function ( optionalTarget ) {
35052 console.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );
35053 return this.getCenter( optionalTarget );
35054 },
35055 empty: function () {
35056 console.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );
35057 return this.isEmpty();
35058 },
35059 isIntersectionBox: function ( box ) {
35060 console.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );
35061 return this.intersectsBox( box );
35062 },
35063 isIntersectionSphere: function ( sphere ) {
35064 console.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );
35065 return this.intersectsSphere( sphere );
35066 },
35067 size: function ( optionalTarget ) {
35068 console.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );
35069 return this.getSize( optionalTarget );
35070 }
35071 } );
35072 Object.assign( Sphere.prototype, {
35073 empty: function () {
35074 console.warn( 'THREE.Sphere: .empty() has been renamed to .isEmpty().' );
35075 return this.isEmpty();
35076 },
35077 } );
35078 Frustum.prototype.setFromMatrix = function ( m ) {
35079 console.warn( 'THREE.Frustum: .setFromMatrix() has been renamed to .setFromProjectionMatrix().' );
35080 return this.setFromProjectionMatrix( m );
35081 };
35082 Line3.prototype.center = function ( optionalTarget ) {
35083 console.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );
35084 return this.getCenter( optionalTarget );
35085 };
35086 Object.assign( MathUtils, {
35087 random16: function () {
35088 console.warn( 'THREE.Math: .random16() has been deprecated. Use Math.random() instead.' );
35089 return Math.random();
35090 },
35091 nearestPowerOfTwo: function ( value ) {
35092 console.warn( 'THREE.Math: .nearestPowerOfTwo() has been renamed to .floorPowerOfTwo().' );
35093 return MathUtils.floorPowerOfTwo( value );
35094 },
35095 nextPowerOfTwo: function ( value ) {
35096 console.warn( 'THREE.Math: .nextPowerOfTwo() has been renamed to .ceilPowerOfTwo().' );
35097 return MathUtils.ceilPowerOfTwo( value );
35098 }
35099 } );
35100 Object.assign( Matrix3.prototype, {
35101 flattenToArrayOffset: function ( array, offset ) {
35102 console.warn( "THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." );
35103 return this.toArray( array, offset );
35104 },
35105 multiplyVector3: function ( vector ) {
35106 console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );
35107 return vector.applyMatrix3( this );
35108 },
35109 multiplyVector3Array: function ( ) {
35110 console.error( 'THREE.Matrix3: .multiplyVector3Array() has been removed.' );
35111 },
35112 applyToBufferAttribute: function ( attribute ) {
35113 console.warn( 'THREE.Matrix3: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix3( matrix ) instead.' );
35114 return attribute.applyMatrix3( this );
35115 },
35116 applyToVector3Array: function ( ) {
35117 console.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );
35118 }
35119 } );
35120 Object.assign( Matrix4.prototype, {
35121 extractPosition: function ( m ) {
35122 console.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );
35123 return this.copyPosition( m );
35124 },
35125 flattenToArrayOffset: function ( array, offset ) {
35126 console.warn( "THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." );
35127 return this.toArray( array, offset );
35128 },
35129 getPosition: function () {
35130 console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );
35131 return new Vector3().setFromMatrixColumn( this, 3 );
35132 },
35133 setRotationFromQuaternion: function ( q ) {
35134 console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );
35135 return this.makeRotationFromQuaternion( q );
35136 },
35137 multiplyToArray: function () {
35138 console.warn( 'THREE.Matrix4: .multiplyToArray() has been removed.' );
35139 },
35140 multiplyVector3: function ( vector ) {
35141 console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
35142 return vector.applyMatrix4( this );
35143 },
35144 multiplyVector4: function ( vector ) {
35145 console.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
35146 return vector.applyMatrix4( this );
35147 },
35148 multiplyVector3Array: function ( ) {
35149 console.error( 'THREE.Matrix4: .multiplyVector3Array() has been removed.' );
35150 },
35151 rotateAxis: function ( v ) {
35152 console.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );
35153 v.transformDirection( this );
35154 },
35155 crossVector: function ( vector ) {
35156 console.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
35157 return vector.applyMatrix4( this );
35158 },
35159 translate: function () {
35160 console.error( 'THREE.Matrix4: .translate() has been removed.' );
35161 },
35162 rotateX: function () {
35163 console.error( 'THREE.Matrix4: .rotateX() has been removed.' );
35164 },
35165 rotateY: function () {
35166 console.error( 'THREE.Matrix4: .rotateY() has been removed.' );
35167 },
35168 rotateZ: function () {
35169 console.error( 'THREE.Matrix4: .rotateZ() has been removed.' );
35170 },
35171 rotateByAxis: function () {
35172 console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );
35173 },
35174 applyToBufferAttribute: function ( attribute ) {
35175 console.warn( 'THREE.Matrix4: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix4( matrix ) instead.' );
35176 return attribute.applyMatrix4( this );
35177 },
35178 applyToVector3Array: function ( ) {
35179 console.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );
35180 },
35181 makeFrustum: function ( left, right, bottom, top, near, far ) {
35182 console.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );
35183 return this.makePerspective( left, right, top, bottom, near, far );
35184 }
35185 } );
35186 Plane.prototype.isIntersectionLine = function ( line ) {
35187 console.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );
35188 return this.intersectsLine( line );
35189 };
35190 Quaternion.prototype.multiplyVector3 = function ( vector ) {
35191 console.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );
35192 return vector.applyQuaternion( this );
35193 };
35194 Object.assign( Ray.prototype, {
35195 isIntersectionBox: function ( box ) {
35196 console.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );
35197 return this.intersectsBox( box );
35198 },
35199 isIntersectionPlane: function ( plane ) {
35200 console.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );
35201 return this.intersectsPlane( plane );
35202 },
35203 isIntersectionSphere: function ( sphere ) {
35204 console.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );
35205 return this.intersectsSphere( sphere );
35206 }
35207 } );
35208 Object.assign( Triangle.prototype, {
35209 area: function () {
35210 console.warn( 'THREE.Triangle: .area() has been renamed to .getArea().' );
35211 return this.getArea();
35212 },
35213 barycoordFromPoint: function ( point, target ) {
35214 console.warn( 'THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().' );
35215 return this.getBarycoord( point, target );
35216 },
35217 midpoint: function ( target ) {
35218 console.warn( 'THREE.Triangle: .midpoint() has been renamed to .getMidpoint().' );
35219 return this.getMidpoint( target );
35220 },
35221 normal: function ( target ) {
35222 console.warn( 'THREE.Triangle: .normal() has been renamed to .getNormal().' );
35223 return this.getNormal( target );
35224 },
35225 plane: function ( target ) {
35226 console.warn( 'THREE.Triangle: .plane() has been renamed to .getPlane().' );
35227 return this.getPlane( target );
35228 }
35229 } );
35230 Object.assign( Triangle, {
35231 barycoordFromPoint: function ( point, a, b, c, target ) {
35232 console.warn( 'THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().' );
35233 return Triangle.getBarycoord( point, a, b, c, target );
35234 },
35235 normal: function ( a, b, c, target ) {
35236 console.warn( 'THREE.Triangle: .normal() has been renamed to .getNormal().' );
35237 return Triangle.getNormal( a, b, c, target );
35238 }
35239 } );
35240 Object.assign( Shape.prototype, {
35241 extractAllPoints: function ( divisions ) {
35242 console.warn( 'THREE.Shape: .extractAllPoints() has been removed. Use .extractPoints() instead.' );
35243 return this.extractPoints( divisions );
35244 },
35245 extrude: function ( options ) {
35246 console.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );
35247 return new ExtrudeGeometry( this, options );
35248 },
35249 makeGeometry: function ( options ) {
35250 console.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );
35251 return new ShapeGeometry( this, options );
35252 }
35253 } );
35254 Object.assign( Vector2.prototype, {
35255 fromAttribute: function ( attribute, index, offset ) {
35256 console.warn( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' );
35257 return this.fromBufferAttribute( attribute, index, offset );
35258 },
35259 distanceToManhattan: function ( v ) {
35260 console.warn( 'THREE.Vector2: .distanceToManhattan() has been renamed to .manhattanDistanceTo().' );
35261 return this.manhattanDistanceTo( v );
35262 },
35263 lengthManhattan: function () {
35264 console.warn( 'THREE.Vector2: .lengthManhattan() has been renamed to .manhattanLength().' );
35265 return this.manhattanLength();
35266 }
35267 } );
35268 Object.assign( Vector3.prototype, {
35269 setEulerFromRotationMatrix: function () {
35270 console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );
35271 },
35272 setEulerFromQuaternion: function () {
35273 console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );
35274 },
35275 getPositionFromMatrix: function ( m ) {
35276 console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );
35277 return this.setFromMatrixPosition( m );
35278 },
35279 getScaleFromMatrix: function ( m ) {
35280 console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );
35281 return this.setFromMatrixScale( m );
35282 },
35283 getColumnFromMatrix: function ( index, matrix ) {
35284 console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );
35285 return this.setFromMatrixColumn( matrix, index );
35286 },
35287 applyProjection: function ( m ) {
35288 console.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' );
35289 return this.applyMatrix4( m );
35290 },
35291 fromAttribute: function ( attribute, index, offset ) {
35292 console.warn( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' );
35293 return this.fromBufferAttribute( attribute, index, offset );
35294 },
35295 distanceToManhattan: function ( v ) {
35296 console.warn( 'THREE.Vector3: .distanceToManhattan() has been renamed to .manhattanDistanceTo().' );
35297 return this.manhattanDistanceTo( v );
35298 },
35299 lengthManhattan: function () {
35300 console.warn( 'THREE.Vector3: .lengthManhattan() has been renamed to .manhattanLength().' );
35301 return this.manhattanLength();
35302 }
35303 } );
35304 Object.assign( Vector4.prototype, {
35305 fromAttribute: function ( attribute, index, offset ) {
35306 console.warn( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' );
35307 return this.fromBufferAttribute( attribute, index, offset );
35308 },
35309 lengthManhattan: function () {
35310 console.warn( 'THREE.Vector4: .lengthManhattan() has been renamed to .manhattanLength().' );
35311 return this.manhattanLength();
35312 }
35313 } );
35314 Object.assign( Geometry.prototype, {
35315 computeTangents: function () {
35316 console.error( 'THREE.Geometry: .computeTangents() has been removed.' );
35317 },
35318 computeLineDistances: function () {
35319 console.error( 'THREE.Geometry: .computeLineDistances() has been removed. Use THREE.Line.computeLineDistances() instead.' );
35320 },
35321 applyMatrix: function ( matrix ) {
35322 console.warn( 'THREE.Geometry: .applyMatrix() has been renamed to .applyMatrix4().' );
35323 return this.applyMatrix4( matrix );
35324 }
35325 } );
35326 Object.assign( Object3D.prototype, {
35327 getChildByName: function ( name ) {
35328 console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );
35329 return this.getObjectByName( name );
35330 },
35331 renderDepth: function () {
35332 console.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );
35333 },
35334 translate: function ( distance, axis ) {
35335 console.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );
35336 return this.translateOnAxis( axis, distance );
35337 },
35338 getWorldRotation: function () {
35339 console.error( 'THREE.Object3D: .getWorldRotation() has been removed. Use THREE.Object3D.getWorldQuaternion( target ) instead.' );
35340 },
35341 applyMatrix: function ( matrix ) {
35342 console.warn( 'THREE.Object3D: .applyMatrix() has been renamed to .applyMatrix4().' );
35343 return this.applyMatrix4( matrix );
35344 }
35345 } );
35346 Object.defineProperties( Object3D.prototype, {
35347 eulerOrder: {
35348 get: function () {
35349 console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );
35350 return this.rotation.order;
35351 },
35352 set: function ( value ) {
35353 console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );
35354 this.rotation.order = value;
35355 }
35356 },
35357 useQuaternion: {
35358 get: function () {
35359 console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
35360 },
35361 set: function () {
35362 console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
35363 }
35364 }
35365 } );
35366 Object.assign( Mesh.prototype, {
35367 setDrawMode: function () {
35368 console.error( 'THREE.Mesh: .setDrawMode() has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.' );
35369 },
35370 } );
35371 Object.defineProperties( Mesh.prototype, {
35372 drawMode: {
35373 get: function () {
35374 console.error( 'THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode.' );
35375 return TrianglesDrawMode;
35376 },
35377 set: function () {
35378 console.error( 'THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.' );
35379 }
35380 }
35381 } );
35382 Object.defineProperties( LOD.prototype, {
35383 objects: {
35384 get: function () {
35385 console.warn( 'THREE.LOD: .objects has been renamed to .levels.' );
35386 return this.levels;
35387 }
35388 }
35389 } );
35390 Object.defineProperty( Skeleton.prototype, 'useVertexTexture', {
35391 get: function () {
35392 console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' );
35393 },
35394 set: function () {
35395 console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' );
35396 }
35397 } );
35398 SkinnedMesh.prototype.initBones = function () {
35399 console.error( 'THREE.SkinnedMesh: initBones() has been removed.' );
35400 };
35401 Object.defineProperty( Curve.prototype, '__arcLengthDivisions', {
35402 get: function () {
35403 console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' );
35404 return this.arcLengthDivisions;
35405 },
35406 set: function ( value ) {
35407 console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' );
35408 this.arcLengthDivisions = value;
35409 }
35410 } );
35411 PerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {
35412 console.warn( "THREE.PerspectiveCamera.setLens is deprecated. " +
35413 "Use .setFocalLength and .filmGauge for a photographic setup." );
35414 if ( filmGauge !== undefined ) this.filmGauge = filmGauge;
35415 this.setFocalLength( focalLength );
35416 };
35417 Object.defineProperties( Light.prototype, {
35418 onlyShadow: {
35419 set: function () {
35420 console.warn( 'THREE.Light: .onlyShadow has been removed.' );
35421 }
35422 },
35423 shadowCameraFov: {
35424 set: function ( value ) {
35425 console.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );
35426 this.shadow.camera.fov = value;
35427 }
35428 },
35429 shadowCameraLeft: {
35430 set: function ( value ) {
35431 console.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );
35432 this.shadow.camera.left = value;
35433 }
35434 },
35435 shadowCameraRight: {
35436 set: function ( value ) {
35437 console.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );
35438 this.shadow.camera.right = value;
35439 }
35440 },
35441 shadowCameraTop: {
35442 set: function ( value ) {
35443 console.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );
35444 this.shadow.camera.top = value;
35445 }
35446 },
35447 shadowCameraBottom: {
35448 set: function ( value ) {
35449 console.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );
35450 this.shadow.camera.bottom = value;
35451 }
35452 },
35453 shadowCameraNear: {
35454 set: function ( value ) {
35455 console.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );
35456 this.shadow.camera.near = value;
35457 }
35458 },
35459 shadowCameraFar: {
35460 set: function ( value ) {
35461 console.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );
35462 this.shadow.camera.far = value;
35463 }
35464 },
35465 shadowCameraVisible: {
35466 set: function () {
35467 console.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );
35468 }
35469 },
35470 shadowBias: {
35471 set: function ( value ) {
35472 console.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );
35473 this.shadow.bias = value;
35474 }
35475 },
35476 shadowDarkness: {
35477 set: function () {
35478 console.warn( 'THREE.Light: .shadowDarkness has been removed.' );
35479 }
35480 },
35481 shadowMapWidth: {
35482 set: function ( value ) {
35483 console.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );
35484 this.shadow.mapSize.width = value;
35485 }
35486 },
35487 shadowMapHeight: {
35488 set: function ( value ) {
35489 console.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );
35490 this.shadow.mapSize.height = value;
35491 }
35492 }
35493 } );
35494 Object.defineProperties( BufferAttribute.prototype, {
35495 length: {
35496 get: function () {
35497 console.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' );
35498 return this.array.length;
35499 }
35500 },
35501 dynamic: {
35502 get: function () {
35503 console.warn( 'THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.' );
35504 return this.usage === DynamicDrawUsage;
35505 },
35506 set: function ( ) {
35507 console.warn( 'THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.' );
35508 this.setUsage( DynamicDrawUsage );
35509 }
35510 }
35511 } );
35512 Object.assign( BufferAttribute.prototype, {
35513 setDynamic: function ( value ) {
35514 console.warn( 'THREE.BufferAttribute: .setDynamic() has been deprecated. Use .setUsage() instead.' );
35515 this.setUsage( value === true ? DynamicDrawUsage : StaticDrawUsage );
35516 return this;
35517 },
35518 copyIndicesArray: function ( ) {
35519 console.error( 'THREE.BufferAttribute: .copyIndicesArray() has been removed.' );
35520 },
35521 setArray: function ( ) {
35522 console.error( 'THREE.BufferAttribute: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers' );
35523 }
35524 } );
35525 Object.assign( BufferGeometry.prototype, {
35526 addIndex: function ( index ) {
35527 console.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );
35528 this.setIndex( index );
35529 },
35530 addAttribute: function ( name, attribute ) {
35531 console.warn( 'THREE.BufferGeometry: .addAttribute() has been renamed to .setAttribute().' );
35532 if ( ! ( attribute && attribute.isBufferAttribute ) && ! ( attribute && attribute.isInterleavedBufferAttribute ) ) {
35533 console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );
35534 return this.setAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );
35535 }
35536 if ( name === 'index' ) {
35537 console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );
35538 this.setIndex( attribute );
35539 return this;
35540 }
35541 return this.setAttribute( name, attribute );
35542 },
35543 addDrawCall: function ( start, count, indexOffset ) {
35544 if ( indexOffset !== undefined ) {
35545 console.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );
35546 }
35547 console.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );
35548 this.addGroup( start, count );
35549 },
35550 clearDrawCalls: function () {
35551 console.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );
35552 this.clearGroups();
35553 },
35554 computeTangents: function () {
35555 console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );
35556 },
35557 computeOffsets: function () {
35558 console.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );
35559 },
35560 removeAttribute: function ( name ) {
35561 console.warn( 'THREE.BufferGeometry: .removeAttribute() has been renamed to .deleteAttribute().' );
35562 return this.deleteAttribute( name );
35563 },
35564 applyMatrix: function ( matrix ) {
35565 console.warn( 'THREE.BufferGeometry: .applyMatrix() has been renamed to .applyMatrix4().' );
35566 return this.applyMatrix4( matrix );
35567 }
35568 } );
35569 Object.defineProperties( BufferGeometry.prototype, {
35570 drawcalls: {
35571 get: function () {
35572 console.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );
35573 return this.groups;
35574 }
35575 },
35576 offsets: {
35577 get: function () {
35578 console.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );
35579 return this.groups;
35580 }
35581 }
35582 } );
35583 Object.defineProperties( InstancedBufferGeometry.prototype, {
35584 maxInstancedCount: {
35585 get: function () {
35586 console.warn( 'THREE.InstancedBufferGeometry: .maxInstancedCount has been renamed to .instanceCount.' );
35587 return this.instanceCount;
35588 },
35589 set: function ( value ) {
35590 console.warn( 'THREE.InstancedBufferGeometry: .maxInstancedCount has been renamed to .instanceCount.' );
35591 this.instanceCount = value;
35592 }
35593 }
35594 } );
35595 Object.defineProperties( Raycaster.prototype, {
35596 linePrecision: {
35597 get: function () {
35598 console.warn( 'THREE.Raycaster: .linePrecision has been deprecated. Use .params.Line.threshold instead.' );
35599 return this.params.Line.threshold;
35600 },
35601 set: function ( value ) {
35602 console.warn( 'THREE.Raycaster: .linePrecision has been deprecated. Use .params.Line.threshold instead.' );
35603 this.params.Line.threshold = value;
35604 }
35605 }
35606 } );
35607 Object.defineProperties( InterleavedBuffer.prototype, {
35608 dynamic: {
35609 get: function () {
35610 console.warn( 'THREE.InterleavedBuffer: .length has been deprecated. Use .usage instead.' );
35611 return this.usage === DynamicDrawUsage;
35612 },
35613 set: function ( value ) {
35614 console.warn( 'THREE.InterleavedBuffer: .length has been deprecated. Use .usage instead.' );
35615 this.setUsage( value );
35616 }
35617 }
35618 } );
35619 Object.assign( InterleavedBuffer.prototype, {
35620 setDynamic: function ( value ) {
35621 console.warn( 'THREE.InterleavedBuffer: .setDynamic() has been deprecated. Use .setUsage() instead.' );
35622 this.setUsage( value === true ? DynamicDrawUsage : StaticDrawUsage );
35623 return this;
35624 },
35625 setArray: function ( ) {
35626 console.error( 'THREE.InterleavedBuffer: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers' );
35627 }
35628 } );
35629 Object.assign( ExtrudeBufferGeometry.prototype, {
35630 getArrays: function () {
35631 console.error( 'THREE.ExtrudeBufferGeometry: .getArrays() has been removed.' );
35632 },
35633 addShapeList: function () {
35634 console.error( 'THREE.ExtrudeBufferGeometry: .addShapeList() has been removed.' );
35635 },
35636 addShape: function () {
35637 console.error( 'THREE.ExtrudeBufferGeometry: .addShape() has been removed.' );
35638 }
35639 } );
35640 Object.assign( Scene.prototype, {
35641 dispose: function () {
35642 console.error( 'THREE.Scene: .dispose() has been removed.' );
35643 }
35644 } );
35645 Object.defineProperties( Uniform.prototype, {
35646 dynamic: {
35647 set: function () {
35648 console.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );
35649 }
35650 },
35651 onUpdate: {
35652 value: function () {
35653 console.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );
35654 return this;
35655 }
35656 }
35657 } );
35658 Object.defineProperties( Material.prototype, {
35659 wrapAround: {
35660 get: function () {
35661 console.warn( 'THREE.Material: .wrapAround has been removed.' );
35662 },
35663 set: function () {
35664 console.warn( 'THREE.Material: .wrapAround has been removed.' );
35665 }
35666 },
35667 overdraw: {
35668 get: function () {
35669 console.warn( 'THREE.Material: .overdraw has been removed.' );
35670 },
35671 set: function () {
35672 console.warn( 'THREE.Material: .overdraw has been removed.' );
35673 }
35674 },
35675 wrapRGB: {
35676 get: function () {
35677 console.warn( 'THREE.Material: .wrapRGB has been removed.' );
35678 return new Color();
35679 }
35680 },
35681 shading: {
35682 get: function () {
35683 console.error( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' );
35684 },
35685 set: function ( value ) {
35686 console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' );
35687 this.flatShading = ( value === FlatShading );
35688 }
35689 },
35690 stencilMask: {
35691 get: function () {
35692 console.warn( 'THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.' );
35693 return this.stencilFuncMask;
35694 },
35695 set: function ( value ) {
35696 console.warn( 'THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.' );
35697 this.stencilFuncMask = value;
35698 }
35699 }
35700 } );
35701 Object.defineProperties( MeshPhongMaterial.prototype, {
35702 metal: {
35703 get: function () {
35704 console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );
35705 return false;
35706 },
35707 set: function () {
35708 console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );
35709 }
35710 }
35711 } );
35712 Object.defineProperties( MeshPhysicalMaterial.prototype, {
35713 transparency: {
35714 get: function () {
35715 console.warn( 'THREE.MeshPhysicalMaterial: .transparency has been renamed to .transmission.' );
35716 return this.transmission;
35717 },
35718 set: function ( value ) {
35719 console.warn( 'THREE.MeshPhysicalMaterial: .transparency has been renamed to .transmission.' );
35720 this.transmission = value;
35721 }
35722 }
35723 } );
35724 Object.defineProperties( ShaderMaterial.prototype, {
35725 derivatives: {
35726 get: function () {
35727 console.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );
35728 return this.extensions.derivatives;
35729 },
35730 set: function ( value ) {
35731 console.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );
35732 this.extensions.derivatives = value;
35733 }
35734 }
35735 } );
35736 Object.assign( WebGLRenderer.prototype, {
35737 clearTarget: function ( renderTarget, color, depth, stencil ) {
35738 console.warn( 'THREE.WebGLRenderer: .clearTarget() has been deprecated. Use .setRenderTarget() and .clear() instead.' );
35739 this.setRenderTarget( renderTarget );
35740 this.clear( color, depth, stencil );
35741 },
35742 animate: function ( callback ) {
35743 console.warn( 'THREE.WebGLRenderer: .animate() is now .setAnimationLoop().' );
35744 this.setAnimationLoop( callback );
35745 },
35746 getCurrentRenderTarget: function () {
35747 console.warn( 'THREE.WebGLRenderer: .getCurrentRenderTarget() is now .getRenderTarget().' );
35748 return this.getRenderTarget();
35749 },
35750 getMaxAnisotropy: function () {
35751 console.warn( 'THREE.WebGLRenderer: .getMaxAnisotropy() is now .capabilities.getMaxAnisotropy().' );
35752 return this.capabilities.getMaxAnisotropy();
35753 },
35754 getPrecision: function () {
35755 console.warn( 'THREE.WebGLRenderer: .getPrecision() is now .capabilities.precision.' );
35756 return this.capabilities.precision;
35757 },
35758 resetGLState: function () {
35759 console.warn( 'THREE.WebGLRenderer: .resetGLState() is now .state.reset().' );
35760 return this.state.reset();
35761 },
35762 supportsFloatTextures: function () {
35763 console.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).' );
35764 return this.extensions.get( 'OES_texture_float' );
35765 },
35766 supportsHalfFloatTextures: function () {
35767 console.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).' );
35768 return this.extensions.get( 'OES_texture_half_float' );
35769 },
35770 supportsStandardDerivatives: function () {
35771 console.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).' );
35772 return this.extensions.get( 'OES_standard_derivatives' );
35773 },
35774 supportsCompressedTextureS3TC: function () {
35775 console.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).' );
35776 return this.extensions.get( 'WEBGL_compressed_texture_s3tc' );
35777 },
35778 supportsCompressedTexturePVRTC: function () {
35779 console.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).' );
35780 return this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );
35781 },
35782 supportsBlendMinMax: function () {
35783 console.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).' );
35784 return this.extensions.get( 'EXT_blend_minmax' );
35785 },
35786 supportsVertexTextures: function () {
35787 console.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );
35788 return this.capabilities.vertexTextures;
35789 },
35790 supportsInstancedArrays: function () {
35791 console.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \'ANGLE_instanced_arrays\' ).' );
35792 return this.extensions.get( 'ANGLE_instanced_arrays' );
35793 },
35794 enableScissorTest: function ( boolean ) {
35795 console.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );
35796 this.setScissorTest( boolean );
35797 },
35798 initMaterial: function () {
35799 console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );
35800 },
35801 addPrePlugin: function () {
35802 console.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );
35803 },
35804 addPostPlugin: function () {
35805 console.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );
35806 },
35807 updateShadowMap: function () {
35808 console.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );
35809 },
35810 setFaceCulling: function () {
35811 console.warn( 'THREE.WebGLRenderer: .setFaceCulling() has been removed.' );
35812 },
35813 allocTextureUnit: function () {
35814 console.warn( 'THREE.WebGLRenderer: .allocTextureUnit() has been removed.' );
35815 },
35816 setTexture: function () {
35817 console.warn( 'THREE.WebGLRenderer: .setTexture() has been removed.' );
35818 },
35819 setTexture2D: function () {
35820 console.warn( 'THREE.WebGLRenderer: .setTexture2D() has been removed.' );
35821 },
35822 setTextureCube: function () {
35823 console.warn( 'THREE.WebGLRenderer: .setTextureCube() has been removed.' );
35824 },
35825 getActiveMipMapLevel: function () {
35826 console.warn( 'THREE.WebGLRenderer: .getActiveMipMapLevel() is now .getActiveMipmapLevel().' );
35827 return this.getActiveMipmapLevel();
35828 }
35829 } );
35830 Object.defineProperties( WebGLRenderer.prototype, {
35831 shadowMapEnabled: {
35832 get: function () {
35833 return this.shadowMap.enabled;
35834 },
35835 set: function ( value ) {
35836 console.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );
35837 this.shadowMap.enabled = value;
35838 }
35839 },
35840 shadowMapType: {
35841 get: function () {
35842 return this.shadowMap.type;
35843 },
35844 set: function ( value ) {
35845 console.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );
35846 this.shadowMap.type = value;
35847 }
35848 },
35849 shadowMapCullFace: {
35850 get: function () {
35851 console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.' );
35852 return undefined;
35853 },
35854 set: function ( ) {
35855 console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.' );
35856 }
35857 },
35858 context: {
35859 get: function () {
35860 console.warn( 'THREE.WebGLRenderer: .context has been removed. Use .getContext() instead.' );
35861 return this.getContext();
35862 }
35863 },
35864 vr: {
35865 get: function () {
35866 console.warn( 'THREE.WebGLRenderer: .vr has been renamed to .xr' );
35867 return this.xr;
35868 }
35869 },
35870 gammaInput: {
35871 get: function () {
35872 console.warn( 'THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.' );
35873 return false;
35874 },
35875 set: function () {
35876 console.warn( 'THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.' );
35877 }
35878 },
35879 gammaOutput: {
35880 get: function () {
35881 console.warn( 'THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.' );
35882 return false;
35883 },
35884 set: function ( value ) {
35885 console.warn( 'THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.' );
35886 this.outputEncoding = ( value === true ) ? sRGBEncoding : LinearEncoding;
35887 }
35888 },
35889 toneMappingWhitePoint: {
35890 get: function () {
35891 console.warn( 'THREE.WebGLRenderer: .toneMappingWhitePoint has been removed.' );
35892 return 1.0;
35893 },
35894 set: function () {
35895 console.warn( 'THREE.WebGLRenderer: .toneMappingWhitePoint has been removed.' );
35896 }
35897 },
35898 } );
35899 Object.defineProperties( WebGLShadowMap.prototype, {
35900 cullFace: {
35901 get: function () {
35902 console.warn( 'THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.' );
35903 return undefined;
35904 },
35905 set: function ( ) {
35906 console.warn( 'THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.' );
35907 }
35908 },
35909 renderReverseSided: {
35910 get: function () {
35911 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.' );
35912 return undefined;
35913 },
35914 set: function () {
35915 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.' );
35916 }
35917 },
35918 renderSingleSided: {
35919 get: function () {
35920 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.' );
35921 return undefined;
35922 },
35923 set: function () {
35924 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.' );
35925 }
35926 }
35927 } );
35928 function WebGLRenderTargetCube( width, height, options ) {
35929 console.warn( 'THREE.WebGLRenderTargetCube( width, height, options ) is now WebGLCubeRenderTarget( size, options ).' );
35930 return new WebGLCubeRenderTarget( width, options );
35931 }
35932 Object.defineProperties( WebGLRenderTarget.prototype, {
35933 wrapS: {
35934 get: function () {
35935 console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );
35936 return this.texture.wrapS;
35937 },
35938 set: function ( value ) {
35939 console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );
35940 this.texture.wrapS = value;
35941 }
35942 },
35943 wrapT: {
35944 get: function () {
35945 console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );
35946 return this.texture.wrapT;
35947 },
35948 set: function ( value ) {
35949 console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );
35950 this.texture.wrapT = value;
35951 }
35952 },
35953 magFilter: {
35954 get: function () {
35955 console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );
35956 return this.texture.magFilter;
35957 },
35958 set: function ( value ) {
35959 console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );
35960 this.texture.magFilter = value;
35961 }
35962 },
35963 minFilter: {
35964 get: function () {
35965 console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );
35966 return this.texture.minFilter;
35967 },
35968 set: function ( value ) {
35969 console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );
35970 this.texture.minFilter = value;
35971 }
35972 },
35973 anisotropy: {
35974 get: function () {
35975 console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );
35976 return this.texture.anisotropy;
35977 },
35978 set: function ( value ) {
35979 console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );
35980 this.texture.anisotropy = value;
35981 }
35982 },
35983 offset: {
35984 get: function () {
35985 console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );
35986 return this.texture.offset;
35987 },
35988 set: function ( value ) {
35989 console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );
35990 this.texture.offset = value;
35991 }
35992 },
35993 repeat: {
35994 get: function () {
35995 console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );
35996 return this.texture.repeat;
35997 },
35998 set: function ( value ) {
35999 console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );
36000 this.texture.repeat = value;
36001 }
36002 },
36003 format: {
36004 get: function () {
36005 console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );
36006 return this.texture.format;
36007 },
36008 set: function ( value ) {
36009 console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );
36010 this.texture.format = value;
36011 }
36012 },
36013 type: {
36014 get: function () {
36015 console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );
36016 return this.texture.type;
36017 },
36018 set: function ( value ) {
36019 console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );
36020 this.texture.type = value;
36021 }
36022 },
36023 generateMipmaps: {
36024 get: function () {
36025 console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );
36026 return this.texture.generateMipmaps;
36027 },
36028 set: function ( value ) {
36029 console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );
36030 this.texture.generateMipmaps = value;
36031 }
36032 }
36033 } );
36034 Object.defineProperties( Audio.prototype, {
36035 load: {
36036 value: function ( file ) {
36037 console.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' );
36038 const scope = this;
36039 const audioLoader = new AudioLoader();
36040 audioLoader.load( file, function ( buffer ) {
36041 scope.setBuffer( buffer );
36042 } );
36043 return this;
36044 }
36045 },
36046 startTime: {
36047 set: function () {
36048 console.warn( 'THREE.Audio: .startTime is now .play( delay ).' );
36049 }
36050 }
36051 } );
36052 AudioAnalyser.prototype.getData = function () {
36053 console.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );
36054 return this.getFrequencyData();
36055 };
36056 CubeCamera.prototype.updateCubeMap = function ( renderer, scene ) {
36057 console.warn( 'THREE.CubeCamera: .updateCubeMap() is now .update().' );
36058 return this.update( renderer, scene );
36059 };
36060 const GeometryUtils = {
36061 merge: function ( geometry1, geometry2, materialIndexOffset ) {
36062 console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );
36063 let matrix;
36064 if ( geometry2.isMesh ) {
36065 geometry2.matrixAutoUpdate && geometry2.updateMatrix();
36066 matrix = geometry2.matrix;
36067 geometry2 = geometry2.geometry;
36068 }
36069 geometry1.merge( geometry2, matrix, materialIndexOffset );
36070 },
36071 center: function ( geometry ) {
36072 console.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );
36073 return geometry.center();
36074 }
36075 };
36076 ImageUtils.crossOrigin = undefined;
36077 ImageUtils.loadTexture = function ( url, mapping, onLoad, onError ) {
36078 console.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );
36079 const loader = new TextureLoader();
36080 loader.setCrossOrigin( this.crossOrigin );
36081 const texture = loader.load( url, onLoad, undefined, onError );
36082 if ( mapping ) texture.mapping = mapping;
36083 return texture;
36084 };
36085 ImageUtils.loadTextureCube = function ( urls, mapping, onLoad, onError ) {
36086 console.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );
36087 const loader = new CubeTextureLoader();
36088 loader.setCrossOrigin( this.crossOrigin );
36089 const texture = loader.load( urls, onLoad, undefined, onError );
36090 if ( mapping ) texture.mapping = mapping;
36091 return texture;
36092 };
36093 ImageUtils.loadCompressedTexture = function () {
36094 console.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );
36095 };
36096 ImageUtils.loadCompressedTextureCube = function () {
36097 console.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );
36098 };
36099 function CanvasRenderer() {
36100 console.error( 'THREE.CanvasRenderer has been removed' );
36101 }
36102 function JSONLoader() {
36103 console.error( 'THREE.JSONLoader has been removed.' );
36104 }
36105 const SceneUtils = {
36106 createMultiMaterialObject: function ( ) {
36107 console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' );
36108 },
36109 detach: function ( ) {
36110 console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' );
36111 },
36112 attach: function ( ) {
36113 console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' );
36114 }
36115 };
36116 function LensFlare() {
36117 console.error( 'THREE.LensFlare has been moved to /examples/jsm/objects/Lensflare.js' );
36118 }
36119 if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
36120 __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'register', { detail: {
36121 revision: REVISION,
36122 } } ) );
36123 }
36124 var three_module = Object.freeze({
36125 __proto__: null,
36126 ACESFilmicToneMapping: ACESFilmicToneMapping,
36127 AddEquation: AddEquation,
36128 AddOperation: AddOperation,
36129 AdditiveAnimationBlendMode: AdditiveAnimationBlendMode,
36130 AdditiveBlending: AdditiveBlending,
36131 AlphaFormat: AlphaFormat,
36132 AlwaysDepth: AlwaysDepth,
36133 AlwaysStencilFunc: AlwaysStencilFunc,
36134 AmbientLight: AmbientLight,
36135 AmbientLightProbe: AmbientLightProbe,
36136 AnimationClip: AnimationClip,
36137 AnimationLoader: AnimationLoader,
36138 AnimationMixer: AnimationMixer,
36139 AnimationObjectGroup: AnimationObjectGroup,
36140 AnimationUtils: AnimationUtils,
36141 ArcCurve: ArcCurve,
36142 ArrayCamera: ArrayCamera,
36143 ArrowHelper: ArrowHelper,
36144 Audio: Audio,
36145 AudioAnalyser: AudioAnalyser,
36146 AudioContext: AudioContext,
36147 AudioListener: AudioListener,
36148 AudioLoader: AudioLoader,
36149 AxesHelper: AxesHelper,
36150 AxisHelper: AxisHelper,
36151 BackSide: BackSide,
36152 BasicDepthPacking: BasicDepthPacking,
36153 BasicShadowMap: BasicShadowMap,
36154 BinaryTextureLoader: BinaryTextureLoader,
36155 Bone: Bone,
36156 BooleanKeyframeTrack: BooleanKeyframeTrack,
36157 BoundingBoxHelper: BoundingBoxHelper,
36158 Box2: Box2,
36159 Box3: Box3,
36160 Box3Helper: Box3Helper,
36161 BoxBufferGeometry: BoxBufferGeometry,
36162 BoxGeometry: BoxGeometry,
36163 BoxHelper: BoxHelper,
36164 BufferAttribute: BufferAttribute,
36165 BufferGeometry: BufferGeometry,
36166 BufferGeometryLoader: BufferGeometryLoader,
36167 ByteType: ByteType,
36168 Cache: Cache,
36169 Camera: Camera,
36170 CameraHelper: CameraHelper,
36171 CanvasRenderer: CanvasRenderer,
36172 CanvasTexture: CanvasTexture,
36173 CatmullRomCurve3: CatmullRomCurve3,
36174 CineonToneMapping: CineonToneMapping,
36175 CircleBufferGeometry: CircleBufferGeometry,
36176 CircleGeometry: CircleGeometry,
36177 ClampToEdgeWrapping: ClampToEdgeWrapping,
36178 Clock: Clock,
36179 ClosedSplineCurve3: ClosedSplineCurve3,
36180 Color: Color,
36181 ColorKeyframeTrack: ColorKeyframeTrack,
36182 CompressedTexture: CompressedTexture,
36183 CompressedTextureLoader: CompressedTextureLoader,
36184 ConeBufferGeometry: ConeBufferGeometry,
36185 ConeGeometry: ConeGeometry,
36186 CubeCamera: CubeCamera,
36187 CubeGeometry: BoxGeometry,
36188 CubeReflectionMapping: CubeReflectionMapping,
36189 CubeRefractionMapping: CubeRefractionMapping,
36190 CubeTexture: CubeTexture,
36191 CubeTextureLoader: CubeTextureLoader,
36192 CubeUVReflectionMapping: CubeUVReflectionMapping,
36193 CubeUVRefractionMapping: CubeUVRefractionMapping,
36194 CubicBezierCurve: CubicBezierCurve,
36195 CubicBezierCurve3: CubicBezierCurve3,
36196 CubicInterpolant: CubicInterpolant,
36197 CullFaceBack: CullFaceBack,
36198 CullFaceFront: CullFaceFront,
36199 CullFaceFrontBack: CullFaceFrontBack,
36200 CullFaceNone: CullFaceNone,
36201 Curve: Curve,
36202 CurvePath: CurvePath,
36203 CustomBlending: CustomBlending,
36204 CustomToneMapping: CustomToneMapping,
36205 CylinderBufferGeometry: CylinderBufferGeometry,
36206 CylinderGeometry: CylinderGeometry,
36207 Cylindrical: Cylindrical,
36208 DataTexture: DataTexture,
36209 DataTexture2DArray: DataTexture2DArray,
36210 DataTexture3D: DataTexture3D,
36211 DataTextureLoader: DataTextureLoader,
36212 DecrementStencilOp: DecrementStencilOp,
36213 DecrementWrapStencilOp: DecrementWrapStencilOp,
36214 DefaultLoadingManager: DefaultLoadingManager,
36215 DepthFormat: DepthFormat,
36216 DepthStencilFormat: DepthStencilFormat,
36217 DepthTexture: DepthTexture,
36218 DirectionalLight: DirectionalLight,
36219 DirectionalLightHelper: DirectionalLightHelper,
36220 DiscreteInterpolant: DiscreteInterpolant,
36221 DodecahedronBufferGeometry: DodecahedronBufferGeometry,
36222 DodecahedronGeometry: DodecahedronGeometry,
36223 DoubleSide: DoubleSide,
36224 DstAlphaFactor: DstAlphaFactor,
36225 DstColorFactor: DstColorFactor,
36226 DynamicBufferAttribute: DynamicBufferAttribute,
36227 DynamicCopyUsage: DynamicCopyUsage,
36228 DynamicDrawUsage: DynamicDrawUsage,
36229 DynamicReadUsage: DynamicReadUsage,
36230 EdgesGeometry: EdgesGeometry,
36231 EdgesHelper: EdgesHelper,
36232 EllipseCurve: EllipseCurve,
36233 EqualDepth: EqualDepth,
36234 EqualStencilFunc: EqualStencilFunc,
36235 EquirectangularReflectionMapping: EquirectangularReflectionMapping,
36236 EquirectangularRefractionMapping: EquirectangularRefractionMapping,
36237 Euler: Euler,
36238 EventDispatcher: EventDispatcher,
36239 ExtrudeBufferGeometry: ExtrudeBufferGeometry,
36240 ExtrudeGeometry: ExtrudeGeometry,
36241 Face3: Face3,
36242 Face4: Face4,
36243 FaceColors: FaceColors,
36244 FileLoader: FileLoader,
36245 FlatShading: FlatShading,
36246 Float32Attribute: Float32Attribute,
36247 Float32BufferAttribute: Float32BufferAttribute,
36248 Float64Attribute: Float64Attribute,
36249 Float64BufferAttribute: Float64BufferAttribute,
36250 FloatType: FloatType,
36251 Fog: Fog,
36252 FogExp2: FogExp2,
36253 Font: Font,
36254 FontLoader: FontLoader,
36255 FrontSide: FrontSide,
36256 Frustum: Frustum,
36257 GLBufferAttribute: GLBufferAttribute,
36258 GLSL1: GLSL1,
36259 GLSL3: GLSL3,
36260 GammaEncoding: GammaEncoding,
36261 Geometry: Geometry,
36262 GeometryUtils: GeometryUtils,
36263 GreaterDepth: GreaterDepth,
36264 GreaterEqualDepth: GreaterEqualDepth,
36265 GreaterEqualStencilFunc: GreaterEqualStencilFunc,
36266 GreaterStencilFunc: GreaterStencilFunc,
36267 GridHelper: GridHelper,
36268 Group: Group,
36269 HalfFloatType: HalfFloatType,
36270 HemisphereLight: HemisphereLight,
36271 HemisphereLightHelper: HemisphereLightHelper,
36272 HemisphereLightProbe: HemisphereLightProbe,
36273 IcosahedronBufferGeometry: IcosahedronBufferGeometry,
36274 IcosahedronGeometry: IcosahedronGeometry,
36275 ImageBitmapLoader: ImageBitmapLoader,
36276 ImageLoader: ImageLoader,
36277 ImageUtils: ImageUtils,
36278 ImmediateRenderObject: ImmediateRenderObject,
36279 IncrementStencilOp: IncrementStencilOp,
36280 IncrementWrapStencilOp: IncrementWrapStencilOp,
36281 InstancedBufferAttribute: InstancedBufferAttribute,
36282 InstancedBufferGeometry: InstancedBufferGeometry,
36283 InstancedInterleavedBuffer: InstancedInterleavedBuffer,
36284 InstancedMesh: InstancedMesh,
36285 Int16Attribute: Int16Attribute,
36286 Int16BufferAttribute: Int16BufferAttribute,
36287 Int32Attribute: Int32Attribute,
36288 Int32BufferAttribute: Int32BufferAttribute,
36289 Int8Attribute: Int8Attribute,
36290 Int8BufferAttribute: Int8BufferAttribute,
36291 IntType: IntType,
36292 InterleavedBuffer: InterleavedBuffer,
36293 InterleavedBufferAttribute: InterleavedBufferAttribute,
36294 Interpolant: Interpolant,
36295 InterpolateDiscrete: InterpolateDiscrete,
36296 InterpolateLinear: InterpolateLinear,
36297 InterpolateSmooth: InterpolateSmooth,
36298 InvertStencilOp: InvertStencilOp,
36299 JSONLoader: JSONLoader,
36300 KeepStencilOp: KeepStencilOp,
36301 KeyframeTrack: KeyframeTrack,
36302 LOD: LOD,
36303 LatheBufferGeometry: LatheBufferGeometry,
36304 LatheGeometry: LatheGeometry,
36305 Layers: Layers,
36306 LensFlare: LensFlare,
36307 LessDepth: LessDepth,
36308 LessEqualDepth: LessEqualDepth,
36309 LessEqualStencilFunc: LessEqualStencilFunc,
36310 LessStencilFunc: LessStencilFunc,
36311 Light: Light,
36312 LightProbe: LightProbe,
36313 LightShadow: LightShadow,
36314 Line: Line,
36315 Line3: Line3,
36316 LineBasicMaterial: LineBasicMaterial,
36317 LineCurve: LineCurve,
36318 LineCurve3: LineCurve3,
36319 LineDashedMaterial: LineDashedMaterial,
36320 LineLoop: LineLoop,
36321 LinePieces: LinePieces,
36322 LineSegments: LineSegments,
36323 LineStrip: LineStrip,
36324 LinearEncoding: LinearEncoding,
36325 LinearFilter: LinearFilter,
36326 LinearInterpolant: LinearInterpolant,
36327 LinearMipMapLinearFilter: LinearMipMapLinearFilter,
36328 LinearMipMapNearestFilter: LinearMipMapNearestFilter,
36329 LinearMipmapLinearFilter: LinearMipmapLinearFilter,
36330 LinearMipmapNearestFilter: LinearMipmapNearestFilter,
36331 LinearToneMapping: LinearToneMapping,
36332 Loader: Loader,
36333 LoaderUtils: LoaderUtils,
36334 LoadingManager: LoadingManager,
36335 LogLuvEncoding: LogLuvEncoding,
36336 LoopOnce: LoopOnce,
36337 LoopPingPong: LoopPingPong,
36338 LoopRepeat: LoopRepeat,
36339 LuminanceAlphaFormat: LuminanceAlphaFormat,
36340 LuminanceFormat: LuminanceFormat,
36341 MOUSE: MOUSE,
36342 Material: Material,
36343 MaterialLoader: MaterialLoader,
36344 Math: MathUtils,
36345 MathUtils: MathUtils,
36346 Matrix3: Matrix3,
36347 Matrix4: Matrix4,
36348 MaxEquation: MaxEquation,
36349 Mesh: Mesh,
36350 MeshBasicMaterial: MeshBasicMaterial,
36351 MeshDepthMaterial: MeshDepthMaterial,
36352 MeshDistanceMaterial: MeshDistanceMaterial,
36353 MeshFaceMaterial: MeshFaceMaterial,
36354 MeshLambertMaterial: MeshLambertMaterial,
36355 MeshMatcapMaterial: MeshMatcapMaterial,
36356 MeshNormalMaterial: MeshNormalMaterial,
36357 MeshPhongMaterial: MeshPhongMaterial,
36358 MeshPhysicalMaterial: MeshPhysicalMaterial,
36359 MeshStandardMaterial: MeshStandardMaterial,
36360 MeshToonMaterial: MeshToonMaterial,
36361 MinEquation: MinEquation,
36362 MirroredRepeatWrapping: MirroredRepeatWrapping,
36363 MixOperation: MixOperation,
36364 MultiMaterial: MultiMaterial,
36365 MultiplyBlending: MultiplyBlending,
36366 MultiplyOperation: MultiplyOperation,
36367 NearestFilter: NearestFilter,
36368 NearestMipMapLinearFilter: NearestMipMapLinearFilter,
36369 NearestMipMapNearestFilter: NearestMipMapNearestFilter,
36370 NearestMipmapLinearFilter: NearestMipmapLinearFilter,
36371 NearestMipmapNearestFilter: NearestMipmapNearestFilter,
36372 NeverDepth: NeverDepth,
36373 NeverStencilFunc: NeverStencilFunc,
36374 NoBlending: NoBlending,
36375 NoColors: NoColors,
36376 NoToneMapping: NoToneMapping,
36377 NormalAnimationBlendMode: NormalAnimationBlendMode,
36378 NormalBlending: NormalBlending,
36379 NotEqualDepth: NotEqualDepth,
36380 NotEqualStencilFunc: NotEqualStencilFunc,
36381 NumberKeyframeTrack: NumberKeyframeTrack,
36382 Object3D: Object3D,
36383 ObjectLoader: ObjectLoader,
36384 ObjectSpaceNormalMap: ObjectSpaceNormalMap,
36385 OctahedronBufferGeometry: OctahedronBufferGeometry,
36386 OctahedronGeometry: OctahedronGeometry,
36387 OneFactor: OneFactor,
36388 OneMinusDstAlphaFactor: OneMinusDstAlphaFactor,
36389 OneMinusDstColorFactor: OneMinusDstColorFactor,
36390 OneMinusSrcAlphaFactor: OneMinusSrcAlphaFactor,
36391 OneMinusSrcColorFactor: OneMinusSrcColorFactor,
36392 OrthographicCamera: OrthographicCamera,
36393 PCFShadowMap: PCFShadowMap,
36394 PCFSoftShadowMap: PCFSoftShadowMap,
36395 PMREMGenerator: PMREMGenerator,
36396 ParametricBufferGeometry: ParametricBufferGeometry,
36397 ParametricGeometry: ParametricGeometry,
36398 Particle: Particle,
36399 ParticleBasicMaterial: ParticleBasicMaterial,
36400 ParticleSystem: ParticleSystem,
36401 ParticleSystemMaterial: ParticleSystemMaterial,
36402 Path: Path,
36403 PerspectiveCamera: PerspectiveCamera,
36404 Plane: Plane,
36405 PlaneBufferGeometry: PlaneBufferGeometry,
36406 PlaneGeometry: PlaneGeometry,
36407 PlaneHelper: PlaneHelper,
36408 PointCloud: PointCloud,
36409 PointCloudMaterial: PointCloudMaterial,
36410 PointLight: PointLight,
36411 PointLightHelper: PointLightHelper,
36412 Points: Points,
36413 PointsMaterial: PointsMaterial,
36414 PolarGridHelper: PolarGridHelper,
36415 PolyhedronBufferGeometry: PolyhedronBufferGeometry,
36416 PolyhedronGeometry: PolyhedronGeometry,
36417 PositionalAudio: PositionalAudio,
36418 PropertyBinding: PropertyBinding,
36419 PropertyMixer: PropertyMixer,
36420 QuadraticBezierCurve: QuadraticBezierCurve,
36421 QuadraticBezierCurve3: QuadraticBezierCurve3,
36422 Quaternion: Quaternion,
36423 QuaternionKeyframeTrack: QuaternionKeyframeTrack,
36424 QuaternionLinearInterpolant: QuaternionLinearInterpolant,
36425 REVISION: REVISION,
36426 RGBADepthPacking: RGBADepthPacking,
36427 RGBAFormat: RGBAFormat,
36428 RGBAIntegerFormat: RGBAIntegerFormat,
36429 RGBA_ASTC_10x10_Format: RGBA_ASTC_10x10_Format,
36430 RGBA_ASTC_10x5_Format: RGBA_ASTC_10x5_Format,
36431 RGBA_ASTC_10x6_Format: RGBA_ASTC_10x6_Format,
36432 RGBA_ASTC_10x8_Format: RGBA_ASTC_10x8_Format,
36433 RGBA_ASTC_12x10_Format: RGBA_ASTC_12x10_Format,
36434 RGBA_ASTC_12x12_Format: RGBA_ASTC_12x12_Format,
36435 RGBA_ASTC_4x4_Format: RGBA_ASTC_4x4_Format,
36436 RGBA_ASTC_5x4_Format: RGBA_ASTC_5x4_Format,
36437 RGBA_ASTC_5x5_Format: RGBA_ASTC_5x5_Format,
36438 RGBA_ASTC_6x5_Format: RGBA_ASTC_6x5_Format,
36439 RGBA_ASTC_6x6_Format: RGBA_ASTC_6x6_Format,
36440 RGBA_ASTC_8x5_Format: RGBA_ASTC_8x5_Format,
36441 RGBA_ASTC_8x6_Format: RGBA_ASTC_8x6_Format,
36442 RGBA_ASTC_8x8_Format: RGBA_ASTC_8x8_Format,
36443 RGBA_BPTC_Format: RGBA_BPTC_Format,
36444 RGBA_ETC2_EAC_Format: RGBA_ETC2_EAC_Format,
36445 RGBA_PVRTC_2BPPV1_Format: RGBA_PVRTC_2BPPV1_Format,
36446 RGBA_PVRTC_4BPPV1_Format: RGBA_PVRTC_4BPPV1_Format,
36447 RGBA_S3TC_DXT1_Format: RGBA_S3TC_DXT1_Format,
36448 RGBA_S3TC_DXT3_Format: RGBA_S3TC_DXT3_Format,
36449 RGBA_S3TC_DXT5_Format: RGBA_S3TC_DXT5_Format,
36450 RGBDEncoding: RGBDEncoding,
36451 RGBEEncoding: RGBEEncoding,
36452 RGBEFormat: RGBEFormat,
36453 RGBFormat: RGBFormat,
36454 RGBIntegerFormat: RGBIntegerFormat,
36455 RGBM16Encoding: RGBM16Encoding,
36456 RGBM7Encoding: RGBM7Encoding,
36457 RGB_ETC1_Format: RGB_ETC1_Format,
36458 RGB_ETC2_Format: RGB_ETC2_Format,
36459 RGB_PVRTC_2BPPV1_Format: RGB_PVRTC_2BPPV1_Format,
36460 RGB_PVRTC_4BPPV1_Format: RGB_PVRTC_4BPPV1_Format,
36461 RGB_S3TC_DXT1_Format: RGB_S3TC_DXT1_Format,
36462 RGFormat: RGFormat,
36463 RGIntegerFormat: RGIntegerFormat,
36464 RawShaderMaterial: RawShaderMaterial,
36465 Ray: Ray,
36466 Raycaster: Raycaster,
36467 RectAreaLight: RectAreaLight,
36468 RedFormat: RedFormat,
36469 RedIntegerFormat: RedIntegerFormat,
36470 ReinhardToneMapping: ReinhardToneMapping,
36471 RepeatWrapping: RepeatWrapping,
36472 ReplaceStencilOp: ReplaceStencilOp,
36473 ReverseSubtractEquation: ReverseSubtractEquation,
36474 RingBufferGeometry: RingBufferGeometry,
36475 RingGeometry: RingGeometry,
36476 SRGB8_ALPHA8_ASTC_10x10_Format: SRGB8_ALPHA8_ASTC_10x10_Format,
36477 SRGB8_ALPHA8_ASTC_10x5_Format: SRGB8_ALPHA8_ASTC_10x5_Format,
36478 SRGB8_ALPHA8_ASTC_10x6_Format: SRGB8_ALPHA8_ASTC_10x6_Format,
36479 SRGB8_ALPHA8_ASTC_10x8_Format: SRGB8_ALPHA8_ASTC_10x8_Format,
36480 SRGB8_ALPHA8_ASTC_12x10_Format: SRGB8_ALPHA8_ASTC_12x10_Format,
36481 SRGB8_ALPHA8_ASTC_12x12_Format: SRGB8_ALPHA8_ASTC_12x12_Format,
36482 SRGB8_ALPHA8_ASTC_4x4_Format: SRGB8_ALPHA8_ASTC_4x4_Format,
36483 SRGB8_ALPHA8_ASTC_5x4_Format: SRGB8_ALPHA8_ASTC_5x4_Format,
36484 SRGB8_ALPHA8_ASTC_5x5_Format: SRGB8_ALPHA8_ASTC_5x5_Format,
36485 SRGB8_ALPHA8_ASTC_6x5_Format: SRGB8_ALPHA8_ASTC_6x5_Format,
36486 SRGB8_ALPHA8_ASTC_6x6_Format: SRGB8_ALPHA8_ASTC_6x6_Format,
36487 SRGB8_ALPHA8_ASTC_8x5_Format: SRGB8_ALPHA8_ASTC_8x5_Format,
36488 SRGB8_ALPHA8_ASTC_8x6_Format: SRGB8_ALPHA8_ASTC_8x6_Format,
36489 SRGB8_ALPHA8_ASTC_8x8_Format: SRGB8_ALPHA8_ASTC_8x8_Format,
36490 Scene: Scene,
36491 SceneUtils: SceneUtils,
36492 ShaderChunk: ShaderChunk,
36493 ShaderLib: ShaderLib,
36494 ShaderMaterial: ShaderMaterial,
36495 ShadowMaterial: ShadowMaterial,
36496 Shape: Shape,
36497 ShapeBufferGeometry: ShapeBufferGeometry,
36498 ShapeGeometry: ShapeGeometry,
36499 ShapePath: ShapePath,
36500 ShapeUtils: ShapeUtils,
36501 ShortType: ShortType,
36502 Skeleton: Skeleton,
36503 SkeletonHelper: SkeletonHelper,
36504 SkinnedMesh: SkinnedMesh,
36505 SmoothShading: SmoothShading,
36506 Sphere: Sphere,
36507 SphereBufferGeometry: SphereBufferGeometry,
36508 SphereGeometry: SphereGeometry,
36509 Spherical: Spherical,
36510 SphericalHarmonics3: SphericalHarmonics3,
36511 Spline: Spline,
36512 SplineCurve: SplineCurve,
36513 SplineCurve3: SplineCurve3,
36514 SpotLight: SpotLight,
36515 SpotLightHelper: SpotLightHelper,
36516 Sprite: Sprite,
36517 SpriteMaterial: SpriteMaterial,
36518 SrcAlphaFactor: SrcAlphaFactor,
36519 SrcAlphaSaturateFactor: SrcAlphaSaturateFactor,
36520 SrcColorFactor: SrcColorFactor,
36521 StaticCopyUsage: StaticCopyUsage,
36522 StaticDrawUsage: StaticDrawUsage,
36523 StaticReadUsage: StaticReadUsage,
36524 StereoCamera: StereoCamera,
36525 StreamCopyUsage: StreamCopyUsage,
36526 StreamDrawUsage: StreamDrawUsage,
36527 StreamReadUsage: StreamReadUsage,
36528 StringKeyframeTrack: StringKeyframeTrack,
36529 SubtractEquation: SubtractEquation,
36530 SubtractiveBlending: SubtractiveBlending,
36531 TOUCH: TOUCH,
36532 TangentSpaceNormalMap: TangentSpaceNormalMap,
36533 TetrahedronBufferGeometry: TetrahedronBufferGeometry,
36534 TetrahedronGeometry: TetrahedronGeometry,
36535 TextBufferGeometry: TextBufferGeometry,
36536 TextGeometry: TextGeometry,
36537 Texture: Texture,
36538 TextureLoader: TextureLoader,
36539 TorusBufferGeometry: TorusBufferGeometry,
36540 TorusGeometry: TorusGeometry,
36541 TorusKnotBufferGeometry: TorusKnotBufferGeometry,
36542 TorusKnotGeometry: TorusKnotGeometry,
36543 Triangle: Triangle,
36544 TriangleFanDrawMode: TriangleFanDrawMode,
36545 TriangleStripDrawMode: TriangleStripDrawMode,
36546 TrianglesDrawMode: TrianglesDrawMode,
36547 TubeBufferGeometry: TubeBufferGeometry,
36548 TubeGeometry: TubeGeometry,
36549 UVMapping: UVMapping,
36550 Uint16Attribute: Uint16Attribute,
36551 Uint16BufferAttribute: Uint16BufferAttribute,
36552 Uint32Attribute: Uint32Attribute,
36553 Uint32BufferAttribute: Uint32BufferAttribute,
36554 Uint8Attribute: Uint8Attribute,
36555 Uint8BufferAttribute: Uint8BufferAttribute,
36556 Uint8ClampedAttribute: Uint8ClampedAttribute,
36557 Uint8ClampedBufferAttribute: Uint8ClampedBufferAttribute,
36558 Uniform: Uniform,
36559 UniformsLib: UniformsLib,
36560 UniformsUtils: UniformsUtils,
36561 UnsignedByteType: UnsignedByteType,
36562 UnsignedInt248Type: UnsignedInt248Type,
36563 UnsignedIntType: UnsignedIntType,
36564 UnsignedShort4444Type: UnsignedShort4444Type,
36565 UnsignedShort5551Type: UnsignedShort5551Type,
36566 UnsignedShort565Type: UnsignedShort565Type,
36567 UnsignedShortType: UnsignedShortType,
36568 VSMShadowMap: VSMShadowMap,
36569 Vector2: Vector2,
36570 Vector3: Vector3,
36571 Vector4: Vector4,
36572 VectorKeyframeTrack: VectorKeyframeTrack,
36573 Vertex: Vertex,
36574 VertexColors: VertexColors,
36575 VideoTexture: VideoTexture,
36576 WebGL1Renderer: WebGL1Renderer,
36577 WebGLCubeRenderTarget: WebGLCubeRenderTarget,
36578 WebGLMultisampleRenderTarget: WebGLMultisampleRenderTarget,
36579 WebGLRenderTarget: WebGLRenderTarget,
36580 WebGLRenderTargetCube: WebGLRenderTargetCube,
36581 WebGLRenderer: WebGLRenderer,
36582 WebGLUtils: WebGLUtils,
36583 WireframeGeometry: WireframeGeometry,
36584 WireframeHelper: WireframeHelper,
36585 WrapAroundEnding: WrapAroundEnding,
36586 XHRLoader: XHRLoader,
36587 ZeroCurvatureEnding: ZeroCurvatureEnding,
36588 ZeroFactor: ZeroFactor,
36589 ZeroSlopeEnding: ZeroSlopeEnding,
36590 ZeroStencilOp: ZeroStencilOp,
36591 sRGBEncoding: sRGBEncoding
36592 });
36593 var OrbitControls = function ( object, domElement ) {
36594 if ( domElement === undefined ) console.warn( 'THREE.OrbitControls: The second parameter "domElement" is now mandatory.' );
36595 if ( domElement === document ) console.error( 'THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.' );
36596 this.object = object;
36597 this.domElement = domElement;
36598 this.enabled = true;
36599 this.target = new Vector3();
36600 this.minDistance = 0;
36601 this.maxDistance = Infinity;
36602 this.minZoom = 0;
36603 this.maxZoom = Infinity;
36604 this.minPolarAngle = 0;
36605 this.maxPolarAngle = Math.PI;
36606 this.minAzimuthAngle = - Infinity;
36607 this.maxAzimuthAngle = Infinity;
36608 this.enableDamping = false;
36609 this.dampingFactor = 0.05;
36610 this.enableZoom = true;
36611 this.zoomSpeed = 1.0;
36612 this.enableRotate = true;
36613 this.rotateSpeed = 1.0;
36614 this.enablePan = true;
36615 this.panSpeed = 1.0;
36616 this.screenSpacePanning = true;
36617 this.keyPanSpeed = 7.0;
36618 this.autoRotate = false;
36619 this.autoRotateSpeed = 2.0;
36620 this.enableKeys = true;
36621 this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
36622 this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };
36623 this.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN };
36624 this.target0 = this.target.clone();
36625 this.position0 = this.object.position.clone();
36626 this.zoom0 = this.object.zoom;
36627 this.getPolarAngle = function () {
36628 return spherical.phi;
36629 };
36630 this.getAzimuthalAngle = function () {
36631 return spherical.theta;
36632 };
36633 this.saveState = function () {
36634 scope.target0.copy( scope.target );
36635 scope.position0.copy( scope.object.position );
36636 scope.zoom0 = scope.object.zoom;
36637 };
36638 this.reset = function () {
36639 scope.target.copy( scope.target0 );
36640 scope.object.position.copy( scope.position0 );
36641 scope.object.zoom = scope.zoom0;
36642 scope.object.updateProjectionMatrix();
36643 scope.dispatchEvent( changeEvent );
36644 scope.update();
36645 state = STATE.NONE;
36646 };
36647 this.update = function () {
36648 var offset = new Vector3();
36649 var quat = new Quaternion().setFromUnitVectors( object.up, new Vector3( 0, 1, 0 ) );
36650 var quatInverse = quat.clone().inverse();
36651 var lastPosition = new Vector3();
36652 var lastQuaternion = new Quaternion();
36653 var twoPI = 2 * Math.PI;
36654 return function update() {
36655 var position = scope.object.position;
36656 offset.copy( position ).sub( scope.target );
36657 offset.applyQuaternion( quat );
36658 spherical.setFromVector3( offset );
36659 if ( scope.autoRotate && state === STATE.NONE ) {
36660 rotateLeft( getAutoRotationAngle() );
36661 }
36662 if ( scope.enableDamping ) {
36663 spherical.theta += sphericalDelta.theta * scope.dampingFactor;
36664 spherical.phi += sphericalDelta.phi * scope.dampingFactor;
36665 } else {
36666 spherical.theta += sphericalDelta.theta;
36667 spherical.phi += sphericalDelta.phi;
36668 }
36669 var min = scope.minAzimuthAngle;
36670 var max = scope.maxAzimuthAngle;
36671 if ( isFinite( min ) && isFinite( max ) ) {
36672 if ( min < - Math.PI ) min += twoPI; else if ( min > Math.PI ) min -= twoPI;
36673 if ( max < - Math.PI ) max += twoPI; else if ( max > Math.PI ) max -= twoPI;
36674 if ( min < max ) {
36675 spherical.theta = Math.max( min, Math.min( max, spherical.theta ) );
36676 } else {
36677 spherical.theta = ( spherical.theta > ( min + max ) / 2 ) ?
36678 Math.max( min, spherical.theta ) :
36679 Math.min( max, spherical.theta );
36680 }
36681 }
36682 spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
36683 spherical.makeSafe();
36684 spherical.radius *= scale;
36685 spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );
36686 if ( scope.enableDamping === true ) {
36687 scope.target.addScaledVector( panOffset, scope.dampingFactor );
36688 } else {
36689 scope.target.add( panOffset );
36690 }
36691 offset.setFromSpherical( spherical );
36692 offset.applyQuaternion( quatInverse );
36693 position.copy( scope.target ).add( offset );
36694 scope.object.lookAt( scope.target );
36695 if ( scope.enableDamping === true ) {
36696 sphericalDelta.theta *= ( 1 - scope.dampingFactor );
36697 sphericalDelta.phi *= ( 1 - scope.dampingFactor );
36698 panOffset.multiplyScalar( 1 - scope.dampingFactor );
36699 } else {
36700 sphericalDelta.set( 0, 0, 0 );
36701 panOffset.set( 0, 0, 0 );
36702 }
36703 scale = 1;
36704 if ( zoomChanged ||
36705 lastPosition.distanceToSquared( scope.object.position ) > EPS ||
36706 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {
36707 scope.dispatchEvent( changeEvent );
36708 lastPosition.copy( scope.object.position );
36709 lastQuaternion.copy( scope.object.quaternion );
36710 zoomChanged = false;
36711 return true;
36712 }
36713 return false;
36714 };
36715 }();
36716 this.dispose = function () {
36717 scope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );
36718 scope.domElement.removeEventListener( 'pointerdown', onPointerDown, false );
36719 scope.domElement.removeEventListener( 'wheel', onMouseWheel, false );
36720 scope.domElement.removeEventListener( 'touchstart', onTouchStart, false );
36721 scope.domElement.removeEventListener( 'touchend', onTouchEnd, false );
36722 scope.domElement.removeEventListener( 'touchmove', onTouchMove, false );
36723 scope.domElement.ownerDocument.removeEventListener( 'pointermove', onPointerMove, false );
36724 scope.domElement.ownerDocument.removeEventListener( 'pointerup', onPointerUp, false );
36725 scope.domElement.removeEventListener( 'keydown', onKeyDown, false );
36726 };
36727 var scope = this;
36728 var changeEvent = { type: 'change' };
36729 var startEvent = { type: 'start' };
36730 var endEvent = { type: 'end' };
36731 var STATE = {
36732 NONE: - 1,
36733 ROTATE: 0,
36734 DOLLY: 1,
36735 PAN: 2,
36736 TOUCH_ROTATE: 3,
36737 TOUCH_PAN: 4,
36738 TOUCH_DOLLY_PAN: 5,
36739 TOUCH_DOLLY_ROTATE: 6
36740 };
36741 var state = STATE.NONE;
36742 var EPS = 0.000001;
36743 var spherical = new Spherical();
36744 var sphericalDelta = new Spherical();
36745 var scale = 1;
36746 var panOffset = new Vector3();
36747 var zoomChanged = false;
36748 var rotateStart = new Vector2();
36749 var rotateEnd = new Vector2();
36750 var rotateDelta = new Vector2();
36751 var panStart = new Vector2();
36752 var panEnd = new Vector2();
36753 var panDelta = new Vector2();
36754 var dollyStart = new Vector2();
36755 var dollyEnd = new Vector2();
36756 var dollyDelta = new Vector2();
36757 function getAutoRotationAngle() {
36758 return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
36759 }
36760 function getZoomScale() {
36761 return Math.pow( 0.95, scope.zoomSpeed );
36762 }
36763 function rotateLeft( angle ) {
36764 sphericalDelta.theta -= angle;
36765 }
36766 function rotateUp( angle ) {
36767 sphericalDelta.phi -= angle;
36768 }
36769 var panLeft = function () {
36770 var v = new Vector3();
36771 return function panLeft( distance, objectMatrix ) {
36772 v.setFromMatrixColumn( objectMatrix, 0 );
36773 v.multiplyScalar( - distance );
36774 panOffset.add( v );
36775 };
36776 }();
36777 var panUp = function () {
36778 var v = new Vector3();
36779 return function panUp( distance, objectMatrix ) {
36780 if ( scope.screenSpacePanning === true ) {
36781 v.setFromMatrixColumn( objectMatrix, 1 );
36782 } else {
36783 v.setFromMatrixColumn( objectMatrix, 0 );
36784 v.crossVectors( scope.object.up, v );
36785 }
36786 v.multiplyScalar( distance );
36787 panOffset.add( v );
36788 };
36789 }();
36790 var pan = function () {
36791 var offset = new Vector3();
36792 return function pan( deltaX, deltaY ) {
36793 var element = scope.domElement;
36794 if ( scope.object.isPerspectiveCamera ) {
36795 var position = scope.object.position;
36796 offset.copy( position ).sub( scope.target );
36797 var targetDistance = offset.length();
36798 targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );
36799 panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );
36800 panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );
36801 } else if ( scope.object.isOrthographicCamera ) {
36802 panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );
36803 panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );
36804 } else {
36805 console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
36806 scope.enablePan = false;
36807 }
36808 };
36809 }();
36810 function dollyOut( dollyScale ) {
36811 if ( scope.object.isPerspectiveCamera ) {
36812 scale /= dollyScale;
36813 } else if ( scope.object.isOrthographicCamera ) {
36814 scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );
36815 scope.object.updateProjectionMatrix();
36816 zoomChanged = true;
36817 } else {
36818 console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
36819 scope.enableZoom = false;
36820 }
36821 }
36822 function dollyIn( dollyScale ) {
36823 if ( scope.object.isPerspectiveCamera ) {
36824 scale *= dollyScale;
36825 } else if ( scope.object.isOrthographicCamera ) {
36826 scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );
36827 scope.object.updateProjectionMatrix();
36828 zoomChanged = true;
36829 } else {
36830 console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
36831 scope.enableZoom = false;
36832 }
36833 }
36834 function handleMouseDownRotate( event ) {
36835 rotateStart.set( event.clientX, event.clientY );
36836 }
36837 function handleMouseDownDolly( event ) {
36838 dollyStart.set( event.clientX, event.clientY );
36839 }
36840 function handleMouseDownPan( event ) {
36841 panStart.set( event.clientX, event.clientY );
36842 }
36843 function handleMouseMoveRotate( event ) {
36844 rotateEnd.set( event.clientX, event.clientY );
36845 rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );
36846 var element = scope.domElement;
36847 rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight );
36848 rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );
36849 rotateStart.copy( rotateEnd );
36850 scope.update();
36851 }
36852 function handleMouseMoveDolly( event ) {
36853 dollyEnd.set( event.clientX, event.clientY );
36854 dollyDelta.subVectors( dollyEnd, dollyStart );
36855 if ( dollyDelta.y > 0 ) {
36856 dollyOut( getZoomScale() );
36857 } else if ( dollyDelta.y < 0 ) {
36858 dollyIn( getZoomScale() );
36859 }
36860 dollyStart.copy( dollyEnd );
36861 scope.update();
36862 }
36863 function handleMouseMovePan( event ) {
36864 panEnd.set( event.clientX, event.clientY );
36865 panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );
36866 pan( panDelta.x, panDelta.y );
36867 panStart.copy( panEnd );
36868 scope.update();
36869 }
36870 function handleMouseWheel( event ) {
36871 if ( event.deltaY < 0 ) {
36872 dollyIn( getZoomScale() );
36873 } else if ( event.deltaY > 0 ) {
36874 dollyOut( getZoomScale() );
36875 }
36876 scope.update();
36877 }
36878 function handleKeyDown( event ) {
36879 var needsUpdate = false;
36880 switch ( event.keyCode ) {
36881 case scope.keys.UP:
36882 pan( 0, scope.keyPanSpeed );
36883 needsUpdate = true;
36884 break;
36885 case scope.keys.BOTTOM:
36886 pan( 0, - scope.keyPanSpeed );
36887 needsUpdate = true;
36888 break;
36889 case scope.keys.LEFT:
36890 pan( scope.keyPanSpeed, 0 );
36891 needsUpdate = true;
36892 break;
36893 case scope.keys.RIGHT:
36894 pan( - scope.keyPanSpeed, 0 );
36895 needsUpdate = true;
36896 break;
36897 }
36898 if ( needsUpdate ) {
36899 event.preventDefault();
36900 scope.update();
36901 }
36902 }
36903 function handleTouchStartRotate( event ) {
36904 if ( event.touches.length == 1 ) {
36905 rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
36906 } else {
36907 var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX );
36908 var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY );
36909 rotateStart.set( x, y );
36910 }
36911 }
36912 function handleTouchStartPan( event ) {
36913 if ( event.touches.length == 1 ) {
36914 panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
36915 } else {
36916 var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX );
36917 var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY );
36918 panStart.set( x, y );
36919 }
36920 }
36921 function handleTouchStartDolly( event ) {
36922 var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
36923 var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
36924 var distance = Math.sqrt( dx * dx + dy * dy );
36925 dollyStart.set( 0, distance );
36926 }
36927 function handleTouchStartDollyPan( event ) {
36928 if ( scope.enableZoom ) handleTouchStartDolly( event );
36929 if ( scope.enablePan ) handleTouchStartPan( event );
36930 }
36931 function handleTouchStartDollyRotate( event ) {
36932 if ( scope.enableZoom ) handleTouchStartDolly( event );
36933 if ( scope.enableRotate ) handleTouchStartRotate( event );
36934 }
36935 function handleTouchMoveRotate( event ) {
36936 if ( event.touches.length == 1 ) {
36937 rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
36938 } else {
36939 var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX );
36940 var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY );
36941 rotateEnd.set( x, y );
36942 }
36943 rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );
36944 var element = scope.domElement;
36945 rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight );
36946 rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );
36947 rotateStart.copy( rotateEnd );
36948 }
36949 function handleTouchMovePan( event ) {
36950 if ( event.touches.length == 1 ) {
36951 panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
36952 } else {
36953 var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX );
36954 var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY );
36955 panEnd.set( x, y );
36956 }
36957 panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );
36958 pan( panDelta.x, panDelta.y );
36959 panStart.copy( panEnd );
36960 }
36961 function handleTouchMoveDolly( event ) {
36962 var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
36963 var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
36964 var distance = Math.sqrt( dx * dx + dy * dy );
36965 dollyEnd.set( 0, distance );
36966 dollyDelta.set( 0, Math.pow( dollyEnd.y / dollyStart.y, scope.zoomSpeed ) );
36967 dollyOut( dollyDelta.y );
36968 dollyStart.copy( dollyEnd );
36969 }
36970 function handleTouchMoveDollyPan( event ) {
36971 if ( scope.enableZoom ) handleTouchMoveDolly( event );
36972 if ( scope.enablePan ) handleTouchMovePan( event );
36973 }
36974 function handleTouchMoveDollyRotate( event ) {
36975 if ( scope.enableZoom ) handleTouchMoveDolly( event );
36976 if ( scope.enableRotate ) handleTouchMoveRotate( event );
36977 }
36978 function onPointerDown( event ) {
36979 if ( scope.enabled === false ) return;
36980 switch ( event.pointerType ) {
36981 case 'mouse':
36982 onMouseDown( event );
36983 break;
36984 }
36985 }
36986 function onPointerMove( event ) {
36987 if ( scope.enabled === false ) return;
36988 switch ( event.pointerType ) {
36989 case 'mouse':
36990 onMouseMove( event );
36991 break;
36992 }
36993 }
36994 function onPointerUp( event ) {
36995 if ( scope.enabled === false ) return;
36996 switch ( event.pointerType ) {
36997 case 'mouse':
36998 onMouseUp();
36999 break;
37000 }
37001 }
37002 function onMouseDown( event ) {
37003 event.preventDefault();
37004 scope.domElement.focus ? scope.domElement.focus() : window.focus();
37005 var mouseAction;
37006 switch ( event.button ) {
37007 case 0:
37008 mouseAction = scope.mouseButtons.LEFT;
37009 break;
37010 case 1:
37011 mouseAction = scope.mouseButtons.MIDDLE;
37012 break;
37013 case 2:
37014 mouseAction = scope.mouseButtons.RIGHT;
37015 break;
37016 default:
37017 mouseAction = - 1;
37018 }
37019 switch ( mouseAction ) {
37020 case MOUSE.DOLLY:
37021 if ( scope.enableZoom === false ) return;
37022 handleMouseDownDolly( event );
37023 state = STATE.DOLLY;
37024 break;
37025 case MOUSE.ROTATE:
37026 if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
37027 if ( scope.enablePan === false ) return;
37028 handleMouseDownPan( event );
37029 state = STATE.PAN;
37030 } else {
37031 if ( scope.enableRotate === false ) return;
37032 handleMouseDownRotate( event );
37033 state = STATE.ROTATE;
37034 }
37035 break;
37036 case MOUSE.PAN:
37037 if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
37038 if ( scope.enableRotate === false ) return;
37039 handleMouseDownRotate( event );
37040 state = STATE.ROTATE;
37041 } else {
37042 if ( scope.enablePan === false ) return;
37043 handleMouseDownPan( event );
37044 state = STATE.PAN;
37045 }
37046 break;
37047 default:
37048 state = STATE.NONE;
37049 }
37050 if ( state !== STATE.NONE ) {
37051 scope.domElement.ownerDocument.addEventListener( 'pointermove', onPointerMove, false );
37052 scope.domElement.ownerDocument.addEventListener( 'pointerup', onPointerUp, false );
37053 scope.dispatchEvent( startEvent );
37054 }
37055 }
37056 function onMouseMove( event ) {
37057 if ( scope.enabled === false ) return;
37058 event.preventDefault();
37059 switch ( state ) {
37060 case STATE.ROTATE:
37061 if ( scope.enableRotate === false ) return;
37062 handleMouseMoveRotate( event );
37063 break;
37064 case STATE.DOLLY:
37065 if ( scope.enableZoom === false ) return;
37066 handleMouseMoveDolly( event );
37067 break;
37068 case STATE.PAN:
37069 if ( scope.enablePan === false ) return;
37070 handleMouseMovePan( event );
37071 break;
37072 }
37073 }
37074 function onMouseUp( event ) {
37075 if ( scope.enabled === false ) return;
37076 scope.domElement.ownerDocument.removeEventListener( 'pointermove', onPointerMove, false );
37077 scope.domElement.ownerDocument.removeEventListener( 'pointerup', onPointerUp, false );
37078 scope.dispatchEvent( endEvent );
37079 state = STATE.NONE;
37080 }
37081 function onMouseWheel( event ) {
37082 if ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;
37083 event.preventDefault();
37084 event.stopPropagation();
37085 scope.dispatchEvent( startEvent );
37086 handleMouseWheel( event );
37087 scope.dispatchEvent( endEvent );
37088 }
37089 function onKeyDown( event ) {
37090 if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;
37091 handleKeyDown( event );
37092 }
37093 function onTouchStart( event ) {
37094 if ( scope.enabled === false ) return;
37095 event.preventDefault();
37096 switch ( event.touches.length ) {
37097 case 1:
37098 switch ( scope.touches.ONE ) {
37099 case TOUCH.ROTATE:
37100 if ( scope.enableRotate === false ) return;
37101 handleTouchStartRotate( event );
37102 state = STATE.TOUCH_ROTATE;
37103 break;
37104 case TOUCH.PAN:
37105 if ( scope.enablePan === false ) return;
37106 handleTouchStartPan( event );
37107 state = STATE.TOUCH_PAN;
37108 break;
37109 default:
37110 state = STATE.NONE;
37111 }
37112 break;
37113 case 2:
37114 switch ( scope.touches.TWO ) {
37115 case TOUCH.DOLLY_PAN:
37116 if ( scope.enableZoom === false && scope.enablePan === false ) return;
37117 handleTouchStartDollyPan( event );
37118 state = STATE.TOUCH_DOLLY_PAN;
37119 break;
37120 case TOUCH.DOLLY_ROTATE:
37121 if ( scope.enableZoom === false && scope.enableRotate === false ) return;
37122 handleTouchStartDollyRotate( event );
37123 state = STATE.TOUCH_DOLLY_ROTATE;
37124 break;
37125 default:
37126 state = STATE.NONE;
37127 }
37128 break;
37129 default:
37130 state = STATE.NONE;
37131 }
37132 if ( state !== STATE.NONE ) {
37133 scope.dispatchEvent( startEvent );
37134 }
37135 }
37136 function onTouchMove( event ) {
37137 if ( scope.enabled === false ) return;
37138 event.preventDefault();
37139 event.stopPropagation();
37140 switch ( state ) {
37141 case STATE.TOUCH_ROTATE:
37142 if ( scope.enableRotate === false ) return;
37143 handleTouchMoveRotate( event );
37144 scope.update();
37145 break;
37146 case STATE.TOUCH_PAN:
37147 if ( scope.enablePan === false ) return;
37148 handleTouchMovePan( event );
37149 scope.update();
37150 break;
37151 case STATE.TOUCH_DOLLY_PAN:
37152 if ( scope.enableZoom === false && scope.enablePan === false ) return;
37153 handleTouchMoveDollyPan( event );
37154 scope.update();
37155 break;
37156 case STATE.TOUCH_DOLLY_ROTATE:
37157 if ( scope.enableZoom === false && scope.enableRotate === false ) return;
37158 handleTouchMoveDollyRotate( event );
37159 scope.update();
37160 break;
37161 default:
37162 state = STATE.NONE;
37163 }
37164 }
37165 function onTouchEnd( event ) {
37166 if ( scope.enabled === false ) return;
37167 scope.dispatchEvent( endEvent );
37168 state = STATE.NONE;
37169 }
37170 function onContextMenu( event ) {
37171 if ( scope.enabled === false ) return;
37172 event.preventDefault();
37173 }
37174 scope.domElement.addEventListener( 'contextmenu', onContextMenu, false );
37175 scope.domElement.addEventListener( 'pointerdown', onPointerDown, false );
37176 scope.domElement.addEventListener( 'wheel', onMouseWheel, false );
37177 scope.domElement.addEventListener( 'touchstart', onTouchStart, false );
37178 scope.domElement.addEventListener( 'touchend', onTouchEnd, false );
37179 scope.domElement.addEventListener( 'touchmove', onTouchMove, false );
37180 scope.domElement.addEventListener( 'keydown', onKeyDown, false );
37181 if ( scope.domElement.tabIndex === - 1 ) {
37182 scope.domElement.tabIndex = 0;
37183 }
37184 this.update();
37185 };
37186 OrbitControls.prototype = Object.create( EventDispatcher.prototype );
37187 OrbitControls.prototype.constructor = OrbitControls;
37188 var MapControls = function ( object, domElement ) {
37189 OrbitControls.call( this, object, domElement );
37190 this.screenSpacePanning = false;
37191 this.mouseButtons.LEFT = MOUSE.PAN;
37192 this.mouseButtons.RIGHT = MOUSE.ROTATE;
37193 this.touches.ONE = TOUCH.PAN;
37194 this.touches.TWO = TOUCH.DOLLY_ROTATE;
37195 };
37196 MapControls.prototype = Object.create( EventDispatcher.prototype );
37197 MapControls.prototype.constructor = MapControls;
37198
37199 function createQuad(r, z = 0) {
37200 const vertices = [-r, -r, z, r, -r, z, r, r, z, -r, r, z];
37201 const indices = [0, 1, 2, 0, 2, 3];
37202 return { vertices, indices }
37203 }
37204 const unitQuad = createQuad(0.5, 0);
37205 function meshColor(color, mesh) {
37206 return color[mesh.options.colorType] || color
37207 }
37208 function disposeMesh(mesh) {
37209 mesh.parent.remove(mesh);
37210 mesh.geometry.dispose();
37211 mesh.material.dispose();
37212 if (mesh.material.map) mesh.material.map.dispose();
37213 forLoop(mesh.userData, (val, key) => delete mesh.userData[key]);
37214 }
37215 const zMultiplier = 0.25;
37216 const PI = Math.PI;
37217 class BaseMesh {
37218 constructor(view, options = {}) {
37219 options = Object.assign(this.constructor.options(view), options);
37220 const { scene, world } = view;
37221 Object.assign(this, { scene, world, view, options });
37222 this.mesh = null;
37223 this.name = this.constructor.name;
37224 }
37225 centerMesh() {
37226 let { centerX, centerY, width, height } = this.world;
37227 if (this.canvas) [centerX, centerY] = [0, 0];
37228 const z =
37229 this.view.meshes.patches === this &&
37230 this.view.options.turtles.meshClass === 'Obj3DMesh'
37231 ? this.world.minZ
37232 : this.options.z * zMultiplier;
37233 this.mesh.position.set(-centerX, -centerY, z);
37234 }
37235 init() {
37236 throw Error('init is abstract, must be overriden')
37237 }
37238 update() {
37239 throw Error('update is abstract, must be overriden')
37240 }
37241 get spriteSheetTexture() {
37242 if (this.view.spriteSheet.texture == null) {
37243 const texture = new three_module.CanvasTexture(
37244 this.view.spriteSheet.ctx.canvas
37245 );
37246 this.view.spriteSheet.texture = texture;
37247 }
37248 return this.view.spriteSheet.texture
37249 }
37250 }
37251 class NullMesh {
37252 constructor() {
37253 this.options = {};
37254 }
37255 init() {}
37256 update() {}
37257 }
37258 class CanvasMesh extends BaseMesh {
37259 static options(view) {
37260 return {
37261 textureOptions: {
37262 minFilter: three_module.LinearFilter,
37263 magFilter: three_module.LinearFilter,
37264 },
37265 z: 0.0,
37266 useSegments: false,
37267 canvas: view.patchesCanvas(),
37268 }
37269 }
37270 init() {
37271 if (this.mesh) disposeMesh(this.mesh);
37272 const { canvas, textureOptions, useSegments, z } = this.options;
37273 Object.assign(this, { canvas, z, textureOptions });
37274 const { width, height, centerX, centerY } = this.world;
37275 const texture = new three_module.CanvasTexture(canvas);
37276 Object.assign(texture, textureOptions);
37277 const geometry = new three_module.PlaneBufferGeometry(
37278 width,
37279 height,
37280 useSegments ? width : 1,
37281 useSegments ? height : 1
37282 );
37283 const material = new three_module.MeshBasicMaterial({
37284 map: texture,
37285 side: three_module.DoubleSide,
37286 transparent: true,
37287 });
37288 this.mesh = new three_module.Mesh(geometry, material);
37289 this.mesh.position.z = z;
37290 this.scene.add(this.mesh);
37291 }
37292 update() {
37293 this.mesh.material.map.needsUpdate = true;
37294 }
37295 }
37296 class PatchesMesh extends CanvasMesh {
37297 static options(view) {
37298 return {
37299 textureOptions: {
37300 minFilter: three_module.NearestFilter,
37301 magFilter: three_module.NearestFilter,
37302 },
37303 z: 0.0,
37304 useSegments: false,
37305 colorType: 'pixel',
37306 canvas: view.patchesCanvas(),
37307 }
37308 }
37309 init() {
37310 super.init();
37311 this.centerMesh();
37312 }
37313 update(data, viewFcn = d => d) {
37314 if (data) this.view.patchesView.setPixels(data, viewFcn);
37315 this.view.patchesView.updateCanvas();
37316 super.update();
37317 }
37318 }
37319 class QuadSpritesMesh extends BaseMesh {
37320 static options() {
37321 return {
37322 z: 2.0,
37323 colorType: 'css',
37324 }
37325 }
37326 init() {
37327 if (this.mesh) disposeMesh(this.mesh);
37328 const texture = this.spriteSheetTexture;
37329 const geometry = new three_module.BufferGeometry();
37330 geometry.setAttribute(
37331 'position',
37332 new three_module.Float32BufferAttribute([], 3)
37333 );
37334 geometry.setAttribute('uv', new three_module.Float32BufferAttribute([], 2));
37335 geometry.setIndex(new three_module.Uint32BufferAttribute([], 1));
37336 const material = new three_module.MeshBasicMaterial({
37337 map: texture,
37338 alphaTest: 0.5,
37339 side: three_module.DoubleSide,
37340 });
37341 this.mesh = new three_module.Mesh(geometry, material);
37342 this.centerMesh();
37343 this.scene.add(this.mesh);
37344 }
37345 update(turtles, viewFcn) {
37346 const { vertices, indices } = unitQuad;
37347 const positions = new Float32Array(vertices.length * turtles.length);
37348 const uvs = [];
37349 const indexes = [];
37350 forLoop(turtles, (turtle, i) => {
37351 if (turtle.hidden) return
37352 let { x, y, z, theta } = turtle;
37353 const viewData = viewFcn(turtle, i);
37354 let { size, sprite } = viewData;
37355 if (!sprite)
37356 sprite = this.view.getSprite(
37357 viewData.shape,
37358 meshColor(viewData.color, this)
37359 );
37360 const cos = Math.cos(theta);
37361 const sin = Math.sin(theta);
37362 const offset = i * vertices.length;
37363 for (let j = 0; j < vertices.length; j = j + 3) {
37364 const x0 = vertices[j];
37365 const y0 = vertices[j + 1];
37366 positions[j + offset] = size * (x0 * cos - y0 * sin) + x;
37367 positions[j + offset + 1] = size * (x0 * sin + y0 * cos) + y;
37368 positions[j + offset + 2] = z;
37369 }
37370 indexes.push(...indices.map(ix => ix + i * 4));
37371 uvs.push(...sprite.uvs);
37372 });
37373 this.mesh.geometry.setAttribute(
37374 'position',
37375 new three_module.BufferAttribute(positions, 3)
37376 );
37377 this.mesh.geometry.setAttribute(
37378 'uv',
37379 new three_module.Float32BufferAttribute(uvs, 2)
37380 );
37381 this.mesh.geometry.setIndex(new three_module.Uint32BufferAttribute(indexes, 1));
37382 }
37383 }
37384 class PointsMesh extends BaseMesh {
37385 static options() {
37386 return {
37387 size: 1,
37388 color: null,
37389 z: 2.5,
37390 colorType: 'webgl',
37391 }
37392 }
37393 init() {
37394 if (this.mesh) disposeMesh(this.mesh);
37395 const size = this.options.size;
37396 this.fixedColor = this.options.color
37397 ? new three_module.Color(...meshColor(this.options.color, this))
37398 : null;
37399 const geometry = new three_module.BufferGeometry();
37400 geometry.setAttribute(
37401 'position',
37402 new three_module.Float32BufferAttribute([], 3)
37403 );
37404 if (!this.fixedColor) {
37405 geometry.setAttribute(
37406 'color',
37407 new three_module.Float32BufferAttribute([], 3)
37408 );
37409 }
37410 const material = this.fixedColor
37411 ? new three_module.PointsMaterial({
37412 size: size,
37413 color: this.fixedColor,
37414 })
37415 : new three_module.PointsMaterial({
37416 size: size,
37417 vertexColors: true,
37418 });
37419 this.mesh = new three_module.Points(geometry, material);
37420 this.centerMesh();
37421 this.scene.add(this.mesh);
37422 }
37423 update(agents, viewFcn) {
37424 const vertices = [];
37425 const colors = this.fixedColor ? null : [];
37426 forLoop(agents, (agent, i) => {
37427 if (agent.hidden) return
37428 let { x, y, z } = agent;
37429 vertices.push(x, y, z);
37430 if (colors) colors.push(...meshColor(viewFcn(agent, i).color, this));
37431 });
37432 this.mesh.geometry.setAttribute(
37433 'position',
37434 new three_module.Float32BufferAttribute(vertices, 3)
37435 );
37436 if (colors) {
37437 this.mesh.geometry.setAttribute(
37438 'color',
37439 new three_module.Float32BufferAttribute(colors, 3)
37440 );
37441 }
37442 }
37443 }
37444 class LinksMesh extends BaseMesh {
37445 static options() {
37446 return {
37447 color: null,
37448 z: 1,
37449 colorType: 'webgl',
37450 }
37451 }
37452 init() {
37453 if (this.mesh) disposeMesh(this.mesh);
37454 this.fixedColor = this.options.color
37455 ? new three_module.Color(...meshColor(this.options.color, this))
37456 : null;
37457 const geometry = new three_module.BufferGeometry();
37458 geometry.setAttribute(
37459 'position',
37460 new three_module.Float32BufferAttribute([], 3)
37461 );
37462 if (!this.fixedColor) {
37463 geometry.setAttribute(
37464 'color',
37465 new three_module.Float32BufferAttribute([], 3)
37466 );
37467 }
37468 const material = this.fixedColor
37469 ? new three_module.LineBasicMaterial({ color: this.fixedColor })
37470 : new three_module.LineBasicMaterial({ vertexColors: true });
37471 this.mesh = new three_module.LineSegments(geometry, material);
37472 this.centerMesh();
37473 this.scene.add(this.mesh);
37474 }
37475 update(links, viewFcn) {
37476 const vertices = [];
37477 const colors = this.fixedColor ? null : [];
37478 forLoop(links, (link, i) => {
37479 let { x0, y0, z0, x1, y1, z1 } = link;
37480 if (!z0) z0 = 0;
37481 if (!z1) z1 = 0;
37482 vertices.push(x0, y0, z0, x1, y1, z1);
37483 if (colors) {
37484 const color = meshColor(viewFcn(link, i).color, this);
37485 colors.push(...color, ...color);
37486 }
37487 });
37488 this.mesh.geometry.setAttribute(
37489 'position',
37490 new three_module.Float32BufferAttribute(vertices, 3)
37491 );
37492 if (colors) {
37493 this.mesh.geometry.setAttribute(
37494 'color',
37495 new three_module.Float32BufferAttribute(colors, 3)
37496 );
37497 }
37498 }
37499 }
37500 const geometries = {
37501 Dart: () => turtleGeometry(),
37502 Cone0: () => new three_module.ConeBufferGeometry(0.5).rotateX(PI / 2),
37503 Cone: () => new three_module.ConeBufferGeometry(0.5).rotateZ(-PI / 2),
37504 Cube: () => new three_module.BoxBufferGeometry(),
37505 Cylinder0: () =>
37506 new three_module.CylinderBufferGeometry(0.5, 0.5, 1).rotateX(PI / 2),
37507 Cylinder: () =>
37508 new three_module.CylinderBufferGeometry(0.5, 0.5, 1).rotateZ(-PI / 2),
37509 Sphere: () => new three_module.SphereBufferGeometry(0.5),
37510 };
37511 const Obj3DShapes = AgentArray.fromArray(Object.keys(geometries));
37512 function getGeometry(shape) {
37513 let geometry = geometries[shape];
37514 if (!geometry) {
37515 console.log('Geometry not found: ', shape, '..using Default');
37516 shape = 'Dart';
37517 geometry = geometries[shape];
37518 }
37519 return [geometry(), shape]
37520 }
37521 class Obj3DMesh extends BaseMesh {
37522 static options() {
37523 return {
37524 z: 2.0,
37525 colorType: 'webgl',
37526 useAxes: false,
37527 }
37528 }
37529 init() {
37530 if (this.meshes) this.meshes.forEach(mesh => disposeMesh(mesh));
37531 this.meshes = new Map();
37532 this.lastAgentsLength = null;
37533 this.lastAgentsMaxID = null;
37534 }
37535 newMesh(shape = 'Dart', color = 'red', size = 1) {
37536 var [geometry, shape] = getGeometry(shape);
37537 if (size !== 1) geometry.scale(size, size, size);
37538 const view = { shape, color, size };
37539 color = new three_module.Color(...meshColor(color, this));
37540 const material = this.view.options.useLights
37541 ? new three_module.MeshPhongMaterial({ color })
37542 : new three_module.MeshBasicMaterial({ color });
37543 const mesh = new three_module.Mesh(geometry, material);
37544 mesh.rotation.order = 'ZYX';
37545 if (this.options.useAxes) mesh.add(new three_module.AxesHelper(size));
37546 mesh.userData.view = view;
37547 this.scene.add(mesh);
37548 return mesh
37549 }
37550 checkDeadAgents(agents) {
37551 const lastLen = this.lastAgentsLength;
37552 const lastID = this.lastAgentsMaxID;
37553 if (lastLen === 0) return
37554 if (
37555 lastLen != null &&
37556 (lastLen > agents.length || agents.last().id !== lastID)
37557 ) {
37558 console.log('look for dead agents');
37559 this.meshes.forEach((mesh, agent) => {
37560 if (mesh.userData.agent.id === -1) {
37561 console.log('found one:', mesh.userData.agent);
37562 disposeMesh(mesh);
37563 this.meshes.delete(agent);
37564 }
37565 });
37566 }
37567 this.lastAgentsLength = agents.length;
37568 this.lastAgentsMaxID = agents.length === 0 ? null : agents.last().id;
37569 }
37570 update(agents, viewFcn) {
37571 this.checkDeadAgents(agents);
37572 if (agents.hidden) return
37573 forLoop(agents, agent => {
37574 if (agent.hidden) return
37575 const view = viewFcn(agent);
37576 let mesh = this.meshes.get(agent);
37577 if (mesh) {
37578 var { shape, color, size } = mesh.userData.view;
37579 if (color !== view.color) {
37580 color = mesh.userData.view.color = view.color;
37581 color = new three_module.Color(...meshColor(color, this));
37582 mesh.material.color = color;
37583 }
37584 if (shape !== view.shape) {
37585 var [geometry, shape] = getGeometry(view.shape);
37586 mesh.geometry.dispose();
37587 mesh.geometry = geometry;
37588 mesh.geometry.scale(size, size, size);
37589 mesh.userData.view.shape = shape;
37590 }
37591 if (size !== view.size) {
37592 size = view.size / size;
37593 mesh.geometry.scale(size, size, size);
37594 mesh.userData.view.size = view.size;
37595 }
37596 }
37597 if (!mesh) {
37598 mesh = this.newMesh(view.shape, view.color, view.size);
37599 this.meshes.set(agent, mesh);
37600 mesh.userData.agent = agent;
37601 }
37602 const obj3d = agent.obj3d;
37603 if (obj3d) {
37604 const pos = obj3d.position;
37605 mesh.position.set(pos.x, pos.y, pos.z);
37606 const rot = obj3d.rotation;
37607 mesh.rotation.set(rot.x, rot.y, rot.z);
37608 } else {
37609 mesh.position.set(agent.x, agent.y, agent.z);
37610 mesh.rotation.set(0, 0, 0);
37611 }
37612 });
37613 }
37614 }
37615 function turtleGeometry() {
37616 const ax = 0.5;
37617 const bx = -0.5;
37618 const by = -0.5;
37619 const cx = -0.3;
37620 const top = 0.35;
37621 const bot = 0;
37622 const geometry = new three_module.Geometry();
37623 geometry.vertices.push(
37624 new three_module.Vector3(ax, 0, bot),
37625 new three_module.Vector3(bx, by, bot),
37626 new three_module.Vector3(cx, 0, top),
37627 new three_module.Vector3(bx, -by, bot),
37628 new three_module.Vector3(cx, 0, bot)
37629 );
37630 const [A, B, C, D, E] = [0, 1, 2, 3, 4];
37631 geometry.faces.push(
37632 new three_module.Face3(A, D, C),
37633 new three_module.Face3(A, C, B),
37634 new three_module.Face3(A, B, E),
37635 new three_module.Face3(A, E, D),
37636 new three_module.Face3(C, D, E),
37637 new three_module.Face3(C, E, B)
37638 );
37639 geometry.computeFaceNormals();
37640 return geometry
37641 }
37642 var ThreeMeshes = {
37643 BaseMesh,
37644 NullMesh,
37645 CanvasMesh,
37646 PatchesMesh,
37647 QuadSpritesMesh,
37648 PointsMesh,
37649 LinksMesh,
37650 Obj3DMesh,
37651 Obj3DShapes,
37652 };
37653
37654 class ThreeView {
37655 static shapeNames() {
37656 return ThreeMeshes.Obj3DShapes
37657 }
37658 static defaultOptions(useThreeHelpers = true) {
37659 const options = {
37660 div: document.body,
37661 orthoView: false,
37662 clearColor: 0x000000,
37663 useAxes: useThreeHelpers,
37664 useGrid: useThreeHelpers,
37665 useWorldOutline: useThreeHelpers,
37666 useLights: true,
37667 spriteSize: 64,
37668 patches: {
37669 meshClass: 'PatchesMesh',
37670 },
37671 turtles: {
37672 meshClass: 'QuadSpritesMesh',
37673 },
37674 links: {
37675 meshClass: 'LinksMesh',
37676 },
37677 };
37678 return options
37679 }
37680 constructor(
37681 world = World.defaultOptions(),
37682 options = {}
37683 ) {
37684 options = Object.assign(ThreeView.defaultOptions(), options);
37685 options.useLights =
37686 options.useLights || options.turtles.meshClass === 'Obj3DMesh';
37687 this.div = isString(options.div)
37688 ? document.getElementById(options.div)
37689 : options.div;
37690 if (!this.div.height) this.div.style.height = '600px';
37691 this.world = new World(world.world || world);
37692 this.options = options;
37693 this.ticks = 0;
37694 if (this.options.spriteSize !== 0) {
37695 const isPOT = isPowerOf2(this.options.spriteSize);
37696 this.spriteSheet = new SpriteSheet(
37697 this.options.spriteSize,
37698 16,
37699 isPOT
37700 );
37701 }
37702 if (options.patches && options.patches.meshClass === 'PatchesMesh') {
37703 this.patchesView = new PatchesView(
37704 this.world.width,
37705 this.world.height
37706 );
37707 }
37708 this.initThree();
37709 this.initThreeHelpers();
37710 this.initMeshes();
37711 }
37712 initThree() {
37713 const { clientWidth, clientHeight } = this.div;
37714 const { orthoView, clearColor } = this.options;
37715 const [width, height] = this.world.getWorldSize();
37716 const [halfW, halfH] = [width / 2, height / 2];
37717 const orthographicCam = new three_module.OrthographicCamera(
37718 -halfW,
37719 halfW,
37720 halfH,
37721 -halfH,
37722 1,
37723 20 * width
37724 );
37725 orthographicCam.position.set(0, 0, 10 * width);
37726 orthographicCam.up.set(0, 0, 1);
37727 const perspectiveCam = new three_module.PerspectiveCamera(
37728 45,
37729 clientWidth / clientHeight,
37730 0.1,
37731 10000
37732 );
37733 perspectiveCam.position.set(width, width, width);
37734 perspectiveCam.up.set(0, 0, 1);
37735 const scene = new three_module.Scene();
37736 const camera = orthoView ? orthographicCam : perspectiveCam;
37737 const renderer = new three_module.WebGLRenderer();
37738 renderer.setPixelRatio(window.devicePixelRatio);
37739 renderer.setSize(clientWidth, clientHeight);
37740 renderer.setClearColor(clearColor);
37741 this.div.appendChild(renderer.domElement);
37742 this.orbitControls = new OrbitControls(camera, renderer.domElement);
37743 window.addEventListener('resize', () => {
37744 this.resize();
37745 });
37746 Object.assign(this, {
37747 scene,
37748 camera,
37749 renderer,
37750 orthographicCam,
37751 perspectiveCam,
37752 });
37753 }
37754 resize() {
37755 const { clientWidth, clientHeight } = this.div;
37756 const [width, height] = this.world.getWorldSize();
37757 if (this.options.orthoView) {
37758 const zoom = Math.min(clientWidth / width, clientHeight / height);
37759 this.renderer.setSize(zoom * width, zoom * height);
37760 } else {
37761 this.camera.aspect = clientWidth / clientHeight;
37762 this.camera.updateProjectionMatrix();
37763 this.renderer.setSize(clientWidth, clientHeight);
37764 }
37765 }
37766 toggleCamera() {
37767 this.options.orthoView = !this.options.orthoView;
37768 if (this.options.orthoView) {
37769 this.camera = this.orthographicCam;
37770 } else {
37771 this.camera = this.perspectiveCam;
37772 }
37773 this.resize();
37774 this.renderer.render(this.scene, this.camera);
37775 }
37776 snapshot(useOrtho = true) {
37777 const { scene, renderer, model } = this;
37778 const toggle = useOrtho && this.camera === this.perspectiveCam;
37779 if (toggle) {
37780 this.toggleCamera();
37781 }
37782 renderer.render(scene, this.camera);
37783 const durl = renderer.domElement.toDataURL();
37784 if (toggle) this.toggleCamera();
37785 return durl
37786 }
37787 initThreeHelpers() {
37788 const { scene, renderer, camera, world } = this;
37789 const {
37790 useAxes,
37791 useGrid,
37792 useLights,
37793 useWorldOutline,
37794 } = this.options;
37795 const { width, height, depth, minZ } = this.world;
37796 const helpers = {};
37797 if (useAxes) {
37798 helpers.axes = new three_module.AxesHelper((1.5 * width) / 2);
37799 scene.add(helpers.axes);
37800 }
37801 if (useGrid) {
37802 helpers.grid = new three_module.GridHelper(1.25 * width, 10);
37803 helpers.grid.rotation.x = three_module.Math.degToRad(90);
37804 helpers.grid.position.z = minZ;
37805 scene.add(helpers.grid);
37806 }
37807 if (useLights) {
37808 const width = world.width;
37809 helpers.directionalLight = new three_module.DirectionalLight(0xffffff, 1);
37810 helpers.directionalLight.position.set(width, width, width);
37811 scene.add(helpers.directionalLight);
37812 helpers.diffuseLight = new three_module.AmbientLight(0x404040);
37813 scene.add(helpers.diffuseLight);
37814 }
37815 if (useWorldOutline) {
37816 const geometry = new three_module.BoxBufferGeometry(width, height, depth);
37817 const edges = new three_module.EdgesGeometry(geometry);
37818 helpers.outline = new three_module.LineSegments(
37819 edges,
37820 new three_module.LineBasicMaterial({ color: 0x80808080 })
37821 );
37822 scene.add(helpers.outline);
37823 }
37824 this.helpers = helpers;
37825 }
37826 initMeshes() {
37827 this.meshes = {};
37828 forLoop(this.options, (val, key) => {
37829 if (val.meshClass && val.meshClass !== 'NullMesh') {
37830 const Mesh = ThreeMeshes[val.meshClass];
37831 const options = val;
37832 const mesh = new Mesh(this, options);
37833 this.meshes[key] = mesh;
37834 mesh.init();
37835 }
37836 });
37837 }
37838 setPatchesSmoothing(smooth = false) {
37839 const filter = smooth ? three_module.LinearFilter : three_module.NearestFilter;
37840 this.meshes.patches.mesh.material.map.magFilter = filter;
37841 }
37842 idle(ms = 32) {
37843 timeoutLoop(() => this.render(), -1, ms);
37844 }
37845 render() {
37846 this.renderer.render(this.scene, this.camera);
37847 this.ticks++;
37848 }
37849 getSprite(shape, fillColor, strokeColor = null) {
37850 return this.spriteSheet.getSprite(shape, fillColor, strokeColor)
37851 }
37852 checkViewFcn(viewFcn) {
37853 return isObject$1(viewFcn) ? () => viewFcn : viewFcn
37854 }
37855 patchesCanvas() {
37856 return this.patchesView.ctx.canvas
37857 }
37858 clearPatches(color) {
37859 this.patchesView.clear(color);
37860 this.meshes.patches.update();
37861 }
37862 drawPatchesImage(img) {
37863 const options = this.meshes.patches.options;
37864 options.textureOptions = {
37865 minFilter: three_module.NearestFilter,
37866 magFilter: three_module.LinearFilter,
37867 };
37868 options.canvas = img;
37869 this.meshes.patches.init();
37870 }
37871 createPatchPixels(pixelFcn) {
37872 this.patchesView.createPixels(pixelFcn);
37873 const data = this.patchesView.pixels;
37874 this.meshes.patches.update(data, d => d);
37875 }
37876 drawPatches(data, viewFcn) {
37877 if (isOofA(data)) data = toAofO(data);
37878 this.meshes.patches.update(data, viewFcn);
37879 }
37880 drawTurtles(data, viewFcn) {
37881 if (isOofA(data)) data = toAofO(data);
37882 viewFcn = this.checkViewFcn(viewFcn);
37883 this.meshes.turtles.update(data, viewFcn);
37884 }
37885 drawLinks(data, viewFcn) {
37886 if (isOofA(data)) data = toAofO(data);
37887 viewFcn = this.checkViewFcn(viewFcn);
37888 this.meshes.links.update(data, viewFcn);
37889 }
37890 }
37891
37892 function isStaticColor(color) {
37893 return !isDynamicColor(color)
37894 }
37895 function isDynamicColor(color) {
37896 return (
37897 color === 'random' || isImageable(color) || isFunction(color)
37898 )
37899 }
37900 class ThreeDraw extends ThreeView {
37901 static defaultOptions() {
37902 return {
37903 patchesMesh: null,
37904 turtlesMesh: null,
37905 linksMesh: null,
37906 patchesColor: 'random',
37907 patchesSize: 1,
37908 initPatches: null,
37909 turtlesColor: 'random',
37910 turtlesShape: 'dart',
37911 turtlesSize: 1,
37912 linksColor: 'random',
37913 linksWidth: 1,
37914 patchesMap: 'DarkGray',
37915 turtlesMap: 'Basic16',
37916 }
37917 }
37918 constructor(model, viewOptions = {}, drawOptions = {}) {
37919 if (viewOptions.drawOptions) {
37920 drawOptions = viewOptions.drawOptions;
37921 delete viewOptions.drawOptions;
37922 }
37923 drawOptions = Object.assign(ThreeDraw.defaultOptions(), drawOptions);
37924 if (typeof drawOptions.turtlesMap === 'string')
37925 drawOptions.turtlesMap = ColorMap[drawOptions.turtlesMap];
37926 if (typeof drawOptions.patchesMap === 'string')
37927 drawOptions.patchesMap = ColorMap[drawOptions.patchesMap];
37928 const { patches, turtles, links } = Object.assign(
37929 ThreeView.defaultOptions(),
37930 viewOptions
37931 );
37932 const meshes = { patches, turtles, links };
37933 for (const mesh of ['patches', 'turtles', 'links']) {
37934 const meshName = mesh + 'Mesh';
37935 if (drawOptions[meshName]) {
37936 const option = drawOptions[meshName];
37937 meshes[mesh] =
37938 typeof option === 'string' ? { meshClass: option } : option;
37939 }
37940 const color = mesh + 'Color';
37941 if (isStaticColor(drawOptions[color])) {
37942 drawOptions[color] = Color$1.toTypedColor(drawOptions[color]);
37943 meshes[mesh].color = drawOptions[color];
37944 }
37945 const size = mesh + 'Size';
37946 if (typeof drawOptions[size] === 'number') {
37947 meshes[mesh].size = drawOptions[size];
37948 }
37949 }
37950 Object.assign(viewOptions, meshes);
37951 super(model.world, viewOptions);
37952 console.log('viewOptions', viewOptions);
37953 console.log('drawOptions', drawOptions);
37954 console.log('meshes', meshes);
37955 if (this.meshName('patches') === 'PatchesMesh') {
37956 if (drawOptions.initPatches) {
37957 const colors = drawOptions.initPatches(model, this);
37958 this.createPatchPixels(i => colors[i]);
37959 } else if (drawOptions.patchesColor === 'random') {
37960 this.createPatchPixels(i =>
37961 drawOptions.patchesMap.randomColor()
37962 );
37963 }
37964 }
37965 this.checkParams(drawOptions);
37966 Object.assign(this, { model, view: this, drawOptions });
37967 }
37968 checkParams(params) {
37969 const keys = Object.keys(params);
37970 const defaults = ThreeDraw.defaultOptions();
37971 keys.forEach(k => {
37972 if (defaults[k] === undefined) {
37973 console.log(
37974 'Legal ThreeDraw parameters',
37975 Object.keys(ThreeDraw.defaultOptions())
37976 );
37977 throw Error('Unknown ThreeDraw parameter: ' + k)
37978 }
37979 });
37980 }
37981 getMesh(agentSet) {
37982 return this.meshes[agentSet]
37983 }
37984 meshName(agentSet) {
37985 return this.meshes[agentSet].name
37986 }
37987 draw() {
37988 let {
37989 patchesColor,
37990 patchesShape,
37991 patchesSize,
37992 initPatches,
37993 turtlesColor,
37994 turtlesShape,
37995 turtlesSize,
37996 linksColor,
37997 linksWidth,
37998 patchesMap,
37999 turtlesMap,
38000 } = this.drawOptions;
38001 const { model, view } = this;
38002 const getColor = (agent, color, map) =>
38003 color === 'random'
38004 ? map.atIndex(agent.id)
38005 : typeof color === 'function'
38006 ? checkColor(agent, color(agent))
38007 : color;
38008 const getShape = (agent, shape) =>
38009 typeof shape === 'function' ? shape(agent) : shape;
38010 const getSize = (agent, size) =>
38011 typeof size === 'function' ? size(agent) : size;
38012 const checkColor = (agent, color, map = turtlesMap) =>
38013 color === 'random'
38014 ? map.atIndex(agent.id)
38015 : Color$1.toTypedColor(color);
38016 let lastImage, lastClearColor;
38017 if (this.meshName('patches') === 'PatchesMesh') {
38018 if (patchesColor === 'random' || initPatches) ; else if (typeof patchesColor === 'function') {
38019 view.drawPatches(model.patches, p => patchesColor(p));
38020 } else if (isImageable(patchesColor)) {
38021 if (patchesColor !== lastImage) {
38022 view.drawPatchesImage(patchesColor);
38023 lastImage = patchesColor;
38024 }
38025 } else {
38026 if (patchesColor !== lastClearColor) {
38027 view.clearPatches(patchesColor);
38028 lastClearColor = patchesColor;
38029 }
38030 }
38031 } else {
38032 view.drawPatches(model.patches, p => ({
38033 shape: getShape(p, patchesShape),
38034 color: getColor(p, patchesColor, patchesMap),
38035 size: getSize(p, patchesSize),
38036 }));
38037 }
38038 view.drawLinks(model.links, l => ({
38039 color: getColor(l, linksColor, turtlesMap),
38040 width: linksWidth,
38041 }));
38042 view.drawTurtles(model.turtles, t => ({
38043 shape: getShape(t, turtlesShape),
38044 color: getColor(t, turtlesColor, turtlesMap),
38045 size: getSize(t, turtlesSize),
38046 }));
38047 view.render();
38048 }
38049 }
38050
38051 var Stats = function () {
38052 var mode = 0;
38053 var container = document.createElement( 'div' );
38054 container.style.cssText = 'position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000';
38055 container.addEventListener( 'click', function ( event ) {
38056 event.preventDefault();
38057 showPanel( ++ mode % container.children.length );
38058 }, false );
38059 function addPanel( panel ) {
38060 container.appendChild( panel.dom );
38061 return panel;
38062 }
38063 function showPanel( id ) {
38064 for ( var i = 0; i < container.children.length; i ++ ) {
38065 container.children[ i ].style.display = i === id ? 'block' : 'none';
38066 }
38067 mode = id;
38068 }
38069 var beginTime = ( performance || Date ).now(), prevTime = beginTime, frames = 0;
38070 var fpsPanel = addPanel( new Stats.Panel( 'FPS', '#0ff', '#002' ) );
38071 var msPanel = addPanel( new Stats.Panel( 'MS', '#0f0', '#020' ) );
38072 if ( self.performance && self.performance.memory ) {
38073 var memPanel = addPanel( new Stats.Panel( 'MB', '#f08', '#201' ) );
38074 }
38075 showPanel( 0 );
38076 return {
38077 REVISION: 16,
38078 dom: container,
38079 addPanel: addPanel,
38080 showPanel: showPanel,
38081 begin: function () {
38082 beginTime = ( performance || Date ).now();
38083 },
38084 end: function () {
38085 frames ++;
38086 var time = ( performance || Date ).now();
38087 msPanel.update( time - beginTime, 200 );
38088 if ( time >= prevTime + 1000 ) {
38089 fpsPanel.update( ( frames * 1000 ) / ( time - prevTime ), 100 );
38090 prevTime = time;
38091 frames = 0;
38092 if ( memPanel ) {
38093 var memory = performance.memory;
38094 memPanel.update( memory.usedJSHeapSize / 1048576, memory.jsHeapSizeLimit / 1048576 );
38095 }
38096 }
38097 return time;
38098 },
38099 update: function () {
38100 beginTime = this.end();
38101 },
38102 domElement: container,
38103 setMode: showPanel
38104 };
38105 };
38106 Stats.Panel = function ( name, fg, bg ) {
38107 var min = Infinity, max = 0, round = Math.round;
38108 var PR = round( window.devicePixelRatio || 1 );
38109 var WIDTH = 80 * PR, HEIGHT = 48 * PR,
38110 TEXT_X = 3 * PR, TEXT_Y = 2 * PR,
38111 GRAPH_X = 3 * PR, GRAPH_Y = 15 * PR,
38112 GRAPH_WIDTH = 74 * PR, GRAPH_HEIGHT = 30 * PR;
38113 var canvas = document.createElement( 'canvas' );
38114 canvas.width = WIDTH;
38115 canvas.height = HEIGHT;
38116 canvas.style.cssText = 'width:80px;height:48px';
38117 var context = canvas.getContext( '2d' );
38118 context.font = 'bold ' + ( 9 * PR ) + 'px Helvetica,Arial,sans-serif';
38119 context.textBaseline = 'top';
38120 context.fillStyle = bg;
38121 context.fillRect( 0, 0, WIDTH, HEIGHT );
38122 context.fillStyle = fg;
38123 context.fillText( name, TEXT_X, TEXT_Y );
38124 context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT );
38125 context.fillStyle = bg;
38126 context.globalAlpha = 0.9;
38127 context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT );
38128 return {
38129 dom: canvas,
38130 update: function ( value, maxValue ) {
38131 min = Math.min( min, value );
38132 max = Math.max( max, value );
38133 context.fillStyle = bg;
38134 context.globalAlpha = 1;
38135 context.fillRect( 0, 0, WIDTH, GRAPH_Y );
38136 context.fillStyle = fg;
38137 context.fillText( round( value ) + ' ' + name + ' (' + round( min ) + '-' + round( max ) + ')', TEXT_X, TEXT_Y );
38138 context.drawImage( canvas, GRAPH_X + PR, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT, GRAPH_X, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT );
38139 context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, GRAPH_HEIGHT );
38140 context.fillStyle = bg;
38141 context.globalAlpha = 0.9;
38142 context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, round( ( 1 - ( value / maxValue ) ) * GRAPH_HEIGHT ) );
38143 }
38144 };
38145 };
38146
38147 class Animator {
38148 constructor(fcn, steps = -1, fps = 30) {
38149 Object.assign(this, { fcn, steps, fps, timeoutID: null, ticks: 0 });
38150 this.start();
38151 }
38152 start() {
38153 if (this.timeoutID) return
38154 this.timeoutID = setInterval(() => this.step(), 1000 / this.fps);
38155 return this
38156 }
38157 stop() {
38158 if (this.timeoutID) clearInterval(this.timeoutID);
38159 this.timeoutID = null;
38160 return this
38161 }
38162 step() {
38163 if (this.ticks === this.steps) return this.stop()
38164 this.ticks++;
38165 this.fcn();
38166 if (this.stats) this.stats.update();
38167 return this
38168 }
38169 isRunning() {
38170 return this.timeoutID != null
38171 }
38172 startStats(left = '0px') {
38173 if (this.stats) return console.log('startStats: already running')
38174 this.stats = new Stats();
38175 document.body.appendChild(this.stats.dom);
38176 this.stats.dom.style.left = left;
38177 return this
38178 }
38179 setFps(fps) {
38180 this.reset(this.steps, fps);
38181 }
38182 setSteps(steps) {
38183 this.reset(steps, this.fps);
38184 }
38185 reset(steps = this.steps, fps = this.fps) {
38186 this.stop();
38187 this.steps = steps;
38188 this.ticks = 0;
38189 this.fps = fps;
38190 this.start();
38191 }
38192 toggle() {
38193 if (this.timeoutID) this.stop();
38194 else if (this.steps === 0) this.reset();
38195 else this.start();
38196 }
38197 once() {
38198 this.stop();
38199 this.step();
38200 }
38201 }
38202
38203 class Evented {
38204 events = {}
38205 on(name, callback) {
38206 if (!this.events[name]) {
38207 this.events[name] = [];
38208 }
38209 this.events[name].push(callback);
38210 return callback
38211 }
38212 off(name, callback = null) {
38213 if (this.events[name]) {
38214 if (callback) {
38215 this.events[name] = this.events[name].filter(
38216 cb => cb !== callback
38217 );
38218 }
38219 if (this.events[name].length === 0 || !callback) {
38220 delete this.events[name];
38221 }
38222 }
38223 }
38224 emit(name, ...args) {
38225 if (this.events[name]) {
38226 this.events[name].forEach(callback => callback(...args));
38227 }
38228 }
38229 }
38230
38231 class Mouse {
38232 constructor(canvas, world, callback = (evt, mouse) => {}) {
38233 if (typeof canvas === 'string') {
38234 canvas = document.getElementById(canvas);
38235 }
38236 Object.assign(this, { canvas, world, callback });
38237 this.mouseDown = e => this.handleMouseDown(e);
38238 this.mouseUp = e => this.handleMouseUp(e);
38239 this.mouseMove = e => this.handleMouseMove(e);
38240 }
38241 resetParams() {
38242 this.x = this.y = NaN;
38243 this.moved = this.down = false;
38244 }
38245 start() {
38246 this.canvas.addEventListener('mousedown', this.mouseDown);
38247 document.body.addEventListener('mouseup', this.mouseUp);
38248 this.canvas.addEventListener('mousemove', this.mouseMove);
38249 this.resetParams();
38250 return this
38251 }
38252 stop() {
38253 this.canvas.removeEventListener('mousedown', this.mouseDown);
38254 document.body.removeEventListener('mouseup', this.mouseUp);
38255 this.canvas.removeEventListener('mousemove', this.mouseMove);
38256 this.resetParams();
38257 return this
38258 }
38259 get running() {
38260 return !isNaN(this.x)
38261 }
38262 run(on = true) {
38263 if (on) this.start();
38264 else this.stop();
38265 }
38266 generalHandler(e, down, moved) {
38267 this.down = down;
38268 this.moved = moved;
38269 this.setXY(e);
38270 this.callback(this, e);
38271 }
38272 handleMouseDown(e) {
38273 this.action = 'down';
38274 this.generalHandler(e, true, false);
38275 }
38276 handleMouseUp(e) {
38277 this.action = 'up';
38278 this.generalHandler(e, false, false);
38279 }
38280 handleMouseMove(e) {
38281 this.action = this.down ? 'drag' : 'move';
38282 this.generalHandler(e, this.down, true);
38283 }
38284 setXY(e) {
38285 const { canvas, world } = this;
38286 const patchSize = world.patchSize(canvas);
38287 const rect = this.canvas.getBoundingClientRect();
38288 const pixX = e.clientX - rect.left;
38289 const pixY = e.clientY - rect.top
38290 ;[this.x, this.y] = world.pixelXYtoPatchXY(pixX, pixY, patchSize);
38291 }
38292 }
38293
38294 function isGeojson(obj) {
38295 return typeof obj === 'object' && obj.type === 'FeatureCollection'
38296 }
38297 function clone(json) {
38298 return JSON.parse(JSON.stringify(json))
38299 }
38300 function minify(json) {
38301 if (typeof json === 'string') json = JSON.parse(json);
38302 const str = JSON.stringify(json);
38303 return str.replace(/},{/g, '},\n\n{')
38304 }
38305 function bboxFeature(bbox, properties = {}) {
38306 const coords = bboxCoords(bbox);
38307 coords.push(coords[0]);
38308 return {
38309 type: 'Feature',
38310 geometry: {
38311 cordinates: coords,
38312 type: 'Polygon',
38313 },
38314 properties,
38315 }
38316 }
38317 function flattenMultiLineStrings(geojson, cloneJson = true) {
38318 if (cloneJson) geojson = clone(geojson);
38319 const features = geojson.features || geojson;
38320 const lineStrings = features.reduce((acc, obj) => {
38321 const geom = obj.geometry;
38322 if (geom.type === 'LineString') {
38323 geom.coordinates.properties = obj.properties;
38324 acc.push(geom.coordinates);
38325 } else if (geom.type === 'MultiLineString') {
38326 geom.coordinates.forEach(a => {
38327 a.properties = obj.properties;
38328 acc.push(a);
38329 });
38330 }
38331 return acc
38332 }, []);
38333 return lineStrings
38334 }
38335 function lineStringsToLinks(model, bbox, lineStrings) {
38336 const xfm = model.world.xfm || model.world.bboxTransform(...bbox);
38337 lineStrings = flattenMultiLineStrings(lineStrings);
38338 const nodeCache = {};
38339 const newTurtles = [];
38340 const newLinks = [];
38341 function getNode(pt) {
38342 const key = pt.toString();
38343 let node = nodeCache[key];
38344 if (node) return node
38345 node = model.turtles.createOne(t => {
38346 t.setxy(...xfm.toWorld(pt));
38347 t.lon = pt[0];
38348 t.lat = pt[1];
38349 });
38350 nodeCache[key] = node;
38351 newTurtles.push(node);
38352 return node
38353 }
38354 function newLink(pt0, pt1) {
38355 const t0 = getNode(pt0);
38356 const t1 = getNode(pt1);
38357 const link = model.links.createOne(t0, t1);
38358 newLinks.push(link);
38359 return link
38360 }
38361 function lineStringToLinks(lineString) {
38362 lineString.reduce((acc, pt, i, a) => {
38363 const link = newLink(a[i - 1], pt);
38364 if (i === 1) {
38365 acc = [link];
38366 acc.properties = lineString.properties;
38367 } else {
38368 acc.push(link);
38369 }
38370 link.lineString = acc;
38371 return acc
38372 });
38373 }
38374 lineStrings.forEach(lineString => lineStringToLinks(lineString));
38375 return [newTurtles, newLinks]
38376 }
38377 function flatten(gj, cloneJson = true) {
38378 if (cloneJson) gj = clone(gj);
38379 switch ((gj && gj.type) || null) {
38380 case 'FeatureCollection':
38381 gj.features = gj.features.reduce(function (mem, feature) {
38382 return mem.concat(flatten(feature))
38383 }, []);
38384 return gj
38385 case 'Feature':
38386 if (!gj.geometry) return [gj]
38387 return flatten(gj.geometry).map(function (geom) {
38388 var data = {
38389 type: 'Feature',
38390 properties: JSON.parse(JSON.stringify(gj.properties)),
38391 geometry: geom,
38392 };
38393 if (gj.id !== undefined) {
38394 data.id = gj.id;
38395 }
38396 return data
38397 })
38398 case 'MultiPoint':
38399 return gj.coordinates.map(function (_) {
38400 return { type: 'Point', coordinates: _ }
38401 })
38402 case 'MultiPolygon':
38403 return gj.coordinates.map(function (_) {
38404 return { type: 'Polygon', coordinates: _ }
38405 })
38406 case 'MultiLineString':
38407 return gj.coordinates.map(function (_) {
38408 return { type: 'LineString', coordinates: _ }
38409 })
38410 case 'GeometryCollection':
38411 return gj.geometries.map(flatten).reduce(function (memo, geoms) {
38412 return memo.concat(geoms)
38413 }, [])
38414 case 'Point':
38415 case 'Polygon':
38416 case 'LineString':
38417 return [gj]
38418 }
38419 }
38420 function geojsonBBox(gj) {
38421 var coords, bbox;
38422 if (!gj.hasOwnProperty('type')) return
38423 coords = getCoordinates(gj);
38424 bbox = [
38425 Number.POSITIVE_INFINITY,
38426 Number.POSITIVE_INFINITY,
38427 Number.NEGATIVE_INFINITY,
38428 Number.NEGATIVE_INFINITY,
38429 ];
38430 return coords.reduce(function (prev, coord) {
38431 return [
38432 Math.min(coord[0], prev[0]),
38433 Math.min(coord[1], prev[1]),
38434 Math.max(coord[0], prev[2]),
38435 Math.max(coord[1], prev[3]),
38436 ]
38437 }, bbox)
38438 }
38439 function getCoordinates(gj) {
38440 switch (gj.type) {
38441 case 'Point':
38442 return [gj.coordinates]
38443 case 'LineString':
38444 case 'MultiPoint':
38445 return gj.coordinates
38446 case 'Polygon':
38447 case 'MultiLineString':
38448 return gj.coordinates.reduce(function (dump, part) {
38449 return dump.concat(part)
38450 }, [])
38451 case 'MultiPolygon':
38452 return gj.coordinates.reduce(function (dump, poly) {
38453 return dump.concat(
38454 poly.reduce(function (points, part) {
38455 return points.concat(part)
38456 }, [])
38457 )
38458 }, [])
38459 case 'Feature':
38460 return getCoordinates(gj.geometry)
38461 case 'GeometryCollection':
38462 return gj.geometries.reduce(function (dump, g) {
38463 return dump.concat(getCoordinates(g))
38464 }, [])
38465 case 'FeatureCollection':
38466 return gj.features.reduce(function (dump, f) {
38467 return dump.concat(getCoordinates(f))
38468 }, [])
38469 }
38470 }
38471
38472 var geojson = /*#__PURE__*/Object.freeze({
38473 __proto__: null,
38474 isGeojson: isGeojson,
38475 clone: clone,
38476 minify: minify,
38477 bboxFeature: bboxFeature,
38478 flattenMultiLineStrings: flattenMultiLineStrings,
38479 lineStringsToLinks: lineStringsToLinks,
38480 flatten: flatten,
38481 geojsonBBox: geojsonBBox,
38482 getCoordinates: getCoordinates
38483 });
38484
38485 exports.AgentArray = AgentArray;
38486 exports.AgentList = AgentList;
38487 exports.AgentSet = AgentSet;
38488 exports.Animator = Animator;
38489 exports.Color = Color$1;
38490 exports.ColorMap = ColorMap;
38491 exports.DataSet = DataSet;
38492 exports.Evented = Evented;
38493 exports.GeoWorld = GeoWorld;
38494 exports.Link = Link;
38495 exports.Links = Links;
38496 exports.Model = Model;
38497 exports.Model3D = Model3D;
38498 exports.Mouse = Mouse;
38499 exports.Object3D = Object3D$1;
38500 exports.Patch = Patch;
38501 exports.Patches = Patches;
38502 exports.PatchesView = PatchesView;
38503 exports.RGBADataSet = RGBADataSet$1;
38504 exports.RGBDataSet = RGBDataSet;
38505 exports.Shapes = Shapes;
38506 exports.SpriteSheet = SpriteSheet;
38507 exports.ThreeDraw = ThreeDraw;
38508 exports.ThreeMeshes = ThreeMeshes;
38509 exports.ThreeView = ThreeView;
38510 exports.TileData = TileData;
38511 exports.Turtle = Turtle;
38512 exports.Turtle3D = Turtle3D;
38513 exports.Turtles = Turtles;
38514 exports.TurtlesView = TurtlesView;
38515 exports.TwoDraw = TwoDraw;
38516 exports.TwoView = TwoView;
38517 exports.World = World;
38518 exports.geojson = geojson;
38519 exports.gis = gis;
38520 exports.steg = steg;
38521 exports.turfImports = turfImports;
38522 exports.utils = util;
38523
38524}));