@woosh/meep-engine 2.43.21 → 2.43.23
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/tetrahedra/delaunay/compute_delaunay_tetrahedral_mesh.js +2 -2
- 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/binary/BinaryElementPool.js +288 -0
- package/core/geom/3d/topology/struct/binary/BinaryElementPool.spec.js +36 -0
- package/core/geom/3d/topology/struct/binary/BinaryTopology.js +617 -0
- package/core/geom/3d/topology/struct/binary/BinaryTopology.spec.js +16 -0
- package/core/geom/3d/topology/struct/binary/io/OrderedEdge.js +66 -0
- package/core/geom/3d/topology/struct/binary/io/bt_index_geometry_to_topology.js +188 -0
- package/core/geom/3d/topology/struct/binary/io/bt_index_geometry_to_topology.spec.js +84 -0
- package/core/geom/3d/topology/struct/binary/io/bt_mesh_calc_edges.js +51 -0
- package/core/geom/3d/topology/struct/binary/io/create_edge.js +106 -0
- package/core/geom/3d/topology/struct/binary/io/get_or_create_edge_map.js +26 -0
- package/core/geom/3d/topology/struct/binary/query/bt_mesh_edge_has_vertex.js +16 -0
- package/core/geom/3d/topology/struct/binary/query/bt_mesh_edge_has_vertex.spec.js +15 -0
- package/core/geom/3d/topology/struct/binary/query/bt_mesh_edge_other_vertex.js +21 -0
- package/core/geom/3d/topology/struct/binary/query/bt_mesh_edge_other_vertex.spec.js +16 -0
- package/core/geom/3d/topology/struct/prototypeBinaryTopology.js +55 -0
- package/core/path/PATH_SEPARATOR.js +1 -0
- package/core/path/computeFileExtension.js +24 -0
- package/core/path/computeFileExtension.spec.js +13 -0
- package/core/path/computePathBase.js +21 -0
- package/core/path/computePathBase.spec.js +13 -0
- package/core/path/computePathDirectory.js +25 -0
- package/editor/view/library/MeshLibraryView.js +1 -1
- package/engine/asset/guessAssetType.js +1 -1
- package/engine/asset/loaders/image/ImageRGBADataLoader.js +1 -1
- package/engine/asset/loaders/texture/TextureAssetLoader.js +1 -1
- package/engine/ecs/storage/BinaryBufferSerializer.js +7 -0
- package/engine/graphics/material/composeCompile.js +3 -5
- package/engine/graphics/micron/plugin/GLTFAssetTransformer.js +90 -65
- package/engine/graphics/sh3/README.md +2 -0
- package/engine/graphics/sh3/path_tracer/PathTracer.js +2 -15
- package/engine/graphics/sh3/path_tracer/getBiasedNormalSample.js +1 -1
- package/engine/graphics/sh3/path_tracer/prototypePathTracer.js +14 -9
- package/engine/graphics/texture/cubemap/load_environment_map.js +1 -1
- package/engine/graphics/util/makeMeshPreviewScene.js +38 -26
- package/engine/network/RemoteController.js +98 -0
- package/engine/network/remoteEditor.js +33 -0
- package/engine/save/storage/IndexedDBStorage.js +1 -0
- package/package.json +1 -1
- package/view/elements/MeshPreview.js +5 -1
- package/core/FilePath.js +0 -73
- package/core/FilePath.spec.js +0 -25
- package/core/geom/3d/topology/struct/BinaryTopology.js +0 -112
|
@@ -0,0 +1,617 @@
|
|
|
1
|
+
import { BinaryElementPool } from "./BinaryElementPool.js";
|
|
2
|
+
import { array_copy } from "../../../../../collection/array/copyArray.js";
|
|
3
|
+
import { assert } from "../../../../../assert.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Byte size of FLOAT_32
|
|
7
|
+
* @readonly
|
|
8
|
+
* @type {number}
|
|
9
|
+
*/
|
|
10
|
+
const FLOAT_32_SIZE = 4;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Byte size of UINT_32
|
|
14
|
+
* @readonly
|
|
15
|
+
* @type {number}
|
|
16
|
+
*/
|
|
17
|
+
const UINT_32_SIZE = 4;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @readonly
|
|
21
|
+
* @type {number}
|
|
22
|
+
*/
|
|
23
|
+
export const NULL_POINTER = 0xFFFFFFFF;
|
|
24
|
+
|
|
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);
|
|
73
|
+
|
|
74
|
+
|
|
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
|
+
}
|
|
86
|
+
|
|
87
|
+
trim() {
|
|
88
|
+
this.__loop_pool.trim();
|
|
89
|
+
this.__vertex_pool.trim();
|
|
90
|
+
this.__edge_pool.trim();
|
|
91
|
+
this.__face_pool.trim();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
get vertices() {
|
|
95
|
+
return this.__vertex_pool;
|
|
96
|
+
}
|
|
97
|
+
|
|
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;
|
|
104
|
+
}
|
|
105
|
+
|
|
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
|
+
}
|
|
113
|
+
|
|
114
|
+
get faces() {
|
|
115
|
+
return this.__face_pool;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
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
|
+
}
|
|
128
|
+
|
|
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;
|
|
137
|
+
|
|
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);
|
|
141
|
+
}
|
|
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
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
*
|
|
159
|
+
* @param {number[]|ArrayLike<number>|Float32Array} result
|
|
160
|
+
* @param {number} result_offset
|
|
161
|
+
* @param {number} id vertex ID
|
|
162
|
+
*/
|
|
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
|
+
}
|
|
170
|
+
|
|
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;
|
|
179
|
+
|
|
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
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* @param {number} id
|
|
187
|
+
* @returns {number}
|
|
188
|
+
*/
|
|
189
|
+
vertex_read_edge(id) {
|
|
190
|
+
const pool = this.__vertex_pool;
|
|
191
|
+
|
|
192
|
+
const address = pool.element_address(id);
|
|
193
|
+
return pool.data_view.getUint32(address + 6 * UINT_32_SIZE);
|
|
194
|
+
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
*
|
|
199
|
+
* @param {number} edge_id
|
|
200
|
+
* @param {number} id
|
|
201
|
+
*/
|
|
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);
|
|
207
|
+
}
|
|
208
|
+
|
|
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
|
+
/**
|
|
259
|
+
* @param {number} id edge ID
|
|
260
|
+
* @returns {number}
|
|
261
|
+
*/
|
|
262
|
+
edge_read_loop(id) {
|
|
263
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
264
|
+
const pool = this.__edge_pool;
|
|
265
|
+
|
|
266
|
+
assert.equal(pool.is_allocated(id), true, 'element is not allocated');
|
|
267
|
+
|
|
268
|
+
const address = pool.element_address(id);
|
|
269
|
+
return pool.data_view.getUint32(address + 2 * UINT_32_SIZE);
|
|
270
|
+
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
*
|
|
275
|
+
* @param {number} value
|
|
276
|
+
* @param {number} id edge ID
|
|
277
|
+
*/
|
|
278
|
+
edge_write_loop(id, value) {
|
|
279
|
+
const pool = this.__edge_pool;
|
|
280
|
+
|
|
281
|
+
const address = pool.element_address(id);
|
|
282
|
+
pool.data_view.setUint32(address + 2 * UINT_32_SIZE, value);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* @param {number} id edge ID
|
|
287
|
+
* @returns {number}
|
|
288
|
+
*/
|
|
289
|
+
edge_read_v1_disk_next(id) {
|
|
290
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
291
|
+
const pool = this.__edge_pool;
|
|
292
|
+
|
|
293
|
+
// assert.equal(pool.is_allocated(id), true, 'element is not allocated');
|
|
294
|
+
|
|
295
|
+
const address = pool.element_address(id);
|
|
296
|
+
return pool.data_view.getUint32(address + 3 * UINT_32_SIZE);
|
|
297
|
+
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
*
|
|
302
|
+
* @param {number} value
|
|
303
|
+
* @param {number} id edge ID
|
|
304
|
+
*/
|
|
305
|
+
edge_write_v1_disk_next(id, value) {
|
|
306
|
+
const pool = this.__edge_pool;
|
|
307
|
+
|
|
308
|
+
// assert.equal(pool.is_allocated(id), true, 'element is not allocated');
|
|
309
|
+
|
|
310
|
+
const address = pool.element_address(id);
|
|
311
|
+
pool.data_view.setUint32(address + 3 * UINT_32_SIZE, value);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* @param {number} id edge ID
|
|
316
|
+
* @returns {number}
|
|
317
|
+
*/
|
|
318
|
+
edge_read_v1_disk_prev(id) {
|
|
319
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
320
|
+
const pool = this.__edge_pool;
|
|
321
|
+
|
|
322
|
+
// assert.equal(pool.is_allocated(id), true, 'element is not allocated');
|
|
323
|
+
|
|
324
|
+
const address = pool.element_address(id);
|
|
325
|
+
return pool.data_view.getUint32(address + 4 * UINT_32_SIZE);
|
|
326
|
+
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
*
|
|
331
|
+
* @param {number} value
|
|
332
|
+
* @param {number} id edge ID
|
|
333
|
+
*/
|
|
334
|
+
edge_write_v1_disk_prev(id, value) {
|
|
335
|
+
const pool = this.__edge_pool;
|
|
336
|
+
|
|
337
|
+
// assert.equal(pool.is_allocated(id), true, 'element is not allocated');
|
|
338
|
+
|
|
339
|
+
const address = pool.element_address(id);
|
|
340
|
+
pool.data_view.setUint32(address + 4 * UINT_32_SIZE, value);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* @param {number} id edge ID
|
|
345
|
+
* @returns {number}
|
|
346
|
+
*/
|
|
347
|
+
edge_read_v2_disk_next(id) {
|
|
348
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
349
|
+
const pool = this.__edge_pool;
|
|
350
|
+
|
|
351
|
+
// assert.equal(pool.is_allocated(id), true, 'element is not allocated');
|
|
352
|
+
|
|
353
|
+
const address = pool.element_address(id);
|
|
354
|
+
return pool.data_view.getUint32(address + 5 * UINT_32_SIZE);
|
|
355
|
+
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
*
|
|
360
|
+
* @param {number} value
|
|
361
|
+
* @param {number} id edge ID
|
|
362
|
+
*/
|
|
363
|
+
edge_write_v2_disk_next(id, value) {
|
|
364
|
+
const pool = this.__edge_pool;
|
|
365
|
+
|
|
366
|
+
// assert.equal(pool.is_allocated(id), true, 'element is not allocated');
|
|
367
|
+
|
|
368
|
+
const address = pool.element_address(id);
|
|
369
|
+
pool.data_view.setUint32(address + 5 * UINT_32_SIZE, value);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* @param {number} id edge ID
|
|
374
|
+
* @returns {number}
|
|
375
|
+
*/
|
|
376
|
+
edge_read_v2_disk_prev(id) {
|
|
377
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
378
|
+
const pool = this.__edge_pool;
|
|
379
|
+
|
|
380
|
+
// assert.equal(pool.is_allocated(id), true, 'element is not allocated');
|
|
381
|
+
|
|
382
|
+
const address = pool.element_address(id);
|
|
383
|
+
return pool.data_view.getUint32(address + 6 * UINT_32_SIZE);
|
|
384
|
+
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
*
|
|
389
|
+
* @param {number} value
|
|
390
|
+
* @param {number} id edge ID
|
|
391
|
+
*/
|
|
392
|
+
edge_write_v2_disk_prev(id, value) {
|
|
393
|
+
const pool = this.__edge_pool;
|
|
394
|
+
|
|
395
|
+
// assert.equal(pool.is_allocated(id), true, 'element is not allocated');
|
|
396
|
+
|
|
397
|
+
const address = pool.element_address(id);
|
|
398
|
+
pool.data_view.setUint32(address + 6 * UINT_32_SIZE, value);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
loop_create() {
|
|
402
|
+
const id = this.__loop_pool.allocate();
|
|
403
|
+
|
|
404
|
+
this.loop_initialize(id);
|
|
405
|
+
|
|
406
|
+
return id;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Put loop into valid initial state, set all pointers to NULL
|
|
411
|
+
* @param {number} id
|
|
412
|
+
*/
|
|
413
|
+
loop_initialize(id) {
|
|
414
|
+
this.loop_write_radial_next(id, id);
|
|
415
|
+
this.loop_write_radial_prev(id, id);
|
|
416
|
+
this.loop_write_next(id, id);
|
|
417
|
+
this.loop_write_prev(id, id);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* @param {number} id loop ID
|
|
422
|
+
* @returns {number}
|
|
423
|
+
*/
|
|
424
|
+
loop_read_vertex(id) {
|
|
425
|
+
const pool = this.__loop_pool;
|
|
426
|
+
|
|
427
|
+
const address = pool.element_address(id);
|
|
428
|
+
return pool.data_view.getUint32(address);
|
|
429
|
+
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
*
|
|
434
|
+
* @param {number} value
|
|
435
|
+
* @param {number} id loop ID
|
|
436
|
+
*/
|
|
437
|
+
loop_write_vertex(id, value) {
|
|
438
|
+
const pool = this.__loop_pool;
|
|
439
|
+
|
|
440
|
+
const address = pool.element_address(id);
|
|
441
|
+
pool.data_view.setUint32(address, value);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
*
|
|
446
|
+
* @param {number} id loop ID
|
|
447
|
+
* @returns {number}
|
|
448
|
+
*/
|
|
449
|
+
loop_read_edge(id) {
|
|
450
|
+
const pool = this.__loop_pool;
|
|
451
|
+
|
|
452
|
+
const address = pool.element_address(id);
|
|
453
|
+
return pool.data_view.getUint32(address + UINT_32_SIZE);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
*
|
|
458
|
+
* @param {number} value
|
|
459
|
+
* @param {number} id loop ID
|
|
460
|
+
*/
|
|
461
|
+
loop_write_edge(id, value) {
|
|
462
|
+
const pool = this.__loop_pool;
|
|
463
|
+
|
|
464
|
+
const address = pool.element_address(id);
|
|
465
|
+
pool.data_view.setUint32(address + UINT_32_SIZE, value);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
*
|
|
470
|
+
* @param {number} id loop ID
|
|
471
|
+
* @returns {number}
|
|
472
|
+
*/
|
|
473
|
+
loop_read_face(id) {
|
|
474
|
+
const pool = this.__loop_pool;
|
|
475
|
+
|
|
476
|
+
const address = pool.element_address(id);
|
|
477
|
+
return pool.data_view.getUint32(address + 2 * UINT_32_SIZE);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
*
|
|
482
|
+
* @param {number} value
|
|
483
|
+
* @param {number} id loop ID
|
|
484
|
+
*/
|
|
485
|
+
loop_write_face(id, value) {
|
|
486
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
487
|
+
|
|
488
|
+
const pool = this.__loop_pool;
|
|
489
|
+
|
|
490
|
+
const address = pool.element_address(id);
|
|
491
|
+
pool.data_view.setUint32(address + 2 * UINT_32_SIZE, value);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
*
|
|
496
|
+
* @param {number} id loop ID
|
|
497
|
+
* @returns {number}
|
|
498
|
+
*/
|
|
499
|
+
loop_read_radial_next(id) {
|
|
500
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
501
|
+
const pool = this.__loop_pool;
|
|
502
|
+
|
|
503
|
+
const address = pool.element_address(id);
|
|
504
|
+
return pool.data_view.getUint32(address + 3 * UINT_32_SIZE);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
*
|
|
509
|
+
* @param {number} value
|
|
510
|
+
* @param {number} id loop ID
|
|
511
|
+
*/
|
|
512
|
+
loop_write_radial_next(id, value) {
|
|
513
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
514
|
+
const pool = this.__loop_pool;
|
|
515
|
+
|
|
516
|
+
const address = pool.element_address(id);
|
|
517
|
+
pool.data_view.setUint32(address + 3 * UINT_32_SIZE, value);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
*
|
|
522
|
+
* @param {number} id loop ID
|
|
523
|
+
* @returns {number}
|
|
524
|
+
*/
|
|
525
|
+
loop_read_radial_prev(id) {
|
|
526
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
527
|
+
const pool = this.__loop_pool;
|
|
528
|
+
|
|
529
|
+
const address = pool.element_address(id);
|
|
530
|
+
return pool.data_view.getUint32(address + 4 * UINT_32_SIZE);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
*
|
|
535
|
+
* @param {number} value
|
|
536
|
+
* @param {number} id loop ID
|
|
537
|
+
*/
|
|
538
|
+
loop_write_radial_prev(id, value) {
|
|
539
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
540
|
+
const pool = this.__loop_pool;
|
|
541
|
+
|
|
542
|
+
const address = pool.element_address(id);
|
|
543
|
+
pool.data_view.setUint32(address + 4 * UINT_32_SIZE, value);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
*
|
|
548
|
+
* @param {number} id loop ID
|
|
549
|
+
* @returns {number}
|
|
550
|
+
*/
|
|
551
|
+
loop_read_next(id) {
|
|
552
|
+
const pool = this.__loop_pool;
|
|
553
|
+
|
|
554
|
+
const address = pool.element_address(id);
|
|
555
|
+
return pool.data_view.getUint32(address + 5 * UINT_32_SIZE);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
*
|
|
560
|
+
* @param {number} value
|
|
561
|
+
* @param {number} id loop ID
|
|
562
|
+
*/
|
|
563
|
+
loop_write_next(id, value) {
|
|
564
|
+
const pool = this.__loop_pool;
|
|
565
|
+
|
|
566
|
+
const address = pool.element_address(id);
|
|
567
|
+
pool.data_view.setUint32(address + 5 * UINT_32_SIZE, value);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
*
|
|
572
|
+
* @param {number} id loop ID
|
|
573
|
+
* @returns {number}
|
|
574
|
+
*/
|
|
575
|
+
loop_read_prev(id) {
|
|
576
|
+
const pool = this.__loop_pool;
|
|
577
|
+
|
|
578
|
+
const address = pool.element_address(id);
|
|
579
|
+
return pool.data_view.getUint32(address + 6 * UINT_32_SIZE);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
*
|
|
584
|
+
* @param {number} value
|
|
585
|
+
* @param {number} id loop ID
|
|
586
|
+
*/
|
|
587
|
+
loop_write_prev(id, value) {
|
|
588
|
+
const pool = this.__loop_pool;
|
|
589
|
+
|
|
590
|
+
const address = pool.element_address(id);
|
|
591
|
+
pool.data_view.setUint32(address + 6 * UINT_32_SIZE, value);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
*
|
|
596
|
+
* @param {number} id face ID
|
|
597
|
+
* @returns {number}
|
|
598
|
+
*/
|
|
599
|
+
face_read_loop(id) {
|
|
600
|
+
const pool = this.__face_pool;
|
|
601
|
+
|
|
602
|
+
const address = pool.element_address(id);
|
|
603
|
+
return pool.data_view.getUint32(address);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
*
|
|
608
|
+
* @param {number} value
|
|
609
|
+
* @param {number} id face ID
|
|
610
|
+
*/
|
|
611
|
+
face_write_loop(id, value) {
|
|
612
|
+
const pool = this.__face_pool;
|
|
613
|
+
|
|
614
|
+
const address = pool.element_address(id);
|
|
615
|
+
pool.data_view.setUint32(address, value);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
@@ -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
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { split_by_2 } from "../../../../morton/mortonEncode_magicbits.js";
|
|
2
|
+
|
|
3
|
+
export class OrderedEdge {
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {number} v1
|
|
7
|
+
* @param {number} v2
|
|
8
|
+
*/
|
|
9
|
+
constructor(v1, v2) {
|
|
10
|
+
if (v1 < v2) {
|
|
11
|
+
this.v_low = v1;
|
|
12
|
+
this.v_high = v2;
|
|
13
|
+
} else {
|
|
14
|
+
this.v_low = v2;
|
|
15
|
+
this.v_high = v1;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* @param {number} v1
|
|
22
|
+
* @param {number} v2
|
|
23
|
+
*/
|
|
24
|
+
set(v1, v2) {
|
|
25
|
+
if (v1 < v2) {
|
|
26
|
+
this.v_low = v1;
|
|
27
|
+
this.v_high = v2;
|
|
28
|
+
} else {
|
|
29
|
+
this.v_low = v2;
|
|
30
|
+
this.v_high = v1;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
*
|
|
36
|
+
* @param {OrderedEdge} other
|
|
37
|
+
*/
|
|
38
|
+
copy(other) {
|
|
39
|
+
this.v_low = other.v_low;
|
|
40
|
+
this.v_high = other.v_high;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
clone() {
|
|
44
|
+
return new OrderedEdge(this.v_low, this.v_high);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
*
|
|
49
|
+
* @return {number}
|
|
50
|
+
*/
|
|
51
|
+
hash() {
|
|
52
|
+
// resulting hashes are close by
|
|
53
|
+
return split_by_2(this.v_low) | (split_by_2(this.v_high) << 1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
* @param {OrderedEdge} other
|
|
59
|
+
* @returns {boolean}
|
|
60
|
+
*/
|
|
61
|
+
equals(other) {
|
|
62
|
+
return this.v_low === other.v_low
|
|
63
|
+
&& this.v_high === other.v_high
|
|
64
|
+
;
|
|
65
|
+
}
|
|
66
|
+
}
|