@woosh/meep-engine 2.48.20 → 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 (94) hide show
  1. package/package.json +1 -1
  2. package/src/engine/graphics/micron/MICRON_GEOMETRY_FIELD.js +0 -1
  3. package/src/engine/graphics/micron/MICRON_URI_FIELD.js +0 -1
  4. package/src/engine/graphics/micron/build/MICRON_PATCH_SIZE_MAX.js +0 -5
  5. package/src/engine/graphics/micron/build/PatchRepresentation.js +0 -424
  6. package/src/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +0 -311
  7. package/src/engine/graphics/micron/build/build_geometry_info.js +0 -21
  8. package/src/engine/graphics/micron/build/clustering/assignInitialPatchNeighbours.js +0 -63
  9. package/src/engine/graphics/micron/build/clustering/assign_patch_neighbours_from_topology.js +0 -46
  10. package/src/engine/graphics/micron/build/clustering/build_clustering_2.js +0 -37
  11. package/src/engine/graphics/micron/build/clustering/build_leaf_patches.js +0 -326
  12. package/src/engine/graphics/micron/build/clustering/build_leaf_patches_metis.js +0 -76
  13. package/src/engine/graphics/micron/build/clustering/computeBorderLengthChange.js +0 -59
  14. package/src/engine/graphics/micron/build/clustering/computeFaceCurvatureScore.js +0 -57
  15. package/src/engine/graphics/micron/build/clustering/computeOpenFaceFreedom.js +0 -35
  16. package/src/engine/graphics/micron/build/clustering/compute_face_connection_weight.js +0 -35
  17. package/src/engine/graphics/micron/build/clustering/populateOpenFaceNeighboursForPatch.js +0 -56
  18. package/src/engine/graphics/micron/build/clustering/validate_leaf_patch_connectivity.js +0 -44
  19. package/src/engine/graphics/micron/build/compute_micron_buffer_array_constructor.js +0 -24
  20. package/src/engine/graphics/micron/build/compute_vertex_remap_cost.js +0 -29
  21. package/src/engine/graphics/micron/build/debug/build_clustering_info.js +0 -58
  22. package/src/engine/graphics/micron/build/debug/build_graph_info.js +0 -59
  23. package/src/engine/graphics/micron/build/fill_patch_geometry_data.js +0 -270
  24. package/src/engine/graphics/micron/build/hierarchy/buildAbstractPatchHierarchy.js +0 -196
  25. package/src/engine/graphics/micron/build/hierarchy/build_intermediate_patch_topology.js +0 -162
  26. package/src/engine/graphics/micron/build/hierarchy/build_merge_graph.js +0 -89
  27. package/src/engine/graphics/micron/build/hierarchy/computePatchMergeScore.js +0 -146
  28. package/src/engine/graphics/micron/build/hierarchy/compute_patches_shared_vertex_count.js +0 -32
  29. package/src/engine/graphics/micron/build/hierarchy/compute_patches_shared_vertices.js +0 -34
  30. package/src/engine/graphics/micron/build/hierarchy/merge_patches.js +0 -581
  31. package/src/engine/graphics/micron/build/hierarchy/metis_cluster_clusters.js +0 -53
  32. package/src/engine/graphics/micron/build/hierarchy/optimize_graph_partitioning_balance.js +0 -515
  33. package/src/engine/graphics/micron/build/hierarchy/patch_combine.js +0 -180
  34. package/src/engine/graphics/micron/build/hierarchy/patch_fill_holes_by_uncollapse.js +0 -60
  35. package/src/engine/graphics/micron/build/hierarchy/patch_stitch_parent_border.js +0 -320
  36. package/src/engine/graphics/micron/build/hierarchy/qvdr_build_simplified_clusters.js +0 -547
  37. package/src/engine/graphics/micron/build/hierarchy/qvdr_build_tree.js +0 -140
  38. package/src/engine/graphics/micron/buildPatchwork.js +0 -68
  39. package/src/engine/graphics/micron/convert_three_object_to_micron.js +0 -179
  40. package/src/engine/graphics/micron/debug/VirtualGeometryStats.js +0 -42
  41. package/src/engine/graphics/micron/format/MICRON_GEOMETRY_PROPERTY_NAME.js +0 -1
  42. package/src/engine/graphics/micron/format/MicronGeometry.d.ts +0 -21
  43. package/src/engine/graphics/micron/format/MicronGeometry.js +0 -334
  44. package/src/engine/graphics/micron/format/MicronGeometryPatch.d.ts +0 -3
  45. package/src/engine/graphics/micron/format/MicronGeometryPatch.js +0 -205
  46. package/src/engine/graphics/micron/format/MicronGeometryPatchOccurance.js +0 -50
  47. package/src/engine/graphics/micron/format/ThreeMicronMesh.d.ts +0 -10
  48. package/src/engine/graphics/micron/format/ThreeMicronMesh.js +0 -45
  49. package/src/engine/graphics/micron/format/VirtualGeometry.js +0 -158
  50. package/src/engine/graphics/micron/format/micron_build_proxy_geometry.js +0 -205
  51. package/src/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.js +0 -123
  52. package/src/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.spec.js +0 -63
  53. package/src/engine/graphics/micron/format/serialization/collection/geometry_collection_serialization.js +0 -83
  54. package/src/engine/graphics/micron/format/serialization/collection/geometry_collection_serialization.spec.js +0 -51
  55. package/src/engine/graphics/micron/format/serialization/deserialize_attribute_spec.js +0 -25
  56. package/src/engine/graphics/micron/format/serialization/deserialize_patch.js +0 -106
  57. package/src/engine/graphics/micron/format/serialization/serialize_attribute_spec.js +0 -18
  58. package/src/engine/graphics/micron/format/serialization/serialize_patch.js +0 -84
  59. package/src/engine/graphics/micron/format/validate_patch_bounds.js +0 -69
  60. package/src/engine/graphics/micron/plugin/GLTFAssetTransformer.js +0 -265
  61. package/src/engine/graphics/micron/plugin/GLTF_MICRON_ID_FIELD.js +0 -5
  62. package/src/engine/graphics/micron/plugin/MicronRenderPlugin.d.ts +0 -8
  63. package/src/engine/graphics/micron/plugin/MicronRenderPlugin.js +0 -150
  64. package/src/engine/graphics/micron/plugin/serialization/BufferGeometrySerializationAdapter.js +0 -176
  65. package/src/engine/graphics/micron/plugin/shaded_geometry/MicronShadedGeometryRenderAdapter.js +0 -216
  66. package/src/engine/graphics/micron/prototypeMicronProxyBuild.js +0 -227
  67. package/src/engine/graphics/micron/prototypeVirtualGeometry.js +0 -911
  68. package/src/engine/graphics/micron/render/PatchCacheKey.js +0 -79
  69. package/src/engine/graphics/micron/render/VIRTUAL_MESH_FLAG.d.ts +0 -1
  70. package/src/engine/graphics/micron/render/VIRTUAL_MESH_FLAG.js +0 -1
  71. package/src/engine/graphics/micron/render/VirtualGeometryBuilder.js +0 -207
  72. package/src/engine/graphics/micron/render/approximateTriangleArea.js +0 -25
  73. package/src/engine/graphics/micron/render/culling/PatchCullingSystem.js +0 -129
  74. package/src/engine/graphics/micron/render/instanced/PatchDataTextures.js +0 -329
  75. package/src/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +0 -175
  76. package/src/engine/graphics/micron/render/instanced/shader/constants.js +0 -3
  77. package/src/engine/graphics/micron/render/instanced/shader/gen_micron_vertex_attribute_texture_name.js +0 -8
  78. package/src/engine/graphics/micron/render/instanced/shader/shader_rewrite_standard.js +0 -250
  79. package/src/engine/graphics/micron/render/makeThreeMeshFromVirtualGeometry.js +0 -37
  80. package/src/engine/graphics/micron/render/refinement/ActivePatchFlags.js +0 -8
  81. package/src/engine/graphics/micron/render/refinement/ActivePatchList.js +0 -241
  82. package/src/engine/graphics/micron/render/refinement/ActivePatchRecord.js +0 -154
  83. package/src/engine/graphics/micron/render/refinement/RefinementSpec.js +0 -84
  84. package/src/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +0 -133
  85. package/src/engine/graphics/micron/render/refinement/is_patch_facing_back.js +0 -43
  86. package/src/engine/graphics/micron/render/refinement/is_patch_visible.js +0 -37
  87. package/src/engine/graphics/micron/render/v1/MaterialContext.js +0 -150
  88. package/src/engine/graphics/micron/render/v1/MaterialVertexSpec.js +0 -115
  89. package/src/engine/graphics/micron/render/v1/MicronRenderContext.js +0 -145
  90. package/src/engine/graphics/micron/render/v1/ThreeVirtualGeometryAdapter.js +0 -255
  91. package/src/engine/graphics/micron/render/v1/VGThreeRenderer.js +0 -142
  92. package/src/engine/graphics/micron/render/v1/getTransformedPositionsCached.js +0 -54
  93. package/src/engine/graphics/micron/simplifyGeometry.js +0 -26
  94. package/src/engine/graphics/micron/util/patchToBufferGeometry.js +0 -19
