@woosh/meep-engine 2.75.4 → 2.75.6
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/build/bundle-worker-image-decoder.js +1 -1
- package/build/meep.cjs +91 -74
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +91 -74
- package/editor/ecs/component/editors/ecs/ParameterLookupTableEditor.js +35 -21
- package/package.json +2 -2
- package/src/core/collection/array/array_compute_min_max.js +20 -0
- package/src/core/collection/map/HashMap.js +16 -14
- package/src/core/geom/2d/convex-hull/fixed_convex_hull_humus.js +23 -13
- package/src/core/geom/2d/intersect_ray_2d.js +7 -14
- package/src/core/geom/3d/aabb/AABB3.js +13 -0
- package/src/core/geom/3d/topology/samples/sampleFloodFill.js +21 -21
- package/src/core/geom/3d/topology/tm_face_area.js +1 -1
- package/src/core/geom/3d/triangle/computeTriangleSurfaceArea.js +39 -0
- package/src/core/process/task/util/countTask.js +1 -2
- package/src/engine/EngineBootstrapper.js +15 -7
- package/src/engine/animation/curve/AnimationCurve.js +50 -31
- package/src/engine/animation/curve/AnimationCurve.spec.js +9 -1
- package/src/engine/animation/curve/compression/prototypeCurveCompression.js +20 -11
- package/src/engine/animation/curve/compute_curve_aabb.js +26 -0
- package/src/engine/animation/curve/draw/build_curve_editor.js +82 -42
- package/src/engine/animation/curve/draw/build_plot_entity_from_array.js +5 -5
- package/src/engine/animation/curve/preset/CURVE_EASE_IN.js +8 -0
- package/src/engine/animation/curve/preset/CURVE_EASE_IN_OUT.js +7 -0
- package/src/engine/animation/curve/preset/CURVE_EASE_OUT.js +7 -0
- package/src/engine/asset/loaders/image/png/PNGReader.js +119 -1
- package/src/engine/graphics/GraphicsEngine.d.ts +6 -3
- package/src/engine/graphics/canvas/canvas2d_draw_grid.js +42 -0
- package/src/engine/{animation/curve/draw/draw_label.js → graphics/canvas/canvas2d_draw_label.js} +6 -1
- package/src/engine/graphics/canvas/canvas2d_draw_linear_scale.js +64 -0
- package/src/engine/graphics/canvas/canvas2d_draw_path.js +60 -0
- package/src/engine/graphics/canvas/canvas2d_plot_data_line.js +84 -0
- package/src/engine/{animation/curve/draw/plot_array.js → graphics/canvas/canvas2d_plot_line_array.js} +8 -25
- package/src/engine/graphics/geometry/computeMeshSurfaceArea.js +2 -37
- package/src/engine/graphics/impostors/octahedral/bake/prepare_bake_material.js +8 -26
- package/src/engine/graphics/material/manager/MaterialManager.d.ts +6 -0
- package/src/engine/graphics/sh3/LightProbeVolume.js +38 -17
- package/src/engine/graphics/sh3/path_tracer/prototypePathTracer.js +26 -35
- package/src/engine/graphics/sh3/prototypeSH3Probe.js +166 -100
- package/src/engine/graphics/texture/makeOnePixelTexture.js +19 -0
- package/src/engine/graphics/texture/sprite/prototypeSpriteCutoutGeometry.js +5 -68
- package/src/engine/input/devices/PointerDevice.js +6 -3
- package/src/engine/makeSimpleTaskProgressView.js +33 -0
- package/src/engine/scene/transitionToScene.js +9 -10
- package/src/view/task/TaskLoadingScreen.js +5 -12
- package/src/view/task/TaskProgressView.js +9 -9
- package/src/engine/animation/curve/draw/draw_grid.js +0 -27
- package/src/engine/animation/curve/draw/plot_data.js +0 -49
- package/src/engine/graphics/geometry/QuadGeometry.js +0 -13
|
@@ -11,14 +11,12 @@ import GUIElementSystem from "../../../ecs/gui/GUIElementSystem.js";
|
|
|
11
11
|
import ViewportPosition from "../../../ecs/gui/position/ViewportPosition.js";
|
|
12
12
|
import ViewportPositionSystem from "../../../ecs/gui/position/ViewportPositionSystem.js";
|
|
13
13
|
import { EngineHarness } from "../../../EngineHarness.js";
|
|
14
|
+
import { canvas2d_draw_path } from "../../canvas/canvas2d_draw_path.js";
|
|
14
15
|
import { Sampler2D } from "../sampler/Sampler2D.js";
|
|
15
16
|
import sampler2D2Canvas from "../sampler/Sampler2D2Canvas.js";
|
|
16
17
|
import { make_edge_condition_channel_threshold } from "../sampler/search/make_edge_condition_channel_threshold.js";
|
|
17
18
|
import { sampler2d_find_pixels } from "../sampler/search/sampler2d_find_pixels.js";
|
|
18
19
|
|
|
19
|
-
const edge_condition_alpha0 = make_edge_condition_channel_threshold(3, 0);
|
|
20
|
-
|
|
21
|
-
|
|
22
20
|
function sampler_as_view(sampler) {
|
|
23
21
|
|
|
24
22
|
const vSpriteSource = new CanvasView();
|
|
@@ -33,67 +31,6 @@ function sampler_as_view(sampler) {
|
|
|
33
31
|
return vSpriteSource;
|
|
34
32
|
}
|
|
35
33
|
|
|
36
|
-
/**
|
|
37
|
-
*
|
|
38
|
-
* @param {number[]} vertices
|
|
39
|
-
* @param {CanvasRenderingContext2D} ctx
|
|
40
|
-
* @param [fillColor]
|
|
41
|
-
* @param [strokeColor]
|
|
42
|
-
* @param [highlight_vertices]
|
|
43
|
-
* @param [vertex_draw_size]
|
|
44
|
-
* @param {number} [offset] in pixels
|
|
45
|
-
*/
|
|
46
|
-
function drawPath({
|
|
47
|
-
vertices,
|
|
48
|
-
ctx,
|
|
49
|
-
fillColor = 'transparent',
|
|
50
|
-
strokeColor = 'red',
|
|
51
|
-
highlight_vertices = true,
|
|
52
|
-
vertex_draw_size = 8,
|
|
53
|
-
offset = [0, 0]
|
|
54
|
-
}) {
|
|
55
|
-
|
|
56
|
-
function draw_point(x, y) {
|
|
57
|
-
ctx.fillStyle = 'rgba(255,255,255,0.8)';
|
|
58
|
-
ctx.strokeStyle = 'black';
|
|
59
|
-
ctx.lineWidth = "1px";
|
|
60
|
-
|
|
61
|
-
const x1 = x - vertex_draw_size / 2 + offset[0];
|
|
62
|
-
const y1 = y - vertex_draw_size / 2 + offset[1];
|
|
63
|
-
|
|
64
|
-
ctx.fillRect(x1, y1, vertex_draw_size, vertex_draw_size);
|
|
65
|
-
|
|
66
|
-
ctx.strokeRect(x1, y1, vertex_draw_size, vertex_draw_size);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (highlight_vertices) {
|
|
70
|
-
for (let i = 0; i < vertices.length / 2; i++) {
|
|
71
|
-
draw_point(vertices[i * 2], vertices[i * 2 + 1]);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
ctx.fillStyle = fillColor;
|
|
76
|
-
ctx.strokeStyle = strokeColor;
|
|
77
|
-
ctx.lineWidth = "1px";
|
|
78
|
-
|
|
79
|
-
ctx.beginPath();
|
|
80
|
-
|
|
81
|
-
ctx.moveTo(vertices[0] + offset[0], vertices[1] + offset[1]);
|
|
82
|
-
// drawPoint(jarvis_vertices[0].x, jarvis_vertices[0].y, jarvis_vertices[0].z, 'red');
|
|
83
|
-
|
|
84
|
-
for (let i = 1; i < vertices.length / 2; i++) {
|
|
85
|
-
|
|
86
|
-
ctx.lineTo(vertices[i * 2] + offset[0], vertices[i * 2 + 1] + offset[1]);
|
|
87
|
-
|
|
88
|
-
// drawPoint(last.x, last.y, last.z, 'red');
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
ctx.closePath();
|
|
92
|
-
ctx.stroke();
|
|
93
|
-
ctx.fill();
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
97
34
|
/**
|
|
98
35
|
*
|
|
99
36
|
* @param {Engine} engine
|
|
@@ -104,10 +41,10 @@ async function main(engine) {
|
|
|
104
41
|
// const path = "data/textures/particle/UETools/Bones_01.png";
|
|
105
42
|
// const path = "data/textures/particle/UETools/x64/Bones_01.png";
|
|
106
43
|
// const path = "data/textures/particle/KriptoFX/x256/SmokeTile2.png";
|
|
107
|
-
const path = "data/textures/particle/KriptoFX/CloudMask.png";
|
|
44
|
+
// const path = "data/textures/particle/KriptoFX/CloudMask.png";
|
|
108
45
|
// const path = "data/textures/particle/travnik/arrow_2_64.png";
|
|
109
46
|
// const path = "data/textures/particle/travnik/leaf_01.png";
|
|
110
|
-
|
|
47
|
+
const path = "data/textures/particle/travnik/portal_2_blue_64.png";
|
|
111
48
|
// const path = "data/textures/particle/travnik/flake.png";
|
|
112
49
|
|
|
113
50
|
const asset = await engine.assetManager.promise(path, 'image')
|
|
@@ -147,7 +84,7 @@ async function main(engine) {
|
|
|
147
84
|
// we make it a bit larger to fit markers drawn at the edges of the image
|
|
148
85
|
vHull.size.set(sampler.width + 32, sampler.height + 32);
|
|
149
86
|
|
|
150
|
-
|
|
87
|
+
canvas2d_draw_path({
|
|
151
88
|
vertices: convex_hull_vertices,
|
|
152
89
|
ctx: vHull.context2d,
|
|
153
90
|
offset: [16, 16]
|
|
@@ -184,7 +121,7 @@ async function main(engine) {
|
|
|
184
121
|
|
|
185
122
|
vOptimalPoly.size.set(sampler.width + 100, sampler.height + 100);
|
|
186
123
|
|
|
187
|
-
|
|
124
|
+
canvas2d_draw_path({
|
|
188
125
|
vertices: optimal_poly,
|
|
189
126
|
ctx: vOptimalPoly.context2d,
|
|
190
127
|
strokeColor: '#30c0ff',
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Created by Alex on 29/01/2015.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import { assert } from "../../../core/assert.js";
|
|
5
5
|
import Signal from "../../../core/events/signal/Signal.js";
|
|
6
|
+
import Vector2 from "../../../core/geom/Vector2.js";
|
|
6
7
|
import Vector3 from "../../../core/geom/Vector3.js";
|
|
7
|
-
import {
|
|
8
|
+
import { sign } from "../../../core/math/sign.js";
|
|
8
9
|
import { MouseEvents } from "./events/MouseEvents.js";
|
|
9
10
|
import { TouchEvents } from "./events/TouchEvents.js";
|
|
10
|
-
import { sign } from "../../../core/math/sign.js";
|
|
11
11
|
import { InputDeviceSwitch } from "./InputDeviceSwitch.js";
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -353,6 +353,9 @@ export class PointerDevice {
|
|
|
353
353
|
down: new Signal(),
|
|
354
354
|
up: new Signal(),
|
|
355
355
|
move: new Signal(),
|
|
356
|
+
/**
|
|
357
|
+
* @type {Signal<Vector2, (MouseEvent|TouchEvent)>}
|
|
358
|
+
*/
|
|
356
359
|
tap: new Signal(),
|
|
357
360
|
drag: new Signal(),
|
|
358
361
|
dragStart: new Signal(),
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import Vector2 from "../core/geom/Vector2.js";
|
|
2
|
+
import TaskProgressView from "../view/task/TaskProgressView.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {Task|TaskGroup} task
|
|
7
|
+
* @param {Localization} localization
|
|
8
|
+
* @param {Vector2} [size]
|
|
9
|
+
* @returns {TaskProgressView}
|
|
10
|
+
*/
|
|
11
|
+
export function makeSimpleTaskProgressView({
|
|
12
|
+
task,
|
|
13
|
+
localization,
|
|
14
|
+
size = new Vector2(256, 32)
|
|
15
|
+
}) {
|
|
16
|
+
|
|
17
|
+
const vProgress = new TaskProgressView({
|
|
18
|
+
task,
|
|
19
|
+
localization
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
vProgress.size.copy(size);
|
|
23
|
+
vProgress.css({
|
|
24
|
+
position: 'absolute',
|
|
25
|
+
top: 0,
|
|
26
|
+
left: 0,
|
|
27
|
+
pointerEvents: "none"
|
|
28
|
+
});
|
|
29
|
+
vProgress.el.querySelector('.fill').style.background = 'rgb(255,220,94)';
|
|
30
|
+
vProgress.el.querySelector('.progress-bar').style.height = '8px';
|
|
31
|
+
|
|
32
|
+
return vProgress;
|
|
33
|
+
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { assert } from "../../core/assert.js";
|
|
2
|
+
import { noop } from "../../core/function/Functions.js";
|
|
2
3
|
import Task from "../../core/process/task/Task.js";
|
|
4
|
+
import TaskGroup from "../../core/process/task/TaskGroup.js";
|
|
3
5
|
import TaskState from "../../core/process/task/TaskState.js";
|
|
4
|
-
import { noop } from "../../core/function/Functions.js";
|
|
5
|
-
import { compileAllMaterials } from "../graphics/ecs/compileAllMaterials.js";
|
|
6
|
-
import { createTaskWaitForMeshesToLoad } from "../graphics/ecs/mesh/createTaskWaitForMeshesToLoad.js";
|
|
7
|
-
import { loadVisibleTerrainTiles } from "../ecs/terrain/util/loadVisibleTerrainTiles.js";
|
|
8
|
-
import { TaskLoadingScreen } from "../../view/task/TaskLoadingScreen.js";
|
|
9
6
|
import { actionTask } from "../../core/process/task/util/actionTask.js";
|
|
10
7
|
import { delayTask } from "../../core/process/task/util/delayTask.js";
|
|
11
8
|
import { wrapTaskIgnoreFailure } from "../../core/process/task/util/wrapTaskIgnoreFailure.js";
|
|
12
|
-
import {
|
|
9
|
+
import { TaskLoadingScreen } from "../../view/task/TaskLoadingScreen.js";
|
|
10
|
+
import { loadVisibleTerrainTiles } from "../ecs/terrain/util/loadVisibleTerrainTiles.js";
|
|
11
|
+
import { compileAllMaterials } from "../graphics/ecs/compileAllMaterials.js";
|
|
12
|
+
import { createTaskWaitForMeshesToLoad } from "../graphics/ecs/mesh/createTaskWaitForMeshesToLoad.js";
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -117,7 +117,6 @@ export function transitionToScene({
|
|
|
117
117
|
|
|
118
118
|
Task.joinAll(allTasks,
|
|
119
119
|
() => {
|
|
120
|
-
cleanup();
|
|
121
120
|
|
|
122
121
|
taskGroup.state.set(TaskState.SUCCEEDED);
|
|
123
122
|
|
|
@@ -126,8 +125,6 @@ export function transitionToScene({
|
|
|
126
125
|
},
|
|
127
126
|
() => {
|
|
128
127
|
|
|
129
|
-
cleanup();
|
|
130
|
-
|
|
131
128
|
taskGroup.state.set(TaskState.FAILED);
|
|
132
129
|
|
|
133
130
|
taskGroup.on.failed.send0();
|
|
@@ -140,5 +137,7 @@ export function transitionToScene({
|
|
|
140
137
|
engine.executor.runMany(extraTasks);
|
|
141
138
|
}, noop);
|
|
142
139
|
|
|
140
|
+
promise.finally(cleanup);
|
|
141
|
+
|
|
143
142
|
return promise;
|
|
144
143
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import TaskProgressView from "./TaskProgressView.js";
|
|
2
|
-
import { AssetLoaderStatusView } from "../asset/AssetLoaderStatusView.js";
|
|
3
|
-
import { logger } from "../../engine/logging/GlobalLogger.js";
|
|
4
|
-
import { array_remove_first } from "../../core/collection/array/array_remove_first.js";
|
|
5
1
|
import { assert } from "../../core/assert.js";
|
|
2
|
+
import { array_remove_first } from "../../core/collection/array/array_remove_first.js";
|
|
3
|
+
import { logger } from "../../engine/logging/GlobalLogger.js";
|
|
4
|
+
import { AssetLoaderStatusView } from "../asset/AssetLoaderStatusView.js";
|
|
5
|
+
import TaskProgressView from "./TaskProgressView.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @type {TaskLoadingScreen}
|
|
@@ -133,14 +133,7 @@ export class TaskLoadingScreen {
|
|
|
133
133
|
|
|
134
134
|
this._pending_cleanup.push(cleanup);
|
|
135
135
|
|
|
136
|
-
const promise =
|
|
137
|
-
|
|
138
|
-
const p = task.promise();
|
|
139
|
-
|
|
140
|
-
p.finally(attempt_cleanup);
|
|
141
|
-
p.then(resolve, reject);
|
|
142
|
-
|
|
143
|
-
});
|
|
136
|
+
const promise = task.promise().finally(attempt_cleanup);
|
|
144
137
|
|
|
145
138
|
this._active_promise = promise;
|
|
146
139
|
|
|
@@ -3,26 +3,26 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import LabelView from '../common/LabelView.js';
|
|
6
|
+
import Vector1 from "../../core/geom/Vector1.js";
|
|
7
|
+
import { RemainingTimeEstimator } from "../../core/process/task/RemainingTimeEstimator.js";
|
|
9
8
|
|
|
10
9
|
import TaskState from '../../core/process/task/TaskState.js';
|
|
11
|
-
|
|
12
|
-
import dom from '../DOM.js';
|
|
13
10
|
import Clock from "../../engine/Clock.js";
|
|
14
|
-
import
|
|
11
|
+
import LabelView from '../common/LabelView.js';
|
|
15
12
|
import { LocalizedLabelView } from "../common/LocalizedLabelView.js";
|
|
16
|
-
|
|
13
|
+
|
|
14
|
+
import dom from '../DOM.js';
|
|
15
|
+
import SmoothProgressBar from '../elements/progress/SmoothProgressBar.js';
|
|
16
|
+
import View from '../View.js';
|
|
17
17
|
|
|
18
18
|
class TaskProgressView extends View {
|
|
19
19
|
/**
|
|
20
20
|
*
|
|
21
21
|
* @param {Task|TaskGroup} task
|
|
22
|
-
* @param {Localization} localization
|
|
22
|
+
* @param {Localization} [localization]
|
|
23
23
|
* @constructor
|
|
24
24
|
*/
|
|
25
|
-
constructor({ task, localization }) {
|
|
25
|
+
constructor({ task, localization=null }) {
|
|
26
26
|
super();
|
|
27
27
|
|
|
28
28
|
function makeNameId() {
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* @param {CanvasRenderingContext2D} ctx
|
|
4
|
-
* @param {number} width
|
|
5
|
-
* @param {number} height
|
|
6
|
-
* @param {string} color
|
|
7
|
-
* @param {number} spacing
|
|
8
|
-
* @param {number} [offset_x]
|
|
9
|
-
* @param {number} [offset_y]
|
|
10
|
-
*/
|
|
11
|
-
export function draw_grid({ ctx, width, height, color = 'red', spacing = 10, offset_x = 0, offset_y = 0 }) {
|
|
12
|
-
ctx.fillStyle = 'none';
|
|
13
|
-
ctx.lineWidth = 1;
|
|
14
|
-
ctx.strokeStyle = color;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
ctx.beginPath();
|
|
18
|
-
for (let x = offset_x; x < width; x += spacing) {
|
|
19
|
-
ctx.moveTo(x, 0);
|
|
20
|
-
ctx.lineTo(x, height);
|
|
21
|
-
}
|
|
22
|
-
for (let y = offset_y; y < width; y += spacing) {
|
|
23
|
-
ctx.moveTo(0, y);
|
|
24
|
-
ctx.lineTo(width, y);
|
|
25
|
-
}
|
|
26
|
-
ctx.stroke();
|
|
27
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { draw_grid } from "./draw_grid.js";
|
|
2
|
-
import { plot_array } from "./plot_array.js";
|
|
3
|
-
import Vector2 from "../../../../core/geom/Vector2.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
*
|
|
7
|
-
* @param {CanvasRenderingContext2D} ctx
|
|
8
|
-
* @param {number[]|Float32Array} data
|
|
9
|
-
* @param {Vector2} [margin]
|
|
10
|
-
* @param {number} width
|
|
11
|
-
* @param {number} height
|
|
12
|
-
* @param {number[]} [range_y]
|
|
13
|
-
*/
|
|
14
|
-
export function plot_data({
|
|
15
|
-
ctx,
|
|
16
|
-
data,
|
|
17
|
-
margin = Vector2.zero,
|
|
18
|
-
width,
|
|
19
|
-
height,
|
|
20
|
-
range_y
|
|
21
|
-
}) {
|
|
22
|
-
|
|
23
|
-
ctx.fillStyle = '#222222';
|
|
24
|
-
ctx.fillRect(0, 0, width, height);
|
|
25
|
-
|
|
26
|
-
draw_grid({
|
|
27
|
-
ctx,
|
|
28
|
-
width,
|
|
29
|
-
height,
|
|
30
|
-
color: '#262626',
|
|
31
|
-
spacing: 32
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
draw_grid({
|
|
35
|
-
ctx,
|
|
36
|
-
width,
|
|
37
|
-
height,
|
|
38
|
-
color: '#303030',
|
|
39
|
-
spacing: 32,
|
|
40
|
-
offset_x: 16,
|
|
41
|
-
offset_y: 16
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
ctx.fillStyle = 'none';
|
|
45
|
-
ctx.strokeStyle = '#00ff00';
|
|
46
|
-
ctx.lineWidth = 1;
|
|
47
|
-
plot_array(ctx, width - margin.x * 2, height - margin.y * 2, margin.x, margin.y, data, range_y);
|
|
48
|
-
|
|
49
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Created by Alex on 01/11/2014.
|
|
3
|
-
*/
|
|
4
|
-
import { PlaneBufferGeometry } from 'three';
|
|
5
|
-
|
|
6
|
-
let faces = [[0, 1, 2], [0, 2, 3]];
|
|
7
|
-
let vertices = [];
|
|
8
|
-
|
|
9
|
-
const QuadGeometry = function (width, height) {
|
|
10
|
-
return new PlaneBufferGeometry(width, height, 1, 1);
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export default QuadGeometry;
|