@woosh/meep-engine 2.139.0 → 2.140.0
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/package.json +1 -1
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_aabb.d.ts +3 -3
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_aabb.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_aabb.js +4 -4
- package/src/{engine/physics/broadphase/aabb_transform_oriented.d.ts → core/geom/3d/aabb/aabb3_transform_oriented.d.ts} +2 -2
- package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts.map +1 -0
- package/src/{engine/physics/broadphase/aabb_transform_oriented.js → core/geom/3d/aabb/aabb3_transform_oriented.js} +1 -1
- package/src/core/geom/3d/quaternion/quat3_to_matrix3.d.ts +54 -0
- package/src/core/geom/3d/quaternion/quat3_to_matrix3.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/quat3_to_matrix3.js +69 -0
- package/src/core/geom/3d/shape/AbstractShape3D.d.ts +24 -2
- package/src/core/geom/3d/shape/AbstractShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/AbstractShape3D.js +24 -1
- package/src/core/geom/3d/shape/HeightMapShape3D.d.ts +148 -0
- package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -0
- package/src/core/geom/3d/shape/HeightMapShape3D.js +451 -0
- package/src/core/geom/3d/shape/MeshShape3D.d.ts +210 -0
- package/src/core/geom/3d/shape/MeshShape3D.d.ts.map +1 -0
- package/src/core/geom/3d/shape/MeshShape3D.js +593 -0
- package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/TransformedShape3D.js +46 -2
- package/src/core/geom/3d/shape/Triangle3D.d.ts +95 -0
- package/src/core/geom/3d/shape/Triangle3D.d.ts.map +1 -0
- package/src/core/geom/3d/shape/Triangle3D.js +318 -0
- package/src/core/geom/3d/shape/UnionShape3D.js +13 -0
- package/src/core/geom/3d/shape/shape_mesh_from_geometry.d.ts +30 -0
- package/src/core/geom/3d/shape/shape_mesh_from_geometry.d.ts.map +1 -0
- package/src/core/geom/3d/shape/shape_mesh_from_geometry.js +64 -0
- package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.js +9 -11
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.d.ts +28 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.js +48 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.d.ts.map +1 -1
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.js +40 -18
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts +9 -5
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts.map +1 -1
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.js +38 -10
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts +14 -5
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts.map +1 -1
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.js +47 -5
- package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts +19 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.js +75 -13
- package/src/core/geom/3d/triangle/v3_compute_triangle_normal.d.ts +2 -2
- package/src/core/geom/3d/triangle/v3_compute_triangle_normal.d.ts.map +1 -1
- package/src/core/geom/3d/triangle/v3_compute_triangle_normal.js +1 -1
- package/src/core/geom/vec3/v3_dot_array_array.d.ts +3 -3
- package/src/core/geom/vec3/v3_dot_array_array.d.ts.map +1 -1
- package/src/core/geom/vec3/v3_dot_array_array.js +2 -2
- package/src/core/geom/vec3/v3_negate_array.d.ts +3 -3
- package/src/core/geom/vec3/v3_negate_array.d.ts.map +1 -1
- package/src/core/geom/vec3/v3_negate_array.js +2 -2
- package/src/core/geom/vec3/v3_quat3_apply.d.ts +29 -0
- package/src/core/geom/vec3/v3_quat3_apply.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_quat3_apply.js +39 -0
- package/src/core/geom/vec3/v3_quat3_apply_inverse.d.ts +30 -0
- package/src/core/geom/vec3/v3_quat3_apply_inverse.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_quat3_apply_inverse.js +41 -0
- package/src/core/geom/vec3/v3_triple_cross_product.d.ts +32 -0
- package/src/core/geom/vec3/v3_triple_cross_product.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_triple_cross_product.js +45 -0
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +16 -3
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerController.js +211 -211
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +72 -8
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +37 -5
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +101 -3
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +1789 -1416
- package/src/engine/control/first-person/TODO.md +173 -127
- package/src/engine/control/first-person/abilities/Slide.d.ts.map +1 -1
- package/src/engine/control/first-person/abilities/Slide.js +9 -1
- package/src/engine/control/first-person/prototype_first_person_controller.js +88 -2
- package/src/engine/control/first-person/test/buildTestPlayer.d.ts.map +1 -1
- package/src/engine/control/first-person/test/buildTestPlayer.js +9 -1
- package/src/engine/graphics/geometry/CapsuleGeometry.d.ts +42 -0
- package/src/engine/graphics/geometry/CapsuleGeometry.d.ts.map +1 -0
- package/src/engine/graphics/geometry/CapsuleGeometry.js +171 -0
- package/src/engine/physics/BULLET_REVIEW.md +945 -0
- package/src/engine/physics/CANNON_REVIEW.md +1300 -0
- package/src/engine/physics/JOLT_REVIEW.md +913 -0
- package/src/engine/physics/PLAN.md +461 -236
- package/src/engine/physics/RAPIER_REVIEW.md +934 -0
- package/src/engine/physics/REVIEW_001_ACTION_PLAN.md +642 -0
- package/src/engine/physics/broadphase/compute_fat_world_aabb.js +2 -2
- package/src/engine/physics/contact/ManifoldStore.d.ts +83 -10
- package/src/engine/physics/contact/ManifoldStore.d.ts.map +1 -1
- package/src/engine/physics/contact/ManifoldStore.js +608 -499
- package/src/engine/physics/ecs/ColliderObserverSystem.d.ts +2 -2
- package/src/engine/physics/ecs/ColliderObserverSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.d.ts +128 -20
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +1301 -1159
- package/src/engine/physics/fluid/FluidSimulator.d.ts.map +1 -1
- package/src/engine/physics/fluid/FluidSimulator.js +2 -1
- package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts +28 -6
- package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js +39 -17
- package/src/engine/physics/gjk/expanding_polytope_algorithm.d.ts +6 -6
- package/src/engine/physics/gjk/expanding_polytope_algorithm.d.ts.map +1 -1
- package/src/engine/physics/gjk/expanding_polytope_algorithm.js +68 -22
- package/src/engine/physics/gjk/gjk.d.ts +28 -2
- package/src/engine/physics/gjk/gjk.d.ts.map +1 -1
- package/src/engine/physics/gjk/gjk.js +421 -378
- package/src/engine/physics/gjk/minkowski_support.d.ts +37 -0
- package/src/engine/physics/gjk/minkowski_support.d.ts.map +1 -0
- package/src/engine/physics/gjk/minkowski_support.js +75 -0
- package/src/engine/physics/gjk/mpr.d.ts +56 -0
- package/src/engine/physics/gjk/mpr.d.ts.map +1 -0
- package/src/engine/physics/gjk/mpr.js +344 -0
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts +20 -5
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -1
- package/src/engine/physics/inertia/world_inverse_inertia.js +36 -38
- package/src/engine/physics/integration/integrate_position.d.ts +25 -7
- package/src/engine/physics/integration/integrate_position.d.ts.map +1 -1
- package/src/engine/physics/integration/integrate_position.js +43 -12
- package/src/engine/physics/integration/integrate_velocity.d.ts +30 -0
- package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -1
- package/src/engine/physics/integration/integrate_velocity.js +82 -1
- package/src/engine/physics/narrowphase/PosedShape.d.ts +0 -8
- package/src/engine/physics/narrowphase/PosedShape.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/PosedShape.js +28 -30
- package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/box_box_manifold.js +113 -17
- package/src/engine/physics/narrowphase/box_triangle_contact.d.ts +30 -0
- package/src/engine/physics/narrowphase/box_triangle_contact.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/box_triangle_contact.js +811 -0
- package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/capsule_contacts.js +10 -56
- package/src/engine/physics/narrowphase/capsule_triangle_contact.d.ts +71 -0
- package/src/engine/physics/narrowphase/capsule_triangle_contact.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/capsule_triangle_contact.js +375 -0
- package/src/engine/physics/narrowphase/compute_penetration.d.ts +91 -0
- package/src/engine/physics/narrowphase/compute_penetration.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/compute_penetration.js +396 -0
- package/src/engine/physics/narrowphase/decomposition/aabb_world_to_local.d.ts +35 -0
- package/src/engine/physics/narrowphase/decomposition/aabb_world_to_local.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/decomposition/aabb_world_to_local.js +80 -0
- package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.d.ts +31 -0
- package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.js +55 -0
- package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts +42 -0
- package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.js +204 -0
- package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts +42 -0
- package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.js +94 -0
- package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.d.ts +37 -0
- package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.js +37 -0
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts +8 -2
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/narrowphase_step.js +1422 -382
- package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/sphere_box_contact.js +16 -23
- package/src/engine/physics/narrowphase/sphere_triangle_contact.d.ts +48 -0
- package/src/engine/physics/narrowphase/sphere_triangle_contact.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/sphere_triangle_contact.js +143 -0
- package/src/engine/physics/queries/overlap_shape.d.ts +51 -0
- package/src/engine/physics/queries/overlap_shape.d.ts.map +1 -0
- package/src/engine/physics/queries/overlap_shape.js +183 -0
- package/src/engine/physics/queries/shape_cast.d.ts +56 -0
- package/src/engine/physics/queries/shape_cast.d.ts.map +1 -0
- package/src/engine/physics/queries/shape_cast.js +387 -0
- package/src/engine/physics/solver/solve_contacts.d.ts +116 -30
- package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -1
- package/src/engine/physics/solver/solve_contacts.js +641 -223
- package/src/engine/physics/broadphase/aabb_transform_oriented.d.ts.map +0 -1
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts +0 -20
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts.map +0 -1
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.js +0 -83
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { assert } from "../../../assert.js";
|
|
2
|
+
import {
|
|
3
|
+
tetrahedral_mesh_build_vertex_to_tets_map
|
|
4
|
+
} from "./tetrahedral_mesh_build_vertex_to_tets_map.js";
|
|
2
5
|
import { compute_tetrahedron_quality } from "./compute_tetrahedron_quality.js";
|
|
3
6
|
import {
|
|
4
7
|
tetrahedral_mesh_find_tets_around_edge
|
|
5
8
|
} from "./tetrahedral_mesh_find_tets_around_edge.js";
|
|
6
|
-
import {
|
|
7
|
-
tetrahedral_mesh_find_tets_attached_to_vertex
|
|
8
|
-
} from "./tetrahedral_mesh_find_tets_attached_to_vertex.js";
|
|
9
9
|
import { tetrahedral_mesh_flip_23 } from "./tetrahedral_mesh_flip_23.js";
|
|
10
10
|
import { tetrahedral_mesh_flip_32 } from "./tetrahedral_mesh_flip_32.js";
|
|
11
11
|
import {
|
|
@@ -27,14 +27,12 @@ const FACE_VERTICES_BY_OPPOSITE = [
|
|
|
27
27
|
[0, 1, 2],
|
|
28
28
|
];
|
|
29
29
|
|
|
30
|
-
// Scratch for the 2-3 / 3-2 flip out-parameters
|
|
31
|
-
//
|
|
32
|
-
// re-entrant.
|
|
30
|
+
// Scratch for the 2-3 / 3-2 flip out-parameters. Module-level — the driver
|
|
31
|
+
// is not re-entrant.
|
|
33
32
|
const scratch_out_23 = new Uint32Array(3);
|
|
34
33
|
const scratch_out_32 = new Uint32Array(2);
|
|
35
34
|
const scratch_edge_ring = new Array(16);
|
|
36
35
|
const scratch_ring_closed = [0];
|
|
37
|
-
let scratch_local_tets = new Array(64);
|
|
38
36
|
|
|
39
37
|
// The 6 unique vertex-pair (i, j) slots in a 4-vertex tet, enumerating
|
|
40
38
|
// every edge once. Used to iterate the 6 edges of a candidate tet during
|
|
@@ -122,6 +120,13 @@ export function tetrahedral_mesh_improve_quality(mesh, points, options = {}) {
|
|
|
122
120
|
// delete and re-introduce tet IDs underneath us.
|
|
123
121
|
const live = mesh.getLive();
|
|
124
122
|
|
|
123
|
+
// Build a vertex->tets cache once per pass. Used by the boundary
|
|
124
|
+
// check (flip-invariant — safe to use for the whole pass) and by
|
|
125
|
+
// the local quality eval (filtered through mesh.exists; may miss
|
|
126
|
+
// newly-flipped tets which is fine: the live-snapshot iteration
|
|
127
|
+
// already misses them too, and they'll be picked up next pass).
|
|
128
|
+
const vertex_to_tets = tetrahedral_mesh_build_vertex_to_tets_map(mesh);
|
|
129
|
+
|
|
125
130
|
for (let li = 0; li < live.length; li++) {
|
|
126
131
|
const tet = live[li];
|
|
127
132
|
if (!mesh.exists(tet)) continue;
|
|
@@ -134,19 +139,19 @@ export function tetrahedral_mesh_improve_quality(mesh, points, options = {}) {
|
|
|
134
139
|
for (let i = 0; i < 4; i++) {
|
|
135
140
|
if (!mesh.exists(tet)) break;
|
|
136
141
|
const v_id = mesh.getVertexIndex(tet, i);
|
|
137
|
-
if (tetrahedral_mesh_vertex_is_boundary(mesh, v_id)) continue;
|
|
142
|
+
if (tetrahedral_mesh_vertex_is_boundary(mesh, v_id, vertex_to_tets)) continue;
|
|
138
143
|
|
|
139
144
|
const v3 = v_id * 3;
|
|
140
145
|
const old_x = points[v3];
|
|
141
146
|
const old_y = points[v3 + 1];
|
|
142
147
|
const old_z = points[v3 + 2];
|
|
143
148
|
|
|
144
|
-
const old_min = local_min_quality_around_vertex(mesh, points, v_id);
|
|
149
|
+
const old_min = local_min_quality_around_vertex(mesh, points, v_id, vertex_to_tets);
|
|
145
150
|
|
|
146
|
-
const moved = tetrahedral_mesh_smooth_vertex(mesh, points, v_id, smoothing_weight);
|
|
151
|
+
const moved = tetrahedral_mesh_smooth_vertex(mesh, points, v_id, smoothing_weight, vertex_to_tets);
|
|
147
152
|
if (!moved) continue;
|
|
148
153
|
|
|
149
|
-
const new_min = local_min_quality_around_vertex(mesh, points, v_id);
|
|
154
|
+
const new_min = local_min_quality_around_vertex(mesh, points, v_id, vertex_to_tets);
|
|
150
155
|
if (new_min > old_min) {
|
|
151
156
|
stats.smoothings_committed++;
|
|
152
157
|
any_improvement = true;
|
|
@@ -349,16 +354,33 @@ function scan_min_quality(mesh, points) {
|
|
|
349
354
|
/**
|
|
350
355
|
* Min quality across all tets containing `v_id`. Used to score the local
|
|
351
356
|
* effect of moving (or undoing the move of) a single vertex.
|
|
357
|
+
*
|
|
358
|
+
* Reads the incident tets directly from the pass-level cache and filters
|
|
359
|
+
* out tets that have since been deleted. Cache entries whose vertex set
|
|
360
|
+
* no longer contains `v_id` (because a flip re-used the slot) are
|
|
361
|
+
* silently skipped — those tets are no longer part of `v_id`'s 1-ring
|
|
362
|
+
* anyway.
|
|
352
363
|
*/
|
|
353
|
-
function local_min_quality_around_vertex(mesh, points, v_id) {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
const n = tetrahedral_mesh_find_tets_attached_to_vertex(scratch_local_tets, 0, mesh, v_id);
|
|
364
|
+
function local_min_quality_around_vertex(mesh, points, v_id, vertex_to_tets) {
|
|
365
|
+
const tets = vertex_to_tets.get(v_id);
|
|
366
|
+
if (tets === undefined) return 1;
|
|
358
367
|
|
|
359
368
|
let min_q = 1;
|
|
360
|
-
for (let i = 0; i <
|
|
361
|
-
const
|
|
369
|
+
for (let i = 0; i < tets.length; i++) {
|
|
370
|
+
const tet = tets[i];
|
|
371
|
+
if (!mesh.exists(tet)) continue;
|
|
372
|
+
// Tet may have been re-used by a flip with a different vertex set;
|
|
373
|
+
// confirm v_id is still incident before counting it.
|
|
374
|
+
let still_incident = false;
|
|
375
|
+
for (let s = 0; s < 4; s++) {
|
|
376
|
+
if (mesh.getVertexIndex(tet, s) === v_id) {
|
|
377
|
+
still_incident = true;
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
if (!still_incident) continue;
|
|
382
|
+
|
|
383
|
+
const q = compute_tetrahedron_quality(mesh, points, tet);
|
|
362
384
|
if (q < min_q) min_q = q;
|
|
363
385
|
}
|
|
364
386
|
return min_q;
|
|
@@ -6,10 +6,13 @@
|
|
|
6
6
|
* Mutates `points` in place. Does NOT touch the mesh topology.
|
|
7
7
|
*
|
|
8
8
|
* The 1-ring is computed by finding every tet that contains `vertex_id` and
|
|
9
|
-
* collecting the OTHER 3 vertices of each tet, deduplicated.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* collecting the OTHER 3 vertices of each tet, deduplicated.
|
|
10
|
+
*
|
|
11
|
+
* If `vertex_to_tets_map` is provided (a `Map<vertex_id, tet_id[]>` from
|
|
12
|
+
* {@link tetrahedral_mesh_build_vertex_to_tets_map}), the incident-tet
|
|
13
|
+
* lookup runs in O(deg) instead of O(N). Entries pointing to deleted tets
|
|
14
|
+
* or to tets that no longer contain `vertex_id` (e.g. flipped) are
|
|
15
|
+
* silently filtered.
|
|
13
16
|
*
|
|
14
17
|
* Does NOT check whether the vertex sits on the mesh boundary — the caller
|
|
15
18
|
* is responsible for skipping boundary vertices (via
|
|
@@ -25,7 +28,8 @@
|
|
|
25
28
|
* @param {Float32Array|number[]} points flat (x,y,z) positions — mutated in place
|
|
26
29
|
* @param {number} vertex_id
|
|
27
30
|
* @param {number} [weight] move fraction, default 1.0
|
|
31
|
+
* @param {Map<number, number[]>} [vertex_to_tets_map] optional adjacency cache
|
|
28
32
|
* @returns {boolean} true if `points` was modified
|
|
29
33
|
*/
|
|
30
|
-
export function tetrahedral_mesh_smooth_vertex(mesh: TetrahedralMesh, points: Float32Array | number[], vertex_id: number, weight?: number): boolean;
|
|
34
|
+
export function tetrahedral_mesh_smooth_vertex(mesh: TetrahedralMesh, points: Float32Array | number[], vertex_id: number, weight?: number, vertex_to_tets_map?: Map<number, number[]>): boolean;
|
|
31
35
|
//# sourceMappingURL=tetrahedral_mesh_smooth_vertex.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tetrahedral_mesh_smooth_vertex.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.js"],"names":[],"mappings":"AAWA
|
|
1
|
+
{"version":3,"file":"tetrahedral_mesh_smooth_vertex.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.js"],"names":[],"mappings":"AAWA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,8EANW,YAAY,GAAC,MAAM,EAAE,aACrB,MAAM,WACN,MAAM,uBACN,IAAI,MAAM,EAAE,MAAM,EAAE,CAAC,GACnB,OAAO,CAiGnB"}
|
|
@@ -17,10 +17,13 @@ let scratch_neighbours = new Array(128);
|
|
|
17
17
|
* Mutates `points` in place. Does NOT touch the mesh topology.
|
|
18
18
|
*
|
|
19
19
|
* The 1-ring is computed by finding every tet that contains `vertex_id` and
|
|
20
|
-
* collecting the OTHER 3 vertices of each tet, deduplicated.
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* collecting the OTHER 3 vertices of each tet, deduplicated.
|
|
21
|
+
*
|
|
22
|
+
* If `vertex_to_tets_map` is provided (a `Map<vertex_id, tet_id[]>` from
|
|
23
|
+
* {@link tetrahedral_mesh_build_vertex_to_tets_map}), the incident-tet
|
|
24
|
+
* lookup runs in O(deg) instead of O(N). Entries pointing to deleted tets
|
|
25
|
+
* or to tets that no longer contain `vertex_id` (e.g. flipped) are
|
|
26
|
+
* silently filtered.
|
|
24
27
|
*
|
|
25
28
|
* Does NOT check whether the vertex sits on the mesh boundary — the caller
|
|
26
29
|
* is responsible for skipping boundary vertices (via
|
|
@@ -36,9 +39,10 @@ let scratch_neighbours = new Array(128);
|
|
|
36
39
|
* @param {Float32Array|number[]} points flat (x,y,z) positions — mutated in place
|
|
37
40
|
* @param {number} vertex_id
|
|
38
41
|
* @param {number} [weight] move fraction, default 1.0
|
|
42
|
+
* @param {Map<number, number[]>} [vertex_to_tets_map] optional adjacency cache
|
|
39
43
|
* @returns {boolean} true if `points` was modified
|
|
40
44
|
*/
|
|
41
|
-
export function tetrahedral_mesh_smooth_vertex(mesh, points, vertex_id, weight = 1.0) {
|
|
45
|
+
export function tetrahedral_mesh_smooth_vertex(mesh, points, vertex_id, weight = 1.0, vertex_to_tets_map) {
|
|
42
46
|
assert.defined(mesh, 'mesh');
|
|
43
47
|
assert.defined(points, 'points');
|
|
44
48
|
assert.isNonNegativeInteger(vertex_id, 'vertex_id');
|
|
@@ -47,12 +51,36 @@ export function tetrahedral_mesh_smooth_vertex(mesh, points, vertex_id, weight =
|
|
|
47
51
|
if (weight === 0) return false;
|
|
48
52
|
|
|
49
53
|
// 1. Find tets containing the vertex.
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
let tet_count;
|
|
55
|
+
if (vertex_to_tets_map !== undefined) {
|
|
56
|
+
const cached = vertex_to_tets_map.get(vertex_id);
|
|
57
|
+
if (cached === undefined) return false;
|
|
58
|
+
if (scratch_tets.length < cached.length) {
|
|
59
|
+
scratch_tets = new Array(Math.max(cached.length, scratch_tets.length * 2));
|
|
60
|
+
}
|
|
61
|
+
// Filter stale entries (deleted tets, or tets that no longer
|
|
62
|
+
// contain vertex_id because a flip re-used the slot).
|
|
63
|
+
tet_count = 0;
|
|
64
|
+
for (let i = 0; i < cached.length; i++) {
|
|
65
|
+
const tet = cached[i];
|
|
66
|
+
if (!mesh.exists(tet)) continue;
|
|
67
|
+
let still_incident = false;
|
|
68
|
+
for (let s = 0; s < 4; s++) {
|
|
69
|
+
if (mesh.getVertexIndex(tet, s) === vertex_id) {
|
|
70
|
+
still_incident = true;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (still_incident) scratch_tets[tet_count++] = tet;
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
if (scratch_tets.length < mesh.count) {
|
|
78
|
+
scratch_tets = new Array(Math.max(mesh.count, scratch_tets.length * 2));
|
|
79
|
+
}
|
|
80
|
+
tet_count = tetrahedral_mesh_find_tets_attached_to_vertex(
|
|
81
|
+
scratch_tets, 0, mesh, vertex_id
|
|
82
|
+
);
|
|
52
83
|
}
|
|
53
|
-
const tet_count = tetrahedral_mesh_find_tets_attached_to_vertex(
|
|
54
|
-
scratch_tets, 0, mesh, vertex_id
|
|
55
|
-
);
|
|
56
84
|
|
|
57
85
|
if (tet_count === 0) return false;
|
|
58
86
|
|
|
@@ -8,15 +8,24 @@
|
|
|
8
8
|
* external surface (which usually represents some geometric constraint
|
|
9
9
|
* the caller wants preserved).
|
|
10
10
|
*
|
|
11
|
-
* Cost
|
|
11
|
+
* Cost without `vertex_to_tets_map`: O(N) over the live tets, same as
|
|
12
12
|
* {@link tetrahedral_mesh_find_tets_attached_to_vertex} which it shares
|
|
13
|
-
* the same scan structure with.
|
|
14
|
-
*
|
|
15
|
-
* a
|
|
13
|
+
* the same scan structure with.
|
|
14
|
+
*
|
|
15
|
+
* Cost with `vertex_to_tets_map`: O(deg(vertex)) — usually a small
|
|
16
|
+
* constant. For repeated calls over many vertices in a tight loop
|
|
17
|
+
* (e.g. a sliver-removal pass), build the map once via
|
|
18
|
+
* {@link tetrahedral_mesh_build_vertex_to_tets_map} and pass it in.
|
|
19
|
+
*
|
|
20
|
+
* Note: boundary status is invariant under interior 2-3 / 3-2 flips, so
|
|
21
|
+
* a once-per-pass cache stays valid for boundary queries even as the
|
|
22
|
+
* pass commits flips, as long as a freshly-snapshotted cache is built
|
|
23
|
+
* for each NEW pass.
|
|
16
24
|
*
|
|
17
25
|
* @param {TetrahedralMesh} mesh
|
|
18
26
|
* @param {number} vertex_id
|
|
27
|
+
* @param {Map<number, number[]>} [vertex_to_tets_map] optional cache
|
|
19
28
|
* @returns {boolean}
|
|
20
29
|
*/
|
|
21
|
-
export function tetrahedral_mesh_vertex_is_boundary(mesh: TetrahedralMesh, vertex_id: number): boolean;
|
|
30
|
+
export function tetrahedral_mesh_vertex_is_boundary(mesh: TetrahedralMesh, vertex_id: number, vertex_to_tets_map?: Map<number, number[]>): boolean;
|
|
22
31
|
//# sourceMappingURL=tetrahedral_mesh_vertex_is_boundary.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tetrahedral_mesh_vertex_is_boundary.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.js"],"names":[],"mappings":"AAGA
|
|
1
|
+
{"version":3,"file":"tetrahedral_mesh_vertex_is_boundary.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,sFAJW,MAAM,uBACN,IAAI,MAAM,EAAE,MAAM,EAAE,CAAC,GACnB,OAAO,CAkEnB"}
|
|
@@ -11,20 +11,62 @@ import { INVALID_NEIGHBOUR } from "./TetrahedralMesh.js";
|
|
|
11
11
|
* external surface (which usually represents some geometric constraint
|
|
12
12
|
* the caller wants preserved).
|
|
13
13
|
*
|
|
14
|
-
* Cost
|
|
14
|
+
* Cost without `vertex_to_tets_map`: O(N) over the live tets, same as
|
|
15
15
|
* {@link tetrahedral_mesh_find_tets_attached_to_vertex} which it shares
|
|
16
|
-
* the same scan structure with.
|
|
17
|
-
*
|
|
18
|
-
* a
|
|
16
|
+
* the same scan structure with.
|
|
17
|
+
*
|
|
18
|
+
* Cost with `vertex_to_tets_map`: O(deg(vertex)) — usually a small
|
|
19
|
+
* constant. For repeated calls over many vertices in a tight loop
|
|
20
|
+
* (e.g. a sliver-removal pass), build the map once via
|
|
21
|
+
* {@link tetrahedral_mesh_build_vertex_to_tets_map} and pass it in.
|
|
22
|
+
*
|
|
23
|
+
* Note: boundary status is invariant under interior 2-3 / 3-2 flips, so
|
|
24
|
+
* a once-per-pass cache stays valid for boundary queries even as the
|
|
25
|
+
* pass commits flips, as long as a freshly-snapshotted cache is built
|
|
26
|
+
* for each NEW pass.
|
|
19
27
|
*
|
|
20
28
|
* @param {TetrahedralMesh} mesh
|
|
21
29
|
* @param {number} vertex_id
|
|
30
|
+
* @param {Map<number, number[]>} [vertex_to_tets_map] optional cache
|
|
22
31
|
* @returns {boolean}
|
|
23
32
|
*/
|
|
24
|
-
export function tetrahedral_mesh_vertex_is_boundary(mesh, vertex_id) {
|
|
33
|
+
export function tetrahedral_mesh_vertex_is_boundary(mesh, vertex_id, vertex_to_tets_map) {
|
|
25
34
|
assert.defined(mesh, 'mesh');
|
|
26
35
|
assert.isNonNegativeInteger(vertex_id, 'vertex_id');
|
|
27
36
|
|
|
37
|
+
if (vertex_to_tets_map !== undefined) {
|
|
38
|
+
const tets = vertex_to_tets_map.get(vertex_id);
|
|
39
|
+
if (tets === undefined) return false;
|
|
40
|
+
|
|
41
|
+
for (let ti = 0; ti < tets.length; ti++) {
|
|
42
|
+
const tet = tets[ti];
|
|
43
|
+
// Tets in the cache may have been deleted since it was built.
|
|
44
|
+
if (!mesh.exists(tet)) continue;
|
|
45
|
+
|
|
46
|
+
// Find the slot of vertex_id in this tet — present by
|
|
47
|
+
// construction unless a flip re-used the tet ID with
|
|
48
|
+
// different vertices, in which case skip.
|
|
49
|
+
let v_slot = -1;
|
|
50
|
+
for (let i = 0; i < 4; i++) {
|
|
51
|
+
if (mesh.getVertexIndex(tet, i) === vertex_id) {
|
|
52
|
+
v_slot = i;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (v_slot < 0) continue;
|
|
57
|
+
|
|
58
|
+
// The 3 faces containing vertex_id are the ones NOT opposite v_slot.
|
|
59
|
+
for (let j = 0; j < 4; j++) {
|
|
60
|
+
if (j === v_slot) continue;
|
|
61
|
+
if (mesh.getNeighbour(tet, j) === INVALID_NEIGHBOUR) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Slow path: scan every live tet.
|
|
28
70
|
let is_boundary = false;
|
|
29
71
|
|
|
30
72
|
mesh.forEach((tet, m) => {
|
|
@@ -66,6 +66,17 @@ export class BinaryElementPool implements Iterable<number> {
|
|
|
66
66
|
* @private
|
|
67
67
|
*/
|
|
68
68
|
private __capacity;
|
|
69
|
+
/**
|
|
70
|
+
* Occupancy index: bit `id` is 1 when slot `id` is allocated, 0 when
|
|
71
|
+
* free. Lets {@link is_allocated} answer in O(1) instead of scanning
|
|
72
|
+
* {@link __free}. The {@link __free} stack remains the allocator; this
|
|
73
|
+
* is purely a membership accelerator kept in lockstep with it.
|
|
74
|
+
* `preventShrink` stops the bitset reallocating smaller when top slots
|
|
75
|
+
* are cleared — its capacity tracks the pool, not the live set.
|
|
76
|
+
* @type {BitSet}
|
|
77
|
+
* @private
|
|
78
|
+
*/
|
|
79
|
+
private __occupancy;
|
|
69
80
|
/**
|
|
70
81
|
*
|
|
71
82
|
* @param {ArrayBuffer} buffer
|
|
@@ -193,6 +204,14 @@ export class BinaryElementPool implements Iterable<number> {
|
|
|
193
204
|
* @param {BinaryElementPool} other
|
|
194
205
|
*/
|
|
195
206
|
copy(other: BinaryElementPool): void;
|
|
207
|
+
/**
|
|
208
|
+
* Rebuild the occupancy index from `__size` and the current free set:
|
|
209
|
+
* every id in `[0, size)` is allocated except those held in `__free`.
|
|
210
|
+
* Used after {@link copy}, where the data buffer and free set are adopted
|
|
211
|
+
* wholesale.
|
|
212
|
+
* @private
|
|
213
|
+
*/
|
|
214
|
+
private __rebuild_occupancy_from_free;
|
|
196
215
|
/**
|
|
197
216
|
* Used for type checking
|
|
198
217
|
* @readonly
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BinaryElementPool.d.ts","sourceRoot":"","sources":["../../../../../../../../src/core/geom/3d/topology/struct/binary/BinaryElementPool.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BinaryElementPool.d.ts","sourceRoot":"","sources":["../../../../../../../../src/core/geom/3d/topology/struct/binary/BinaryElementPool.js"],"names":[],"mappings":"AA4BA;;;GAGG;AACH,mDAFyB,MAAM;IA0B3B;;;;;OAKG;IACH,uBAJW,MAAM,qBACN,MAAM,sBACN,OAAO,EA+DjB;IAzFD;;;;OAIG;IACH,eAAY;IAEZ;;;;;OAKG;IACH,uBAAmB;IAEnB;;;;OAIG;IACH,eAAW;IAeP;;;;OAIG;IACH,oBAA4B;IAG5B;;;;OAIG;IACH,sBAA8F;IAC9F;;;;OAIG;IACH,qBAAsD;IACtD;;;;OAIG;IACH,sBAAwD;IACxD;;;;OAIG;IACH,uBAA0D;IAC1D,oBAAiD;IAEjD;;;;OAIG;IACH,mBAAkC;IAElC;;;;;;;;;OASG;IACH,oBAA8C;IAKlD;;;;OAIG;IACH,wBAHW,WAAW,2BACX,MAAM,QA8BhB;IAED;;;OAGG;IACH,+BAEC;IAED;;;OAGG;IACH,wBAEC;IAED;;;;OAIG;IACH,mBAEC;IAED;;;OAGG;IACH,uBAEC;IAED;;;OAGG;IACH,uBAEC;IAGD;;;OAGG;IACH,+BAEC;IAED;;;OAGG;IACH,iCAEC;IAED;;OAEG;IACH,aAEC;IAED;;;;OAIG;IACH,oBAHW,MAAM,GACL,MAAM,CAMjB;IAED;;;;;OAKG;IACH,iBAHW,MAAM,GACL,MAAM,CAIjB;IAED;;;;OAIG;IACH,iBAHW,MAAM,GACL,OAAO,CAYlB;IAED;;;;OAIG;IACH,uBA2BC;IAED;;;;OAIG;IACH,wBAQC;IAED;;;OAGG;IACH,0BAFW,MAAM,QAMhB;IAGD;;;OAGG;IACH,YAFY,MAAM,CAyBjB;IAED;;;;OAIG;IACH,2BAHW,MAAM,GACL,MAAM,CAmBjB;IAED;;;;;OAKG;IACH,QAHW,MAAM,KACN,MAAM,QAiBhB;IAED;;;;OAIG;IACH,YAFW,MAAM,QAchB;IAED;;OAEG;IACH,uBAOC;IAED;;;;;OAKG;IACH,mBAFW,MAAM,QAchB;IAED;;;OAGG;IACH,cAIC;IAED;;;OAGG;IACH,YAFW,iBAAiB,QA4B3B;IAED;;;;;;OAMG;IACH,sCAaC;IAoBL;;;;OAIG;IACH,8BAFU,OAAO,CAE8B;IAvB3C;;;OAGG;IACH,qBAFY,UAAU,MAAM,CAAC,CAa5B;CACJ"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { assert } from "../../../../../assert.js";
|
|
2
2
|
import { align_4 } from "../../../../../binary/align_4.js";
|
|
3
|
+
import { BitSet } from "../../../../../binary/BitSet.js";
|
|
3
4
|
import { makeArrayBuffer } from "../../../../../binary/makeArrayBuffer.js";
|
|
4
5
|
import { array_swap } from "../../../../../collection/array/array_swap.js";
|
|
5
6
|
import { array_buffer_copy } from "../../../../../collection/array/typed/array_buffer_copy.js";
|
|
@@ -107,6 +108,19 @@ export class BinaryElementPool {
|
|
|
107
108
|
*/
|
|
108
109
|
this.__capacity = initial_capacity;
|
|
109
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Occupancy index: bit `id` is 1 when slot `id` is allocated, 0 when
|
|
113
|
+
* free. Lets {@link is_allocated} answer in O(1) instead of scanning
|
|
114
|
+
* {@link __free}. The {@link __free} stack remains the allocator; this
|
|
115
|
+
* is purely a membership accelerator kept in lockstep with it.
|
|
116
|
+
* `preventShrink` stops the bitset reallocating smaller when top slots
|
|
117
|
+
* are cleared — its capacity tracks the pool, not the live set.
|
|
118
|
+
* @type {BitSet}
|
|
119
|
+
* @private
|
|
120
|
+
*/
|
|
121
|
+
this.__occupancy = new BitSet(this.__capacity);
|
|
122
|
+
this.__occupancy.preventShrink();
|
|
123
|
+
|
|
110
124
|
}
|
|
111
125
|
|
|
112
126
|
/**
|
|
@@ -134,6 +148,14 @@ export class BinaryElementPool {
|
|
|
134
148
|
// drop free slots
|
|
135
149
|
this.__free_pointer = 0;
|
|
136
150
|
this.__size = allocated_record_count;
|
|
151
|
+
|
|
152
|
+
// Rebuild occupancy for the adopted buffer: the free set is dropped, so
|
|
153
|
+
// exactly [0, allocated_record_count) is allocated.
|
|
154
|
+
this.__occupancy = new BitSet(capacity);
|
|
155
|
+
this.__occupancy.preventShrink();
|
|
156
|
+
if (allocated_record_count > 0) {
|
|
157
|
+
this.__occupancy.setRange(0, allocated_record_count - 1);
|
|
158
|
+
}
|
|
137
159
|
}
|
|
138
160
|
|
|
139
161
|
/**
|
|
@@ -235,18 +257,8 @@ export class BinaryElementPool {
|
|
|
235
257
|
return false;
|
|
236
258
|
}
|
|
237
259
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
for (let i = 0; i < pointer; i++) {
|
|
241
|
-
const _id = this.__free[i];
|
|
242
|
-
|
|
243
|
-
if (id === _id) {
|
|
244
|
-
// found in unallocated set
|
|
245
|
-
return false;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
return true;
|
|
260
|
+
// O(1) occupancy bit read.
|
|
261
|
+
return this.__occupancy.get(id);
|
|
250
262
|
}
|
|
251
263
|
|
|
252
264
|
/**
|
|
@@ -278,6 +290,9 @@ export class BinaryElementPool {
|
|
|
278
290
|
typed_array_copy(old_data_uint8, this.__data_uint8);
|
|
279
291
|
|
|
280
292
|
this.__capacity = new_capacity;
|
|
293
|
+
|
|
294
|
+
// The bitset self-manages capacity on set(); preventShrink keeps it from
|
|
295
|
+
// dropping below the used region on clears. Nothing to do here.
|
|
281
296
|
}
|
|
282
297
|
|
|
283
298
|
/**
|
|
@@ -314,7 +329,9 @@ export class BinaryElementPool {
|
|
|
314
329
|
if (this.__free_pointer > 0) {
|
|
315
330
|
// get unused slot
|
|
316
331
|
this.__free_pointer--;
|
|
317
|
-
|
|
332
|
+
const id = this.__free[this.__free_pointer];
|
|
333
|
+
this.__occupancy.set(id, true);
|
|
334
|
+
return id;
|
|
318
335
|
}
|
|
319
336
|
|
|
320
337
|
// allocate new
|
|
@@ -328,6 +345,8 @@ export class BinaryElementPool {
|
|
|
328
345
|
|
|
329
346
|
// assert.greaterThan(this.__data_buffer.byteLength, result * this.__item_size, 'memory underflow');
|
|
330
347
|
|
|
348
|
+
this.__occupancy.set(result, true);
|
|
349
|
+
|
|
331
350
|
return result;
|
|
332
351
|
}
|
|
333
352
|
|
|
@@ -347,6 +366,11 @@ export class BinaryElementPool {
|
|
|
347
366
|
|
|
348
367
|
// assert.greaterThanOrEqual(this.__data_buffer.byteLength, (offset + count) * this.__item_size, 'memory underflow');
|
|
349
368
|
|
|
369
|
+
// Mark the whole range allocated.
|
|
370
|
+
if (count > 0) {
|
|
371
|
+
this.__occupancy.setRange(offset, offset + count - 1);
|
|
372
|
+
}
|
|
373
|
+
|
|
350
374
|
return offset;
|
|
351
375
|
}
|
|
352
376
|
|
|
@@ -382,11 +406,13 @@ export class BinaryElementPool {
|
|
|
382
406
|
if (id === this.__size - 1) {
|
|
383
407
|
// releasing item at the end of the reserved region, don't have to push it into free set
|
|
384
408
|
this.__size--;
|
|
409
|
+
this.__occupancy.set(id, false);
|
|
385
410
|
} else if (id >= this.__size) {
|
|
386
411
|
// do nothing, just throw it away
|
|
387
412
|
// this should never happen
|
|
388
413
|
} else {
|
|
389
414
|
this.__free[this.__free_pointer++] = id;
|
|
415
|
+
this.__occupancy.set(id, false);
|
|
390
416
|
}
|
|
391
417
|
}
|
|
392
418
|
|
|
@@ -395,6 +421,11 @@ export class BinaryElementPool {
|
|
|
395
421
|
*/
|
|
396
422
|
clear_free_set() {
|
|
397
423
|
this.__free_pointer = 0;
|
|
424
|
+
|
|
425
|
+
// With the free set empty, every slot in [0, size) is allocated again.
|
|
426
|
+
if (this.__size > 0) {
|
|
427
|
+
this.__occupancy.setRange(0, this.__size - 1);
|
|
428
|
+
}
|
|
398
429
|
}
|
|
399
430
|
|
|
400
431
|
/**
|
|
@@ -409,6 +440,12 @@ export class BinaryElementPool {
|
|
|
409
440
|
|
|
410
441
|
this.__size = new_size;
|
|
411
442
|
this.__free_pointer = 0;
|
|
443
|
+
|
|
444
|
+
// Free set discarded: [0, new_size) is the live region with no holes.
|
|
445
|
+
this.__occupancy.reset();
|
|
446
|
+
if (new_size > 0) {
|
|
447
|
+
this.__occupancy.setRange(0, new_size - 1);
|
|
448
|
+
}
|
|
412
449
|
}
|
|
413
450
|
|
|
414
451
|
/**
|
|
@@ -418,6 +455,7 @@ export class BinaryElementPool {
|
|
|
418
455
|
clear() {
|
|
419
456
|
this.__size = 0;
|
|
420
457
|
this.__free_pointer = 0;
|
|
458
|
+
this.__occupancy.reset();
|
|
421
459
|
}
|
|
422
460
|
|
|
423
461
|
/**
|
|
@@ -448,6 +486,30 @@ export class BinaryElementPool {
|
|
|
448
486
|
|
|
449
487
|
this.__free_pointer = other.__free_pointer;
|
|
450
488
|
this.__free = other.__free.slice();
|
|
489
|
+
|
|
490
|
+
this.__rebuild_occupancy_from_free();
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* Rebuild the occupancy index from `__size` and the current free set:
|
|
495
|
+
* every id in `[0, size)` is allocated except those held in `__free`.
|
|
496
|
+
* Used after {@link copy}, where the data buffer and free set are adopted
|
|
497
|
+
* wholesale.
|
|
498
|
+
* @private
|
|
499
|
+
*/
|
|
500
|
+
__rebuild_occupancy_from_free() {
|
|
501
|
+
this.__occupancy = new BitSet(Math.max(this.__capacity, this.__size));
|
|
502
|
+
this.__occupancy.preventShrink();
|
|
503
|
+
|
|
504
|
+
if (this.__size > 0) {
|
|
505
|
+
this.__occupancy.setRange(0, this.__size - 1);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
const free = this.__free;
|
|
509
|
+
const pointer = this.__free_pointer;
|
|
510
|
+
for (let i = 0; i < pointer; i++) {
|
|
511
|
+
this.__occupancy.set(free[i], false);
|
|
512
|
+
}
|
|
451
513
|
}
|
|
452
514
|
|
|
453
515
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Compute face normal for a triangle
|
|
3
|
-
* @param {number[]|Float32Array} result X,Y,Z normalized vector is written here
|
|
3
|
+
* @param {number[]|Float32Array|Float64Array} result X,Y,Z normalized vector is written here
|
|
4
4
|
* @param {number} result_offset offset into result array where to start writing
|
|
5
5
|
* @param {number} a_x
|
|
6
6
|
* @param {number} a_y
|
|
@@ -12,5 +12,5 @@
|
|
|
12
12
|
* @param {number} c_y
|
|
13
13
|
* @param {number} c_z
|
|
14
14
|
*/
|
|
15
|
-
export function v3_compute_triangle_normal(result: number[] | Float32Array, result_offset: number, a_x: number, a_y: number, a_z: number, b_x: number, b_y: number, b_z: number, c_x: number, c_y: number, c_z: number): void;
|
|
15
|
+
export function v3_compute_triangle_normal(result: number[] | Float32Array | Float64Array, result_offset: number, a_x: number, a_y: number, a_z: number, b_x: number, b_y: number, b_z: number, c_x: number, c_y: number, c_z: number): void;
|
|
16
16
|
//# sourceMappingURL=v3_compute_triangle_normal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v3_compute_triangle_normal.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/triangle/v3_compute_triangle_normal.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,mDAZW,MAAM,EAAE,GAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"v3_compute_triangle_normal.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/triangle/v3_compute_triangle_normal.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,mDAZW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,iBAClC,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,QA0ChB"}
|
|
@@ -2,7 +2,7 @@ import { v3_length_sqr } from "../../vec3/v3_length_sqr.js";
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Compute face normal for a triangle
|
|
5
|
-
* @param {number[]|Float32Array} result X,Y,Z normalized vector is written here
|
|
5
|
+
* @param {number[]|Float32Array|Float64Array} result X,Y,Z normalized vector is written here
|
|
6
6
|
* @param {number} result_offset offset into result array where to start writing
|
|
7
7
|
* @param {number} a_x
|
|
8
8
|
* @param {number} a_y
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
*
|
|
3
|
-
* @param {number[]|Float32Array} a
|
|
3
|
+
* @param {number[]|Float32Array|Float64Array} a
|
|
4
4
|
* @param {number} a_offset
|
|
5
|
-
* @param {number[]|Float32Array} b
|
|
5
|
+
* @param {number[]|Float32Array|Float64Array} b
|
|
6
6
|
* @param {number} b_offset
|
|
7
7
|
* @returns {number}
|
|
8
8
|
*/
|
|
9
|
-
export function v3_dot_array_array(a: number[] | Float32Array, a_offset: number, b: number[] | Float32Array, b_offset: number): number;
|
|
9
|
+
export function v3_dot_array_array(a: number[] | Float32Array | Float64Array, a_offset: number, b: number[] | Float32Array | Float64Array, b_offset: number): number;
|
|
10
10
|
//# sourceMappingURL=v3_dot_array_array.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v3_dot_array_array.d.ts","sourceRoot":"","sources":["../../../../../src/core/geom/vec3/v3_dot_array_array.js"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,sCANW,MAAM,EAAE,GAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"v3_dot_array_array.d.ts","sourceRoot":"","sources":["../../../../../src/core/geom/vec3/v3_dot_array_array.js"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,sCANW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,YAClC,MAAM,KACN,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,YAClC,MAAM,GACJ,MAAM,CAgBlB"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
*
|
|
3
|
-
* @param {number[]|Float32Array} a
|
|
3
|
+
* @param {number[]|Float32Array|Float64Array} a
|
|
4
4
|
* @param {number} a_offset
|
|
5
|
-
* @param {number[]|Float32Array} b
|
|
5
|
+
* @param {number[]|Float32Array|Float64Array} b
|
|
6
6
|
* @param {number} b_offset
|
|
7
7
|
* @returns {number}
|
|
8
8
|
*/
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
*
|
|
3
|
-
* @param {number[]|Float32Array} result
|
|
3
|
+
* @param {number[]|Float32Array|Float64Array} result
|
|
4
4
|
* @param {number} result_offset
|
|
5
|
-
* @param {number[]|Float32Array} input
|
|
5
|
+
* @param {number[]|Float32Array|Float64Array} input
|
|
6
6
|
* @param {number} input_offset
|
|
7
7
|
*/
|
|
8
|
-
export function v3_negate_array(result: number[] | Float32Array, result_offset: number, input: number[] | Float32Array, input_offset: number): void;
|
|
8
|
+
export function v3_negate_array(result: number[] | Float32Array | Float64Array, result_offset: number, input: number[] | Float32Array | Float64Array, input_offset: number): void;
|
|
9
9
|
//# sourceMappingURL=v3_negate_array.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v3_negate_array.d.ts","sourceRoot":"","sources":["../../../../../src/core/geom/vec3/v3_negate_array.js"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wCALW,MAAM,EAAE,GAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"v3_negate_array.d.ts","sourceRoot":"","sources":["../../../../../src/core/geom/vec3/v3_negate_array.js"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wCALW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,iBAClC,MAAM,SACN,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,gBAClC,MAAM,QAUhB"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
*
|
|
3
|
-
* @param {number[]|Float32Array} result
|
|
3
|
+
* @param {number[]|Float32Array|Float64Array} result
|
|
4
4
|
* @param {number} result_offset
|
|
5
|
-
* @param {number[]|Float32Array} input
|
|
5
|
+
* @param {number[]|Float32Array|Float64Array} input
|
|
6
6
|
* @param {number} input_offset
|
|
7
7
|
*/
|
|
8
8
|
export function v3_negate_array(result, result_offset, input, input_offset) {
|