@woosh/meep-engine 2.48.19 → 2.48.21

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.
Files changed (117) hide show
  1. package/package.json +1 -1
  2. package/src/core/binary/type/BinaryDataType.d.ts +15 -0
  3. package/src/{engine/graphics/render/forward_plus/data/computeDataType.js → core/binary/type/computeBinaryDataTypeByPrecision.js} +3 -3
  4. package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.js +62 -0
  5. package/src/core/graph/layout/computeDisconnectedSubGraphs.js +1 -0
  6. package/src/core/process/task/TaskGroup.js +1 -1
  7. package/src/core/process/task/util/task_tree_compute_leaf_tasks.js +21 -0
  8. package/src/engine/graphics/geometry/AttributeSpec.d.ts +2 -2
  9. package/src/engine/graphics/material/optimization/MaterialOptimizationContext.js +1 -3
  10. package/src/engine/graphics/render/forward_plus/LightManager.js +9 -7
  11. package/src/engine/graphics/{micron/render/instanced → texture}/AttributeDataTexture.js +28 -19
  12. package/src/engine/graphics/{render/forward_plus/data → texture}/TextureBackedMemoryRegion.js +8 -8
  13. package/src/engine/graphics/{render/forward_plus/data → texture}/computeThreeTextureFormat.js +2 -2
  14. package/src/engine/graphics/{render/forward_plus/data → texture}/computeThreeTextureInternalFormatFromDataType.js +1 -1
  15. package/src/engine/graphics/{render/forward_plus/data → texture}/computeThreeTextureTypeFromDataType.js +1 -1
  16. package/src/engine/graphics/texture/sampler/Sampler2D2Canvas.js +1 -1
  17. package/src/engine/graphics/texture/sampler/sampler2DToFloat32Texture.js +1 -3
  18. package/src/generation/GridTaskGroup.js +4 -4
  19. package/src/generation/filtering/numeric/util/populateSampler2DFromCellFilter.js +10 -2
  20. package/src/generation/filtering/numeric/util/sampler_from_filter.js +26 -0
  21. package/src/generation/filtering/numeric/util/visualise_filters_as_grid.js +81 -0
  22. package/src/generation/grid/generation/GridTaskSequence.js +3 -1
  23. package/src/engine/graphics/micron/MICRON_GEOMETRY_FIELD.js +0 -1
  24. package/src/engine/graphics/micron/MICRON_URI_FIELD.js +0 -1
  25. package/src/engine/graphics/micron/build/MICRON_PATCH_SIZE_MAX.js +0 -5
  26. package/src/engine/graphics/micron/build/PatchRepresentation.js +0 -424
  27. package/src/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +0 -311
  28. package/src/engine/graphics/micron/build/build_geometry_info.js +0 -21
  29. package/src/engine/graphics/micron/build/clustering/assignInitialPatchNeighbours.js +0 -63
  30. package/src/engine/graphics/micron/build/clustering/assign_patch_neighbours_from_topology.js +0 -46
  31. package/src/engine/graphics/micron/build/clustering/build_clustering_2.js +0 -37
  32. package/src/engine/graphics/micron/build/clustering/build_leaf_patches.js +0 -326
  33. package/src/engine/graphics/micron/build/clustering/build_leaf_patches_metis.js +0 -76
  34. package/src/engine/graphics/micron/build/clustering/computeBorderLengthChange.js +0 -59
  35. package/src/engine/graphics/micron/build/clustering/computeFaceCurvatureScore.js +0 -57
  36. package/src/engine/graphics/micron/build/clustering/computeOpenFaceFreedom.js +0 -35
  37. package/src/engine/graphics/micron/build/clustering/compute_face_connection_weight.js +0 -35
  38. package/src/engine/graphics/micron/build/clustering/populateOpenFaceNeighboursForPatch.js +0 -56
  39. package/src/engine/graphics/micron/build/clustering/validate_leaf_patch_connectivity.js +0 -44
  40. package/src/engine/graphics/micron/build/compute_micron_buffer_array_constructor.js +0 -24
  41. package/src/engine/graphics/micron/build/compute_vertex_remap_cost.js +0 -29
  42. package/src/engine/graphics/micron/build/debug/build_clustering_info.js +0 -58
  43. package/src/engine/graphics/micron/build/debug/build_graph_info.js +0 -59
  44. package/src/engine/graphics/micron/build/fill_patch_geometry_data.js +0 -270
  45. package/src/engine/graphics/micron/build/hierarchy/buildAbstractPatchHierarchy.js +0 -196
  46. package/src/engine/graphics/micron/build/hierarchy/build_intermediate_patch_topology.js +0 -162
  47. package/src/engine/graphics/micron/build/hierarchy/build_merge_graph.js +0 -89
  48. package/src/engine/graphics/micron/build/hierarchy/computePatchMergeScore.js +0 -146
  49. package/src/engine/graphics/micron/build/hierarchy/compute_patches_shared_vertex_count.js +0 -32
  50. package/src/engine/graphics/micron/build/hierarchy/compute_patches_shared_vertices.js +0 -34
  51. package/src/engine/graphics/micron/build/hierarchy/merge_patches.js +0 -581
  52. package/src/engine/graphics/micron/build/hierarchy/metis_cluster_clusters.js +0 -53
  53. package/src/engine/graphics/micron/build/hierarchy/optimize_graph_partitioning_balance.js +0 -515
  54. package/src/engine/graphics/micron/build/hierarchy/patch_combine.js +0 -180
  55. package/src/engine/graphics/micron/build/hierarchy/patch_fill_holes_by_uncollapse.js +0 -60
  56. package/src/engine/graphics/micron/build/hierarchy/patch_stitch_parent_border.js +0 -320
  57. package/src/engine/graphics/micron/build/hierarchy/qvdr_build_simplified_clusters.js +0 -547
  58. package/src/engine/graphics/micron/build/hierarchy/qvdr_build_tree.js +0 -140
  59. package/src/engine/graphics/micron/buildPatchwork.js +0 -68
  60. package/src/engine/graphics/micron/convert_three_object_to_micron.js +0 -179
  61. package/src/engine/graphics/micron/debug/VirtualGeometryStats.js +0 -42
  62. package/src/engine/graphics/micron/format/MICRON_GEOMETRY_PROPERTY_NAME.js +0 -1
  63. package/src/engine/graphics/micron/format/MicronGeometry.d.ts +0 -21
  64. package/src/engine/graphics/micron/format/MicronGeometry.js +0 -334
  65. package/src/engine/graphics/micron/format/MicronGeometryPatch.d.ts +0 -3
  66. package/src/engine/graphics/micron/format/MicronGeometryPatch.js +0 -205
  67. package/src/engine/graphics/micron/format/MicronGeometryPatchOccurance.js +0 -50
  68. package/src/engine/graphics/micron/format/ThreeMicronMesh.d.ts +0 -10
  69. package/src/engine/graphics/micron/format/ThreeMicronMesh.js +0 -45
  70. package/src/engine/graphics/micron/format/VirtualGeometry.js +0 -158
  71. package/src/engine/graphics/micron/format/micron_build_proxy_geometry.js +0 -205
  72. package/src/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.js +0 -123
  73. package/src/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.spec.js +0 -63
  74. package/src/engine/graphics/micron/format/serialization/collection/geometry_collection_serialization.js +0 -83
  75. package/src/engine/graphics/micron/format/serialization/collection/geometry_collection_serialization.spec.js +0 -51
  76. package/src/engine/graphics/micron/format/serialization/deserialize_attribute_spec.js +0 -25
  77. package/src/engine/graphics/micron/format/serialization/deserialize_patch.js +0 -106
  78. package/src/engine/graphics/micron/format/serialization/serialize_attribute_spec.js +0 -18
  79. package/src/engine/graphics/micron/format/serialization/serialize_patch.js +0 -84
  80. package/src/engine/graphics/micron/format/validate_patch_bounds.js +0 -69
  81. package/src/engine/graphics/micron/plugin/GLTFAssetTransformer.js +0 -265
  82. package/src/engine/graphics/micron/plugin/GLTF_MICRON_ID_FIELD.js +0 -5
  83. package/src/engine/graphics/micron/plugin/MicronRenderPlugin.d.ts +0 -8
  84. package/src/engine/graphics/micron/plugin/MicronRenderPlugin.js +0 -150
  85. package/src/engine/graphics/micron/plugin/serialization/BufferGeometrySerializationAdapter.js +0 -176
  86. package/src/engine/graphics/micron/plugin/shaded_geometry/MicronShadedGeometryRenderAdapter.js +0 -216
  87. package/src/engine/graphics/micron/prototypeMicronProxyBuild.js +0 -227
  88. package/src/engine/graphics/micron/prototypeVirtualGeometry.js +0 -911
  89. package/src/engine/graphics/micron/render/PatchCacheKey.js +0 -79
  90. package/src/engine/graphics/micron/render/VIRTUAL_MESH_FLAG.d.ts +0 -1
  91. package/src/engine/graphics/micron/render/VIRTUAL_MESH_FLAG.js +0 -1
  92. package/src/engine/graphics/micron/render/VirtualGeometryBuilder.js +0 -207
  93. package/src/engine/graphics/micron/render/approximateTriangleArea.js +0 -25
  94. package/src/engine/graphics/micron/render/culling/PatchCullingSystem.js +0 -129
  95. package/src/engine/graphics/micron/render/instanced/PatchDataTextures.js +0 -325
  96. package/src/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +0 -175
  97. package/src/engine/graphics/micron/render/instanced/shader/constants.js +0 -3
  98. package/src/engine/graphics/micron/render/instanced/shader/gen_micron_vertex_attribute_texture_name.js +0 -8
  99. package/src/engine/graphics/micron/render/instanced/shader/shader_rewrite_standard.js +0 -250
  100. package/src/engine/graphics/micron/render/makeThreeMeshFromVirtualGeometry.js +0 -37
  101. package/src/engine/graphics/micron/render/refinement/ActivePatchFlags.js +0 -8
  102. package/src/engine/graphics/micron/render/refinement/ActivePatchList.js +0 -241
  103. package/src/engine/graphics/micron/render/refinement/ActivePatchRecord.js +0 -154
  104. package/src/engine/graphics/micron/render/refinement/RefinementSpec.js +0 -84
  105. package/src/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +0 -133
  106. package/src/engine/graphics/micron/render/refinement/is_patch_facing_back.js +0 -43
  107. package/src/engine/graphics/micron/render/refinement/is_patch_visible.js +0 -37
  108. package/src/engine/graphics/micron/render/v1/MaterialContext.js +0 -150
  109. package/src/engine/graphics/micron/render/v1/MaterialVertexSpec.js +0 -115
  110. package/src/engine/graphics/micron/render/v1/MicronRenderContext.js +0 -145
  111. package/src/engine/graphics/micron/render/v1/ThreeVirtualGeometryAdapter.js +0 -255
  112. package/src/engine/graphics/micron/render/v1/VGThreeRenderer.js +0 -142
  113. package/src/engine/graphics/micron/render/v1/getTransformedPositionsCached.js +0 -54
  114. package/src/engine/graphics/micron/simplifyGeometry.js +0 -26
  115. package/src/engine/graphics/micron/util/patchToBufferGeometry.js +0 -19
  116. /package/src/{engine/graphics/render/forward_plus/data → core/math}/NumericType.js +0 -0
  117. /package/src/engine/graphics/{render/forward_plus/data → texture}/channelCountToThreIntegerTextureType.js +0 -0