@@ -1,515 +0,0 @@
1
- import { graph_k_means_cluster_detailed } from "../../../../../core/graph/graph_k_means_cluster.js";
2
- import { array_remove_first } from "../../../../../core/collection/array/array_remove_first.js";
3
-
4
- /**
5
- *
6
- * @param {number[]} G
7
- * @param {number[]} T
8
- * @param {number[]} C
9
- * @param {number} k
10
- * @param {number[]} node_cluster_assignment
11
- * @param {number[][]} parts
12
- * @returns {number}
13
- */
14
- function process_cycle(
15
- G,
16
- T,
17
- C,
18
- k,
19
- node_cluster_assignment,
20
- parts
21
- ) {
22
- let ops = 0;
23
- let j = 0;
24
- for (let i = 0; i < k; i++, j = i) {
25
- if (C[i] !== 255 || T[j] < 0) {
26
- continue;
27
- }
28
-
29
- while (C[j] === 255 && T[j] >= 0) {
30
- C[j] = i;
31
- j = T[j];
32
- }
33
-
34
- if (C[j] === i && T[j] >= 0) {
35
- do {
36
- const node_index = G[j];
37
- const destination_cluster_index = T[j];
38
-
39
- const source_cluster_index = node_cluster_assignment[node_index];
40
-
41
- if (source_cluster_index !== destination_cluster_index) {
42
-
43
- // rewrite assignment
44
- node_cluster_assignment[node_index] = destination_cluster_index;
45
-
46
- // move between part arrays
47
- array_remove_first(parts[source_cluster_index], node_index);
48
- parts[destination_cluster_index].push(node_index);
49
-
50
- ops++;
51
- } else {
52
- // no movement
53
- // break;
54
- }
55
-
56
- j = destination_cluster_index;
57
- } while (C[j] === i);
58
- }
59
- }
60
-
61
- return ops;
62
- }
63
-
64
- const move_suggestion = {
65
- t: 0,
66
- g: 0
67
- };
68
-
69
- /**
70
- * Algorithm GreedyCompute for a part to compute which node to go and where
71
- * @param {number} part_index
72
- * @param {number[][]} parts part
73
- * @param {number} k number of partitions
74
- * @param {Graph<T>} graph
75
- * @param {T[]} node_array
76
- * @param {number[]} node_cluster_assignment
77
- * @param {Float32Array} pressure_vector
78
- * @param {Uint8Array} visited_vector
79
- * @param {Map<T, number>} node_index_map
80
- */
81
- function greedy_compute(
82
- part_index,
83
- parts,
84
- k,
85
- graph,
86
- node_array,
87
- node_cluster_assignment,
88
- node_index_map,
89
- pressure_vector,
90
- visited_vector
91
- ) {
92
-
93
-
94
- let best_node_pressure = 1;
95
- let best_overall_gain = Number.NEGATIVE_INFINITY
96
-
97
- let i, j;
98
-
99
- const part = parts[part_index];
100
-
101
- const part_size = part.length;
102
-
103
- for (i = 0; i < k; i++) {
104
-
105
- if (i === part_index) {
106
- // skip self
107
- continue;
108
- }
109
-
110
- const cluster_size = parts[i].length;
111
-
112
- pressure_vector[i] = part_size / (cluster_size + 0.01);
113
- }
114
-
115
- for (i = 0; i < part_size; i++) {
116
- // reset gain vector
117
- visited_vector.fill(0);
118
-
119
- const node_index = part[i];
120
-
121
- // de-reference actual node
122
- const node = node_array[node_index];
123
-
124
- // get neighbours of node
125
- const node_container = graph.getNodeContainer(node);
126
- const edges = node_container.getEdges();
127
-
128
- // lets consider where this node might move
129
- const edge_count = edges.length;
130
-
131
- for (let i1 = 0; i1 < edge_count; i1++) {
132
- const edge = edges[i1];
133
-
134
- const neighbour = edge.other(node);
135
-
136
- const neighbour_index = node_index_map.get(neighbour);
137
-
138
- const neighbour_cluster_index = node_cluster_assignment[neighbour_index];
139
-
140
- visited_vector[neighbour_cluster_index] = 1;
141
- }
142
-
143
- // find X such that Gv[x] is highest value
144
-
145
- for (j = 0; j < k; j++) {
146
-
147
- if (j === part_index) {
148
- continue;
149
- }
150
-
151
- if (visited_vector[j] === 0) {
152
- continue;
153
- }
154
-
155
- const pressure = pressure_vector[j];
156
-
157
- if (pressure < best_node_pressure) {
158
- continue;
159
- } else {
160
- best_node_pressure = pressure;
161
- }
162
-
163
- const gain = compute_node_move_cost(
164
- graph,
165
- node_container,
166
- part_index,
167
- j,
168
- node_array,
169
- node_cluster_assignment,
170
- node_index_map
171
- );
172
-
173
- if (gain > best_overall_gain) {
174
- // update gain
175
- move_suggestion.g = node_index;
176
- move_suggestion.t = j;
177
-
178
- best_overall_gain = gain;
179
- }
180
- }
181
-
182
- }
183
-
184
- return best_overall_gain;
185
- }
186
-
187
- /**
188
- *
189
- * @param {number} node_index
190
- * @param {number} destination_cluster_index
191
- * @param {number} source_cluster_index
192
- * @param {number[]} node_cluster_assignment
193
- * @param {number[][]} parts
194
- */
195
- function pass_node(
196
- node_index,
197
- destination_cluster_index,
198
- source_cluster_index,
199
- node_cluster_assignment,
200
- parts
201
- ) {
202
-
203
- // rewrite assignment
204
- node_cluster_assignment[node_index] = destination_cluster_index;
205
-
206
- // move between part arrays
207
- array_remove_first(parts[source_cluster_index], node_index);
208
- parts[destination_cluster_index].push(node_index);
209
-
210
- }
211
-
212
- /**
213
- * @template T
214
- * @param {number} k
215
- * @param {number[][]} parts
216
- * @param {Graph<T>} graph
217
- * @param {T[]} node_array
218
- * @param {number[]} node_cluster_assignment
219
- * @param {Map<T, number>} node_index_map
220
- */
221
- function greedy_cycle(
222
- k,
223
- parts,
224
- graph,
225
- node_array,
226
- node_cluster_assignment,
227
- node_index_map
228
- ) {
229
- if (k > 127) {
230
- throw new Error('Too many parts, algorithm only supports 127');
231
- }
232
-
233
- const n = node_array.length;
234
-
235
- const pressure_vector = new Float32Array(k);
236
- const visited_vector = new Uint8Array(k);
237
-
238
- const balance_lower_limit = Math.floor(n / k);
239
- const balance_upper_limit = Math.ceil(n / k);
240
-
241
- let step_op_count, i, balanced;
242
-
243
- move_suggestion.g = -1;
244
- move_suggestion.t = -1;
245
-
246
- do {
247
- balanced = true;
248
-
249
- for (i = 0; i < k; i++) {
250
- const cluster = parts[i];
251
- const cluster_size = cluster.length;
252
- if (cluster_size < balance_lower_limit || cluster_size > balance_upper_limit) {
253
- balanced = false;
254
- }
255
- }
256
-
257
- if (balanced) {
258
- // already balanced, stop here
259
- break;
260
- }
261
-
262
- step_op_count = 0;
263
-
264
- for (i = 0; i < k; i++) {
265
-
266
- greedy_compute(
267
- i,
268
- parts,
269
- k,
270
- graph,
271
- node_array,
272
- node_cluster_assignment,
273
- node_index_map,
274
- pressure_vector,
275
- visited_vector
276
- );
277
-
278
- const target_cluster = move_suggestion.t;
279
-
280
- if (target_cluster === -1) {
281
- // no target
282
- continue;
283
- }
284
-
285
- const node_index = move_suggestion.g;
286
-
287
- pass_node(node_index, target_cluster, i, node_cluster_assignment, parts);
288
-
289
- move_suggestion.g = -1;
290
- move_suggestion.t = -1;
291
-
292
- step_op_count++;
293
- }
294
-
295
- }
296
- while (step_op_count > 0);
297
- }
298
-
299
- /**
300
- * compute total weight of edges that will be fully within the target cluster
301
- * @template T
302
- * @param {Graph<T,WeightedEdge<T>>} graph
303
- * @param {NodeContainer<T>} node_container
304
- * @param {number} source_cluster
305
- * @param {number} target_cluster
306
- * @param {T[]} node_array
307
- * @param {number[]} node_cluster_assignments Node to cluster references
308
- * @returns {number} lower is better
309
- * @param {Map<T, number>} node_index_map
310
- */
311
- function compute_node_move_cost(
312
- graph,
313
- node_container,
314
- source_cluster,
315
- target_cluster,
316
- node_array,
317
- node_cluster_assignments,
318
- node_index_map
319
- ) {
320
- let weight_gain = 0;
321
-
322
- const existing_edges = node_container.getEdges();
323
-
324
- const node = node_container.node;
325
-
326
- // find edges that make up the current cut
327
- const existing_edge_count = existing_edges.length;
328
-
329
- for (let i = 0; i < existing_edge_count; i++) {
330
- const edge = existing_edges[i];
331
-
332
- const node_neighbour = edge.other(node);
333
-
334
- const neighbour_index = node_index_map.get(node_neighbour);
335
-
336
- const neighbour_cluster_index = node_cluster_assignments[neighbour_index];
337
-
338
- if (neighbour_cluster_index === target_cluster) {
339
- // this edge will be consumed by the new cluster and will be removed from current cut
340
- weight_gain += edge.weight;
341
- } else if (neighbour_cluster_index === source_cluster) {
342
- weight_gain -= edge.weight;
343
- }
344
- }
345
-
346
- return weight_gain;
347
- }
348
-
349
- /**
350
- * Based on GreedyCycle algorithm
351
- * @see Fast Approximate Graph Partitioning Algorithms
352
- * @template T
353
- * @param {Graph<T>} graph
354
- * @param {T[][]} parts
355
- * @param {T[]} node_array
356
- * @param {number[]} node_cluster_assignments Node to cluster references
357
- */
358
- function optimize_graph_partitioning_balance(
359
- graph,
360
- parts,
361
- node_array,
362
- node_cluster_assignments
363
- ) {
364
- let optimization_op_count_step = 0;
365
-
366
- const node_count = node_array.length;
367
-
368
- const partition_count = parts.length;
369
-
370
- const upper_cluster_size_bound = Math.ceil(node_count / partition_count);
371
- const lower_cluster_size_bound = Math.floor(node_count / partition_count);
372
-
373
- // quick check if partitions are already optimal
374
- let optimal_cluster_sizes = true;
375
- for (let i = 0; i < partition_count; i++) {
376
- const part = parts[i];
377
-
378
- const cluster_size = part.length;
379
- if (cluster_size < lower_cluster_size_bound || cluster_size > upper_cluster_size_bound) {
380
- optimal_cluster_sizes = false;
381
- break;
382
- }
383
- }
384
-
385
- if (optimal_cluster_sizes) {
386
- return;
387
- }
388
-
389
- // compute current cut weight
390
-
391
- do {
392
- optimization_op_count_step = 0;
393
-
394
- let best_source_cluster = -1;
395
- let best_cost = 0;
396
- let best_target_node = -1;
397
- let best_target_node_origin_cluster = -1;
398
-
399
- // TODO we can compute multiple moves in a single pass
400
-
401
- for (let i = 0; i < node_count; i++) {
402
- const node = node_array[i];
403
-
404
- const node_partition_index = node_cluster_assignments[i];
405
-
406
- const source_part = parts[node_partition_index];
407
- const source_part_size = source_part.length;
408
- if (source_part_size >= upper_cluster_size_bound) {
409
- // partition is already full, skip
410
- continue;
411
- }
412
-
413
- const container = graph.getNodeContainer(node);
414
-
415
- const edges = container.getEdges();
416
-
417
- // lets consider where this node might move
418
- const edge_count = edges.length;
419
- for (let i1 = 0; i1 < edge_count; i1++) {
420
- const edge = edges[i1];
421
-
422
- const neighbour = edge.other(node);
423
-
424
- const neighbour_index = node_array.indexOf(neighbour);
425
-
426
- const neighbour_partition_index = node_cluster_assignments[neighbour_index];
427
-
428
- if (neighbour_partition_index === node_partition_index) {
429
- // belongs to the same cluster, no swap/move opportunity
430
- continue;
431
- }
432
-
433
- // if (parts[neighbour_partition_index].length <= upper_cluster_size_bound) {
434
- // neighbour partition would have too few elements
435
- // continue;
436
- // }
437
-
438
- const cost = compute_node_move_cost(graph, neighbour, neighbour_partition_index, node_partition_index, node_array, node_cluster_assignments);
439
-
440
- if (cost < best_cost) {
441
-
442
- best_source_cluster = node_partition_index;
443
- best_target_node = neighbour_index;
444
- best_cost = cost;
445
- best_target_node_origin_cluster = neighbour_partition_index;
446
- }
447
-
448
-
449
- }
450
- }
451
-
452
- if (best_source_cluster !== -1) {
453
- // do move
454
- node_cluster_assignments[best_target_node] = best_source_cluster;
455
-
456
- array_remove_first(parts[best_target_node_origin_cluster], best_target_node);
457
- parts[best_source_cluster].push(best_target_node);
458
-
459
- optimization_op_count_step++;
460
- } else {
461
- for (let i = 0; i < parts.length; i++) {
462
- if (parts[i].length > upper_cluster_size_bound) {
463
-
464
- debugger;
465
- }
466
- }
467
- }
468
-
469
- } while (optimization_op_count_step > 0);
470
- }
471
-
472
- /**
473
- * @template T
474
- * @param {T[]} node_array
475
- * @param {number} k
476
- * @param {Graph<T>} graph
477
- * @returns {number[][]}
478
- */
479
- export function optimize_graph_partitioning_balance_detailed(node_array, k, graph) {
480
- const node_count = node_array.length;
481
- /**
482
- *
483
- * @type {number[]}
484
- */
485
- const node_cluster_assignments = new Uint8Array(node_count);
486
- // fill with "UNASSIGNED" value
487
- node_cluster_assignments.fill(255);
488
-
489
- /**
490
- * build node index
491
- * @type {Map<T, number>}
492
- */
493
- const node_index_map = new Map();
494
-
495
- for (let i = 0; i < node_count; i++) {
496
- node_index_map.set(node_array[i], i);
497
- }
498
-
499
- const clusters = graph_k_means_cluster_detailed(node_array, k, 1249, node_cluster_assignments, node_index_map, graph);
500
-
501
- greedy_cycle(k, clusters, graph, node_array, node_cluster_assignments, node_index_map);
502
-
503
- return clusters;
504
- }
505
-
506
- /**
507
- * @template T
508
- * @param {Graph<T>} graph
509
- * @param {number} k
510
- * @returns {number[][]}
511
- */
512
- export function graph_build_balanced_partitions(graph, k) {
513
- const node_array = Array.from(graph.getNodes());
514
- return optimize_graph_partitioning_balance_detailed(node_array, k, graph);
515
- }
@@ -1,180 +0,0 @@
1
- import { PatchRepresentation } from "../PatchRepresentation.js";
2
- import { array_copy } from "../../../../../core/collection/array/copyArray.js";
3
- import { array_copy_unique } from "../../../../../core/collection/array/array_copy_unique.js";
4
- import { array_remove_first } from "../../../../../core/collection/array/array_remove_first.js";
5
- import { max2 } from "../../../../../core/math/max2.js";
6
- import { array_push_if_unique } from "../../../../../core/collection/array/array_push_if_unique.js";
7
- import {
8
- compute_bounding_sphere_of_2_spheres
9
- } from "../../../../../core/geom/3d/compute_bounding_sphere_of_2_spheres.js";
10
- import { compute_bounding_cone_of_2_cones } from "../../../../../core/geom/3d/cone/compute_bounding_cone_of_2_cones.js";
11
- import { ConicRay } from "../../../../../core/geom/ConicRay.js";
12
- import { passThrough } from "../../../../../core/function/Functions.js";
13
-
14
- /**
15
- *
16
- * @param {PatchRepresentation} r
17
- */
18
- export function compute_neighbours_from_children(r) {
19
-
20
- const this_neighbours = r.neighbours;
21
-
22
- const children = r.children;
23
-
24
- const child_count = children.length;
25
-
26
- const child_0 = children[0];
27
-
28
- array_copy(child_0.neighbours, 0, this_neighbours, 0, child_0.neighbours.length);
29
- for (let i = 1; i < child_count; i++) {
30
- const child = children[i];
31
- array_copy_unique(child.neighbours, 0, this_neighbours, this_neighbours.length, child.neighbours.length)
32
- }
33
-
34
- // remove children from own neighbourhood set
35
- for (let i = 0; i < child_count; i++) {
36
- const child = children[i];
37
- array_remove_first(this_neighbours, child);
38
- }
39
-
40
- // add self to neighbours
41
- let this_neighbour_count = this_neighbours.length;
42
- for (let i = 0; i < this_neighbour_count; i++) {
43
- const neighbour = this_neighbours[i];
44
-
45
- // remove neighbours that are part of the hierarchy
46
- if (neighbour.isDescendantOf(r)) {
47
-
48
- this_neighbours.splice(i, 1);
49
-
50
- i--;
51
- this_neighbour_count--;
52
-
53
- continue;
54
- }
55
-
56
- // link back from neighbour to this new patch
57
- array_push_if_unique(neighbour.neighbours, r);
58
- }
59
-
60
-
61
- }
62
-
63
- /**
64
- * @template T
65
- * @param {ConicRay} result
66
- * @param {T[]} inputs
67
- * @param {function(T):ConicRay} extract
68
- */
69
- function compute_bounding_cone_of_cones(result, inputs, extract = passThrough) {
70
- const open = inputs.map(extract);
71
-
72
- while (open.length > 1) {
73
- const r0 = open.shift();
74
- const r1 = open.shift();
75
-
76
- const out = new ConicRay();
77
-
78
- compute_bounding_cone_of_2_cones(out, r0, r1);
79
-
80
- open.push(out);
81
- }
82
-
83
- result.copy(open[0]);
84
- }
85
-
86
- /**
87
- * @template T
88
- * @param {number[]|vec4} result
89
- * @param {T[]} inputs
90
- * @param {function(T):(number[]|vec4)} extract
91
- */
92
- function compute_bounding_sphere_of_spheres(result, inputs, extract) {
93
- const open = inputs.map(extract);
94
-
95
- while (open.length > 1) {
96
- const r0 = open.shift();
97
- const r1 = open.shift();
98
-
99
- const out = [];
100
-
101
- compute_bounding_sphere_of_2_spheres(out, r0, r1);
102
-
103
- open.push(out);
104
- }
105
-
106
- array_copy(open[0], 0, result, 0, 4);
107
- }
108
-
109
- /**
110
- *
111
- * @param {PatchRepresentation[]} children
112
- * @returns {PatchRepresentation}
113
- */
114
- export function patch_build_parent(children) {
115
-
116
- const r = new PatchRepresentation();
117
-
118
- r.children = children;
119
-
120
- for (let i = 0; i < children.length; i++) {
121
- const child = children[i];
122
- // set parent
123
- child.parents.push(r);
124
-
125
- //figure out lod
126
- r.lod = max2(r.lod, child.lod + 1);
127
-
128
- // combine bounds
129
- // r.bounding_box.expandToFit(child.bounding_box);
130
- }
131
-
132
- // combine bounds
133
- // compute_bounding_cone_of_cones(r.normal_cone, children, c => c.normal_cone);
134
- // compute_bounding_sphere_of_spheres(r.bounding_sphere, children, t => t.bounding_sphere);
135
-
136
-
137
- return r;
138
- }
139
-
140
- /**
141
- *
142
- * @return {PatchRepresentation}
143
- * @param {PatchRepresentation} a
144
- * @param {PatchRepresentation} b
145
- * @param {boolean} is_connected are patches neighbours?
146
- */
147
- export function patch_combine(a, b, is_connected) {
148
-
149
- const r = new PatchRepresentation();
150
-
151
- //figure out lod
152
- r.lod = max2(a.lod, b.lod) + 1;
153
-
154
- r.children = [a, b];
155
-
156
- // set parent
157
- a.parent = r;
158
- b.parent = r;
159
-
160
- // patch neighbours
161
- compute_neighbours_from_children(r);
162
-
163
- //combine bounds
164
- r.bounding_box.expandToFit(a.bounding_box);
165
- r.bounding_box.expandToFit(b.bounding_box);
166
-
167
- compute_bounding_cone_of_2_cones(r.normal_cone, a.normal_cone, b.normal_cone);
168
- compute_bounding_sphere_of_2_spheres(r.bounding_sphere, a.bounding_sphere, b.bounding_sphere);
169
-
170
- // const errors = [];
171
- // const is_valid = r.validate(errors.push, errors);
172
- //
173
- // if (!is_valid) {
174
- // debugger;
175
- // }
176
-
177
- // build_intermediate_patch_topology(r);
178
-
179
- return r;
180
- }