@woosh/meep-engine 2.43.20 → 2.43.22
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/core/collection/HashMap.d.ts +2 -2
- package/core/collection/HashMap.js +22 -2
- package/core/geom/3d/morton/mortonEncode_magicbits.js +18 -0
- package/core/geom/3d/topology/struct/BinaryElementPool.js +292 -0
- package/core/geom/3d/topology/struct/BinaryElementPool.spec.js +36 -0
- package/core/geom/3d/topology/struct/BinaryTopology.js +454 -66
- package/core/geom/3d/topology/struct/BinaryTopology.spec.js +16 -0
- package/core/geom/3d/topology/struct/TopoEdge.js +4 -0
- package/core/geom/3d/topology/struct/TopoMesh.js +25 -0
- package/core/geom/3d/topology/struct/TopoTriangle.js +4 -0
- package/core/geom/3d/topology/struct/TopoVertex.js +8 -0
- package/core/geom/3d/topology/struct/bt_index_geometry_to_topology.js +329 -0
- package/core/geom/3d/topology/struct/bt_index_geometry_to_topology.spec.js +26 -0
- package/core/geom/3d/topology/struct/prototypeBinaryTopology.js +55 -0
- package/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.js +12 -3
- package/engine/graphics/micron/format/MicronGeometryPatch.d.ts +1 -1
- package/engine/graphics/micron/format/MicronGeometryPatch.js +2 -1
- package/engine/graphics/micron/plugin/GLTFAssetTransformer.js +89 -64
- package/engine/graphics/sh3/path_tracer/PathTracedMesh.js +4 -0
- package/engine/graphics/sh3/path_tracer/PathTracer.js +90 -36
- package/engine/graphics/sh3/path_tracer/getBiasedNormalSample.js +1 -1
- package/engine/graphics/sh3/path_tracer/prototypePathTracer.js +44 -10
- package/engine/graphics/sh3/path_tracer/ray_hit_apply_transform.js +28 -13
- package/engine/save/storage/IndexedDBStorage.js +1 -0
- package/package.json +1 -1
|
@@ -1,112 +1,500 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BinaryElementPool } from "./BinaryElementPool.js";
|
|
2
|
+
import { array_copy } from "../../../../collection/array/copyArray.js";
|
|
3
|
+
import { assert } from "../../../../assert.js";
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Byte size of FLOAT_32
|
|
7
|
+
* @readonly
|
|
8
|
+
* @type {number}
|
|
9
|
+
*/
|
|
10
|
+
const FLOAT_32_SIZE = 4;
|
|
4
11
|
|
|
5
12
|
/**
|
|
13
|
+
* Byte size of UINT_32
|
|
6
14
|
* @readonly
|
|
7
15
|
* @type {number}
|
|
8
16
|
*/
|
|
9
|
-
const
|
|
17
|
+
const UINT_32_SIZE = 4;
|
|
10
18
|
|
|
11
19
|
/**
|
|
12
20
|
* @readonly
|
|
13
21
|
* @type {number}
|
|
14
22
|
*/
|
|
15
|
-
const
|
|
23
|
+
export const NULL_POINTER = 0xFFFFFFFF;
|
|
16
24
|
|
|
17
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Heavily influenced by blender's internal mesh structure
|
|
27
|
+
* @see https://github.com/blender/blender/blob/master/source/blender/bmesh/bmesh_class.h
|
|
28
|
+
*/
|
|
29
|
+
export class BinaryTopology {
|
|
30
|
+
/**
|
|
31
|
+
* structure:
|
|
32
|
+
* coordinate: float32[3] // vertex coordinates
|
|
33
|
+
* normal: float32[3] // vertex normal
|
|
34
|
+
* edge_pointer: uint32 // Pointer to (any) edge using this vertex (for disk cycles)
|
|
35
|
+
*
|
|
36
|
+
* @type {BinaryElementPool}
|
|
37
|
+
* @private
|
|
38
|
+
*/
|
|
39
|
+
__vertex_pool = new BinaryElementPool(3 * FLOAT_32_SIZE + 3 * FLOAT_32_SIZE + UINT_32_SIZE);
|
|
40
|
+
/**
|
|
41
|
+
* structure:
|
|
42
|
+
* v1: uint32 // Vertices (unordered)
|
|
43
|
+
* v2: uint32 // Vertices (unordered)
|
|
44
|
+
* l: uint32 // The list of loops around the edge points at a Loop
|
|
45
|
+
* v1_disk_link: uint32[2] // Disk Cycle Pointers edge around vertex v1 and d2 does the same for v2.
|
|
46
|
+
* v2_disk_link: uint32[2] // see above
|
|
47
|
+
* @type {BinaryElementPool}
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
__edge_pool = new BinaryElementPool(UINT_32_SIZE * 7);
|
|
51
|
+
/**
|
|
52
|
+
* Loop represents a corner of the face
|
|
53
|
+
* structure:
|
|
54
|
+
* v: uint32 // The vertex this loop points to. This vertex must be unique within the cycle
|
|
55
|
+
* e: uint32 // The edge this loop uses.
|
|
56
|
+
* f: uint32 // The face this loop is part of.
|
|
57
|
+
* radial_next: uint32 // Other loops connected to this edge.
|
|
58
|
+
* radial_prev: uint32
|
|
59
|
+
* next: uint32 // Other loops that are part of this face.
|
|
60
|
+
* prev: uint32
|
|
61
|
+
* @type {BinaryElementPool}
|
|
62
|
+
* @private
|
|
63
|
+
*/
|
|
64
|
+
__loop_pool = new BinaryElementPool(UINT_32_SIZE * 7);
|
|
65
|
+
/**
|
|
66
|
+
* structure:
|
|
67
|
+
* l_first: uint32 // first loop pointer
|
|
68
|
+
* no: float32[3] // Face normal
|
|
69
|
+
* @type {BinaryElementPool}
|
|
70
|
+
* @private
|
|
71
|
+
*/
|
|
72
|
+
__face_pool = new BinaryElementPool(UINT_32_SIZE + FLOAT_32_SIZE * 3);
|
|
18
73
|
|
|
19
|
-
constructor(item_size, initial_capacity = INITIAL_CAPACITY) {
|
|
20
|
-
/**
|
|
21
|
-
* Size of a single pool item in bytes
|
|
22
|
-
* @type {number}
|
|
23
|
-
* @private
|
|
24
|
-
*/
|
|
25
|
-
this.__item_size = item_size;
|
|
26
|
-
/**
|
|
27
|
-
* Unused slots
|
|
28
|
-
* @type {number[]}
|
|
29
|
-
* @private
|
|
30
|
-
*/
|
|
31
|
-
this.__free = [];
|
|
32
74
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
this.
|
|
75
|
+
/**
|
|
76
|
+
* Total (approximate) size of this structure in memory, in bytes
|
|
77
|
+
* @return {number}
|
|
78
|
+
*/
|
|
79
|
+
get byteSize() {
|
|
80
|
+
return this.__loop_pool.byteSize
|
|
81
|
+
+ this.__vertex_pool.byteSize
|
|
82
|
+
+ this.__edge_pool.byteSize
|
|
83
|
+
+ this.__face_pool.byteSize
|
|
84
|
+
;
|
|
85
|
+
}
|
|
39
86
|
|
|
40
|
-
|
|
41
|
-
this.
|
|
87
|
+
trim() {
|
|
88
|
+
this.__loop_pool.trim();
|
|
89
|
+
this.__vertex_pool.trim();
|
|
90
|
+
this.__edge_pool.trim();
|
|
91
|
+
this.__face_pool.trim();
|
|
92
|
+
}
|
|
42
93
|
|
|
43
|
-
|
|
94
|
+
get vertices() {
|
|
95
|
+
return this.__vertex_pool;
|
|
96
|
+
}
|
|
44
97
|
|
|
45
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Edges are shared among faces, edges point to 2 unordered vertices
|
|
100
|
+
* @return {BinaryElementPool}
|
|
101
|
+
*/
|
|
102
|
+
get edges() {
|
|
103
|
+
return this.__edge_pool;
|
|
46
104
|
}
|
|
47
105
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Loops are corners of faces, a single vertex can be associated with many loops, one per connected face
|
|
108
|
+
* @return {BinaryElementPool}
|
|
109
|
+
*/
|
|
110
|
+
get loops() {
|
|
111
|
+
return this.__loop_pool;
|
|
112
|
+
}
|
|
53
113
|
|
|
54
|
-
|
|
114
|
+
get faces() {
|
|
115
|
+
return this.__face_pool;
|
|
116
|
+
}
|
|
55
117
|
|
|
56
|
-
const new_data_buffer = new ArrayBuffer(new_capacity * this.__item_size);
|
|
57
118
|
|
|
58
|
-
|
|
59
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Clear the topology, removed all data
|
|
121
|
+
*/
|
|
122
|
+
clear() {
|
|
123
|
+
this.__vertex_pool.clear();
|
|
124
|
+
this.__edge_pool.clear();
|
|
125
|
+
this.__loop_pool.clear();
|
|
126
|
+
this.__face_pool.clear();
|
|
127
|
+
}
|
|
60
128
|
|
|
61
|
-
|
|
62
|
-
|
|
129
|
+
/**
|
|
130
|
+
*
|
|
131
|
+
* @param {number[]|ArrayLike<number>|Float32Array} result
|
|
132
|
+
* @param {number} result_offset
|
|
133
|
+
* @param {number} id vertex ID
|
|
134
|
+
*/
|
|
135
|
+
vertex_read_coordinate(result, result_offset, id) {
|
|
136
|
+
const pool = this.__vertex_pool;
|
|
63
137
|
|
|
64
|
-
|
|
138
|
+
const v_address = pool.element_address(id);
|
|
139
|
+
const v_offset = v_address >> 2; // get 4-byte boundary
|
|
140
|
+
array_copy(pool.data_float32, v_offset, result, result_offset, 3);
|
|
65
141
|
}
|
|
66
142
|
|
|
143
|
+
/**
|
|
144
|
+
*
|
|
145
|
+
* @param {number} id
|
|
146
|
+
* @param {number[]} value
|
|
147
|
+
* @param {number} value_offset
|
|
148
|
+
*/
|
|
149
|
+
vertex_write_coordinate(id, value, value_offset) {
|
|
150
|
+
const pool = this.__vertex_pool;
|
|
151
|
+
|
|
152
|
+
const v_address = pool.element_address(id);
|
|
153
|
+
const v_offset = v_address >> 2; // get 4-byte boundary
|
|
154
|
+
array_copy(value, value_offset, pool.data_float32, v_offset, 3);
|
|
155
|
+
}
|
|
67
156
|
|
|
68
157
|
/**
|
|
69
158
|
*
|
|
70
|
-
* @
|
|
159
|
+
* @param {number[]|ArrayLike<number>|Float32Array} result
|
|
160
|
+
* @param {number} result_offset
|
|
161
|
+
* @param {number} id vertex ID
|
|
71
162
|
*/
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
163
|
+
vertex_read_normal(result, result_offset, id) {
|
|
164
|
+
const pool = this.__vertex_pool;
|
|
165
|
+
|
|
166
|
+
const v_address = pool.element_address(id) + 3 * FLOAT_32_SIZE;
|
|
167
|
+
const v_offset = v_address >> 2; // get 4-byte boundary
|
|
168
|
+
array_copy(pool.data_float32, v_offset, result, result_offset, 3);
|
|
169
|
+
}
|
|
78
170
|
|
|
79
|
-
|
|
171
|
+
/**
|
|
172
|
+
*
|
|
173
|
+
* @param {number} id
|
|
174
|
+
* @param {number[]} value
|
|
175
|
+
* @param {number} value_offset
|
|
176
|
+
*/
|
|
177
|
+
vertex_write_normal(id, value, value_offset) {
|
|
178
|
+
const pool = this.__vertex_pool;
|
|
80
179
|
|
|
81
|
-
|
|
180
|
+
const v_address = pool.element_address(id) + 3 * FLOAT_32_SIZE;
|
|
181
|
+
const v_offset = v_address >> 2; // get 4-byte boundary
|
|
182
|
+
array_copy(value, value_offset, pool.data_float32, v_offset, 3);
|
|
183
|
+
}
|
|
82
184
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
185
|
+
/**
|
|
186
|
+
* @param {number} id
|
|
187
|
+
* @returns {number}
|
|
188
|
+
*/
|
|
189
|
+
vertex_read_edge(id) {
|
|
190
|
+
const pool = this.__vertex_pool;
|
|
86
191
|
|
|
87
|
-
|
|
192
|
+
const address = pool.element_address(id);
|
|
193
|
+
return pool.data_view.getUint32(address + 6 * UINT_32_SIZE);
|
|
88
194
|
|
|
89
|
-
return result;
|
|
90
195
|
}
|
|
91
196
|
|
|
92
197
|
/**
|
|
93
198
|
*
|
|
199
|
+
* @param {number} edge_id
|
|
94
200
|
* @param {number} id
|
|
95
201
|
*/
|
|
96
|
-
|
|
97
|
-
|
|
202
|
+
vertex_write_edge(id, edge_id) {
|
|
203
|
+
const pool = this.__vertex_pool;
|
|
204
|
+
|
|
205
|
+
const address = pool.element_address(id);
|
|
206
|
+
pool.data_view.setUint32(address + 6 * UINT_32_SIZE, edge_id);
|
|
98
207
|
}
|
|
99
|
-
}
|
|
100
208
|
|
|
101
|
-
/**
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
209
|
+
/**
|
|
210
|
+
* @param {number} id edge ID
|
|
211
|
+
* @returns {number}
|
|
212
|
+
*/
|
|
213
|
+
edge_read_vertex1(id) {
|
|
214
|
+
const pool = this.__edge_pool;
|
|
215
|
+
|
|
216
|
+
const address = pool.element_address(id);
|
|
217
|
+
return pool.data_view.getUint32(address);
|
|
218
|
+
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
*
|
|
223
|
+
* @param {number} value
|
|
224
|
+
* @param {number} id edge ID
|
|
225
|
+
*/
|
|
226
|
+
edge_write_vertex1(id, value) {
|
|
227
|
+
const pool = this.__edge_pool;
|
|
228
|
+
|
|
229
|
+
const address = pool.element_address(id);
|
|
230
|
+
pool.data_view.setUint32(address, value);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* @param {number} id edge ID
|
|
235
|
+
* @returns {number}
|
|
236
|
+
*/
|
|
237
|
+
edge_read_vertex2(id) {
|
|
238
|
+
const pool = this.__edge_pool;
|
|
239
|
+
|
|
240
|
+
const address = pool.element_address(id);
|
|
241
|
+
return pool.data_view.getUint32(address + UINT_32_SIZE);
|
|
242
|
+
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
*
|
|
247
|
+
* @param {number} value
|
|
248
|
+
* @param {number} id edge ID
|
|
249
|
+
*/
|
|
250
|
+
edge_write_vertex2(id, value) {
|
|
251
|
+
const pool = this.__edge_pool;
|
|
252
|
+
|
|
253
|
+
const address = pool.element_address(id);
|
|
254
|
+
pool.data_view.setUint32(address + UINT_32_SIZE, value);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* @param {number} id edge ID
|
|
259
|
+
* @returns {number}
|
|
260
|
+
*/
|
|
261
|
+
edge_read_loop(id) {
|
|
262
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
263
|
+
const pool = this.__edge_pool;
|
|
264
|
+
|
|
265
|
+
assert.equal(pool.is_allocated(id), true, 'element is not allocated');
|
|
266
|
+
|
|
267
|
+
const address = pool.element_address(id);
|
|
268
|
+
return pool.data_view.getUint32(address + 2 * UINT_32_SIZE);
|
|
269
|
+
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
*
|
|
274
|
+
* @param {number} value
|
|
275
|
+
* @param {number} id edge ID
|
|
276
|
+
*/
|
|
277
|
+
edge_write_loop(id, value) {
|
|
278
|
+
const pool = this.__edge_pool;
|
|
279
|
+
|
|
280
|
+
const address = pool.element_address(id);
|
|
281
|
+
pool.data_view.setUint32(address + 2 * UINT_32_SIZE, value);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
loop_create() {
|
|
285
|
+
const id = this.__loop_pool.allocate();
|
|
286
|
+
|
|
287
|
+
this.loop_initialize(id);
|
|
288
|
+
|
|
289
|
+
return id;
|
|
290
|
+
}
|
|
110
291
|
|
|
292
|
+
/**
|
|
293
|
+
* Put loop into valid initial state, set all pointers to NULL
|
|
294
|
+
* @param {number} id
|
|
295
|
+
*/
|
|
296
|
+
loop_initialize(id) {
|
|
297
|
+
this.loop_write_radial_next(id, NULL_POINTER);
|
|
298
|
+
this.loop_write_radial_prev(id, NULL_POINTER);
|
|
299
|
+
this.loop_write_next(id, NULL_POINTER);
|
|
300
|
+
this.loop_write_prev(id, NULL_POINTER);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* @param {number} id loop ID
|
|
305
|
+
* @returns {number}
|
|
306
|
+
*/
|
|
307
|
+
loop_read_vertex(id) {
|
|
308
|
+
const pool = this.__loop_pool;
|
|
309
|
+
|
|
310
|
+
const address = pool.element_address(id);
|
|
311
|
+
return pool.data_view.getUint32(address);
|
|
312
|
+
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
*
|
|
317
|
+
* @param {number} value
|
|
318
|
+
* @param {number} id loop ID
|
|
319
|
+
*/
|
|
320
|
+
loop_write_vertex(id, value) {
|
|
321
|
+
const pool = this.__loop_pool;
|
|
322
|
+
|
|
323
|
+
const address = pool.element_address(id);
|
|
324
|
+
pool.data_view.setUint32(address, value);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
*
|
|
329
|
+
* @param {number} id loop ID
|
|
330
|
+
* @returns {number}
|
|
331
|
+
*/
|
|
332
|
+
loop_read_edge(id) {
|
|
333
|
+
const pool = this.__loop_pool;
|
|
334
|
+
|
|
335
|
+
const address = pool.element_address(id);
|
|
336
|
+
return pool.data_view.getUint32(address + UINT_32_SIZE);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
*
|
|
341
|
+
* @param {number} value
|
|
342
|
+
* @param {number} id loop ID
|
|
343
|
+
*/
|
|
344
|
+
loop_write_edge(id, value) {
|
|
345
|
+
const pool = this.__loop_pool;
|
|
346
|
+
|
|
347
|
+
const address = pool.element_address(id);
|
|
348
|
+
pool.data_view.setUint32(address + UINT_32_SIZE, value);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
*
|
|
353
|
+
* @param {number} id loop ID
|
|
354
|
+
* @returns {number}
|
|
355
|
+
*/
|
|
356
|
+
loop_read_face(id) {
|
|
357
|
+
const pool = this.__loop_pool;
|
|
358
|
+
|
|
359
|
+
const address = pool.element_address(id);
|
|
360
|
+
return pool.data_view.getUint32(address + 2 * UINT_32_SIZE);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
*
|
|
365
|
+
* @param {number} value
|
|
366
|
+
* @param {number} id loop ID
|
|
367
|
+
*/
|
|
368
|
+
loop_write_face(id, value) {
|
|
369
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
370
|
+
|
|
371
|
+
const pool = this.__loop_pool;
|
|
372
|
+
|
|
373
|
+
const address = pool.element_address(id);
|
|
374
|
+
pool.data_view.setUint32(address + 2 * UINT_32_SIZE, value);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
*
|
|
379
|
+
* @param {number} id loop ID
|
|
380
|
+
* @returns {number}
|
|
381
|
+
*/
|
|
382
|
+
loop_read_radial_next(id) {
|
|
383
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
384
|
+
const pool = this.__loop_pool;
|
|
385
|
+
|
|
386
|
+
const address = pool.element_address(id);
|
|
387
|
+
return pool.data_view.getUint32(address + 3 * UINT_32_SIZE);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
*
|
|
392
|
+
* @param {number} value
|
|
393
|
+
* @param {number} id loop ID
|
|
394
|
+
*/
|
|
395
|
+
loop_write_radial_next(id, value) {
|
|
396
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
397
|
+
const pool = this.__loop_pool;
|
|
398
|
+
|
|
399
|
+
const address = pool.element_address(id);
|
|
400
|
+
pool.data_view.setUint32(address + 3 * UINT_32_SIZE, value);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
*
|
|
405
|
+
* @param {number} id loop ID
|
|
406
|
+
* @returns {number}
|
|
407
|
+
*/
|
|
408
|
+
loop_read_radial_prev(id) {
|
|
409
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
410
|
+
const pool = this.__loop_pool;
|
|
411
|
+
|
|
412
|
+
const address = pool.element_address(id);
|
|
413
|
+
return pool.data_view.getUint32(address + 4 * UINT_32_SIZE);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
*
|
|
418
|
+
* @param {number} value
|
|
419
|
+
* @param {number} id loop ID
|
|
420
|
+
*/
|
|
421
|
+
loop_write_radial_prev(id, value) {
|
|
422
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
423
|
+
const pool = this.__loop_pool;
|
|
424
|
+
|
|
425
|
+
const address = pool.element_address(id);
|
|
426
|
+
pool.data_view.setUint32(address + 4 * UINT_32_SIZE, value);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
*
|
|
431
|
+
* @param {number} id loop ID
|
|
432
|
+
* @returns {number}
|
|
433
|
+
*/
|
|
434
|
+
loop_read_next(id) {
|
|
435
|
+
const pool = this.__loop_pool;
|
|
436
|
+
|
|
437
|
+
const address = pool.element_address(id);
|
|
438
|
+
return pool.data_view.getUint32(address + 5 * UINT_32_SIZE);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
*
|
|
443
|
+
* @param {number} value
|
|
444
|
+
* @param {number} id loop ID
|
|
445
|
+
*/
|
|
446
|
+
loop_write_next(id, value) {
|
|
447
|
+
const pool = this.__loop_pool;
|
|
111
448
|
|
|
449
|
+
const address = pool.element_address(id);
|
|
450
|
+
pool.data_view.setUint32(address + 5 * UINT_32_SIZE, value);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
*
|
|
455
|
+
* @param {number} id loop ID
|
|
456
|
+
* @returns {number}
|
|
457
|
+
*/
|
|
458
|
+
loop_read_prev(id) {
|
|
459
|
+
const pool = this.__loop_pool;
|
|
460
|
+
|
|
461
|
+
const address = pool.element_address(id);
|
|
462
|
+
return pool.data_view.getUint32(address + 6 * UINT_32_SIZE);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
*
|
|
467
|
+
* @param {number} value
|
|
468
|
+
* @param {number} id loop ID
|
|
469
|
+
*/
|
|
470
|
+
loop_write_prev(id, value) {
|
|
471
|
+
const pool = this.__loop_pool;
|
|
472
|
+
|
|
473
|
+
const address = pool.element_address(id);
|
|
474
|
+
pool.data_view.setUint32(address + 6 * UINT_32_SIZE, value);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
*
|
|
479
|
+
* @param {number} id face ID
|
|
480
|
+
* @returns {number}
|
|
481
|
+
*/
|
|
482
|
+
face_read_loop(id) {
|
|
483
|
+
const pool = this.__face_pool;
|
|
484
|
+
|
|
485
|
+
const address = pool.element_address(id);
|
|
486
|
+
return pool.data_view.getUint32(address);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
*
|
|
491
|
+
* @param {number} value
|
|
492
|
+
* @param {number} id face ID
|
|
493
|
+
*/
|
|
494
|
+
face_write_loop(id, value) {
|
|
495
|
+
const pool = this.__face_pool;
|
|
496
|
+
|
|
497
|
+
const address = pool.element_address(id);
|
|
498
|
+
pool.data_view.setUint32(address, value);
|
|
499
|
+
}
|
|
112
500
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BinaryTopology } from "./BinaryTopology.js";
|
|
2
|
+
|
|
3
|
+
test('create and set vertex', () => {
|
|
4
|
+
|
|
5
|
+
const topo = new BinaryTopology();
|
|
6
|
+
|
|
7
|
+
const v = topo.vertices.allocate();
|
|
8
|
+
|
|
9
|
+
topo.vertex_write_coordinate(v, [1, 2, 0], 0);
|
|
10
|
+
|
|
11
|
+
const coordinate = [];
|
|
12
|
+
|
|
13
|
+
topo.vertex_read_coordinate(coordinate, 0, v);
|
|
14
|
+
|
|
15
|
+
expect(coordinate).toEqual([1, 2, 0]);
|
|
16
|
+
});
|
|
@@ -35,6 +35,31 @@ export class TopoMesh {
|
|
|
35
35
|
this.__faces = new Set();
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Approximation of memory footprint of this object
|
|
40
|
+
* NOTE: this is highly speculative and will differ from reality depending on VM running the code as well as many other factors
|
|
41
|
+
* @return {number}
|
|
42
|
+
*/
|
|
43
|
+
get byteSize() {
|
|
44
|
+
let r = 0;
|
|
45
|
+
|
|
46
|
+
for (let i = 0; i < this.vertices.length; i++) {
|
|
47
|
+
const v = this.vertices[i];
|
|
48
|
+
|
|
49
|
+
r += v.byteSize;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
for (const edge of this.__edges) {
|
|
53
|
+
r += edge.byteSize;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
for (const face of this.__faces) {
|
|
57
|
+
r += face.byteSize;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return r;
|
|
61
|
+
}
|
|
62
|
+
|
|
38
63
|
/**
|
|
39
64
|
*
|
|
40
65
|
* @returns {Set<TopoEdge>}
|
|
@@ -52,6 +52,14 @@ export class TopoVertex {
|
|
|
52
52
|
return this.z;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Estimate of this object's size in RAM, in bytes
|
|
57
|
+
* @return {number}
|
|
58
|
+
*/
|
|
59
|
+
get byteSize() {
|
|
60
|
+
return 80 + 6 * 4 + 8 + this.edges.length * 8 + 10 + this.faces.length * 8 + 10;
|
|
61
|
+
}
|
|
62
|
+
|
|
55
63
|
/**
|
|
56
64
|
*
|
|
57
65
|
* @param {TopoVertex} other
|