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 = 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 = 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 = 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}];
|
3370 | way[highway];
|
3371 | (._;>;);
|
3372 | out;`;
|
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 © ';
|
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 = 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 = 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 = 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 = 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 | }));
|