@1pizzateam/roostr 0.0.0-stage → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/roostr.js ADDED
@@ -0,0 +1,3322 @@
1
+ /*
2
+ MIT License
3
+
4
+ Copyright (c) 2015 Ludovic CLUBER
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
23
+
24
+ https://github.com/1pizzateam/RoostR.js
25
+ */
26
+
27
+ import { Mat4x3, Vec3, Frustum, Vec2, Time, Utils, Mat4, Ray3, Rect, Trigo, Quat, Mat3, Box, Sphere as Sphere$1 } from '@1pizzateam/spock';
28
+ export { Accumulator, Bezier, Box as BoundingBox, Sphere as BoundingSphere, Circ, Frustum, Grid, Mat3, Mat4, Mat4x3, NumArray, Quat, Rand, Ray3 as Ray, Rect, RollingAverage, Plane as SpatialPlane, Time, Trigo, Utils, Vec2, Vec3 } from '@1pizzateam/spock';
29
+
30
+ class GLState {
31
+ program = null;
32
+ arrayBuffer = null;
33
+ elementBuffer = null;
34
+ attributeMask = null;
35
+ maxAttributes = 0;
36
+ frameOfProgram = new WeakMap();
37
+ materialOfProgram = new WeakMap();
38
+ materialVersionOfProgram = new WeakMap();
39
+ invalidate() {
40
+ this.program = null;
41
+ this.arrayBuffer = null;
42
+ this.elementBuffer = null;
43
+ this.attributeMask = null;
44
+ }
45
+ }
46
+ const states = new WeakMap();
47
+ function getGLState(context) {
48
+ let state = states.get(context);
49
+ if (!state) {
50
+ state = new GLState();
51
+ states.set(context, state);
52
+ }
53
+ return state;
54
+ }
55
+
56
+ class SceneRenderer {
57
+ context;
58
+ blendKey = '';
59
+ blendEnabled = null;
60
+ depthWrite = null;
61
+ constructor(context) {
62
+ this.context = context;
63
+ this.defaultSettings();
64
+ }
65
+ invalidateState() {
66
+ getGLState(this.context).invalidate();
67
+ this.blendKey = '';
68
+ this.blendEnabled = null;
69
+ this.depthWrite = null;
70
+ }
71
+ defaultSettings() {
72
+ this.setDepthFunc('LEQUAL');
73
+ this.enableDepthTest();
74
+ this.disableBlendMode();
75
+ }
76
+ enable(capability) {
77
+ if (capability === 'BLEND')
78
+ this.blendEnabled = true;
79
+ this.context.enable(this.context[capability]);
80
+ }
81
+ disable(capability) {
82
+ if (capability === 'BLEND')
83
+ this.blendEnabled = false;
84
+ this.context.disable(this.context[capability]);
85
+ }
86
+ setDepthFunc(mode) {
87
+ this.context.depthFunc(this.context[mode]);
88
+ }
89
+ setBlendFunction(sourceFactor, destinationFactor) {
90
+ this.context.blendFunc(this.context[sourceFactor], this.context[destinationFactor]);
91
+ }
92
+ setBlendEquation(mode) {
93
+ this.context.blendEquation(this.context[mode]);
94
+ }
95
+ enableDepthTest() {
96
+ this.enable('DEPTH_TEST');
97
+ this.depthWrite = true;
98
+ this.context.depthMask(true);
99
+ }
100
+ disableDepthTest() {
101
+ this.disable('DEPTH_TEST');
102
+ this.depthWrite = false;
103
+ this.context.depthMask(false);
104
+ }
105
+ enableBlendMode(equation, source, destination) {
106
+ const key = equation + '|' + source + '|' + destination;
107
+ if (key !== this.blendKey) {
108
+ this.setBlendEquation(equation);
109
+ this.setBlendFunction(source, destination);
110
+ this.blendKey = key;
111
+ }
112
+ if (this.blendEnabled !== true)
113
+ this.enable('BLEND');
114
+ }
115
+ disableBlendMode() {
116
+ if (this.blendEnabled !== false)
117
+ this.disable('BLEND');
118
+ }
119
+ setDepthWrite(enabled) {
120
+ if (this.depthWrite === enabled)
121
+ return;
122
+ this.depthWrite = enabled;
123
+ this.context.depthMask(enabled);
124
+ }
125
+ getParameter(parameterName) {
126
+ return this.context.getParameter(parameterName);
127
+ }
128
+ }
129
+
130
+ class SceneGraph {
131
+ model;
132
+ nbModel;
133
+ modelStackTop;
134
+ constructor() {
135
+ this.model = [new Mat4x3()];
136
+ this.model[0].identity();
137
+ this.nbModel = this.model.length;
138
+ this.modelStackTop = 0;
139
+ }
140
+ pushModelMatrix(modelMatrix) {
141
+ this.modelStackTop++;
142
+ if (this.modelStackTop === this.nbModel) {
143
+ this.model.push(new Mat4x3());
144
+ this.nbModel++;
145
+ }
146
+ this.model[this.modelStackTop].copy(modelMatrix);
147
+ }
148
+ popModelMatrix() {
149
+ if (this.modelStackTop > 0)
150
+ this.modelStackTop--;
151
+ }
152
+ getWorldMatrix() {
153
+ return this.model[this.modelStackTop];
154
+ }
155
+ }
156
+
157
+ const MAX_LIGHTS = 8;
158
+ class Lights {
159
+ static _ambient = new Vec3();
160
+ warnedOverflow = false;
161
+ directionals;
162
+ points;
163
+ spots;
164
+ ambients;
165
+ nbDirectionals;
166
+ nbPoints;
167
+ nbSpots;
168
+ nbAmbients;
169
+ flatArrays;
170
+ constructor() {
171
+ this.directionals = [];
172
+ this.points = [];
173
+ this.spots = [];
174
+ this.ambients = [];
175
+ this.nbDirectionals = 0;
176
+ this.nbPoints = 0;
177
+ this.nbSpots = 0;
178
+ this.nbAmbients = 0;
179
+ this.flatArrays = {
180
+ position: [],
181
+ diffuse: [],
182
+ specular: [],
183
+ constantAttenuation: [],
184
+ linearAttenuation: [],
185
+ quadraticAttenuation: [],
186
+ cutoff: [],
187
+ exponent: [],
188
+ direction: [],
189
+ type: [],
190
+ ambient: [0, 0, 0]
191
+ };
192
+ }
193
+ addLight(light) {
194
+ switch (light.type) {
195
+ case 'directional':
196
+ this.directionals.push(light);
197
+ this.nbDirectionals++;
198
+ break;
199
+ case 'point':
200
+ this.points.push(light);
201
+ this.nbPoints++;
202
+ break;
203
+ case 'spot':
204
+ this.spots.push(light);
205
+ this.nbSpots++;
206
+ break;
207
+ case 'ambient':
208
+ this.ambients.push(light);
209
+ this.nbAmbients++;
210
+ break;
211
+ }
212
+ }
213
+ removeLight(light) {
214
+ let idx;
215
+ switch (light.type) {
216
+ case 'directional':
217
+ idx = this.directionals.indexOf(light);
218
+ if (idx !== -1) {
219
+ this.directionals.splice(idx, 1);
220
+ this.nbDirectionals--;
221
+ return true;
222
+ }
223
+ return false;
224
+ case 'point':
225
+ idx = this.points.indexOf(light);
226
+ if (idx !== -1) {
227
+ this.points.splice(idx, 1);
228
+ this.nbPoints--;
229
+ return true;
230
+ }
231
+ return false;
232
+ case 'spot':
233
+ idx = this.spots.indexOf(light);
234
+ if (idx !== -1) {
235
+ this.spots.splice(idx, 1);
236
+ this.nbSpots--;
237
+ return true;
238
+ }
239
+ return false;
240
+ case 'ambient':
241
+ idx = this.ambients.indexOf(light);
242
+ if (idx !== -1) {
243
+ this.ambients.splice(idx, 1);
244
+ this.nbAmbients--;
245
+ return true;
246
+ }
247
+ return false;
248
+ default:
249
+ return false;
250
+ }
251
+ }
252
+ ClearFlatArrays() {
253
+ this.flatArrays.position.length = 0;
254
+ this.flatArrays.diffuse.length = 0;
255
+ this.flatArrays.specular.length = 0;
256
+ this.flatArrays.constantAttenuation.length = 0;
257
+ this.flatArrays.linearAttenuation.length = 0;
258
+ this.flatArrays.quadraticAttenuation.length = 0;
259
+ this.flatArrays.cutoff.length = 0;
260
+ this.flatArrays.exponent.length = 0;
261
+ this.flatArrays.direction.length = 0;
262
+ this.flatArrays.type.length = 0;
263
+ }
264
+ ensureBuffers(count) {
265
+ const f = this.flatArrays;
266
+ if (f.floatPosition && f.floatPosition.length === count * 3)
267
+ return;
268
+ f.floatPosition = new Float32Array(count * 3);
269
+ f.floatDiffuse = new Float32Array(count * 3);
270
+ f.floatSpecular = new Float32Array(count * 3);
271
+ f.floatDirection = new Float32Array(count * 3);
272
+ f.floatAttenuation = new Float32Array(count * 3);
273
+ f.floatCutoff = new Float32Array(count);
274
+ f.floatExponent = new Float32Array(count);
275
+ f.floatType = new Float32Array(count);
276
+ f.packedPosition = new Float32Array(count * 4);
277
+ f.packedDiffuse = new Float32Array(count * 4);
278
+ f.packedSpecular = new Float32Array(count * 4);
279
+ }
280
+ push(index, kind, light) {
281
+ const f = this.flatArrays;
282
+ const o = index * 3;
283
+ const isSpot = kind === 'spot';
284
+ const isDirectional = kind === 'directional';
285
+ const att = isDirectional ? null : light;
286
+ light.position.toArray(f.floatPosition, o);
287
+ light.diffuse.toArray(f.floatDiffuse, o);
288
+ light.specular.toArray(f.floatSpecular, o);
289
+ if (isDirectional)
290
+ light.direction.toArray(f.floatDirection, o);
291
+ else if (isSpot)
292
+ light.direction.toArray(f.floatDirection, o);
293
+ else
294
+ f.floatDirection.fill(0, o, o + 3);
295
+ const constant = att ? att.constantAttenuation : 1;
296
+ const linear = att ? att.linearAttenuation : 0;
297
+ const quadratic = att ? att.quadraticAttenuation : 0;
298
+ f.floatAttenuation[o] = constant;
299
+ f.floatAttenuation[o + 1] = linear;
300
+ f.floatAttenuation[o + 2] = quadratic;
301
+ f.floatCutoff[index] = isSpot ? light.cutoff : 0;
302
+ f.floatExponent[index] = isSpot ? light.exponent : 0;
303
+ f.floatType[index] = isDirectional ? 0 : isSpot ? 2 : 1;
304
+ const q = index * 4;
305
+ light.position.toArray(f.packedPosition, q);
306
+ f.packedPosition[q + 3] = f.floatType[index];
307
+ light.diffuse.toArray(f.packedDiffuse, q);
308
+ f.packedDiffuse[q + 3] = f.floatCutoff[index];
309
+ light.specular.toArray(f.packedSpecular, q);
310
+ f.packedSpecular[q + 3] = f.floatExponent[index];
311
+ const dir = isDirectional || isSpot ? light.direction : null;
312
+ f.position.push(light.position.x, light.position.y, light.position.z);
313
+ f.diffuse.push(light.diffuse.x, light.diffuse.y, light.diffuse.z);
314
+ f.specular.push(light.specular.x, light.specular.y, light.specular.z);
315
+ if (dir)
316
+ f.direction.push(dir.x, dir.y, dir.z);
317
+ else
318
+ f.direction.push(0, 0, 0);
319
+ f.constantAttenuation.push(constant);
320
+ f.linearAttenuation.push(linear);
321
+ f.quadraticAttenuation.push(quadratic);
322
+ f.cutoff.push(isSpot ? light.cutoff : 0);
323
+ f.exponent.push(isSpot ? light.exponent : 0);
324
+ f.type.push(kind);
325
+ }
326
+ flatten(extraAmbient) {
327
+ this.ClearFlatArrays();
328
+ const total = this.nbSpots + this.nbPoints + this.nbDirectionals;
329
+ const count = Math.min(total, MAX_LIGHTS);
330
+ if (total > MAX_LIGHTS && !this.warnedOverflow) {
331
+ this.warnedOverflow = true;
332
+ console.warn(`Lights: ${total} lights added, only the first ${MAX_LIGHTS} (spots, points, then directionals) are used.`);
333
+ }
334
+ this.ensureBuffers(count);
335
+ let index = 0;
336
+ for (let i = 0; i < this.nbSpots && index < count; i++)
337
+ this.push(index++, 'spot', this.spots[i]);
338
+ for (let i = 0; i < this.nbPoints && index < count; i++)
339
+ this.push(index++, 'point', this.points[i]);
340
+ for (let i = 0; i < this.nbDirectionals && index < count; i++)
341
+ this.push(index++, 'directional', this.directionals[i]);
342
+ const ambient = Lights._ambient.setScalar(0, 0, 0);
343
+ if (extraAmbient)
344
+ ambient.add(extraAmbient);
345
+ for (let i = 0; i < this.nbAmbients; i++)
346
+ ambient.addScaledVector(this.ambients[i].diffuse, this.ambients[i].intensity);
347
+ if (!this.flatArrays.floatAmbient)
348
+ this.flatArrays.floatAmbient = new Float32Array(3);
349
+ ambient.toArray(this.flatArrays.floatAmbient);
350
+ this.flatArrays.ambient = [ambient.x, ambient.y, ambient.z];
351
+ return this.flatArrays;
352
+ }
353
+ clear() {
354
+ this.directionals = [];
355
+ this.points = [];
356
+ this.spots = [];
357
+ this.ambients = [];
358
+ this.nbDirectionals = 0;
359
+ this.nbPoints = 0;
360
+ this.nbSpots = 0;
361
+ this.nbAmbients = 0;
362
+ this.ClearFlatArrays();
363
+ }
364
+ getFlatArray(property) {
365
+ if (this.flatArrays.hasOwnProperty(property))
366
+ return this.flatArrays[property];
367
+ return undefined;
368
+ }
369
+ }
370
+
371
+ function assignVec3(target, xOrVec, y, z) {
372
+ if (xOrVec instanceof Vec3)
373
+ return target.copy(xOrVec);
374
+ if (typeof xOrVec === 'number')
375
+ return target.setScalar(xOrVec, y, z);
376
+ return target.setArray(xOrVec);
377
+ }
378
+
379
+ class Scene {
380
+ meshes;
381
+ nbMeshes;
382
+ lights;
383
+ ambientColor;
384
+ fog;
385
+ enableFrustumCulling;
386
+ context;
387
+ renderer;
388
+ graph;
389
+ resolution;
390
+ scratchFrustum = new Frustum();
391
+ scratchVec = new Vec3();
392
+ frame = { id: 0 };
393
+ frameCounter = 0;
394
+ traversalStamp = 0;
395
+ opaqueList = [];
396
+ blendedList = [];
397
+ constructor(contextOrOptions) {
398
+ this.meshes = [];
399
+ this.nbMeshes = 0;
400
+ this.lights = new Lights();
401
+ this.ambientColor = new Vec3(0, 0, 0);
402
+ this.fog = null;
403
+ this.enableFrustumCulling = false;
404
+ let ctx = null;
405
+ let opts = null;
406
+ if (contextOrOptions && typeof contextOrOptions.createBuffer === 'function')
407
+ ctx = contextOrOptions;
408
+ else if (contextOrOptions && typeof contextOrOptions === 'object') {
409
+ opts = contextOrOptions;
410
+ if (opts.context)
411
+ ctx = opts.context;
412
+ else if (opts.canvasId)
413
+ ctx = Scene.contextFromCanvas(opts.canvasId);
414
+ if (opts.ambientColor)
415
+ this.setAmbientColor(opts.ambientColor);
416
+ if (opts.fog)
417
+ this.fog = opts.fog;
418
+ if (opts.enableFrustumCulling !== undefined)
419
+ this.enableFrustumCulling = opts.enableFrustumCulling;
420
+ }
421
+ else
422
+ ctx = contextOrOptions;
423
+ if (!ctx)
424
+ throw new Error('Scene requires a WebGL context or a canvasId.');
425
+ this.context = ctx;
426
+ this.resolution = new Vec2(ctx.drawingBufferWidth || 0, ctx.drawingBufferHeight || 0);
427
+ this.renderer = new SceneRenderer(this.context);
428
+ this.graph = new SceneGraph();
429
+ if (opts && this.context) {
430
+ if (opts.viewport)
431
+ this.setViewport(opts.viewport.x || 0, opts.viewport.y || 0, opts.viewport.width, opts.viewport.height);
432
+ if (opts.clearColor) {
433
+ const c = opts.clearColor;
434
+ if (Array.isArray(c))
435
+ this.context.clearColor(c[0] ?? 0, c[1] ?? 0, c[2] ?? 0, c[3] ?? 1);
436
+ else if ('x' in c && 'y' in c && 'z' in c)
437
+ this.context.clearColor(c.x, c.y, c.z, 1.0);
438
+ }
439
+ if (opts.depthTest !== false && this.context.DEPTH_TEST) {
440
+ this.context.enable(this.context.DEPTH_TEST);
441
+ if (this.context.LEQUAL)
442
+ this.context.depthFunc(this.context.LEQUAL);
443
+ }
444
+ if (opts.cullFace && opts.cullFace !== 'NONE' && this.context.CULL_FACE) {
445
+ this.context.enable(this.context.CULL_FACE);
446
+ const mode = this.context[opts.cullFace] || this.context.BACK;
447
+ if (mode)
448
+ this.context.cullFace(mode);
449
+ }
450
+ if (opts.frontFace && this.context.frontFace) {
451
+ const mode = this.context[opts.frontFace] || this.context.CCW;
452
+ if (mode)
453
+ this.context.frontFace(mode);
454
+ }
455
+ }
456
+ }
457
+ static contextFromCanvas(canvasId) {
458
+ const canvas = typeof canvasId === 'string' ? document.getElementById(canvasId) : canvasId;
459
+ if (!canvas)
460
+ return null;
461
+ return (canvas.getContext('webgl') || canvas.getContext('experimental-webgl'));
462
+ }
463
+ setViewport(x, y, width, height) {
464
+ this.resolution.setScalar(width, height);
465
+ if (this.context && this.context.viewport)
466
+ this.context.viewport(x, y, width, height);
467
+ }
468
+ setSize(sizeOrWidth, height) {
469
+ const w = sizeOrWidth instanceof Vec2 ? sizeOrWidth.x : sizeOrWidth;
470
+ const h = sizeOrWidth instanceof Vec2 ? sizeOrWidth.y : (height ?? 0);
471
+ if (this.context && this.context.canvas) {
472
+ const canvas = this.context.canvas;
473
+ canvas.width = w;
474
+ canvas.height = h;
475
+ }
476
+ this.setViewport(0, 0, w, h);
477
+ }
478
+ clear(color = true, depth = true) {
479
+ if (!this.context)
480
+ return;
481
+ let mask = 0;
482
+ if (color)
483
+ mask |= this.context.COLOR_BUFFER_BIT;
484
+ if (depth)
485
+ mask |= this.context.DEPTH_BUFFER_BIT;
486
+ if (mask)
487
+ this.context.clear(mask);
488
+ }
489
+ addMesh(mesh) {
490
+ if (this.meshes.indexOf(mesh) === -1) {
491
+ this.meshes.push(mesh);
492
+ this.nbMeshes++;
493
+ }
494
+ }
495
+ removeMesh(mesh) {
496
+ const index = this.meshes.indexOf(mesh);
497
+ if (index !== -1) {
498
+ this.meshes.splice(index, 1);
499
+ this.nbMeshes--;
500
+ return true;
501
+ }
502
+ return false;
503
+ }
504
+ addLight(light) {
505
+ this.lights.addLight(light);
506
+ }
507
+ removeLight(light) {
508
+ return this.lights.removeLight(light);
509
+ }
510
+ setAmbientColor(rOrVec, g, b) {
511
+ if (typeof rOrVec === 'number')
512
+ this.ambientColor.setScalar(rOrVec, g ?? 0, b ?? 0);
513
+ else
514
+ assignVec3(this.ambientColor, rOrVec);
515
+ return this;
516
+ }
517
+ setFog(color, nearOrG, farOrB, near, far) {
518
+ if (typeof color === 'number')
519
+ this.fog = {
520
+ color: new Vec3(color, nearOrG, farOrB ?? 0),
521
+ near: near ?? 1,
522
+ far: far ?? 1000
523
+ };
524
+ else
525
+ this.fog = {
526
+ color: assignVec3(new Vec3(), color),
527
+ near: nearOrG,
528
+ far: farOrB ?? 1000
529
+ };
530
+ return this;
531
+ }
532
+ clearFog() {
533
+ this.fog = null;
534
+ return this;
535
+ }
536
+ clearMeshes() {
537
+ this.meshes = [];
538
+ this.nbMeshes = 0;
539
+ }
540
+ clearLights() {
541
+ this.lights.clear();
542
+ }
543
+ destroy(destroyMeshes = true) {
544
+ if (destroyMeshes)
545
+ for (const mesh of this.meshes)
546
+ mesh.destroy();
547
+ this.clearMeshes();
548
+ this.clearLights();
549
+ this.clearFog();
550
+ }
551
+ getLightsProperty(property) {
552
+ return this.lights.getFlatArray(property);
553
+ }
554
+ enableBlendMode(equation, source, destination) {
555
+ this.renderer.enableBlendMode(equation, source, destination);
556
+ }
557
+ disableBlendMode() {
558
+ this.renderer.disableBlendMode();
559
+ }
560
+ getRendererBlendMode() {
561
+ return this.renderer.getParameter(this.context.BLEND);
562
+ }
563
+ raycast(ray, precise = false) {
564
+ this.computeWorldMatrices();
565
+ const hits = [];
566
+ const visit = (mesh) => {
567
+ if (!mesh.isActive())
568
+ return;
569
+ const hit = mesh.raycast(ray, precise);
570
+ if (hit)
571
+ hits.push({ mesh, distance: hit.distance, point: hit.point });
572
+ for (const child of mesh.children)
573
+ visit(child);
574
+ };
575
+ for (const mesh of this.meshes)
576
+ if (mesh.traversalStamp !== this.traversalStamp)
577
+ visit(mesh);
578
+ hits.sort((a, b) => a.distance - b.distance);
579
+ return hits;
580
+ }
581
+ render(camera, time = Time.now()) {
582
+ this.computeWorldMatrices();
583
+ const flatLights = this.lights.flatten(this.ambientColor);
584
+ const frustum = this.enableFrustumCulling
585
+ ? this.scratchFrustum.setFromProjectionViewMatrix(camera.getProjectionViewMatrix())
586
+ : null;
587
+ this.collect(camera, frustum, true, true, this.traversalStamp);
588
+ const frame = this.beginFrame();
589
+ this.disableBlendMode();
590
+ const projMatrix = camera.getProjectionMatrix();
591
+ const viewMatrix = camera.getViewMatrix();
592
+ const camPos = camera.position;
593
+ let renderedCount = 0;
594
+ for (const mesh of this.opaqueList) {
595
+ this.renderer.setDepthWrite(mesh.depthWrite);
596
+ mesh.renderSelf(projMatrix, viewMatrix, flatLights, time, false, camPos, this.fog, frame);
597
+ renderedCount++;
598
+ }
599
+ renderedCount += this.drawBlended(camera, time, flatLights, frame);
600
+ this.renderer.setDepthWrite(true);
601
+ return renderedCount;
602
+ }
603
+ markDescendants() {
604
+ const stamp = ++this.traversalStamp;
605
+ const mark = (mesh) => {
606
+ for (const child of mesh.children) {
607
+ child.traversalStamp = stamp;
608
+ mark(child);
609
+ }
610
+ };
611
+ for (const mesh of this.meshes)
612
+ mark(mesh);
613
+ return stamp;
614
+ }
615
+ computeWorldMatrices() {
616
+ const stamp = this.markDescendants();
617
+ for (const mesh of this.meshes)
618
+ if (mesh.traversalStamp !== stamp)
619
+ mesh.computeWorldMatrix(this.graph);
620
+ }
621
+ beginFrame() {
622
+ this.renderer.invalidateState();
623
+ this.frame.id = ++this.frameCounter;
624
+ this.frame.resolution = this.resolution;
625
+ return this.frame;
626
+ }
627
+ collect(camera, frustum, opaque, blended, stamp) {
628
+ this.opaqueList.length = 0;
629
+ this.blendedList.length = 0;
630
+ const visit = (mesh) => {
631
+ if (!mesh.isActive())
632
+ return;
633
+ const wanted = mesh.blendMode ? blended : opaque;
634
+ if (wanted && !(frustum && !frustum.intersectsSphere(mesh.computeBoundingSphere()))) {
635
+ if (mesh.blendMode) {
636
+ mesh.sortKey = mesh.getWorldPosition(this.scratchVec).getDistance(camera.position, true);
637
+ this.blendedList.push(mesh);
638
+ }
639
+ else
640
+ this.opaqueList.push(mesh);
641
+ }
642
+ for (const child of mesh.children)
643
+ visit(child);
644
+ };
645
+ for (const mesh of this.meshes)
646
+ if (mesh.traversalStamp !== stamp)
647
+ visit(mesh);
648
+ }
649
+ drawBlended(camera, time, flatLights, frame) {
650
+ const list = this.blendedList;
651
+ if (list.length === 0)
652
+ return 0;
653
+ if (list.length > 1)
654
+ list.sort((a, b) => b.sortKey - a.sortKey);
655
+ const projMatrix = camera.getProjectionMatrix();
656
+ const viewMatrix = camera.getViewMatrix();
657
+ const camPos = camera.position;
658
+ for (const mesh of list) {
659
+ const blend = mesh.blendOptions;
660
+ this.enableBlendMode(blend.equation, blend.source, blend.destination);
661
+ this.renderer.setDepthWrite(mesh.depthWrite);
662
+ mesh.renderSelf(projMatrix, viewMatrix, flatLights, time, true, camPos, this.fog, frame);
663
+ }
664
+ this.disableBlendMode();
665
+ this.renderer.setDepthWrite(true);
666
+ return list.length;
667
+ }
668
+ renderBlended(camera, time = Time.now(), flatLights = this.lights.flatten(this.ambientColor), frustum = null) {
669
+ this.collect(camera, frustum, false, true, this.markDescendants());
670
+ return this.drawBlended(camera, time, flatLights, this.beginFrame());
671
+ }
672
+ }
673
+
674
+ class Renderer {
675
+ canvas;
676
+ context;
677
+ isContextLost = false;
678
+ options;
679
+ onContextLostBound;
680
+ onContextRestoredBound;
681
+ constructor(canvasID, options = {}) {
682
+ this.options = options;
683
+ this.onContextLostBound = (e) => {
684
+ e.preventDefault();
685
+ this.isContextLost = true;
686
+ this.options.onContextLost?.();
687
+ };
688
+ this.onContextRestoredBound = () => {
689
+ this.isContextLost = false;
690
+ this.defaultSettings();
691
+ this.options.onContextRestored?.();
692
+ };
693
+ this.canvas = typeof canvasID === 'string' ? this.findById(canvasID) : canvasID;
694
+ this.context = null;
695
+ if (this.canvas) {
696
+ this.canvas.width = options.width ?? 1280;
697
+ this.canvas.height = options.height ?? 720;
698
+ const attributes = { alpha: false, ...options.contextAttributes };
699
+ this.context = (this.canvas.getContext("webgl", attributes) ||
700
+ this.canvas.getContext("experimental-webgl", attributes)) || null;
701
+ if (this.context) {
702
+ if (typeof this.canvas.addEventListener === 'function') {
703
+ this.canvas.addEventListener('webglcontextlost', this.onContextLostBound);
704
+ this.canvas.addEventListener('webglcontextrestored', this.onContextRestoredBound);
705
+ }
706
+ this.defaultSettings();
707
+ }
708
+ }
709
+ }
710
+ dispose() {
711
+ if (this.canvas && typeof this.canvas.removeEventListener === 'function') {
712
+ this.canvas.removeEventListener('webglcontextlost', this.onContextLostBound);
713
+ this.canvas.removeEventListener('webglcontextrestored', this.onContextRestoredBound);
714
+ }
715
+ }
716
+ defaultSettings() {
717
+ if (!this.context)
718
+ return;
719
+ this.context.getExtension('OES_standard_derivatives');
720
+ this.setFrontFace('CW');
721
+ this.enable('CULL_FACE');
722
+ this.setCullFace('BACK');
723
+ this.setViewport(this.context.drawingBufferWidth, this.context.drawingBufferHeight);
724
+ this.setClearColor(0.0, 0.0, 0.0, 1.0);
725
+ }
726
+ setFrontFace(mode) {
727
+ if (this.context)
728
+ this.context.frontFace(this.context[mode]);
729
+ }
730
+ enable(capability) {
731
+ if (this.context)
732
+ this.context.enable(this.context[capability]);
733
+ }
734
+ disable(capability) {
735
+ if (this.context)
736
+ this.context.disable(this.context[capability]);
737
+ }
738
+ setCullFace(mode) {
739
+ if (this.context)
740
+ this.context.cullFace(this.context[mode]);
741
+ }
742
+ setViewport(width, height) {
743
+ if (this.context)
744
+ this.context.viewport(0, 0, width, height);
745
+ }
746
+ setClearColor(rOrVec, g, b, a) {
747
+ if (this.context)
748
+ if (rOrVec instanceof Vec3) {
749
+ const alpha = g !== undefined ? Utils.clamp(g, 0, 1) : 1.0;
750
+ this.context.clearColor(Utils.clamp(rOrVec.x, 0, 1), Utils.clamp(rOrVec.y, 0, 1), Utils.clamp(rOrVec.z, 0, 1), alpha);
751
+ }
752
+ else {
753
+ const green = g !== undefined ? Utils.clamp(g, 0, 1) : 0;
754
+ const blue = b !== undefined ? Utils.clamp(b, 0, 1) : 0;
755
+ const alpha = a !== undefined ? Utils.clamp(a, 0, 1) : 1.0;
756
+ this.context.clearColor(Utils.clamp(rOrVec, 0, 1), green, blue, alpha);
757
+ }
758
+ }
759
+ clearFrame() {
760
+ if (this.context)
761
+ this.context.clear(this.context.COLOR_BUFFER_BIT | this.context.DEPTH_BUFFER_BIT);
762
+ }
763
+ getContext() {
764
+ return this.context;
765
+ }
766
+ getCanvas() {
767
+ return this.canvas;
768
+ }
769
+ setSize(sizeOrWidth, height) {
770
+ const w = sizeOrWidth instanceof Vec2 ? sizeOrWidth.x : sizeOrWidth;
771
+ const h = sizeOrWidth instanceof Vec2 ? sizeOrWidth.y : (height ?? 0);
772
+ if (this.canvas) {
773
+ this.canvas.width = w;
774
+ this.canvas.height = h;
775
+ }
776
+ this.setViewport(w, h);
777
+ }
778
+ findById(id) {
779
+ return document.getElementById(id);
780
+ }
781
+ }
782
+
783
+ class RenderTarget {
784
+ width;
785
+ height;
786
+ context;
787
+ framebuffer;
788
+ texture;
789
+ depthBuffer;
790
+ constructor(sizeOrWidth, heightOrContext, context) {
791
+ if (sizeOrWidth instanceof Vec2) {
792
+ this.width = sizeOrWidth.x;
793
+ this.height = sizeOrWidth.y;
794
+ this.context = heightOrContext;
795
+ }
796
+ else {
797
+ this.width = sizeOrWidth;
798
+ this.height = heightOrContext;
799
+ this.context = context;
800
+ }
801
+ this.framebuffer = null;
802
+ this.texture = null;
803
+ this.depthBuffer = null;
804
+ this.init();
805
+ }
806
+ init() {
807
+ const gl = this.context;
808
+ this.framebuffer = gl.createFramebuffer();
809
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
810
+ this.texture = gl.createTexture();
811
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
812
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
813
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
814
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
815
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
816
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
817
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0);
818
+ this.depthBuffer = gl.createRenderbuffer();
819
+ gl.bindRenderbuffer(gl.RENDERBUFFER, this.depthBuffer);
820
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.width, this.height);
821
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.depthBuffer);
822
+ gl.bindTexture(gl.TEXTURE_2D, null);
823
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
824
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
825
+ }
826
+ bind() {
827
+ const gl = this.context;
828
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
829
+ gl.viewport(0, 0, this.width, this.height);
830
+ }
831
+ unbind(viewportWidthOrSize, viewportHeight) {
832
+ const gl = this.context;
833
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
834
+ if (viewportWidthOrSize instanceof Vec2)
835
+ gl.viewport(0, 0, viewportWidthOrSize.x, viewportWidthOrSize.y);
836
+ else if (viewportWidthOrSize !== undefined && viewportHeight !== undefined)
837
+ gl.viewport(0, 0, viewportWidthOrSize, viewportHeight);
838
+ }
839
+ getSize(target = new Vec2()) {
840
+ return target.setScalar(this.width, this.height);
841
+ }
842
+ setSize(sizeOrWidth, height) {
843
+ const w = sizeOrWidth instanceof Vec2 ? sizeOrWidth.x : sizeOrWidth;
844
+ const h = sizeOrWidth instanceof Vec2 ? sizeOrWidth.y : (height ?? 0);
845
+ if (this.width === w && this.height === h)
846
+ return;
847
+ this.width = w;
848
+ this.height = h;
849
+ const gl = this.context;
850
+ if (this.texture) {
851
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
852
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
853
+ gl.bindTexture(gl.TEXTURE_2D, null);
854
+ }
855
+ if (this.depthBuffer) {
856
+ gl.bindRenderbuffer(gl.RENDERBUFFER, this.depthBuffer);
857
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.width, this.height);
858
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
859
+ }
860
+ }
861
+ dispose() {
862
+ const gl = this.context;
863
+ if (this.framebuffer) {
864
+ gl.deleteFramebuffer(this.framebuffer);
865
+ this.framebuffer = null;
866
+ }
867
+ if (this.texture) {
868
+ gl.deleteTexture(this.texture);
869
+ this.texture = null;
870
+ }
871
+ if (this.depthBuffer) {
872
+ gl.deleteRenderbuffer(this.depthBuffer);
873
+ this.depthBuffer = null;
874
+ }
875
+ }
876
+ }
877
+
878
+ class Camera {
879
+ viewMatrix;
880
+ projectionMatrix;
881
+ position;
882
+ target;
883
+ up;
884
+ cachedViewMatrix;
885
+ cachedProjectionMatrix;
886
+ projectionViewMatrix = new Mat4();
887
+ inverseProjectionViewMatrix = new Mat4();
888
+ isProjectionViewDirty = true;
889
+ isInverseDirty = true;
890
+ static _scratchNear = new Vec3();
891
+ static _scratchFar = new Vec3();
892
+ static _scratchDir = new Vec3();
893
+ static _scratchNdc = new Vec3();
894
+ constructor(position, target, up) {
895
+ this.viewMatrix = new Mat4x3();
896
+ this.projectionMatrix = new Mat4();
897
+ this.viewMatrix.identity();
898
+ this.projectionMatrix.identity();
899
+ this.cachedViewMatrix = new Float32Array(16);
900
+ this.cachedProjectionMatrix = new Float32Array(16);
901
+ this.viewMatrix.toArray(this.cachedViewMatrix);
902
+ this.projectionMatrix.toArray(this.cachedProjectionMatrix);
903
+ this.position = position;
904
+ this.target = target;
905
+ this.up = up;
906
+ }
907
+ setViewMatrix() {
908
+ this.viewMatrix.lookAtRH(this.position, this.target, this.up);
909
+ this.viewMatrix.toArray(this.cachedViewMatrix);
910
+ this.invalidateProjectionView();
911
+ }
912
+ setProjectionMatrix() {
913
+ this.projectionMatrix.toArray(this.cachedProjectionMatrix);
914
+ this.invalidateProjectionView();
915
+ }
916
+ invalidateProjectionView() {
917
+ this.isProjectionViewDirty = true;
918
+ this.isInverseDirty = true;
919
+ }
920
+ getProjectionViewMatrix() {
921
+ if (this.isProjectionViewDirty) {
922
+ this.projectionViewMatrix.copy(this.projectionMatrix).multiplyAffine(this.viewMatrix);
923
+ this.isProjectionViewDirty = false;
924
+ }
925
+ return this.projectionViewMatrix.toArray();
926
+ }
927
+ getInverseProjectionViewMatrix() {
928
+ if (this.isInverseDirty) {
929
+ this.getProjectionViewMatrix();
930
+ this.inverseProjectionViewMatrix.copy(this.projectionViewMatrix).invert();
931
+ this.isInverseDirty = false;
932
+ }
933
+ return this.inverseProjectionViewMatrix;
934
+ }
935
+ setPosition(xOrVec, y, z) {
936
+ if (xOrVec instanceof Vec3)
937
+ this.position.copy(xOrVec);
938
+ else
939
+ this.position.setScalar(xOrVec, y, z);
940
+ this.setViewMatrix();
941
+ }
942
+ setTarget(xOrVec, y, z) {
943
+ if (xOrVec instanceof Vec3)
944
+ this.target.copy(xOrVec);
945
+ else
946
+ this.target.setScalar(xOrVec, y, z);
947
+ this.setViewMatrix();
948
+ }
949
+ setUp(xOrVec, y, z) {
950
+ if (xOrVec instanceof Vec3)
951
+ this.up.copy(xOrVec);
952
+ else
953
+ this.up.setScalar(xOrVec, y, z);
954
+ this.setViewMatrix();
955
+ }
956
+ lookAt(target) {
957
+ this.setTarget(target);
958
+ }
959
+ getViewDirection(target = new Vec3()) {
960
+ return target.subVectors(this.target, this.position).normalize();
961
+ }
962
+ getDistance() {
963
+ return this.position.getDistance(this.target);
964
+ }
965
+ dolly(amount) {
966
+ this.position.lerp(this.target, amount);
967
+ this.setViewMatrix();
968
+ }
969
+ getViewMatrix() {
970
+ return this.cachedViewMatrix;
971
+ }
972
+ getProjectionMatrix() {
973
+ return this.cachedProjectionMatrix;
974
+ }
975
+ getViewMatrixObject() {
976
+ return this.viewMatrix;
977
+ }
978
+ getProjectionMatrixObject() {
979
+ return this.projectionMatrix;
980
+ }
981
+ getRay(ndcOrX, ndcYOrTarget, targetRay = new Ray3()) {
982
+ let ndcX;
983
+ let ndcY;
984
+ let outRay = targetRay;
985
+ if (ndcOrX instanceof Vec2) {
986
+ ndcX = ndcOrX.x;
987
+ ndcY = ndcOrX.y;
988
+ if (ndcYOrTarget instanceof Ray3)
989
+ outRay = ndcYOrTarget;
990
+ }
991
+ else {
992
+ ndcX = ndcOrX;
993
+ ndcY = typeof ndcYOrTarget === 'number' ? ndcYOrTarget : 0;
994
+ }
995
+ const inverse = this.getInverseProjectionViewMatrix();
996
+ const near = inverse.transformPoint(Camera._scratchNdc.setScalar(ndcX, ndcY, -1), Camera._scratchNear);
997
+ const far = inverse.transformPoint(Camera._scratchNdc.setScalar(ndcX, ndcY, 1.0), Camera._scratchFar);
998
+ const dir = Camera._scratchDir.subVectors(far, near).normalize();
999
+ outRay.set(near, dir);
1000
+ return outRay;
1001
+ }
1002
+ }
1003
+
1004
+ class PerspectiveCamera extends Camera {
1005
+ fov;
1006
+ ratio;
1007
+ zNear;
1008
+ zFar;
1009
+ constructor(fov, zNearOrContext, zFarOrNear, contextOrFar) {
1010
+ super(new Vec3(), new Vec3(), new Vec3(0.0, 1.0, 0.0));
1011
+ let zNear = 0.1;
1012
+ let zFar = 1000;
1013
+ let context = null;
1014
+ if (zNearOrContext && typeof zNearOrContext !== 'number') {
1015
+ context = zNearOrContext;
1016
+ zNear = typeof zFarOrNear === 'number' ? zFarOrNear : 0.1;
1017
+ zFar = typeof contextOrFar === 'number' ? contextOrFar : 1000;
1018
+ }
1019
+ else {
1020
+ zNear = typeof zNearOrContext === 'number' ? zNearOrContext : 0.1;
1021
+ zFar = typeof zFarOrNear === 'number' ? zFarOrNear : 1000;
1022
+ if (contextOrFar && typeof contextOrFar !== 'number')
1023
+ context = contextOrFar;
1024
+ }
1025
+ this.fov = fov;
1026
+ this.ratio = 0;
1027
+ this.zNear = zNear;
1028
+ this.zFar = zFar;
1029
+ const viewport = context && typeof context.getParameter === 'function' ? context.getParameter(context.VIEWPORT) : null;
1030
+ this.setProjectionMatrix(viewport);
1031
+ super.setViewMatrix();
1032
+ }
1033
+ setProjectionMatrix(viewport) {
1034
+ if (viewport instanceof Vec2)
1035
+ this.ratio = viewport.x / Math.max(1, viewport.y);
1036
+ else if (viewport && viewport.length >= 4)
1037
+ this.ratio = viewport[2] / Math.max(1, viewport[3]);
1038
+ else
1039
+ this.ratio = this.ratio || 1;
1040
+ this.projectionMatrix.perspective(this.fov, this.ratio, this.zNear, this.zFar);
1041
+ super.setProjectionMatrix();
1042
+ }
1043
+ setFov(fov) {
1044
+ this.fov = fov;
1045
+ this.setProjectionMatrix();
1046
+ }
1047
+ setNearFar(zNear, zFar) {
1048
+ this.zNear = zNear;
1049
+ this.zFar = zFar;
1050
+ this.setProjectionMatrix();
1051
+ }
1052
+ }
1053
+
1054
+ class OrthographicCamera extends Camera {
1055
+ left;
1056
+ right;
1057
+ top;
1058
+ bottom;
1059
+ near;
1060
+ far;
1061
+ constructor(boundsOrLeft, rightOrNear, topOrFar, bottom, near, far) {
1062
+ super(new Vec3(), new Vec3(), new Vec3(0.0, 1.0, 0.0));
1063
+ if (boundsOrLeft instanceof Rect) {
1064
+ this.left = boundsOrLeft.topLeftCorner.x;
1065
+ this.right = boundsOrLeft.bottomRightCorner.x;
1066
+ this.bottom = boundsOrLeft.topLeftCorner.y;
1067
+ this.top = boundsOrLeft.bottomRightCorner.y;
1068
+ this.near = rightOrNear !== undefined ? rightOrNear : -1e3;
1069
+ this.far = topOrFar !== undefined ? topOrFar : 1000;
1070
+ }
1071
+ else {
1072
+ this.left = boundsOrLeft;
1073
+ this.right = rightOrNear;
1074
+ this.top = topOrFar;
1075
+ this.bottom = bottom;
1076
+ this.near = near !== undefined ? near : -1e3;
1077
+ this.far = far !== undefined ? far : 1000;
1078
+ }
1079
+ this.setProjectionMatrix();
1080
+ super.setViewMatrix();
1081
+ }
1082
+ setProjectionMatrix() {
1083
+ this.projectionMatrix.orthographic(this.left, this.right, this.top, this.bottom, this.near, this.far);
1084
+ super.setProjectionMatrix();
1085
+ }
1086
+ setBounds(boundsOrLeft, rightOrNear, topOrFar, bottom, near, far) {
1087
+ if (boundsOrLeft instanceof Rect) {
1088
+ this.left = boundsOrLeft.topLeftCorner.x;
1089
+ this.right = boundsOrLeft.bottomRightCorner.x;
1090
+ this.bottom = boundsOrLeft.topLeftCorner.y;
1091
+ this.top = boundsOrLeft.bottomRightCorner.y;
1092
+ if (rightOrNear !== undefined)
1093
+ this.near = rightOrNear;
1094
+ if (topOrFar !== undefined)
1095
+ this.far = topOrFar;
1096
+ }
1097
+ else {
1098
+ this.left = boundsOrLeft;
1099
+ this.right = rightOrNear;
1100
+ this.top = topOrFar;
1101
+ this.bottom = bottom;
1102
+ if (near !== undefined)
1103
+ this.near = near;
1104
+ if (far !== undefined)
1105
+ this.far = far;
1106
+ }
1107
+ this.setProjectionMatrix();
1108
+ }
1109
+ }
1110
+
1111
+ class OrbitControls {
1112
+ camera;
1113
+ domElement;
1114
+ distance;
1115
+ targetDistance;
1116
+ azimuth;
1117
+ targetAzimuth;
1118
+ elevation;
1119
+ targetElevation;
1120
+ minDistance;
1121
+ maxDistance;
1122
+ minElevation;
1123
+ maxElevation;
1124
+ rotateSpeed;
1125
+ zoomSpeed;
1126
+ panSpeed;
1127
+ enableDamping;
1128
+ dampingFactor;
1129
+ isDragging;
1130
+ dragMode;
1131
+ previousMouseX;
1132
+ previousMouseY;
1133
+ touchStartDistance;
1134
+ activePointerId = null;
1135
+ appliedPose = new Vec3(NaN, NaN, NaN);
1136
+ appliedTarget = new Vec3(NaN, NaN, NaN);
1137
+ onPointerDownBound;
1138
+ onPointerMoveBound;
1139
+ onPointerUpBound;
1140
+ onWheelBound;
1141
+ onContextMenuBound;
1142
+ onTouchStartBound;
1143
+ onTouchMoveBound;
1144
+ onTouchEndBound;
1145
+ constructor(camera, domElement) {
1146
+ this.camera = camera;
1147
+ this.domElement = domElement;
1148
+ this.minDistance = 0.1;
1149
+ this.maxDistance = 10000;
1150
+ this.minElevation = -Trigo.halfpi + 0.01;
1151
+ this.maxElevation = Trigo.halfpi - 0.01;
1152
+ this.rotateSpeed = 1.0;
1153
+ this.zoomSpeed = 1.0;
1154
+ this.panSpeed = 1.0;
1155
+ this.enableDamping = false;
1156
+ this.dampingFactor = 0.05;
1157
+ this.isDragging = false;
1158
+ this.dragMode = null;
1159
+ this.previousMouseX = 0;
1160
+ this.previousMouseY = 0;
1161
+ this.touchStartDistance = 0;
1162
+ const spherical = OrbitControls._scratchSpherical.subVectors(this.camera.position, this.camera.target).getSpherical(OrbitControls._scratchSpherical);
1163
+ this.distance = spherical.x || 10;
1164
+ this.targetDistance = this.distance;
1165
+ this.azimuth = spherical.y;
1166
+ this.targetAzimuth = this.azimuth;
1167
+ this.elevation = spherical.z;
1168
+ this.targetElevation = this.elevation;
1169
+ this.onPointerDownBound = this.onPointerDown.bind(this);
1170
+ this.onPointerMoveBound = this.onPointerMove.bind(this);
1171
+ this.onPointerUpBound = this.onPointerUp.bind(this);
1172
+ this.onWheelBound = this.onWheel.bind(this);
1173
+ this.onContextMenuBound = (e) => e.preventDefault();
1174
+ this.onTouchStartBound = this.onTouchStart.bind(this);
1175
+ this.onTouchMoveBound = this.onTouchMove.bind(this);
1176
+ this.onTouchEndBound = this.onTouchEnd.bind(this);
1177
+ this.attach();
1178
+ this.update();
1179
+ }
1180
+ attach() {
1181
+ if (!this.domElement || typeof this.domElement.addEventListener !== 'function')
1182
+ return;
1183
+ if (this.domElement.style)
1184
+ this.domElement.style.touchAction = 'none';
1185
+ this.domElement.addEventListener('pointerdown', this.onPointerDownBound);
1186
+ if (typeof window !== 'undefined') {
1187
+ window.addEventListener('pointermove', this.onPointerMoveBound);
1188
+ window.addEventListener('pointerup', this.onPointerUpBound);
1189
+ }
1190
+ this.domElement.addEventListener('wheel', this.onWheelBound, { passive: false });
1191
+ this.domElement.addEventListener('contextmenu', this.onContextMenuBound);
1192
+ this.domElement.addEventListener('touchstart', this.onTouchStartBound, { passive: false });
1193
+ this.domElement.addEventListener('touchmove', this.onTouchMoveBound, { passive: false });
1194
+ this.domElement.addEventListener('touchend', this.onTouchEndBound);
1195
+ this.domElement.addEventListener('touchcancel', this.onTouchEndBound);
1196
+ }
1197
+ dispose() {
1198
+ if (!this.domElement || typeof this.domElement.removeEventListener !== 'function')
1199
+ return;
1200
+ this.domElement.removeEventListener('pointerdown', this.onPointerDownBound);
1201
+ if (typeof window !== 'undefined') {
1202
+ window.removeEventListener('pointermove', this.onPointerMoveBound);
1203
+ window.removeEventListener('pointerup', this.onPointerUpBound);
1204
+ }
1205
+ this.domElement.removeEventListener('wheel', this.onWheelBound);
1206
+ this.domElement.removeEventListener('contextmenu', this.onContextMenuBound);
1207
+ this.domElement.removeEventListener('touchstart', this.onTouchStartBound);
1208
+ this.domElement.removeEventListener('touchmove', this.onTouchMoveBound);
1209
+ this.domElement.removeEventListener('touchend', this.onTouchEndBound);
1210
+ this.domElement.removeEventListener('touchcancel', this.onTouchEndBound);
1211
+ }
1212
+ onPointerDown(e) {
1213
+ if (e.isPrimary === false)
1214
+ return;
1215
+ this.activePointerId = e.pointerId ?? null;
1216
+ this.isDragging = true;
1217
+ this.previousMouseX = e.clientX;
1218
+ this.previousMouseY = e.clientY;
1219
+ if (e.button === 2 || e.shiftKey)
1220
+ this.dragMode = 'pan';
1221
+ else
1222
+ this.dragMode = 'rotate';
1223
+ }
1224
+ onPointerMove(e) {
1225
+ if (!this.isDragging)
1226
+ return;
1227
+ if (this.activePointerId !== null && e.pointerId !== undefined && e.pointerId !== this.activePointerId)
1228
+ return;
1229
+ const deltaX = e.clientX - this.previousMouseX;
1230
+ const deltaY = e.clientY - this.previousMouseY;
1231
+ this.previousMouseX = e.clientX;
1232
+ this.previousMouseY = e.clientY;
1233
+ if (this.dragMode === 'rotate') {
1234
+ const elementHeight = this.domElement.clientHeight || 500;
1235
+ this.targetAzimuth -= (deltaX / elementHeight) * Trigo.pi * this.rotateSpeed;
1236
+ this.targetElevation += (deltaY / elementHeight) * Trigo.pi * this.rotateSpeed;
1237
+ this.targetElevation = Utils.clamp(this.targetElevation, this.minElevation, this.maxElevation);
1238
+ }
1239
+ else if (this.dragMode === 'pan')
1240
+ this.pan(deltaX, deltaY);
1241
+ if (!this.enableDamping) {
1242
+ this.azimuth = this.targetAzimuth;
1243
+ this.elevation = this.targetElevation;
1244
+ this.update();
1245
+ }
1246
+ }
1247
+ onPointerUp() {
1248
+ this.isDragging = false;
1249
+ this.activePointerId = null;
1250
+ this.dragMode = null;
1251
+ }
1252
+ onWheel(e) {
1253
+ e.preventDefault();
1254
+ const factor = e.deltaY > 0 ? 1.1 : (1 / 1.1);
1255
+ this.targetDistance *= Math.pow(factor, this.zoomSpeed);
1256
+ this.targetDistance = Utils.clamp(this.targetDistance, this.minDistance, this.maxDistance);
1257
+ if (!this.enableDamping) {
1258
+ this.distance = this.targetDistance;
1259
+ this.update();
1260
+ }
1261
+ }
1262
+ onTouchStart(e) {
1263
+ if (e.touches.length === 2) {
1264
+ e.preventDefault();
1265
+ this.touchStartDistance = OrbitControls.touchDistance(e.touches);
1266
+ }
1267
+ }
1268
+ onTouchMove(e) {
1269
+ if (e.touches.length === 2) {
1270
+ e.preventDefault();
1271
+ const currentDistance = OrbitControls.touchDistance(e.touches);
1272
+ const factor = this.touchStartDistance / (currentDistance || 1);
1273
+ this.touchStartDistance = currentDistance;
1274
+ this.targetDistance *= factor;
1275
+ this.targetDistance = Utils.clamp(this.targetDistance, this.minDistance, this.maxDistance);
1276
+ if (!this.enableDamping) {
1277
+ this.distance = this.targetDistance;
1278
+ this.update();
1279
+ }
1280
+ }
1281
+ }
1282
+ onTouchEnd(e) {
1283
+ if (e.touches.length < 2)
1284
+ this.touchStartDistance = 0;
1285
+ }
1286
+ static _touchA = new Vec2();
1287
+ static _touchB = new Vec2();
1288
+ static touchDistance(touches) {
1289
+ return OrbitControls._touchA.setScalar(touches[0].clientX, touches[0].clientY)
1290
+ .getDistance(OrbitControls._touchB.setScalar(touches[1].clientX, touches[1].clientY));
1291
+ }
1292
+ static _scratchForward = new Vec3();
1293
+ static _scratchRight = new Vec3();
1294
+ static _scratchUp = new Vec3();
1295
+ static _scratchPan = new Vec3();
1296
+ static _scratchSpherical = new Vec3();
1297
+ pan(deltaX, deltaY) {
1298
+ const factor = (this.distance / 1000) * this.panSpeed;
1299
+ const forward = this.camera.getViewDirection(OrbitControls._scratchForward);
1300
+ const right = OrbitControls._scratchRight.crossVectors(forward, this.camera.up).normalize();
1301
+ const up = OrbitControls._scratchUp.crossVectors(right, forward).normalize();
1302
+ OrbitControls._scratchPan.setScalar(0, 0, 0)
1303
+ .add(right.scale(-deltaX * factor))
1304
+ .add(up.scale(deltaY * factor));
1305
+ this.camera.target.add(OrbitControls._scratchPan);
1306
+ this.camera.position.add(OrbitControls._scratchPan);
1307
+ }
1308
+ update(deltaTime) {
1309
+ if (this.enableDamping) {
1310
+ const t = deltaTime === undefined
1311
+ ? this.dampingFactor
1312
+ : 1 - Math.pow(1 - this.dampingFactor, deltaTime * 60);
1313
+ const turn = Trigo.normalizeRadian(this.targetAzimuth - this.azimuth);
1314
+ this.azimuth = Utils.lerp(this.azimuth, this.azimuth + turn, t);
1315
+ this.elevation = Utils.lerp(this.elevation, this.targetElevation, t);
1316
+ this.distance = Utils.lerp(this.distance, this.targetDistance, t);
1317
+ }
1318
+ const target = this.camera.target;
1319
+ const pose = OrbitControls._scratchSpherical.setScalar(this.distance, this.azimuth, this.elevation);
1320
+ if (pose.equals(this.appliedPose) && target.equals(this.appliedTarget))
1321
+ return;
1322
+ this.appliedPose.copy(pose);
1323
+ this.appliedTarget.copy(target);
1324
+ this.camera.position.setFromSpherical(this.distance, this.azimuth, this.elevation).add(target);
1325
+ this.camera.setViewMatrix();
1326
+ }
1327
+ }
1328
+
1329
+ const Shader = {
1330
+ create(context, str, type) {
1331
+ let shader = context.createShader(context[type]);
1332
+ if (!shader)
1333
+ return null;
1334
+ context.shaderSource(shader, str);
1335
+ context.compileShader(shader);
1336
+ if (!context.getShaderParameter(shader, context.COMPILE_STATUS)) {
1337
+ console.error(`${type} compilation failed:`, context.getShaderInfoLog(shader));
1338
+ context.deleteShader(shader);
1339
+ return null;
1340
+ }
1341
+ return shader;
1342
+ }
1343
+ };
1344
+
1345
+ const caches = new WeakMap();
1346
+ const owners = new WeakMap();
1347
+ class Program {
1348
+ static create(context, vertexShader, fragmentShader) {
1349
+ let program = context.createProgram();
1350
+ if (program) {
1351
+ let vshader = Shader.create(context, vertexShader, 'VERTEX_SHADER');
1352
+ let fshader = Shader.create(context, fragmentShader, 'FRAGMENT_SHADER');
1353
+ if (!vshader || !fshader) {
1354
+ if (vshader)
1355
+ context.deleteShader(vshader);
1356
+ if (fshader)
1357
+ context.deleteShader(fshader);
1358
+ context.deleteProgram(program);
1359
+ return null;
1360
+ }
1361
+ context.attachShader(program, vshader);
1362
+ context.attachShader(program, fshader);
1363
+ context.linkProgram(program);
1364
+ if (!context.getProgramParameter(program, context.LINK_STATUS)) {
1365
+ console.error('Program link failed:', context.getProgramInfoLog(program));
1366
+ context.deleteShader(vshader);
1367
+ context.deleteShader(fshader);
1368
+ context.deleteProgram(program);
1369
+ return null;
1370
+ }
1371
+ context.detachShader(program, vshader);
1372
+ context.detachShader(program, fshader);
1373
+ context.deleteShader(vshader);
1374
+ context.deleteShader(fshader);
1375
+ }
1376
+ return program;
1377
+ }
1378
+ static acquire(context, vertexShader, fragmentShader) {
1379
+ let cache = caches.get(context);
1380
+ if (!cache) {
1381
+ cache = new Map();
1382
+ caches.set(context, cache);
1383
+ }
1384
+ const key = vertexShader + '\u0000' + fragmentShader;
1385
+ let entry = cache.get(key);
1386
+ if (!entry) {
1387
+ const program = Program.create(context, vertexShader, fragmentShader);
1388
+ if (!program)
1389
+ return null;
1390
+ entry = { program, key, refs: 0 };
1391
+ cache.set(key, entry);
1392
+ owners.set(program, entry);
1393
+ }
1394
+ entry.refs++;
1395
+ return entry.program;
1396
+ }
1397
+ static release(context, program) {
1398
+ const entry = owners.get(program);
1399
+ if (!entry) {
1400
+ context.deleteProgram(program);
1401
+ return;
1402
+ }
1403
+ if (--entry.refs > 0)
1404
+ return;
1405
+ caches.get(context)?.delete(entry.key);
1406
+ owners.delete(program);
1407
+ context.deleteProgram(program);
1408
+ }
1409
+ }
1410
+
1411
+ const isPowerOfTwo = (n) => (n & (n - 1)) === 0;
1412
+ function canGenerateMipmaps(context, width, height) {
1413
+ if (typeof WebGL2RenderingContext !== 'undefined' && context instanceof WebGL2RenderingContext)
1414
+ return true;
1415
+ return isPowerOfTwo(width) && isPowerOfTwo(height);
1416
+ }
1417
+ const Texture = {
1418
+ create(source, context, options) {
1419
+ let webGLTexture = context.createTexture();
1420
+ if (!webGLTexture)
1421
+ return null;
1422
+ const flipY = options?.flipY !== undefined ? options.flipY : true;
1423
+ const magFilter = options?.magFilter !== undefined ? options.magFilter : context.LINEAR;
1424
+ const minFilter = options?.minFilter !== undefined ? options.minFilter : context.LINEAR;
1425
+ const wrapS = options?.wrapS !== undefined ? options.wrapS : context.CLAMP_TO_EDGE;
1426
+ const wrapT = options?.wrapT !== undefined ? options.wrapT : context.CLAMP_TO_EDGE;
1427
+ context.bindTexture(context.TEXTURE_2D, webGLTexture);
1428
+ context.pixelStorei(context.UNPACK_FLIP_Y_WEBGL, flipY ? 1 : 0);
1429
+ context.texParameteri(context.TEXTURE_2D, context.TEXTURE_MAG_FILTER, magFilter);
1430
+ context.texParameteri(context.TEXTURE_2D, context.TEXTURE_MIN_FILTER, minFilter);
1431
+ context.texParameteri(context.TEXTURE_2D, context.TEXTURE_WRAP_S, wrapS);
1432
+ context.texParameteri(context.TEXTURE_2D, context.TEXTURE_WRAP_T, wrapT);
1433
+ if (source instanceof Uint8Array)
1434
+ context.texImage2D(context.TEXTURE_2D, 0, context.RGBA, options?.width || 1, options?.height || 1, 0, context.RGBA, context.UNSIGNED_BYTE, source);
1435
+ else
1436
+ context.texImage2D(context.TEXTURE_2D, 0, context.RGBA, context.RGBA, context.UNSIGNED_BYTE, source);
1437
+ if (options?.generateMipmaps) {
1438
+ const width = source instanceof Uint8Array ? options.width || 1 : source.width;
1439
+ const height = source instanceof Uint8Array ? options.height || 1 : source.height;
1440
+ if (canGenerateMipmaps(context, width, height))
1441
+ context.generateMipmap(context.TEXTURE_2D);
1442
+ else
1443
+ console.warn('Texture: mipmaps skipped, WebGL1 requires power-of-two dimensions.');
1444
+ }
1445
+ context.bindTexture(context.TEXTURE_2D, null);
1446
+ return webGLTexture;
1447
+ },
1448
+ load(url, context, options) {
1449
+ return new Promise((resolve, reject) => {
1450
+ const img = new Image();
1451
+ img.crossOrigin = 'anonymous';
1452
+ img.onload = () => resolve(Texture.create(img, context, options));
1453
+ img.onerror = (err) => reject(err);
1454
+ img.src = url;
1455
+ });
1456
+ },
1457
+ update(texture, source, context, xOffset = 0, yOffset = 0, width, height, flipY = true) {
1458
+ context.bindTexture(context.TEXTURE_2D, texture);
1459
+ context.pixelStorei(context.UNPACK_FLIP_Y_WEBGL, flipY ? 1 : 0);
1460
+ if (source instanceof Uint8Array)
1461
+ context.texSubImage2D(context.TEXTURE_2D, 0, xOffset, yOffset, width || 1, height || 1, context.RGBA, context.UNSIGNED_BYTE, source);
1462
+ else
1463
+ context.texSubImage2D(context.TEXTURE_2D, 0, xOffset, yOffset, context.RGBA, context.UNSIGNED_BYTE, source);
1464
+ context.bindTexture(context.TEXTURE_2D, null);
1465
+ }
1466
+ };
1467
+
1468
+ class Uniform {
1469
+ type;
1470
+ value;
1471
+ constructor(type, value) {
1472
+ this.type = type;
1473
+ this.value = value;
1474
+ }
1475
+ }
1476
+ function uploadUniform(context, location, uniform) {
1477
+ const value = uniform.value;
1478
+ const type = uniform.type;
1479
+ if (value instanceof Vec3)
1480
+ context.uniform3f(location, value.x, value.y, value.z);
1481
+ else if (value instanceof Vec2)
1482
+ context.uniform2f(location, value.x, value.y);
1483
+ else if (value instanceof Quat)
1484
+ context.uniform4f(location, value.vector.x, value.vector.y, value.vector.z, value.w);
1485
+ else if (value instanceof Mat4 || value instanceof Mat4x3 || value instanceof Mat3) {
1486
+ if (value instanceof Mat3)
1487
+ context.uniformMatrix3fv(location, false, value.toArray());
1488
+ else
1489
+ context.uniformMatrix4fv(location, false, value.toArray());
1490
+ }
1491
+ else if (type.indexOf('Matrix') !== -1)
1492
+ context[type](location, false, value);
1493
+ else
1494
+ context[type](location, value);
1495
+ }
1496
+
1497
+ class MeshRenderer {
1498
+ context;
1499
+ state;
1500
+ constructor(context) {
1501
+ this.context = context;
1502
+ this.state = getGLState(context);
1503
+ this.defaultSettings();
1504
+ }
1505
+ defaultSettings() {
1506
+ }
1507
+ createBuffer(target, size, drawMethod) {
1508
+ let buffer = this.context.createBuffer();
1509
+ this.bindBuffer(target, buffer);
1510
+ this.context.bufferData(this.context[target], size, this.context[drawMethod]);
1511
+ return buffer;
1512
+ }
1513
+ useProgram(program) {
1514
+ if (this.state.program === program)
1515
+ return;
1516
+ this.state.program = program;
1517
+ this.context.useProgram(program);
1518
+ }
1519
+ bindBuffer(target, buffer) {
1520
+ if (target === 'ARRAY_BUFFER') {
1521
+ if (this.state.arrayBuffer === buffer)
1522
+ return;
1523
+ this.state.arrayBuffer = buffer;
1524
+ }
1525
+ else if (target === 'ELEMENT_ARRAY_BUFFER') {
1526
+ if (this.state.elementBuffer === buffer)
1527
+ return;
1528
+ this.state.elementBuffer = buffer;
1529
+ }
1530
+ this.context.bindBuffer(this.context[target], buffer);
1531
+ }
1532
+ deleteBuffer(buffer) {
1533
+ if (this.state.arrayBuffer === buffer)
1534
+ this.state.arrayBuffer = null;
1535
+ if (this.state.elementBuffer === buffer)
1536
+ this.state.elementBuffer = null;
1537
+ this.context.deleteBuffer(buffer);
1538
+ }
1539
+ setAttributeMask(mask) {
1540
+ const previous = this.state.attributeMask;
1541
+ if (previous === mask)
1542
+ return;
1543
+ if (this.state.maxAttributes === 0)
1544
+ this.state.maxAttributes = Math.min(16, this.context.getParameter(this.context.MAX_VERTEX_ATTRIBS) || 8);
1545
+ const changed = previous === null ? (1 << this.state.maxAttributes) - 1 : previous ^ mask;
1546
+ for (let i = 0; i < this.state.maxAttributes && (changed >> i) !== 0; i++)
1547
+ if ((changed >> i) & 1)
1548
+ if ((mask >> i) & 1)
1549
+ this.context.enableVertexAttribArray(i);
1550
+ else
1551
+ this.context.disableVertexAttribArray(i);
1552
+ this.state.attributeMask = mask;
1553
+ }
1554
+ vertexAttribPointer(index, size, type, normalized, stride, offset) {
1555
+ this.context.vertexAttribPointer(index, size, this.context[type], normalized, stride, offset);
1556
+ }
1557
+ drawElements(primitive, subMesh, indexType) {
1558
+ const mode = typeof primitive === 'number' ? primitive : (this.context[primitive] ?? this.context.TRIANGLES);
1559
+ const type = indexType ?? this.context.UNSIGNED_SHORT;
1560
+ const bytes = type === this.context.UNSIGNED_SHORT ? 2 : 4;
1561
+ this.context.drawElements(mode, subMesh.count, type, subMesh.start * bytes);
1562
+ }
1563
+ drawArrays(primitive, subMesh) {
1564
+ const mode = typeof primitive === 'number' ? primitive : (this.context[primitive] ?? this.context.TRIANGLES);
1565
+ this.context.drawArrays(mode, subMesh.start, subMesh.count);
1566
+ }
1567
+ }
1568
+
1569
+ class SubMesh {
1570
+ start;
1571
+ count;
1572
+ constructor(start, count) {
1573
+ this.start = start;
1574
+ this.count = count;
1575
+ }
1576
+ }
1577
+
1578
+ class Material {
1579
+ ambient;
1580
+ diffuse;
1581
+ specular;
1582
+ shininess;
1583
+ uniforms;
1584
+ version = 0;
1585
+ constructor(options) {
1586
+ this.ambient = new Vec3(0.5, 0.5, 0.5);
1587
+ this.diffuse = new Vec3(0.6, 0.6, 0.6);
1588
+ this.specular = new Vec3(0.8, 0.8, 0.8);
1589
+ this.shininess = 8.0;
1590
+ this.uniforms = {
1591
+ materialAmbient: new Uniform('uniform3fv', this.ambient.toArray()),
1592
+ materialDiffuse: new Uniform('uniform3fv', this.diffuse.toArray()),
1593
+ materialSpecular: new Uniform('uniform3fv', this.specular.toArray()),
1594
+ materialShininess: new Uniform('uniform1f', this.shininess)
1595
+ };
1596
+ if (options) {
1597
+ if (options.ambient)
1598
+ this.setAmbient(options.ambient);
1599
+ if (options.diffuse)
1600
+ this.setDiffuse(options.diffuse);
1601
+ if (options.specular)
1602
+ this.setSpecular(options.specular);
1603
+ if (options.shininess !== undefined)
1604
+ this.setShininess(options.shininess);
1605
+ }
1606
+ }
1607
+ setAmbient(xOrVec, y, z) {
1608
+ assignVec3(this.ambient, xOrVec, y, z).toArray(this.uniforms.materialAmbient.value);
1609
+ this.version++;
1610
+ }
1611
+ setDiffuse(xOrVec, y, z) {
1612
+ assignVec3(this.diffuse, xOrVec, y, z).toArray(this.uniforms.materialDiffuse.value);
1613
+ this.version++;
1614
+ }
1615
+ setSpecular(xOrVec, y, z) {
1616
+ assignVec3(this.specular, xOrVec, y, z).toArray(this.uniforms.materialSpecular.value);
1617
+ this.version++;
1618
+ }
1619
+ setShininess(shininess) {
1620
+ this.shininess = shininess;
1621
+ this.uniforms.materialShininess.value = this.shininess;
1622
+ this.version++;
1623
+ }
1624
+ updateUniforms() {
1625
+ let changed = this.sync(this.ambient, this.uniforms.materialAmbient);
1626
+ changed = this.sync(this.diffuse, this.uniforms.materialDiffuse) || changed;
1627
+ changed = this.sync(this.specular, this.uniforms.materialSpecular) || changed;
1628
+ if (this.uniforms.materialShininess.value !== this.shininess) {
1629
+ this.uniforms.materialShininess.value = this.shininess;
1630
+ changed = true;
1631
+ }
1632
+ if (changed)
1633
+ this.version++;
1634
+ return changed;
1635
+ }
1636
+ sync(vector, uniform) {
1637
+ const value = uniform.value;
1638
+ if (value[0] === vector.x && value[1] === vector.y && value[2] === vector.z)
1639
+ return false;
1640
+ vector.toArray(value);
1641
+ return true;
1642
+ }
1643
+ }
1644
+
1645
+ const BasicShader = {
1646
+ vertex: `
1647
+ attribute vec3 aVertexPosition;
1648
+ attribute vec2 aTextureCoord;
1649
+
1650
+ uniform mat4 uModelMatrix;
1651
+ uniform mat4 uViewMatrix;
1652
+ uniform mat4 uProjectionMatrix;
1653
+
1654
+ varying vec2 vTextureCoord;
1655
+
1656
+ void main(void) {
1657
+ vTextureCoord = aTextureCoord;
1658
+ gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4(aVertexPosition, 1.0);
1659
+ }
1660
+ `,
1661
+ fragment: `
1662
+ precision mediump float;
1663
+
1664
+ varying vec2 vTextureCoord;
1665
+
1666
+ uniform sampler2D uSampler;
1667
+ uniform vec3 uMaterialDiffuse;
1668
+ uniform int uHasTexture;
1669
+
1670
+ void main(void) {
1671
+ vec4 color = vec4(uMaterialDiffuse, 1.0);
1672
+ if (uHasTexture == 1) {
1673
+ color *= texture2D(uSampler, vTextureCoord);
1674
+ }
1675
+ gl_FragColor = color;
1676
+ }
1677
+ `,
1678
+ create(context) {
1679
+ return Program.create(context, BasicShader.vertex, BasicShader.fragment);
1680
+ }
1681
+ };
1682
+ const NormalShader = {
1683
+ vertex: `
1684
+ attribute vec3 aVertexPosition;
1685
+ attribute vec3 aVertexNormal;
1686
+
1687
+ uniform mat4 uModelMatrix;
1688
+ uniform mat4 uViewMatrix;
1689
+ uniform mat4 uProjectionMatrix;
1690
+ uniform mat3 uNormalMatrix;
1691
+
1692
+ varying vec3 vNormal;
1693
+
1694
+ void main(void) {
1695
+ vNormal = normalize(uNormalMatrix * aVertexNormal);
1696
+ gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4(aVertexPosition, 1.0);
1697
+ }
1698
+ `,
1699
+ fragment: `
1700
+ precision mediump float;
1701
+
1702
+ varying vec3 vNormal;
1703
+
1704
+ void main(void) {
1705
+ gl_FragColor = vec4(vNormal * 0.5 + 0.5, 1.0);
1706
+ }
1707
+ `,
1708
+ create(context) {
1709
+ return Program.create(context, NormalShader.vertex, NormalShader.fragment);
1710
+ }
1711
+ };
1712
+ const PhongShader = {
1713
+ vertex: `
1714
+ attribute vec3 aVertexPosition;
1715
+ attribute vec3 aVertexNormal;
1716
+ attribute vec2 aTextureCoord;
1717
+
1718
+ uniform mat4 uModelMatrix;
1719
+ uniform mat4 uViewMatrix;
1720
+ uniform mat4 uProjectionMatrix;
1721
+ uniform mat3 uNormalMatrix;
1722
+
1723
+ varying vec3 vWorldPosition;
1724
+ varying vec3 vNormal;
1725
+ varying vec2 vTextureCoord;
1726
+
1727
+ void main(void) {
1728
+ vec4 worldPos = uModelMatrix * vec4(aVertexPosition, 1.0);
1729
+ vWorldPosition = worldPos.xyz;
1730
+ vNormal = normalize(uNormalMatrix * aVertexNormal);
1731
+ vTextureCoord = aTextureCoord;
1732
+ gl_Position = uProjectionMatrix * uViewMatrix * worldPos;
1733
+ }
1734
+ `,
1735
+ fragment: `
1736
+ #ifdef GL_FRAGMENT_PRECISION_HIGH
1737
+ precision highp float;
1738
+ #else
1739
+ precision mediump float;
1740
+ #endif
1741
+
1742
+ varying vec3 vWorldPosition;
1743
+ varying vec3 vNormal;
1744
+ varying vec2 vTextureCoord;
1745
+
1746
+ uniform vec3 uMaterialAmbient;
1747
+ uniform vec3 uMaterialDiffuse;
1748
+ uniform vec3 uMaterialSpecular;
1749
+ uniform float uMaterialShininess;
1750
+
1751
+ uniform vec3 uAmbientLight;
1752
+ uniform vec3 uAmbientColor;
1753
+
1754
+ const int MAX_LIGHTS = 8;
1755
+ uniform int uNbLights;
1756
+ // Packed: (position.xyz, type), (diffuse.rgb, cutoff), (specular.rgb, exponent)
1757
+ uniform vec4 uLightPositionType[MAX_LIGHTS];
1758
+ uniform vec4 uLightDiffuseCutoff[MAX_LIGHTS];
1759
+ uniform vec4 uLightSpecularExponent[MAX_LIGHTS];
1760
+ uniform vec3 uLightDirection[MAX_LIGHTS];
1761
+ uniform vec3 uLightAttenuation[MAX_LIGHTS];
1762
+
1763
+ uniform sampler2D uSampler;
1764
+ uniform int uHasTexture;
1765
+
1766
+ uniform vec3 uCameraPosition;
1767
+
1768
+ uniform vec3 uFogColor;
1769
+ uniform float uFogNear;
1770
+ uniform float uFogFar;
1771
+ uniform int uHasFog;
1772
+
1773
+ void main(void) {
1774
+ vec3 normal = normalize(vNormal);
1775
+ vec3 viewDir = normalize(uCameraPosition - vWorldPosition);
1776
+
1777
+ vec3 totalAmbient = (uAmbientLight + uAmbientColor) * uMaterialAmbient;
1778
+ vec3 totalDiffuse = vec3(0.0);
1779
+ vec3 totalSpecular = vec3(0.0);
1780
+
1781
+ for (int i = 0; i < MAX_LIGHTS; i++) {
1782
+ if (i >= uNbLights) break;
1783
+
1784
+ vec4 positionType = uLightPositionType[i];
1785
+ vec4 diffuseCutoff = uLightDiffuseCutoff[i];
1786
+ vec4 specularExponent = uLightSpecularExponent[i];
1787
+
1788
+ vec3 lightDir;
1789
+ float attenuation = 1.0;
1790
+
1791
+ if (positionType.w < 0.5) {
1792
+ // Directional
1793
+ lightDir = normalize(-uLightDirection[i]);
1794
+ } else {
1795
+ // Point or Spot
1796
+ vec3 lightVec = positionType.xyz - vWorldPosition;
1797
+ float d = length(lightVec);
1798
+ lightDir = normalize(lightVec);
1799
+
1800
+ float c = uLightAttenuation[i].x;
1801
+ float l = uLightAttenuation[i].y;
1802
+ float q = uLightAttenuation[i].z;
1803
+ attenuation = 1.0 / max(c + l * d + q * d * d, 1.0);
1804
+
1805
+ if (positionType.w > 1.5) {
1806
+ // Spot
1807
+ float spotEffect = dot(normalize(uLightDirection[i]), -lightDir);
1808
+ float cutoffCos = cos(radians(diffuseCutoff.w));
1809
+ if (spotEffect > cutoffCos) {
1810
+ attenuation *= pow(spotEffect, max(specularExponent.w, 1.0));
1811
+ } else {
1812
+ attenuation = 0.0;
1813
+ }
1814
+ }
1815
+ }
1816
+
1817
+ float NdotL = max(dot(normal, lightDir), 0.0);
1818
+ totalDiffuse += diffuseCutoff.rgb * uMaterialDiffuse * NdotL * attenuation;
1819
+
1820
+ if (NdotL > 0.0) {
1821
+ vec3 halfDir = normalize(lightDir + viewDir);
1822
+ float NdotH = max(dot(normal, halfDir), 0.0);
1823
+ float spec = pow(NdotH, max(uMaterialShininess, 1.0));
1824
+ totalSpecular += specularExponent.rgb * uMaterialSpecular * spec * attenuation;
1825
+ }
1826
+ }
1827
+
1828
+ vec4 texColor = vec4(1.0);
1829
+ if (uHasTexture == 1) {
1830
+ texColor = texture2D(uSampler, vTextureCoord);
1831
+ }
1832
+
1833
+ vec3 finalColor = (totalAmbient + totalDiffuse) * texColor.rgb + totalSpecular;
1834
+
1835
+ if (uHasFog == 1) {
1836
+ float dist = length(uCameraPosition - vWorldPosition);
1837
+ float fogFactor = clamp((uFogFar - dist) / max(uFogFar - uFogNear, 0.0001), 0.0, 1.0);
1838
+ finalColor = mix(uFogColor, finalColor, fogFactor);
1839
+ }
1840
+
1841
+ gl_FragColor = vec4(finalColor, texColor.a);
1842
+ }
1843
+ `,
1844
+ create(context) {
1845
+ return Program.create(context, PhongShader.vertex, PhongShader.fragment);
1846
+ }
1847
+ };
1848
+
1849
+ var eDrawMethod;
1850
+ (function (eDrawMethod) {
1851
+ eDrawMethod["drawElements"] = "drawElements";
1852
+ eDrawMethod["drawArrays"] = "drawArrays";
1853
+ })(eDrawMethod || (eDrawMethod = {}));
1854
+ class Mesh {
1855
+ boundingBox;
1856
+ boundingSphere;
1857
+ vertices;
1858
+ indices;
1859
+ normals;
1860
+ uvs;
1861
+ itemSize;
1862
+ subMeshes;
1863
+ nbSubMeshes;
1864
+ primitive;
1865
+ customUniforms;
1866
+ context;
1867
+ renderer;
1868
+ WebGLTexture;
1869
+ vertexBuffer;
1870
+ indexBuffer;
1871
+ normalBuffer;
1872
+ texCoordBuffer;
1873
+ position;
1874
+ scale;
1875
+ quaternion;
1876
+ modelMatrix;
1877
+ worldMatrix;
1878
+ normalMatrix;
1879
+ parent = null;
1880
+ traversalStamp = 0;
1881
+ sortKey = 0;
1882
+ _rotation;
1883
+ isRotationStale;
1884
+ isTransformDirty;
1885
+ isWorldDirty = true;
1886
+ ownsTexture = false;
1887
+ indexType;
1888
+ static UP = new Vec3(0, 1, 0);
1889
+ static scratchQuat = new Quat();
1890
+ static scratchView = new Mat4x3();
1891
+ static scratchVec = new Vec3();
1892
+ static scratchCamera = new Vec3();
1893
+ static scratchDir = new Vec3();
1894
+ static scratchA = new Vec3();
1895
+ static scratchB = new Vec3();
1896
+ static scratchC = new Vec3();
1897
+ static scratchHit = new Vec3();
1898
+ static scratchWorldHit = new Vec3();
1899
+ static scratchInverse = new Mat4x3();
1900
+ static scratchRay = new Ray3();
1901
+ isBoundsDirty = true;
1902
+ isNormalMatrixDirty = true;
1903
+ localBoundingBox;
1904
+ localBoundingSphere;
1905
+ active;
1906
+ drawMethod;
1907
+ programs;
1908
+ nbPrograms;
1909
+ materials;
1910
+ children;
1911
+ blendMode;
1912
+ blendOptions = { equation: 'FUNC_ADD', source: 'SRC_ALPHA', destination: 'ONE' };
1913
+ depthWrite = true;
1914
+ zOrder;
1915
+ constructor(meshOrContext, contextOrMesh) {
1916
+ let mesh;
1917
+ let context;
1918
+ if (meshOrContext && ('drawingBufferWidth' in meshOrContext || typeof meshOrContext.createBuffer === 'function')) {
1919
+ context = meshOrContext;
1920
+ mesh = contextOrMesh;
1921
+ }
1922
+ else {
1923
+ mesh = meshOrContext;
1924
+ context = contextOrMesh;
1925
+ }
1926
+ this.vertices = mesh && mesh.vertices ? mesh.vertices : null;
1927
+ this.indices = mesh && mesh.indices ? mesh.indices : null;
1928
+ this.normals = mesh && mesh.normals ? mesh.normals : null;
1929
+ this.uvs = mesh && mesh.uvs ? mesh.uvs : null;
1930
+ this.itemSize = mesh && mesh.itemSize ? mesh.itemSize : null;
1931
+ this.subMeshes = mesh && mesh.subMeshes ? mesh.subMeshes : [];
1932
+ if (this.subMeshes.length === 0 && this.vertices && this.vertices.length > 0)
1933
+ this.subMeshes = [new SubMesh(0, this.indices ? this.indices.length : this.vertices.length / (this.itemSize || 3))];
1934
+ this.nbSubMeshes = this.subMeshes.length;
1935
+ this.primitive = mesh && mesh.primitive ? mesh.primitive : null;
1936
+ this.customUniforms = {};
1937
+ this.context = context;
1938
+ this.renderer = new MeshRenderer(this.context);
1939
+ this.WebGLTexture = null;
1940
+ this.vertexBuffer = this.vertices
1941
+ ? this.renderer.createBuffer('ARRAY_BUFFER', this.vertices instanceof Float32Array ? this.vertices : new Float32Array(this.vertices), 'STATIC_DRAW')
1942
+ : null;
1943
+ this.indexType = this.context.UNSIGNED_SHORT;
1944
+ this.indexBuffer = this.indices
1945
+ ? this.renderer.createBuffer('ELEMENT_ARRAY_BUFFER', this.createIndexData(this.indices), 'STATIC_DRAW')
1946
+ : null;
1947
+ this.normalBuffer = this.normals
1948
+ ? this.renderer.createBuffer('ARRAY_BUFFER', this.normals instanceof Float32Array ? this.normals : new Float32Array(this.normals), 'STATIC_DRAW')
1949
+ : null;
1950
+ this.texCoordBuffer = this.uvs
1951
+ ? this.renderer.createBuffer('ARRAY_BUFFER', this.uvs instanceof Float32Array ? this.uvs : new Float32Array(this.uvs), 'STATIC_DRAW')
1952
+ : null;
1953
+ this.position = new Vec3();
1954
+ this._rotation = new Vec3();
1955
+ this.scale = new Vec3(1.0, 1.0, 1.0);
1956
+ this.quaternion = new Quat();
1957
+ this.modelMatrix = new Mat4x3();
1958
+ this.worldMatrix = new Mat4x3();
1959
+ this.normalMatrix = new Mat3();
1960
+ this.isRotationStale = false;
1961
+ this.isTransformDirty = false;
1962
+ this.modelMatrix.identity();
1963
+ this.worldMatrix.identity();
1964
+ this.normalMatrix.identity();
1965
+ this.isBoundsDirty = true;
1966
+ this.isNormalMatrixDirty = true;
1967
+ this.localBoundingBox = new Box();
1968
+ this.localBoundingSphere = new Sphere$1();
1969
+ this.boundingBox = new Box();
1970
+ this.boundingSphere = new Sphere$1();
1971
+ if (this.vertices && this.vertices.length > 0) {
1972
+ this.localBoundingBox.setFromPoints(this.vertices, this.itemSize || 3);
1973
+ this.localBoundingSphere.setFromPoints(this.vertices, undefined, this.itemSize || 3);
1974
+ }
1975
+ this.active = true;
1976
+ this.drawMethod = this.indices ? eDrawMethod.drawElements : eDrawMethod.drawArrays;
1977
+ this.programs = [];
1978
+ this.nbPrograms = 0;
1979
+ this.materials = [];
1980
+ this.children = [];
1981
+ this.blendMode = false;
1982
+ this.zOrder = 0;
1983
+ }
1984
+ setActive() {
1985
+ this.active = true;
1986
+ }
1987
+ setInactive() {
1988
+ this.active = false;
1989
+ }
1990
+ toggleActive() {
1991
+ this.active = !this.active;
1992
+ return this.active;
1993
+ }
1994
+ isActive() {
1995
+ return this.active;
1996
+ }
1997
+ addChild(mesh) {
1998
+ if (this.children.indexOf(mesh) === -1) {
1999
+ if (mesh.parent && mesh.parent !== this)
2000
+ mesh.parent.removeChild(mesh);
2001
+ this.children.push(mesh);
2002
+ mesh.parent = this;
2003
+ mesh.isWorldDirty = true;
2004
+ }
2005
+ }
2006
+ removeChild(mesh) {
2007
+ const index = this.children.indexOf(mesh);
2008
+ if (index !== -1) {
2009
+ this.children.splice(index, 1);
2010
+ mesh.parent = null;
2011
+ mesh.isWorldDirty = true;
2012
+ return true;
2013
+ }
2014
+ return false;
2015
+ }
2016
+ addProgram(vertexShaderOrProgram, fragmentShaderOrMaterial, material) {
2017
+ if (this.nbPrograms < this.nbSubMeshes) {
2018
+ let program;
2019
+ let mat;
2020
+ if (typeof vertexShaderOrProgram !== 'string') {
2021
+ program = vertexShaderOrProgram;
2022
+ mat = (fragmentShaderOrMaterial instanceof Material) ? fragmentShaderOrMaterial : new Material();
2023
+ }
2024
+ else {
2025
+ program = Program.acquire(this.context, vertexShaderOrProgram, fragmentShaderOrMaterial);
2026
+ mat = (material instanceof Material) ? material : (fragmentShaderOrMaterial instanceof Material ? fragmentShaderOrMaterial : new Material());
2027
+ }
2028
+ if (!program)
2029
+ return false;
2030
+ this.programs.push(program);
2031
+ this.addMaterial(mat);
2032
+ this.createProgram();
2033
+ return true;
2034
+ }
2035
+ return false;
2036
+ }
2037
+ clearPrograms() {
2038
+ for (let program of this.programs)
2039
+ Program.release(this.context, program);
2040
+ this.programs = [];
2041
+ this.nbPrograms = 0;
2042
+ this.materials = [];
2043
+ }
2044
+ addMaterial(material) {
2045
+ if (material && this.materials.length < this.nbSubMeshes) {
2046
+ this.materials.push(material);
2047
+ let materialUniforms = material.uniforms;
2048
+ for (let property in materialUniforms)
2049
+ if (materialUniforms.hasOwnProperty(property))
2050
+ for (let program of this.programs)
2051
+ if (program[property] === undefined)
2052
+ program[property] = this.context.getUniformLocation(program, 'u' + this.ucfirst(property));
2053
+ return true;
2054
+ }
2055
+ return false;
2056
+ }
2057
+ markDirty() {
2058
+ this.isTransformDirty = true;
2059
+ this.isBoundsDirty = true;
2060
+ this.isNormalMatrixDirty = true;
2061
+ }
2062
+ get rotation() {
2063
+ if (this.isRotationStale) {
2064
+ this.quaternion.getEuler(this._rotation);
2065
+ this.isRotationStale = false;
2066
+ }
2067
+ return this._rotation;
2068
+ }
2069
+ set rotation(euler) {
2070
+ this.setRotation(euler);
2071
+ }
2072
+ rotationChanged() {
2073
+ this.isRotationStale = true;
2074
+ this.markDirty();
2075
+ }
2076
+ setPosition(xOrVec, y, z) {
2077
+ assignVec3(this.position, xOrVec, y, z);
2078
+ this.markDirty();
2079
+ return this;
2080
+ }
2081
+ setRotation(xOrVec, y, z) {
2082
+ assignVec3(this._rotation, xOrVec, y, z);
2083
+ this.quaternion.setFromEuler(this._rotation);
2084
+ this.isRotationStale = false;
2085
+ this.markDirty();
2086
+ return this;
2087
+ }
2088
+ setScale(xOrVec, y, z) {
2089
+ if (typeof xOrVec === 'number' && y === undefined && z === undefined)
2090
+ this.scale.setScalar(xOrVec, xOrVec, xOrVec);
2091
+ else
2092
+ assignVec3(this.scale, xOrVec, y, z);
2093
+ this.markDirty();
2094
+ return this;
2095
+ }
2096
+ scaleBy(factorOrVec) {
2097
+ if (factorOrVec instanceof Vec3)
2098
+ this.scale.multiply(factorOrVec);
2099
+ else
2100
+ this.scale.scale(factorOrVec);
2101
+ this.markDirty();
2102
+ return this;
2103
+ }
2104
+ setQuaternion(q) {
2105
+ this.quaternion.copy(q);
2106
+ this.rotationChanged();
2107
+ return this;
2108
+ }
2109
+ slerp(targetQuat, t) {
2110
+ this.quaternion.slerp(targetQuat, t);
2111
+ this.rotationChanged();
2112
+ return this;
2113
+ }
2114
+ rotateX(angle) {
2115
+ this.quaternion.rotateX(angle);
2116
+ this.rotationChanged();
2117
+ return this;
2118
+ }
2119
+ rotateY(angle) {
2120
+ this.quaternion.rotateY(angle);
2121
+ this.rotationChanged();
2122
+ return this;
2123
+ }
2124
+ rotateZ(angle) {
2125
+ this.quaternion.rotateZ(angle);
2126
+ this.rotationChanged();
2127
+ return this;
2128
+ }
2129
+ rotateOnAxis(axis, angle) {
2130
+ this.quaternion.multiply(Mesh.scratchQuat.setAxisAngle(axis, angle));
2131
+ this.rotationChanged();
2132
+ return this;
2133
+ }
2134
+ translate(xOrVec, y, z) {
2135
+ if (typeof xOrVec === 'number')
2136
+ this.position.add(Mesh.scratchVec.setScalar(xOrVec, y ?? 0, z ?? 0));
2137
+ else
2138
+ this.position.add(xOrVec instanceof Vec3 ? xOrVec : Mesh.scratchVec.setArray(xOrVec));
2139
+ this.markDirty();
2140
+ return this;
2141
+ }
2142
+ lookAt(target, up = Mesh.UP) {
2143
+ if (this.position.equals(target))
2144
+ return this;
2145
+ this.quaternion.lookAt(this.position, target, up);
2146
+ this.rotationChanged();
2147
+ return this;
2148
+ }
2149
+ updateModelMatrix() {
2150
+ if (!this.isTransformDirty)
2151
+ return false;
2152
+ this.modelMatrix.compose(this.position, this.quaternion, this.scale);
2153
+ this.isTransformDirty = false;
2154
+ this.isBoundsDirty = true;
2155
+ this.isNormalMatrixDirty = true;
2156
+ return true;
2157
+ }
2158
+ computeNormalMatrix() {
2159
+ if (!this.isNormalMatrixDirty)
2160
+ return this.normalMatrix;
2161
+ this.worldMatrix.toNormalMatrix(this.normalMatrix.toArray());
2162
+ this.isNormalMatrixDirty = false;
2163
+ return this.normalMatrix;
2164
+ }
2165
+ getWorldPosition(target = new Vec3()) {
2166
+ return this.worldMatrix.getTranslation(target);
2167
+ }
2168
+ getWorldDirection(target = new Vec3()) {
2169
+ return this.worldMatrix.getColumn(2, target).opposite().normalize();
2170
+ }
2171
+ distanceTo(target) {
2172
+ const targetPos = target instanceof Vec3 ? target : target.getWorldPosition();
2173
+ return this.getWorldPosition(Mesh.scratchVec).getDistance(targetPos);
2174
+ }
2175
+ isInsideBounds(min, max) {
2176
+ return this.getWorldPosition(Mesh.scratchVec).isInBounds(min, max);
2177
+ }
2178
+ computeBounds() {
2179
+ if (!this.isBoundsDirty)
2180
+ return;
2181
+ if (this.vertices && this.vertices.length > 0) {
2182
+ this.boundingBox.copy(this.localBoundingBox).applyMatrix4(this.worldMatrix);
2183
+ this.boundingSphere.copy(this.localBoundingSphere).applyMatrix4(this.worldMatrix);
2184
+ }
2185
+ else {
2186
+ const pos = this.getWorldPosition(Mesh.scratchVec);
2187
+ this.boundingBox.set(pos, pos);
2188
+ this.boundingSphere.set(pos, 0);
2189
+ }
2190
+ this.isBoundsDirty = false;
2191
+ }
2192
+ computeBoundingBox() {
2193
+ this.computeBounds();
2194
+ return this.boundingBox;
2195
+ }
2196
+ computeBoundingSphere() {
2197
+ this.computeBounds();
2198
+ return this.boundingSphere;
2199
+ }
2200
+ raycast(ray, precise = false) {
2201
+ if (!this.isActive())
2202
+ return null;
2203
+ const sphere = this.computeBoundingSphere();
2204
+ const hitPoint = ray.intersectSphere(sphere);
2205
+ if (!hitPoint)
2206
+ return null;
2207
+ if (precise && this.vertices && (this.primitive === 'TRIANGLES' || this.primitive === 'TRIANGLE_STRIP'))
2208
+ return this.raycastTriangles(ray);
2209
+ return { distance: ray.origin.getDistance(hitPoint), point: hitPoint };
2210
+ }
2211
+ raycastTriangles(ray) {
2212
+ const inverse = Mesh.scratchInverse.copy(this.worldMatrix).invertAffine();
2213
+ const localRay = Mesh.scratchRay.set(inverse.transformPoint(ray.origin, Mesh.scratchVec), inverse.transformDirection(ray.direction, Mesh.scratchDir));
2214
+ const strip = this.primitive === 'TRIANGLE_STRIP';
2215
+ let best = null;
2216
+ let bestDistance = Infinity;
2217
+ for (const subMesh of this.subMeshes) {
2218
+ const end = subMesh.start + subMesh.count;
2219
+ for (let i = subMesh.start; i + 2 < end; i += strip ? 1 : 3) {
2220
+ this.getVertex(i, Mesh.scratchA);
2221
+ if (strip && (i - subMesh.start) % 2 === 1) {
2222
+ this.getVertex(i + 2, Mesh.scratchB);
2223
+ this.getVertex(i + 1, Mesh.scratchC);
2224
+ }
2225
+ else {
2226
+ this.getVertex(i + 1, Mesh.scratchB);
2227
+ this.getVertex(i + 2, Mesh.scratchC);
2228
+ }
2229
+ const local = localRay.intersectTriangle(Mesh.scratchA, Mesh.scratchB, Mesh.scratchC, false, Mesh.scratchHit);
2230
+ if (!local)
2231
+ continue;
2232
+ const world = this.worldMatrix.transformPoint(local, Mesh.scratchWorldHit);
2233
+ const distance = ray.origin.getDistance(world);
2234
+ if (distance < bestDistance) {
2235
+ bestDistance = distance;
2236
+ best = (best ?? new Vec3()).copy(world);
2237
+ }
2238
+ }
2239
+ }
2240
+ return best ? { distance: bestDistance, point: best } : null;
2241
+ }
2242
+ getVertex(index, target) {
2243
+ const vertices = this.vertices;
2244
+ const size = this.itemSize || 3;
2245
+ const offset = (this.indices ? this.indices[index] : index) * size;
2246
+ return target.setScalar(vertices[offset], vertices[offset + 1], size > 2 ? vertices[offset + 2] : 0);
2247
+ }
2248
+ useBasicMaterial(options) {
2249
+ const mat = new Material();
2250
+ if (options?.color)
2251
+ mat.setDiffuse(options.color);
2252
+ this.addProgram(BasicShader.vertex, BasicShader.fragment, mat);
2253
+ this.applyTextureOption(options?.texture);
2254
+ return this;
2255
+ }
2256
+ usePhongMaterial(options) {
2257
+ const mat = new Material();
2258
+ if (options?.ambient)
2259
+ mat.setAmbient(options.ambient);
2260
+ if (options?.diffuse)
2261
+ mat.setDiffuse(options.diffuse);
2262
+ if (options?.specular)
2263
+ mat.setSpecular(options.specular);
2264
+ if (options?.shininess !== undefined)
2265
+ mat.setShininess(options.shininess);
2266
+ this.addProgram(PhongShader.vertex, PhongShader.fragment, mat);
2267
+ this.applyTextureOption(options?.texture);
2268
+ return this;
2269
+ }
2270
+ useNormalMaterial() {
2271
+ this.addProgram(NormalShader.vertex, NormalShader.fragment, new Material());
2272
+ return this;
2273
+ }
2274
+ applyTextureOption(texture) {
2275
+ if (!texture)
2276
+ return;
2277
+ if (typeof WebGLTexture !== 'undefined' && texture instanceof WebGLTexture) {
2278
+ this.releaseTexture();
2279
+ this.WebGLTexture = texture;
2280
+ this.ownsTexture = false;
2281
+ }
2282
+ else
2283
+ this.setTexture(texture);
2284
+ }
2285
+ releaseTexture() {
2286
+ if (this.WebGLTexture && this.ownsTexture)
2287
+ this.context.deleteTexture(this.WebGLTexture);
2288
+ this.WebGLTexture = null;
2289
+ this.ownsTexture = false;
2290
+ }
2291
+ setWorldMatrix(worldMatrix) {
2292
+ this.worldMatrix.copy(worldMatrix).multiply(this.modelMatrix);
2293
+ this.isBoundsDirty = true;
2294
+ this.isNormalMatrixDirty = true;
2295
+ this.isWorldDirty = false;
2296
+ }
2297
+ setTexture(img, options) {
2298
+ const texture = Texture.create(img, this.context, options);
2299
+ if (!texture)
2300
+ return;
2301
+ this.releaseTexture();
2302
+ this.WebGLTexture = texture;
2303
+ this.ownsTexture = true;
2304
+ for (let program of this.programs)
2305
+ if (program.sampler === undefined)
2306
+ program.sampler = this.context.getUniformLocation(program, 'uSampler');
2307
+ }
2308
+ addCustomUniform(name, type, value) {
2309
+ if (!this.customUniforms.hasOwnProperty(name)) {
2310
+ this.customUniforms[name] = new Uniform(type, value);
2311
+ for (let program of this.programs)
2312
+ if (program[name] === undefined)
2313
+ program[name] = this.context.getUniformLocation(program, 'u' + this.ucfirst(name));
2314
+ }
2315
+ }
2316
+ setCustomUniform(name, value) {
2317
+ if (this.customUniforms.hasOwnProperty(name))
2318
+ this.customUniforms[name].value = value;
2319
+ }
2320
+ createIndexData(indices) {
2321
+ let max = 0;
2322
+ for (let i = 0; i < indices.length; i++)
2323
+ if (indices[i] > max)
2324
+ max = indices[i];
2325
+ if (max > 65535) {
2326
+ if (this.context.getExtension && this.context.getExtension('OES_element_index_uint')) {
2327
+ this.indexType = this.context.UNSIGNED_INT;
2328
+ return new Uint32Array(indices);
2329
+ }
2330
+ console.warn('Mesh: indices exceed 65535 but OES_element_index_uint is unavailable; geometry will be corrupted.');
2331
+ }
2332
+ return indices instanceof Uint16Array ? indices : new Uint16Array(indices);
2333
+ }
2334
+ static initializedPrograms = new WeakSet();
2335
+ createProgram() {
2336
+ let program = this.programs[this.nbPrograms];
2337
+ if (!Mesh.initializedPrograms.has(program)) {
2338
+ Mesh.initializedPrograms.add(program);
2339
+ this.addProgramAttribute('vertexPosition');
2340
+ this.addProgramAttribute('vertexNormal');
2341
+ this.addProgramAttribute('textureCoord');
2342
+ this.addProgramUniform('modelMatrix');
2343
+ this.addProgramUniform('normalMatrix');
2344
+ this.addProgramUniform('viewMatrix');
2345
+ this.addProgramUniform('projectionMatrix');
2346
+ this.addProgramUniform('time');
2347
+ this.addProgramUniform('screenResolution');
2348
+ this.addProgramUniform('sampler');
2349
+ this.addProgramUniform('hasTexture');
2350
+ this.addProgramUniform('nbLights');
2351
+ this.addProgramUniform('lightPosition');
2352
+ this.addProgramUniform('lightDiffuse');
2353
+ this.addProgramUniform('lightSpecular');
2354
+ this.addProgramUniform('lightDirection');
2355
+ this.addProgramUniform('lightAttenuation');
2356
+ this.addProgramUniform('lightCutoff');
2357
+ this.addProgramUniform('lightExponent');
2358
+ this.addProgramUniform('lightType');
2359
+ this.addProgramUniform('lightPositionType');
2360
+ this.addProgramUniform('lightDiffuseCutoff');
2361
+ this.addProgramUniform('lightSpecularExponent');
2362
+ this.addProgramUniform('ambientLight');
2363
+ this.addProgramUniform('ambientColor');
2364
+ this.addProgramUniform('cameraPosition');
2365
+ this.addProgramUniform('hasFog');
2366
+ this.addProgramUniform('fogColor');
2367
+ this.addProgramUniform('fogNear');
2368
+ this.addProgramUniform('fogFar');
2369
+ if (program.screenResolution) {
2370
+ this.renderer.useProgram(program);
2371
+ let viewport = this.context.getParameter(this.context.VIEWPORT);
2372
+ if (viewport && viewport.length >= 4)
2373
+ this.context.uniform2f(program.screenResolution, viewport[2], viewport[3]);
2374
+ }
2375
+ }
2376
+ for (let property in this.customUniforms)
2377
+ if (this.customUniforms.hasOwnProperty(property) && program[property] === undefined)
2378
+ this.addProgramUniform(property);
2379
+ for (let mat of this.materials)
2380
+ for (let property in mat.uniforms)
2381
+ if (mat.uniforms.hasOwnProperty(property) && program[property] === undefined)
2382
+ this.addProgramUniform(property);
2383
+ this.nbPrograms++;
2384
+ }
2385
+ addProgramAttribute(name) {
2386
+ this.programs[this.nbPrograms][name] = this.context.getAttribLocation(this.programs[this.nbPrograms], 'a' + this.ucfirst(name));
2387
+ }
2388
+ addProgramUniform(name) {
2389
+ const ucName = 'u' + this.ucfirst(name);
2390
+ let loc = this.context.getUniformLocation(this.programs[this.nbPrograms], ucName);
2391
+ if (loc === null)
2392
+ loc = this.context.getUniformLocation(this.programs[this.nbPrograms], ucName + '[0]');
2393
+ this.programs[this.nbPrograms][name] = loc;
2394
+ }
2395
+ activateBlendMode() {
2396
+ this.blendMode = true;
2397
+ }
2398
+ deactivateBlendMode() {
2399
+ this.blendMode = false;
2400
+ }
2401
+ setBlend(source = 'SRC_ALPHA', destination = 'ONE', equation = 'FUNC_ADD') {
2402
+ this.blendOptions.equation = equation;
2403
+ this.blendOptions.source = source;
2404
+ this.blendOptions.destination = destination;
2405
+ this.blendMode = true;
2406
+ return this;
2407
+ }
2408
+ setDepthWrite(enabled) {
2409
+ this.depthWrite = enabled;
2410
+ return this;
2411
+ }
2412
+ computeWorldMatrix(graph) {
2413
+ const modelChanged = this.updateModelMatrix();
2414
+ const changed = this.isWorldDirty || modelChanged;
2415
+ if (changed)
2416
+ this.setWorldMatrix(graph.getWorldMatrix());
2417
+ graph.pushModelMatrix(this.worldMatrix);
2418
+ for (let child of this.children) {
2419
+ if (changed)
2420
+ child.isWorldDirty = true;
2421
+ child.computeWorldMatrix(graph);
2422
+ }
2423
+ graph.popModelMatrix();
2424
+ }
2425
+ render(projectionMatrix, viewMatrix, lights, time, blendMode, cameraPosition, fog, frame) {
2426
+ if (!this.isActive())
2427
+ return;
2428
+ this.renderSelf(projectionMatrix, viewMatrix, lights, time, blendMode, cameraPosition, fog, frame);
2429
+ for (let child of this.children)
2430
+ child.render(projectionMatrix, viewMatrix, lights, time, blendMode, cameraPosition, fog, frame);
2431
+ }
2432
+ renderSelf(projectionMatrix, viewMatrix, lights, time, blendMode, cameraPosition, fog, frame) {
2433
+ if (!this.isActive() || this.nbPrograms === 0 || this.blendMode !== blendMode)
2434
+ return;
2435
+ const context = this.context;
2436
+ const renderer = this.renderer;
2437
+ const state = renderer.state;
2438
+ for (let i = 0; i < this.nbSubMeshes; i++) {
2439
+ const program = this.programs[i] || this.programs[this.nbPrograms - 1];
2440
+ renderer.useProgram(program);
2441
+ if (!frame || state.frameOfProgram.get(program) !== frame.id) {
2442
+ if (frame)
2443
+ state.frameOfProgram.set(program, frame.id);
2444
+ this.uploadFrameUniforms(program, projectionMatrix, viewMatrix, lights, time, cameraPosition, fog, frame);
2445
+ }
2446
+ const material = this.materials[i] || this.materials[this.materials.length - 1];
2447
+ if (material) {
2448
+ material.updateUniforms();
2449
+ if (state.materialOfProgram.get(program) !== material || state.materialVersionOfProgram.get(program) !== material.version) {
2450
+ state.materialOfProgram.set(program, material);
2451
+ state.materialVersionOfProgram.set(program, material.version);
2452
+ const materialUniforms = material.uniforms;
2453
+ for (let property in materialUniforms)
2454
+ if (materialUniforms.hasOwnProperty(property) && program[property])
2455
+ uploadUniform(context, program[property], materialUniforms[property]);
2456
+ }
2457
+ }
2458
+ let attributeMask = 0;
2459
+ if (this.indices)
2460
+ renderer.bindBuffer('ELEMENT_ARRAY_BUFFER', this.indexBuffer);
2461
+ if (program.vertexPosition !== -1 && program.vertexPosition !== undefined && this.vertexBuffer) {
2462
+ renderer.bindBuffer('ARRAY_BUFFER', this.vertexBuffer);
2463
+ renderer.vertexAttribPointer(program.vertexPosition, this.itemSize, 'FLOAT', false, 0, 0);
2464
+ attributeMask |= 1 << program.vertexPosition;
2465
+ }
2466
+ if (this.normals && program.vertexNormal !== -1 && program.vertexNormal !== undefined) {
2467
+ renderer.bindBuffer('ARRAY_BUFFER', this.normalBuffer);
2468
+ renderer.vertexAttribPointer(program.vertexNormal, 3, 'FLOAT', false, 0, 0);
2469
+ attributeMask |= 1 << program.vertexNormal;
2470
+ }
2471
+ if (this.uvs && program.textureCoord !== -1 && program.textureCoord !== undefined) {
2472
+ renderer.bindBuffer('ARRAY_BUFFER', this.texCoordBuffer);
2473
+ renderer.vertexAttribPointer(program.textureCoord, 2, 'FLOAT', false, 0, 0);
2474
+ attributeMask |= 1 << program.textureCoord;
2475
+ }
2476
+ renderer.setAttributeMask(attributeMask);
2477
+ if (this.WebGLTexture) {
2478
+ context.activeTexture(context.TEXTURE0);
2479
+ context.bindTexture(context.TEXTURE_2D, this.WebGLTexture);
2480
+ if (program.sampler)
2481
+ context.uniform1i(program.sampler, 0);
2482
+ if (program.hasTexture)
2483
+ context.uniform1i(program.hasTexture, 1);
2484
+ }
2485
+ else if (program.hasTexture)
2486
+ context.uniform1i(program.hasTexture, 0);
2487
+ if (program.modelMatrix)
2488
+ context.uniformMatrix4fv(program.modelMatrix, false, this.worldMatrix.toArray());
2489
+ if (program.normalMatrix) {
2490
+ this.computeNormalMatrix();
2491
+ context.uniformMatrix3fv(program.normalMatrix, false, this.normalMatrix.toArray());
2492
+ }
2493
+ for (let property in this.customUniforms)
2494
+ if (this.customUniforms.hasOwnProperty(property) && program[property])
2495
+ uploadUniform(context, program[property], this.customUniforms[property]);
2496
+ renderer[this.drawMethod](this.primitive, this.subMeshes[i], this.indexType);
2497
+ }
2498
+ }
2499
+ static lightTypeValue(type) {
2500
+ return type === 'directional' ? 0 : type === 'point' ? 1 : 2;
2501
+ }
2502
+ static packVec4(xyz, w) {
2503
+ const count = Math.floor(xyz.length / 3);
2504
+ const packed = new Float32Array(count * 4);
2505
+ for (let i = 0; i < count; i++) {
2506
+ packed[i * 4] = xyz[i * 3];
2507
+ packed[i * 4 + 1] = xyz[i * 3 + 1];
2508
+ packed[i * 4 + 2] = xyz[i * 3 + 2];
2509
+ packed[i * 4 + 3] = w[i] || 0;
2510
+ }
2511
+ return packed;
2512
+ }
2513
+ uploadFrameUniforms(program, projectionMatrix, viewMatrix, lights, time, cameraPosition, fog, frame) {
2514
+ const context = this.context;
2515
+ if (program.projectionMatrix)
2516
+ context.uniformMatrix4fv(program.projectionMatrix, false, projectionMatrix);
2517
+ if (program.viewMatrix)
2518
+ context.uniformMatrix4fv(program.viewMatrix, false, viewMatrix);
2519
+ if (program.time)
2520
+ context.uniform1f(program.time, time);
2521
+ if (frame && frame.resolution && program.screenResolution)
2522
+ context.uniform2f(program.screenResolution, frame.resolution.x, frame.resolution.y);
2523
+ if (lights) {
2524
+ if (program.nbLights && lights.type)
2525
+ context.uniform1i(program.nbLights, lights.type.length);
2526
+ if (program.lightPosition && lights.position && lights.position.length > 0)
2527
+ context.uniform3fv(program.lightPosition, lights.floatPosition || new Float32Array(lights.position));
2528
+ if (program.lightDiffuse && lights.diffuse && lights.diffuse.length > 0)
2529
+ context.uniform3fv(program.lightDiffuse, lights.floatDiffuse || new Float32Array(lights.diffuse));
2530
+ if (program.lightSpecular && lights.specular && lights.specular.length > 0)
2531
+ context.uniform3fv(program.lightSpecular, lights.floatSpecular || new Float32Array(lights.specular));
2532
+ if (program.lightDirection && lights.direction && lights.direction.length > 0)
2533
+ context.uniform3fv(program.lightDirection, lights.floatDirection || new Float32Array(lights.direction));
2534
+ if (program.lightAttenuation && (lights.floatAttenuation || lights.constantAttenuation?.length)) {
2535
+ let attArr = lights.floatAttenuation;
2536
+ if (!attArr) {
2537
+ const att = [];
2538
+ for (let k = 0; k < lights.constantAttenuation.length; k++)
2539
+ att.push(lights.constantAttenuation[k] || 0, lights.linearAttenuation[k] || 0, lights.quadraticAttenuation[k] || 0);
2540
+ attArr = new Float32Array(att);
2541
+ }
2542
+ context.uniform3fv(program.lightAttenuation, attArr);
2543
+ }
2544
+ if (program.lightCutoff && lights.cutoff && lights.cutoff.length > 0)
2545
+ context.uniform1fv(program.lightCutoff, lights.floatCutoff || new Float32Array(lights.cutoff));
2546
+ if (program.lightExponent && lights.exponent && lights.exponent.length > 0)
2547
+ context.uniform1fv(program.lightExponent, lights.floatExponent || new Float32Array(lights.exponent));
2548
+ if (program.lightType && (lights.floatType || lights.type?.length)) {
2549
+ let typeArr = lights.floatType;
2550
+ if (!typeArr)
2551
+ typeArr = new Float32Array(lights.type.map(t => t === 'directional' ? 0 : t === 'point' ? 1 : 2));
2552
+ context.uniform1fv(program.lightType, typeArr);
2553
+ }
2554
+ if (program.lightPositionType && lights.position && lights.position.length > 0)
2555
+ context.uniform4fv(program.lightPositionType, lights.packedPosition || Mesh.packVec4(lights.position, (lights.type || []).map(Mesh.lightTypeValue)));
2556
+ if (program.lightDiffuseCutoff && lights.diffuse && lights.diffuse.length > 0)
2557
+ context.uniform4fv(program.lightDiffuseCutoff, lights.packedDiffuse || Mesh.packVec4(lights.diffuse, lights.cutoff || []));
2558
+ if (program.lightSpecularExponent && lights.specular && lights.specular.length > 0)
2559
+ context.uniform4fv(program.lightSpecularExponent, lights.packedSpecular || Mesh.packVec4(lights.specular, lights.exponent || []));
2560
+ if (program.ambientLight && lights.ambient)
2561
+ context.uniform3fv(program.ambientLight, lights.floatAmbient || new Float32Array(lights.ambient));
2562
+ }
2563
+ if (program.cameraPosition) {
2564
+ let camera = cameraPosition;
2565
+ if (!camera && viewMatrix) {
2566
+ Mesh.scratchView.toArray().set(viewMatrix);
2567
+ camera = Mesh.scratchView.invertAffine().getTranslation(Mesh.scratchCamera);
2568
+ }
2569
+ if (camera)
2570
+ context.uniform3f(program.cameraPosition, camera.x, camera.y, camera.z);
2571
+ }
2572
+ if (program.hasFog)
2573
+ if (fog) {
2574
+ context.uniform1i(program.hasFog, 1);
2575
+ if (program.fogColor)
2576
+ context.uniform3f(program.fogColor, fog.color.x, fog.color.y, fog.color.z);
2577
+ if (program.fogNear)
2578
+ context.uniform1f(program.fogNear, fog.near);
2579
+ if (program.fogFar)
2580
+ context.uniform1f(program.fogFar, fog.far);
2581
+ }
2582
+ else
2583
+ context.uniform1i(program.hasFog, 0);
2584
+ }
2585
+ destroy() {
2586
+ this.clearPrograms();
2587
+ if (this.vertexBuffer)
2588
+ this.renderer.deleteBuffer(this.vertexBuffer), this.vertexBuffer = null;
2589
+ if (this.indexBuffer)
2590
+ this.renderer.deleteBuffer(this.indexBuffer), this.indexBuffer = null;
2591
+ if (this.normalBuffer)
2592
+ this.renderer.deleteBuffer(this.normalBuffer), this.normalBuffer = null;
2593
+ if (this.texCoordBuffer)
2594
+ this.renderer.deleteBuffer(this.texCoordBuffer), this.texCoordBuffer = null;
2595
+ this.releaseTexture();
2596
+ for (let child of this.children) {
2597
+ child.parent = null;
2598
+ child.destroy();
2599
+ }
2600
+ this.children = [];
2601
+ }
2602
+ ucfirst(string) {
2603
+ return string.charAt(0).toUpperCase() + string.slice(1);
2604
+ }
2605
+ }
2606
+
2607
+ class BasicMesh {
2608
+ vertices;
2609
+ indices;
2610
+ normals;
2611
+ uvs;
2612
+ subMeshes;
2613
+ itemSize;
2614
+ primitive;
2615
+ constructor() {
2616
+ this.vertices = null;
2617
+ this.indices = null;
2618
+ this.normals = null;
2619
+ this.uvs = null;
2620
+ this.subMeshes = [];
2621
+ this.itemSize = 3;
2622
+ this.primitive = 'TRIANGLES';
2623
+ }
2624
+ }
2625
+
2626
+ class Line extends BasicMesh {
2627
+ thickness;
2628
+ constructor(vertices, thickness) {
2629
+ super();
2630
+ this.thickness = thickness ? thickness * 0.5 : 1.0;
2631
+ if (vertices && vertices.length > 0 && vertices[0] instanceof Vec3) {
2632
+ const flat = [];
2633
+ for (const v of vertices)
2634
+ flat.push(v.x, v.y, v.z);
2635
+ this.vertices = flat;
2636
+ }
2637
+ else
2638
+ this.vertices = vertices || [];
2639
+ this.itemSize = 3;
2640
+ this.subMeshes = [
2641
+ new SubMesh(0, this.vertices.length / this.itemSize)
2642
+ ];
2643
+ this.primitive = 'LINE_STRIP';
2644
+ }
2645
+ }
2646
+
2647
+ class FullscreenQuad extends BasicMesh {
2648
+ constructor() {
2649
+ super();
2650
+ this.vertices = [1.0, -1,
2651
+ -1, -1,
2652
+ 1.0, 1.0,
2653
+ -1, 1.0
2654
+ ];
2655
+ this.uvs = [1.0, 0.0,
2656
+ 0.0, 0.0,
2657
+ 1.0, 1.0,
2658
+ 0.0, 1.0
2659
+ ];
2660
+ this.subMeshes = [
2661
+ new SubMesh(0, 4)
2662
+ ];
2663
+ this.itemSize = 2;
2664
+ this.primitive = 'TRIANGLE_STRIP';
2665
+ }
2666
+ }
2667
+
2668
+ class Quad extends BasicMesh {
2669
+ constructor(sizeOrWidth, height) {
2670
+ super();
2671
+ let width;
2672
+ let h;
2673
+ if (sizeOrWidth instanceof Vec2) {
2674
+ width = sizeOrWidth.x * 0.5;
2675
+ h = sizeOrWidth.y * 0.5;
2676
+ }
2677
+ else if (sizeOrWidth instanceof Rect) {
2678
+ width = sizeOrWidth.size.x * 0.5;
2679
+ h = sizeOrWidth.size.y * 0.5;
2680
+ }
2681
+ else {
2682
+ width = sizeOrWidth ? sizeOrWidth * 0.5 : 1.0;
2683
+ h = height ? height * 0.5 : 1.0;
2684
+ }
2685
+ this.vertices = [width, -h, 0.0,
2686
+ -width, -h, 0.0,
2687
+ width, h, 0.0,
2688
+ -width, h, 0.0
2689
+ ];
2690
+ this.uvs = [1.0, 0.0,
2691
+ 0.0, 0.0,
2692
+ 1.0, 1.0,
2693
+ 0.0, 1.0
2694
+ ];
2695
+ this.subMeshes = [
2696
+ new SubMesh(0, 4)
2697
+ ];
2698
+ this.itemSize = 3;
2699
+ this.primitive = 'TRIANGLE_STRIP';
2700
+ }
2701
+ }
2702
+
2703
+ class MultiQuad extends BasicMesh {
2704
+ quad;
2705
+ constructor(sizeOrWidth, height) {
2706
+ super();
2707
+ let width;
2708
+ let h;
2709
+ if (sizeOrWidth instanceof Vec2) {
2710
+ width = sizeOrWidth.x * 0.5;
2711
+ h = sizeOrWidth.y * 0.5;
2712
+ }
2713
+ else if (sizeOrWidth instanceof Rect) {
2714
+ width = sizeOrWidth.size.x * 0.5;
2715
+ h = sizeOrWidth.size.y * 0.5;
2716
+ }
2717
+ else {
2718
+ width = sizeOrWidth ? sizeOrWidth * 0.5 : 1.0;
2719
+ h = height ? height * 0.5 : 1.0;
2720
+ }
2721
+ this.quad = {
2722
+ vertices: new Float32Array([width, -h, 0.0,
2723
+ -width, h, 0.0,
2724
+ -width, -h, 0.0,
2725
+ width, h, 0.0
2726
+ ]),
2727
+ indices: new Int32Array([0, 1, 2,
2728
+ 0, 3, 1
2729
+ ]),
2730
+ uvs: new Float32Array([1.0, 0.0,
2731
+ 0.0, 1.0,
2732
+ 0.0, 0.0,
2733
+ 1.0, 1.0
2734
+ ])
2735
+ };
2736
+ this.vertices = [];
2737
+ this.indices = [];
2738
+ this.uvs = [];
2739
+ this.subMeshes = [
2740
+ new SubMesh(0, 4)
2741
+ ];
2742
+ }
2743
+ createQuads(length) {
2744
+ for (let i = 0; i < length; i++) {
2745
+ this.vertices.push(...this.quad.vertices);
2746
+ this.indices.push(...this.createIndices(i));
2747
+ this.uvs.push(...this.quad.uvs);
2748
+ }
2749
+ if (this.subMeshes.length > 0 && length > 0)
2750
+ this.subMeshes[0].count = this.indices.length;
2751
+ }
2752
+ createIndices(quadIndex) {
2753
+ const indices = [];
2754
+ for (let i = 0; i < 6; i++)
2755
+ indices.push(this.quad.indices[i] + quadIndex * 4);
2756
+ return indices;
2757
+ }
2758
+ }
2759
+
2760
+ class Cube extends BasicMesh {
2761
+ constructor(sizeOrDimensions = 1.0, flat = false) {
2762
+ super();
2763
+ let sx, sy, sz;
2764
+ if (sizeOrDimensions instanceof Vec3) {
2765
+ const half = sizeOrDimensions.clone().halve();
2766
+ sx = half.x || 0.5;
2767
+ sy = half.y || 0.5;
2768
+ sz = half.z || 0.5;
2769
+ }
2770
+ else {
2771
+ const s = sizeOrDimensions ? sizeOrDimensions * 0.5 : 1.0;
2772
+ sx = s;
2773
+ sy = s;
2774
+ sz = s;
2775
+ }
2776
+ if (flat) {
2777
+ this.vertices = [
2778
+ -sx, -sy, sz, sx, -sy, sz, sx, sy, sz, -sx, sy, sz,
2779
+ sx, -sy, -sz, -sx, -sy, -sz, -sx, sy, -sz, sx, sy, -sz,
2780
+ -sx, sy, sz, sx, sy, sz, sx, sy, -sz, -sx, sy, -sz,
2781
+ -sx, -sy, -sz, sx, -sy, -sz, sx, -sy, sz, -sx, -sy, sz,
2782
+ sx, -sy, sz, sx, -sy, -sz, sx, sy, -sz, sx, sy, sz,
2783
+ -sx, -sy, -sz, -sx, -sy, sz, -sx, sy, sz, -sx, sy, -sz
2784
+ ];
2785
+ this.normals = [
2786
+ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
2787
+ 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1,
2788
+ 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,
2789
+ 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
2790
+ 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
2791
+ -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0
2792
+ ];
2793
+ this.indices = [
2794
+ 0, 1, 2, 0, 2, 3,
2795
+ 4, 5, 6, 4, 6, 7,
2796
+ 8, 9, 10, 8, 10, 11,
2797
+ 12, 13, 14, 12, 14, 15,
2798
+ 16, 17, 18, 16, 18, 19,
2799
+ 20, 21, 22, 20, 22, 23
2800
+ ];
2801
+ this.subMeshes = [
2802
+ new SubMesh(0, 36)
2803
+ ];
2804
+ return;
2805
+ }
2806
+ this.vertices = [sx, -sy, -sz,
2807
+ -sx, -sy, sz,
2808
+ sx, -sy, sz,
2809
+ -sx, sy, sz,
2810
+ sx, sy, -sz,
2811
+ sx, sy, sz,
2812
+ -sx, -sy, -sz,
2813
+ -sx, sy, -sz
2814
+ ];
2815
+ this.indices = [2, 5, 3, 2, 3, 1,
2816
+ 4, 0, 6, 4, 6, 7,
2817
+ 3, 5, 4, 3, 4, 7,
2818
+ 0, 2, 1, 0, 1, 6,
2819
+ 5, 2, 0, 5, 0, 4,
2820
+ 6, 1, 3, 6, 3, 7
2821
+ ];
2822
+ this.normals = [0.5773, -0.5773, -0.5773,
2823
+ -0.5773, -0.5773, 0.5773,
2824
+ 0.5773, -0.5773, 0.5773,
2825
+ -0.5773, 0.5773, 0.5773,
2826
+ 0.5773, 0.5773, -0.5773,
2827
+ 0.5773, 0.5773, 0.5773,
2828
+ -0.5773, -0.5773, -0.5773,
2829
+ -0.5773, 0.5773, -0.5773
2830
+ ];
2831
+ this.subMeshes = [
2832
+ new SubMesh(0, 36)
2833
+ ];
2834
+ }
2835
+ }
2836
+
2837
+ class Sphere extends BasicMesh {
2838
+ constructor() {
2839
+ super();
2840
+ this.vertices = [-0.7071, -0.7071, 0, -0.5449, -0.8315, 0.1084, -0.5556, -0.8315, 0, -0.8315, 0.5556, 0, -0.9061, 0.3827, 0.1802, -0.9239, 0.3827, 0, -0.3753, -0.9239, 0.0747, -0.3827, -0.9239, 0, -0.9619, 0.1951, 0.1913, -0.9808, 0.1951, 0, -0.1913, -0.9808, 0.0381, -0.1951, -0.9808, 0, -0.9808, 0, 0.1951, -1, 0, 0, -0.1951, 0.9808, 0, 0, 1, 0, -0.1913, 0.9808, 0.0381, 0, -1, 0, -0.9619, -0.1951, 0.1913, -0.9808, -0.1951, 0, -0.3753, 0.9239, 0.0747, -0.3827, 0.9239, 0, -0.9239, -0.3827, 0, -0.9061, -0.3827, 0.1802, -0.5556, 0.8315, 0, -0.5449, 0.8315, 0.1084, -0.8155, -0.5556, 0.1622, -0.8315, -0.5556, 0, -0.6935, 0.7071, 0.1379, -0.7071, 0.7071, 0, -0.6935, -0.7071, 0.1379, -0.8155, 0.5556, 0.1622, -0.7682, -0.5556, 0.3182, -0.6533, -0.7071, 0.2706, -0.7682, 0.5556, 0.3182, -0.5133, -0.8315, 0.2126, -0.8536, 0.3827, 0.3536, -0.3536, -0.9239, 0.1464, -0.9061, 0.1951, 0.3753, -0.1802, -0.9808, 0.0747, -0.9239, 0, 0.3827, -0.1802, 0.9808, 0.0747, -0.9061, -0.1951, 0.3753, -0.3536, 0.9239, 0.1464, -0.8536, -0.3827, 0.3536, -0.5133, 0.8315, 0.2126, -0.6533, 0.7071, 0.2706, -0.1622, 0.9808, 0.1084, -0.1622, -0.9808, 0.1084, -0.8155, -0.1951, 0.5449, -0.3182, 0.9239, 0.2126, -0.7682, -0.3827, 0.5133, -0.4619, 0.8315, 0.3087, -0.6913, -0.5556, 0.4619, -0.5879, 0.7071, 0.3928, -0.5879, -0.7071, 0.3928, -0.6913, 0.5556, 0.4619, -0.4619, -0.8315, 0.3087, -0.7682, 0.3827, 0.5133, -0.3182, -0.9239, 0.2126, -0.8155, 0.1951, 0.5449, -0.8315, 0, 0.5556, -0.5879, 0.5556, 0.5879, -0.3928, -0.8315, 0.3928, -0.6533, 0.3827, 0.6533, -0.2706, -0.9239, 0.2706, -0.6935, 0.1951, 0.6935, -0.1379, -0.9808, 0.1379, -0.7071, 0, 0.7071, -0.1379, 0.9808, 0.1379, -0.6935, -0.1951, 0.6935, -0.2706, 0.9239, 0.2706, -0.6533, -0.3827, 0.6533, -0.3928, 0.8315, 0.3928, -0.5879, -0.5556, 0.5879, -0.5, 0.7071, 0.5, -0.5, -0.7071, 0.5, -0.5449, -0.1951, 0.8155, -0.2126, 0.9239, 0.3182, -0.5133, -0.3827, 0.7682, -0.3087, 0.8315, 0.4619, -0.4619, -0.5556, 0.6913, -0.3928, 0.7071, 0.5879, -0.3928, -0.7071, 0.5879, -0.4619, 0.5556, 0.6913, -0.3087, -0.8315, 0.4619, -0.5133, 0.3827, 0.7682, -0.2126, -0.9239, 0.3182, -0.5449, 0.1951, 0.8155, -0.1084, -0.9808, 0.1622, -0.5556, 0, 0.8315, -0.1084, 0.9808, 0.1622, -0.2126, -0.8315, 0.5133, -0.3536, 0.3827, 0.8536, -0.1464, -0.9239, 0.3536, -0.3753, 0.1951, 0.9061, -0.0747, -0.9808, 0.1802, -0.3827, 0, 0.9239, -0.0747, 0.9808, 0.1802, -0.3753, -0.1951, 0.9061, -0.1464, 0.9239, 0.3536, -0.3536, -0.3827, 0.8536, -0.2126, 0.8315, 0.5133, -0.3182, -0.5556, 0.7682, -0.2706, 0.7071, 0.6533, -0.2706, -0.7071, 0.6533, -0.3182, 0.5556, 0.7682, -0.1802, -0.3827, 0.9061, -0.1084, 0.8315, 0.5449, -0.1622, -0.5556, 0.8155, -0.1379, 0.7071, 0.6935, -0.1379, -0.7071, 0.6935, -0.1622, 0.5556, 0.8155, -0.1084, -0.8315, 0.5449, -0.1802, 0.3827, 0.9061, -0.0747, -0.9239, 0.3753, -0.1913, 0.1951, 0.9619, -0.0381, -0.9808, 0.1913, -0.1951, 0, 0.9808, -0.0381, 0.9808, 0.1913, -0.1913, -0.1951, 0.9619, -0.0747, 0.9239, 0.3753, 0, -0.8315, 0.5556, 0, -0.9239, 0.3827, 0, 0.3827, 0.9239, 0, 0.1951, 0.9808, 0, -0.9808, 0.1951, 0, 0, 1, 0, 0.9808, 0.1951, 0, -0.1951, 0.9808, 0, 0.9239, 0.3827, 0, -0.3827, 0.9239, 0, 0.8315, 0.5556, 0, -0.5556, 0.8315, 0, 0.7071, 0.7071, 0, -0.7071, 0.7071, 0, 0.5556, 0.8315, 0.1084, 0.8315, 0.5449, 0.1802, -0.3827, 0.9061, 0.1622, -0.5556, 0.8155, 0.138, 0.7071, 0.6935, 0.138, -0.7071, 0.6935, 0.1622, 0.5556, 0.8155, 0.1084, -0.8315, 0.5449, 0.1802, 0.3827, 0.9061, 0.0747, -0.9239, 0.3753, 0.1913, 0.1951, 0.9619, 0.0381, -0.9808, 0.1913, 0.1951, 0, 0.9808, 0.0381, 0.9808, 0.1913, 0.1913, -0.1951, 0.9619, 0.0747, 0.9239, 0.3753, 0.3536, 0.3827, 0.8536, 0.3753, 0.1951, 0.9061, 0.0747, -0.9808, 0.1802, 0.3827, 0, 0.9239, 0.0747, 0.9808, 0.1802, 0.3753, -0.1951, 0.9061, 0.1464, 0.9239, 0.3536, 0.3536, -0.3827, 0.8536, 0.2126, 0.8315, 0.5133, 0.3182, -0.5556, 0.7682, 0.2706, 0.7071, 0.6533, 0.2706, -0.7071, 0.6533, 0.3182, 0.5556, 0.7682, 0.2126, -0.8315, 0.5133, 0.1464, -0.9239, 0.3536, 0.5133, -0.3827, 0.7682, 0.4619, -0.5556, 0.6913, 0.3928, 0.7071, 0.5879, 0.3928, -0.7071, 0.5879, 0.4619, 0.5556, 0.6913, 0.3087, -0.8315, 0.4619, 0.5133, 0.3827, 0.7682, 0.2126, -0.9239, 0.3182, 0.5449, 0.1951, 0.8155, 0.1084, -0.9808, 0.1622, 0.5556, 0, 0.8315, 0.1084, 0.9808, 0.1622, 0.5449, -0.1951, 0.8155, 0.2126, 0.9239, 0.3182, 0.3087, 0.8315, 0.4619, 0.2706, -0.9239, 0.2706, 0.138, -0.9808, 0.1379, 0.7071, 0, 0.7071, 0.138, 0.9808, 0.1379, 0.6935, -0.1951, 0.6935, 0.2706, 0.9239, 0.2706, 0.6533, -0.3827, 0.6533, 0.3928, 0.8315, 0.3928, 0.5879, -0.5556, 0.5879, 0.5, 0.7071, 0.5, 0.5, -0.7071, 0.5, 0.5879, 0.5556, 0.5879, 0.3928, -0.8315, 0.3928, 0.6533, 0.3827, 0.6533, 0.6935, 0.1951, 0.6935, 0.4619, 0.8315, 0.3087, 0.5879, 0.7071, 0.3928, 0.5879, -0.7071, 0.3928, 0.6913, 0.5556, 0.4619, 0.4619, -0.8315, 0.3087, 0.7682, 0.3827, 0.5133, 0.3182, -0.9239, 0.2126, 0.8155, 0.1951, 0.5449, 0.1622, -0.9808, 0.1084, 0.8315, 0, 0.5556, 0.1622, 0.9808, 0.1084, 0.8155, -0.1951, 0.5449, 0.3182, 0.9239, 0.2126, 0.7682, -0.3827, 0.5133, 0.6913, -0.5556, 0.4619, 0.9239, 0, 0.3827, 0.1802, 0.9808, 0.0747, 0.1802, -0.9808, 0.0747, 0.9061, -0.1951, 0.3753, 0.3536, 0.9239, 0.1464, 0.8536, -0.3827, 0.3536, 0.5133, 0.8315, 0.2126, 0.7682, -0.5556, 0.3182, 0.6533, 0.7071, 0.2706, 0.6533, -0.7071, 0.2706, 0.7682, 0.5556, 0.3182, 0.5133, -0.8315, 0.2126, 0.8536, 0.3827, 0.3536, 0.3536, -0.9239, 0.1464, 0.9061, 0.1951, 0.3753, 0.6935, -0.7071, 0.1379, 0.8155, 0.5556, 0.1622, 0.5449, -0.8315, 0.1084, 0.9061, 0.3827, 0.1802, 0.3753, -0.9239, 0.0747, 0.9619, 0.1951, 0.1913, 0.1913, -0.9808, 0.0381, 0.9808, 0, 0.1951, 0.1913, 0.9808, 0.0381, 0.9619, -0.1951, 0.1913, 0.3753, 0.9239, 0.0747, 0.9061, -0.3827, 0.1802, 0.5449, 0.8315, 0.1084, 0.8155, -0.5556, 0.1622, 0.6935, 0.7071, 0.1379, 0.1951, -0.9808, 0, 0.9808, -0.1951, 0, 0.3827, 0.9239, 0, 0.9239, -0.3827, 0, 0.5556, 0.8315, 0, 0.8315, -0.5556, 0, 0.7071, 0.7071, 0, 0.7071, -0.7071, 0, 0.8315, 0.5556, 0, 0.5556, -0.8315, 0, 0.9239, 0.3827, 0, 0.3827, -0.9239, 0, 0.9808, 0.1951, 0, 1, 0, 0, 0.1951, 0.9808, 0, 0.5449, -0.8315, -0.1084, 0.9061, 0.3827, -0.1802, 0.3753, -0.9239, -0.0747, 0.9619, 0.1951, -0.1913, 0.1913, -0.9808, -0.0381, 0.9808, 0, -0.1951, 0.1913, 0.9808, -0.0381, 0.9619, -0.1951, -0.1913, 0.3753, 0.9239, -0.0747, 0.9061, -0.3827, -0.1802, 0.5449, 0.8315, -0.1084, 0.8155, -0.5556, -0.1622, 0.6935, 0.7071, -0.1379, 0.6935, -0.7071, -0.1379, 0.8155, 0.5556, -0.1622, 0.3536, 0.9239, -0.1464, 0.8536, -0.3827, -0.3536, 0.5133, 0.8315, -0.2126, 0.7682, -0.5556, -0.3182, 0.6533, 0.7071, -0.2706, 0.6533, -0.7071, -0.2706, 0.7682, 0.5556, -0.3182, 0.5133, -0.8315, -0.2126, 0.8536, 0.3827, -0.3536, 0.3536, -0.9239, -0.1464, 0.9061, 0.1951, -0.3753, 0.1802, -0.9808, -0.0747, 0.9239, 0, -0.3827, 0.1802, 0.9808, -0.0747, 0.9061, -0.1951, -0.3753, 0.7682, 0.3827, -0.5133, 0.3182, -0.9239, -0.2126, 0.8155, 0.1951, -0.5449, 0.1622, -0.9808, -0.1084, 0.8315, 0, -0.5556, 0.1622, 0.9808, -0.1084, 0.8155, -0.1951, -0.5449, 0.3182, 0.9239, -0.2126, 0.7682, -0.3827, -0.5133, 0.4619, 0.8315, -0.3087, 0.6913, -0.5556, -0.4619, 0.5879, 0.7071, -0.3928, 0.5879, -0.7071, -0.3928, 0.6913, 0.5556, -0.4619, 0.4619, -0.8315, -0.3087, 0.6533, -0.3827, -0.6533, 0.3928, 0.8315, -0.3928, 0.5879, -0.5556, -0.5879, 0.5, 0.7071, -0.5, 0.5, -0.7071, -0.5, 0.5879, 0.5556, -0.5879, 0.3928, -0.8315, -0.3928, 0.6533, 0.3827, -0.6533, 0.2706, -0.9239, -0.2706, 0.6935, 0.1951, -0.6935, 0.1379, -0.9808, -0.1379, 0.7071, 0, -0.7071, 0.138, 0.9808, -0.1379, 0.6935, -0.1951, -0.6935, 0.2706, 0.9239, -0.2706, 0.3087, -0.8315, -0.4619, 0.2126, -0.9239, -0.3182, 0.5133, 0.3827, -0.7682, 0.5449, 0.1951, -0.8155, 0.1084, -0.9808, -0.1622, 0.5556, 0, -0.8315, 0.1084, 0.9808, -0.1622, 0.5449, -0.1951, -0.8155, 0.2126, 0.9239, -0.3182, 0.5133, -0.3827, -0.7682, 0.3087, 0.8315, -0.4619, 0.4619, -0.5556, -0.6913, 0.3928, 0.7071, -0.5879, 0.3928, -0.7071, -0.5879, 0.4619, 0.5556, -0.6913, 0.2126, 0.8315, -0.5133, 0.3536, -0.3827, -0.8536, 0.3182, -0.5556, -0.7682, 0.2706, 0.7071, -0.6533, 0.2706, -0.7071, -0.6533, 0.3182, 0.5556, -0.7682, 0.2126, -0.8315, -0.5133, 0.3536, 0.3827, -0.8536, 0.1464, -0.9239, -0.3536, 0.3753, 0.1951, -0.9061, 0.0747, -0.9808, -0.1802, 0.3827, 0, -0.9239, 0.0747, 0.9808, -0.1802, 0.3753, -0.1951, -0.9061, 0.1464, 0.9239, -0.3536, 0.1802, 0.3827, -0.9061, 0.1913, 0.1951, -0.9619, 0.0381, -0.9808, -0.1913, 0.1951, 0, -0.9808, 0.0381, 0.9808, -0.1913, 0.1913, -0.1951, -0.9619, 0.0747, 0.9239, -0.3753, 0.1802, -0.3827, -0.9061, 0.1084, 0.8315, -0.5449, 0.1622, -0.5556, -0.8155, 0.1379, 0.7071, -0.6935, 0.1379, -0.7071, -0.6935, 0.1622, 0.5556, -0.8155, 0.1084, -0.8315, -0.5449, 0.0747, -0.9239, -0.3753, 0, -0.3827, -0.9239, 0, -0.5556, -0.8315, 0, 0.8315, -0.5556, 0, 0.7071, -0.7071, 0, -0.7071, -0.7071, 0, 0.5556, -0.8315, 0, -0.8315, -0.5556, 0, 0.3827, -0.9239, 0, -0.9239, -0.3827, 0, 0.1951, -0.9808, 0, -0.9808, -0.1951, 0, 0, -1, 0, 0.9808, -0.1951, 0, -0.1951, -0.9808, 0, 0.9239, -0.3827, -0.0381, -0.9808, -0.1913, -0.1951, 0, -0.9808, -0.0381, 0.9808, -0.1913, -0.1913, -0.1951, -0.9619, -0.0747, 0.9239, -0.3753, -0.1802, -0.3827, -0.9061, -0.1084, 0.8315, -0.5449, -0.1622, -0.5556, -0.8155, -0.1379, 0.7071, -0.6935, -0.1379, -0.7071, -0.6935, -0.1622, 0.5556, -0.8155, -0.1084, -0.8315, -0.5449, -0.1802, 0.3827, -0.9061, -0.0747, -0.9239, -0.3753, -0.1913, 0.1951, -0.9619, -0.2706, -0.7071, -0.6533, -0.3182, 0.5556, -0.7682, -0.2126, -0.8315, -0.5133, -0.3536, 0.3827, -0.8536, -0.1464, -0.9239, -0.3536, -0.3753, 0.1951, -0.9061, -0.0747, -0.9808, -0.1802, -0.3827, 0, -0.9239, -0.0747, 0.9808, -0.1802, -0.3753, -0.1951, -0.9061, -0.1464, 0.9239, -0.3536, -0.3536, -0.3827, -0.8536, -0.2126, 0.8315, -0.5133, -0.3182, -0.5556, -0.7682, -0.2706, 0.7071, -0.6533, -0.1084, 0.9808, -0.1622, -0.1084, -0.9808, -0.1622, -0.5556, 0, -0.8315, -0.5449, -0.1951, -0.8155, -0.2126, 0.9239, -0.3182, -0.5133, -0.3827, -0.7682, -0.3087, 0.8315, -0.4619, -0.4619, -0.5556, -0.6913, -0.3928, 0.7071, -0.5879, -0.3928, -0.7071, -0.5879, -0.4619, 0.5556, -0.6913, -0.3087, -0.8315, -0.4619, -0.5133, 0.3827, -0.7682, -0.2126, -0.9239, -0.3182, -0.5449, 0.1951, -0.8155, -0.5, 0.7071, -0.5, -0.5879, 0.5556, -0.5879, -0.3928, -0.8315, -0.3928, -0.6533, 0.3827, -0.6533, -0.2706, -0.9239, -0.2706, -0.6935, 0.1951, -0.6935, -0.1379, -0.9808, -0.1379, -0.7071, 0, -0.7071, -0.1379, 0.9808, -0.1379, -0.6935, -0.1951, -0.6935, -0.2706, 0.9239, -0.2706, -0.6533, -0.3827, -0.6533, -0.3928, 0.8315, -0.3928, -0.5879, -0.5556, -0.5879, -0.5, -0.7071, -0.5, -0.8155, -0.1951, -0.5449, -0.3182, 0.9239, -0.2126, -0.7682, -0.3827, -0.5133, -0.4619, 0.8315, -0.3087, -0.6913, -0.5556, -0.4619, -0.5879, 0.7071, -0.3928, -0.5879, -0.7071, -0.3928, -0.6913, 0.5556, -0.4619, -0.4619, -0.8315, -0.3087, -0.7682, 0.3827, -0.5133, -0.3182, -0.9239, -0.2126, -0.8155, 0.1951, -0.5449, -0.1622, -0.9808, -0.1084, -0.8315, 0, -0.5556, -0.1622, 0.9808, -0.1084, -0.5133, -0.8315, -0.2126, -0.8536, 0.3827, -0.3536, -0.3536, -0.9239, -0.1464, -0.9061, 0.1951, -0.3753, -0.1802, -0.9808, -0.0747, -0.9239, 0, -0.3827, -0.1802, 0.9808, -0.0747, -0.9061, -0.1951, -0.3753, -0.3536, 0.9239, -0.1464, -0.8536, -0.3827, -0.3536, -0.5133, 0.8315, -0.2126, -0.7682, -0.5556, -0.3182, -0.6533, 0.7071, -0.2706, -0.6533, -0.7071, -0.2706, -0.7682, 0.5556, -0.3182, -0.3753, 0.9239, -0.0747, -0.9061, -0.3827, -0.1802, -0.5449, 0.8315, -0.1084, -0.8155, -0.5556, -0.1622, -0.6935, 0.7071, -0.1379, -0.6935, -0.7071, -0.1379, -0.8155, 0.5556, -0.1622, -0.5449, -0.8315, -0.1084, -0.9061, 0.3827, -0.1802, -0.3753, -0.9239, -0.0747, -0.9619, 0.1951, -0.1913, -0.1913, -0.9808, -0.0381, -0.9808, 0, -0.1951, -0.1913, 0.9808, -0.0381, -0.9619, -0.1951, -0.1913
2841
+ ];
2842
+ this.indices = [0, 1, 2, 3, 4, 5, 2, 6, 7, 5, 8, 9, 7, 10, 11, 9, 12, 13, 14, 15, 16, 17, 11, 10, 13, 18, 19, 14, 20, 21, 22, 18, 23, 24, 20, 25, 22, 26, 27, 24, 28, 29, 0, 26, 30, 29, 31, 3, 30, 32, 33, 28, 34, 31, 30, 35, 1, 31, 36, 4, 1, 37, 6, 4, 38, 8, 6, 39, 10, 8, 40, 12, 16, 15, 41, 17, 10, 39, 18, 40, 42, 16, 43, 20, 23, 42, 44, 20, 45, 25, 23, 32, 26, 25, 46, 28, 41, 15, 47, 17, 39, 48, 40, 49, 42, 41, 50, 43, 42, 51, 44, 43, 52, 45, 32, 51, 53, 45, 54, 46, 33, 53, 55, 46, 56, 34, 33, 57, 35, 34, 58, 36, 35, 59, 37, 38, 58, 60, 37, 48, 39, 38, 61, 40, 54, 62, 56, 55, 63, 57, 56, 64, 58, 57, 65, 59, 58, 66, 60, 59, 67, 48, 61, 66, 68, 47, 15, 69, 17, 48, 67, 61, 70, 49, 47, 71, 50, 49, 72, 51, 50, 73, 52, 53, 72, 74, 52, 75, 54, 53, 76, 55, 68, 77, 70, 69, 78, 71, 70, 79, 72, 71, 80, 73, 74, 79, 81, 73, 82, 75, 74, 83, 76, 62, 82, 84, 63, 83, 85, 62, 86, 64, 65, 85, 87, 64, 88, 66, 65, 89, 67, 68, 88, 90, 69, 15, 91, 17, 67, 89, 83, 92, 85, 84, 93, 86, 87, 92, 94, 88, 93, 95, 87, 96, 89, 88, 97, 90, 91, 15, 98, 17, 89, 96, 90, 99, 77, 91, 100, 78, 77, 101, 79, 78, 102, 80, 81, 101, 103, 80, 104, 82, 83, 103, 105, 84, 104, 106, 99, 107, 101, 100, 108, 102, 103, 107, 109, 104, 108, 110, 105, 109, 111, 104, 112, 106, 105, 113, 92, 106, 114, 93, 92, 115, 94, 95, 114, 116, 96, 115, 117, 95, 118, 97, 98, 15, 119, 17, 96, 117, 97, 120, 99, 98, 121, 100, 115, 122, 123, 116, 124, 125, 117, 123, 126, 116, 127, 118, 119, 15, 128, 17, 117, 126, 120, 127, 129, 119, 130, 121, 120, 131, 107, 121, 132, 108, 109, 131, 133, 108, 134, 110, 109, 135, 111, 110, 136, 112, 113, 135, 122, 112, 124, 114, 130, 137, 132, 133, 138, 139, 132, 140, 134, 133, 141, 135, 136, 140, 142, 122, 141, 143, 136, 144, 124, 122, 145, 123, 125, 144, 146, 126, 145, 147, 125, 148, 127, 128, 15, 149, 17, 126, 147, 127, 150, 129, 130, 149, 151, 129, 138, 131, 146, 152, 153, 145, 154, 147, 146, 155, 148, 149, 15, 156, 17, 147, 154, 148, 157, 150, 149, 158, 151, 150, 159, 138, 137, 158, 160, 139, 159, 161, 137, 162, 140, 139, 163, 141, 140, 164, 142, 141, 165, 143, 142, 152, 144, 145, 165, 166, 161, 167, 168, 160, 169, 162, 161, 170, 163, 164, 169, 171, 165, 170, 172, 164, 173, 152, 165, 174, 166, 153, 173, 175, 166, 176, 154, 153, 177, 155, 156, 15, 178, 17, 154, 176, 157, 177, 179, 156, 180, 158, 157, 167, 159, 158, 181, 160, 176, 182, 183, 175, 184, 177, 178, 15, 185, 17, 176, 183, 177, 186, 179, 178, 187, 180, 179, 188, 167, 180, 189, 181, 167, 190, 168, 181, 191, 169, 168, 192, 170, 169, 193, 171, 172, 192, 194, 171, 195, 173, 172, 182, 174, 175, 195, 196, 191, 197, 198, 190, 199, 192, 193, 198, 200, 194, 199, 201, 193, 202, 195, 194, 203, 182, 196, 202, 204, 183, 203, 205, 196, 206, 184, 185, 15, 207, 17, 183, 205, 186, 206, 208, 185, 209, 187, 186, 210, 188, 187, 197, 189, 190, 210, 211, 204, 212, 206, 207, 15, 213, 17, 205, 214, 206, 215, 208, 207, 216, 209, 208, 217, 210, 197, 216, 218, 211, 217, 219, 197, 220, 198, 211, 221, 199, 198, 222, 200, 201, 221, 223, 200, 224, 202, 201, 225, 203, 204, 224, 226, 203, 214, 205, 219, 227, 221, 220, 228, 222, 221, 229, 223, 222, 230, 224, 223, 231, 225, 226, 230, 232, 214, 231, 233, 226, 234, 212, 213, 15, 235, 17, 214, 233, 212, 236, 215, 213, 237, 216, 215, 238, 217, 216, 239, 218, 219, 238, 240, 218, 241, 220, 17, 233, 242, 234, 243, 236, 235, 244, 237, 236, 245, 238, 239, 244, 246, 240, 245, 247, 241, 246, 248, 240, 249, 227, 241, 250, 228, 229, 249, 251, 228, 252, 230, 229, 253, 231, 232, 252, 254, 233, 253, 242, 232, 255, 234, 235, 15, 256, 249, 257, 251, 250, 258, 252, 251, 259, 253, 254, 258, 260, 253, 261, 242, 254, 262, 255, 256, 15, 263, 17, 242, 261, 255, 264, 243, 256, 265, 244, 243, 266, 245, 244, 267, 246, 247, 266, 268, 248, 267, 269, 247, 270, 249, 250, 269, 271, 263, 272, 265, 264, 273, 266, 265, 274, 267, 268, 273, 275, 269, 274, 276, 268, 277, 270, 271, 276, 278, 270, 279, 257, 271, 280, 258, 259, 279, 281, 260, 280, 282, 261, 281, 283, 260, 284, 262, 263, 15, 285, 17, 261, 283, 264, 284, 286, 278, 287, 280, 279, 288, 281, 282, 287, 289, 283, 288, 290, 282, 291, 284, 285, 15, 292, 17, 283, 290, 284, 293, 286, 285, 294, 272, 286, 295, 273, 272, 296, 274, 275, 295, 297, 274, 298, 276, 275, 299, 277, 278, 298, 300, 279, 299, 301, 293, 302, 295, 294, 303, 296, 297, 302, 304, 298, 303, 305, 297, 306, 299, 300, 305, 307, 299, 308, 301, 300, 309, 287, 301, 310, 288, 289, 309, 311, 288, 312, 290, 291, 311, 313, 292, 15, 314, 17, 290, 312, 291, 315, 293, 292, 316, 294, 310, 317, 318, 311, 319, 320, 310, 321, 312, 311, 322, 313, 314, 15, 323, 17, 312, 321, 313, 324, 315, 314, 325, 316, 315, 326, 302, 316, 327, 303, 304, 326, 328, 305, 327, 329, 304, 330, 306, 307, 329, 331, 306, 317, 308, 307, 319, 309, 325, 332, 327, 328, 333, 334, 329, 332, 335, 330, 334, 336, 331, 335, 337, 330, 338, 317, 331, 339, 319, 318, 338, 340, 320, 339, 341, 321, 340, 342, 320, 343, 322, 323, 15, 344, 17, 321, 342, 322, 345, 324, 323, 346, 325, 324, 333, 326, 341, 347, 348, 340, 349, 342, 341, 350, 343, 344, 15, 351, 17, 342, 349, 343, 352, 345, 346, 351, 353, 345, 354, 333, 346, 355, 332, 334, 354, 356, 335, 355, 357, 334, 358, 336, 337, 357, 359, 336, 360, 338, 337, 347, 339, 340, 360, 361, 356, 362, 363, 357, 364, 365, 356, 366, 358, 357, 367, 359, 360, 366, 368, 359, 369, 347, 361, 368, 370, 348, 369, 371, 361, 372, 349, 348, 373, 350, 351, 15, 374, 17, 349, 372, 352, 373, 375, 353, 374, 376, 352, 362, 354, 353, 364, 355, 370, 377, 372, 371, 378, 373, 374, 15, 379, 17, 372, 377, 375, 378, 380, 376, 379, 381, 375, 382, 362, 376, 383, 364, 363, 382, 384, 365, 383, 385, 363, 386, 366, 367, 385, 387, 366, 388, 368, 367, 389, 369, 370, 388, 390, 371, 389, 391, 384, 392, 386, 385, 393, 387, 386, 394, 388, 387, 395, 389, 390, 394, 396, 391, 395, 397, 390, 398, 377, 391, 399, 378, 379, 15, 400, 17, 377, 398, 378, 401, 380, 379, 402, 381, 380, 403, 382, 381, 404, 383, 384, 403, 405, 385, 404, 406, 400, 15, 407, 17, 398, 408, 401, 409, 410, 400, 411, 402, 401, 412, 403, 404, 411, 413, 405, 412, 414, 406, 413, 415, 405, 416, 392, 393, 415, 417, 392, 418, 394, 393, 419, 395, 396, 418, 420, 397, 419, 421, 396, 408, 398, 397, 409, 399, 417, 422, 423, 416, 424, 418, 417, 425, 419, 418, 426, 420, 421, 425, 427, 420, 428, 408, 421, 429, 409, 407, 15, 430, 17, 408, 428, 410, 429, 431, 407, 432, 411, 410, 433, 412, 411, 434, 413, 414, 433, 435, 413, 422, 415, 414, 436, 416, 429, 437, 431, 430, 438, 432, 431, 439, 433, 432, 440, 434, 435, 439, 441, 434, 442, 422, 435, 443, 436, 423, 442, 444, 424, 443, 445, 423, 446, 425, 424, 447, 426, 427, 446, 448, 426, 449, 428, 429, 448, 450, 430, 15, 451, 17, 428, 449, 443, 452, 445, 444, 453, 446, 445, 454, 447, 448, 453, 455, 447, 456, 449, 448, 457, 450, 451, 15, 458, 17, 449, 456, 450, 459, 437, 438, 458, 460, 437, 461, 439, 440, 460, 462, 441, 461, 463, 442, 462, 464, 441, 465, 443, 444, 464, 466, 458, 467, 460, 459, 468, 461, 460, 469, 462, 463, 468, 470, 462, 471, 464, 463, 472, 465, 466, 471, 473, 465, 474, 452, 466, 475, 453, 452, 476, 454, 455, 475, 477, 456, 476, 478, 455, 479, 457, 458, 15, 480, 17, 456, 478, 457, 481, 459, 475, 3, 5, 474, 7, 476, 477, 5, 9, 476, 11, 478, 479, 9, 13, 480, 15, 14, 17, 478, 11, 479, 19, 481, 467, 14, 21, 481, 22, 468, 469, 21, 24, 468, 27, 470, 471, 24, 29, 470, 0, 472, 473, 29, 3, 472, 2, 474, 0, 30, 1, 3, 31, 4, 2, 1, 6, 5, 4, 8, 7, 6, 10, 9, 8, 12, 13, 12, 18, 14, 16, 20, 22, 19, 18, 24, 21, 20, 22, 23, 26, 24, 25, 28, 0, 27, 26, 29, 28, 31, 30, 26, 32, 28, 46, 34, 30, 33, 35, 31, 34, 36, 1, 35, 37, 4, 36, 38, 6, 37, 39, 8, 38, 40, 18, 12, 40, 16, 41, 43, 23, 18, 42, 20, 43, 45, 23, 44, 32, 25, 45, 46, 40, 61, 49, 41, 47, 50, 42, 49, 51, 43, 50, 52, 32, 44, 51, 45, 52, 54, 33, 32, 53, 46, 54, 56, 33, 55, 57, 34, 56, 58, 35, 57, 59, 38, 36, 58, 37, 59, 48, 38, 60, 61, 54, 75, 62, 55, 76, 63, 56, 62, 64, 57, 63, 65, 58, 64, 66, 59, 65, 67, 61, 60, 66, 61, 68, 70, 47, 69, 71, 49, 70, 72, 50, 71, 73, 53, 51, 72, 52, 73, 75, 53, 74, 76, 68, 90, 77, 69, 91, 78, 70, 77, 79, 71, 78, 80, 74, 72, 79, 73, 80, 82, 74, 81, 83, 62, 75, 82, 63, 76, 83, 62, 84, 86, 65, 63, 85, 64, 86, 88, 65, 87, 89, 68, 66, 88, 83, 105, 92, 84, 106, 93, 87, 85, 92, 88, 86, 93, 87, 94, 96, 88, 95, 97, 90, 97, 99, 91, 98, 100, 77, 99, 101, 78, 100, 102, 81, 79, 101, 80, 102, 104, 83, 81, 103, 84, 82, 104, 99, 120, 107, 100, 121, 108, 103, 101, 107, 104, 102, 108, 105, 103, 109, 104, 110, 112, 105, 111, 113, 106, 112, 114, 92, 113, 115, 95, 93, 114, 96, 94, 115, 95, 116, 118, 97, 118, 120, 98, 119, 121, 115, 113, 122, 116, 114, 124, 117, 115, 123, 116, 125, 127, 120, 118, 127, 119, 128, 130, 120, 129, 131, 121, 130, 132, 109, 107, 131, 108, 132, 134, 109, 133, 135, 110, 134, 136, 113, 111, 135, 112, 136, 124, 130, 151, 137, 133, 131, 138, 132, 137, 140, 133, 139, 141, 136, 134, 140, 122, 135, 141, 136, 142, 144, 122, 143, 145, 125, 124, 144, 126, 123, 145, 125, 146, 148, 127, 148, 150, 130, 128, 149, 129, 150, 138, 146, 144, 152, 145, 166, 154, 146, 153, 155, 148, 155, 157, 149, 156, 158, 150, 157, 159, 137, 151, 158, 139, 138, 159, 137, 160, 162, 139, 161, 163, 140, 162, 164, 141, 163, 165, 142, 164, 152, 145, 143, 165, 161, 159, 167, 160, 181, 169, 161, 168, 170, 164, 162, 169, 165, 163, 170, 164, 171, 173, 165, 172, 174, 153, 152, 173, 166, 174, 176, 153, 175, 177, 157, 155, 177, 156, 178, 180, 157, 179, 167, 158, 180, 181, 176, 174, 182, 175, 196, 184, 177, 184, 186, 178, 185, 187, 179, 186, 188, 180, 187, 189, 167, 188, 190, 181, 189, 191, 168, 190, 192, 169, 191, 193, 172, 170, 192, 171, 193, 195, 172, 194, 182, 175, 173, 195, 191, 189, 197, 190, 211, 199, 193, 191, 198, 194, 192, 199, 193, 200, 202, 194, 201, 203, 196, 195, 202, 183, 182, 203, 196, 204, 206, 186, 184, 206, 185, 207, 209, 186, 208, 210, 187, 209, 197, 190, 188, 210, 204, 226, 212, 206, 212, 215, 207, 213, 216, 208, 215, 217, 197, 209, 216, 211, 210, 217, 197, 218, 220, 211, 219, 221, 198, 220, 222, 201, 199, 221, 200, 222, 224, 201, 223, 225, 204, 202, 224, 203, 225, 214, 219, 240, 227, 220, 241, 228, 221, 227, 229, 222, 228, 230, 223, 229, 231, 226, 224, 230, 214, 225, 231, 226, 232, 234, 212, 234, 236, 213, 235, 237, 215, 236, 238, 216, 237, 239, 219, 217, 238, 218, 239, 241, 234, 255, 243, 235, 256, 244, 236, 243, 245, 239, 237, 244, 240, 238, 245, 241, 239, 246, 240, 247, 249, 241, 248, 250, 229, 227, 249, 228, 250, 252, 229, 251, 253, 232, 230, 252, 233, 231, 253, 232, 254, 255, 249, 270, 257, 250, 271, 258, 251, 257, 259, 254, 252, 258, 253, 259, 261, 254, 260, 262, 255, 262, 264, 256, 263, 265, 243, 264, 266, 244, 265, 267, 247, 245, 266, 248, 246, 267, 247, 268, 270, 250, 248, 269, 263, 285, 272, 264, 286, 273, 265, 272, 274, 268, 266, 273, 269, 267, 274, 268, 275, 277, 271, 269, 276, 270, 277, 279, 271, 278, 280, 259, 257, 279, 260, 258, 280, 261, 259, 281, 260, 282, 284, 264, 262, 284, 278, 300, 287, 279, 301, 288, 282, 280, 287, 283, 281, 288, 282, 289, 291, 284, 291, 293, 285, 292, 294, 286, 293, 295, 272, 294, 296, 275, 273, 295, 274, 296, 298, 275, 297, 299, 278, 276, 298, 279, 277, 299, 293, 315, 302, 294, 316, 303, 297, 295, 302, 298, 296, 303, 297, 304, 306, 300, 298, 305, 299, 306, 308, 300, 307, 309, 301, 308, 310, 289, 287, 309, 288, 310, 312, 291, 289, 311, 291, 313, 315, 292, 314, 316, 310, 308, 317, 311, 309, 319, 310, 318, 321, 311, 320, 322, 313, 322, 324, 314, 323, 325, 315, 324, 326, 316, 325, 327, 304, 302, 326, 305, 303, 327, 304, 328, 330, 307, 305, 329, 306, 330, 317, 307, 331, 319, 325, 346, 332, 328, 326, 333, 329, 327, 332, 330, 328, 334, 331, 329, 335, 330, 336, 338, 331, 337, 339, 318, 317, 338, 320, 319, 339, 321, 318, 340, 320, 341, 343, 322, 343, 345, 323, 344, 346, 324, 345, 333, 341, 339, 347, 340, 361, 349, 341, 348, 350, 343, 350, 352, 346, 344, 351, 345, 352, 354, 346, 353, 355, 334, 333, 354, 335, 332, 355, 334, 356, 358, 337, 335, 357, 336, 358, 360, 337, 359, 347, 340, 338, 360, 356, 354, 362, 357, 355, 364, 356, 363, 366, 357, 365, 367, 360, 358, 366, 359, 367, 369, 361, 360, 368, 348, 347, 369, 361, 370, 372, 348, 371, 373, 352, 350, 373, 353, 351, 374, 352, 375, 362, 353, 376, 364, 370, 390, 377, 371, 391, 378, 375, 373, 378, 376, 374, 379, 375, 380, 382, 376, 381, 383, 363, 362, 382, 365, 364, 383, 363, 384, 386, 367, 365, 385, 366, 386, 388, 367, 387, 389, 370, 368, 388, 371, 369, 389, 384, 405, 392, 385, 406, 393, 386, 392, 394, 387, 393, 395, 390, 388, 394, 391, 389, 395, 390, 396, 398, 391, 397, 399, 378, 399, 401, 379, 400, 402, 380, 401, 403, 381, 402, 404, 384, 382, 403, 385, 383, 404, 401, 399, 409, 400, 407, 411, 401, 410, 412, 404, 402, 411, 405, 403, 412, 406, 404, 413, 405, 414, 416, 393, 406, 415, 392, 416, 418, 393, 417, 419, 396, 394, 418, 397, 395, 419, 396, 420, 408, 397, 421, 409, 417, 415, 422, 416, 436, 424, 417, 423, 425, 418, 424, 426, 421, 419, 425, 420, 426, 428, 421, 427, 429, 410, 409, 429, 407, 430, 432, 410, 431, 433, 411, 432, 434, 414, 412, 433, 413, 434, 422, 414, 435, 436, 429, 450, 437, 430, 451, 438, 431, 437, 439, 432, 438, 440, 435, 433, 439, 434, 440, 442, 435, 441, 443, 423, 422, 442, 424, 436, 443, 423, 444, 446, 424, 445, 447, 427, 425, 446, 426, 447, 449, 429, 427, 448, 443, 465, 452, 444, 466, 453, 445, 452, 454, 448, 446, 453, 447, 454, 456, 448, 455, 457, 450, 457, 459, 438, 451, 458, 437, 459, 461, 440, 438, 460, 441, 439, 461, 442, 440, 462, 441, 463, 465, 444, 442, 464, 458, 480, 467, 459, 481, 468, 460, 467, 469, 463, 461, 468, 462, 469, 471, 463, 470, 472, 466, 464, 471, 465, 472, 474, 466, 473, 475, 452, 474, 476, 455, 453, 475, 456, 454, 476, 455, 477, 479, 457, 479, 481, 475, 473, 3, 474, 2, 7, 477, 475, 5, 476, 7, 11, 479, 477, 9, 479, 13, 19, 467, 480, 14, 481, 19, 22, 469, 467, 21, 468, 22, 27, 471, 469, 24, 470, 27, 0, 473, 471, 29, 472, 0, 2
2843
+ ];
2844
+ this.normals = [-0.7101, -0.704, 0, -0.549, -0.8286, 0.1092, -0.5598, -0.8286, 0, -0.8333, 0.5528, 0, -0.907, 0.3805, 0.1804, -0.9247, 0.3805, 0, -0.3804, -0.9217, 0.0757, -0.3879, -0.9217, 0, -0.9622, 0.1939, 0.1914, -0.981, 0.1939, 0, -0.1971, -0.9796, 0.0392, -0.201, -0.9796, 0, -0.9808, 0, 0.1951, -1, 0, 0, -0.201, 0.9796, 0, 0, 1, 0, -0.1971, 0.9796, 0.0392, 0, -1, 0, -0.9622, -0.1939, 0.1914, -0.981, -0.1939, 0, -0.3804, 0.9217, 0.0757, -0.3879, 0.9217, 0, -0.9247, -0.3805, 0, -0.907, -0.3805, 0.1804, -0.5598, 0.8286, 0, -0.549, 0.8286, 0.1092, -0.8173, -0.5528, 0.1626, -0.8333, -0.5528, 0, -0.6965, 0.704, 0.1385, -0.7101, 0.704, 0, -0.6965, -0.704, 0.1385, -0.8173, 0.5528, 0.1626, -0.7699, -0.5528, 0.3189, -0.6561, -0.704, 0.2717, -0.7699, 0.5528, 0.3189, -0.5171, -0.8286, 0.2142, -0.8544, 0.3805, 0.3539, -0.3583, -0.9217, 0.1484, -0.9063, 0.1939, 0.3754, -0.1856, -0.9796, 0.0769, -0.9239, 0, 0.3827, -0.1856, 0.9796, 0.0769, -0.9063, -0.1939, 0.3754, -0.3583, 0.9217, 0.1484, -0.8544, -0.3805, 0.3539, -0.5171, 0.8286, 0.2142, -0.6561, 0.704, 0.2717, -0.1671, 0.9796, 0.1116, -0.1671, -0.9796, 0.1116, -0.8157, -0.1939, 0.545, -0.3225, 0.9217, 0.2155, -0.7689, -0.3805, 0.5137, -0.4654, 0.8286, 0.311, -0.6929, -0.5528, 0.463, -0.5904, 0.704, 0.3945, -0.5904, -0.704, 0.3945, -0.6929, 0.5528, 0.463, -0.4654, -0.8286, 0.311, -0.7689, 0.3805, 0.5137, -0.3225, -0.9217, 0.2155, -0.8157, 0.1939, 0.545, -0.8314, 0, 0.5556, -0.5893, 0.5528, 0.5893, -0.3958, -0.8286, 0.3958, -0.6539, 0.3805, 0.6539, -0.2743, -0.9217, 0.2743, -0.6937, 0.1939, 0.6937, -0.1421, -0.9796, 0.1421, -0.7071, 0, 0.7071, -0.1421, 0.9796, 0.1421, -0.6937, -0.1939, 0.6937, -0.2743, 0.9217, 0.2743, -0.6539, -0.3805, 0.6539, -0.3958, 0.8286, 0.3958, -0.5893, -0.5528, 0.5893, -0.5021, 0.704, 0.5021, -0.5021, -0.704, 0.5021, -0.545, -0.1939, 0.8157, -0.2155, 0.9217, 0.3225, -0.5137, -0.3805, 0.7689, -0.311, 0.8286, 0.4654, -0.463, -0.5528, 0.6929, -0.3945, 0.704, 0.5904, -0.3945, -0.704, 0.5904, -0.463, 0.5528, 0.6929, -0.311, -0.8286, 0.4654, -0.5137, 0.3805, 0.7689, -0.2155, -0.9217, 0.3225, -0.545, 0.1939, 0.8157, -0.1116, -0.9796, 0.1671, -0.5556, 0, 0.8314, -0.1116, 0.9796, 0.1671, -0.2142, -0.8286, 0.5171, -0.3539, 0.3805, 0.8544, -0.1484, -0.9217, 0.3583, -0.3754, 0.1939, 0.9063, -0.0769, -0.9796, 0.1856, -0.3827, 0, 0.9239, -0.0769, 0.9796, 0.1856, -0.3754, -0.1939, 0.9063, -0.1484, 0.9217, 0.3583, -0.3539, -0.3805, 0.8544, -0.2142, 0.8286, 0.5171, -0.3189, -0.5528, 0.7699, -0.2717, 0.704, 0.6561, -0.2717, -0.704, 0.6561, -0.3189, 0.5528, 0.7699, -0.1804, -0.3805, 0.907, -0.1092, 0.8286, 0.549, -0.1626, -0.5528, 0.8173, -0.1385, 0.704, 0.6965, -0.1385, -0.704, 0.6965, -0.1626, 0.5528, 0.8173, -0.1092, -0.8286, 0.549, -0.1804, 0.3805, 0.907, -0.0757, -0.9217, 0.3804, -0.1914, 0.1939, 0.9622, -0.0392, -0.9796, 0.1971, -0.1951, 0, 0.9808, -0.0392, 0.9796, 0.1971, -0.1914, -0.1939, 0.9622, -0.0757, 0.9217, 0.3804, 0, -0.8286, 0.5598, 0, -0.9217, 0.3879, 0, 0.3805, 0.9247, 0, 0.1939, 0.981, 0, -0.9796, 0.201, 0, 0, 1, 0, 0.9796, 0.201, 0, -0.1939, 0.981, 0, 0.9217, 0.3879, 0, -0.3805, 0.9247, 0, 0.8286, 0.5598, 0, -0.5528, 0.8333, 0, 0.704, 0.7101, 0, -0.704, 0.7101, 0, 0.5528, 0.8333, 0.1092, 0.8286, 0.549, 0.1804, -0.3805, 0.907, 0.1626, -0.5528, 0.8173, 0.1385, 0.704, 0.6965, 0.1385, -0.704, 0.6965, 0.1626, 0.5528, 0.8173, 0.1092, -0.8286, 0.549, 0.1804, 0.3805, 0.907, 0.0757, -0.9217, 0.3804, 0.1914, 0.1939, 0.9622, 0.0392, -0.9796, 0.1971, 0.1951, 0, 0.9808, 0.0392, 0.9796, 0.1971, 0.1914, -0.1939, 0.9622, 0.0757, 0.9217, 0.3804, 0.3539, 0.3805, 0.8544, 0.3754, 0.1939, 0.9063, 0.0769, -0.9796, 0.1856, 0.3827, 0, 0.9239, 0.0769, 0.9796, 0.1856, 0.3754, -0.1939, 0.9063, 0.1484, 0.9217, 0.3583, 0.3539, -0.3805, 0.8544, 0.2142, 0.8286, 0.5171, 0.3189, -0.5528, 0.7699, 0.2717, 0.704, 0.6561, 0.2717, -0.704, 0.6561, 0.3189, 0.5528, 0.7699, 0.2142, -0.8286, 0.5171, 0.1484, -0.9217, 0.3583, 0.5137, -0.3805, 0.7689, 0.463, -0.5528, 0.6929, 0.3945, 0.704, 0.5904, 0.3945, -0.704, 0.5904, 0.463, 0.5528, 0.6929, 0.311, -0.8286, 0.4654, 0.5137, 0.3805, 0.7689, 0.2155, -0.9217, 0.3225, 0.545, 0.1939, 0.8157, 0.1116, -0.9796, 0.1671, 0.5556, 0, 0.8314, 0.1116, 0.9796, 0.1671, 0.545, -0.1939, 0.8157, 0.2155, 0.9217, 0.3225, 0.311, 0.8286, 0.4654, 0.2743, -0.9217, 0.2743, 0.1421, -0.9796, 0.1421, 0.7071, 0, 0.7071, 0.1421, 0.9796, 0.1421, 0.6937, -0.1939, 0.6937, 0.2743, 0.9217, 0.2743, 0.6539, -0.3805, 0.6539, 0.3958, 0.8286, 0.3958, 0.5893, -0.5528, 0.5893, 0.5021, 0.704, 0.5021, 0.5021, -0.704, 0.5021, 0.5893, 0.5528, 0.5893, 0.3958, -0.8286, 0.3958, 0.6539, 0.3805, 0.6539, 0.6937, 0.1939, 0.6937, 0.4654, 0.8286, 0.311, 0.5904, 0.704, 0.3945, 0.5904, -0.704, 0.3945, 0.6929, 0.5528, 0.463, 0.4654, -0.8286, 0.311, 0.7689, 0.3805, 0.5137, 0.3225, -0.9217, 0.2155, 0.8157, 0.1939, 0.545, 0.1671, -0.9796, 0.1116, 0.8314, 0, 0.5556, 0.1671, 0.9796, 0.1116, 0.8157, -0.1939, 0.545, 0.3225, 0.9217, 0.2155, 0.7689, -0.3805, 0.5137, 0.6929, -0.5528, 0.463, 0.9239, 0, 0.3827, 0.1856, 0.9796, 0.0769, 0.1856, -0.9796, 0.0769, 0.9063, -0.1939, 0.3754, 0.3583, 0.9217, 0.1484, 0.8544, -0.3805, 0.3539, 0.5171, 0.8286, 0.2142, 0.7699, -0.5528, 0.3189, 0.6561, 0.704, 0.2717, 0.6561, -0.704, 0.2717, 0.7699, 0.5528, 0.3189, 0.5171, -0.8286, 0.2142, 0.8544, 0.3805, 0.3539, 0.3583, -0.9217, 0.1484, 0.9063, 0.1939, 0.3754, 0.6965, -0.704, 0.1385, 0.8173, 0.5528, 0.1626, 0.549, -0.8286, 0.1092, 0.907, 0.3805, 0.1804, 0.3804, -0.9217, 0.0757, 0.9622, 0.1939, 0.1914, 0.1971, -0.9796, 0.0392, 0.9808, 0, 0.1951, 0.1971, 0.9796, 0.0392, 0.9622, -0.1939, 0.1914, 0.3804, 0.9217, 0.0757, 0.907, -0.3805, 0.1804, 0.549, 0.8286, 0.1092, 0.8173, -0.5528, 0.1626, 0.6965, 0.704, 0.1385, 0.201, -0.9796, 0, 0.981, -0.1939, 0, 0.3879, 0.9217, 0, 0.9247, -0.3805, 0, 0.5598, 0.8286, 0, 0.8333, -0.5528, 0, 0.7101, 0.704, 0, 0.7101, -0.704, 0, 0.8333, 0.5528, 0, 0.5598, -0.8286, 0, 0.9247, 0.3805, 0, 0.3879, -0.9217, 0, 0.981, 0.1939, 0, 1, 0, 0, 0.201, 0.9796, 0, 0.549, -0.8286, -0.1092, 0.907, 0.3805, -0.1804, 0.3804, -0.9217, -0.0757, 0.9622, 0.1939, -0.1914, 0.1971, -0.9796, -0.0392, 0.9808, 0, -0.1951, 0.1971, 0.9796, -0.0392, 0.9622, -0.1939, -0.1914, 0.3804, 0.9217, -0.0757, 0.907, -0.3805, -0.1804, 0.549, 0.8286, -0.1092, 0.8173, -0.5528, -0.1626, 0.6965, 0.704, -0.1385, 0.6965, -0.704, -0.1385, 0.8173, 0.5528, -0.1626, 0.3583, 0.9217, -0.1484, 0.8544, -0.3805, -0.3539, 0.5171, 0.8286, -0.2142, 0.7699, -0.5528, -0.3189, 0.6561, 0.704, -0.2717, 0.6561, -0.704, -0.2717, 0.7699, 0.5528, -0.3189, 0.5171, -0.8286, -0.2142, 0.8544, 0.3805, -0.3539, 0.3583, -0.9217, -0.1484, 0.9063, 0.1939, -0.3754, 0.1856, -0.9796, -0.0769, 0.9239, 0, -0.3827, 0.1856, 0.9796, -0.0769, 0.9063, -0.1939, -0.3754, 0.7689, 0.3805, -0.5137, 0.3225, -0.9217, -0.2155, 0.8157, 0.1939, -0.545, 0.1671, -0.9796, -0.1116, 0.8314, 0, -0.5556, 0.1671, 0.9796, -0.1116, 0.8157, -0.1939, -0.545, 0.3225, 0.9217, -0.2155, 0.7689, -0.3805, -0.5137, 0.4654, 0.8286, -0.311, 0.6929, -0.5528, -0.463, 0.5904, 0.704, -0.3945, 0.5904, -0.704, -0.3945, 0.6929, 0.5528, -0.463, 0.4654, -0.8286, -0.311, 0.6539, -0.3805, -0.6539, 0.3958, 0.8286, -0.3958, 0.5893, -0.5528, -0.5893, 0.5021, 0.704, -0.5021, 0.5021, -0.704, -0.5021, 0.5893, 0.5528, -0.5893, 0.3958, -0.8286, -0.3958, 0.6539, 0.3805, -0.6539, 0.2743, -0.9217, -0.2743, 0.6937, 0.1939, -0.6937, 0.1421, -0.9796, -0.1421, 0.7071, 0, -0.7071, 0.1421, 0.9796, -0.1421, 0.6937, -0.1939, -0.6937, 0.2743, 0.9217, -0.2743, 0.311, -0.8286, -0.4654, 0.2155, -0.9217, -0.3225, 0.5137, 0.3805, -0.7689, 0.545, 0.1939, -0.8157, 0.1116, -0.9796, -0.1671, 0.5556, 0, -0.8314, 0.1116, 0.9796, -0.1671, 0.545, -0.1939, -0.8157, 0.2155, 0.9217, -0.3225, 0.5137, -0.3805, -0.7689, 0.311, 0.8286, -0.4654, 0.463, -0.5528, -0.6929, 0.3945, 0.704, -0.5904, 0.3945, -0.704, -0.5904, 0.463, 0.5528, -0.6929, 0.2142, 0.8286, -0.5171, 0.3539, -0.3805, -0.8544, 0.3189, -0.5528, -0.7699, 0.2717, 0.704, -0.6561, 0.2717, -0.704, -0.6561, 0.3189, 0.5528, -0.7699, 0.2142, -0.8286, -0.5171, 0.3539, 0.3805, -0.8544, 0.1484, -0.9217, -0.3583, 0.3754, 0.1939, -0.9063, 0.0769, -0.9796, -0.1856, 0.3827, 0, -0.9239, 0.0769, 0.9796, -0.1856, 0.3754, -0.1939, -0.9063, 0.1484, 0.9217, -0.3583, 0.1804, 0.3805, -0.907, 0.1914, 0.1939, -0.9622, 0.0392, -0.9796, -0.1971, 0.1951, 0, -0.9808, 0.0392, 0.9796, -0.1971, 0.1914, -0.1939, -0.9622, 0.0757, 0.9217, -0.3804, 0.1804, -0.3805, -0.907, 0.1092, 0.8286, -0.549, 0.1626, -0.5528, -0.8173, 0.1385, 0.704, -0.6965, 0.1385, -0.704, -0.6965, 0.1626, 0.5528, -0.8173, 0.1092, -0.8286, -0.549, 0.0757, -0.9217, -0.3804, 0, -0.3805, -0.9247, 0, -0.5528, -0.8333, 0, 0.8286, -0.5598, 0, 0.704, -0.7101, 0, -0.704, -0.7101, 0, 0.5528, -0.8333, 0, -0.8286, -0.5598, 0, 0.3805, -0.9247, 0, -0.9217, -0.3879, 0, 0.1939, -0.981, 0, -0.9796, -0.201, 0, 0, -1, 0, 0.9796, -0.201, 0, -0.1939, -0.981, 0, 0.9217, -0.3879, -0.0392, -0.9796, -0.1971, -0.1951, 0, -0.9808, -0.0392, 0.9796, -0.1971, -0.1914, -0.1939, -0.9622, -0.0757, 0.9217, -0.3804, -0.1804, -0.3805, -0.907, -0.1092, 0.8286, -0.549, -0.1626, -0.5528, -0.8173, -0.1385, 0.704, -0.6965, -0.1385, -0.704, -0.6965, -0.1626, 0.5528, -0.8173, -0.1092, -0.8286, -0.549, -0.1804, 0.3805, -0.907, -0.0757, -0.9217, -0.3804, -0.1914, 0.1939, -0.9622, -0.2717, -0.704, -0.6561, -0.3189, 0.5528, -0.7699, -0.2142, -0.8286, -0.5171, -0.3539, 0.3805, -0.8544, -0.1484, -0.9217, -0.3583, -0.3754, 0.1939, -0.9063, -0.0769, -0.9796, -0.1856, -0.3827, 0, -0.9239, -0.0769, 0.9796, -0.1856, -0.3754, -0.1939, -0.9063, -0.1484, 0.9217, -0.3583, -0.3539, -0.3805, -0.8544, -0.2142, 0.8286, -0.5171, -0.3189, -0.5528, -0.7699, -0.2717, 0.704, -0.6561, -0.1116, 0.9796, -0.1671, -0.1116, -0.9796, -0.1671, -0.5556, 0, -0.8314, -0.545, -0.1939, -0.8157, -0.2155, 0.9217, -0.3225, -0.5137, -0.3805, -0.7689, -0.311, 0.8286, -0.4654, -0.463, -0.5528, -0.6929, -0.3945, 0.704, -0.5904, -0.3945, -0.704, -0.5904, -0.463, 0.5528, -0.6929, -0.311, -0.8286, -0.4654, -0.5137, 0.3805, -0.7689, -0.2155, -0.9217, -0.3225, -0.545, 0.1939, -0.8157, -0.5021, 0.704, -0.5021, -0.5893, 0.5528, -0.5893, -0.3958, -0.8286, -0.3958, -0.6539, 0.3805, -0.6539, -0.2743, -0.9217, -0.2743, -0.6937, 0.1939, -0.6937, -0.1421, -0.9796, -0.1421, -0.7071, 0, -0.7071, -0.1421, 0.9796, -0.1421, -0.6937, -0.1939, -0.6937, -0.2743, 0.9217, -0.2743, -0.6539, -0.3805, -0.6539, -0.3958, 0.8286, -0.3958, -0.5893, -0.5528, -0.5893, -0.5021, -0.704, -0.5021, -0.8157, -0.1939, -0.545, -0.3225, 0.9217, -0.2155, -0.7689, -0.3805, -0.5137, -0.4654, 0.8286, -0.311, -0.6929, -0.5528, -0.463, -0.5904, 0.704, -0.3945, -0.5904, -0.704, -0.3945, -0.6929, 0.5528, -0.463, -0.4654, -0.8286, -0.311, -0.7689, 0.3805, -0.5137, -0.3225, -0.9217, -0.2155, -0.8157, 0.1939, -0.545, -0.1671, -0.9796, -0.1116, -0.8314, 0, -0.5556, -0.1671, 0.9796, -0.1116, -0.5171, -0.8286, -0.2142, -0.8544, 0.3805, -0.3539, -0.3583, -0.9217, -0.1484, -0.9063, 0.1939, -0.3754, -0.1856, -0.9796, -0.0769, -0.9239, 0, -0.3827, -0.1856, 0.9796, -0.0769, -0.9063, -0.1939, -0.3754, -0.3583, 0.9217, -0.1484, -0.8544, -0.3805, -0.3539, -0.5171, 0.8286, -0.2142, -0.7699, -0.5528, -0.3189, -0.6561, 0.704, -0.2717, -0.6561, -0.704, -0.2717, -0.7699, 0.5528, -0.3189, -0.3804, 0.9217, -0.0757, -0.907, -0.3805, -0.1804, -0.549, 0.8286, -0.1092, -0.8173, -0.5528, -0.1626, -0.6965, 0.704, -0.1385, -0.6965, -0.704, -0.1385, -0.8173, 0.5528, -0.1626, -0.549, -0.8286, -0.1092, -0.907, 0.3805, -0.1804, -0.3804, -0.9217, -0.0757, -0.9622, 0.1939, -0.1914, -0.1971, -0.9796, -0.0392, -0.9808, 0, -0.1951, -0.1971, 0.9796, -0.0392, -0.9622, -0.1939, -0.1914
2845
+ ];
2846
+ this.subMeshes = [
2847
+ new SubMesh(0, 2880)
2848
+ ];
2849
+ }
2850
+ }
2851
+
2852
+ class Hemisphere extends BasicMesh {
2853
+ constructor() {
2854
+ super();
2855
+ this.vertices = [-0.5556, -0.8315, 0, -0.3753, -0.9239, 0.0747, -0.3827, -0.9239, 0, -0.9239, 0.3827, 0, -0.9619, 0.1951, 0.1913, -0.9808, 0.1951, 0, -0.1913, -0.9808, 0.0381, -0.1951, -0.9808, 0, -0.9808, 0, 0.1951, -1, 0, 0, -0.1951, 0.9808, 0, 0, 1, 0, -0.1913, 0.9808, 0.0381, 0, -1, 0, -0.9619, -0.1951, 0.1913, -0.9808, -0.1951, 0, -0.3753, 0.9239, 0.0747, -0.3827, 0.9239, 0, -0.9239, -0.3827, 0, -0.9061, -0.3827, 0.1802, -0.5556, 0.8315, 0, -0.5449, 0.8315, 0.1084, -0.8155, -0.5556, 0.1622, -0.8315, -0.5556, 0, -0.6935, 0.7071, 0.1379, -0.7071, 0.7071, 0, -0.7071, -0.7071, 0, -0.6935, -0.7071, 0.1379, -0.8155, 0.5556, 0.1622, -0.8315, 0.5556, 0, -0.5449, -0.8315, 0.1084, -0.9061, 0.3827, 0.1802, -0.5133, -0.8315, 0.2126, -0.8536, 0.3827, 0.3536, -0.3536, -0.9239, 0.1464, -0.9061, 0.1951, 0.3753, -0.1802, -0.9808, 0.0747, -0.9239, 0, 0.3827, -0.1802, 0.9808, 0.0747, -0.9061, -0.1951, 0.3753, -0.3536, 0.9239, 0.1464, -0.8536, -0.3827, 0.3536, -0.5133, 0.8315, 0.2126, -0.7682, -0.5556, 0.3182, -0.6533, 0.7071, 0.2706, -0.6533, -0.7071, 0.2706, -0.7682, 0.5556, 0.3182, -0.3182, 0.9239, 0.2126, -0.7682, -0.3827, 0.5133, -0.4619, 0.8315, 0.3087, -0.6913, -0.5556, 0.4619, -0.5879, 0.7071, 0.3928, -0.5879, -0.7071, 0.3928, -0.6913, 0.5556, 0.4619, -0.4619, -0.8315, 0.3087, -0.7682, 0.3827, 0.5133, -0.3182, -0.9239, 0.2126, -0.8155, 0.1951, 0.5449, -0.1622, -0.9808, 0.1084, -0.8315, 0, 0.5556, -0.1622, 0.9808, 0.1084, -0.8155, -0.1951, 0.5449, -0.6533, 0.3827, 0.6533, -0.2706, -0.9239, 0.2706, -0.6935, 0.1951, 0.6935, -0.1379, -0.9808, 0.1379, -0.7071, 0, 0.7071, -0.1379, 0.9808, 0.1379, -0.6935, -0.1951, 0.6935, -0.2706, 0.9239, 0.2706, -0.6533, -0.3827, 0.6533, -0.3928, 0.8315, 0.3928, -0.5879, -0.5556, 0.5879, -0.5, 0.7071, 0.5, -0.5, -0.7071, 0.5, -0.5879, 0.5556, 0.5879, -0.3928, -0.8315, 0.3928, -0.5133, -0.3827, 0.7682, -0.3087, 0.8315, 0.4619, -0.4619, -0.5556, 0.6913, -0.3928, 0.7071, 0.5879, -0.3928, -0.7071, 0.5879, -0.4619, 0.5556, 0.6913, -0.3087, -0.8315, 0.4619, -0.5133, 0.3827, 0.7682, -0.2126, -0.9239, 0.3182, -0.5449, 0.1951, 0.8155, -0.1084, -0.9808, 0.1622, -0.5556, 0, 0.8315, -0.1084, 0.9808, 0.1622, -0.5449, -0.1951, 0.8155, -0.2126, 0.9239, 0.3182, -0.2126, -0.8315, 0.5133, -0.1464, -0.9239, 0.3536, -0.3536, 0.3827, 0.8536, -0.3753, 0.1951, 0.9061, -0.0747, -0.9808, 0.1802, -0.3827, 0, 0.9239, -0.0747, 0.9808, 0.1802, -0.3753, -0.1951, 0.9061, -0.1464, 0.9239, 0.3536, -0.3536, -0.3827, 0.8536, -0.2126, 0.8315, 0.5133, -0.3182, -0.5556, 0.7682, -0.2706, 0.7071, 0.6533, -0.2706, -0.7071, 0.6533, -0.3182, 0.5556, 0.7682, -0.1802, -0.3827, 0.9061, -0.1622, -0.5556, 0.8155, -0.1084, 0.8315, 0.5449, -0.1379, 0.7071, 0.6935, -0.1379, -0.7071, 0.6935, -0.1622, 0.5556, 0.8155, -0.1084, -0.8315, 0.5449, -0.1802, 0.3827, 0.9061, -0.0747, -0.9239, 0.3753, -0.1913, 0.1951, 0.9619, -0.0381, -0.9808, 0.1913, -0.1951, 0, 0.9808, -0.0381, 0.9808, 0.1913, -0.1913, -0.1951, 0.9619, -0.0747, 0.9239, 0.3753, 0, -0.9239, 0.3827, 0, -0.9808, 0.1951, 0, 0, 1, 0, 0.9808, 0.1951, 0, -0.1951, 0.9808, 0, 0.9239, 0.3827, 0, -0.3827, 0.9239, 0, 0.8315, 0.5556, 0, -0.5556, 0.8315, 0, 0.7071, 0.7071, 0, -0.7071, 0.7071, 0, 0.5556, 0.8315, 0, -0.8315, 0.5556, 0, 0.3827, 0.9239, 0, 0.1951, 0.9808, 0.138, 0.7071, 0.6935, 0.138, -0.7071, 0.6935, 0.1622, 0.5556, 0.8155, 0.1084, -0.8315, 0.5449, 0.1802, 0.3827, 0.9061, 0.0747, -0.9239, 0.3753, 0.1913, 0.1951, 0.9619, 0.0381, -0.9808, 0.1913, 0.1951, 0, 0.9808, 0.0381, 0.9808, 0.1913, 0.1913, -0.1951, 0.9619, 0.0747, 0.9239, 0.3753, 0.1802, -0.3827, 0.9061, 0.1084, 0.8315, 0.5449, 0.1622, -0.5556, 0.8155, 0.3827, 0, 0.9239, 0.0747, 0.9808, 0.1802, 0.0747, -0.9808, 0.1802, 0.3753, -0.1951, 0.9061, 0.1464, 0.9239, 0.3536, 0.3536, -0.3827, 0.8536, 0.2126, 0.8315, 0.5133, 0.3182, -0.5556, 0.7682, 0.2706, 0.7071, 0.6533, 0.2706, -0.7071, 0.6533, 0.3182, 0.5556, 0.7682, 0.2126, -0.8315, 0.5133, 0.3536, 0.3827, 0.8536, 0.1464, -0.9239, 0.3536, 0.3753, 0.1951, 0.9061, 0.3928, -0.7071, 0.5879, 0.3928, 0.7071, 0.5879, 0.4619, 0.5556, 0.6913, 0.3087, -0.8315, 0.4619, 0.5133, 0.3827, 0.7682, 0.2126, -0.9239, 0.3182, 0.5449, 0.1951, 0.8155, 0.1084, -0.9808, 0.1622, 0.5556, 0, 0.8315, 0.1084, 0.9808, 0.1622, 0.5449, -0.1951, 0.8155, 0.2126, 0.9239, 0.3182, 0.5133, -0.3827, 0.7682, 0.3087, 0.8315, 0.4619, 0.4619, -0.5556, 0.6913, 0.138, 0.9808, 0.1379, 0.138, -0.9808, 0.1379, 0.6935, -0.1951, 0.6935, 0.2706, 0.9239, 0.2706, 0.6533, -0.3827, 0.6533, 0.3928, 0.8315, 0.3928, 0.5879, -0.5556, 0.5879, 0.5, 0.7071, 0.5, 0.5, -0.7071, 0.5, 0.5879, 0.5556, 0.5879, 0.3928, -0.8315, 0.3928, 0.6533, 0.3827, 0.6533, 0.2706, -0.9239, 0.2706, 0.6935, 0.1951, 0.6935, 0.7071, 0, 0.7071, 0.5879, 0.7071, 0.3928, 0.6913, 0.5556, 0.4619, 0.5879, -0.7071, 0.3928, 0.4619, -0.8315, 0.3087, 0.7682, 0.3827, 0.5133, 0.3182, -0.9239, 0.2126, 0.8155, 0.1951, 0.5449, 0.1622, -0.9808, 0.1084, 0.8315, 0, 0.5556, 0.1622, 0.9808, 0.1084, 0.8155, -0.1951, 0.5449, 0.3182, 0.9239, 0.2126, 0.7682, -0.3827, 0.5133, 0.4619, 0.8315, 0.3087, 0.6913, -0.5556, 0.4619, 0.9061, -0.1951, 0.3753, 0.3536, 0.9239, 0.1464, 0.8536, -0.3827, 0.3536, 0.5133, 0.8315, 0.2126, 0.7682, -0.5556, 0.3182, 0.6533, 0.7071, 0.2706, 0.6533, -0.7071, 0.2706, 0.7682, 0.5556, 0.3182, 0.5133, -0.8315, 0.2126, 0.8536, 0.3827, 0.3536, 0.3536, -0.9239, 0.1464, 0.9061, 0.1951, 0.3753, 0.1802, -0.9808, 0.0747, 0.9239, 0, 0.3827, 0.1802, 0.9808, 0.0747, 0.5449, -0.8315, 0.1084, 0.9061, 0.3827, 0.1802, 0.3753, -0.9239, 0.0747, 0.9619, 0.1951, 0.1913, 0.1913, -0.9808, 0.0381, 0.9808, 0, 0.1951, 0.1913, 0.9808, 0.0381, 0.9619, -0.1951, 0.1913, 0.3753, 0.9239, 0.0747, 0.9061, -0.3827, 0.1802, 0.5449, 0.8315, 0.1084, 0.8155, -0.5556, 0.1622, 0.6935, 0.7071, 0.1379, 0.6935, -0.7071, 0.1379, 0.8155, 0.5556, 0.1622, 0.9239, -0.3827, 0, 0.3827, 0.9239, 0, 0.5556, 0.8315, 0, 0.8315, -0.5556, 0, 0.7071, 0.7071, 0, 0.7071, -0.7071, 0, 0.8315, 0.5556, 0, 0.5556, -0.8315, 0, 0.9239, 0.3827, 0, 0.3827, -0.9239, 0, 0.9808, 0.1951, 0, 0.1951, -0.9808, 0, 1, 0, 0, 0.1951, 0.9808, 0, 0.9808, -0.1951, 0
2856
+ ];
2857
+ this.indices = [0, 1, 2, 3, 4, 5, 2, 6, 7, 5, 8, 9, 10, 11, 12, 13, 7, 6, 9, 14, 15, 10, 16, 17, 18, 14, 19, 20, 16, 21, 18, 22, 23, 20, 24, 25, 26, 22, 27, 25, 28, 29, 26, 30, 0, 29, 31, 3, 27, 32, 30, 28, 33, 31, 30, 34, 1, 31, 35, 4, 1, 36, 6, 4, 37, 8, 12, 11, 38, 13, 6, 36, 14, 37, 39, 12, 40, 16, 19, 39, 41, 16, 42, 21, 19, 43, 22, 21, 44, 24, 27, 43, 45, 24, 46, 28, 38, 47, 40, 39, 48, 41, 40, 49, 42, 43, 48, 50, 42, 51, 44, 45, 50, 52, 44, 53, 46, 45, 54, 32, 46, 55, 33, 32, 56, 34, 35, 55, 57, 34, 58, 36, 35, 59, 37, 38, 11, 60, 13, 36, 58, 37, 61, 39, 53, 62, 55, 54, 63, 56, 55, 64, 57, 56, 65, 58, 59, 64, 66, 60, 11, 67, 13, 58, 65, 59, 68, 61, 60, 69, 47, 61, 70, 48, 47, 71, 49, 50, 70, 72, 49, 73, 51, 50, 74, 52, 51, 75, 53, 52, 76, 54, 68, 77, 70, 69, 78, 71, 72, 77, 79, 71, 80, 73, 72, 81, 74, 75, 80, 82, 76, 81, 83, 75, 84, 62, 63, 83, 85, 62, 86, 64, 63, 87, 65, 66, 86, 88, 67, 11, 89, 13, 65, 87, 66, 90, 68, 67, 91, 69, 85, 92, 93, 86, 94, 95, 85, 96, 87, 86, 97, 88, 89, 11, 98, 13, 87, 96, 88, 99, 90, 89, 100, 91, 90, 101, 77, 91, 102, 78, 79, 101, 103, 78, 104, 80, 81, 103, 105, 82, 104, 106, 81, 92, 83, 82, 94, 84, 103, 107, 108, 104, 109, 110, 105, 108, 111, 104, 112, 106, 105, 113, 92, 106, 114, 94, 92, 115, 93, 95, 114, 116, 96, 115, 117, 95, 118, 97, 98, 11, 119, 13, 96, 117, 97, 120, 99, 98, 121, 100, 99, 107, 101, 100, 109, 102, 117, 122, 123, 116, 124, 118, 119, 11, 125, 13, 117, 123, 120, 124, 126, 119, 127, 121, 120, 128, 107, 121, 129, 109, 108, 128, 130, 109, 131, 110, 108, 132, 111, 110, 133, 112, 113, 132, 134, 112, 135, 114, 115, 134, 122, 116, 135, 136, 129, 137, 131, 130, 138, 132, 133, 137, 139, 134, 138, 140, 133, 141, 135, 134, 142, 122, 136, 141, 143, 123, 142, 144, 136, 145, 124, 125, 11, 146, 13, 123, 144, 124, 147, 126, 127, 146, 148, 126, 149, 128, 127, 150, 129, 130, 149, 151, 143, 152, 145, 146, 11, 153, 13, 144, 154, 145, 155, 147, 146, 156, 148, 147, 157, 149, 150, 156, 158, 151, 157, 159, 150, 160, 137, 151, 161, 138, 137, 162, 139, 138, 163, 140, 139, 164, 141, 142, 163, 165, 143, 164, 166, 142, 154, 144, 159, 167, 161, 162, 168, 169, 163, 167, 170, 162, 171, 164, 163, 172, 165, 166, 171, 173, 165, 174, 154, 166, 175, 152, 153, 11, 176, 13, 154, 174, 155, 175, 177, 153, 178, 156, 155, 179, 157, 156, 180, 158, 159, 179, 181, 158, 168, 160, 176, 11, 182, 13, 174, 183, 175, 184, 177, 176, 185, 178, 177, 186, 179, 178, 187, 180, 179, 188, 181, 180, 189, 168, 181, 190, 167, 168, 191, 169, 170, 190, 192, 169, 193, 171, 170, 194, 172, 173, 193, 195, 174, 194, 183, 173, 196, 175, 191, 197, 198, 192, 199, 200, 191, 201, 193, 192, 202, 194, 195, 201, 203, 183, 202, 204, 195, 205, 196, 182, 11, 206, 13, 183, 204, 184, 205, 207, 182, 208, 185, 184, 209, 186, 185, 210, 187, 188, 209, 211, 189, 210, 197, 188, 199, 190, 205, 212, 207, 206, 213, 208, 207, 214, 209, 210, 213, 215, 211, 214, 216, 210, 217, 197, 211, 218, 199, 197, 219, 198, 200, 218, 220, 198, 221, 201, 200, 222, 202, 203, 221, 223, 202, 224, 204, 203, 225, 205, 206, 11, 226, 13, 204, 224, 218, 227, 220, 219, 228, 221, 220, 229, 222, 223, 228, 230, 224, 229, 231, 223, 232, 225, 226, 11, 233, 13, 224, 231, 225, 234, 212, 226, 235, 213, 212, 236, 214, 213, 237, 215, 216, 236, 238, 215, 239, 217, 216, 240, 218, 217, 241, 219, 234, 242, 236, 237, 243, 244, 238, 242, 245, 239, 244, 246, 238, 247, 240, 239, 248, 241, 227, 247, 249, 241, 250, 228, 227, 251, 229, 230, 250, 252, 231, 251, 253, 230, 254, 232, 233, 11, 255, 13, 231, 253, 232, 256, 234, 233, 243, 235, 0, 30, 1, 3, 31, 4, 2, 1, 6, 5, 4, 8, 9, 8, 14, 10, 12, 16, 18, 15, 14, 20, 17, 16, 18, 19, 22, 20, 21, 24, 26, 23, 22, 25, 24, 28, 26, 27, 30, 29, 28, 31, 27, 45, 32, 28, 46, 33, 30, 32, 34, 31, 33, 35, 1, 34, 36, 4, 35, 37, 14, 8, 37, 12, 38, 40, 19, 14, 39, 16, 40, 42, 19, 41, 43, 21, 42, 44, 27, 22, 43, 24, 44, 46, 38, 60, 47, 39, 61, 48, 40, 47, 49, 43, 41, 48, 42, 49, 51, 45, 43, 50, 44, 51, 53, 45, 52, 54, 46, 53, 55, 32, 54, 56, 35, 33, 55, 34, 56, 58, 35, 57, 59, 37, 59, 61, 53, 75, 62, 54, 76, 63, 55, 62, 64, 56, 63, 65, 59, 57, 64, 59, 66, 68, 60, 67, 69, 61, 68, 70, 47, 69, 71, 50, 48, 70, 49, 71, 73, 50, 72, 74, 51, 73, 75, 52, 74, 76, 68, 90, 77, 69, 91, 78, 72, 70, 77, 71, 78, 80, 72, 79, 81, 75, 73, 80, 76, 74, 81, 75, 82, 84, 63, 76, 83, 62, 84, 86, 63, 85, 87, 66, 64, 86, 66, 88, 90, 67, 89, 91, 85, 83, 92, 86, 84, 94, 85, 93, 96, 86, 95, 97, 88, 97, 99, 89, 98, 100, 90, 99, 101, 91, 100, 102, 79, 77, 101, 78, 102, 104, 81, 79, 103, 82, 80, 104, 81, 105, 92, 82, 106, 94, 103, 101, 107, 104, 102, 109, 105, 103, 108, 104, 110, 112, 105, 111, 113, 106, 112, 114, 92, 113, 115, 95, 94, 114, 96, 93, 115, 95, 116, 118, 97, 118, 120, 98, 119, 121, 99, 120, 107, 100, 121, 109, 117, 115, 122, 116, 136, 124, 120, 118, 124, 119, 125, 127, 120, 126, 128, 121, 127, 129, 108, 107, 128, 109, 129, 131, 108, 130, 132, 110, 131, 133, 113, 111, 132, 112, 133, 135, 115, 113, 134, 116, 114, 135, 129, 150, 137, 130, 151, 138, 133, 131, 137, 134, 132, 138, 133, 139, 141, 134, 140, 142, 136, 135, 141, 123, 122, 142, 136, 143, 145, 124, 145, 147, 127, 125, 146, 126, 147, 149, 127, 148, 150, 130, 128, 149, 143, 166, 152, 145, 152, 155, 146, 153, 156, 147, 155, 157, 150, 148, 156, 151, 149, 157, 150, 158, 160, 151, 159, 161, 137, 160, 162, 138, 161, 163, 139, 162, 164, 142, 140, 163, 143, 141, 164, 142, 165, 154, 159, 181, 167, 162, 160, 168, 163, 161, 167, 162, 169, 171, 163, 170, 172, 166, 164, 171, 165, 172, 174, 166, 173, 175, 155, 152, 175, 153, 176, 178, 155, 177, 179, 156, 178, 180, 159, 157, 179, 158, 180, 168, 175, 196, 184, 176, 182, 185, 177, 184, 186, 178, 185, 187, 179, 186, 188, 180, 187, 189, 181, 188, 190, 168, 189, 191, 170, 167, 190, 169, 191, 193, 170, 192, 194, 173, 171, 193, 174, 172, 194, 173, 195, 196, 191, 189, 197, 192, 190, 199, 191, 198, 201, 192, 200, 202, 195, 193, 201, 183, 194, 202, 195, 203, 205, 184, 196, 205, 182, 206, 208, 184, 207, 209, 185, 208, 210, 188, 186, 209, 189, 187, 210, 188, 211, 199, 205, 225, 212, 206, 226, 213, 207, 212, 214, 210, 208, 213, 211, 209, 214, 210, 215, 217, 211, 216, 218, 197, 217, 219, 200, 199, 218, 198, 219, 221, 200, 220, 222, 203, 201, 221, 202, 222, 224, 203, 223, 225, 218, 240, 227, 219, 241, 228, 220, 227, 229, 223, 221, 228, 224, 222, 229, 223, 230, 232, 225, 232, 234, 226, 233, 235, 212, 234, 236, 213, 235, 237, 216, 214, 236, 215, 237, 239, 216, 238, 240, 217, 239, 241, 234, 256, 242, 237, 235, 243, 238, 236, 242, 239, 237, 244, 238, 245, 247, 239, 246, 248, 227, 240, 247, 241, 248, 250, 227, 249, 251, 230, 228, 250, 231, 229, 251, 230, 252, 254, 232, 254, 256, 233, 255, 243
2858
+ ];
2859
+ this.normals = [-0.5589, -0.8274, 0.055, -0.3804, -0.9217, 0.0757, -0.3876, -0.921, 0.0381, -0.9209, 0.3789, 0.0907, -0.9622, 0.1939, 0.1914, -0.9764, 0.193, 0.0962, -0.1971, -0.9796, 0.0392, -0.2009, -0.9794, 0.0198, -0.9808, 0, 0.1951, -0.9952, 0, 0.098, -0.2009, 0.9794, 0.0198, 0, 0.998, 0.063, -0.1971, 0.9796, 0.0392, 0, -0.998, 0.063, -0.9622, -0.1939, 0.1914, -0.9764, -0.193, 0.0962, -0.3804, 0.9217, 0.0757, -0.3876, 0.921, 0.0381, -0.9209, -0.3789, 0.0907, -0.907, -0.3805, 0.1804, -0.5589, 0.8274, 0.055, -0.549, 0.8286, 0.1092, -0.8173, -0.5528, 0.1626, -0.8305, -0.5509, 0.0818, -0.6965, 0.704, 0.1385, -0.7084, 0.7023, 0.0698, -0.7084, -0.7023, 0.0698, -0.6965, -0.704, 0.1385, -0.8173, 0.5528, 0.1626, -0.8305, 0.5509, 0.0818, -0.549, -0.8286, 0.1092, -0.907, 0.3805, 0.1804, -0.5171, -0.8286, 0.2142, -0.8544, 0.3805, 0.3539, -0.3583, -0.9217, 0.1484, -0.9063, 0.1939, 0.3754, -0.1856, -0.9796, 0.0769, -0.9239, 0, 0.3827, -0.1856, 0.9796, 0.0769, -0.9063, -0.1939, 0.3754, -0.3583, 0.9217, 0.1484, -0.8544, -0.3805, 0.3539, -0.5171, 0.8286, 0.2142, -0.7699, -0.5528, 0.3189, -0.6561, 0.704, 0.2717, -0.6561, -0.704, 0.2717, -0.7699, 0.5528, 0.3189, -0.3225, 0.9217, 0.2155, -0.7689, -0.3805, 0.5137, -0.4654, 0.8286, 0.311, -0.6929, -0.5528, 0.463, -0.5904, 0.704, 0.3945, -0.5904, -0.704, 0.3945, -0.6929, 0.5528, 0.463, -0.4654, -0.8286, 0.311, -0.7689, 0.3805, 0.5137, -0.3225, -0.9217, 0.2155, -0.8157, 0.1939, 0.545, -0.1671, -0.9796, 0.1116, -0.8314, 0, 0.5556, -0.1671, 0.9796, 0.1116, -0.8157, -0.1939, 0.545, -0.6539, 0.3805, 0.6539, -0.2743, -0.9217, 0.2743, -0.6937, 0.1939, 0.6937, -0.1421, -0.9796, 0.1421, -0.7071, 0, 0.7071, -0.1421, 0.9796, 0.1421, -0.6937, -0.1939, 0.6937, -0.2743, 0.9217, 0.2743, -0.6539, -0.3805, 0.6539, -0.3958, 0.8286, 0.3958, -0.5893, -0.5528, 0.5893, -0.5021, 0.704, 0.5021, -0.5021, -0.704, 0.5021, -0.5893, 0.5528, 0.5893, -0.3958, -0.8286, 0.3958, -0.5137, -0.3805, 0.7689, -0.311, 0.8286, 0.4654, -0.463, -0.5528, 0.6929, -0.3945, 0.704, 0.5904, -0.3945, -0.704, 0.5904, -0.463, 0.5528, 0.6929, -0.311, -0.8286, 0.4654, -0.5137, 0.3805, 0.7689, -0.2155, -0.9217, 0.3225, -0.545, 0.1939, 0.8157, -0.1116, -0.9796, 0.1671, -0.5556, 0, 0.8314, -0.1116, 0.9796, 0.1671, -0.545, -0.1939, 0.8157, -0.2155, 0.9217, 0.3225, -0.2142, -0.8286, 0.5171, -0.1484, -0.9217, 0.3583, -0.3539, 0.3805, 0.8544, -0.3754, 0.1939, 0.9063, -0.0769, -0.9796, 0.1856, -0.3827, 0, 0.9239, -0.0769, 0.9796, 0.1856, -0.3754, -0.1939, 0.9063, -0.1484, 0.9217, 0.3583, -0.3539, -0.3805, 0.8544, -0.2142, 0.8286, 0.5171, -0.3189, -0.5528, 0.7699, -0.2717, 0.704, 0.6561, -0.2717, -0.704, 0.6561, -0.3189, 0.5528, 0.7699, -0.1804, -0.3805, 0.907, -0.1626, -0.5528, 0.8173, -0.1092, 0.8286, 0.549, -0.1385, 0.704, 0.6965, -0.1385, -0.704, 0.6965, -0.1626, 0.5528, 0.8173, -0.1092, -0.8286, 0.549, -0.1804, 0.3805, 0.907, -0.0757, -0.9217, 0.3804, -0.1914, 0.1939, 0.9622, -0.0392, -0.9796, 0.1971, -0.1951, 0, 0.9808, -0.0392, 0.9796, 0.1971, -0.1914, -0.1939, 0.9622, -0.0757, 0.9217, 0.3804, 0, -0.9217, 0.3879, 0, -0.9796, 0.201, 0, 0, 1, 0, 0.9796, 0.201, 0, -0.1939, 0.981, 0, 0.9217, 0.3879, 0, -0.3805, 0.9247, 0, 0.8286, 0.5598, 0, -0.5528, 0.8333, 0, 0.704, 0.7101, 0, -0.704, 0.7101, 0, 0.5528, 0.8333, 0, -0.8286, 0.5598, 0, 0.3805, 0.9247, 0, 0.1939, 0.981, 0.1385, 0.704, 0.6965, 0.1385, -0.704, 0.6965, 0.1626, 0.5528, 0.8173, 0.1092, -0.8286, 0.549, 0.1804, 0.3805, 0.907, 0.0757, -0.9217, 0.3804, 0.1914, 0.1939, 0.9622, 0.0392, -0.9796, 0.1971, 0.1951, 0, 0.9808, 0.0392, 0.9796, 0.1971, 0.1914, -0.1939, 0.9622, 0.0757, 0.9217, 0.3804, 0.1804, -0.3805, 0.907, 0.1092, 0.8286, 0.549, 0.1626, -0.5528, 0.8173, 0.3827, 0, 0.9239, 0.0769, 0.9796, 0.1856, 0.0769, -0.9796, 0.1856, 0.3754, -0.1939, 0.9063, 0.1484, 0.9217, 0.3583, 0.3539, -0.3805, 0.8544, 0.2142, 0.8286, 0.5171, 0.3189, -0.5528, 0.7699, 0.2717, 0.704, 0.6561, 0.2717, -0.704, 0.6561, 0.3189, 0.5528, 0.7699, 0.2142, -0.8286, 0.5171, 0.3539, 0.3805, 0.8544, 0.1484, -0.9217, 0.3583, 0.3754, 0.1939, 0.9063, 0.3945, -0.704, 0.5904, 0.3945, 0.704, 0.5904, 0.463, 0.5528, 0.6929, 0.311, -0.8286, 0.4654, 0.5137, 0.3805, 0.7689, 0.2155, -0.9217, 0.3225, 0.545, 0.1939, 0.8157, 0.1116, -0.9796, 0.1671, 0.5556, 0, 0.8314, 0.1116, 0.9796, 0.1671, 0.545, -0.1939, 0.8157, 0.2155, 0.9217, 0.3225, 0.5137, -0.3805, 0.7689, 0.311, 0.8286, 0.4654, 0.463, -0.5528, 0.6929, 0.1421, 0.9796, 0.1421, 0.1421, -0.9796, 0.1421, 0.6937, -0.1939, 0.6937, 0.2743, 0.9217, 0.2743, 0.6539, -0.3805, 0.6539, 0.3958, 0.8286, 0.3958, 0.5893, -0.5528, 0.5893, 0.5021, 0.704, 0.5021, 0.5021, -0.704, 0.5021, 0.5893, 0.5528, 0.5893, 0.3958, -0.8286, 0.3958, 0.6539, 0.3805, 0.6539, 0.2743, -0.9217, 0.2743, 0.6937, 0.1939, 0.6937, 0.7071, 0, 0.7071, 0.5904, 0.704, 0.3945, 0.6929, 0.5528, 0.463, 0.5904, -0.704, 0.3945, 0.4654, -0.8286, 0.311, 0.7689, 0.3805, 0.5137, 0.3225, -0.9217, 0.2155, 0.8157, 0.1939, 0.545, 0.1671, -0.9796, 0.1116, 0.8314, 0, 0.5556, 0.1671, 0.9796, 0.1116, 0.8157, -0.1939, 0.545, 0.3225, 0.9217, 0.2155, 0.7689, -0.3805, 0.5137, 0.4654, 0.8286, 0.311, 0.6929, -0.5528, 0.463, 0.9063, -0.1939, 0.3754, 0.3583, 0.9217, 0.1484, 0.8544, -0.3805, 0.3539, 0.5171, 0.8286, 0.2142, 0.7699, -0.5528, 0.3189, 0.6561, 0.704, 0.2717, 0.6561, -0.704, 0.2717, 0.7699, 0.5528, 0.3189, 0.5171, -0.8286, 0.2142, 0.8544, 0.3805, 0.3539, 0.3583, -0.9217, 0.1484, 0.9063, 0.1939, 0.3754, 0.1856, -0.9796, 0.0769, 0.9239, 0, 0.3827, 0.1856, 0.9796, 0.0769, 0.549, -0.8286, 0.1092, 0.907, 0.3805, 0.1804, 0.3804, -0.9217, 0.0757, 0.9622, 0.1939, 0.1914, 0.1971, -0.9796, 0.0392, 0.9808, 0, 0.1951, 0.1971, 0.9796, 0.0392, 0.9622, -0.1939, 0.1914, 0.3804, 0.9217, 0.0757, 0.907, -0.3805, 0.1804, 0.549, 0.8286, 0.1092, 0.8173, -0.5528, 0.1626, 0.6965, 0.704, 0.1385, 0.6965, -0.704, 0.1385, 0.8173, 0.5528, 0.1626, 0.9209, -0.3789, 0.0907, 0.3876, 0.921, 0.0381, 0.5589, 0.8274, 0.055, 0.8305, -0.5509, 0.0818, 0.7084, 0.7023, 0.0698, 0.7084, -0.7023, 0.0698, 0.8305, 0.5509, 0.0818, 0.5589, -0.8274, 0.055, 0.9209, 0.3789, 0.0907, 0.3876, -0.921, 0.0381, 0.9764, 0.193, 0.0962, 0.2009, -0.9794, 0.0198, 0.9952, 0, 0.098, 0.2009, 0.9794, 0.0198, 0.9764, -0.193, 0.0962
2860
+ ];
2861
+ this.subMeshes = [
2862
+ new SubMesh(0, 1440)
2863
+ ];
2864
+ }
2865
+ }
2866
+
2867
+ class Plane extends BasicMesh {
2868
+ constructor(sizeOrWidth = 1.0, heightOrWidthSegments = 1.0, widthOrHeightSegments = 1, heightSegmentsOrOrientation, orientation = 'xz') {
2869
+ super();
2870
+ let w;
2871
+ let h;
2872
+ let gridX;
2873
+ let gridY;
2874
+ let orient;
2875
+ if (sizeOrWidth instanceof Vec2) {
2876
+ w = sizeOrWidth.x || 1.0;
2877
+ h = sizeOrWidth.y || 1.0;
2878
+ gridX = Utils.clamp(Utils.floor(heightOrWidthSegments || 1, 0), 1, Infinity);
2879
+ gridY = Utils.clamp(Utils.floor(widthOrHeightSegments || 1, 0), 1, Infinity);
2880
+ orient = (typeof heightSegmentsOrOrientation === 'string' ? heightSegmentsOrOrientation : orientation) || 'xz';
2881
+ }
2882
+ else {
2883
+ w = sizeOrWidth || 1.0;
2884
+ h = heightOrWidthSegments || 1.0;
2885
+ gridX = Utils.clamp(Utils.floor(widthOrHeightSegments || 1, 0), 1, Infinity);
2886
+ gridY = Utils.clamp(Utils.floor((typeof heightSegmentsOrOrientation === 'number' ? heightSegmentsOrOrientation : 1) || 1, 0), 1, Infinity);
2887
+ orient = orientation || 'xz';
2888
+ }
2889
+ const gridX1 = gridX + 1;
2890
+ const gridY1 = gridY + 1;
2891
+ const segmentWidth = w / gridX;
2892
+ const segmentHeight = h / gridY;
2893
+ const vertices = [];
2894
+ const normals = [];
2895
+ const uvs = [];
2896
+ const indices = [];
2897
+ const halfW = w * 0.5;
2898
+ const halfH = h * 0.5;
2899
+ for (let iy = 0; iy < gridY1; iy++) {
2900
+ const y = iy * segmentHeight - halfH;
2901
+ for (let ix = 0; ix < gridX1; ix++) {
2902
+ const x = ix * segmentWidth - halfW;
2903
+ if (orient === 'xz') {
2904
+ vertices.push(x, 0, y);
2905
+ normals.push(0, 1, 0);
2906
+ }
2907
+ else {
2908
+ vertices.push(x, -y, 0);
2909
+ normals.push(0, 0, 1);
2910
+ }
2911
+ uvs.push(ix / gridX, 1.0 - iy / gridY);
2912
+ }
2913
+ }
2914
+ for (let iy = 0; iy < gridY; iy++)
2915
+ for (let ix = 0; ix < gridX; ix++) {
2916
+ const a = ix + gridX1 * iy;
2917
+ const b = ix + gridX1 * (iy + 1);
2918
+ const c = (ix + 1) + gridX1 * (iy + 1);
2919
+ const d = (ix + 1) + gridX1 * iy;
2920
+ indices.push(a, b, d);
2921
+ indices.push(b, c, d);
2922
+ }
2923
+ this.vertices = vertices;
2924
+ this.normals = normals;
2925
+ this.uvs = uvs;
2926
+ this.indices = indices;
2927
+ this.itemSize = 3;
2928
+ this.primitive = 'TRIANGLES';
2929
+ this.subMeshes = [new SubMesh(0, indices.length)];
2930
+ }
2931
+ }
2932
+
2933
+ class Cylinder extends BasicMesh {
2934
+ constructor(radiusTop = 1.0, radiusBottom = 1.0, height = 1.0, radialSegments = 16, heightSegments = 1, openEnded = false) {
2935
+ super();
2936
+ const rTop = radiusTop !== undefined ? radiusTop : 1.0;
2937
+ const rBottom = radiusBottom !== undefined ? radiusBottom : 1.0;
2938
+ const h = height || 1.0;
2939
+ const radSeg = Utils.clamp(Utils.floor(radialSegments || 16, 0), 3, Infinity);
2940
+ const hSeg = Utils.clamp(Utils.floor(heightSegments || 1, 0), 1, Infinity);
2941
+ const vertices = [];
2942
+ const normals = [];
2943
+ const uvs = [];
2944
+ const indices = [];
2945
+ let index = 0;
2946
+ const indexGrid = [];
2947
+ const halfH = h * 0.5;
2948
+ const tanTheta = (rBottom - rTop) / h;
2949
+ for (let y = 0; y <= hSeg; y++) {
2950
+ const indexRow = [];
2951
+ const v = y / hSeg;
2952
+ const radius = v * (rBottom - rTop) + rTop;
2953
+ const py = -v * h + halfH;
2954
+ for (let x = 0; x <= radSeg; x++) {
2955
+ const u = x / radSeg;
2956
+ const theta = u * Trigo.twopi;
2957
+ const sinTheta = Trigo.sine(theta);
2958
+ const cosTheta = Trigo.cosine(theta);
2959
+ const px = radius * sinTheta;
2960
+ const pz = radius * cosTheta;
2961
+ vertices.push(px, py, pz);
2962
+ const nx = sinTheta;
2963
+ const ny = tanTheta;
2964
+ const nz = cosTheta;
2965
+ const nLen = Math.hypot(nx, ny, nz) || 1.0;
2966
+ normals.push(nx / nLen, ny / nLen, nz / nLen);
2967
+ uvs.push(u, 1.0 - v);
2968
+ indexRow.push(index++);
2969
+ }
2970
+ indexGrid.push(indexRow);
2971
+ }
2972
+ for (let x = 0; x < radSeg; x++)
2973
+ for (let y = 0; y < hSeg; y++) {
2974
+ const a = indexGrid[y][x];
2975
+ const b = indexGrid[y + 1][x];
2976
+ const c = indexGrid[y + 1][x + 1];
2977
+ const d = indexGrid[y][x + 1];
2978
+ indices.push(a, b, d);
2979
+ indices.push(b, c, d);
2980
+ }
2981
+ if (!openEnded) {
2982
+ if (rTop > 0) {
2983
+ const centerIndexTop = index++;
2984
+ vertices.push(0, halfH, 0);
2985
+ normals.push(0, 1, 0);
2986
+ uvs.push(0.5, 0.5);
2987
+ const topCapStartIndex = index;
2988
+ for (let x = 0; x <= radSeg; x++) {
2989
+ const u = x / radSeg;
2990
+ const theta = u * Trigo.twopi;
2991
+ const px = rTop * Trigo.sine(theta);
2992
+ const pz = rTop * Trigo.cosine(theta);
2993
+ vertices.push(px, halfH, pz);
2994
+ normals.push(0, 1, 0);
2995
+ uvs.push(Trigo.sine(theta) * 0.5 + 0.5, Trigo.cosine(theta) * 0.5 + 0.5);
2996
+ index++;
2997
+ }
2998
+ for (let x = 0; x < radSeg; x++)
2999
+ indices.push(centerIndexTop, topCapStartIndex + x, topCapStartIndex + x + 1);
3000
+ }
3001
+ if (rBottom > 0) {
3002
+ const centerIndexBottom = index++;
3003
+ vertices.push(0, -halfH, 0);
3004
+ normals.push(0, -1, 0);
3005
+ uvs.push(0.5, 0.5);
3006
+ const bottomCapStartIndex = index;
3007
+ for (let x = 0; x <= radSeg; x++) {
3008
+ const u = x / radSeg;
3009
+ const theta = u * Trigo.twopi;
3010
+ const px = rBottom * Trigo.sine(theta);
3011
+ const pz = rBottom * Trigo.cosine(theta);
3012
+ vertices.push(px, -halfH, pz);
3013
+ normals.push(0, -1, 0);
3014
+ uvs.push(Trigo.sine(theta) * 0.5 + 0.5, Trigo.cosine(theta) * 0.5 + 0.5);
3015
+ index++;
3016
+ }
3017
+ for (let x = 0; x < radSeg; x++)
3018
+ indices.push(centerIndexBottom, bottomCapStartIndex + x + 1, bottomCapStartIndex + x);
3019
+ }
3020
+ }
3021
+ this.vertices = vertices;
3022
+ this.normals = normals;
3023
+ this.uvs = uvs;
3024
+ this.indices = indices;
3025
+ this.itemSize = 3;
3026
+ this.primitive = 'TRIANGLES';
3027
+ this.subMeshes = [new SubMesh(0, indices.length)];
3028
+ }
3029
+ }
3030
+
3031
+ class VWing extends BasicMesh {
3032
+ constructor() {
3033
+ super();
3034
+ this.vertices = [0, 0, -7.3975, 0, -0.2707, 0, 1.4678, 0, 0, 0, 0.5653, 1.8374, 0, 1.4694, 0, 0, 1.553, -1.0874, 0, 0.7405, -5.3869, 2.3189, 0.251, 0, 1.4678, 0, 0, 1.6633, 2.6, 1.6982, 6.65, -0.8596, 3.1485, 2.3189, 0.251, 0, 1.9333, -0.2938, -1.9828, 1.4678, 0, 0, 2.3189, 0.251, 0, 1.4678, 0, 0, 1.4678, 0, 0, 1.6148, -0.4246, -2.7743, 1.9333, -0.2938, -1.9828, 1.4678, 0, 0, 1.6148, -0.4246, -2.7743, 1.6148, -0.4246, -2.7743, 1.9333, -0.2938, -1.9828, -1.4678, 0, 0, -2.3189, 0.251, 0, -1.6633, 2.6, 1.6982, -1.4678, 0, 0, -6.65, -0.8596, 3.1485, -1.9333, -0.2938, -1.9828, -2.3189, 0.251, 0, -1.4678, 0, 0, -2.3189, 0.251, 0, -1.4678, 0, 0, -1.4678, 0, 0, -1.6148, -0.4246, -2.7743, -1.9333, -0.2938, -1.9828, -1.6148, -0.4246, -2.7743, -1.4678, 0, 0, -1.6148, -0.4246, -2.7743, -1.9333, -0.2938, -1.9828, 0, -0.2707, 0, 0, 0.5653, 1.8374, 1.4678, 0, 0, 0, -0.2707, 0, -1.4678, 0, 0
3035
+ ];
3036
+ this.indices = [0, 1, 2, 2, 3, 4, 5, 2, 4, 6, 0, 2, 5, 6, 2, 7, 8, 9, 10, 11, 12, 10, 12, 13, 14, 10, 15, 16, 12, 17, 7, 9, 18, 9, 19, 20, 21, 22, 9, 0, 23, 1, 23, 4, 3, 5, 4, 23, 6, 23, 0, 5, 23, 6, 24, 25, 26, 27, 28, 29, 27, 30, 28, 31, 32, 27, 33, 34, 28, 24, 35, 25, 25, 36, 37, 38, 25, 39, 40, 41, 42, 43, 44, 41
3037
+ ];
3038
+ this.normals = [0, -0.1063, -0.9943, 0, -0.9819, 0.1891, 0.9233, -0.2975, 0.2427, 0, 0.0714, 0.9974, 0, 0.9697, 0.2443, 0, 0.9961, -0.088, 0, 0.9478, -0.3187, 0.553, 0.7911, 0.2613, -0.7402, -0.526, 0.4187, -0.0528, 0.7418, 0.6686, 0.7771, -0.1425, 0.6131, 0.553, 0.7911, 0.2613, 0.8324, -0.4718, -0.2906, -0.7402, -0.526, 0.4187, 0.553, 0.7911, 0.2613, -0.7402, -0.526, 0.4187, -0.7402, -0.526, 0.4187, -0.1135, -0.2998, -0.9472, 0.8324, -0.4718, -0.2906, -0.7402, -0.526, 0.4187, -0.1135, -0.2998, -0.9472, -0.1135, -0.2998, -0.9472, 0.8324, -0.4718, -0.2906, -0.9233, -0.2975, 0.2427, -0.553, 0.7911, 0.2613, 0.0528, 0.7418, 0.6686, 0.7402, -0.526, 0.4187, -0.7771, -0.1425, 0.6131, -0.8324, -0.4718, -0.2906, -0.553, 0.7911, 0.2613, 0.7402, -0.526, 0.4187, -0.553, 0.7911, 0.2613, 0.7402, -0.526, 0.4187, 0.7402, -0.526, 0.4187, 0.1135, -0.2998, -0.9472, -0.8324, -0.4718, -0.2906, 0.1135, -0.2998, -0.9472, 0.7402, -0.526, 0.4187, 0.1135, -0.2998, -0.9472, -0.8324, -0.4718, -0.2906, 0, -0.9819, 0.1891, 0, 0.0714, 0.9974, 0.9233, -0.2975, 0.2427, 0, -0.9819, 0.1891, -0.9233, -0.2975, 0.2427
3039
+ ];
3040
+ this.subMeshes = [
3041
+ new SubMesh(0, 78),
3042
+ new SubMesh(78, 6)
3043
+ ];
3044
+ }
3045
+ }
3046
+
3047
+ class Cannon extends BasicMesh {
3048
+ constructor() {
3049
+ super();
3050
+ this.vertices = [0, -0.4, 0.1885, 0.7, 0, -0.9849, 0, -0.4, -0.9849, 0, 0.4, -0.9849, 0.7, 0, 0.4525, 0, 0.4, 0.9293, 0, 0, -0.8408, 0, 0.4, -0.9849, 0, 0, 1.9525, 0, 0.4, 0.9293, 0.7, 0, 0.4525, 0, 0, -0.8408, 0, 0.3, -1.1203, 0.6, 0, -1.1203, 0, 0.11, -2.8486, 0.2351, 0, -3.0108, 0, -0.11, -3.0108, 0, -0.3, -1.1203, 0, 0, -0.8408, 0.7, 0, 0.4525, 0, -0.4, 0.1885, -0.7, 0, -0.9849, -0.7, 0, 0.4525, 0, 0.4, -0.9849, -0.7, 0, 0.4525, 0, 0.4, 0.9293, 0, 0, -0.8408, -0.6, 0, -1.1203, -0.2351, 0, -3.0108, 0, 0, -0.8408, -0.7, 0, 0.4525, 0, -0.4, 0.1885, 0.7, 0, 0.4525, -0.7, 0, 0.4525
3051
+ ];
3052
+ this.indices = [0, 1, 2, 3, 4, 5, 1, 6, 2, 1, 7, 6, 8, 9, 10, 11, 12, 13, 14, 13, 12, 15, 14, 16, 13, 17, 18, 19, 20, 8, 17, 13, 15, 15, 16, 17, 21, 0, 2, 22, 3, 5, 21, 2, 6, 21, 6, 23, 8, 24, 25, 26, 27, 12, 27, 14, 12, 28, 16, 14, 27, 29, 17, 30, 8, 31, 17, 28, 27, 28, 17, 16, 0, 32, 1, 3, 1, 4, 14, 15, 13, 21, 33, 0, 22, 21, 3, 27, 28, 14
3053
+ ];
3054
+ this.normals = [0, -0.9962, 0.0863, 0.7964, 0, -0.6047, 0, -0.7073, -0.7069, 0, 0.7073, -0.7069, 0.9834, -0.0314, 0.1787, 0, 0.973, 0.231, 0, 0, -1, 0, 0.7073, -0.7069, 0, -0.0518, 0.9987, 0, 0.973, 0.231, 0.9834, -0.0314, 0.1787, 0, 0, -1, 0, 0.9499, 0.3124, 0.9369, 0.0022, 0.3496, 0, 0.9436, -0.3311, 0.6731, 0.0686, -0.7363, 0, -0.5683, -0.8228, 0, -0.948, 0.3182, 0, 0, -1, 0.9834, -0.0314, 0.1787, 0, -0.9962, 0.0863, -0.7964, 0, -0.6047, -0.9834, -0.0314, 0.1787, 0, 0.7073, -0.7069, -0.9834, -0.0314, 0.1787, 0, 0.973, 0.231, 0, 0, -1, -0.9369, 0.0022, 0.3496, -0.6731, 0.0686, -0.7363, 0, 0, -1, -0.9834, -0.0314, 0.1787, 0, -0.9962, 0.0863, 0.9834, -0.0314, 0.1787, -0.9834, -0.0314, 0.1787
3055
+ ];
3056
+ this.subMeshes = [
3057
+ new SubMesh(0, 90)
3058
+ ];
3059
+ }
3060
+ }
3061
+
3062
+ class CustomMesh {
3063
+ vertices;
3064
+ indices;
3065
+ normals;
3066
+ uvs;
3067
+ subMeshes;
3068
+ itemSize;
3069
+ primitive;
3070
+ primitives;
3071
+ constructor() {
3072
+ this.vertices = null;
3073
+ this.indices = null;
3074
+ this.normals = null;
3075
+ this.uvs = null;
3076
+ this.subMeshes = [];
3077
+ this.itemSize = 3;
3078
+ this.primitive = 'TRIANGLES';
3079
+ this.primitives = ['POINTS',
3080
+ 'LINE_STRIP',
3081
+ 'LINE_LOOP',
3082
+ 'LINES',
3083
+ 'TRIANGLE_STRIP',
3084
+ 'TRIANGLE_FAN',
3085
+ 'TRIANGLES'
3086
+ ];
3087
+ }
3088
+ static toFloat32(array) {
3089
+ if (array.length > 0 && array[0] instanceof Vec3) {
3090
+ const flat = new Float32Array(array.length * 3);
3091
+ for (let i = 0; i < array.length; i++)
3092
+ array[i].toArray(flat, i * 3);
3093
+ return flat;
3094
+ }
3095
+ return array instanceof Float32Array ? array.slice(0) : new Float32Array(array);
3096
+ }
3097
+ setVertices(array) {
3098
+ this.vertices = CustomMesh.toFloat32(array);
3099
+ }
3100
+ setIndices(array) {
3101
+ this.indices = array instanceof Int32Array ? array.slice(0) : new Int32Array(array);
3102
+ }
3103
+ setNormals(array) {
3104
+ this.normals = CustomMesh.toFloat32(array);
3105
+ }
3106
+ setUvs(array) {
3107
+ this.uvs = array instanceof Float32Array ? array.slice(0) : new Float32Array(array);
3108
+ }
3109
+ addSubMeshes(array) {
3110
+ for (let i = 0; i < array.length; i += 2)
3111
+ this.addSubMesh(array[i], array[i + 1]);
3112
+ }
3113
+ addSubMesh(start, count) {
3114
+ this.subMeshes.push(new SubMesh(start, count));
3115
+ }
3116
+ setItemSize(itemSize) {
3117
+ this.itemSize = itemSize;
3118
+ }
3119
+ setPrimitive(primitive) {
3120
+ for (let i = 0; i < this.primitives.length; i++)
3121
+ if (this.primitives[i] === primitive) {
3122
+ this.primitive = primitive;
3123
+ return true;
3124
+ }
3125
+ return false;
3126
+ }
3127
+ static _vA = new Vec3();
3128
+ static _vB = new Vec3();
3129
+ static _vC = new Vec3();
3130
+ static _e1 = new Vec3();
3131
+ static _e2 = new Vec3();
3132
+ static _n = new Vec3();
3133
+ static _sum = new Vec3();
3134
+ static UP = new Vec3(0, 1, 0);
3135
+ static accumulate(normals, offset, n) {
3136
+ CustomMesh._sum.setArray(normals, offset).add(n).toArray(normals, offset);
3137
+ }
3138
+ computeVertexNormals() {
3139
+ if (!this.vertices || this.vertices.length === 0)
3140
+ return null;
3141
+ const vertices = this.vertices;
3142
+ const normals = new Float32Array(vertices.length);
3143
+ const vA = CustomMesh._vA, vB = CustomMesh._vB, vC = CustomMesh._vC;
3144
+ const e1 = CustomMesh._e1, e2 = CustomMesh._e2, n = CustomMesh._n;
3145
+ const faceNormal = (iA, iB, iC) => {
3146
+ vA.setArray(vertices, iA);
3147
+ vB.setArray(vertices, iB);
3148
+ vC.setArray(vertices, iC);
3149
+ return n.crossVectors(e1.subVectors(vB, vA), e2.subVectors(vC, vA));
3150
+ };
3151
+ if (this.indices && this.indices.length > 0)
3152
+ for (let i = 0; i + 2 < this.indices.length; i += 3) {
3153
+ const iA = this.indices[i] * 3;
3154
+ const iB = this.indices[i + 1] * 3;
3155
+ const iC = this.indices[i + 2] * 3;
3156
+ faceNormal(iA, iB, iC);
3157
+ CustomMesh.accumulate(normals, iA, n);
3158
+ CustomMesh.accumulate(normals, iB, n);
3159
+ CustomMesh.accumulate(normals, iC, n);
3160
+ }
3161
+ else
3162
+ for (let i = 0; i + 8 < vertices.length; i += 9) {
3163
+ faceNormal(i, i + 3, i + 6);
3164
+ n.toArray(normals, i);
3165
+ n.toArray(normals, i + 3);
3166
+ n.toArray(normals, i + 6);
3167
+ }
3168
+ for (let i = 0; i < normals.length; i += 3)
3169
+ n.setArray(normals, i).normalize(CustomMesh.UP).toArray(normals, i);
3170
+ this.normals = normals;
3171
+ return this.normals;
3172
+ }
3173
+ }
3174
+
3175
+ class DirectionalLight {
3176
+ position;
3177
+ diffuse;
3178
+ specular;
3179
+ direction;
3180
+ type;
3181
+ constructor(directionOrOptions) {
3182
+ this.position = new Vec3();
3183
+ this.direction = new Vec3(0, -1, 0);
3184
+ this.diffuse = new Vec3(0.6, 0.6, 0.6);
3185
+ this.specular = new Vec3(0.8, 0.8, 0.8);
3186
+ this.type = 'directional';
3187
+ if (directionOrOptions)
3188
+ if (directionOrOptions instanceof Vec3 || Array.isArray(directionOrOptions))
3189
+ this.setDirection(directionOrOptions);
3190
+ else if (typeof directionOrOptions === 'object') {
3191
+ if (directionOrOptions.direction)
3192
+ this.setDirection(directionOrOptions.direction);
3193
+ if (directionOrOptions.diffuse)
3194
+ this.setDiffuse(directionOrOptions.diffuse);
3195
+ if (directionOrOptions.specular)
3196
+ this.setSpecular(directionOrOptions.specular);
3197
+ if (directionOrOptions.position)
3198
+ this.setPosition(directionOrOptions.position);
3199
+ }
3200
+ }
3201
+ setPosition(xOrVec, y, z) {
3202
+ assignVec3(this.position, xOrVec, y, z);
3203
+ }
3204
+ setDirection(xOrVec, y, z) {
3205
+ assignVec3(this.direction, xOrVec, y, z).normalize();
3206
+ }
3207
+ setDiffuse(xOrVec, y, z) {
3208
+ assignVec3(this.diffuse, xOrVec, y, z);
3209
+ }
3210
+ setSpecular(xOrVec, y, z) {
3211
+ assignVec3(this.specular, xOrVec, y, z);
3212
+ }
3213
+ }
3214
+
3215
+ class PointLight extends DirectionalLight {
3216
+ constantAttenuation;
3217
+ linearAttenuation;
3218
+ quadraticAttenuation;
3219
+ constructor(positionOrOptions) {
3220
+ super();
3221
+ this.constantAttenuation = 0;
3222
+ this.linearAttenuation = 1.0;
3223
+ this.quadraticAttenuation = 0;
3224
+ this.type = 'point';
3225
+ if (positionOrOptions)
3226
+ if (positionOrOptions instanceof Vec3 || Array.isArray(positionOrOptions))
3227
+ this.setPosition(positionOrOptions);
3228
+ else if (typeof positionOrOptions === 'object') {
3229
+ if (positionOrOptions.position)
3230
+ this.setPosition(positionOrOptions.position);
3231
+ if (positionOrOptions.diffuse)
3232
+ this.setDiffuse(positionOrOptions.diffuse);
3233
+ if (positionOrOptions.specular)
3234
+ this.setSpecular(positionOrOptions.specular);
3235
+ if (positionOrOptions.constantAttenuation !== undefined)
3236
+ this.setConstantAttenuation(positionOrOptions.constantAttenuation);
3237
+ if (positionOrOptions.linearAttenuation !== undefined)
3238
+ this.setLinearAttenuation(positionOrOptions.linearAttenuation);
3239
+ if (positionOrOptions.quadraticAttenuation !== undefined)
3240
+ this.setQuadraticAttenuation(positionOrOptions.quadraticAttenuation);
3241
+ }
3242
+ }
3243
+ setConstantAttenuation(value) {
3244
+ this.constantAttenuation = value;
3245
+ }
3246
+ setLinearAttenuation(value) {
3247
+ this.linearAttenuation = value;
3248
+ }
3249
+ setQuadraticAttenuation(value) {
3250
+ this.quadraticAttenuation = value;
3251
+ }
3252
+ }
3253
+
3254
+ class SpotLight extends PointLight {
3255
+ cutoff;
3256
+ exponent;
3257
+ direction;
3258
+ constructor(positionOrOptions) {
3259
+ super(positionOrOptions);
3260
+ this.cutoff = 180;
3261
+ this.exponent = 0;
3262
+ this.direction = new Vec3(1.0, 0.0, 0.0);
3263
+ this.type = 'spot';
3264
+ if (positionOrOptions && typeof positionOrOptions === 'object' && !(positionOrOptions instanceof Vec3) && !Array.isArray(positionOrOptions)) {
3265
+ if (positionOrOptions.direction)
3266
+ this.setDirection(positionOrOptions.direction);
3267
+ if (positionOrOptions.cutoff !== undefined)
3268
+ this.setCutoff(positionOrOptions.cutoff);
3269
+ if (positionOrOptions.exponent !== undefined)
3270
+ this.setExponent(positionOrOptions.exponent);
3271
+ }
3272
+ }
3273
+ setCutoff(value) {
3274
+ this.cutoff = value;
3275
+ }
3276
+ setExponent(value) {
3277
+ this.exponent = value;
3278
+ }
3279
+ setDirection(xOrVec, y, z) {
3280
+ assignVec3(this.direction, xOrVec, y, z);
3281
+ }
3282
+ }
3283
+
3284
+ class AmbientLight {
3285
+ diffuse;
3286
+ intensity;
3287
+ type;
3288
+ constructor(rOrVec = 1.0, g = 1.0, b = 1.0, intensity = 1.0) {
3289
+ this.diffuse = new Vec3();
3290
+ if (rOrVec instanceof Vec3) {
3291
+ this.diffuse.copy(rOrVec);
3292
+ this.intensity = g !== undefined ? g : 1.0;
3293
+ }
3294
+ else {
3295
+ this.diffuse.setScalar(rOrVec, g, b);
3296
+ this.intensity = intensity;
3297
+ }
3298
+ this.type = 'ambient';
3299
+ }
3300
+ setColor(xOrVec, y, z) {
3301
+ if (typeof xOrVec === 'number')
3302
+ this.diffuse.setScalar(xOrVec, y ?? 0, z ?? 0);
3303
+ else
3304
+ assignVec3(this.diffuse, xOrVec);
3305
+ return this;
3306
+ }
3307
+ setIntensity(intensity) {
3308
+ this.intensity = intensity;
3309
+ return this;
3310
+ }
3311
+ getColor() {
3312
+ return this.diffuse;
3313
+ }
3314
+ get color() {
3315
+ return this.diffuse;
3316
+ }
3317
+ set color(c) {
3318
+ this.diffuse.copy(c);
3319
+ }
3320
+ }
3321
+
3322
+ export { AmbientLight, BasicMesh, BasicShader, Camera, Cannon, Cube, CustomMesh, Cylinder, DirectionalLight, FullscreenQuad, Hemisphere, Lights, Line, MAX_LIGHTS, Material, Mesh, MultiQuad, NormalShader, OrbitControls, OrthographicCamera, PerspectiveCamera, PhongShader, Plane, PointLight, Program, Quad, RenderTarget, Renderer, Scene, Shader, Sphere, SpotLight, SubMesh, Texture, Uniform, VWing, eDrawMethod };