simulationjsv2 0.8.4 → 0.10.1
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/TODO.md +4 -0
- package/dist/geometry.d.ts +34 -32
- package/dist/geometry.js +165 -66
- package/dist/globals.d.ts +9 -0
- package/dist/globals.js +22 -0
- package/dist/graphics.d.ts +17 -9
- package/dist/graphics.js +92 -62
- package/dist/internalUtils.d.ts +1 -3
- package/dist/internalUtils.js +1 -10
- package/dist/pipelineUtil.d.ts +5 -0
- package/dist/pipelineUtil.js +22 -0
- package/dist/simulation.d.ts +2 -0
- package/dist/simulation.js +10 -3
- package/dist/utils.d.ts +5 -1
- package/dist/utils.js +32 -5
- package/package.json +1 -1
package/TODO.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# TODO
|
|
2
2
|
|
|
3
|
+
- [ ] Materials for planes
|
|
4
|
+
- [ ] Transform vertex colors on material
|
|
5
|
+
- [x] Morph objects into other objects
|
|
6
|
+
- [x] `transform` function taking another object and transitioning from current geometry's vertices (positions only)
|
|
3
7
|
- [x] Change render vertices to use index buffer
|
|
4
8
|
- [x] Add cull modes
|
|
5
9
|
- [x] Fix shaders
|
package/dist/geometry.d.ts
CHANGED
|
@@ -1,26 +1,34 @@
|
|
|
1
|
-
import { CircleGeometryParams, CubeGeometryParams, EmptyParams, Spline2dGeometryParams, SquareGeometryParams, Vector3, LineGeometryParams, TraceLinesParams } from './types.js';
|
|
2
|
-
import { Vertex } from './utils.js';
|
|
1
|
+
import { CircleGeometryParams, CubeGeometryParams, EmptyParams, Spline2dGeometryParams, SquareGeometryParams, Vector3, LineGeometryParams, TraceLinesParams, LerpFunc } from './types.js';
|
|
3
2
|
import { CubicBezierCurve2d, SplinePoint2d } from './graphics.js';
|
|
4
3
|
export declare abstract class Geometry<T extends EmptyParams> {
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
private subdivision;
|
|
5
|
+
private subdivisionVertexLimit;
|
|
6
|
+
private fromVertices;
|
|
7
|
+
private currentInterpolate;
|
|
8
|
+
private updated;
|
|
9
|
+
protected wireframeOrder: number[];
|
|
10
|
+
protected triangleOrder: number[];
|
|
7
11
|
protected abstract params: T;
|
|
8
12
|
protected vertices: Vector3[];
|
|
9
13
|
protected topology: 'list' | 'strip';
|
|
10
|
-
constructor(
|
|
14
|
+
constructor(geometryType?: 'list' | 'strip');
|
|
11
15
|
getTopology(): "list" | "strip";
|
|
12
|
-
|
|
16
|
+
computeVertices(): void;
|
|
17
|
+
compute(): void;
|
|
18
|
+
triangulate(): void;
|
|
19
|
+
setSubdivisions(num: number, vertexLimit?: number): void;
|
|
20
|
+
clearSubdivisions(): void;
|
|
21
|
+
setSubdivisionVertexLimit(limit: number): void;
|
|
22
|
+
clearSubdivisionVertexLimit(): void;
|
|
23
|
+
animateFrom(fromVertices: Vector3[], t: number, f?: LerpFunc): Promise<void>;
|
|
13
24
|
getIndexes(wireframe: boolean): number[];
|
|
14
25
|
getVertices(): Vector3[];
|
|
26
|
+
hasUpdated(): boolean;
|
|
15
27
|
}
|
|
16
28
|
export declare class PlaneGeometry extends Geometry<EmptyParams> {
|
|
17
29
|
protected params: {};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
private rawVertices;
|
|
21
|
-
constructor(vertices: Vertex[]);
|
|
22
|
-
recompute(): void;
|
|
23
|
-
updateVertices(vertices: Vertex[]): void;
|
|
30
|
+
constructor(vertices: Vector3[]);
|
|
31
|
+
updateVertices(vertices: Vector3[]): void;
|
|
24
32
|
}
|
|
25
33
|
export declare class CubeGeometry extends Geometry<CubeGeometryParams> {
|
|
26
34
|
protected params: CubeGeometryParams;
|
|
@@ -30,7 +38,7 @@ export declare class CubeGeometry extends Geometry<CubeGeometryParams> {
|
|
|
30
38
|
setWidth(width: number): void;
|
|
31
39
|
setHeight(height: number): void;
|
|
32
40
|
setDepth(depth: number): void;
|
|
33
|
-
|
|
41
|
+
computeVertices(): void;
|
|
34
42
|
updateSize(width: number, height: number, depth: number): void;
|
|
35
43
|
}
|
|
36
44
|
export declare class SquareGeometry extends Geometry<SquareGeometryParams> {
|
|
@@ -40,26 +48,24 @@ export declare class SquareGeometry extends Geometry<SquareGeometryParams> {
|
|
|
40
48
|
constructor(width: number, height: number);
|
|
41
49
|
setWidth(width: number): void;
|
|
42
50
|
setHeight(height: number): void;
|
|
43
|
-
|
|
51
|
+
computeVertices(): void;
|
|
44
52
|
}
|
|
45
53
|
export declare class BlankGeometry extends Geometry<EmptyParams> {
|
|
46
|
-
protected wireframeOrder: never[];
|
|
47
|
-
protected triangleOrder: never[];
|
|
48
54
|
protected params: {};
|
|
49
55
|
constructor();
|
|
50
|
-
recompute(): void;
|
|
51
56
|
}
|
|
52
57
|
export declare class CircleGeometry extends Geometry<CircleGeometryParams> {
|
|
53
|
-
protected wireframeOrder: number[];
|
|
54
|
-
protected triangleOrder: number[];
|
|
55
58
|
protected params: CircleGeometryParams;
|
|
56
59
|
constructor(radius: number, detail: number);
|
|
60
|
+
setDetail(detail: number): void;
|
|
61
|
+
getDetail(): number;
|
|
57
62
|
setRadius(radius: number): void;
|
|
58
|
-
|
|
63
|
+
getRadius(): number;
|
|
64
|
+
computeVertices(): void;
|
|
65
|
+
}
|
|
66
|
+
export declare class OutlineCircleGeometry {
|
|
59
67
|
}
|
|
60
68
|
export declare class Spline2dGeometry extends Geometry<Spline2dGeometryParams> {
|
|
61
|
-
protected wireframeOrder: number[];
|
|
62
|
-
protected triangleOrder: number[];
|
|
63
69
|
protected params: Spline2dGeometryParams;
|
|
64
70
|
constructor(points: SplinePoint2d[], thickness: number, detail: number);
|
|
65
71
|
updateInterpolationStart(start: number): void;
|
|
@@ -73,35 +79,31 @@ export declare class Spline2dGeometry extends Geometry<Spline2dGeometryParams> {
|
|
|
73
79
|
getVertexInterpolations(): number[];
|
|
74
80
|
getCurveVertexIndices(): number[];
|
|
75
81
|
private computeCurves;
|
|
76
|
-
|
|
82
|
+
computeVertices(): void;
|
|
77
83
|
}
|
|
78
84
|
export declare class Line2dGeometry extends Geometry<LineGeometryParams> {
|
|
79
85
|
protected wireframeOrder: number[];
|
|
80
86
|
protected triangleOrder: number[];
|
|
81
87
|
protected params: LineGeometryParams;
|
|
82
88
|
constructor(pos: Vector3, to: Vector3, thickness: number);
|
|
83
|
-
|
|
89
|
+
computeVertices(): void;
|
|
84
90
|
}
|
|
85
91
|
export declare class Line3dGeometry extends Geometry<LineGeometryParams> {
|
|
86
92
|
protected wireframeOrder: number[];
|
|
87
93
|
protected triangleOrder: number[];
|
|
88
94
|
protected params: LineGeometryParams;
|
|
89
95
|
constructor(pos: Vector3, to: Vector3, thickness: number);
|
|
90
|
-
|
|
96
|
+
computeVertices(): void;
|
|
91
97
|
}
|
|
92
98
|
export declare class PolygonGeometry extends Geometry<EmptyParams> {
|
|
93
|
-
protected wireframeOrder: number[];
|
|
94
|
-
protected triangleOrder: number[];
|
|
95
99
|
protected params: {};
|
|
96
100
|
constructor(vertices: Vector3[]);
|
|
97
|
-
|
|
101
|
+
computeVertices(): void;
|
|
98
102
|
}
|
|
99
|
-
export declare class
|
|
100
|
-
protected wireframeOrder: number[];
|
|
101
|
-
protected triangleOrder: never[];
|
|
103
|
+
export declare class TraceLinesGeometry extends Geometry<TraceLinesParams> {
|
|
102
104
|
protected params: TraceLinesParams;
|
|
103
105
|
constructor(maxLen?: number);
|
|
104
|
-
|
|
106
|
+
triangulate(): void;
|
|
105
107
|
getVertexCount(): number;
|
|
106
108
|
getOrder(_: boolean): readonly [Vector3[], number[]];
|
|
107
109
|
addVertex(vert: Vector3): void;
|
package/dist/geometry.js
CHANGED
|
@@ -1,42 +1,150 @@
|
|
|
1
1
|
import { mat4, vec2, vec3 } from 'wgpu-matrix';
|
|
2
|
-
import { cloneBuf, matrix4, vector2, vector2FromVector3, vector3, vector3FromVector2 } from './utils.js';
|
|
2
|
+
import { cloneBuf, cloneVectors, matrix4, transitionValues, vector2, vector2FromVector3, vector3, vector3FromVector2 } from './utils.js';
|
|
3
3
|
import { CubicBezierCurve2d } from './graphics.js';
|
|
4
4
|
import { createIndexArray, lossyTriangulate, lossyTriangulateStrip, triangulateWireFrameOrder } from './internalUtils.js';
|
|
5
5
|
export class Geometry {
|
|
6
|
+
subdivision = 0;
|
|
7
|
+
subdivisionVertexLimit = null;
|
|
8
|
+
// null if not animating, assumed to be at least the length of vertices
|
|
9
|
+
fromVertices = null;
|
|
10
|
+
currentInterpolate = 0; // stops animating after 1
|
|
11
|
+
updated;
|
|
12
|
+
wireframeOrder;
|
|
13
|
+
triangleOrder;
|
|
6
14
|
vertices;
|
|
7
15
|
topology;
|
|
8
|
-
constructor(
|
|
9
|
-
this.vertices =
|
|
16
|
+
constructor(geometryType = 'list') {
|
|
17
|
+
this.vertices = [];
|
|
10
18
|
this.topology = geometryType;
|
|
19
|
+
this.updated = true;
|
|
20
|
+
this.wireframeOrder = [];
|
|
21
|
+
this.triangleOrder = [];
|
|
11
22
|
}
|
|
12
23
|
getTopology() {
|
|
13
24
|
return this.topology;
|
|
14
25
|
}
|
|
26
|
+
computeVertices() { }
|
|
27
|
+
compute() {
|
|
28
|
+
this.computeVertices();
|
|
29
|
+
this.updated = false;
|
|
30
|
+
// handle subdivisions
|
|
31
|
+
let initialVertices = [...this.vertices];
|
|
32
|
+
outer: for (let i = 0; i < this.subdivision; i++) {
|
|
33
|
+
const initialLength = initialVertices.length;
|
|
34
|
+
for (let j = 0; j < initialLength - 1; j++) {
|
|
35
|
+
if (this.subdivisionVertexLimit && this.vertices.length >= this.subdivisionVertexLimit)
|
|
36
|
+
break outer;
|
|
37
|
+
const vert = initialVertices[j];
|
|
38
|
+
const nextVert = initialVertices[j + 1];
|
|
39
|
+
const newVert = cloneBuf(nextVert);
|
|
40
|
+
vec3.add(newVert, vert, newVert);
|
|
41
|
+
vec3.divScalar(newVert, 2, newVert);
|
|
42
|
+
this.vertices.splice(j * 2 + 1, 0, newVert);
|
|
43
|
+
}
|
|
44
|
+
if (initialLength >= 2) {
|
|
45
|
+
const first = initialVertices[0];
|
|
46
|
+
const last = initialVertices[initialVertices.length - 1];
|
|
47
|
+
const newVert = cloneBuf(first);
|
|
48
|
+
vec3.add(newVert, last, newVert);
|
|
49
|
+
vec3.divScalar(newVert, 2, newVert);
|
|
50
|
+
this.vertices.push(newVert);
|
|
51
|
+
}
|
|
52
|
+
initialVertices = [...this.vertices];
|
|
53
|
+
}
|
|
54
|
+
// handle animation
|
|
55
|
+
if (this.fromVertices) {
|
|
56
|
+
const initialFrom = cloneVectors(this.fromVertices);
|
|
57
|
+
const changes = [];
|
|
58
|
+
for (let i = 0; i < this.vertices.length; i++) {
|
|
59
|
+
const from = initialFrom[i];
|
|
60
|
+
const to = this.vertices[i];
|
|
61
|
+
const diff = cloneBuf(to);
|
|
62
|
+
vec3.sub(diff, from, diff);
|
|
63
|
+
changes.push(diff);
|
|
64
|
+
}
|
|
65
|
+
for (let i = this.vertices.length; i < initialFrom.length; i++) {
|
|
66
|
+
const from = initialFrom[i];
|
|
67
|
+
const to = this.vertices[this.vertices.length - 1];
|
|
68
|
+
const diff = cloneBuf(to);
|
|
69
|
+
vec3.sub(diff, from, diff);
|
|
70
|
+
changes.push(diff);
|
|
71
|
+
}
|
|
72
|
+
for (let i = 0; i < initialFrom.length; i++) {
|
|
73
|
+
const diff = changes[i];
|
|
74
|
+
vec3.mulScalar(diff, this.currentInterpolate, diff);
|
|
75
|
+
vec3.add(initialFrom[i], diff, initialFrom[i]);
|
|
76
|
+
}
|
|
77
|
+
this.vertices = initialFrom;
|
|
78
|
+
}
|
|
79
|
+
if (this.fromVertices || this.subdivision > 0)
|
|
80
|
+
this.triangulate();
|
|
81
|
+
}
|
|
82
|
+
triangulate() {
|
|
83
|
+
this.wireframeOrder = triangulateWireFrameOrder(this.vertices.length);
|
|
84
|
+
const indexArray = createIndexArray(this.vertices.length);
|
|
85
|
+
if (this.topology === 'list') {
|
|
86
|
+
this.triangleOrder = lossyTriangulate(indexArray).flat();
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
this.triangleOrder = lossyTriangulateStrip(indexArray);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
setSubdivisions(num, vertexLimit) {
|
|
93
|
+
if (num >= 0) {
|
|
94
|
+
this.subdivision = num;
|
|
95
|
+
if (vertexLimit)
|
|
96
|
+
this.subdivisionVertexLimit = vertexLimit;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
clearSubdivisions() {
|
|
100
|
+
this.subdivision = 0;
|
|
101
|
+
this.clearSubdivisionVertexLimit();
|
|
102
|
+
}
|
|
103
|
+
setSubdivisionVertexLimit(limit) {
|
|
104
|
+
this.subdivisionVertexLimit = limit;
|
|
105
|
+
}
|
|
106
|
+
clearSubdivisionVertexLimit() {
|
|
107
|
+
this.subdivisionVertexLimit = null;
|
|
108
|
+
}
|
|
109
|
+
animateFrom(fromVertices, t, f) {
|
|
110
|
+
this.fromVertices = fromVertices;
|
|
111
|
+
// ensure at least the length of vertices
|
|
112
|
+
if (fromVertices.length < this.vertices.length) {
|
|
113
|
+
const initialLen = fromVertices.length;
|
|
114
|
+
for (let i = 0; i < this.vertices.length - initialLen; i++) {
|
|
115
|
+
const last = cloneBuf(fromVertices[fromVertices.length - 1]);
|
|
116
|
+
this.fromVertices.push(last);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return transitionValues((p) => {
|
|
120
|
+
this.currentInterpolate += p;
|
|
121
|
+
this.updated = true;
|
|
122
|
+
}, () => {
|
|
123
|
+
this.currentInterpolate = 0;
|
|
124
|
+
this.fromVertices = null;
|
|
125
|
+
this.updated = true;
|
|
126
|
+
}, t, f);
|
|
127
|
+
}
|
|
15
128
|
getIndexes(wireframe) {
|
|
16
129
|
return wireframe ? this.wireframeOrder : this.triangleOrder;
|
|
17
130
|
}
|
|
18
131
|
getVertices() {
|
|
19
132
|
return this.vertices;
|
|
20
133
|
}
|
|
134
|
+
hasUpdated() {
|
|
135
|
+
return this.updated;
|
|
136
|
+
}
|
|
21
137
|
}
|
|
22
138
|
export class PlaneGeometry extends Geometry {
|
|
23
139
|
params = {};
|
|
24
|
-
wireframeOrder;
|
|
25
|
-
triangleOrder;
|
|
26
|
-
rawVertices;
|
|
27
140
|
constructor(vertices) {
|
|
28
|
-
super(
|
|
29
|
-
this.
|
|
30
|
-
this.
|
|
31
|
-
this.rawVertices = vertices;
|
|
32
|
-
this.updateVertices(vertices);
|
|
141
|
+
super('strip');
|
|
142
|
+
this.vertices = vertices;
|
|
143
|
+
this.triangulate();
|
|
33
144
|
}
|
|
34
|
-
recompute() { }
|
|
35
145
|
updateVertices(vertices) {
|
|
36
|
-
this.
|
|
37
|
-
this.
|
|
38
|
-
this.wireframeOrder = triangulateWireFrameOrder(this.vertices.length);
|
|
39
|
-
this.triangleOrder = lossyTriangulateStrip(createIndexArray(this.rawVertices.length));
|
|
146
|
+
this.vertices = vertices;
|
|
147
|
+
this.triangulate();
|
|
40
148
|
}
|
|
41
149
|
}
|
|
42
150
|
export class CubeGeometry extends Geometry {
|
|
@@ -58,7 +166,7 @@ export class CubeGeometry extends Geometry {
|
|
|
58
166
|
height,
|
|
59
167
|
depth
|
|
60
168
|
};
|
|
61
|
-
this.
|
|
169
|
+
this.computeVertices();
|
|
62
170
|
}
|
|
63
171
|
setWidth(width) {
|
|
64
172
|
this.params.width = width;
|
|
@@ -69,7 +177,7 @@ export class CubeGeometry extends Geometry {
|
|
|
69
177
|
setDepth(depth) {
|
|
70
178
|
this.params.depth = depth;
|
|
71
179
|
}
|
|
72
|
-
|
|
180
|
+
computeVertices() {
|
|
73
181
|
const { width, height, depth } = this.params;
|
|
74
182
|
this.vertices = [
|
|
75
183
|
// front face
|
|
@@ -95,12 +203,12 @@ export class SquareGeometry extends Geometry {
|
|
|
95
203
|
triangleOrder = [0, 3, 1, 2];
|
|
96
204
|
params;
|
|
97
205
|
constructor(width, height) {
|
|
98
|
-
super(
|
|
206
|
+
super('strip');
|
|
99
207
|
this.params = {
|
|
100
208
|
width,
|
|
101
209
|
height
|
|
102
210
|
};
|
|
103
|
-
this.
|
|
211
|
+
this.computeVertices();
|
|
104
212
|
}
|
|
105
213
|
setWidth(width) {
|
|
106
214
|
this.params.width = width;
|
|
@@ -108,61 +216,60 @@ export class SquareGeometry extends Geometry {
|
|
|
108
216
|
setHeight(height) {
|
|
109
217
|
this.params.height = height;
|
|
110
218
|
}
|
|
111
|
-
|
|
219
|
+
computeVertices() {
|
|
112
220
|
this.vertices = [
|
|
113
|
-
vector3(-this.params.width, this.params.height),
|
|
114
|
-
vector3(this.params.width, this.params.height),
|
|
115
|
-
vector3(this.params.width, -this.params.height),
|
|
116
|
-
vector3(-this.params.width, -this.params.height)
|
|
221
|
+
vector3(-this.params.width / 2, this.params.height / 2),
|
|
222
|
+
vector3(this.params.width / 2, this.params.height / 2),
|
|
223
|
+
vector3(this.params.width / 2, -this.params.height / 2),
|
|
224
|
+
vector3(-this.params.width / 2, -this.params.height / 2)
|
|
117
225
|
];
|
|
118
226
|
}
|
|
119
227
|
}
|
|
120
228
|
export class BlankGeometry extends Geometry {
|
|
121
|
-
wireframeOrder = [];
|
|
122
|
-
triangleOrder = [];
|
|
123
229
|
params = {};
|
|
124
230
|
constructor() {
|
|
125
231
|
super();
|
|
126
232
|
}
|
|
127
|
-
recompute() { }
|
|
128
233
|
}
|
|
129
234
|
export class CircleGeometry extends Geometry {
|
|
130
|
-
wireframeOrder;
|
|
131
|
-
triangleOrder;
|
|
132
235
|
params;
|
|
133
236
|
constructor(radius, detail) {
|
|
134
|
-
super(
|
|
135
|
-
this.wireframeOrder = [];
|
|
136
|
-
this.triangleOrder = [];
|
|
237
|
+
super('strip');
|
|
137
238
|
this.params = { radius, detail };
|
|
138
|
-
this.
|
|
239
|
+
this.computeVertices();
|
|
240
|
+
}
|
|
241
|
+
setDetail(detail) {
|
|
242
|
+
this.params.detail = detail;
|
|
243
|
+
}
|
|
244
|
+
getDetail() {
|
|
245
|
+
return this.params.detail;
|
|
139
246
|
}
|
|
140
247
|
setRadius(radius) {
|
|
141
248
|
this.params.radius = radius;
|
|
142
249
|
}
|
|
143
|
-
|
|
250
|
+
getRadius() {
|
|
251
|
+
return this.params.radius;
|
|
252
|
+
}
|
|
253
|
+
computeVertices() {
|
|
144
254
|
const vertices = [];
|
|
145
255
|
const rotationInc = (Math.PI * 2) / this.params.detail;
|
|
146
256
|
for (let i = 0; i < this.params.detail; i++) {
|
|
147
257
|
const mat = matrix4();
|
|
148
|
-
mat4.rotateZ(mat, rotationInc * i, mat);
|
|
258
|
+
mat4.rotateZ(mat, -rotationInc * i + Math.PI / 2, mat);
|
|
149
259
|
const vec = vector3(this.params.radius);
|
|
150
260
|
vec3.transformMat4(vec, mat, vec);
|
|
151
261
|
vertices.push(vector3(vec[0], vec[1], vec[2]));
|
|
152
262
|
}
|
|
153
263
|
this.vertices = vertices;
|
|
154
|
-
this.
|
|
155
|
-
this.wireframeOrder = triangulateWireFrameOrder(this.vertices.length);
|
|
264
|
+
this.triangulate();
|
|
156
265
|
}
|
|
157
266
|
}
|
|
267
|
+
export class OutlineCircleGeometry {
|
|
268
|
+
}
|
|
158
269
|
export class Spline2dGeometry extends Geometry {
|
|
159
|
-
wireframeOrder;
|
|
160
|
-
triangleOrder;
|
|
161
270
|
params;
|
|
162
271
|
constructor(points, thickness, detail) {
|
|
163
|
-
super(
|
|
164
|
-
this.wireframeOrder = [];
|
|
165
|
-
this.triangleOrder = [];
|
|
272
|
+
super('strip');
|
|
166
273
|
this.params = {
|
|
167
274
|
points: points,
|
|
168
275
|
curves: [],
|
|
@@ -175,7 +282,7 @@ export class Spline2dGeometry extends Geometry {
|
|
|
175
282
|
curveVertexIndices: []
|
|
176
283
|
};
|
|
177
284
|
this.computeCurves();
|
|
178
|
-
this.
|
|
285
|
+
this.computeVertices();
|
|
179
286
|
}
|
|
180
287
|
updateInterpolationStart(start) {
|
|
181
288
|
this.params.interpolateStart = Math.min(1, Math.max(0, start));
|
|
@@ -238,7 +345,7 @@ export class Spline2dGeometry extends Geometry {
|
|
|
238
345
|
this.params.curves.push(curve);
|
|
239
346
|
}
|
|
240
347
|
}
|
|
241
|
-
|
|
348
|
+
computeVertices() {
|
|
242
349
|
this.vertices = [];
|
|
243
350
|
this.params.vertexInterpolations = [];
|
|
244
351
|
this.params.curveVertexIndices = [];
|
|
@@ -291,8 +398,7 @@ export class Spline2dGeometry extends Geometry {
|
|
|
291
398
|
}
|
|
292
399
|
}
|
|
293
400
|
this.vertices = verticesTop.concat(verticesBottom);
|
|
294
|
-
this.
|
|
295
|
-
this.wireframeOrder = triangulateWireFrameOrder(this.vertices.length);
|
|
401
|
+
this.triangulate();
|
|
296
402
|
}
|
|
297
403
|
}
|
|
298
404
|
export class Line2dGeometry extends Geometry {
|
|
@@ -300,17 +406,17 @@ export class Line2dGeometry extends Geometry {
|
|
|
300
406
|
triangleOrder = [0, 3, 1, 2];
|
|
301
407
|
params;
|
|
302
408
|
constructor(pos, to, thickness) {
|
|
303
|
-
super(
|
|
409
|
+
super('strip');
|
|
304
410
|
this.params = {
|
|
305
411
|
pos,
|
|
306
412
|
to,
|
|
307
413
|
thickness
|
|
308
414
|
};
|
|
309
415
|
}
|
|
310
|
-
|
|
416
|
+
computeVertices() {
|
|
311
417
|
const normal = vector2(-this.params.to[1], this.params.to[0]);
|
|
312
418
|
vec2.normalize(normal, normal);
|
|
313
|
-
vec2.scale(normal, this.params.thickness
|
|
419
|
+
vec2.scale(normal, this.params.thickness, normal);
|
|
314
420
|
this.vertices = [
|
|
315
421
|
vector3(-normal[0], -normal[1]),
|
|
316
422
|
vector3(normal[0], normal[1]),
|
|
@@ -324,14 +430,14 @@ export class Line3dGeometry extends Geometry {
|
|
|
324
430
|
triangleOrder = [0, 3, 1, 2];
|
|
325
431
|
params;
|
|
326
432
|
constructor(pos, to, thickness) {
|
|
327
|
-
super(
|
|
433
|
+
super('strip');
|
|
328
434
|
this.params = {
|
|
329
435
|
pos,
|
|
330
436
|
to,
|
|
331
437
|
thickness
|
|
332
438
|
};
|
|
333
439
|
}
|
|
334
|
-
|
|
440
|
+
computeVertices() {
|
|
335
441
|
const normal = vector2(-this.params.to[1], this.params.to[0]);
|
|
336
442
|
vec2.normalize(normal, normal);
|
|
337
443
|
vec2.scale(normal, this.params.thickness / 2, normal);
|
|
@@ -344,32 +450,25 @@ export class Line3dGeometry extends Geometry {
|
|
|
344
450
|
}
|
|
345
451
|
}
|
|
346
452
|
export class PolygonGeometry extends Geometry {
|
|
347
|
-
wireframeOrder;
|
|
348
|
-
triangleOrder;
|
|
349
453
|
params = {};
|
|
350
454
|
constructor(vertices) {
|
|
351
|
-
super(
|
|
352
|
-
this.wireframeOrder = [];
|
|
353
|
-
this.triangleOrder = [];
|
|
455
|
+
super('strip');
|
|
354
456
|
this.vertices = vertices;
|
|
355
|
-
this.
|
|
457
|
+
this.computeVertices();
|
|
356
458
|
}
|
|
357
|
-
|
|
358
|
-
this.
|
|
359
|
-
this.wireframeOrder = triangulateWireFrameOrder(this.vertices.length);
|
|
459
|
+
computeVertices() {
|
|
460
|
+
this.triangulate();
|
|
360
461
|
}
|
|
361
462
|
}
|
|
362
|
-
export class
|
|
363
|
-
wireframeOrder = [];
|
|
364
|
-
triangleOrder = [];
|
|
463
|
+
export class TraceLinesGeometry extends Geometry {
|
|
365
464
|
params;
|
|
366
465
|
constructor(maxLen) {
|
|
367
|
-
super(
|
|
466
|
+
super('strip');
|
|
368
467
|
this.params = {
|
|
369
468
|
maxLength: maxLen ?? null
|
|
370
469
|
};
|
|
371
470
|
}
|
|
372
|
-
|
|
471
|
+
triangulate() { }
|
|
373
472
|
getVertexCount() {
|
|
374
473
|
return this.vertices.length;
|
|
375
474
|
}
|
package/dist/globals.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/// <reference types="@webgpu/types" />
|
|
2
2
|
import { Shader } from './shaders.js';
|
|
3
|
+
import { Simulation } from './simulation.js';
|
|
4
|
+
import { Color } from './utils.js';
|
|
3
5
|
declare class Logger {
|
|
4
6
|
constructor();
|
|
5
7
|
private fmt;
|
|
@@ -10,8 +12,15 @@ declare class Logger {
|
|
|
10
12
|
}
|
|
11
13
|
export declare const logger: Logger;
|
|
12
14
|
export declare class GlobalInfo {
|
|
15
|
+
private canvas;
|
|
13
16
|
private device;
|
|
17
|
+
private defaultColor;
|
|
14
18
|
constructor();
|
|
19
|
+
setDefaultColor(color: Color): void;
|
|
20
|
+
getDefaultColor(): Color;
|
|
21
|
+
setCanvas(canvas: Simulation): void;
|
|
22
|
+
errorGetCanvas(): Simulation;
|
|
23
|
+
getCanvas(): Simulation | null;
|
|
15
24
|
setDevice(device: GPUDevice): void;
|
|
16
25
|
errorGetDevice(): GPUDevice;
|
|
17
26
|
getDevice(): GPUDevice | null;
|
package/dist/globals.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createPipeline } from './internalUtils.js';
|
|
2
|
+
import { color } from './utils.js';
|
|
2
3
|
class Logger {
|
|
3
4
|
constructor() { }
|
|
4
5
|
fmt(msg) {
|
|
@@ -19,9 +20,30 @@ class Logger {
|
|
|
19
20
|
}
|
|
20
21
|
export const logger = new Logger();
|
|
21
22
|
export class GlobalInfo {
|
|
23
|
+
canvas;
|
|
22
24
|
device;
|
|
25
|
+
defaultColor;
|
|
23
26
|
constructor() {
|
|
27
|
+
this.canvas = null;
|
|
24
28
|
this.device = null;
|
|
29
|
+
this.defaultColor = null;
|
|
30
|
+
}
|
|
31
|
+
setDefaultColor(color) {
|
|
32
|
+
this.defaultColor = color;
|
|
33
|
+
}
|
|
34
|
+
getDefaultColor() {
|
|
35
|
+
return this.defaultColor?.clone() ?? color();
|
|
36
|
+
}
|
|
37
|
+
setCanvas(canvas) {
|
|
38
|
+
this.canvas = canvas;
|
|
39
|
+
}
|
|
40
|
+
errorGetCanvas() {
|
|
41
|
+
if (!this.canvas)
|
|
42
|
+
throw logger.error('Canvas is null');
|
|
43
|
+
return this.canvas;
|
|
44
|
+
}
|
|
45
|
+
getCanvas() {
|
|
46
|
+
return this.canvas;
|
|
25
47
|
}
|
|
26
48
|
setDevice(device) {
|
|
27
49
|
this.device = device;
|
package/dist/graphics.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="@webgpu/types" />
|
|
2
2
|
import type { Vector2, Vector3, LerpFunc, Mat4 } from './types.js';
|
|
3
3
|
import { Vertex, Color } from './utils.js';
|
|
4
|
-
import { BlankGeometry, CircleGeometry, CubeGeometry, Geometry, Line2dGeometry, Line3dGeometry, PlaneGeometry, PolygonGeometry, Spline2dGeometry, SquareGeometry,
|
|
4
|
+
import { BlankGeometry, CircleGeometry, CubeGeometry, Geometry, Line2dGeometry, Line3dGeometry, PlaneGeometry, PolygonGeometry, Spline2dGeometry, SquareGeometry, TraceLinesGeometry as TraceLinesGeometry } from './geometry.js';
|
|
5
5
|
import { Float32ArrayCache } from './internalUtils.js';
|
|
6
6
|
import { Shader } from './shaders.js';
|
|
7
7
|
import { Material } from './materials.js';
|
|
@@ -26,9 +26,6 @@ export declare abstract class SimulationElement3d {
|
|
|
26
26
|
isInstanced: boolean;
|
|
27
27
|
is3d: boolean;
|
|
28
28
|
isEmpty: boolean;
|
|
29
|
-
/**
|
|
30
|
-
* @param pos - Expected to be adjusted to devicePixelRatio before reaching constructor
|
|
31
|
-
*/
|
|
32
29
|
constructor(pos: Vector3, rotation: Vector3, color?: Color);
|
|
33
30
|
getId(): string | null;
|
|
34
31
|
setId(id: string): void;
|
|
@@ -44,6 +41,11 @@ export declare abstract class SimulationElement3d {
|
|
|
44
41
|
getParent(): SimulationElement3d | null;
|
|
45
42
|
getCullMode(): GPUCullMode;
|
|
46
43
|
setCullMode(mode: GPUCullMode): void;
|
|
44
|
+
subDivideTo(limit: number): void;
|
|
45
|
+
setSubdivisions(divisions: number, vertexLimit?: number): void;
|
|
46
|
+
clearSubdivisions(): void;
|
|
47
|
+
setSubdivisionVertexLimit(limit: number): void;
|
|
48
|
+
clearSubdivisionVertexLimit(): void;
|
|
47
49
|
setCenterOffset(offset: Vector3): void;
|
|
48
50
|
getShader(): Shader;
|
|
49
51
|
setShader(shader: Shader): void;
|
|
@@ -62,17 +64,21 @@ export declare abstract class SimulationElement3d {
|
|
|
62
64
|
setWireframe(wireframe: boolean): void;
|
|
63
65
|
isWireframe(): boolean;
|
|
64
66
|
getMaterial(): Material;
|
|
67
|
+
getGeometry(): Geometry<object>;
|
|
68
|
+
getVertices(): Vector3[];
|
|
65
69
|
getRelativePos(): Vector3;
|
|
66
70
|
getPos(): Vector3;
|
|
67
71
|
getRotation(): Vector3;
|
|
68
72
|
getCenterOffset(): Vector3;
|
|
69
73
|
fill(newColor: Color, t?: number, f?: LerpFunc): Promise<void>;
|
|
70
|
-
move(amount: Vector3, t?: number, f?: LerpFunc
|
|
71
|
-
moveTo(pos: Vector3, t?: number, f?: LerpFunc
|
|
74
|
+
move(amount: Vector3, t?: number, f?: LerpFunc): Promise<void>;
|
|
75
|
+
moveTo(pos: Vector3, t?: number, f?: LerpFunc): Promise<void>;
|
|
72
76
|
rotateChildren(angle: Vector3): void;
|
|
73
77
|
rotate(amount: Vector3, t?: number, f?: LerpFunc): Promise<void>;
|
|
74
78
|
rotateTo(rot: Vector3, t?: number, f?: LerpFunc): Promise<void>;
|
|
79
|
+
animateVerticesFrom(vertices: Vector3[], t: number, f?: LerpFunc): Promise<void>;
|
|
75
80
|
getVertexCount(): number;
|
|
81
|
+
getTreeVertexCount(): number;
|
|
76
82
|
getIndexCount(): number;
|
|
77
83
|
writeBuffers(): void;
|
|
78
84
|
getVertexBuffer(): Float32Array;
|
|
@@ -117,12 +123,14 @@ export declare class Square extends SimulationElement2d {
|
|
|
117
123
|
}
|
|
118
124
|
export declare class Circle extends SimulationElement2d {
|
|
119
125
|
protected geometry: CircleGeometry;
|
|
120
|
-
private radius;
|
|
121
|
-
private detail;
|
|
122
126
|
constructor(pos: Vector2, radius: number, color?: Color, detail?: number);
|
|
127
|
+
setDetail(detail: number): void;
|
|
123
128
|
setRadius(num: number, t?: number, f?: LerpFunc): Promise<void>;
|
|
124
129
|
scale(amount: number, t?: number, f?: LerpFunc): Promise<void>;
|
|
125
130
|
}
|
|
131
|
+
export declare class OutlineCircle extends Circle {
|
|
132
|
+
constructor(pos: Vector2, radius: number, color?: Color, detail?: number);
|
|
133
|
+
}
|
|
126
134
|
export declare class Polygon extends SimulationElement2d {
|
|
127
135
|
protected geometry: PolygonGeometry;
|
|
128
136
|
constructor(pos: Vector2, vertices: Vertex[], color?: Color, rotation?: number);
|
|
@@ -227,7 +235,7 @@ export declare class Instance<T extends SimulationElement3d> extends SimulationE
|
|
|
227
235
|
getInstances(): Mat4[];
|
|
228
236
|
getNumInstances(): number;
|
|
229
237
|
getInstanceBuffer(): GPUBuffer;
|
|
230
|
-
|
|
238
|
+
getTreeVertexCount(): number;
|
|
231
239
|
getIndexCount(): number;
|
|
232
240
|
getGeometryTopology(): "list" | "strip";
|
|
233
241
|
getVertexBuffer(): Float32Array;
|
package/dist/graphics.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { vec3, mat4, vec2 } from 'wgpu-matrix';
|
|
2
|
-
import { cloneBuf, vector2, vector3,
|
|
3
|
-
import { BlankGeometry, CircleGeometry, CubeGeometry, Line2dGeometry, Line3dGeometry, PlaneGeometry, PolygonGeometry, Spline2dGeometry, SquareGeometry,
|
|
4
|
-
import { Float32ArrayCache, internalTransitionValues, posTo2dScreen
|
|
2
|
+
import { cloneBuf, vector2, vector3, vector2FromVector3, matrix4, vector3FromVector2, distance2d, interpolateColors } from './utils.js';
|
|
3
|
+
import { BlankGeometry, CircleGeometry, CubeGeometry, Line2dGeometry, Line3dGeometry, PlaneGeometry, PolygonGeometry, Spline2dGeometry, SquareGeometry, TraceLinesGeometry as TraceLinesGeometry } from './geometry.js';
|
|
4
|
+
import { Float32ArrayCache, internalTransitionValues, posTo2dScreen } from './internalUtils.js';
|
|
5
5
|
import { mat4ByteLength, modelProjMatOffset } from './constants.js';
|
|
6
6
|
import { MemoBuffer } from './buffers.js';
|
|
7
7
|
import { globalInfo, logger, pipelineCache } from './globals.js';
|
|
@@ -27,10 +27,7 @@ export class SimulationElement3d {
|
|
|
27
27
|
isInstanced = false;
|
|
28
28
|
is3d = true;
|
|
29
29
|
isEmpty = false;
|
|
30
|
-
|
|
31
|
-
* @param pos - Expected to be adjusted to devicePixelRatio before reaching constructor
|
|
32
|
-
*/
|
|
33
|
-
constructor(pos, rotation, color = new Color()) {
|
|
30
|
+
constructor(pos, rotation, color = globalInfo.getDefaultColor()) {
|
|
34
31
|
this.pos = pos;
|
|
35
32
|
this.centerOffset = vector3();
|
|
36
33
|
this.vertexCache = new Float32ArrayCache();
|
|
@@ -44,7 +41,7 @@ export class SimulationElement3d {
|
|
|
44
41
|
this.prevInfo = null;
|
|
45
42
|
this.shader = defaultShader;
|
|
46
43
|
this.material = new BasicMaterial(color);
|
|
47
|
-
this.cullMode = '
|
|
44
|
+
this.cullMode = 'none';
|
|
48
45
|
this.id = null;
|
|
49
46
|
}
|
|
50
47
|
getId() {
|
|
@@ -102,6 +99,32 @@ export class SimulationElement3d {
|
|
|
102
99
|
setCullMode(mode) {
|
|
103
100
|
this.cullMode = mode;
|
|
104
101
|
}
|
|
102
|
+
subDivideTo(limit) {
|
|
103
|
+
this.geometry.setSubdivisions(Infinity, limit);
|
|
104
|
+
this.vertexCache.updated();
|
|
105
|
+
this.geometry.compute();
|
|
106
|
+
}
|
|
107
|
+
/// may have unexpeced behavior for 3d shapes
|
|
108
|
+
setSubdivisions(divisions, vertexLimit) {
|
|
109
|
+
this.geometry.setSubdivisions(divisions, vertexLimit);
|
|
110
|
+
this.vertexCache.updated();
|
|
111
|
+
this.geometry.compute();
|
|
112
|
+
}
|
|
113
|
+
clearSubdivisions() {
|
|
114
|
+
this.geometry.clearSubdivisions();
|
|
115
|
+
this.vertexCache.updated();
|
|
116
|
+
this.geometry.compute();
|
|
117
|
+
}
|
|
118
|
+
setSubdivisionVertexLimit(limit) {
|
|
119
|
+
this.geometry.setSubdivisionVertexLimit(limit);
|
|
120
|
+
this.vertexCache.updated();
|
|
121
|
+
this.geometry.compute();
|
|
122
|
+
}
|
|
123
|
+
clearSubdivisionVertexLimit() {
|
|
124
|
+
this.geometry.clearSubdivisionVertexLimit();
|
|
125
|
+
this.vertexCache.updated();
|
|
126
|
+
this.geometry.compute();
|
|
127
|
+
}
|
|
105
128
|
setCenterOffset(offset) {
|
|
106
129
|
this.centerOffset = offset;
|
|
107
130
|
}
|
|
@@ -150,7 +173,8 @@ export class SimulationElement3d {
|
|
|
150
173
|
if (!this.parent)
|
|
151
174
|
return;
|
|
152
175
|
this.parent.mirrorParentTransforms3d(mat);
|
|
153
|
-
|
|
176
|
+
const pos = cloneBuf(this.parent.getRelativePos());
|
|
177
|
+
mat4.translate(mat, pos, mat);
|
|
154
178
|
const parentRot = this.parent.getRotation();
|
|
155
179
|
mat4.rotateZ(mat, parentRot[2], mat);
|
|
156
180
|
mat4.rotateY(mat, parentRot[1], mat);
|
|
@@ -161,7 +185,8 @@ export class SimulationElement3d {
|
|
|
161
185
|
if (this.parent) {
|
|
162
186
|
this.mirrorParentTransforms3d(this.modelMatrix);
|
|
163
187
|
}
|
|
164
|
-
|
|
188
|
+
const pos = cloneBuf(this.pos);
|
|
189
|
+
mat4.translate(this.modelMatrix, pos, this.modelMatrix);
|
|
165
190
|
mat4.rotateZ(this.modelMatrix, this.rotation[2], this.modelMatrix);
|
|
166
191
|
mat4.rotateY(this.modelMatrix, this.rotation[1], this.modelMatrix);
|
|
167
192
|
mat4.rotateX(this.modelMatrix, this.rotation[0], this.modelMatrix);
|
|
@@ -176,7 +201,8 @@ export class SimulationElement3d {
|
|
|
176
201
|
this.parent.mirrorParentTransforms2d(mat);
|
|
177
202
|
const parentRot = this.parent.getRotation();
|
|
178
203
|
mat4.rotateZ(mat, parentRot[2], mat);
|
|
179
|
-
|
|
204
|
+
const pos = cloneBuf(this.pos);
|
|
205
|
+
mat4.translate(mat, pos, mat);
|
|
180
206
|
}
|
|
181
207
|
updateModelMatrix2d() {
|
|
182
208
|
mat4.identity(this.modelMatrix);
|
|
@@ -205,6 +231,12 @@ export class SimulationElement3d {
|
|
|
205
231
|
getMaterial() {
|
|
206
232
|
return this.material;
|
|
207
233
|
}
|
|
234
|
+
getGeometry() {
|
|
235
|
+
return this.geometry;
|
|
236
|
+
}
|
|
237
|
+
getVertices() {
|
|
238
|
+
return this.geometry.getVertices();
|
|
239
|
+
}
|
|
208
240
|
getRelativePos() {
|
|
209
241
|
return this.pos;
|
|
210
242
|
}
|
|
@@ -235,10 +267,8 @@ export class SimulationElement3d {
|
|
|
235
267
|
this.vertexCache.updated();
|
|
236
268
|
}, t, f);
|
|
237
269
|
}
|
|
238
|
-
move(amount, t = 0, f
|
|
270
|
+
move(amount, t = 0, f) {
|
|
239
271
|
const tempAmount = cloneBuf(amount);
|
|
240
|
-
if (!fromDevicePixelRatio)
|
|
241
|
-
vector3ToPixelRatio(tempAmount);
|
|
242
272
|
const finalPos = cloneBuf(this.pos);
|
|
243
273
|
vec3.add(finalPos, tempAmount, finalPos);
|
|
244
274
|
return internalTransitionValues((p) => {
|
|
@@ -249,10 +279,8 @@ export class SimulationElement3d {
|
|
|
249
279
|
this.pos = finalPos;
|
|
250
280
|
}, t, f);
|
|
251
281
|
}
|
|
252
|
-
moveTo(pos, t = 0, f
|
|
282
|
+
moveTo(pos, t = 0, f) {
|
|
253
283
|
const tempPos = cloneBuf(pos);
|
|
254
|
-
if (!fromDevicePixelRatio)
|
|
255
|
-
vector3ToPixelRatio(tempPos);
|
|
256
284
|
const diff = vector3();
|
|
257
285
|
vec3.sub(tempPos, this.pos, diff);
|
|
258
286
|
return internalTransitionValues((p) => {
|
|
@@ -293,13 +321,22 @@ export class SimulationElement3d {
|
|
|
293
321
|
this.rotation = cloneBuf(rot);
|
|
294
322
|
}, t, f);
|
|
295
323
|
}
|
|
324
|
+
animateVerticesFrom(vertices, t, f) {
|
|
325
|
+
if (this.getVertexCount() !== vertices.length) {
|
|
326
|
+
throw logger.error(`Expected vertex array of same length, found ${this.getVertexCount()}::${vertices.length}`);
|
|
327
|
+
}
|
|
328
|
+
return this.geometry.animateFrom(vertices, t, f);
|
|
329
|
+
}
|
|
296
330
|
getVertexCount() {
|
|
331
|
+
return this.getVertices().length;
|
|
332
|
+
}
|
|
333
|
+
getTreeVertexCount() {
|
|
297
334
|
if (this.vertexCache.shouldUpdate()) {
|
|
298
|
-
this.geometry.
|
|
335
|
+
this.geometry.compute();
|
|
299
336
|
}
|
|
300
337
|
let vertexCount = this.geometry.getIndexes(this.isWireframe()).length;
|
|
301
338
|
for (let i = 0; i < this.children.length; i++) {
|
|
302
|
-
vertexCount += this.children[i].
|
|
339
|
+
vertexCount += this.children[i].getTreeVertexCount();
|
|
303
340
|
}
|
|
304
341
|
return vertexCount;
|
|
305
342
|
}
|
|
@@ -314,12 +351,11 @@ export class SimulationElement3d {
|
|
|
314
351
|
this.shader.writeBuffers(this);
|
|
315
352
|
}
|
|
316
353
|
getVertexBuffer() {
|
|
317
|
-
if (this.vertexCache.shouldUpdate()) {
|
|
318
|
-
this.geometry.
|
|
354
|
+
if (this.vertexCache.shouldUpdate() || this.geometry.hasUpdated()) {
|
|
355
|
+
this.geometry.compute();
|
|
319
356
|
const vertices = this.geometry.getVertices();
|
|
320
357
|
const stride = this.shader.getBufferLength();
|
|
321
358
|
const vertexBuffer = new Float32Array(vertices.length * stride);
|
|
322
|
-
// const shader = this.isWireframe() ? defaultShader : this.shader;
|
|
323
359
|
for (let i = 0; i < vertices.length; i++) {
|
|
324
360
|
this.shader.setVertexInfo(this, vertexBuffer, vertices[i], i, i * stride);
|
|
325
361
|
}
|
|
@@ -349,7 +385,6 @@ export class SimulationElement2d extends SimulationElement3d {
|
|
|
349
385
|
is3d = false;
|
|
350
386
|
constructor(pos, rotation = vector3(), color) {
|
|
351
387
|
super(vector3FromVector2(pos), rotation, color);
|
|
352
|
-
vector3ToPixelRatio(this.pos);
|
|
353
388
|
}
|
|
354
389
|
rotate2d(amount, t = 0, f) {
|
|
355
390
|
return super.rotate(vector3(0, 0, amount), t, f);
|
|
@@ -369,8 +404,7 @@ export class Plane extends SimulationElement3d {
|
|
|
369
404
|
super(pos, rotation, color);
|
|
370
405
|
this.rotation = rotation;
|
|
371
406
|
this.points = points;
|
|
372
|
-
this.geometry = new PlaneGeometry(points);
|
|
373
|
-
this.cullMode = 'none';
|
|
407
|
+
this.geometry = new PlaneGeometry(points.map((vert) => vert.getPos()));
|
|
374
408
|
}
|
|
375
409
|
setPoints(newPoints) {
|
|
376
410
|
this.points = newPoints;
|
|
@@ -387,8 +421,8 @@ export class Square extends SimulationElement2d {
|
|
|
387
421
|
*/
|
|
388
422
|
constructor(pos, width, height, color, rotation) {
|
|
389
423
|
super(pos, vector3(0, 0, rotation), color);
|
|
390
|
-
this.width = width
|
|
391
|
-
this.height = height
|
|
424
|
+
this.width = width;
|
|
425
|
+
this.height = height;
|
|
392
426
|
this.geometry = new SquareGeometry(this.width, this.height);
|
|
393
427
|
}
|
|
394
428
|
getWidth() {
|
|
@@ -443,7 +477,6 @@ export class Square extends SimulationElement2d {
|
|
|
443
477
|
}, t, f);
|
|
444
478
|
}
|
|
445
479
|
setWidth(num, t = 0, f) {
|
|
446
|
-
num *= devicePixelRatio;
|
|
447
480
|
const diffWidth = num - this.width;
|
|
448
481
|
return internalTransitionValues((p) => {
|
|
449
482
|
this.width += diffWidth * p;
|
|
@@ -456,7 +489,6 @@ export class Square extends SimulationElement2d {
|
|
|
456
489
|
}, t, f);
|
|
457
490
|
}
|
|
458
491
|
setHeight(num, t = 0, f) {
|
|
459
|
-
num *= devicePixelRatio;
|
|
460
492
|
const diffHeight = num - this.height;
|
|
461
493
|
return internalTransitionValues((p) => {
|
|
462
494
|
this.height += diffHeight * p;
|
|
@@ -471,51 +503,57 @@ export class Square extends SimulationElement2d {
|
|
|
471
503
|
}
|
|
472
504
|
export class Circle extends SimulationElement2d {
|
|
473
505
|
geometry;
|
|
474
|
-
radius;
|
|
475
|
-
detail;
|
|
476
506
|
constructor(pos, radius, color, detail = 50) {
|
|
477
507
|
super(pos, vector3(), color);
|
|
478
|
-
this.
|
|
479
|
-
|
|
480
|
-
|
|
508
|
+
this.geometry = new CircleGeometry(radius, detail);
|
|
509
|
+
}
|
|
510
|
+
setDetail(detail) {
|
|
511
|
+
this.geometry.setDetail(detail);
|
|
481
512
|
}
|
|
482
513
|
setRadius(num, t = 0, f) {
|
|
483
|
-
|
|
484
|
-
const diff = num -
|
|
514
|
+
let radius = this.geometry.getRadius();
|
|
515
|
+
const diff = num - radius;
|
|
485
516
|
return internalTransitionValues((p) => {
|
|
486
|
-
|
|
487
|
-
this.geometry.setRadius(
|
|
517
|
+
radius += diff * p;
|
|
518
|
+
this.geometry.setRadius(radius);
|
|
488
519
|
this.vertexCache.updated();
|
|
489
520
|
}, () => {
|
|
490
|
-
|
|
491
|
-
this.geometry.setRadius(
|
|
521
|
+
radius = num;
|
|
522
|
+
this.geometry.setRadius(radius);
|
|
492
523
|
this.vertexCache.updated();
|
|
493
524
|
}, t, f);
|
|
494
525
|
}
|
|
495
526
|
scale(amount, t = 0, f) {
|
|
496
|
-
|
|
497
|
-
const
|
|
527
|
+
let radius = this.geometry.getRadius();
|
|
528
|
+
const finalRadius = radius * amount;
|
|
529
|
+
const diff = finalRadius - radius;
|
|
498
530
|
return internalTransitionValues((p) => {
|
|
499
|
-
|
|
500
|
-
this.geometry.setRadius(
|
|
531
|
+
radius += diff * p;
|
|
532
|
+
this.geometry.setRadius(radius);
|
|
501
533
|
this.vertexCache.updated();
|
|
502
534
|
}, () => {
|
|
503
|
-
|
|
504
|
-
this.geometry.setRadius(
|
|
535
|
+
radius = finalRadius;
|
|
536
|
+
this.geometry.setRadius(radius);
|
|
505
537
|
this.vertexCache.updated();
|
|
506
538
|
}, t, f);
|
|
507
539
|
}
|
|
508
540
|
}
|
|
541
|
+
export class OutlineCircle extends Circle {
|
|
542
|
+
constructor(pos, radius, color, detail) {
|
|
543
|
+
super(pos, radius, color, detail);
|
|
544
|
+
// this.geometry = new OutlineCircleGeometry();
|
|
545
|
+
}
|
|
546
|
+
}
|
|
509
547
|
export class Polygon extends SimulationElement2d {
|
|
510
548
|
geometry;
|
|
511
549
|
constructor(pos, vertices, color, rotation) {
|
|
512
550
|
super(pos, vector3(0, 0, rotation), color);
|
|
513
551
|
const vectors = vertices.map((vert) => vert.getPos());
|
|
552
|
+
const prevColor = this.getColor();
|
|
514
553
|
this.shader = vertexColorShader;
|
|
515
554
|
this.geometry = new PolygonGeometry(vectors);
|
|
516
555
|
this.material = new VertexColorMaterial();
|
|
517
|
-
|
|
518
|
-
this.material.setColor(color);
|
|
556
|
+
this.material.setColor(prevColor);
|
|
519
557
|
const colors = vertices.map((vert) => vert.getColor() ?? this.material.getColor());
|
|
520
558
|
this.material.setVertexColors(colors);
|
|
521
559
|
}
|
|
@@ -592,7 +630,6 @@ export class Line3d extends SimulationElement3d {
|
|
|
592
630
|
super(pos.getPos(), vector3(), to.getColor() ?? undefined);
|
|
593
631
|
this.thickness = thickness;
|
|
594
632
|
this.to = to.getPos();
|
|
595
|
-
vec3.scale(this.to, devicePixelRatio, this.to);
|
|
596
633
|
vec3.sub(this.to, this.pos, this.to);
|
|
597
634
|
this.geometry = new Line3dGeometry(this.pos, this.to, this.thickness);
|
|
598
635
|
}
|
|
@@ -621,7 +658,7 @@ export class Line2d extends SimulationElement2d {
|
|
|
621
658
|
thickness;
|
|
622
659
|
constructor(from, to, thickness = 1) {
|
|
623
660
|
super(vector2FromVector3(from.getPos()), vector3(), from.getColor() ?? undefined);
|
|
624
|
-
this.thickness = thickness
|
|
661
|
+
this.thickness = thickness;
|
|
625
662
|
this.to = to.getPos();
|
|
626
663
|
vec2.sub(this.to, this.pos, this.to);
|
|
627
664
|
this.geometry = new Line2dGeometry(this.pos, this.to, this.thickness);
|
|
@@ -631,8 +668,6 @@ export class Line2d extends SimulationElement2d {
|
|
|
631
668
|
}
|
|
632
669
|
setEnd(pos, t = 0, f) {
|
|
633
670
|
const tempPos = cloneBuf(pos);
|
|
634
|
-
vector3ToPixelRatio(tempPos);
|
|
635
|
-
// vec2.sub(tempPos, this.getPos(), tempPos);
|
|
636
671
|
const diff = vector3();
|
|
637
672
|
vec2.sub(tempPos, this.to, diff);
|
|
638
673
|
return internalTransitionValues((p) => {
|
|
@@ -660,7 +695,6 @@ export class Cube extends SimulationElement3d {
|
|
|
660
695
|
this.geometry = new CubeGeometry(this.width, this.height, this.depth);
|
|
661
696
|
}
|
|
662
697
|
setWidth(width, t = 0, f) {
|
|
663
|
-
width *= devicePixelRatio;
|
|
664
698
|
const diff = width - this.width;
|
|
665
699
|
return internalTransitionValues((p) => {
|
|
666
700
|
this.width += diff * p;
|
|
@@ -673,7 +707,6 @@ export class Cube extends SimulationElement3d {
|
|
|
673
707
|
}, t, f);
|
|
674
708
|
}
|
|
675
709
|
setHeight(height, t = 0, f) {
|
|
676
|
-
height *= devicePixelRatio;
|
|
677
710
|
const diff = height - this.width;
|
|
678
711
|
return internalTransitionValues((p) => {
|
|
679
712
|
this.height += diff * p;
|
|
@@ -686,7 +719,6 @@ export class Cube extends SimulationElement3d {
|
|
|
686
719
|
}, t, f);
|
|
687
720
|
}
|
|
688
721
|
setDepth(depth, t = 0, f) {
|
|
689
|
-
depth *= devicePixelRatio;
|
|
690
722
|
const diff = depth - this.width;
|
|
691
723
|
return internalTransitionValues((p) => {
|
|
692
724
|
this.depth += diff * p;
|
|
@@ -872,17 +904,17 @@ export class Spline2d extends SimulationElement2d {
|
|
|
872
904
|
interpolateStart;
|
|
873
905
|
interpolateLimit;
|
|
874
906
|
length;
|
|
875
|
-
constructor(pos, points, thickness =
|
|
907
|
+
constructor(pos, points, thickness = 1, detail = 40) {
|
|
876
908
|
const tempPos = vector2FromVector3(pos.getPos());
|
|
877
909
|
super(tempPos, vector3(), pos.getColor() ?? undefined);
|
|
878
|
-
this.thickness = thickness
|
|
910
|
+
this.thickness = thickness;
|
|
879
911
|
this.detail = detail;
|
|
880
912
|
this.interpolateStart = 0;
|
|
881
913
|
this.interpolateLimit = 1;
|
|
882
914
|
this.length = 0;
|
|
883
915
|
this.geometry = new Spline2dGeometry(points, this.thickness, this.detail);
|
|
884
916
|
this.material = new VertexColorMaterial();
|
|
885
|
-
this.material.setColor(pos.getColor() ??
|
|
917
|
+
this.material.setColor(pos.getColor() ?? globalInfo.getDefaultColor());
|
|
886
918
|
this.setVertexColors();
|
|
887
919
|
this.shader = vertexColorShader;
|
|
888
920
|
this.estimateLength();
|
|
@@ -974,7 +1006,6 @@ export class Spline2d extends SimulationElement2d {
|
|
|
974
1006
|
this.vertexCache.updated();
|
|
975
1007
|
}
|
|
976
1008
|
setThickness(thickness, t = 0, f) {
|
|
977
|
-
thickness *= devicePixelRatio;
|
|
978
1009
|
const diff = thickness - this.thickness;
|
|
979
1010
|
return internalTransitionValues((p) => {
|
|
980
1011
|
this.thickness += diff * p;
|
|
@@ -1068,7 +1099,6 @@ export class Instance extends SimulationElement3d {
|
|
|
1068
1099
|
const device = globalInfo.getDevice();
|
|
1069
1100
|
if (!device)
|
|
1070
1101
|
return;
|
|
1071
|
-
// this.allocBuffer(size);
|
|
1072
1102
|
const gpuBuffer = this.matrixBuffer.getBuffer();
|
|
1073
1103
|
const buf = new Float32Array(transformation);
|
|
1074
1104
|
device.queue.writeBuffer(gpuBuffer, instance * mat4ByteLength, buf.buffer, buf.byteOffset, buf.byteLength);
|
|
@@ -1099,8 +1129,8 @@ export class Instance extends SimulationElement3d {
|
|
|
1099
1129
|
}
|
|
1100
1130
|
return this.matrixBuffer.getBuffer();
|
|
1101
1131
|
}
|
|
1102
|
-
|
|
1103
|
-
return this.obj.
|
|
1132
|
+
getTreeVertexCount() {
|
|
1133
|
+
return this.obj.getTreeVertexCount();
|
|
1104
1134
|
}
|
|
1105
1135
|
getIndexCount() {
|
|
1106
1136
|
return this.obj.getIndexCount();
|
package/dist/internalUtils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="@webgpu/types" />
|
|
2
|
-
import { Mat4,
|
|
2
|
+
import { Mat4, Vector3 } from './types.js';
|
|
3
3
|
import { Shader } from './shaders.js';
|
|
4
4
|
import { SimulationElement3d } from './graphics.js';
|
|
5
5
|
export declare class Float32ArrayCache {
|
|
@@ -29,8 +29,6 @@ export declare const buildMultisampleTexture: (device: GPUDevice, ctx: GPUCanvas
|
|
|
29
29
|
export declare function lossyTriangulate<T>(vertices: T[]): (readonly [T, T, T])[];
|
|
30
30
|
export declare function lossyTriangulateStrip<T>(vertices: T[]): T[];
|
|
31
31
|
export declare function createIndexArray(length: number): number[];
|
|
32
|
-
export declare function vector3ToPixelRatio(vec: Vector3): void;
|
|
33
|
-
export declare function vector2ToPixelRatio(vec: Vector2): void;
|
|
34
32
|
export declare function triangulateWireFrameOrder(len: number): number[];
|
|
35
33
|
export declare function getVertexAndIndexSize(scene: SimulationElement3d[]): readonly [number, number];
|
|
36
34
|
export declare function internalTransitionValues(onFrame: (deltaT: number, t: number, total: number) => void, adjustment: () => void, transitionLength: number, func?: (n: number) => number): Promise<void>;
|
package/dist/internalUtils.js
CHANGED
|
@@ -141,15 +141,6 @@ export function createIndexArray(length) {
|
|
|
141
141
|
.fill(0)
|
|
142
142
|
.map((_, index) => index);
|
|
143
143
|
}
|
|
144
|
-
export function vector3ToPixelRatio(vec) {
|
|
145
|
-
vec[0] *= devicePixelRatio;
|
|
146
|
-
vec[1] *= devicePixelRatio;
|
|
147
|
-
vec[2] *= devicePixelRatio;
|
|
148
|
-
}
|
|
149
|
-
export function vector2ToPixelRatio(vec) {
|
|
150
|
-
vec[0] *= devicePixelRatio;
|
|
151
|
-
vec[1] *= devicePixelRatio;
|
|
152
|
-
}
|
|
153
144
|
export function triangulateWireFrameOrder(len) {
|
|
154
145
|
const order = Array(len)
|
|
155
146
|
.fill(0)
|
|
@@ -168,7 +159,7 @@ export function getVertexAndIndexSize(scene) {
|
|
|
168
159
|
let indexSize = 0;
|
|
169
160
|
for (let i = 0; i < scene.length; i++) {
|
|
170
161
|
const obj = scene[i];
|
|
171
|
-
vertexSize += obj.
|
|
162
|
+
vertexSize += obj.getTreeVertexCount() * obj.getShader().getBufferLength();
|
|
172
163
|
indexSize += obj.getIndexCount();
|
|
173
164
|
}
|
|
174
165
|
return [vertexSize, indexSize];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/// <reference types="@webgpu/types" />
|
|
2
|
+
import { SimulationElement3d } from './graphics.js';
|
|
3
|
+
import { Shader } from './shaders.js';
|
|
4
|
+
export declare function createBindGroup(shader: Shader, bindGroupIndex: number, buffers: GPUBuffer[]): GPUBindGroup;
|
|
5
|
+
export declare function writeUniformWorldMatrix(el: SimulationElement3d): void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { worldProjMatOffset } from './constants.js';
|
|
2
|
+
import { globalInfo } from './globals.js';
|
|
3
|
+
import { orthogonalMatrix, worldProjectionMatrix } from './simulation.js';
|
|
4
|
+
export function createBindGroup(shader, bindGroupIndex, buffers) {
|
|
5
|
+
const device = globalInfo.errorGetDevice();
|
|
6
|
+
const layout = shader.getBindGroupLayouts()[bindGroupIndex];
|
|
7
|
+
return device.createBindGroup({
|
|
8
|
+
layout: layout,
|
|
9
|
+
entries: buffers.map((buffer, index) => ({
|
|
10
|
+
binding: index,
|
|
11
|
+
resource: {
|
|
12
|
+
buffer
|
|
13
|
+
}
|
|
14
|
+
}))
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export function writeUniformWorldMatrix(el) {
|
|
18
|
+
const device = globalInfo.errorGetDevice();
|
|
19
|
+
const uniformBuffer = el.getUniformBuffer();
|
|
20
|
+
const projBuf = el.is3d ? worldProjectionMatrix : orthogonalMatrix;
|
|
21
|
+
device.queue.writeBuffer(uniformBuffer, worldProjMatOffset, projBuf.buffer, projBuf.byteOffset, projBuf.byteLength);
|
|
22
|
+
}
|
package/dist/simulation.d.ts
CHANGED
|
@@ -50,6 +50,8 @@ export declare class Simulation extends Settings {
|
|
|
50
50
|
start(): void;
|
|
51
51
|
stop(): void;
|
|
52
52
|
setBackground(color: Color): void;
|
|
53
|
+
setDefaultColor(color: Color): void;
|
|
54
|
+
getDefaultColor(): Color;
|
|
53
55
|
getScene(): SimulationElement3d[];
|
|
54
56
|
private render;
|
|
55
57
|
private renderScene;
|
package/dist/simulation.js
CHANGED
|
@@ -167,10 +167,11 @@ export class Simulation extends Settings {
|
|
|
167
167
|
}
|
|
168
168
|
else
|
|
169
169
|
throw logger.error(`Canvas ref/id provided is invalid`);
|
|
170
|
-
|
|
170
|
+
globalInfo.setCanvas(this);
|
|
171
171
|
if (sceneCamera) {
|
|
172
172
|
camera = sceneCamera;
|
|
173
173
|
}
|
|
174
|
+
const parent = this.canvasRef.parentElement;
|
|
174
175
|
if (parent === null)
|
|
175
176
|
throw logger.error('Canvas parent is null');
|
|
176
177
|
this.resizeEvents = [];
|
|
@@ -199,10 +200,10 @@ export class Simulation extends Settings {
|
|
|
199
200
|
this.resizeEvents.push(cb);
|
|
200
201
|
}
|
|
201
202
|
getWidth() {
|
|
202
|
-
return
|
|
203
|
+
return this.canvasRef?.width || 0;
|
|
203
204
|
}
|
|
204
205
|
getHeight() {
|
|
205
|
-
return
|
|
206
|
+
return this.canvasRef?.height || 0;
|
|
206
207
|
}
|
|
207
208
|
add(el, id) {
|
|
208
209
|
addToScene(this.scene, el, id);
|
|
@@ -265,6 +266,12 @@ export class Simulation extends Settings {
|
|
|
265
266
|
setBackground(color) {
|
|
266
267
|
this.bgColor = color;
|
|
267
268
|
}
|
|
269
|
+
setDefaultColor(color) {
|
|
270
|
+
globalInfo.setDefaultColor(color);
|
|
271
|
+
}
|
|
272
|
+
getDefaultColor() {
|
|
273
|
+
return globalInfo.getDefaultColor();
|
|
274
|
+
}
|
|
268
275
|
getScene() {
|
|
269
276
|
return this.scene;
|
|
270
277
|
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="@webgpu/types" />
|
|
2
2
|
import { SimulationElement3d, SplinePoint2d } from './graphics.js';
|
|
3
|
-
import { FloatArray, Mat4, Vector2, Vector2m, Vector3, Vector3m, Vector4 } from './types.js';
|
|
3
|
+
import { FloatArray, LerpFunc, Mat4, Vector2, Vector2m, Vector3, Vector3m, Vector4 } from './types.js';
|
|
4
4
|
import { Shader } from './shaders.js';
|
|
5
5
|
export declare class Color {
|
|
6
6
|
r: number;
|
|
@@ -81,6 +81,10 @@ export declare function waitFor(t: number): Promise<unknown>;
|
|
|
81
81
|
export declare function distance2d(vector1: Vector2m, vector2: Vector2m): number;
|
|
82
82
|
export declare function distance3d(vector1: Vector3m, vector2: Vector3m): number;
|
|
83
83
|
export declare function interpolateColors(colors: Color[], t: number): Color;
|
|
84
|
+
export declare function vectorsToVertex(vectors: Vector3[]): Vertex[];
|
|
85
|
+
export declare function cloneVectors(vectors: Vector3[]): Vector3[];
|
|
84
86
|
export declare function createBindGroup(shader: Shader, bindGroupIndex: number, buffers: GPUBuffer[]): GPUBindGroup;
|
|
85
87
|
export declare function writeUniformWorldMatrix(el: SimulationElement3d): void;
|
|
88
|
+
export declare function transform(from: SimulationElement3d, to: SimulationElement3d, t: number, f?: LerpFunc): Promise<void>;
|
|
89
|
+
export declare function defaultColor(): Color;
|
|
86
90
|
export {};
|
package/dist/utils.js
CHANGED
|
@@ -233,16 +233,11 @@ export function colorf(val, a) {
|
|
|
233
233
|
return color(val, val, val, a);
|
|
234
234
|
}
|
|
235
235
|
export function splinePoint2d(end, control1, control2, detail) {
|
|
236
|
-
vec2.scale(control1, devicePixelRatio, control1);
|
|
237
|
-
vec2.scale(control2, devicePixelRatio, control2);
|
|
238
|
-
vec2.scale(end.getPos(), devicePixelRatio, end.getPos());
|
|
239
236
|
const rawControls = [cloneBuf(control1), cloneBuf(control2)];
|
|
240
237
|
vec2.add(end.getPos(), control2, control2);
|
|
241
238
|
return new SplinePoint2d(null, end, control1, control2, rawControls, detail);
|
|
242
239
|
}
|
|
243
240
|
export function continuousSplinePoint2d(end, control, detail) {
|
|
244
|
-
vec2.scale(control, devicePixelRatio, control);
|
|
245
|
-
vec2.scale(end.getPos(), devicePixelRatio, end.getPos());
|
|
246
241
|
const rawControls = [vector2(), cloneBuf(control)];
|
|
247
242
|
vec2.add(end.getPos(), control, control);
|
|
248
243
|
return new SplinePoint2d(null, end, null, control, rawControls, detail);
|
|
@@ -286,6 +281,12 @@ export function interpolateColors(colors, t) {
|
|
|
286
281
|
res.a += diff.a;
|
|
287
282
|
return res;
|
|
288
283
|
}
|
|
284
|
+
export function vectorsToVertex(vectors) {
|
|
285
|
+
return vectors.map((vec) => vertex(...vec));
|
|
286
|
+
}
|
|
287
|
+
export function cloneVectors(vectors) {
|
|
288
|
+
return vectors.map((vec) => cloneBuf(vec));
|
|
289
|
+
}
|
|
289
290
|
export function createBindGroup(shader, bindGroupIndex, buffers) {
|
|
290
291
|
const device = globalInfo.errorGetDevice();
|
|
291
292
|
const layout = shader.getBindGroupLayouts()[bindGroupIndex];
|
|
@@ -305,3 +306,29 @@ export function writeUniformWorldMatrix(el) {
|
|
|
305
306
|
const projBuf = el.is3d ? worldProjectionMatrix : orthogonalMatrix;
|
|
306
307
|
device.queue.writeBuffer(uniformBuffer, worldProjMatOffset, projBuf.buffer, projBuf.byteOffset, projBuf.byteLength);
|
|
307
308
|
}
|
|
309
|
+
/// may have unexpected position behavior for nested elements, or elements with a geometry with a set triangle order
|
|
310
|
+
export function transform(from, to, t, f) {
|
|
311
|
+
const canvas = globalInfo.errorGetCanvas();
|
|
312
|
+
const fromVertCount = from.getVertexCount();
|
|
313
|
+
const toVertCount = to.getVertexCount();
|
|
314
|
+
if (fromVertCount < toVertCount) {
|
|
315
|
+
from.subDivideTo(toVertCount);
|
|
316
|
+
}
|
|
317
|
+
else if (fromVertCount > toVertCount) {
|
|
318
|
+
to.subDivideTo(fromVertCount);
|
|
319
|
+
}
|
|
320
|
+
canvas.remove(from);
|
|
321
|
+
canvas.add(to);
|
|
322
|
+
const fromVerts = from.getVertices();
|
|
323
|
+
return (async () => {
|
|
324
|
+
const prevPos = to.getPos();
|
|
325
|
+
to.moveTo(from.getPos());
|
|
326
|
+
to.moveTo(prevPos, t, f);
|
|
327
|
+
await to.animateVerticesFrom(fromVerts, t, f);
|
|
328
|
+
from.clearSubdivisions();
|
|
329
|
+
to.clearSubdivisions();
|
|
330
|
+
})();
|
|
331
|
+
}
|
|
332
|
+
export function defaultColor() {
|
|
333
|
+
return globalInfo.getDefaultColor();
|
|
334
|
+
}
|