@woosh/meep-engine 3.29.0 → 3.30.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/build/bundle-worker-image-decoder.js +1 -1
- package/build/bundle-worker-terrain.js +1 -1
- package/package.json +1 -1
- package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
- package/src/core/binary/BinaryBuffer.js +14 -2
- package/src/core/bvh2/bvh3/BVH.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/BVH.js +14 -1
- package/src/core/cache/FrequencySketch.d.ts +3 -1
- package/src/core/cache/FrequencySketch.d.ts.map +1 -1
- package/src/core/cache/FrequencySketch.js +10 -4
- package/src/core/cache/wtinylfu/CacheWTinylfu.d.ts.map +1 -1
- package/src/core/cache/wtinylfu/CacheWTinylfu.js +24 -2
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.d.ts +20 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.js +69 -4
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts +48 -18
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +262 -70
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_fold_limit.d.ts +25 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_fold_limit.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_fold_limit.js +228 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.d.ts +13 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.js +10 -128
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_face_bvh.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_face_bvh.js +11 -1
- package/src/core/graph/mn_graph_collapse_weighted_edge.js +6 -6
- package/src/core/math/lookup/ParameterLookupTable.d.ts.map +1 -1
- package/src/core/math/lookup/ParameterLookupTable.js +10 -5
- package/src/core/math/noise/sdnoise.d.ts.map +1 -1
- package/src/core/math/noise/sdnoise.js +16 -10
- package/src/core/model/object/ImmutableObjectPool.d.ts.map +1 -1
- package/src/core/model/object/ImmutableObjectPool.js +17 -7
- package/src/core/process/executor/ConcurrentExecutor.d.ts +1 -5
- package/src/core/process/executor/ConcurrentExecutor.d.ts.map +1 -1
- package/src/core/process/executor/ConcurrentExecutor.js +95 -1
- package/src/core/process/task/task_find_dependency_cycle.d.ts +17 -0
- package/src/core/process/task/task_find_dependency_cycle.d.ts.map +1 -0
- package/src/core/process/task/task_find_dependency_cycle.js +81 -0
- package/src/core/wfc/WFCCellChoice.d.ts +17 -0
- package/src/core/wfc/WFCCellChoice.d.ts.map +1 -0
- package/src/core/wfc/WFCCellChoice.js +36 -0
- package/src/core/wfc/WFCLattice.d.ts +105 -0
- package/src/core/wfc/WFCLattice.d.ts.map +1 -0
- package/src/core/wfc/WFCLattice.js +235 -0
- package/src/core/wfc/WFCRuleTable.d.ts +172 -0
- package/src/core/wfc/WFCRuleTable.d.ts.map +1 -0
- package/src/core/wfc/WFCRuleTable.js +334 -0
- package/src/core/wfc/WFCState.d.ts +273 -0
- package/src/core/wfc/WFCState.d.ts.map +1 -0
- package/src/core/wfc/WFCState.js +552 -0
- package/src/core/wfc/WFCStatus.d.ts +11 -0
- package/src/core/wfc/WFCStatus.d.ts.map +1 -0
- package/src/core/wfc/WFCStatus.js +28 -0
- package/src/core/wfc/WFCTileWeights.d.ts +48 -0
- package/src/core/wfc/WFCTileWeights.d.ts.map +1 -0
- package/src/core/wfc/WFCTileWeights.js +86 -0
- package/src/core/wfc/WFC_UNRESOLVED.d.ts +12 -0
- package/src/core/wfc/WFC_UNRESOLVED.d.ts.map +1 -0
- package/src/core/wfc/WFC_UNRESOLVED.js +11 -0
- package/src/core/wfc/wfc_estimate_bytes.d.ts +24 -0
- package/src/core/wfc/wfc_estimate_bytes.d.ts.map +1 -0
- package/src/core/wfc/wfc_estimate_bytes.js +47 -0
- package/src/core/wfc/wfc_rule_table_tile_components.d.ts +27 -0
- package/src/core/wfc/wfc_rule_table_tile_components.d.ts.map +1 -0
- package/src/core/wfc/wfc_rule_table_tile_components.js +80 -0
- package/src/core/wfc/wfc_solve.d.ts +21 -0
- package/src/core/wfc/wfc_solve.d.ts.map +1 -0
- package/src/core/wfc/wfc_solve.js +154 -0
- package/src/core/wfc/wfc_state_apply_boundary.d.ts +18 -0
- package/src/core/wfc/wfc_state_apply_boundary.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_apply_boundary.js +61 -0
- package/src/core/wfc/wfc_state_assign.d.ts +11 -0
- package/src/core/wfc/wfc_state_assign.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_assign.js +36 -0
- package/src/core/wfc/wfc_state_ban_bits.d.ts +17 -0
- package/src/core/wfc/wfc_state_ban_bits.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_ban_bits.js +81 -0
- package/src/core/wfc/wfc_state_collapse.d.ts +12 -0
- package/src/core/wfc/wfc_state_collapse.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_collapse.js +73 -0
- package/src/core/wfc/wfc_state_flush_dirty.d.ts +12 -0
- package/src/core/wfc/wfc_state_flush_dirty.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_flush_dirty.js +39 -0
- package/src/core/wfc/wfc_state_propagate.d.ts +14 -0
- package/src/core/wfc/wfc_state_propagate.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_propagate.js +155 -0
- package/src/core/wfc/wfc_state_read.d.ts +11 -0
- package/src/core/wfc/wfc_state_read.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_read.js +38 -0
- package/src/core/wfc/wfc_state_restrict.d.ts +18 -0
- package/src/core/wfc/wfc_state_restrict.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_restrict.js +39 -0
- package/src/core/wfc/wfc_state_set_eligible.d.ts +24 -0
- package/src/core/wfc/wfc_state_set_eligible.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_set_eligible.js +49 -0
- package/src/core/wfc/wfc_state_undo_to.d.ts +13 -0
- package/src/core/wfc/wfc_state_undo_to.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_undo_to.js +84 -0
- package/src/core/wfc/wfc_words_per_cell.d.ts +11 -0
- package/src/core/wfc/wfc_words_per_cell.d.ts.map +1 -0
- package/src/core/wfc/wfc_words_per_cell.js +16 -0
- package/src/engine/ecs/EntityComponentDataset.d.ts +8 -0
- package/src/engine/ecs/EntityComponentDataset.d.ts.map +1 -1
- package/src/engine/ecs/EntityComponentDataset.js +37 -14
- package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts +8 -1
- package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts.map +1 -1
- package/src/engine/ecs/fow/FogOfWarRevealerSystem.js +37 -2
- package/src/engine/ecs/guid/UUID.d.ts.map +1 -1
- package/src/engine/ecs/guid/UUID.js +45 -17
- package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.d.ts.map +1 -1
- package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +3 -1
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +366 -360
- package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_linear.d.ts.map +1 -1
- package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_linear.js +24 -10
- package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts.map +1 -1
- package/src/engine/grid/grid2transform/GridPosition2TransformSystem.js +24 -5
- package/src/engine/interpolation/Interpoland.d.ts +7 -1
- package/src/engine/interpolation/Interpoland.d.ts.map +1 -1
- package/src/engine/interpolation/Interpoland.js +8 -1
- package/src/engine/interpolation/InterpolationSystem.d.ts.map +1 -1
- package/src/engine/interpolation/InterpolationSystem.js +3 -0
- package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts +5 -3
- package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts.map +1 -1
- package/src/engine/interpolation/TransformPoseSerializationAdapter.js +14 -3
- package/src/engine/interpolation/pose_interpoland.d.ts.map +1 -1
- package/src/engine/interpolation/pose_interpoland.js +2 -0
- package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
- package/src/engine/network/orchestrator/NetworkPeer.js +15 -10
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothWorld.js +17 -0
- package/src/engine/physics/mls-mpm/MLS_MPM.d.ts.map +1 -1
- package/src/engine/physics/mls-mpm/MLS_MPM.js +14 -0
- package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts +2 -1
- package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.js +1 -1
- package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts +1 -0
- package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts +1 -0
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts +2 -1
- package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/SampleAudioClip.js +12 -3
- package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts +1 -0
- package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts +1 -0
- package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/runtime/EventInstance.d.ts.map +1 -1
- package/src/engine/sound/sopra/runtime/EventInstance.js +4 -1
- package/src/format/image/avif/av1/decode/decode_coefficients.d.ts.map +1 -1
- package/src/format/image/avif/av1/decode/decode_coefficients.js +248 -259
- package/src/format/image/avif/av1/decode/read_golomb.d.ts +21 -0
- package/src/format/image/avif/av1/decode/read_golomb.d.ts.map +1 -0
- package/src/format/image/avif/av1/decode/read_golomb.js +49 -0
- package/src/format/image/avif/av1/filter/loop_restoration.js +461 -451
- package/src/format/image/avif/av1/util/round2.d.ts +19 -2
- package/src/format/image/avif/av1/util/round2.d.ts.map +1 -1
- package/src/format/image/avif/av1/util/round2.js +51 -27
- package/src/format/image/avif/heif/parse_avif_file.js +24 -0
- package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUTypedTable.js +14 -0
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +46 -3
- package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +91 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +0 -13
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +0 -15
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +5 -5
- package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts +11 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.js +11 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +18 -9
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.js +20 -26
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts +1 -3
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.js +2 -5
- package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +14 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.js +12 -3
- package/src/shade/renderer/light/environment/rgbe/RGBE_ReadPixels_RLE.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/rgbe/RGBE_ReadPixels_RLE.js +7 -1
- package/src/shade/renderer/lightmap/GPULightMap.d.ts.map +1 -1
- package/src/shade/renderer/lightmap/GPULightMap.js +349 -336
- package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
- package/src/shade/renderer/loader/gltf/load_gltf.js +1137 -1128
- package/src/shade/renderer/particles/DESIGN.md +14 -5
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts +25 -10
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +182 -38
- package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/groups/simplex_reference.js +16 -10
- package/src/shade/renderer/particles/graph_particles.d.ts +4 -2
- package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles.js +8 -2
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +8 -2
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +10 -4
- package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.d.ts +31 -0
- package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.js +62 -0
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +13 -0
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
- package/src/shade/renderer/particles/vm/ParticleVMReference.js +95 -17
- package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.d.ts +21 -0
- package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.js +28 -0
- package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +19 -2
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +19 -2
- package/src/shade/renderer/shader/type/WebGPUStruct.d.ts.map +1 -1
- package/src/shade/renderer/shader/type/WebGPUStruct.js +12 -0
- package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.d.ts +8 -2
- package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.d.ts.map +1 -1
- package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.js +41 -6
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +2383 -2356
- package/src/view/tooltip/DomTooltipManager.d.ts +7 -0
- package/src/view/tooltip/DomTooltipManager.d.ts.map +1 -1
- package/src/view/tooltip/DomTooltipManager.js +22 -0
- package/src/view/tooltip/DomTooltipObserver.d.ts.map +1 -1
- package/src/view/tooltip/DomTooltipObserver.js +13 -3
- package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.js +0 -45
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { NULL_POINTER } from "../BinaryTopology.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* How far along a segment an edge collapse may place its surviving vertex before one of the
|
|
5
|
+
* triangles it keeps turns over.
|
|
6
|
+
*
|
|
7
|
+
* **It is one walk and not a search, because the fold test is linear in the placement.** A surviving
|
|
8
|
+
* triangle keeps two of its corners, `b` and `c`, exactly where they were, so with the third at `p`
|
|
9
|
+
* its area vector is
|
|
10
|
+
*
|
|
11
|
+
* N(p) = (b - p) x (c - p) = b x c + p x (b - c)
|
|
12
|
+
*
|
|
13
|
+
* which is affine in `p`. "Still facing the way it did", `N(before) . N(p) > 0`, is therefore a
|
|
14
|
+
* linear inequality; the placements that fold nothing are an intersection of open half-spaces, which
|
|
15
|
+
* is convex; and along a segment `p(t) = from + t (to - from)` the test collapses to an affine
|
|
16
|
+
* function of the single parameter `t`. Two evaluations give the exact crossing rather than
|
|
17
|
+
* approaching it -- with `d0` at `from` and `d1` at `to`, the triangle reaches zero area at
|
|
18
|
+
* `t = d0 / (d0 - d1)` -- and the smallest crossing over both fans is the answer.
|
|
19
|
+
*
|
|
20
|
+
* The walk is {@link bt_edge_collapse_would_fold}'s, which is the same question asked at one point
|
|
21
|
+
* instead of two, and that function is now this one.
|
|
22
|
+
*
|
|
23
|
+
* **What it is for.** A quadric names the placement that best fits the surface and cannot see a fold
|
|
24
|
+
* at all: on a flat region every placement in the plane scores zero, so nothing in the price stops a
|
|
25
|
+
* one-ring that is not star-shaped about the target from turning inside out. A caller that tests its
|
|
26
|
+
* preferred placement and abandons the collapse when it folds has treated a bad *placement* as an
|
|
27
|
+
* impossible *operation*, and those are different things -- measured over one Zorah primitive, 15%
|
|
28
|
+
* of all candidate collapses were discarded that way, and the simplifier then reported itself
|
|
29
|
+
* finished with a mesh it could still have halved. Sliding back toward a placement the surface
|
|
30
|
+
* already passes through is what turns that refusal into an answer, and this is what says how far
|
|
31
|
+
* back to slide.
|
|
32
|
+
*
|
|
33
|
+
* @author Alex Goldring
|
|
34
|
+
* @copyright Company Named Limited (c) 2026
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
const scratch_moved = new Float32Array(3);
|
|
38
|
+
const scratch_b = new Float32Array(3);
|
|
39
|
+
const scratch_c = new Float32Array(3);
|
|
40
|
+
const scratch_before = new Float32Array(3);
|
|
41
|
+
const scratch_at_from = new Float32Array(3);
|
|
42
|
+
const scratch_at_to = new Float32Array(3);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Unnormalised triangle normal `(b - a) x (c - a)`, written into `out`.
|
|
46
|
+
*
|
|
47
|
+
* Deliberately not `v3_compute_triangle_normal`: this needs the raw cross product, because a
|
|
48
|
+
* vanishing magnitude is what says the result is a zero-area sliver and the `dot <= 0` test below is
|
|
49
|
+
* what rejects it. Normalising discards that magnitude, and that function answers `(0, 1, 0)` for a
|
|
50
|
+
* degenerate triangle -- which would let a collapse-to-sliver walk straight past the guard.
|
|
51
|
+
*
|
|
52
|
+
* @param {Float32Array} out
|
|
53
|
+
* @param {number} ax
|
|
54
|
+
* @param {number} ay
|
|
55
|
+
* @param {number} az
|
|
56
|
+
* @param {number} bx
|
|
57
|
+
* @param {number} by
|
|
58
|
+
* @param {number} bz
|
|
59
|
+
* @param {number} cx
|
|
60
|
+
* @param {number} cy
|
|
61
|
+
* @param {number} cz
|
|
62
|
+
*/
|
|
63
|
+
function triangle_cross(out, ax, ay, az, bx, by, bz, cx, cy, cz) {
|
|
64
|
+
const ux = bx - ax;
|
|
65
|
+
const uy = by - ay;
|
|
66
|
+
const uz = bz - az;
|
|
67
|
+
|
|
68
|
+
const vx = cx - ax;
|
|
69
|
+
const vy = cy - ay;
|
|
70
|
+
const vz = cz - az;
|
|
71
|
+
|
|
72
|
+
out[0] = uy * vz - uz * vy;
|
|
73
|
+
out[1] = uz * vx - ux * vz;
|
|
74
|
+
out[2] = ux * vy - uy * vx;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The limit over one endpoint's fan.
|
|
79
|
+
*
|
|
80
|
+
* Faces that also hold `other` are skipped: those are the collapse's own faces and they die with it.
|
|
81
|
+
*
|
|
82
|
+
* @param {BinaryTopology} mesh
|
|
83
|
+
* @param {number} moved the vertex whose position changes
|
|
84
|
+
* @param {number} other the collapse's other endpoint
|
|
85
|
+
* @param {Float32Array|number[]} from
|
|
86
|
+
* @param {number} from_offset
|
|
87
|
+
* @param {Float32Array|number[]} to
|
|
88
|
+
* @param {number} to_offset
|
|
89
|
+
* @returns {number} as {@link bt_edge_collapse_fold_limit}, over this fan alone
|
|
90
|
+
*/
|
|
91
|
+
function fan_fold_limit(mesh, moved, other, from, from_offset, to, to_offset) {
|
|
92
|
+
mesh.vertex_read_coordinate(scratch_moved, 0, moved);
|
|
93
|
+
|
|
94
|
+
const face_pool = mesh.faces;
|
|
95
|
+
|
|
96
|
+
let edge = mesh.vertex_read_edge(moved);
|
|
97
|
+
|
|
98
|
+
if (edge === NULL_POINTER) {
|
|
99
|
+
return 1;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const start_edge = edge;
|
|
103
|
+
|
|
104
|
+
let limit = 1;
|
|
105
|
+
|
|
106
|
+
do {
|
|
107
|
+
const first_loop = mesh.edge_read_loop(edge);
|
|
108
|
+
|
|
109
|
+
if (first_loop !== NULL_POINTER) {
|
|
110
|
+
let loop = first_loop;
|
|
111
|
+
|
|
112
|
+
do {
|
|
113
|
+
// each face of the fan is reached exactly once, via the loop anchored at `moved`
|
|
114
|
+
if (mesh.loop_read_vertex(loop) === moved) {
|
|
115
|
+
const face = mesh.loop_read_face(loop);
|
|
116
|
+
|
|
117
|
+
if (face !== NULL_POINTER && face_pool.is_allocated(face)) {
|
|
118
|
+
const loop_b = mesh.loop_read_next(loop);
|
|
119
|
+
const loop_c = mesh.loop_read_next(loop_b);
|
|
120
|
+
|
|
121
|
+
// triangles only; a larger polygon has no single normal to compare
|
|
122
|
+
if (mesh.loop_read_next(loop_c) === loop) {
|
|
123
|
+
const b = mesh.loop_read_vertex(loop_b);
|
|
124
|
+
const c = mesh.loop_read_vertex(loop_c);
|
|
125
|
+
|
|
126
|
+
if (b !== other && c !== other) {
|
|
127
|
+
mesh.vertex_read_coordinate(scratch_b, 0, b);
|
|
128
|
+
mesh.vertex_read_coordinate(scratch_c, 0, c);
|
|
129
|
+
|
|
130
|
+
triangle_cross(
|
|
131
|
+
scratch_before,
|
|
132
|
+
scratch_moved[0], scratch_moved[1], scratch_moved[2],
|
|
133
|
+
scratch_b[0], scratch_b[1], scratch_b[2],
|
|
134
|
+
scratch_c[0], scratch_c[1], scratch_c[2]
|
|
135
|
+
);
|
|
136
|
+
triangle_cross(
|
|
137
|
+
scratch_at_from,
|
|
138
|
+
from[from_offset], from[from_offset + 1], from[from_offset + 2],
|
|
139
|
+
scratch_b[0], scratch_b[1], scratch_b[2],
|
|
140
|
+
scratch_c[0], scratch_c[1], scratch_c[2]
|
|
141
|
+
);
|
|
142
|
+
triangle_cross(
|
|
143
|
+
scratch_at_to,
|
|
144
|
+
to[to_offset], to[to_offset + 1], to[to_offset + 2],
|
|
145
|
+
scratch_b[0], scratch_b[1], scratch_b[2],
|
|
146
|
+
scratch_c[0], scratch_c[1], scratch_c[2]
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
const d0 = scratch_before[0] * scratch_at_from[0]
|
|
150
|
+
+ scratch_before[1] * scratch_at_from[1]
|
|
151
|
+
+ scratch_before[2] * scratch_at_from[2];
|
|
152
|
+
|
|
153
|
+
if (d0 <= 0) {
|
|
154
|
+
// `from` is not a placement at all, so there is no segment left
|
|
155
|
+
// to measure and nothing further to learn from this fan.
|
|
156
|
+
return -1;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const d1 = scratch_before[0] * scratch_at_to[0]
|
|
160
|
+
+ scratch_before[1] * scratch_at_to[1]
|
|
161
|
+
+ scratch_before[2] * scratch_at_to[2];
|
|
162
|
+
|
|
163
|
+
if (d1 <= 0) {
|
|
164
|
+
// Affine in `t` and positive at `0`, so it has exactly one root
|
|
165
|
+
// on the segment and `d0 - d1` cannot vanish.
|
|
166
|
+
const crossing = d0 / (d0 - d1);
|
|
167
|
+
|
|
168
|
+
if (crossing < limit) {
|
|
169
|
+
limit = crossing;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
loop = mesh.loop_read_radial_next(loop);
|
|
178
|
+
} while (loop !== first_loop && loop !== NULL_POINTER);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
edge = (mesh.edge_read_vertex1(edge) === moved)
|
|
182
|
+
? mesh.edge_read_v1_disk_next(edge)
|
|
183
|
+
: mesh.edge_read_v2_disk_next(edge);
|
|
184
|
+
} while (edge !== start_edge && edge !== NULL_POINTER);
|
|
185
|
+
|
|
186
|
+
return limit;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* How far from `from` toward `to` may a collapse of `survivor`-`victim` place the surviving vertex
|
|
191
|
+
* and still turn no surviving triangle over?
|
|
192
|
+
*
|
|
193
|
+
* Both fans are walked, because both endpoints move: the victim onto the placement by definition,
|
|
194
|
+
* and the survivor too wherever the caller puts it somewhere other than where it already sits. The
|
|
195
|
+
* union of the two is the set of faces the collapse reshapes, which is what makes the answer
|
|
196
|
+
* symmetric in the two endpoints -- a caller that has not yet settled which of them survives can
|
|
197
|
+
* rely on that.
|
|
198
|
+
*
|
|
199
|
+
* @param {BinaryTopology} mesh
|
|
200
|
+
* @param {number} survivor the endpoint that stays allocated
|
|
201
|
+
* @param {number} victim the endpoint that is removed
|
|
202
|
+
* @param {Float32Array|number[]} from the placement to measure from, at `t = 0`
|
|
203
|
+
* @param {Float32Array|number[]} to the placement wanted, at `t = 1`
|
|
204
|
+
* @param {number} [from_offset]
|
|
205
|
+
* @param {number} [to_offset]
|
|
206
|
+
* @returns {number} where the first surviving triangle reaches **zero** area, so the placements that
|
|
207
|
+
* fold nothing are `t` in `[0, limit)` -- open at the top, since zero area is refused along with
|
|
208
|
+
* a flip, and a caller therefore takes a fraction of this rather than this. `1` when nothing on
|
|
209
|
+
* the segment folds, and `-1` when `from` itself does, which is the one answer no amount of
|
|
210
|
+
* sliding recovers from.
|
|
211
|
+
*/
|
|
212
|
+
export function bt_edge_collapse_fold_limit(
|
|
213
|
+
mesh, survivor, victim, from, to, from_offset = 0, to_offset = 0
|
|
214
|
+
) {
|
|
215
|
+
const on_victim = fan_fold_limit(mesh, victim, survivor, from, from_offset, to, to_offset);
|
|
216
|
+
|
|
217
|
+
if (on_victim < 0) {
|
|
218
|
+
return -1;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const on_survivor = fan_fold_limit(mesh, survivor, victim, from, from_offset, to, to_offset);
|
|
222
|
+
|
|
223
|
+
if (on_survivor < 0) {
|
|
224
|
+
return -1;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return Math.min(on_victim, on_survivor);
|
|
228
|
+
}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Triangle-inversion rejection for an edge collapse: would any triangle that survives it come out
|
|
3
|
+
* facing the other way?
|
|
4
|
+
*
|
|
5
|
+
* @author Alex Goldring
|
|
6
|
+
* @copyright Company Named Limited (c) 2026
|
|
7
|
+
*/
|
|
1
8
|
/**
|
|
2
9
|
* Would collapsing `survivor`-`victim` onto `target` turn any surviving triangle inside out?
|
|
3
10
|
*
|
|
@@ -17,6 +24,12 @@
|
|
|
17
24
|
* worse rather than better — a pinned endpoint takes the placement with it, and the surviving
|
|
18
25
|
* vertex lands on the pin rather than anywhere the geometry chose.
|
|
19
26
|
*
|
|
27
|
+
* **A `true` here is not a reason to abandon the collapse**, and a caller free to choose the
|
|
28
|
+
* placement should not treat it as one. The set of placements that fold nothing is convex, so a
|
|
29
|
+
* caller holding one placement it likes and one that works can slide between them and find the
|
|
30
|
+
* best point that does — {@link bt_edge_collapse_fold_limit} is that question, this is the same
|
|
31
|
+
* walk asking it at a single point, and this function is a call to that one.
|
|
32
|
+
*
|
|
20
33
|
* @param {BinaryTopology} mesh
|
|
21
34
|
* @param {number} survivor the endpoint that stays allocated
|
|
22
35
|
* @param {number} victim the endpoint that is removed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bt_edge_collapse_would_fold.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bt_edge_collapse_would_fold.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.js"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,4EANW,MAAM,UACN,MAAM,UACN,YAAY,GAAC,MAAM,EAAE,kBACrB,MAAM,GACJ,OAAO,CAMnB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bt_edge_collapse_fold_limit } from "./bt_edge_collapse_fold_limit.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Triangle-inversion rejection for an edge collapse: would any triangle that survives it come out
|
|
@@ -8,131 +8,6 @@ import { NULL_POINTER } from "../BinaryTopology.js";
|
|
|
8
8
|
* @copyright Company Named Limited (c) 2026
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
const scratch_moved = new Float32Array(3);
|
|
12
|
-
const scratch_b = new Float32Array(3);
|
|
13
|
-
const scratch_c = new Float32Array(3);
|
|
14
|
-
const scratch_before = new Float32Array(3);
|
|
15
|
-
const scratch_after = new Float32Array(3);
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Unnormalised triangle normal `(b - a) x (c - a)`, written into `out`.
|
|
19
|
-
*
|
|
20
|
-
* Deliberately not `v3_compute_triangle_normal`: this needs the raw cross product, because a
|
|
21
|
-
* vanishing magnitude is what says the result is a zero-area sliver and the `dot <= 0` test below is
|
|
22
|
-
* what rejects it. Normalising discards that magnitude, and that function answers `(0, 1, 0)` for a
|
|
23
|
-
* degenerate triangle — which would let a collapse-to-sliver walk straight past the guard.
|
|
24
|
-
*
|
|
25
|
-
* @param {Float32Array} out
|
|
26
|
-
* @param {number} ax
|
|
27
|
-
* @param {number} ay
|
|
28
|
-
* @param {number} az
|
|
29
|
-
* @param {number} bx
|
|
30
|
-
* @param {number} by
|
|
31
|
-
* @param {number} bz
|
|
32
|
-
* @param {number} cx
|
|
33
|
-
* @param {number} cy
|
|
34
|
-
* @param {number} cz
|
|
35
|
-
*/
|
|
36
|
-
function triangle_cross(out, ax, ay, az, bx, by, bz, cx, cy, cz) {
|
|
37
|
-
const ux = bx - ax;
|
|
38
|
-
const uy = by - ay;
|
|
39
|
-
const uz = bz - az;
|
|
40
|
-
|
|
41
|
-
const vx = cx - ax;
|
|
42
|
-
const vy = cy - ay;
|
|
43
|
-
const vz = cz - az;
|
|
44
|
-
|
|
45
|
-
out[0] = uy * vz - uz * vy;
|
|
46
|
-
out[1] = uz * vx - ux * vz;
|
|
47
|
-
out[2] = ux * vy - uy * vx;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Does moving `moved` to `target` reverse any triangle in its fan?
|
|
52
|
-
*
|
|
53
|
-
* Faces that also hold `other` are skipped: those are the collapse's own faces and they die with it.
|
|
54
|
-
*
|
|
55
|
-
* @param {BinaryTopology} mesh
|
|
56
|
-
* @param {number} moved the vertex whose position changes
|
|
57
|
-
* @param {number} other the collapse's other endpoint
|
|
58
|
-
* @param {Float32Array|number[]} target
|
|
59
|
-
* @param {number} target_offset
|
|
60
|
-
* @returns {boolean}
|
|
61
|
-
*/
|
|
62
|
-
function fan_would_fold(mesh, moved, other, target, target_offset) {
|
|
63
|
-
mesh.vertex_read_coordinate(scratch_moved, 0, moved);
|
|
64
|
-
|
|
65
|
-
const face_pool = mesh.faces;
|
|
66
|
-
|
|
67
|
-
let edge = mesh.vertex_read_edge(moved);
|
|
68
|
-
|
|
69
|
-
if (edge === NULL_POINTER) {
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const start_edge = edge;
|
|
74
|
-
|
|
75
|
-
do {
|
|
76
|
-
const first_loop = mesh.edge_read_loop(edge);
|
|
77
|
-
|
|
78
|
-
if (first_loop !== NULL_POINTER) {
|
|
79
|
-
let loop = first_loop;
|
|
80
|
-
|
|
81
|
-
do {
|
|
82
|
-
// each face of the fan is reached exactly once, via the loop anchored at `moved`
|
|
83
|
-
if (mesh.loop_read_vertex(loop) === moved) {
|
|
84
|
-
const face = mesh.loop_read_face(loop);
|
|
85
|
-
|
|
86
|
-
if (face !== NULL_POINTER && face_pool.is_allocated(face)) {
|
|
87
|
-
const loop_b = mesh.loop_read_next(loop);
|
|
88
|
-
const loop_c = mesh.loop_read_next(loop_b);
|
|
89
|
-
|
|
90
|
-
// triangles only; a larger polygon has no single normal to compare
|
|
91
|
-
if (mesh.loop_read_next(loop_c) === loop) {
|
|
92
|
-
const b = mesh.loop_read_vertex(loop_b);
|
|
93
|
-
const c = mesh.loop_read_vertex(loop_c);
|
|
94
|
-
|
|
95
|
-
if (b !== other && c !== other) {
|
|
96
|
-
mesh.vertex_read_coordinate(scratch_b, 0, b);
|
|
97
|
-
mesh.vertex_read_coordinate(scratch_c, 0, c);
|
|
98
|
-
|
|
99
|
-
triangle_cross(
|
|
100
|
-
scratch_before,
|
|
101
|
-
scratch_moved[0], scratch_moved[1], scratch_moved[2],
|
|
102
|
-
scratch_b[0], scratch_b[1], scratch_b[2],
|
|
103
|
-
scratch_c[0], scratch_c[1], scratch_c[2]
|
|
104
|
-
);
|
|
105
|
-
triangle_cross(
|
|
106
|
-
scratch_after,
|
|
107
|
-
target[target_offset], target[target_offset + 1], target[target_offset + 2],
|
|
108
|
-
scratch_b[0], scratch_b[1], scratch_b[2],
|
|
109
|
-
scratch_c[0], scratch_c[1], scratch_c[2]
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
const dot = scratch_before[0] * scratch_after[0]
|
|
113
|
-
+ scratch_before[1] * scratch_after[1]
|
|
114
|
-
+ scratch_before[2] * scratch_after[2];
|
|
115
|
-
|
|
116
|
-
if (dot <= 0) {
|
|
117
|
-
return true;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
loop = mesh.loop_read_radial_next(loop);
|
|
125
|
-
} while (loop !== first_loop && loop !== NULL_POINTER);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
edge = (mesh.edge_read_vertex1(edge) === moved)
|
|
129
|
-
? mesh.edge_read_v1_disk_next(edge)
|
|
130
|
-
: mesh.edge_read_v2_disk_next(edge);
|
|
131
|
-
} while (edge !== start_edge && edge !== NULL_POINTER);
|
|
132
|
-
|
|
133
|
-
return false;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
11
|
/**
|
|
137
12
|
* Would collapsing `survivor`-`victim` onto `target` turn any surviving triangle inside out?
|
|
138
13
|
*
|
|
@@ -152,6 +27,12 @@ function fan_would_fold(mesh, moved, other, target, target_offset) {
|
|
|
152
27
|
* worse rather than better — a pinned endpoint takes the placement with it, and the surviving
|
|
153
28
|
* vertex lands on the pin rather than anywhere the geometry chose.
|
|
154
29
|
*
|
|
30
|
+
* **A `true` here is not a reason to abandon the collapse**, and a caller free to choose the
|
|
31
|
+
* placement should not treat it as one. The set of placements that fold nothing is convex, so a
|
|
32
|
+
* caller holding one placement it likes and one that works can slide between them and find the
|
|
33
|
+
* best point that does — {@link bt_edge_collapse_fold_limit} is that question, this is the same
|
|
34
|
+
* walk asking it at a single point, and this function is a call to that one.
|
|
35
|
+
*
|
|
155
36
|
* @param {BinaryTopology} mesh
|
|
156
37
|
* @param {number} survivor the endpoint that stays allocated
|
|
157
38
|
* @param {number} victim the endpoint that is removed
|
|
@@ -160,6 +41,7 @@ function fan_would_fold(mesh, moved, other, target, target_offset) {
|
|
|
160
41
|
* @returns {boolean}
|
|
161
42
|
*/
|
|
162
43
|
export function bt_edge_collapse_would_fold(mesh, survivor, victim, target, target_offset = 0) {
|
|
163
|
-
return
|
|
164
|
-
|
|
44
|
+
return bt_edge_collapse_fold_limit(
|
|
45
|
+
mesh, survivor, victim, target, target, target_offset, target_offset
|
|
46
|
+
) < 0;
|
|
165
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bt_mesh_build_face_bvh.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_face_bvh.js"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,
|
|
1
|
+
{"version":3,"file":"bt_mesh_build_face_bvh.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_face_bvh.js"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,6EAkEC"}
|
|
@@ -15,12 +15,22 @@ export function bt_mesh_build_face_bvh(bvh, mesh) {
|
|
|
15
15
|
// clear out the BVH
|
|
16
16
|
bvh.release_all();
|
|
17
17
|
|
|
18
|
-
// NOTE: we assume there are no holes in the allocation, data must be packed
|
|
19
18
|
const face_count = mesh.faces.size;
|
|
20
19
|
|
|
21
20
|
const vertex_position = new Float32Array(3);
|
|
22
21
|
|
|
23
22
|
for (let face_id = 0; face_id < face_count; face_id++) {
|
|
23
|
+
/**
|
|
24
|
+
* The face pool can have holes: `bt_face_kill` leaves the slot unallocated with its loop
|
|
25
|
+
* pointer at NULL_POINTER, and reading a loop at that address is off the end of the
|
|
26
|
+
* DataView. The navmesh pipeline compacts only inside three conditional branches, so "the
|
|
27
|
+
* caller hands us a packed mesh" was a precondition no caller could honour. The sibling
|
|
28
|
+
* builder, `bt_mesh_build_surface_triangle_bvh`, skips them the same way.
|
|
29
|
+
*/
|
|
30
|
+
if (!mesh.faces.is_allocated(face_id)) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
|
|
24
34
|
let bounds_x0 = Infinity;
|
|
25
35
|
let bounds_y0 = Infinity;
|
|
26
36
|
let bounds_z0 = Infinity;
|
|
@@ -62,12 +62,12 @@ export function mn_graph_collapse_weighted_edge(
|
|
|
62
62
|
heap.delete(b_edge);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
// The merge above raises the survivor's weight, and the heap is keyed on `-weight`, so the
|
|
66
|
+
// survivor's score *falls* and it has to move up. `bubbleDown` alone, which is what this
|
|
67
|
+
// used to do, is a no-op for an element that has sunk below its parent — the heaviest edge
|
|
68
|
+
// then sits stranded under a lighter one and the coarsener stops collapsing in weight
|
|
69
|
+
// order. `updateElementScore` goes both ways, and does not need the heap's private `data`.
|
|
70
|
+
heap.updateElementScore(target_edge);
|
|
71
71
|
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ParameterLookupTable.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/lookup/ParameterLookupTable.js"],"names":[],"mappings":"AAWA;
|
|
1
|
+
{"version":3,"file":"ParameterLookupTable.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/lookup/ParameterLookupTable.js"],"names":[],"mappings":"AAWA;IAsbI;;;;;OAKG;IACH,sBAJW,MAAM,UACN,MAAM,EAAE,cACR,MAAM,EAAE,wBAQlB;IAED;;;;OAIG;IACH,8CAFa,oBAAoB,CA0BhC;IAjcD;;;;OAIG;IACH,uBAHW,MAAM,EAYhB;IA5CD;;;OAGG;IACH,MAFU,MAAM,EAAE,GAAC,YAAY,CAErB;IAEV;;;OAGG;IACH,WAFU,MAAM,EAAE,GAAC,YAAY,CAEhB;IAEf;;;OAGG;IACH,UAFU,MAAM,CAEH;IAEb;;;OAGG;IACH,UAFU,MAAM,CAEH;IAEb;;;OAGG;IACH,cAA4C;IAUxC;;;OAGG;IACH,UAFU,MAAM,CAEQ;IAI5B;;;OAGG;IACH,WAFW,yBAAyB,QAInC;IAED;;;OAGG;IACH,aAFW,yBAAyB,GAAC,MAAM,QAI1C;IAED;;;;OAIG;IACH,WAHW,yBAAyB,GACvB,OAAO,CAInB;IAED,yBAEC;IAED,0BAGC;IAED;;;;MAMC;IAED;;;;OAIG;IACH,2CAgDC;IAED;;;OAGG;IACH,6CAkCC;IAED;;;;OAIG;IACH,iBAHW,MAAM,UACN,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,QA0D5C;IAED,gCAUC;IAED;;;;OAIG;IACH,cAHW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,GAAC,UAAU,cAC7C,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,QA4B5C;IAED;;;;OAIG;IACH,mBAHW,MAAM,SACN,MAAM,EAAE,QAqClB;IAED;;OAEG;IACH,0BAkBC;IAED,eAgBC;IAED;;;;OAIG;IACH,cAHW,oBAAoB,GAClB,OAAO,CAenB;IAED,oBAwCC;IAgDL;;;OAGG;IACH,iCAFU,OAAO,CAEoC;CANpD;0CAreyC,gCAAgC"}
|
|
@@ -107,15 +107,20 @@ export class ParameterLookupTable {
|
|
|
107
107
|
toBinaryBuffer(buffer) {
|
|
108
108
|
const itemCount = this.positions.length;
|
|
109
109
|
|
|
110
|
-
const itemCountBitSize = Math.log2(itemCount);
|
|
111
|
-
|
|
112
110
|
let itemCountByteSize;
|
|
113
111
|
|
|
114
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Sized from the value and not from `Math.log2(itemCount)`: the bits needed to hold `n` are
|
|
114
|
+
* `ceil(log2(n + 1))`, so a log2 test is off by exactly one representable value at each
|
|
115
|
+
* boundary. 256 read as "8 bits, fits a byte" and `setUint8` then wrote `256 % 256 === 0`,
|
|
116
|
+
* which left the reader allocating nothing and stopping the cursor an entire payload short
|
|
117
|
+
* of where the writer left it.
|
|
118
|
+
*/
|
|
119
|
+
if (itemCount < 256) {
|
|
115
120
|
itemCountByteSize = 1;
|
|
116
|
-
} else if (
|
|
121
|
+
} else if (itemCount < 65536) {
|
|
117
122
|
itemCountByteSize = 2;
|
|
118
|
-
} else if (
|
|
123
|
+
} else if (itemCount < 4294967296) {
|
|
119
124
|
itemCountByteSize = 4;
|
|
120
125
|
} else {
|
|
121
126
|
throw new Error(`Item count is too high`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdnoise.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/noise/sdnoise.js"],"names":[],"mappings":"AA6LA;;;;;;;GAOG;AACH,sCAHW,MAAM,EAAE,KADR,MAAM,GAEJ,MAAM,
|
|
1
|
+
{"version":3,"file":"sdnoise.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/noise/sdnoise.js"],"names":[],"mappings":"AA6LA;;;;;;;GAOG;AACH,sCAHW,MAAM,EAAE,KADR,MAAM,GAEJ,MAAM,CAsDlB;AAUD;;;;;;;;GAQG;AACH,sCAHW,MAAM,EAAE,KAFR,MAAM,KACN,MAAM,GAEJ,MAAM,CAmIlB;AAUD;;;;;;;;;GASG;AACH,sCAHW,MAAM,EAAE,KAHR,MAAM,KACN,MAAM,KACN,MAAM,GAEJ,MAAM,CAgPlB;AAMD;;;;;;;;;;GAUG;AACH,sCAPW,MAAM,EAAE,KACR,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,GACJ,MAAM,CAgSlB"}
|
|
@@ -196,7 +196,10 @@ function grad4(result, hash) {
|
|
|
196
196
|
* @returns {number}
|
|
197
197
|
*/
|
|
198
198
|
export function sdnoise1(derivatives, x) {
|
|
199
|
-
|
|
199
|
+
//Math.floor, not `| 0`: `| 0` truncates toward zero, which names the cell above a negative
|
|
200
|
+
//point rather than the one containing it, and tears the field along every negative cell boundary.
|
|
201
|
+
//Gustavson's reference uses FASTFLOOR here for exactly this reason.
|
|
202
|
+
const i0 = Math.floor(x);
|
|
200
203
|
const i1 = i0 + 1;
|
|
201
204
|
|
|
202
205
|
const x0 = x - i0;
|
|
@@ -275,8 +278,9 @@ export function sdnoise2(derivatives, x, y) {
|
|
|
275
278
|
const xs = x + s;
|
|
276
279
|
const ys = y + s;
|
|
277
280
|
|
|
278
|
-
|
|
279
|
-
let
|
|
281
|
+
//see sdnoise1 on why this is Math.floor and not `| 0`
|
|
282
|
+
let ii, i = Math.floor(xs);
|
|
283
|
+
let jj, j = Math.floor(ys);
|
|
280
284
|
|
|
281
285
|
const t = (i + j) * G2;
|
|
282
286
|
const X0 = i - t; /* Unskew the cell origin back to (x,y) space */
|
|
@@ -426,9 +430,10 @@ export function sdnoise3(derivatives, x, y, z) {
|
|
|
426
430
|
const ys = y + s;
|
|
427
431
|
const zs = z + s;
|
|
428
432
|
|
|
429
|
-
|
|
430
|
-
const
|
|
431
|
-
const
|
|
433
|
+
//see sdnoise1 on why this is Math.floor and not `| 0`
|
|
434
|
+
const i = Math.floor(xs);
|
|
435
|
+
const j = Math.floor(ys);
|
|
436
|
+
const k = Math.floor(zs);
|
|
432
437
|
|
|
433
438
|
const t = (i + j + k) * G3;
|
|
434
439
|
|
|
@@ -683,10 +688,11 @@ export function sdnoise4(derivatives, x, y, z, w) {
|
|
|
683
688
|
const zs = z + s;
|
|
684
689
|
const ws = w + s;
|
|
685
690
|
|
|
686
|
-
|
|
687
|
-
let
|
|
688
|
-
let
|
|
689
|
-
let
|
|
691
|
+
//see sdnoise1 on why this is Math.floor and not `| 0`
|
|
692
|
+
let ii, i = Math.floor(xs);
|
|
693
|
+
let jj, j = Math.floor(ys);
|
|
694
|
+
let kk, k = Math.floor(zs);
|
|
695
|
+
let ll, l = Math.floor(ws);
|
|
690
696
|
|
|
691
697
|
const t = (i + j + k + l) * G4; // Factor for 4D unskewing
|
|
692
698
|
const X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImmutableObjectPool.d.ts","sourceRoot":"","sources":["../../../../../src/core/model/object/ImmutableObjectPool.js"],"names":[],"mappings":"AAIA;;GAEG;AACH;IA+BI;;;OAaC;IA3CD;;;OAGG;IACH,wBAAwB;IACxB;;;OAGG;IACH,MAFU,QAAQ,GAAG,EAAE,aAAa,GAAG,EAAC,KAAK,CAAC,EAAE,CAAC,CAE5B;IAErB;;;;OAIG;IACH,gBAAe;IACf;;;;OAIG;IACH,eAAc;IAEd;;;OAGG;IACH,MAFU,MAAM,CAEP;IAIL;;;OAGG;IACH,UAFU,MAAM,CAEQ;IAExB;;;OAGG;IACH,gBAFU,MAAM,CAEoB;IAGxC,qBAuBC;IAED;;;;;OAKG;IACH,yBAUC;IAED;;;OAGG;IACH,cAIC;IAED;;;;OAIG;IACH,wBAkBC;IAED,
|
|
1
|
+
{"version":3,"file":"ImmutableObjectPool.d.ts","sourceRoot":"","sources":["../../../../../src/core/model/object/ImmutableObjectPool.js"],"names":[],"mappings":"AAIA;;GAEG;AACH;IA+BI;;;OAaC;IA3CD;;;OAGG;IACH,wBAAwB;IACxB;;;OAGG;IACH,MAFU,QAAQ,GAAG,EAAE,aAAa,GAAG,EAAC,KAAK,CAAC,EAAE,CAAC,CAE5B;IAErB;;;;OAIG;IACH,gBAAe;IACf;;;;OAIG;IACH,eAAc;IAEd;;;OAGG;IACH,MAFU,MAAM,CAEP;IAIL;;;OAGG;IACH,UAFU,MAAM,CAEQ;IAExB;;;OAGG;IACH,gBAFU,MAAM,CAEoB;IAGxC,qBAuBC;IAED;;;;;OAKG;IACH,yBAUC;IAED;;;OAGG;IACH,cAIC;IAED;;;;OAIG;IACH,wBAkBC;IAED,mCAqDC;CACJ;wBAxLuB,iCAAiC;6BAD5B,6BAA6B"}
|
|
@@ -131,14 +131,9 @@ export class ImmutableObjectPool {
|
|
|
131
131
|
|
|
132
132
|
add(key, value) {
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if (elements === undefined) {
|
|
137
|
-
// no elements for this key, create container
|
|
138
|
-
elements = [];
|
|
139
|
-
this.data.set(key, elements);
|
|
134
|
+
const existing_elements = this.data.get(key);
|
|
140
135
|
|
|
141
|
-
|
|
136
|
+
if (existing_elements !== undefined && existing_elements.length >= this.perKeyCapacity) {
|
|
142
137
|
// reached capacity for this key, discard element
|
|
143
138
|
return false;
|
|
144
139
|
}
|
|
@@ -149,6 +144,21 @@ export class ImmutableObjectPool {
|
|
|
149
144
|
this.__removeElement(this.__first);
|
|
150
145
|
}
|
|
151
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Resolved after the eviction, never before. When the victim is the last element under this
|
|
149
|
+
* same key, `__removeElement` deletes the bucket out of the map — a reference taken before
|
|
150
|
+
* that points at an array nothing can reach any more, and the element pushed into it is
|
|
151
|
+
* counted in `size` and linked into the eviction list but invisible to `get`, which then
|
|
152
|
+
* makes `clear` throw when it walks the list onto it.
|
|
153
|
+
*/
|
|
154
|
+
let elements = this.data.get(key);
|
|
155
|
+
|
|
156
|
+
if (elements === undefined) {
|
|
157
|
+
// no elements for this key, create container
|
|
158
|
+
elements = [];
|
|
159
|
+
this.data.set(key, elements);
|
|
160
|
+
}
|
|
161
|
+
|
|
152
162
|
const cache_element = new CacheElement();
|
|
153
163
|
|
|
154
164
|
cache_element.value = value;
|
|
@@ -85,11 +85,7 @@ declare class ConcurrentExecutor {
|
|
|
85
85
|
* @returns {boolean}
|
|
86
86
|
*/
|
|
87
87
|
contains(task: Task): boolean;
|
|
88
|
-
|
|
89
|
-
* kicks the scheduler into action, this is an internal method and should not be called from outside
|
|
90
|
-
* @private
|
|
91
|
-
*/
|
|
92
|
-
private prod;
|
|
88
|
+
prod(): void;
|
|
93
89
|
join(callback: any): void;
|
|
94
90
|
#private;
|
|
95
91
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConcurrentExecutor.d.ts","sourceRoot":"","sources":["../../../../../src/core/process/executor/ConcurrentExecutor.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"ConcurrentExecutor.d.ts","sourceRoot":"","sources":["../../../../../src/core/process/executor/ConcurrentExecutor.js"],"names":[],"mappings":";mBASa,OAAO,iBAAiB,EAAE,IAAI;wBAC9B,OAAO,sBAAsB,EAAE,OAAO;AAYnD;;GAEG;AACH;IAaI;;;;;OAKG;IACH,wBAJW,MAAM,aACN,MAAM,EAwChB;IApCG;;;OAGG;IACH,WAFU,MAAM,CAEU;IAC1B;;;OAGG;IACH,UAFU,MAAM,CAEQ;IAExB;;;OAGG;IACH,iBAFU,IAAI,EAAE,CAES;IAEzB;;;OAGG;IACH,YAFU,IAAI,EAAE,CAEI;IAEpB;;;;MAIC;IAED,cAAiB;IAEjB;;;OAGG;IACH,QAFU,MAAM,GAAC,gBAAgB,CAES;IAG9C;;;OAGG;IACH,oBAFW,SAAS,QAqEnB;IAED;;;OAGG;IACH,mBAFW,SAAS,QAenB;IAED;;;;OAIG;IACH,iBAHW,IAAI,GACH,OAAO,CAwBlB;IAED;;;OAGG;IACH,UAFW,IAAI,QAKd;IAED;;;OAGG;IACH,eAFW,IAAI,EAAE,QAMhB;IAED;;;;OAIG;IACH,kBAkCC;IAED;;OAEG;IACH,qBAgDC;IAED;;;;OAIG;IACH,eAHW,IAAI,GACF,OAAO,CAYnB;IA8QD,aAYC;IAED,0BAMC;;CACJ;;;;mBA9mBkB,+BAA+B;wBAknBxC,MAAM"}
|