@woosh/meep-engine 3.64.1 → 3.65.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/CHANGELOG.md +85 -0
- 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 +5 -0
- package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
- package/src/core/binary/BinaryBuffer.js +39 -5
- package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts +65 -6
- package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.js +451 -101
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts +4 -2
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.js +4 -2
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts +8 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.js +45 -10
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.js +237 -119
- package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts +143 -0
- package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts.map +1 -0
- package/src/engine/graphics/ecs/grass/GrassSpecies.js +189 -0
- package/src/engine/graphics/ecs/grass/GrassSurface.d.ts +25 -0
- package/src/engine/graphics/ecs/grass/GrassSurface.d.ts.map +1 -0
- package/src/engine/graphics/ecs/grass/GrassSurface.js +32 -0
- package/src/engine/graphics/ecs/grass/GroundCover.d.ts +68 -0
- package/src/engine/graphics/ecs/grass/GroundCover.d.ts.map +1 -0
- package/src/engine/graphics/ecs/grass/GroundCover.js +85 -0
- package/src/engine/graphics3/GrassSurfaceSystem.d.ts +153 -0
- package/src/engine/graphics3/GrassSurfaceSystem.d.ts.map +1 -0
- package/src/engine/graphics3/GrassSurfaceSystem.js +1076 -0
- package/src/engine/graphics3/GroundCoverSystem.d.ts +33 -0
- package/src/engine/graphics3/GroundCoverSystem.d.ts.map +1 -0
- package/src/engine/graphics3/GroundCoverSystem.js +58 -0
- package/src/engine/network/NetworkSession.d.ts.map +1 -1
- package/src/engine/network/NetworkSession.js +372 -110
- package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
- package/src/engine/network/orchestrator/NetworkPeer.js +6 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +9 -2
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +325 -140
- package/src/engine/network/sim/SimActionExecutor.d.ts +4 -1
- package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
- package/src/engine/network/sim/SimActionExecutor.js +65 -9
- package/src/engine/network/state/PredictionHistory.d.ts.map +1 -1
- package/src/engine/network/state/PredictionHistory.js +6 -1
- package/src/engine/network/time/AdaptiveRenderDelay.d.ts +25 -14
- package/src/engine/network/time/AdaptiveRenderDelay.d.ts.map +1 -1
- package/src/engine/network/time/AdaptiveRenderDelay.js +38 -20
- package/src/engine/network/time/RenderPlayout.d.ts +23 -3
- package/src/engine/network/time/RenderPlayout.d.ts.map +1 -1
- package/src/engine/network/time/RenderPlayout.js +40 -4
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts +5 -1
- package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts.map +1 -1
- package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.js +27 -1
- package/src/shade/device/shader/ShaderModuleCompiler.d.ts +2 -0
- package/src/shade/device/shader/ShaderModuleCompiler.d.ts.map +1 -1
- package/src/shade/device/shader/ShaderModuleCompiler.js +25 -2
- package/src/shade/playground/grass_surfaces/index.html +75 -0
- package/src/shade/playground/grass_surfaces/main.d.ts +2 -0
- package/src/shade/playground/grass_surfaces/main.d.ts.map +1 -0
- package/src/shade/playground/grass_surfaces/main.js +593 -0
- package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts +62 -0
- package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts.map +1 -0
- package/src/shade/playground/grass_surfaces/read_grass_surfaces.js +188 -0
- package/src/shade/playground/probe_clipmap_box/README.md +5 -1
- package/src/shade/playground/probe_clipmap_box/index.html +12 -0
- package/src/shade/playground/probe_clipmap_box/main.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap_box/main.js +15 -0
- package/src/shade/playground/probe_clipmap_box/scene.d.ts +8 -1
- package/src/shade/playground/probe_clipmap_box/scene.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap_box/scene.js +74 -6
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +47 -43
- package/src/shade/renderer/extension/ViewTextures.d.ts +12 -5
- package/src/shade/renderer/extension/ViewTextures.d.ts.map +1 -1
- package/src/shade/renderer/extension/ViewTextures.js +19 -5
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +3 -1
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts.map +1 -1
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.js +6 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +7 -0
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.js +10 -0
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +7 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +46 -15
- package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts +3 -2
- package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.js +3 -2
- package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts +22 -0
- package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts.map +1 -0
- package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.js +247 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +50 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +101 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts +8 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js +12 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts +12 -6
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.js +35 -29
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.js +6 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.js +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts +6 -5
- package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.js +15 -14
- package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +19 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +128 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +19 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +27 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts +19 -11
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.js +35 -11
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +3 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts +40 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.js +174 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.d.ts +4 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.js +10 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts +31 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.js +54 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts +8 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +10 -21
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts +7 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.js +33 -29
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts +28 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.js +138 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts +13 -9
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.js +18 -11
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js +2 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts +5 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.js +15 -30
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts +11 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.js +29 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts +40 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.js +126 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts +36 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.js +221 -0
- package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts +40 -0
- package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts.map +1 -0
- package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.js +86 -0
- package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts +135 -0
- package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/GPUGrassBlades.js +676 -0
- package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts +145 -0
- package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/GRASS_BLADE.js +179 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts +63 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade.js +244 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts +58 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.js +174 -0
- package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts +25 -0
- package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/grass_blade_id_draw.js +133 -0
- package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts +80 -0
- package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/grass_blade_mechanics.js +92 -0
- package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts +29 -0
- package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/grass_blade_resolve.js +175 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts +14 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.js +45 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts +61 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_expand.js +340 -0
- package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts +46 -0
- package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/shader_grass_cell_count.js +280 -0
- package/src/shade/renderer/grass/population/chunk_grass_population.d.ts +60 -0
- package/src/shade/renderer/grass/population/chunk_grass_population.d.ts.map +1 -0
- package/src/shade/renderer/grass/population/chunk_grass_population.js +171 -0
- package/src/shade/renderer/grass/press/GPUGrassPress.d.ts +99 -0
- package/src/shade/renderer/grass/press/GPUGrassPress.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/GPUGrassPress.js +436 -0
- package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts +179 -0
- package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/GRASS_PRESS.js +217 -0
- package/src/shade/renderer/grass/press/chunk_grass_press.d.ts +65 -0
- package/src/shade/renderer/grass/press/chunk_grass_press.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/chunk_grass_press.js +296 -0
- package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts +31 -0
- package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/shader_grass_press_mark.js +169 -0
- package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts +27 -0
- package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/shader_grass_press_stamp.js +183 -0
- package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts +193 -0
- package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/GPUGrassSurfaces.js +1253 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts +211 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE.js +241 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts +82 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.js +111 -0
- package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts +39 -0
- package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_column_cross.js +85 -0
- package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts +29 -0
- package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_directory.js +112 -0
- package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts +27 -0
- package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_slot.js +50 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts +21 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.js +41 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts +32 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_window.js +136 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts +37 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surfel.js +85 -0
- package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts +25 -0
- package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_tile.js +52 -0
- package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts +23 -0
- package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_directory_fill.js +87 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts +43 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake.js +265 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts +13 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.js +49 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts +62 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.js +162 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts +40 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_retire.js +155 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts +19 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.js +58 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts +30 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_want.js +251 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts +21 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.js +75 -0
- package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.js +4 -23
- package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts +12 -0
- package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts.map +1 -0
- package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.js +29 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +22 -0
- package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
- package/src/shade/renderer/scene/GPUSceneContext.js +3 -0
- package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts +27 -0
- package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.js +38 -0
- package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts +28 -0
- package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.js +58 -0
- package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.d.ts.map +1 -1
- package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +8 -0
- package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts +37 -0
- package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.js +148 -0
- package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts +20 -0
- package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.js +169 -0
- package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts +18 -0
- package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts.map +1 -1
- package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.js +28 -0
- package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts +13 -0
- package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts.map +1 -0
- package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.js +22 -0
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
- package/src/shade/renderer/water/GPUWaterRenderer.js +4 -0
- package/src/shade/renderer/wind/GPUSceneWind.d.ts +52 -5
- package/src/shade/renderer/wind/GPUSceneWind.d.ts.map +1 -1
- package/src/shade/renderer/wind/GPUSceneWind.js +164 -8
- package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts +3 -1
- package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts.map +1 -1
- package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.js +3 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts +2 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts.map +1 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.js +18 -13
- package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts +13 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts.map +1 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_previous.js +23 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts +1 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts.map +1 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.js +6 -1
- package/src/shade/renderer/wind/wind_field_add_resources.d.ts +11 -0
- package/src/shade/renderer/wind/wind_field_add_resources.d.ts.map +1 -1
- package/src/shade/renderer/wind/wind_field_add_resources.js +15 -0
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +2 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { f32, u32 } from "../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
2
|
+
import { WebGPUStruct } from "../shader/type/WebGPUStruct.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A mesh row's membership of a grass surface: which surface it is ground of, what a column of that
|
|
6
|
+
* surface traces to find it, and what grows on it.
|
|
7
|
+
*
|
|
8
|
+
* A record of the scene database's `mesh_ground_covers` table, which shares the `meshes` table's index
|
|
9
|
+
* space: a row's ground cover is at the row's own index.
|
|
10
|
+
*
|
|
11
|
+
* **`flags` says what holds.** A row nothing has written, and a row on a page the table has never
|
|
12
|
+
* allocated, both read as a record of zeros, so zero flags is "not ground of any surface" and the other
|
|
13
|
+
* fields are read only when {@link MESH_GROUND_COVER_FLAG_MEMBER} is set.
|
|
14
|
+
*/
|
|
15
|
+
export const MESH_GROUND_COVER_STRUCT = WebGPUStruct.from({
|
|
16
|
+
/**
|
|
17
|
+
* {@link MESH_GROUND_COVER_FLAG_MEMBER}, {@link MESH_GROUND_COVER_FLAG_GROWS}.
|
|
18
|
+
*/
|
|
19
|
+
flags: u32,
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The `transforms` row of the grass surface the mesh is a member of: the surface's frame.
|
|
23
|
+
*/
|
|
24
|
+
surface: u32,
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The geometry a column traces for this member. The mesh's own, or a stand-in's for a geometry
|
|
28
|
+
* that cannot be ray traced itself.
|
|
29
|
+
*/
|
|
30
|
+
geometry: u32,
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Index of the species that grows on the member. Read only when
|
|
34
|
+
* {@link MESH_GROUND_COVER_FLAG_GROWS} is set.
|
|
35
|
+
*/
|
|
36
|
+
species: u32,
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Scale on the member's painted density, 0 to 1.
|
|
40
|
+
*/
|
|
41
|
+
density: f32,
|
|
42
|
+
}, "MeshGroundCover").pack();
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The row is a member of the surface its record names. Its faces are ground of that surface: they
|
|
46
|
+
* hold surfels, and they hide the ground of other members under them.
|
|
47
|
+
*
|
|
48
|
+
* @type {number}
|
|
49
|
+
*/
|
|
50
|
+
export const MESH_GROUND_COVER_FLAG_MEMBER = 1;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Something grows on the member, and its record's `species` holds. A member without it only hides
|
|
54
|
+
* ground.
|
|
55
|
+
*
|
|
56
|
+
* @type {number}
|
|
57
|
+
*/
|
|
58
|
+
export const MESH_GROUND_COVER_FLAG_GROWS = 2;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SCENE_DATABASE_SPEC.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/scene/SCENE_DATABASE_SPEC.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SCENE_DATABASE_SPEC.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/scene/SCENE_DATABASE_SPEC.js"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH,wDAkBG;sCAlCmC,0CAA0C"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { GPUDatabaseDefinition } from "../buffer/table/GPUDatabaseDefinition.js";
|
|
2
|
+
import { GRASS_SURFACE_PARAMS_STRUCT } from "./GRASS_SURFACE_PARAMS_STRUCT.js";
|
|
3
|
+
import { MESH_GROUND_COVER_STRUCT } from "./MESH_GROUND_COVER_STRUCT.js";
|
|
2
4
|
import { MESH_INSTANCE_METADATA_STRUCT } from "./MESH_INSTANCE_METADATA_STRUCT.js";
|
|
3
5
|
import { MESH_OUTLINE_STRUCT } from "./MESH_OUTLINE_STRUCT.js";
|
|
4
6
|
import { NODE3D_STRUCT } from "./NODE3D_STRUCT.js";
|
|
@@ -24,6 +26,12 @@ export const SCENE_DATABASE_SPEC = GPUDatabaseDefinition.from({
|
|
|
24
26
|
// which outline specs a mesh row is drawn with, at the row's own index; written by OutlineSystem
|
|
25
27
|
// when a row's specs change, read by the outline classify pass
|
|
26
28
|
mesh_outlines: MESH_OUTLINE_STRUCT,
|
|
29
|
+
// which grass surface a mesh row is ground of, at the row's own index; written by GrassSurfaceSystem
|
|
30
|
+
// when a membership changes, read by the grass surface bake and by the blades that stand on it
|
|
31
|
+
mesh_ground_covers: MESH_GROUND_COVER_STRUCT,
|
|
32
|
+
// what grows on a grass surface, at the surface's own row; written by GrassSurfaceSystem, read by
|
|
33
|
+
// the passes that count and make its blades
|
|
34
|
+
grass_surface_params: GRASS_SURFACE_PARAMS_STRUCT,
|
|
27
35
|
});
|
|
28
36
|
|
|
29
37
|
SCENE_DATABASE_SPEC.add_link({ table: 'water_bodies', field: 'node', target_database: SCENE_DATABASE_SPEC,
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What {@link chunk_ray_query_nearest_among}'s hook answers for an instance the ray passes by: the
|
|
3
|
+
* engine's one "no index" word, which no geometry reaches.
|
|
4
|
+
*
|
|
5
|
+
* @type {number}
|
|
6
|
+
*/
|
|
7
|
+
export const RAY_QUERY_AMONG_PASS: number;
|
|
8
|
+
/**
|
|
9
|
+
* The nearest hit of a ray among the scene's instances the enclosing shader chooses, each traced as the
|
|
10
|
+
* geometry that shader names for it.
|
|
11
|
+
*
|
|
12
|
+
* ```wgsl
|
|
13
|
+
* fn ray_query_nearest_among(ray: Ray) -> RayHitInfo
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* The walk over the scene's TLAS is `ray_query_nearest`'s. An instance the ray's reach meets is put to the
|
|
17
|
+
* hook before its geometry is entered, so an instance the hook passes by costs its box test and the hook,
|
|
18
|
+
* and none of its triangles.
|
|
19
|
+
*
|
|
20
|
+
* A hit holds the world distance in `t` (negative for a miss), the instance's `meshes` row in `instance`,
|
|
21
|
+
* the geometry that was traced in `geometry`, and `triangle` and `barycentrics` in that geometry.
|
|
22
|
+
*
|
|
23
|
+
* ## The seam: one function the enclosing shader defines
|
|
24
|
+
*
|
|
25
|
+
* - `fn ray_query_among_geometry(mesh: u32) -> u32` is asked about the instance at `meshes` row `mesh`,
|
|
26
|
+
* and answers with the geometry to trace for it, or `RAY_QUERY_AMONG_PASS` to pass it by. An instance
|
|
27
|
+
* traced as a geometry other than its own (a stand-in) is traced under the instance's own transform.
|
|
28
|
+
*
|
|
29
|
+
* The enclosing shader binds what `ray_query_nearest` reads: `tlas`, `scene_database` and the BLAS
|
|
30
|
+
* buffers. The ray's direction is unit length. The TLAS must hold a tree: an empty one
|
|
31
|
+
* (`tlas.root == BVH_NULL_NODE`) is the caller's to turn away.
|
|
32
|
+
*
|
|
33
|
+
* @type {CodeChunk}
|
|
34
|
+
*/
|
|
35
|
+
export const chunk_ray_query_nearest_among: CodeChunk;
|
|
36
|
+
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
37
|
+
//# sourceMappingURL=chunk_ray_query_nearest_among.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_ray_query_nearest_among.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.js"],"names":[],"mappings":"AAYA;;;;;GAKG;AACH,mCAFU,MAAM,CAE+B;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,4CAFU,SAAS,CAsGjB;0BAjJwB,gCAAgC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { UINT32_MAX } from "../../../../../../core/binary/UINT32_MAX.js";
|
|
2
|
+
import { TRANSFORMS_TABLE } from "../../../../scene/chunk_scene_database_access.js";
|
|
3
|
+
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
4
|
+
import { BVH_NULL_NODE_DEFINITION } from "../../bvh/BVH_NULL_NODE_DEFINITION.js";
|
|
5
|
+
import { BVH_TRAVERSAL_STACK_SIZE } from "../../bvh/BVH_TRAVERSAL_STACK_SIZE.js";
|
|
6
|
+
import { chunk_aabb3_intersects_ray } from "../aabb3/chunk_aabb3_intersects_ray.js";
|
|
7
|
+
import { chunk_mat4_inverse } from "../mat4/chunk_mat4_inverse.js";
|
|
8
|
+
import { chunk_ray_query_blas_nearest } from "./chunk_ray_query_blas_nearest.js";
|
|
9
|
+
import { chunk_ray_transform_m4 } from "./chunk_ray_transform_m4.js";
|
|
10
|
+
import { RAY_HIT_INFO } from "./RAY_HIT_INFO.js";
|
|
11
|
+
import { RAY_STRUCT } from "./RAY_STRUCT.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* What {@link chunk_ray_query_nearest_among}'s hook answers for an instance the ray passes by: the
|
|
15
|
+
* engine's one "no index" word, which no geometry reaches.
|
|
16
|
+
*
|
|
17
|
+
* @type {number}
|
|
18
|
+
*/
|
|
19
|
+
export const RAY_QUERY_AMONG_PASS = UINT32_MAX;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The nearest hit of a ray among the scene's instances the enclosing shader chooses, each traced as the
|
|
23
|
+
* geometry that shader names for it.
|
|
24
|
+
*
|
|
25
|
+
* ```wgsl
|
|
26
|
+
* fn ray_query_nearest_among(ray: Ray) -> RayHitInfo
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* The walk over the scene's TLAS is `ray_query_nearest`'s. An instance the ray's reach meets is put to the
|
|
30
|
+
* hook before its geometry is entered, so an instance the hook passes by costs its box test and the hook,
|
|
31
|
+
* and none of its triangles.
|
|
32
|
+
*
|
|
33
|
+
* A hit holds the world distance in `t` (negative for a miss), the instance's `meshes` row in `instance`,
|
|
34
|
+
* the geometry that was traced in `geometry`, and `triangle` and `barycentrics` in that geometry.
|
|
35
|
+
*
|
|
36
|
+
* ## The seam: one function the enclosing shader defines
|
|
37
|
+
*
|
|
38
|
+
* - `fn ray_query_among_geometry(mesh: u32) -> u32` is asked about the instance at `meshes` row `mesh`,
|
|
39
|
+
* and answers with the geometry to trace for it, or `RAY_QUERY_AMONG_PASS` to pass it by. An instance
|
|
40
|
+
* traced as a geometry other than its own (a stand-in) is traced under the instance's own transform.
|
|
41
|
+
*
|
|
42
|
+
* The enclosing shader binds what `ray_query_nearest` reads: `tlas`, `scene_database` and the BLAS
|
|
43
|
+
* buffers. The ray's direction is unit length. The TLAS must hold a tree: an empty one
|
|
44
|
+
* (`tlas.root == BVH_NULL_NODE`) is the caller's to turn away.
|
|
45
|
+
*
|
|
46
|
+
* @type {CodeChunk}
|
|
47
|
+
*/
|
|
48
|
+
export const chunk_ray_query_nearest_among = CodeChunk.from(
|
|
49
|
+
//language=WGSL
|
|
50
|
+
`
|
|
51
|
+
const RAY_QUERY_AMONG_PASS: u32 = ${RAY_QUERY_AMONG_PASS}u;
|
|
52
|
+
|
|
53
|
+
fn ray_query_nearest_among(
|
|
54
|
+
ray: ${RAY_STRUCT.wgsl_ref},
|
|
55
|
+
) -> ${RAY_HIT_INFO.wgsl_ref} {
|
|
56
|
+
var stack = array<u32, ${BVH_TRAVERSAL_STACK_SIZE}>();
|
|
57
|
+
|
|
58
|
+
var node_index = tlas.root;
|
|
59
|
+
var pointer = 1u;
|
|
60
|
+
|
|
61
|
+
let direction_rcp = 1.0 / ray.direction;
|
|
62
|
+
|
|
63
|
+
var best_hit: ${RAY_HIT_INFO.wgsl_ref};
|
|
64
|
+
best_hit.t = -1.0;
|
|
65
|
+
|
|
66
|
+
var global_ray = ray;
|
|
67
|
+
|
|
68
|
+
for (; pointer > 0u && pointer <= ${BVH_TRAVERSAL_STACK_SIZE}u;) {
|
|
69
|
+
|
|
70
|
+
let node = tlas.nodes[node_index];
|
|
71
|
+
|
|
72
|
+
if (!aabb3_intersects_ray(node.bounds, global_ray.origin, direction_rcp, global_ray.tmax)) {
|
|
73
|
+
pointer--;
|
|
74
|
+
node_index = stack[pointer];
|
|
75
|
+
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
let child_1 = node.child_1;
|
|
80
|
+
let child_2 = node.child_2;
|
|
81
|
+
|
|
82
|
+
if (child_1 != BVH_NULL_NODE) {
|
|
83
|
+
// an inner node
|
|
84
|
+
node_index = child_1;
|
|
85
|
+
|
|
86
|
+
stack[pointer] = child_2;
|
|
87
|
+
|
|
88
|
+
pointer++;
|
|
89
|
+
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
pointer--;
|
|
94
|
+
node_index = stack[pointer];
|
|
95
|
+
|
|
96
|
+
// a leaf: child_2 is the instance's meshes row
|
|
97
|
+
let mesh_id = child_2;
|
|
98
|
+
|
|
99
|
+
let geometry_id = ray_query_among_geometry(mesh_id);
|
|
100
|
+
|
|
101
|
+
if (geometry_id == RAY_QUERY_AMONG_PASS) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// a mesh row and its transforms row are the same row
|
|
106
|
+
let global = ${TRANSFORMS_TABLE.marshalling_method_read_field('global')}(&scene_database, mesh_id);
|
|
107
|
+
|
|
108
|
+
let local_ray = ray_transform_m4(global_ray, mat4_inverse(global));
|
|
109
|
+
|
|
110
|
+
let hit = ray_query_blas_nearest(local_ray, geometry_id, &stack, pointer);
|
|
111
|
+
|
|
112
|
+
if (hit.t < 0.0) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let local_hit_position = local_ray.origin + local_ray.direction * hit.t;
|
|
117
|
+
|
|
118
|
+
let global_hit_position = global * vec4(local_hit_position, 1.0);
|
|
119
|
+
|
|
120
|
+
let reach = distance(global_ray.origin, global_hit_position.xyz / global_hit_position.w);
|
|
121
|
+
|
|
122
|
+
if (reach >= global_ray.tmax) {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
global_ray.tmax = reach;
|
|
127
|
+
|
|
128
|
+
best_hit = hit;
|
|
129
|
+
|
|
130
|
+
best_hit.t = reach;
|
|
131
|
+
best_hit.instance = mesh_id;
|
|
132
|
+
best_hit.geometry = geometry_id;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return best_hit;
|
|
136
|
+
}
|
|
137
|
+
`,
|
|
138
|
+
[
|
|
139
|
+
RAY_STRUCT.declaration_chunk,
|
|
140
|
+
RAY_HIT_INFO.declaration_chunk,
|
|
141
|
+
BVH_NULL_NODE_DEFINITION,
|
|
142
|
+
chunk_ray_transform_m4,
|
|
143
|
+
chunk_aabb3_intersects_ray,
|
|
144
|
+
chunk_ray_query_blas_nearest,
|
|
145
|
+
chunk_mat4_inverse,
|
|
146
|
+
TRANSFORMS_TABLE.chunk_read_field('global'),
|
|
147
|
+
]
|
|
148
|
+
);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `shape_record_line_span(kind, parameters, origin, direction) -> vec2<f32>`: the part of a line a core
|
|
3
|
+
* shape record holds, in the record's own local frame. The line is `origin + t · direction`,
|
|
4
|
+
* `direction` unit; the answer is the `t` it enters the shape at and the `t` it leaves at. A line that
|
|
5
|
+
* misses answers a span whose first is greater than its second. Every kind is convex, so the part is
|
|
6
|
+
* one span; a half-space's is open on one side, to `±F32_MAX`, and so may a hull's be.
|
|
7
|
+
*
|
|
8
|
+
* `kind` and `parameters` are as `shape_record_signed_distance` takes them, and the span is where that
|
|
9
|
+
* distance is at most zero along the line.
|
|
10
|
+
*
|
|
11
|
+
* ## Seam
|
|
12
|
+
*
|
|
13
|
+
* A hull's planes come through `shape_record_plane(index)`, which the enclosing shader defines (see
|
|
14
|
+
* `chunk_shape_record_signed_distance`); at most `SHAPE_RECORD_HULL_PLANE_LIMIT` of them are read.
|
|
15
|
+
*
|
|
16
|
+
* @type {CodeChunk}
|
|
17
|
+
*/
|
|
18
|
+
export const chunk_shape_record_line_span: CodeChunk;
|
|
19
|
+
import { CodeChunk } from "../../compiler/CodeChunk.js";
|
|
20
|
+
//# sourceMappingURL=chunk_shape_record_line_span.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_shape_record_line_span.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AACH,2CAFU,SAAS,CAqJjB;0BAxKwB,6BAA6B"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { CodeChunk } from "../../compiler/CodeChunk.js";
|
|
2
|
+
import { F32_MAX_DEFINITION } from "../math/F32_MAX_DEFINITION.js";
|
|
3
|
+
import { chunk_shape_record_kind } from "./chunk_shape_record_kind.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* `shape_record_line_span(kind, parameters, origin, direction) -> vec2<f32>`: the part of a line a core
|
|
7
|
+
* shape record holds, in the record's own local frame. The line is `origin + t · direction`,
|
|
8
|
+
* `direction` unit; the answer is the `t` it enters the shape at and the `t` it leaves at. A line that
|
|
9
|
+
* misses answers a span whose first is greater than its second. Every kind is convex, so the part is
|
|
10
|
+
* one span; a half-space's is open on one side, to `±F32_MAX`, and so may a hull's be.
|
|
11
|
+
*
|
|
12
|
+
* `kind` and `parameters` are as `shape_record_signed_distance` takes them, and the span is where that
|
|
13
|
+
* distance is at most zero along the line.
|
|
14
|
+
*
|
|
15
|
+
* ## Seam
|
|
16
|
+
*
|
|
17
|
+
* A hull's planes come through `shape_record_plane(index)`, which the enclosing shader defines (see
|
|
18
|
+
* `chunk_shape_record_signed_distance`); at most `SHAPE_RECORD_HULL_PLANE_LIMIT` of them are read.
|
|
19
|
+
*
|
|
20
|
+
* @type {CodeChunk}
|
|
21
|
+
*/
|
|
22
|
+
export const chunk_shape_record_line_span = CodeChunk.from(
|
|
23
|
+
//language=WGSL
|
|
24
|
+
`
|
|
25
|
+
const SHAPE_RECORD_LINE_MISS = vec2<f32>(F32_MAX, -F32_MAX);
|
|
26
|
+
|
|
27
|
+
// two spans' common part
|
|
28
|
+
fn shape_record_span_meet(a: vec2<f32>, b: vec2<f32>) -> vec2<f32> {
|
|
29
|
+
return vec2<f32>(max(a.x, b.x), min(a.y, b.y));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// the least span that holds both of two spans, either of which may be a miss
|
|
33
|
+
fn shape_record_span_join(a: vec2<f32>, b: vec2<f32>) -> vec2<f32> {
|
|
34
|
+
if (a.x > a.y) {
|
|
35
|
+
return b;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (b.x > b.y) {
|
|
39
|
+
return a;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return vec2<f32>(min(a.x, b.x), max(a.y, b.y));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// where o + t·d is at most half from zero, along one axis
|
|
46
|
+
fn shape_record_line_slab(o: f32, d: f32, half: f32) -> vec2<f32> {
|
|
47
|
+
if (d == 0.0) {
|
|
48
|
+
if (abs(o) <= half) {
|
|
49
|
+
return vec2<f32>(-F32_MAX, F32_MAX);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return SHAPE_RECORD_LINE_MISS;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let a = (-half - o) / d;
|
|
56
|
+
let b = (half - o) / d;
|
|
57
|
+
|
|
58
|
+
return vec2<f32>(min(a, b), max(a, b));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// where n·(o + t·d) is at most offset
|
|
62
|
+
fn shape_record_line_half_space(o: vec3<f32>, d: vec3<f32>, plane: vec4<f32>) -> vec2<f32> {
|
|
63
|
+
let slope = dot(plane.xyz, d);
|
|
64
|
+
let height = dot(plane.xyz, o) - plane.w;
|
|
65
|
+
|
|
66
|
+
if (slope == 0.0) {
|
|
67
|
+
if (height <= 0.0) {
|
|
68
|
+
return vec2<f32>(-F32_MAX, F32_MAX);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return SHAPE_RECORD_LINE_MISS;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let t = -height / slope;
|
|
75
|
+
|
|
76
|
+
if (slope > 0.0) {
|
|
77
|
+
return vec2<f32>(-F32_MAX, t);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return vec2<f32>(t, F32_MAX);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// where o + t·d is within radius of the origin, o and d of any dimension's worth: |d|² is a, o·d is b
|
|
84
|
+
fn shape_record_line_round(a: f32, b: f32, c: f32) -> vec2<f32> {
|
|
85
|
+
if (a == 0.0) {
|
|
86
|
+
if (c <= 0.0) {
|
|
87
|
+
return vec2<f32>(-F32_MAX, F32_MAX);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return SHAPE_RECORD_LINE_MISS;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
let discriminant = b * b - a * c;
|
|
94
|
+
|
|
95
|
+
if (discriminant < 0.0) {
|
|
96
|
+
return SHAPE_RECORD_LINE_MISS;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let root = sqrt(discriminant);
|
|
100
|
+
|
|
101
|
+
return vec2<f32>((-b - root) / a, (-b + root) / a);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
fn shape_record_line_sphere(o: vec3<f32>, d: vec3<f32>, radius: f32) -> vec2<f32> {
|
|
105
|
+
return shape_record_line_round(dot(d, d), dot(o, d), dot(o, o) - radius * radius);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// a cylinder about Y, of a radius and a height, centred on the origin
|
|
109
|
+
fn shape_record_line_cylinder(o: vec3<f32>, d: vec3<f32>, radius: f32, height: f32) -> vec2<f32> {
|
|
110
|
+
let around = shape_record_line_round(dot(d.xz, d.xz), dot(o.xz, d.xz), dot(o.xz, o.xz) - radius * radius);
|
|
111
|
+
|
|
112
|
+
return shape_record_span_meet(around, shape_record_line_slab(o.y, d.y, height * 0.5));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
fn shape_record_line_span(kind: u32, parameters: vec4<f32>, origin: vec3<f32>, direction: vec3<f32>) -> vec2<f32> {
|
|
116
|
+
if (kind == SHAPE_RECORD_SPHERE) {
|
|
117
|
+
return shape_record_line_sphere(origin, direction, parameters.x);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (kind == SHAPE_RECORD_CAPSULE) {
|
|
121
|
+
// a cylinder with a ball on each end: convex, so the line's part is the span over the three
|
|
122
|
+
let end = vec3<f32>(0.0, parameters.y * 0.5, 0.0);
|
|
123
|
+
|
|
124
|
+
var span = shape_record_line_cylinder(origin, direction, parameters.x, parameters.y);
|
|
125
|
+
|
|
126
|
+
span = shape_record_span_join(span, shape_record_line_sphere(origin - end, direction, parameters.x));
|
|
127
|
+
span = shape_record_span_join(span, shape_record_line_sphere(origin + end, direction, parameters.x));
|
|
128
|
+
|
|
129
|
+
return span;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (kind == SHAPE_RECORD_BOX) {
|
|
133
|
+
var span = shape_record_line_slab(origin.x, direction.x, parameters.x);
|
|
134
|
+
|
|
135
|
+
span = shape_record_span_meet(span, shape_record_line_slab(origin.y, direction.y, parameters.y));
|
|
136
|
+
span = shape_record_span_meet(span, shape_record_line_slab(origin.z, direction.z, parameters.z));
|
|
137
|
+
|
|
138
|
+
return span;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (kind == SHAPE_RECORD_CYLINDER) {
|
|
142
|
+
return shape_record_line_cylinder(origin, direction, parameters.x, parameters.y);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (kind == SHAPE_RECORD_PLANE) {
|
|
146
|
+
return shape_record_line_half_space(origin, direction, parameters);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// SHAPE_RECORD_CONVEX_HULL: what every one of its planes leaves
|
|
150
|
+
let first = u32(parameters.x);
|
|
151
|
+
let count = u32(parameters.y);
|
|
152
|
+
|
|
153
|
+
var span = vec2<f32>(-F32_MAX, F32_MAX);
|
|
154
|
+
|
|
155
|
+
for (var i = 0u; i < SHAPE_RECORD_HULL_PLANE_LIMIT; i++) {
|
|
156
|
+
if (i >= count) {
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
span = shape_record_span_meet(span, shape_record_line_half_space(origin, direction, shape_record_plane(first + i)));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return span;
|
|
164
|
+
}
|
|
165
|
+
`, [
|
|
166
|
+
chunk_shape_record_kind,
|
|
167
|
+
F32_MAX_DEFINITION,
|
|
168
|
+
]
|
|
169
|
+
);
|
|
@@ -16,5 +16,23 @@
|
|
|
16
16
|
* @type {CodeChunk}
|
|
17
17
|
*/
|
|
18
18
|
export const chunk_tile_atlas_slot_origin: CodeChunk;
|
|
19
|
+
/**
|
|
20
|
+
* {@link chunk_tile_atlas_slot_origin} for a footprint of powers of two, given as shifts: what a reader
|
|
21
|
+
* on a hot path takes. `shift` is `tile_atlas_slot_shift(slots_x, slots_y)`, which the host passes in
|
|
22
|
+
* immediate data, so a slot is placed with masks and shifts alone, neither a texture query nor a
|
|
23
|
+
* divide in front of the fetch it addresses.
|
|
24
|
+
*
|
|
25
|
+
* Measured on the brick clipmap's trace (probe and camera rays, RTX 4090 and an RDNA2 iGPU,
|
|
26
|
+
* 2026-11-11), against the footprint from `textureDimensions` and `index_to_grid3d`: 6-7% faster on
|
|
27
|
+
* the 4090, 9.5-15% on the iGPU. The same shifts from a uniform measure the same.
|
|
28
|
+
*
|
|
29
|
+
* ```wgsl
|
|
30
|
+
* fn tile_atlas_slot_origin_shift(slot: u32, shift: u32, tile_size: vec3<u32>) -> vec3<u32>
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @see tile_atlas_slot_shift
|
|
34
|
+
* @type {CodeChunk}
|
|
35
|
+
*/
|
|
36
|
+
export const chunk_tile_atlas_slot_origin_shift: CodeChunk;
|
|
19
37
|
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
20
38
|
//# sourceMappingURL=chunk_tile_atlas_slot_origin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_tile_atlas_slot_origin.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AACH,2CAFU,SAAS,CAWjB;
|
|
1
|
+
{"version":3,"file":"chunk_tile_atlas_slot_origin.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AACH,2CAFU,SAAS,CAWjB;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,iDAFU,SAAS,CAWhB;0BAxDuB,oCAAoC"}
|
|
@@ -28,3 +28,31 @@ fn tile_atlas_slot_origin(slot: u32, slots: vec2<u32>, tile_size: vec3<u32>) ->
|
|
|
28
28
|
chunk_index_to_grid3d,
|
|
29
29
|
]
|
|
30
30
|
);
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* {@link chunk_tile_atlas_slot_origin} for a footprint of powers of two, given as shifts: what a reader
|
|
34
|
+
* on a hot path takes. `shift` is `tile_atlas_slot_shift(slots_x, slots_y)`, which the host passes in
|
|
35
|
+
* immediate data, so a slot is placed with masks and shifts alone, neither a texture query nor a
|
|
36
|
+
* divide in front of the fetch it addresses.
|
|
37
|
+
*
|
|
38
|
+
* Measured on the brick clipmap's trace (probe and camera rays, RTX 4090 and an RDNA2 iGPU,
|
|
39
|
+
* 2026-11-11), against the footprint from `textureDimensions` and `index_to_grid3d`: 6-7% faster on
|
|
40
|
+
* the 4090, 9.5-15% on the iGPU. The same shifts from a uniform measure the same.
|
|
41
|
+
*
|
|
42
|
+
* ```wgsl
|
|
43
|
+
* fn tile_atlas_slot_origin_shift(slot: u32, shift: u32, tile_size: vec3<u32>) -> vec3<u32>
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @see tile_atlas_slot_shift
|
|
47
|
+
* @type {CodeChunk}
|
|
48
|
+
*/
|
|
49
|
+
export const chunk_tile_atlas_slot_origin_shift = CodeChunk.from(
|
|
50
|
+
//language=WGSL
|
|
51
|
+
`
|
|
52
|
+
fn tile_atlas_slot_origin_shift(slot: u32, shift: u32, tile_size: vec3<u32>) -> vec3<u32> {
|
|
53
|
+
let sx = shift & 0xffffu;
|
|
54
|
+
let sy = shift >> 16u;
|
|
55
|
+
|
|
56
|
+
return vec3<u32>(slot & ((1u << sx) - 1u), (slot >> sx) & ((1u << sy) - 1u), slot >> (sx + sy)) * tile_size;
|
|
57
|
+
}
|
|
58
|
+
`);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A {@link GPUTileAtlas3D}'s footprint as `tile_atlas_slot_origin_shift` takes it: `log2 slots_x` in the
|
|
3
|
+
* low 16 bits, `log2 slots_y` in the high 16, one `u32` for a shader's immediate data.
|
|
4
|
+
*
|
|
5
|
+
* An atlas whose footprint starts at powers of two keeps them: a widen doubles a side, capped at a
|
|
6
|
+
* power of two of tiles for a power-of-two tile under a power-of-two `maxTextureDimension3D`.
|
|
7
|
+
*
|
|
8
|
+
* @param {number} slots_x tiles along x, a power of two
|
|
9
|
+
* @param {number} slots_y tiles along y, a power of two
|
|
10
|
+
* @returns {number}
|
|
11
|
+
*/
|
|
12
|
+
export function tile_atlas_slot_shift(slots_x: number, slots_y: number): number;
|
|
13
|
+
//# sourceMappingURL=tile_atlas_slot_shift.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tile_atlas_slot_shift.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/atlas/tile_atlas_slot_shift.js"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,+CAJW,MAAM,WACN,MAAM,GACJ,MAAM,CASlB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { isPowerOfTwo } from "../../../../core/math/isPowerOfTwo.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A {@link GPUTileAtlas3D}'s footprint as `tile_atlas_slot_origin_shift` takes it: `log2 slots_x` in the
|
|
6
|
+
* low 16 bits, `log2 slots_y` in the high 16, one `u32` for a shader's immediate data.
|
|
7
|
+
*
|
|
8
|
+
* An atlas whose footprint starts at powers of two keeps them: a widen doubles a side, capped at a
|
|
9
|
+
* power of two of tiles for a power-of-two tile under a power-of-two `maxTextureDimension3D`.
|
|
10
|
+
*
|
|
11
|
+
* @param {number} slots_x tiles along x, a power of two
|
|
12
|
+
* @param {number} slots_y tiles along y, a power of two
|
|
13
|
+
* @returns {number}
|
|
14
|
+
*/
|
|
15
|
+
export function tile_atlas_slot_shift(slots_x, slots_y) {
|
|
16
|
+
assert.isPositiveInteger(slots_x, 'slots_x');
|
|
17
|
+
assert.isPositiveInteger(slots_y, 'slots_y');
|
|
18
|
+
assert.ok(isPowerOfTwo(slots_x), `slots_x ${slots_x} must be a power of two`);
|
|
19
|
+
assert.ok(isPowerOfTwo(slots_y), `slots_y ${slots_y} must be a power of two`);
|
|
20
|
+
|
|
21
|
+
return (31 - Math.clz32(slots_x)) | ((31 - Math.clz32(slots_y)) << 16);
|
|
22
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPUWaterRenderer.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/water/GPUWaterRenderer.js"],"names":[],"mappings":"AAsBA,sFAAsF;AACtF;IACI,WAAa;IACb,mBAAe;IACf,yBAAqB;IACrB,aAAS;IACT,WAAa;IACb;;;;;;;;;;;MAE6B;IAmB7B;;;OAGG;IACH;;;;;MAA8F;IAC9F;;;OAGG;IACH,wBAAyD;IAMzD,oCAIC;IAED,8FAA8F;IAC9F,qCAgBC;IAED,gBASC;IAuDD;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"GPUWaterRenderer.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/water/GPUWaterRenderer.js"],"names":[],"mappings":"AAsBA,sFAAsF;AACtF;IACI,WAAa;IACb,mBAAe;IACf,yBAAqB;IACrB,aAAS;IACT,WAAa;IACb;;;;;;;;;;;MAE6B;IAmB7B;;;OAGG;IACH;;;;;MAA8F;IAC9F;;;OAGG;IACH,wBAAyD;IAMzD,oCAIC;IAED,8FAA8F;IAC9F,qCAgBC;IAED,gBASC;IAuDD;;;;;;;;;;;;;;;;;;MA+IC;IAQD;;;;;YAMC;IAED;;;;;;;;;;MAOC;IAED;;;;;;;;;;;;;;MAwBC;IAED,gGAAgG;IAChG,mEAYC;;CAyBJ;gCA7X+B,uCAAuC"}
|
|
@@ -228,6 +228,10 @@ export class GPUWaterRenderer {
|
|
|
228
228
|
let states = this.#prepared.get(graph);
|
|
229
229
|
if (states === undefined) { states = new Map(); this.#prepared.set(graph, states); }
|
|
230
230
|
states.set(camera, data);
|
|
231
|
+
// The optics pick the probes at each pixel of the interface, which the G-buffer holds no pixel of: the
|
|
232
|
+
// interface asks for them, by the normal the receivers stored and the optics turn to the eye.
|
|
233
|
+
probes.graph_want_surface({ graph, depth: data.interface_depth, normal: data.trace_metadata, normal_channel: 1,
|
|
234
|
+
two_sided: true, camera: view_ctx.camera.buffer, resolution });
|
|
231
235
|
if (settings.debug_view !== 0) {
|
|
232
236
|
let views = this.#inspection.get(graph);
|
|
233
237
|
if (views === undefined) { views = new Map(); this.#inspection.set(graph, views); }
|