@@ -1,547 +0,0 @@
1
- import { array_push_if_unique } from "../../../../../core/collection/array/array_push_if_unique.js";
2
- import FastBinaryHeap from "../../../../../core/collection/heap/FastBinaryHeap.js";
3
- import {
4
- build_vertex_quadratics
5
- } from "../../../../../core/geom/3d/topology/simplify/quadratic/build_vertex_quadratics.js";
6
- import { compute_set_of_border_vertex_indices } from "./build_intermediate_patch_topology.js";
7
- import { compute_patches_shared_vertices } from "./compute_patches_shared_vertices.js";
8
- import { max2 } from "../../../../../core/math/max2.js";
9
- import { MICRON_PATCH_SIZE_MAX } from "../MICRON_PATCH_SIZE_MAX.js";
10
- import { collapse_edges, extract_edge_cost } from "../../../../../core/geom/3d/topology/simplify/simplifyTopoMesh.js";
11
- import {
12
- build_edge_collapse_candidates
13
- } from "../../../../../core/geom/3d/topology/simplify/build_edge_collapse_candidates.js";
14
- import {
15
- collapse_all_degenerate_edges
16
- } from "../../../../../core/geom/3d/topology/simplify/collapse_all_degenerate_edges.js";
17
- import { compute_set_intersection } from "../../../../../core/collection/set/compute_set_intersection.js";
18
-
19
- /**
20
- * Cluster must share at least this many vertices for the vertex boundary constraint to be relaxed and allow them to be made dependent on each other
21
- * @type {number}
22
- */
23
- const BOUNDARY_RELAXATION_SHARED_VERTEX_THRESHOLD = 5;
24
-
25
- /**
26
- * Common ancestor between patches can be found in a given depth (up-traversal)
27
- * @param {PatchRepresentation} a
28
- * @param {PatchRepresentation} b
29
- * @param {number} depth
30
- */
31
- function patches_share_ancestor_within_depth(a, b, depth) {
32
- let n0 = a.parent;
33
- let n1;
34
-
35
- let d0 = 1;
36
- let d1 = 1;
37
-
38
- while (n0 !== null) {
39
-
40
- n1 = b.parent;
41
-
42
- while (n1 !== null) {
43
-
44
-
45
- if (n0 === n1) {
46
- return true;
47
- }
48
-
49
- n1 = n1.parent;
50
-
51
- d1++
52
-
53
- if (d1 >= depth) {
54
- break;
55
- }
56
- }
57
-
58
- n0 = n0.parent;
59
-
60
- d0++;
61
-
62
- if (d0 >= depth) {
63
- break;
64
- }
65
- }
66
-
67
- // no common ancestor
68
- return false;
69
- }
70
-
71
- /**
72
- * normalized difference in screen-space error between two patches
73
- * @param {PatchRepresentation} a
74
- * @param {PatchRepresentation} b
75
- * @returns {number}
76
- */
77
- function compute_patch_screen_error_difference(a, b) {
78
-
79
- const a_radius = a.bounding_sphere[3];
80
- const b_radius = b.bounding_sphere[3];
81
-
82
- const abs_delta = Math.abs(a_radius - b_radius);
83
-
84
- return abs_delta / max2(a_radius, b_radius);
85
- }
86
-
87
- /**
88
- * A dependency between A and B will not introduce a chain (unless all the clusters in the chain share vertices)
89
- * @param {PatchRepresentation} a
90
- * @param {PatchRepresentation} b
91
- * @returns {boolean}
92
- */
93
- function creates_dependency_chain(a, b) {
94
- const a_dependencies = a.dependencies;
95
- const a_dependencies_count = a_dependencies.length;
96
- if (a_dependencies_count === 0 && b.dependencies.length === 0) {
97
- return false;
98
- }
99
-
100
- // get all dependencies
101
- const open = [a, b];
102
-
103
- /**
104
- *
105
- * @type {Set<number>}
106
- */
107
- let shared_neighbours = compute_patches_shared_vertices(a, b);
108
-
109
- const dependencies_in_chain = new Set();
110
-
111
- while (open.length > 0) {
112
- const link = open.pop();
113
-
114
- dependencies_in_chain.add(link);
115
-
116
- const link_dependencies = link.dependencies;
117
-
118
- const link_dependency_count = link_dependencies.length;
119
- for (let i = 0; i < link_dependency_count; i++) {
120
- const dep = link_dependencies[i];
121
-
122
- if (dependencies_in_chain.has(dep)) {
123
- // already processed
124
- continue;
125
- }
126
-
127
- if (open.indexOf(dep) !== -1) {
128
- // already in the queue
129
- continue;
130
- }
131
-
132
- // check dependency vertices
133
- shared_neighbours = compute_set_intersection(shared_neighbours, dep.vertices_shared);
134
-
135
- if (shared_neighbours.size === 0) {
136
- // creates a chain, not all dependencies share vertices
137
- return true;
138
- }
139
-
140
- open.push(dep);
141
- }
142
- }
143
-
144
- return false;
145
-
146
- }
147
-
148
- /**
149
- * @param {TopoMesh} t
150
- */
151
- function cleanup_disconnected_faces(t) {
152
-
153
- const faces = t.getFaces();
154
-
155
- for (let face of faces) {
156
-
157
- if (face.edges.length < 3) {
158
- // cut
159
- faces.delete(face);
160
- }
161
- }
162
- }
163
-
164
- /**
165
- *
166
- * @param {PatchRepresentation} patch
167
- */
168
- function build_patch_topology_mask_from_children(patch) {
169
- const t = patch.topology_mask;
170
-
171
- const child_a = patch.children[0];
172
- const mask_a = child_a.topology_mask;
173
- t.injectManyFaces(mask_a.getFaces());
174
-
175
- const child_b = patch.children[1];
176
- const mask_b = child_b.topology_mask;
177
- t.injectManyFaces(mask_b.getFaces());
178
-
179
-
180
- // cleanup disconnected faces
181
- cleanup_disconnected_faces(t);
182
- }
183
-
184
- /**
185
- *
186
- * @param {PatchRepresentation} root
187
- * @param {Map<number,PatchRepresentation[]>} result
188
- */
189
- function map_hierarchy_vertices(root, result) {
190
- const leaves = root.collectNodes(p => p.lod === 0);
191
-
192
- for (let i = 0; i < leaves.length; i++) {
193
- const leaf = leaves[i];
194
-
195
- const vertices = leaf.topology_mask.vertices;
196
-
197
- for (let j = 0; j < vertices.length; j++) {
198
- const vertex = vertices[j];
199
-
200
- const vertex_index = vertex.index;
201
-
202
- let participants = result.get(vertex_index);
203
-
204
- if (participants === undefined) {
205
- participants = [];
206
- result.set(vertex_index, participants);
207
- }
208
-
209
- let p = leaf;
210
-
211
- while (p !== null) {
212
- array_push_if_unique(participants, p);
213
-
214
- p.vertices_included.add(vertex_index);
215
-
216
- p = p.parent;
217
- }
218
-
219
- }
220
- }
221
- }
222
-
223
- /**
224
- *
225
- * @param {PatchRepresentation} patch
226
- * @param {Map<number, PatchRepresentation[]>} vertex_patch_map
227
- */
228
- function compute_border_vertices(patch, vertex_patch_map) {
229
-
230
- main:for (const v of patch.vertices_included) {
231
-
232
- const containing_patches = vertex_patch_map.get(v);
233
-
234
-
235
- for (const c of containing_patches) {
236
- if (c.lod > patch.lod) {
237
- continue;
238
- }
239
-
240
- if (!c.isDescendantOf(patch)) {
241
- // interior
242
- continue main;
243
- }
244
- }
245
-
246
- //
247
- patch.vertices_shared.add(v);
248
- }
249
- }
250
-
251
- /**
252
- *
253
- * @param {PatchRepresentation} root
254
- * @param {TopoMesh} mesh
255
- */
256
- export function build_simplified_clusters(root, mesh) {
257
- /**
258
- *
259
- * @type {PatchRepresentation[]}
260
- */
261
- const intermediate_nodes = [];
262
-
263
- /**
264
- *
265
- * @type {PatchRepresentation[][]}
266
- */
267
- const lod_buckets = [];
268
-
269
- /**
270
- *
271
- * @type {Map<number, PatchRepresentation[]>}
272
- */
273
- const vertex_patch_map = new Map();
274
-
275
- map_hierarchy_vertices(root, vertex_patch_map);
276
-
277
- root.traverse(n => {
278
- const lod = n.lod;
279
- if (lod > 0) {
280
- intermediate_nodes.push(n);
281
-
282
- compute_border_vertices(n, vertex_patch_map);
283
- }
284
-
285
- const bucket = lod_buckets[lod];
286
-
287
- if (bucket !== undefined) {
288
- bucket.push(n);
289
- } else {
290
- lod_buckets[lod] = [n];
291
- }
292
-
293
- });
294
-
295
-
296
- /**
297
- *
298
- * @param {PatchRepresentation} patch
299
- * @returns {number} lower = better fitness
300
- */
301
- function score_by_border(patch) {
302
- let total_vertex_count = 0;
303
- const shared_vertices = new Set();
304
-
305
- for (let i = 0; i < patch.children.length; i++) {
306
- const child = patch.children[i];
307
-
308
- child.vertices_shared.forEach(s => {
309
- if (shared_vertices.has(s)) {
310
- shared_vertices.delete(s);
311
- } else {
312
- shared_vertices.add(s);
313
- }
314
- });
315
-
316
- total_vertex_count += child.topology_mask.vertices.length;
317
- }
318
-
319
- // compute proportion of inner to outer vertices in the combined patch
320
- const shared_vertex_count = shared_vertices.size;
321
- const interior_vertices = total_vertex_count - shared_vertex_count;
322
-
323
- return -shared_vertex_count / (interior_vertices + 0.01);
324
- }
325
-
326
- /**
327
- *
328
- * @type {BinaryHeap<PatchRepresentation>}
329
- */
330
- const heap = new FastBinaryHeap(score_by_border);
331
-
332
- // TODO perform simplification directly on the source mesh
333
-
334
-
335
- // keep global quadratics set
336
-
337
- /**
338
- *
339
- * @type {Map<number, Quadratic3>}
340
- */
341
- const vertex_quadratics = new Map();
342
-
343
- build_vertex_quadratics({ mesh: mesh, quadratics: vertex_quadratics });
344
-
345
- let total_relaxed_vertex_count = 0;
346
- let rejection_count_shared_vertices = 0;
347
- let rejection_count_depth = 0;
348
- let rejection_count_error = 0;
349
- let rejection_count_chain = 0;
350
-
351
- // build simplified meshes for each level of LOD
352
- for (let i = 1; i < lod_buckets.length; i++) {
353
- const lod_bucket = lod_buckets[i];
354
-
355
- const bucket_size = lod_bucket.length;
356
-
357
- // push children's topology
358
- for (let j = 0; j < bucket_size; j++) {
359
- const patch = lod_bucket[j];
360
-
361
-
362
- // build face mask
363
- build_patch_topology_mask_from_children(patch);
364
- }
365
-
366
-
367
- // push all patches to the queue
368
- for (let j = 0; j < bucket_size; j++) {
369
- const patch = lod_bucket[j];
370
-
371
- heap.push(patch);
372
- }
373
-
374
- while (!heap.isEmpty()) {
375
- /**
376
- *
377
- * @type {PatchRepresentation}
378
- */
379
- const patch = heap.pop();
380
-
381
-
382
- /**
383
- *
384
- * @type {Set<number>}
385
- */
386
- const restricted_vertices = new Set();
387
-
388
- compute_set_of_border_vertex_indices(restricted_vertices, patch.topology_mask);
389
-
390
- const initial_restricted_vertex_count = restricted_vertices.size;
391
-
392
- /*
393
- consider relaxing boundary constraints for this patch
394
- Relaxing constraints forces both patches to be refined together to assure crack-free boundaries,
395
- which degrades runtime performance but allows for better mesh simplification
396
- */
397
- const neighbours = patch.neighbours;
398
- const neighbour_count = neighbours.length;
399
- const patch_dependencies = patch.dependencies;
400
- for (let j = 0; j < neighbour_count; j++) {
401
- // continue;
402
- const neighbour = neighbours[j];
403
-
404
- if (!heap.contains(neighbour)) {
405
- // neighbour is not at the same level in the hierarchy
406
- continue;
407
- }
408
-
409
- if (patch.dependencies.indexOf(neighbour) !== -1) {
410
- // already dependent
411
- continue;
412
- }
413
-
414
-
415
- if (compute_patch_screen_error_difference(patch, neighbour) > 0.2) {
416
- /*
417
- A and B have similar error-range
418
- condition discourages dependencies between those clusters that are
419
- unlikely to be simultaneously present in the ACL at runtime
420
- */
421
- rejection_count_error++;
422
- continue;
423
- }
424
-
425
- if (patches_share_ancestor_within_depth(patch, neighbour, 2)) {
426
- /*
427
- A and B will not be merged within a small number of levels up the cluster hierarchy.
428
- This condition avoids creating dependencies between clusters that are resolved within only a few additional hierarchy levels.
429
- */
430
- rejection_count_depth++;
431
- continue;
432
- }
433
-
434
-
435
- const shared_vertices = compute_patches_shared_vertices(patch, neighbour);
436
- const shared_vertex_count = shared_vertices.size;
437
-
438
- if (shared_vertex_count < BOUNDARY_RELAXATION_SHARED_VERTEX_THRESHOLD) {
439
- // too few vertices are shared, relaxing boundary constraint is not worth while
440
- rejection_count_shared_vertices++;
441
- continue;
442
- }
443
- if (creates_dependency_chain(patch, neighbour)) {
444
- // condition prevents long dependency chains and preserves selective refinement at the cluster level
445
- rejection_count_chain++;
446
- continue;
447
- }
448
-
449
- // register dependency
450
- array_push_if_unique(patch_dependencies, neighbour);
451
- array_push_if_unique(neighbour.dependencies, patch);
452
-
453
- }
454
-
455
- const dependency_count = patch_dependencies.length;
456
-
457
- if (dependency_count > 0) {
458
- // relax vertex constraints
459
- const vs = [];
460
- vertex_loop:for (const v of restricted_vertices) {
461
- const participating_patches = vertex_patch_map.get(v);
462
-
463
- for (let k = 0; k < dependency_count; k++) {
464
- const dependency = patch_dependencies[k];
465
-
466
- if (participating_patches.indexOf(dependency) === -1) {
467
- continue vertex_loop;
468
- }
469
- }
470
-
471
-
472
- // vertex is fully dependent, can relax
473
- restricted_vertices.delete(v);
474
- vs.push(v);
475
- }
476
-
477
- for (let j = 0; j < vs.length; j++) {
478
- const v = vs[j];
479
-
480
- restricted_vertices.delete(v);
481
- }
482
-
483
- }
484
-
485
- const relaxed_restricted_vertices_count = restricted_vertices.size;
486
-
487
- const relaxed_vertex_count = initial_restricted_vertex_count - relaxed_restricted_vertices_count;
488
-
489
- total_relaxed_vertex_count += relaxed_vertex_count;
490
-
491
-
492
- const num_desired_faces_to_remove = max2(0, patch.topology_mask.getFaces().size - MICRON_PATCH_SIZE_MAX);
493
-
494
- if (num_desired_faces_to_remove > 0) {
495
-
496
- /**
497
- *
498
- * @type {BinaryHeap<EdgeCollapseCandidate>}
499
- */
500
- const open_set = new FastBinaryHeap(extract_edge_cost);
501
-
502
- /**
503
- *
504
- * @type {Map<TopoEdge, EdgeCollapseCandidate>}
505
- */
506
- const edge_to_collapse_map = new Map();
507
-
508
- build_edge_collapse_candidates(
509
- patch.topology_mask,
510
- open_set,
511
- edge_to_collapse_map,
512
- vertex_quadratics,
513
- restricted_vertices
514
- );
515
-
516
- // execute mesh simplification
517
-
518
- collapse_edges(
519
- num_desired_faces_to_remove,
520
- open_set,
521
- [],
522
- mesh,
523
- edge_to_collapse_map,
524
- vertex_quadratics,
525
- restricted_vertices
526
- );
527
- collapse_all_degenerate_edges(patch.topology_mask.getEdges(), mesh);
528
-
529
- }
530
-
531
- }
532
-
533
- // snapshot patch topology
534
- for (let j = 0; j < bucket_size; j++) {
535
- const patch = lod_bucket[j];
536
-
537
- // cleanup mask
538
- cleanup_disconnected_faces(patch.topology_mask);
539
- collapse_all_degenerate_edges(patch.topology_mask.getEdges(), patch.topology_mask);
540
-
541
- // snapshot the mask
542
- patch.snapshotTopology();
543
- }
544
-
545
- }
546
-
547
- }
@@ -1,140 +0,0 @@
1
- import { computePatchMergeScore } from "./computePatchMergeScore.js";
2
- import { array_remove_first } from "../../../../../core/collection/array/array_remove_first.js";
3
- import { patch_combine } from "./patch_combine.js";
4
-
5
- /**
6
- * Ok, so there is no neighbour. No connection between patches,
7
- * but we need to build a single hierarchy,
8
- * so let's find the most suitable candidate to merge with
9
- * @param {PatchRepresentation} source
10
- * @param {PatchRepresentation[]} pool
11
- * @returns {number} index of the best candidate
12
- */
13
- function synthesizeNeighbour(source, pool) {
14
- const open_set_size = pool.length;
15
-
16
- let best_score = Number.NEGATIVE_INFINITY;
17
- let best_candidate = -1;
18
-
19
- for (let i = 0; i < open_set_size; i++) {
20
- const other = pool[i];
21
-
22
- const score = computePatchMergeScore(source, other);
23
-
24
- if (score > best_score) {
25
- best_candidate = i;
26
- best_score = score;
27
- }
28
- }
29
-
30
-
31
- return best_candidate;
32
- }
33
-
34
- /**
35
- *
36
- * @param {PatchRepresentation} source
37
- * @param {PatchRepresentation[]} open_set
38
- * @returns {PatchRepresentation}
39
- */
40
- function pickBestNeighbourForMerge(source, open_set) {
41
- const neighbours = source.neighbours;
42
- const neighbour_count = neighbours.length;
43
-
44
- let best_neighbour_score = Number.NEGATIVE_INFINITY;
45
- let best_neighbour = undefined;
46
-
47
- for (let i = 0; i < neighbour_count; i++) {
48
- const neighbour = neighbours[i];
49
-
50
- if (open_set.indexOf(neighbour) === -1) {
51
- // not in open set, already part of the hierarchy
52
- continue;
53
- }
54
-
55
- const score = computePatchMergeScore(source, neighbour);
56
-
57
- if (score > best_neighbour_score) {
58
- best_neighbour = neighbour;
59
- best_neighbour_score = score;
60
- }
61
- }
62
-
63
- return best_neighbour;
64
- }
65
-
66
- /**
67
- * @see QVDR paper
68
- * @returns {PatchRepresentation}
69
- * @param {PatchRepresentation[]} leaves
70
- */
71
- function build_tree(leaves) {
72
- if (leaves.length === 0) {
73
- throw new Error('Number of leaves must be at least 1, none were given');
74
- }
75
- //
76
- // console.time('build merge graph');
77
- // const leaf_cluster_weight_graph = build_merge_graph(leaves);
78
- // console.timeEnd('build merge graph');
79
-
80
-
81
- const open_set = leaves.slice();
82
-
83
-
84
- /**
85
- *
86
- * @type {PatchRepresentation[]}
87
- */
88
- const neighbourless = [];
89
-
90
- while (open_set.length > 1) {
91
- const candidate_0 = open_set.shift();
92
-
93
- // pick neighbour to combine with
94
- const candidate_1 = pickBestNeighbourForMerge(candidate_0, open_set);
95
-
96
- if (candidate_1 === undefined) {
97
- // no neighbour
98
- neighbourless.push(candidate_0);
99
- continue;
100
- }
101
-
102
- // cut second node from open set
103
- array_remove_first(open_set, candidate_1);
104
-
105
- const merged = patch_combine(candidate_0, candidate_1, true);
106
-
107
- // add to set
108
- open_set.push(merged);
109
- }
110
-
111
- if (neighbourless.length > 0 && open_set.length > 0) {
112
- // move conventional root to the neighbourless set
113
- neighbourless.push(open_set[0]);
114
-
115
- // handle patch groups without neighbours
116
- while (neighbourless.length > 1) {
117
- const candidate_0 = neighbourless.shift();
118
-
119
- const candidate_1_index = synthesizeNeighbour(candidate_0, neighbourless);
120
-
121
- if (candidate_1_index === -1) {
122
- // this should never happen
123
- throw new Error('No candidate found');
124
- }
125
- const candidate_1 = neighbourless[candidate_1_index];
126
-
127
- neighbourless.splice(candidate_1_index, 1);
128
-
129
- const merged = patch_combine(candidate_0, candidate_1, false);
130
-
131
- open_set.push(merged);
132
- }
133
-
134
- // move to open set for return
135
- open_set[0] = neighbourless[0];
136
- }
137
-
138
-
139
- return open_set[0];
140
- }