@woosh/meep-engine 3.11.3 → 3.12.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/README.md +14 -18
- package/editor/SelectionVisualizer.js +127 -127
- package/editor/entity_world_bounds.js +27 -27
- package/editor/particles/rebuildParticleEmitter.js +31 -31
- package/editor/process/SymbolicDisplayProcess.js +1 -1
- package/editor/process/symbolic/CameraSymbolicDisplay.js +146 -146
- package/editor/process/symbolic/LightSymbolicDisplay.js +172 -172
- package/editor/prototypeEditorShell.js +156 -156
- package/editor/selection/editor_pick.js +130 -130
- package/editor/selection/screen_rect_frustum.js +119 -119
- package/editor/tools/v2/TransformControls.js +971 -971
- package/package.json +1 -1
- package/src/engine/Engine.d.ts +3 -3
- package/src/engine/Engine.d.ts.map +1 -1
- package/src/engine/Engine.js +726 -726
- package/src/engine/EngineHarness.d.ts +1 -1
- package/src/engine/EngineHarness.js +590 -590
- package/src/engine/ecs/HIERARCHY_REVIEW.md +717 -717
- package/src/engine/ecs/terrain/ecs/BuildLightTexture.d.ts +1 -1
- package/src/engine/ecs/terrain/ecs/BuildLightTexture.js +27 -27
- package/src/engine/ecs/terrain/ecs/Terrain.d.ts +1 -5
- package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/Terrain.js +790 -790
- package/src/engine/ecs/terrain/util/loadVisibleTerrainTiles.js +129 -129
- package/src/engine/graphics/ecs/camera/camera_find_active.d.ts +1 -1
- package/src/engine/graphics/ecs/camera/camera_find_active.js +28 -28
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts +1 -1
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +428 -428
- package/src/engine/graphics/ecs/water/Water.d.ts +1 -1
- package/src/engine/graphics/ecs/water/Water.js +104 -104
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts +1 -1
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +1 -1
- package/src/engine/graphics3/AnimationGraphSystem.d.ts +65 -0
- package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -0
- package/src/engine/graphics3/AnimationGraphSystem.js +329 -0
- package/src/engine/graphics3/AnimationGraphSystem3.d.ts +6 -61
- package/src/engine/graphics3/AnimationGraphSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationGraphSystem3.js +6 -325
- package/src/engine/graphics3/AnimationSystem.d.ts +76 -0
- package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -0
- package/src/engine/graphics3/AnimationSystem.js +352 -0
- package/src/engine/graphics3/AnimationSystem3.d.ts +6 -72
- package/src/engine/graphics3/AnimationSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationSystem3.js +6 -348
- package/src/engine/graphics3/CameraSystem.d.ts +49 -0
- package/src/engine/graphics3/CameraSystem.d.ts.map +1 -0
- package/src/engine/graphics3/CameraSystem.js +170 -0
- package/src/engine/graphics3/CameraSystem3.d.ts +6 -45
- package/src/engine/graphics3/CameraSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/CameraSystem3.js +6 -166
- package/src/engine/graphics3/DebugDrawSystem.d.ts +72 -0
- package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -0
- package/src/engine/graphics3/DebugDrawSystem.js +205 -0
- package/src/engine/graphics3/DebugDrawSystem3.d.ts +6 -68
- package/src/engine/graphics3/DebugDrawSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/DebugDrawSystem3.js +6 -201
- package/src/engine/graphics3/DecalSystem.d.ts +81 -0
- package/src/engine/graphics3/DecalSystem.d.ts.map +1 -0
- package/src/engine/graphics3/DecalSystem.js +441 -0
- package/src/engine/graphics3/DecalSystem3.d.ts +6 -77
- package/src/engine/graphics3/DecalSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/DecalSystem3.js +6 -437
- package/src/engine/graphics3/FogOfWarSystem.d.ts +74 -0
- package/src/engine/graphics3/FogOfWarSystem.d.ts.map +1 -0
- package/src/engine/graphics3/FogOfWarSystem.js +265 -0
- package/src/engine/graphics3/FogOfWarSystem3.d.ts +6 -70
- package/src/engine/graphics3/FogOfWarSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/FogOfWarSystem3.js +6 -261
- package/src/engine/graphics3/GraphicsEngine.d.ts +340 -0
- package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -0
- package/src/engine/graphics3/GraphicsEngine.js +790 -0
- package/src/engine/graphics3/GraphicsEngine3.d.ts +6 -336
- package/src/engine/graphics3/GraphicsEngine3.d.ts.map +1 -1
- package/src/engine/graphics3/GraphicsEngine3.js +6 -786
- package/src/engine/graphics3/HighlightSystem.d.ts +82 -0
- package/src/engine/graphics3/HighlightSystem.d.ts.map +1 -0
- package/src/engine/graphics3/HighlightSystem.js +241 -0
- package/src/engine/graphics3/HighlightSystem3.d.ts +6 -78
- package/src/engine/graphics3/HighlightSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/HighlightSystem3.js +6 -237
- package/src/engine/graphics3/LightSystem.d.ts +40 -0
- package/src/engine/graphics3/LightSystem.d.ts.map +1 -0
- package/src/engine/graphics3/LightSystem.js +211 -0
- package/src/engine/graphics3/LightSystem3.d.ts +6 -36
- package/src/engine/graphics3/LightSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/LightSystem3.js +6 -207
- package/src/engine/graphics3/MeshSystem.d.ts +106 -0
- package/src/engine/graphics3/MeshSystem.d.ts.map +1 -0
- package/src/engine/graphics3/MeshSystem.js +647 -0
- package/src/engine/graphics3/MeshSystem3.d.ts +6 -102
- package/src/engine/graphics3/MeshSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/MeshSystem3.js +6 -642
- package/src/engine/graphics3/ParticipatingMedia.d.ts +2 -2
- package/src/engine/graphics3/ParticipatingMedia.js +203 -203
- package/src/engine/graphics3/ParticipatingMediaSystem.d.ts +87 -0
- package/src/engine/graphics3/ParticipatingMediaSystem.d.ts.map +1 -0
- package/src/engine/graphics3/ParticipatingMediaSystem.js +184 -0
- package/src/engine/graphics3/ParticipatingMediaSystem3.d.ts +6 -83
- package/src/engine/graphics3/ParticipatingMediaSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/ParticipatingMediaSystem3.js +6 -180
- package/src/engine/graphics3/ParticleEmitterSystem.d.ts +76 -0
- package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -0
- package/src/engine/graphics3/ParticleEmitterSystem.js +289 -0
- package/src/engine/graphics3/ParticleEmitterSystem3.d.ts +6 -72
- package/src/engine/graphics3/ParticleEmitterSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/ParticleEmitterSystem3.js +6 -285
- package/src/engine/graphics3/PathDisplaySystem.d.ts +70 -0
- package/src/engine/graphics3/PathDisplaySystem.d.ts.map +1 -0
- package/src/engine/graphics3/PathDisplaySystem.js +309 -0
- package/src/engine/graphics3/PathDisplaySystem3.d.ts +6 -66
- package/src/engine/graphics3/PathDisplaySystem3.d.ts.map +1 -1
- package/src/engine/graphics3/PathDisplaySystem3.js +6 -305
- package/src/engine/graphics3/Pickable.d.ts +1 -1
- package/src/engine/graphics3/Pickable.js +65 -65
- package/src/engine/graphics3/PickingQuery.d.ts +1 -1
- package/src/engine/graphics3/PickingQuery.js +48 -48
- package/src/engine/graphics3/PickingSystem.d.ts +67 -0
- package/src/engine/graphics3/PickingSystem.d.ts.map +1 -0
- package/src/engine/graphics3/PickingSystem.js +273 -0
- package/src/engine/graphics3/PickingSystem3.d.ts +6 -63
- package/src/engine/graphics3/PickingSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/PickingSystem3.js +6 -269
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts +47 -0
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -0
- package/src/engine/graphics3/ShadedGeometrySystem.js +169 -0
- package/src/engine/graphics3/ShadedGeometrySystem3.d.ts +6 -43
- package/src/engine/graphics3/ShadedGeometrySystem3.d.ts.map +1 -1
- package/src/engine/graphics3/ShadedGeometrySystem3.js +6 -165
- package/src/engine/graphics3/TerrainSystem.d.ts +80 -0
- package/src/engine/graphics3/TerrainSystem.d.ts.map +1 -0
- package/src/engine/graphics3/TerrainSystem.js +566 -0
- package/src/engine/graphics3/TerrainSystem3.d.ts +6 -76
- package/src/engine/graphics3/TerrainSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/TerrainSystem3.js +6 -562
- package/src/engine/graphics3/TooltipComponentSystem.d.ts +65 -0
- package/src/engine/graphics3/TooltipComponentSystem.d.ts.map +1 -0
- package/src/engine/graphics3/TooltipComponentSystem.js +328 -0
- package/src/engine/graphics3/TooltipComponentSystem3.d.ts +6 -61
- package/src/engine/graphics3/TooltipComponentSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/TooltipComponentSystem3.js +6 -324
- package/src/engine/graphics3/Trail3DSystem.d.ts +73 -0
- package/src/engine/graphics3/Trail3DSystem.d.ts.map +1 -0
- package/src/engine/graphics3/Trail3DSystem.js +221 -0
- package/src/engine/graphics3/Trail3DSystem3.d.ts +6 -69
- package/src/engine/graphics3/Trail3DSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/Trail3DSystem3.js +6 -217
- package/src/engine/graphics3/VolumetricLightMap.d.ts +2 -2
- package/src/engine/graphics3/VolumetricLightMap.js +2 -2
- package/src/engine/graphics3/VolumetricLightMapSystem.d.ts +98 -0
- package/src/engine/graphics3/VolumetricLightMapSystem.d.ts.map +1 -0
- package/src/engine/graphics3/VolumetricLightMapSystem.js +261 -0
- package/src/engine/graphics3/VolumetricLightMapSystem3.d.ts +6 -94
- package/src/engine/graphics3/VolumetricLightMapSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/VolumetricLightMapSystem3.js +10 -261
- package/src/engine/graphics3/WaterSystem.d.ts +59 -0
- package/src/engine/graphics3/WaterSystem.d.ts.map +1 -0
- package/src/engine/graphics3/WaterSystem.js +293 -0
- package/src/engine/graphics3/WaterSystem3.d.ts +6 -55
- package/src/engine/graphics3/WaterSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/WaterSystem3.js +6 -289
- package/src/engine/graphics3/animation/AnimationGraphController.d.ts +1 -1
- package/src/engine/graphics3/animation/AnimationGraphController.js +518 -518
- package/src/engine/graphics3/animation/ClipListPlayer.d.ts +1 -1
- package/src/engine/graphics3/animation/ClipListPlayer.js +263 -263
- package/src/engine/graphics3/animation/ClipPlayback.d.ts +2 -2
- package/src/engine/graphics3/animation/ClipPlayback.js +84 -84
- package/src/engine/graphics3/decal/graph_build_decal_clusters.d.ts.map +1 -1
- package/src/engine/graphics3/decal/graph_build_decal_clusters.js +6 -8
- package/src/engine/graphics3/decal/shader_cluster_assign_decals.d.ts +0 -7
- package/src/engine/graphics3/decal/shader_cluster_assign_decals.d.ts.map +1 -1
- package/src/engine/graphics3/decal/shader_cluster_assign_decals.js +1 -1
- package/src/engine/graphics3/decal/shader_cull_decals_frustum.d.ts +0 -4
- package/src/engine/graphics3/decal/shader_cull_decals_frustum.d.ts.map +1 -1
- package/src/engine/graphics3/decal/shader_cull_decals_frustum.js +1 -1
- package/src/engine/graphics3/highlight/pack_highlight_table.d.ts +2 -2
- package/src/engine/graphics3/highlight/pack_highlight_table.d.ts.map +1 -1
- package/src/engine/graphics3/highlight/pack_highlight_table.js +74 -74
- package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +1 -1
- package/src/engine/graphics3/pose/query_entity_node_world_pose.js +101 -101
- package/src/engine/graphics3/preview/make_model_thumbnail.d.ts +3 -3
- package/src/engine/graphics3/preview/make_model_thumbnail.d.ts.map +1 -1
- package/src/engine/graphics3/preview/make_model_thumbnail.js +48 -48
- package/src/engine/graphics3/shade_camera_projection_ray.d.ts +1 -1
- package/src/engine/graphics3/shade_camera_projection_ray.js +77 -77
- package/src/engine/graphics3/shade_node_to_entity_composition.d.ts +1 -1
- package/src/engine/graphics3/shade_node_to_entity_composition.js +84 -84
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.js +0 -1
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.js +0 -1
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.js +133 -134
- package/src/shade/playground/skinned_blas_refit/verify_leaf_triangles.js +202 -202
- package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.js +249 -249
- package/src/shade/renderer/STATIC_GRAPHICS_ENGINE_ASSETS.js +1 -1
- package/src/shade/renderer/animation/pose/PosePlayback.d.ts +2 -1
- package/src/shade/renderer/animation/pose/PosePlayback.d.ts.map +1 -1
- package/src/shade/renderer/animation/pose/PosePlayback.js +2 -1
- package/src/shade/renderer/animation/shader_animation_apply.d.ts.map +1 -1
- package/src/shade/renderer/animation/shader_animation_apply.js +128 -129
- package/src/shade/renderer/animation/shader_animation_pose_resolve.d.ts.map +1 -1
- package/src/shade/renderer/animation/shader_animation_pose_resolve.js +176 -177
- package/src/shade/renderer/animation/shader_animation_tick.d.ts.map +1 -1
- package/src/shade/renderer/animation/shader_animation_tick.js +125 -126
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.js +98 -99
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.js +212 -213
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.js +120 -121
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.js +75 -76
- package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.js +371 -372
- package/src/shade/renderer/animation/skinning/shader_skin_matrix_prep.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/shader_skin_matrix_prep.js +104 -105
- package/src/shade/renderer/atmosphere/shader_multiscatter_lut.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/shader_multiscatter_lut.js +0 -1
- package/src/shade/renderer/buffer/graph_inspect_gpu_buffer.js +136 -136
- package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUDatabase.js +2 -3
- package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +319 -319
- package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.d.ts.map +1 -1
- package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.js +41 -42
- package/src/shade/renderer/buffer/util/shader_buffer_intra_copy_regions.d.ts.map +1 -1
- package/src/shade/renderer/buffer/util/shader_buffer_intra_copy_regions.js +83 -84
- package/src/shade/renderer/dynamic/shader_dynamic_mesh.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/shader_dynamic_mesh.js +177 -170
- package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +918 -918
- package/src/shade/renderer/geometry/bvh/record_blas_refit.js +4 -4
- package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.d.ts.map +1 -1
- package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.js +121 -122
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +774 -774
- package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts +1 -1
- package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.js +69 -70
- package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.js +367 -367
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.js +184 -184
- package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +1115 -1115
- package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +217 -217
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js +142 -143
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.js +0 -1
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.js +140 -141
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.js +0 -1
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.js +0 -1
- package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts.map +1 -1
- package/src/shade/renderer/light/cluster/cull/graph_cull_lights.js +191 -198
- package/src/shade/renderer/light/cluster/cull/shader_cull_lights_frustum.d.ts +0 -6
- package/src/shade/renderer/light/cluster/cull/shader_cull_lights_frustum.d.ts.map +1 -1
- package/src/shade/renderer/light/cluster/cull/shader_cull_lights_frustum.js +120 -120
- package/src/shade/renderer/light/cluster/cull/shader_cull_lights_hzb.d.ts +0 -4
- package/src/shade/renderer/light/cluster/cull/shader_cull_lights_hzb.d.ts.map +1 -1
- package/src/shade/renderer/light/cluster/cull/shader_cull_lights_hzb.js +112 -112
- package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts.map +1 -1
- package/src/shade/renderer/light/cluster/graph_assign_clsuters.js +4 -7
- package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.d.ts +0 -6
- package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.d.ts.map +1 -1
- package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.js +1 -1
- package/src/shade/renderer/lightmap/bake/raster/shader_lightmap_to_viz_buffer.js +222 -222
- package/src/shade/renderer/lightmap/bake/tile/shader_lightmap_tile_composit.js +81 -81
- package/src/shade/renderer/material/GPUMaterialContext.js +380 -380
- package/src/shade/renderer/material/standard/fragment_gbuffer_vt.js +169 -169
- package/src/shade/renderer/object_property/shader_object_property_process.d.ts.map +1 -1
- package/src/shade/renderer/object_property/shader_object_property_process.js +83 -84
- package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.d.ts.map +1 -1
- package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.js +57 -58
- package/src/shade/renderer/particles/prototypeParticleSystem.js +2 -3
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emit.js +117 -118
- package/src/shade/renderer/particles/shaders/shader_particle_finalize.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_finalize.js +77 -79
- package/src/shade/renderer/particles/shaders/shader_particle_render.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_render.js +190 -183
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +99 -100
- package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts.map +1 -1
- package/src/shade/renderer/particles/sort/shader_particle_sort.js +158 -161
- package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +184 -184
- package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.js +119 -119
- package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.js +3 -4
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.js +266 -267
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.js +270 -271
- package/src/shade/renderer/postprocess/nss/shader_nss_concat.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_concat.js +68 -69
- package/src/shade/renderer/postprocess/nss/shader_nss_conv_layer.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_conv_layer.js +225 -226
- package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.js +49 -50
- package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.js +291 -292
- package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.js +230 -231
- package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts +16 -2
- package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.js +12 -12
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +2 -2
- package/src/shade/renderer/rasterize/bucket/shader_count_meshlets_by_material.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/shader_count_meshlets_by_material.js +68 -69
- package/src/shade/renderer/rasterize/bucket/shader_make_meshlet_indirect_draw_commands_by_material.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/shader_make_meshlet_indirect_draw_commands_by_material.js +59 -60
- package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +0 -1
- package/src/shade/renderer/rasterize/bucket/shader_sort_meshlets_by_material.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/shader_sort_meshlets_by_material.js +64 -65
- package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.js +168 -169
- package/src/shade/renderer/rasterize/compute/graph_mesh_sphere_cull.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/compute/graph_mesh_sphere_cull.js +160 -161
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +109 -110
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +115 -116
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_classify_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_classify_bucket.js +139 -140
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_count_by_rasterization_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_count_by_rasterization_bucket.js +91 -92
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_rasterization_bucket_sort.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_rasterization_bucket_sort.js +88 -89
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.js +90 -91
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +65 -66
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.js +89 -90
- package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.js +169 -170
- package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.js +89 -90
- package/src/shade/renderer/rasterize/expand/mesh/shader_meshes_to_meshlet_counts.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/mesh/shader_meshes_to_meshlet_counts.js +61 -62
- package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.js +153 -154
- package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.js +144 -144
- package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.js +88 -88
- package/src/shade/renderer/rasterize/native/oit/shader_oit_generate_moments.js +217 -217
- package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.js +179 -179
- package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +178 -178
- package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.js +194 -194
- package/src/shade/renderer/rasterize/native/viz/viz_rasterization_opaque_pass_descriptor.js +76 -76
- package/src/shade/renderer/restir/di/shader_restir_di_denoise.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/shader_restir_di_denoise.js +136 -137
- package/src/shade/renderer/restir/di/shader_restir_di_resample.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/shader_restir_di_resample.js +129 -130
- package/src/shade/renderer/restir/di/shader_restir_di_resolve.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/shader_restir_di_resolve.js +99 -100
- package/src/shade/renderer/restir/di/shader_restir_di_spatial.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/shader_restir_di_spatial.js +116 -117
- package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +383 -383
- package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy_naive.js +123 -123
- package/src/shade/renderer/scene/hierarchy/shader_nodes_record_input_positions.d.ts.map +1 -1
- package/src/shade/renderer/scene/hierarchy/shader_nodes_record_input_positions.js +64 -65
- package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy.d.ts.map +1 -1
- package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy.js +372 -373
- package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy_naive.d.ts.map +1 -1
- package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy_naive.js +111 -112
- package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.d.ts.map +1 -1
- package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.js +0 -1
- package/src/shade/renderer/shader/ComputeShader.d.ts +24 -3
- package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
- package/src/shade/renderer/shader/ComputeShader.js +350 -296
- package/src/shade/renderer/shader/ImageShader.js +217 -217
- package/src/shade/renderer/shader/ShaderDescriptor.d.ts +5 -0
- package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/ShaderDescriptor.js +20 -0
- package/src/shade/renderer/shader/util/compute_infer_workgroup_size_from_source.d.ts +47 -0
- package/src/shade/renderer/shader/util/compute_infer_workgroup_size_from_source.d.ts.map +1 -0
- package/src/shade/renderer/shader/util/compute_infer_workgroup_size_from_source.js +448 -0
- package/src/shade/renderer/shadow/map/csm/graph_csm_setup_cascades.js +3 -3
- package/src/shade/renderer/shadow/ray/staged/gen/graph_gen_rays.js +3 -3
- package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.js +2 -2
- package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.js +4 -4
- package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.d.ts.map +1 -1
- package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.js +231 -232
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +1 -1
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +12 -15
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts +3 -2
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +3 -2
- package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.d.ts +0 -2
- package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.js +17 -6
- package/src/shade/renderer/water/shader_water.js +246 -246
- package/src/shade/vitest.setup.mjs +1 -1
- package/src/shade/wgsl/emulator/ComputeShaderEmulator.js +291 -291
- package/src/view/minimap/Minimap.d.ts +2 -2
- package/src/view/minimap/Minimap.d.ts.map +1 -1
- package/src/view/minimap/Minimap.js +225 -225
- package/src/view/minimap/dom/MinimapCameraView.d.ts +3 -3
- package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
- package/src/view/minimap/dom/MinimapCameraView.js +206 -206
- package/src/shade/renderer/shadow/map/csm/shader/shader_setup_cascades.d.ts +0 -3
- package/src/shade/renderer/shadow/map/csm/shader/shader_setup_cascades.d.ts.map +0 -1
- package/src/shade/renderer/shadow/map/csm/shader/shader_setup_cascades.js +0 -20
|
@@ -1,790 +1,790 @@
|
|
|
1
|
-
import { m4_allocate } from "../../../../core/geom/3d/mat4/m4_allocate.js";
|
|
2
|
-
import { array_copy } from "../../../../core/collection/array/array_copy.js";
|
|
3
|
-
import { assert } from "../../../../core/assert.js";
|
|
4
|
-
import { BvhClient } from "../../../../core/bvh2/bvh3/BvhClient.js";
|
|
5
|
-
import { IllegalStateException } from "../../../../core/fsm/exceptions/IllegalStateException.js";
|
|
6
|
-
import { SurfacePoint3 } from "../../../../core/geom/3d/SurfacePoint3.js";
|
|
7
|
-
import Vector2 from '../../../../core/geom/Vector2.js';
|
|
8
|
-
import { Sampler2D } from '../../../graphics/texture/sampler/Sampler2D.js';
|
|
9
|
-
import { WHITE_PIXEL_DATA_URL } from "../../../graphics/WHITE_PIXEL_DATA_URL.js";
|
|
10
|
-
import { TerrainOverlay } from '../overlay/TerrainOverlay.js';
|
|
11
|
-
|
|
12
|
-
import Clouds from '../TerrainClouds.js';
|
|
13
|
-
import { TerrainPreview } from "../TerrainPreview.js";
|
|
14
|
-
|
|
15
|
-
import TerrainTileManager from '../tiles/TerrainTileManager.js';
|
|
16
|
-
import { buildLightTexture } from "./BuildLightTexture.js";
|
|
17
|
-
import { GridTransformKind } from "./GridTransformKind.js";
|
|
18
|
-
import { TerrainLayers } from "./layers/TerrainLayers.js";
|
|
19
|
-
import { makeTerrainWorkerProxy } from "./makeTerrainWorkerProxy.js";
|
|
20
|
-
import { OffsetScaleTransform2D } from "./OffsetScaleTransform2D.js";
|
|
21
|
-
import { SplatMapping } from "./splat/SplatMapping.js";
|
|
22
|
-
import { TerrainFlags } from "./TerrainFlags.js";
|
|
23
|
-
|
|
24
|
-
let idCounter = 0;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Terrain is split into equal sized square patches
|
|
28
|
-
* Dimensions of single patch in width and height
|
|
29
|
-
* NOTE: edges of the terrain will typically result in patches smaller than this, so this is upper bound.
|
|
30
|
-
* A fine {@link Terrain#resolution} lowers it further, see {@link TerrainTileManager#maxTileVertexCount}.
|
|
31
|
-
* @type {number}
|
|
32
|
-
*/
|
|
33
|
-
const TILE_SIZE = 32;
|
|
34
|
-
|
|
35
|
-
class Terrain {
|
|
36
|
-
/**
|
|
37
|
-
* @readonly
|
|
38
|
-
* @type {number}
|
|
39
|
-
*/
|
|
40
|
-
id = idCounter++;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @private
|
|
44
|
-
* @type {number|TerrainFlags}
|
|
45
|
-
*/
|
|
46
|
-
flags = 0;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
*
|
|
50
|
-
* @type {number}
|
|
51
|
-
*/
|
|
52
|
-
gridScale = 1;
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Transform from grid coordinate system to world coordinate system
|
|
56
|
-
* @type {OffsetScaleTransform2D}
|
|
57
|
-
*/
|
|
58
|
-
gridTransform = new OffsetScaleTransform2D();
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
*
|
|
62
|
-
* @type {number}
|
|
63
|
-
*/
|
|
64
|
-
gridTransformKind = GridTransformKind.Direct;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Number of geometric subdivisions per single terrain tile
|
|
68
|
-
* @example if value is set to 4, each tile will be split into 4x4 quads
|
|
69
|
-
* @type {number}
|
|
70
|
-
*/
|
|
71
|
-
resolution = 4;
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* @readonly
|
|
75
|
-
* @type {Vector2}
|
|
76
|
-
*/
|
|
77
|
-
size = new Vector2(0, 0);
|
|
78
|
-
/**
|
|
79
|
-
*
|
|
80
|
-
* @type {TerrainPreview}
|
|
81
|
-
*/
|
|
82
|
-
preview = new TerrainPreview();
|
|
83
|
-
/**
|
|
84
|
-
* @readonly
|
|
85
|
-
* @type {SplatMapping}
|
|
86
|
-
*/
|
|
87
|
-
splat = new SplatMapping();
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* @readonly
|
|
91
|
-
* @type {TerrainLayers}
|
|
92
|
-
*/
|
|
93
|
-
layers = new TerrainLayers();
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* @readonly
|
|
97
|
-
* @type {WorkerProxy}
|
|
98
|
-
*/
|
|
99
|
-
__buildWorker = makeTerrainWorkerProxy();
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* @readonly
|
|
103
|
-
* @type {BvhClient}
|
|
104
|
-
*/
|
|
105
|
-
bvh = new BvhClient();
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* @deprecated
|
|
109
|
-
* @type {number}
|
|
110
|
-
*/
|
|
111
|
-
heightRange = 0;
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* whether or not frustum culling is enabled
|
|
115
|
-
* @type {boolean}
|
|
116
|
-
*/
|
|
117
|
-
frustumCulled = true;
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
*
|
|
121
|
-
* @type {AssetManager}
|
|
122
|
-
* @private
|
|
123
|
-
*/
|
|
124
|
-
__assetManager = null;
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Authored data with no consumer: the lightmap it names was bound as the terrain material's
|
|
128
|
-
* `aoMap`, and terrain ambient occlusion under Shade is the renderer's own GTAO. Kept because
|
|
129
|
-
* levels on disk carry it (I-13) and the field is what round-trips them.
|
|
130
|
-
*
|
|
131
|
-
* @type {String}
|
|
132
|
-
*/
|
|
133
|
-
lightMapURL = null;
|
|
134
|
-
|
|
135
|
-
constructor() {
|
|
136
|
-
/**
|
|
137
|
-
*
|
|
138
|
-
* @type {Clouds}
|
|
139
|
-
*/
|
|
140
|
-
this.clouds = new Clouds();
|
|
141
|
-
this.clouds.enabled = true;
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
*
|
|
145
|
-
* @type {Sampler2D}
|
|
146
|
-
*/
|
|
147
|
-
this.samplerHeight = Sampler2D.float32(1, 1, 1);
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* 4x4 transform matrix
|
|
151
|
-
* @private
|
|
152
|
-
* @type {Float32Array}
|
|
153
|
-
*/
|
|
154
|
-
this.__transform_matrix = m4_allocate();
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
*
|
|
158
|
-
* @type {TerrainOverlay}
|
|
159
|
-
*/
|
|
160
|
-
this.overlay = new TerrainOverlay(this.size);
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
*
|
|
164
|
-
* @type {TerrainTileManager}
|
|
165
|
-
* @private
|
|
166
|
-
*/
|
|
167
|
-
this.__tiles = new TerrainTileManager({
|
|
168
|
-
buildWorker: this.__buildWorker
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
this.__tiles.maxTileSize.set(TILE_SIZE, TILE_SIZE);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
*
|
|
176
|
-
* @param {number|TerrainFlags} flag
|
|
177
|
-
* @returns {void}
|
|
178
|
-
*/
|
|
179
|
-
setFlag(flag) {
|
|
180
|
-
this.flags |= flag;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
*
|
|
185
|
-
* @param {number|TerrainFlags} flag
|
|
186
|
-
* @returns {void}
|
|
187
|
-
*/
|
|
188
|
-
clearFlag(flag) {
|
|
189
|
-
this.flags &= ~flag;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
*
|
|
194
|
-
* @param {number|TerrainFlags} flag
|
|
195
|
-
* @param {boolean} value
|
|
196
|
-
*/
|
|
197
|
-
writeFlag(flag, value) {
|
|
198
|
-
if (value) {
|
|
199
|
-
this.setFlag(flag);
|
|
200
|
-
} else {
|
|
201
|
-
this.clearFlag(flag);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
*
|
|
207
|
-
* @param {number|TerrainFlags} flag
|
|
208
|
-
* @returns {boolean}
|
|
209
|
-
*/
|
|
210
|
-
getFlag(flag) {
|
|
211
|
-
return (this.flags & flag) === flag;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Stand the terrain's live services up: the tile build worker starts and the height field is
|
|
216
|
-
* shipped to it.
|
|
217
|
-
*
|
|
218
|
-
* The renderer is not in it. Linking used to bind a three `ShaderMaterial` through the graphics
|
|
219
|
-
* engine's material manager, which is what made this a renderer entry point; drawing terrain is
|
|
220
|
-
* `
|
|
221
|
-
*/
|
|
222
|
-
link() {
|
|
223
|
-
|
|
224
|
-
if (this.getFlag(TerrainFlags.Linked)) {
|
|
225
|
-
// already linked
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
this.startBuildService();
|
|
230
|
-
|
|
231
|
-
this.setFlag(TerrainFlags.Linked);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* disconnect the component, here all resources are released
|
|
236
|
-
*/
|
|
237
|
-
unlink() {
|
|
238
|
-
|
|
239
|
-
if (!this.getFlag(TerrainFlags.Linked)) {
|
|
240
|
-
// not linked
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
this.stopBuildService();
|
|
245
|
-
|
|
246
|
-
this.__tiles.dispose();
|
|
247
|
-
|
|
248
|
-
this.bvh.unlink();
|
|
249
|
-
|
|
250
|
-
this.clearFlag(TerrainFlags.Linked);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
dispose() {
|
|
254
|
-
if (this.getFlag(TerrainFlags.Linked)) {
|
|
255
|
-
throw new IllegalStateException('component is linked, must be unlinked first');
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
update(timeDelta) {
|
|
260
|
-
this.clouds.update(timeDelta);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* @param {number} x
|
|
265
|
-
* @param {number} y
|
|
266
|
-
* @param {function} callback
|
|
267
|
-
* @param {function} missCallback
|
|
268
|
-
* @param {function} errorCallback
|
|
269
|
-
*/
|
|
270
|
-
sampleHeight(x, y, callback, missCallback, errorCallback) {
|
|
271
|
-
assert.isFunction(callback, 'callback');
|
|
272
|
-
assert.isFunction(missCallback, 'missCallback');
|
|
273
|
-
assert.isFunction(errorCallback, 'errorCallback');
|
|
274
|
-
|
|
275
|
-
const hit = new SurfacePoint3();
|
|
276
|
-
|
|
277
|
-
if (this.raycastVerticalFirstSync(hit, x, y)) {
|
|
278
|
-
callback(hit.position.y);
|
|
279
|
-
} else {
|
|
280
|
-
missCallback();
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
*
|
|
286
|
-
* @param {SurfacePoint3} result
|
|
287
|
-
* @param {number} originX
|
|
288
|
-
* @param {number} originY
|
|
289
|
-
* @param {number} originZ
|
|
290
|
-
* @param {number} directionX
|
|
291
|
-
* @param {number} directionY
|
|
292
|
-
* @param {number} directionZ
|
|
293
|
-
* @returns {boolean}
|
|
294
|
-
*/
|
|
295
|
-
raycastFirstSync(
|
|
296
|
-
result,
|
|
297
|
-
originX, originY, originZ,
|
|
298
|
-
directionX, directionY, directionZ
|
|
299
|
-
) {
|
|
300
|
-
return this.__tiles.raycastFirstSync(result, originX, originY, originZ, directionX, directionY, directionZ);
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
*
|
|
305
|
-
* @param {SurfacePoint3} contact
|
|
306
|
-
* @param {number} x
|
|
307
|
-
* @param {number} y
|
|
308
|
-
* @return {boolean}
|
|
309
|
-
*/
|
|
310
|
-
raycastVerticalFirstSync(contact, x, y) {
|
|
311
|
-
return this.__tiles.raycastVerticalFirstSync(contact, x, y);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
*
|
|
316
|
-
* @param {Array.<Vector3>} points3v points in world coordinate space
|
|
317
|
-
* @param {function} callback
|
|
318
|
-
* @param {function} errorCallback
|
|
319
|
-
*/
|
|
320
|
-
projectPointsVertical(points3v, callback, errorCallback) {
|
|
321
|
-
/**
|
|
322
|
-
*
|
|
323
|
-
* @type {Terrain}
|
|
324
|
-
*/
|
|
325
|
-
const terrain = this;
|
|
326
|
-
|
|
327
|
-
let mappedCount = 0;
|
|
328
|
-
|
|
329
|
-
const l = points3v.length;
|
|
330
|
-
|
|
331
|
-
const missedPoints = [];
|
|
332
|
-
|
|
333
|
-
function finalizePoint() {
|
|
334
|
-
if (++mappedCount >= l) {
|
|
335
|
-
mendMissedPoints(points3v, missedPoints);
|
|
336
|
-
callback(points3v);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
function mapPoint(index) {
|
|
342
|
-
const p = points3v[index];
|
|
343
|
-
|
|
344
|
-
function missedCallback() {
|
|
345
|
-
//no mapping
|
|
346
|
-
missedPoints.push(index);
|
|
347
|
-
|
|
348
|
-
finalizePoint();
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
function hitCallback(y) {
|
|
352
|
-
p.y = y;
|
|
353
|
-
|
|
354
|
-
finalizePoint();
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
terrain.sampleHeight(p.x, p.z, hitCallback, missedCallback, errorCallback);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
if (l === 0) {
|
|
361
|
-
callback(points3v);
|
|
362
|
-
} else {
|
|
363
|
-
for (let i = 0; i < l; i++) {
|
|
364
|
-
mapPoint(i);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
*
|
|
371
|
-
* @param {Array.<Vector2>} points2v
|
|
372
|
-
* @param {Vector3[]} result
|
|
373
|
-
* @param {function} callback
|
|
374
|
-
* @param {function} errorCallback
|
|
375
|
-
*/
|
|
376
|
-
mapGridPoints(points2v, result, callback, errorCallback) {
|
|
377
|
-
const terrain = this;
|
|
378
|
-
|
|
379
|
-
const pointCount = points2v.length;
|
|
380
|
-
|
|
381
|
-
for (let i = 0; i < pointCount; i++) {
|
|
382
|
-
const v2 = points2v[i];
|
|
383
|
-
|
|
384
|
-
const v3 = result[i];
|
|
385
|
-
|
|
386
|
-
terrain.mapPointGrid2World(v2.x, v2.y, v3);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
this.projectPointsVertical(result, callback, errorCallback);
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
/**
|
|
393
|
-
*
|
|
394
|
-
* @param {number} x
|
|
395
|
-
* @param {number} y
|
|
396
|
-
* @param {Vector3} result
|
|
397
|
-
*/
|
|
398
|
-
mapPointGrid2World(x, y, result) {
|
|
399
|
-
assert.isNumber(x, 'x');
|
|
400
|
-
assert.isNumber(y, 'y');
|
|
401
|
-
|
|
402
|
-
assert.notNull(result,'result');
|
|
403
|
-
assert.defined(result, 'result');
|
|
404
|
-
assert.ok(result.isVector3, 'result is not Vector3');
|
|
405
|
-
|
|
406
|
-
const transform = this.gridTransform;
|
|
407
|
-
|
|
408
|
-
const _x = x * transform.scale_x + transform.offset_x;
|
|
409
|
-
const _z = y * transform.scale_y + transform.offset_y;
|
|
410
|
-
|
|
411
|
-
result.set(_x, result.y, _z);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
*
|
|
416
|
-
* @param {Vector3} v3
|
|
417
|
-
* @param {Vector2} result
|
|
418
|
-
*/
|
|
419
|
-
mapPointWorld2Grid(v3, result) {
|
|
420
|
-
const transform = this.gridTransform;
|
|
421
|
-
|
|
422
|
-
const x = (v3.x - transform.offset_x) / transform.scale_x;
|
|
423
|
-
const y = (v3.z - transform.offset_y) / transform.scale_y;
|
|
424
|
-
|
|
425
|
-
result.set(x, y);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
/**
|
|
429
|
-
*
|
|
430
|
-
* @return {Promise}
|
|
431
|
-
*/
|
|
432
|
-
promiseAllTiles() {
|
|
433
|
-
/**
|
|
434
|
-
*
|
|
435
|
-
* @type {TerrainTileManager}
|
|
436
|
-
*/
|
|
437
|
-
const tiles = this.__tiles;
|
|
438
|
-
|
|
439
|
-
const promisedTiles = [];
|
|
440
|
-
|
|
441
|
-
tiles.traverse(function (tile) {
|
|
442
|
-
const position = tile.gridPosition;
|
|
443
|
-
|
|
444
|
-
const x = position.x;
|
|
445
|
-
const y = position.y;
|
|
446
|
-
|
|
447
|
-
const tilePromise = tiles.obtain(x, y);
|
|
448
|
-
|
|
449
|
-
promisedTiles.push(tilePromise);
|
|
450
|
-
});
|
|
451
|
-
|
|
452
|
-
//promise all tiles
|
|
453
|
-
return Promise.all(promisedTiles);
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
/**
|
|
457
|
-
*
|
|
458
|
-
* @param {mat4|Float32Array|number[]} m4
|
|
459
|
-
*/
|
|
460
|
-
set transform(m4) {
|
|
461
|
-
array_copy(m4, 0, this.__transform_matrix, 0, 16);
|
|
462
|
-
|
|
463
|
-
this.__tiles.transform = m4;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
/**
|
|
467
|
-
*
|
|
468
|
-
* @return {Float32Array}
|
|
469
|
-
*/
|
|
470
|
-
get transform() {
|
|
471
|
-
return this.__transform_matrix;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
/**
|
|
475
|
-
*
|
|
476
|
-
* @param {TerrainLayer} layer
|
|
477
|
-
*/
|
|
478
|
-
addLayer(layer) {
|
|
479
|
-
const layers = this.layers;
|
|
480
|
-
const index = layers.addLayer(layer);
|
|
481
|
-
|
|
482
|
-
// expand splat
|
|
483
|
-
this.splat.addWeightLayer();
|
|
484
|
-
|
|
485
|
-
if (this.getFlag(TerrainFlags.Built)) {
|
|
486
|
-
// terrain is built, need to do a few updates
|
|
487
|
-
|
|
488
|
-
layers.buildTexture();
|
|
489
|
-
|
|
490
|
-
layer.loadTextureData(this.__assetManager).then(() => {
|
|
491
|
-
// verify that layer is still present
|
|
492
|
-
if (layers.get(index) !== layer) {
|
|
493
|
-
return;
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
layers.writeLayerDataIntoTexture(index);
|
|
497
|
-
});
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
return index;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
/**
|
|
504
|
-
* Replace the terrain's layer set.
|
|
505
|
-
*
|
|
506
|
-
* Rebuilds only what a change of layers actually reaches: the splat map's depth and the layer
|
|
507
|
-
* texture array. Distinct from {@link Terrain#build}, which registers layers as one step of
|
|
508
|
-
* standing a terrain up from nothing -- grid transform, build-worker snapshot and a fresh set
|
|
509
|
-
* of tiles. A terrain that is already built needs none of that to take new layers, and paying
|
|
510
|
-
* for it throws away tile geometry that is still good.
|
|
511
|
-
*
|
|
512
|
-
* @param {TerrainLayer[]} layers
|
|
513
|
-
* @param {AssetManager} assetManager
|
|
514
|
-
* @returns {Promise} settles once every layer's texture data has been written into the array
|
|
515
|
-
*/
|
|
516
|
-
replaceLayers(layers, assetManager) {
|
|
517
|
-
assert.defined(assetManager, 'assetManager');
|
|
518
|
-
assert.notNull(assetManager, 'assetManager');
|
|
519
|
-
assert.equal(assetManager.isAssetManager, true, '.isAssetManager !== true');
|
|
520
|
-
|
|
521
|
-
this.__assetManager = assetManager;
|
|
522
|
-
|
|
523
|
-
const terrain_layers = this.layers;
|
|
524
|
-
|
|
525
|
-
terrain_layers.clear();
|
|
526
|
-
|
|
527
|
-
const layer_count = layers.length;
|
|
528
|
-
|
|
529
|
-
for (let i = 0; i < layer_count; i++) {
|
|
530
|
-
terrain_layers.addLayer(layers[i]);
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
// the splat map carries one weight channel per layer; `Terrain#addLayer` keeps the two in
|
|
534
|
-
// step one layer at a time, this does it for the whole set at once
|
|
535
|
-
this.splat.resize(this.splat.size.x, this.splat.size.y, layer_count);
|
|
536
|
-
|
|
537
|
-
terrain_layers.buildTexture();
|
|
538
|
-
|
|
539
|
-
return terrain_layers.loadTextureData(assetManager);
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
/**
|
|
543
|
-
* Should be called after modifying heights to actualize changes
|
|
544
|
-
* @returns {Promise<void>}
|
|
545
|
-
*/
|
|
546
|
-
async updateHeights() {
|
|
547
|
-
await this.updateWorkerHeights();
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
startBuildService() {
|
|
551
|
-
this.__buildWorker.start();
|
|
552
|
-
this.updateWorkerHeights();
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
/**
|
|
556
|
-
* Ship the current height field to the build worker, which builds tile geometry from a copy of
|
|
557
|
-
* it and is otherwise blind to main-thread height writes.
|
|
558
|
-
*
|
|
559
|
-
* @returns {Promise<void>}
|
|
560
|
-
*/
|
|
561
|
-
async updateWorkerHeights() {
|
|
562
|
-
const s = this.samplerHeight;
|
|
563
|
-
const worker = this.__buildWorker;
|
|
564
|
-
|
|
565
|
-
const version = s.version;
|
|
566
|
-
|
|
567
|
-
const pending = worker.setHeightSampler(s.data, s.itemSize, s.width, s.height);
|
|
568
|
-
|
|
569
|
-
// Claim the snapshot for every tile build submitted from here on -- the worker serves
|
|
570
|
-
// requests in order, so they all see these heights -- and retire the tiles that describe
|
|
571
|
-
// an earlier one. Deliberately not awaited: waiting would leave a window in which builds
|
|
572
|
-
// are already reading the new heights while tiles still claim to hold the old.
|
|
573
|
-
this.__tiles.setHeightVersion(version);
|
|
574
|
-
|
|
575
|
-
await pending;
|
|
576
|
-
|
|
577
|
-
return await worker.computeHeightRange()
|
|
578
|
-
.then(({ min, max }) => {
|
|
579
|
-
this.__tiles.setHeightRange(min, max);
|
|
580
|
-
});
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
stopBuildService() {
|
|
584
|
-
this.__buildWorker.stop();
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
buildGridTransform() {
|
|
588
|
-
if (this.gridTransformKind === GridTransformKind.Legacy) {
|
|
589
|
-
this.gridTransform.scale_x = (this.size.x / (this.size.x - 1)) * this.gridScale;
|
|
590
|
-
this.gridTransform.scale_y = (this.size.y / (this.size.y - 1)) * this.gridScale;
|
|
591
|
-
|
|
592
|
-
this.gridTransform.offset_x = 0;
|
|
593
|
-
this.gridTransform.offset_y = 0;
|
|
594
|
-
|
|
595
|
-
} else if (this.gridTransformKind === GridTransformKind.Direct) {
|
|
596
|
-
this.gridTransform.scale_x = this.gridScale;
|
|
597
|
-
this.gridTransform.scale_y = this.gridScale;
|
|
598
|
-
|
|
599
|
-
this.gridTransform.offset_x = this.gridScale / 2;
|
|
600
|
-
this.gridTransform.offset_y = this.gridScale / 2;
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
buildNonVisual() {
|
|
605
|
-
|
|
606
|
-
this.buildGridTransform();
|
|
607
|
-
|
|
608
|
-
this.bvh.resize(0, 0, 0, 0, 0, 0);
|
|
609
|
-
|
|
610
|
-
//
|
|
611
|
-
this.overlay.size.copy(this.size);
|
|
612
|
-
|
|
613
|
-
this.__tiles.totalSize.copy(this.size);
|
|
614
|
-
this.__tiles.scale.set(this.gridScale, this.gridScale);
|
|
615
|
-
this.__tiles.resolution.set(this.resolution);
|
|
616
|
-
|
|
617
|
-
this.updateWorkerHeights();
|
|
618
|
-
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
/**
|
|
622
|
-
*
|
|
623
|
-
* @param {AssetManager} assetManager
|
|
624
|
-
*/
|
|
625
|
-
build(assetManager) {
|
|
626
|
-
if (this.getFlag(TerrainFlags.Built)) {
|
|
627
|
-
// already built
|
|
628
|
-
console.warn('already built, if you want rebuild to occur, clear this flag first');
|
|
629
|
-
return;
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
assert.defined(assetManager, 'assetManager');
|
|
633
|
-
assert.notNull(assetManager, 'assetManager');
|
|
634
|
-
assert.equal(assetManager.isAssetManager, true, '.isAssetManager !== true');
|
|
635
|
-
|
|
636
|
-
this.__assetManager = assetManager;
|
|
637
|
-
|
|
638
|
-
this.buildNonVisual();
|
|
639
|
-
|
|
640
|
-
this.layers.buildTexture();
|
|
641
|
-
|
|
642
|
-
this.layers.loadTextureData(assetManager);
|
|
643
|
-
|
|
644
|
-
/**
|
|
645
|
-
*
|
|
646
|
-
* @type {Promise<TerrainTileManager>}
|
|
647
|
-
* @deprecated
|
|
648
|
-
*/
|
|
649
|
-
this.pTiles = Promise.resolve(this.__tiles);
|
|
650
|
-
|
|
651
|
-
this.__tiles.initialize();
|
|
652
|
-
|
|
653
|
-
this.setFlag(TerrainFlags.Built);
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
/**
|
|
657
|
-
* Note: For advanced users only. You can seriously mess up how things look and function with respect to terrain here
|
|
658
|
-
* @return {TerrainTileManager}
|
|
659
|
-
*/
|
|
660
|
-
get tiles() {
|
|
661
|
-
return this.__tiles;
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
/**
|
|
665
|
-
* Bake this terrain's ambient-occlusion lightmap onto its material.
|
|
666
|
-
*
|
|
667
|
-
* **Retired (D38, 2026-08-20). Calling this throws.** See {@link buildLightTexture} for what it
|
|
668
|
-
* did and what it cost: a second WebGL context per generated level, tracing a Monte-Carlo AO map
|
|
669
|
-
* into a texture that only the three-based terrain material ever sampled. Terrain shading under
|
|
670
|
-
* Shade is U3b's virtual-texture path, and its ambient occlusion is the renderer's own GTAO.
|
|
671
|
-
*
|
|
672
|
-
* @deprecated retired by D38 — terrain AO is not baked, and this throws if called
|
|
673
|
-
* @throws {Error} always
|
|
674
|
-
*/
|
|
675
|
-
buildLightMap() {
|
|
676
|
-
buildLightTexture();
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
/**
|
|
680
|
-
*
|
|
681
|
-
* @param opt
|
|
682
|
-
* @param {Engine} engine
|
|
683
|
-
*/
|
|
684
|
-
fromJSON({
|
|
685
|
-
resolution = 4,
|
|
686
|
-
preview,
|
|
687
|
-
size = 1,
|
|
688
|
-
scale = 1,
|
|
689
|
-
material,
|
|
690
|
-
heights,
|
|
691
|
-
layers,
|
|
692
|
-
splat,
|
|
693
|
-
overlayTileImage
|
|
694
|
-
} = {}, engine) {
|
|
695
|
-
// mark as needing rebuilding
|
|
696
|
-
this.clearFlag(TerrainFlags.Built);
|
|
697
|
-
|
|
698
|
-
if (preview !== undefined) {
|
|
699
|
-
this.preview.fromJSON(preview);
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
this.resolution = resolution;
|
|
703
|
-
|
|
704
|
-
this.size.fromJSON(size);
|
|
705
|
-
|
|
706
|
-
this.gridScale = scale;
|
|
707
|
-
//
|
|
708
|
-
|
|
709
|
-
this.materialDesc = material;
|
|
710
|
-
|
|
711
|
-
if (heights !== undefined) {
|
|
712
|
-
this.samplerHeight.fromJSON(heights);
|
|
713
|
-
} else {
|
|
714
|
-
this.samplerHeight.data = new Float32Array(1);
|
|
715
|
-
this.samplerHeight.width = 1;
|
|
716
|
-
this.samplerHeight.height = 1;
|
|
717
|
-
this.samplerHeight.itemSize = 1;
|
|
718
|
-
this.samplerHeight.version++;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
this.layers.fromJSON(layers);
|
|
722
|
-
this.splat.fromJSON(splat);
|
|
723
|
-
|
|
724
|
-
if (overlayTileImage !== undefined) {
|
|
725
|
-
this.overlay.baseTileImage = overlayTileImage;
|
|
726
|
-
} else {
|
|
727
|
-
this.overlay.baseTileImage = WHITE_PIXEL_DATA_URL;
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
// debugSamplers(this);
|
|
732
|
-
this.build(engine.assetManager);
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
toJSON() {
|
|
736
|
-
|
|
737
|
-
const result = {
|
|
738
|
-
size: this.size.toJSON(),
|
|
739
|
-
scale: this.gridScale,
|
|
740
|
-
resolution: this.resolution,
|
|
741
|
-
material: this.materialDesc,
|
|
742
|
-
preview: this.preview.toJSON(),
|
|
743
|
-
heights: this.samplerHeight.toJSON(),
|
|
744
|
-
layers: this.layers.toJSON(),
|
|
745
|
-
splat: this.splat.toJSON(),
|
|
746
|
-
overlayTileImage: this.overlay.baseTileImage
|
|
747
|
-
};
|
|
748
|
-
|
|
749
|
-
return result;
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
Terrain.typeName = "Terrain";
|
|
754
|
-
|
|
755
|
-
/**
|
|
756
|
-
*
|
|
757
|
-
* @param {Vector3[]} points
|
|
758
|
-
* @param {number[]} missIndices
|
|
759
|
-
*/
|
|
760
|
-
function mendMissedPoints(points, missIndices) {
|
|
761
|
-
const numPoints = points.length;
|
|
762
|
-
const lastPointIndex = numPoints - 1;
|
|
763
|
-
|
|
764
|
-
const numMisses = missIndices.length;
|
|
765
|
-
|
|
766
|
-
for (let i = 0; i < numMisses; i++) {
|
|
767
|
-
const index = missIndices[i];
|
|
768
|
-
|
|
769
|
-
let heightSum = 0;
|
|
770
|
-
let sampleCount = 0;
|
|
771
|
-
|
|
772
|
-
if (index > 0) {
|
|
773
|
-
heightSum += points[index - 1].y;
|
|
774
|
-
sampleCount++;
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
if (index < lastPointIndex) {
|
|
778
|
-
heightSum += points[index + 1].y;
|
|
779
|
-
sampleCount++;
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
if (sampleCount > 0) {
|
|
783
|
-
points[index].y = heightSum / sampleCount;
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
export default Terrain;
|
|
790
|
-
|
|
1
|
+
import { m4_allocate } from "../../../../core/geom/3d/mat4/m4_allocate.js";
|
|
2
|
+
import { array_copy } from "../../../../core/collection/array/array_copy.js";
|
|
3
|
+
import { assert } from "../../../../core/assert.js";
|
|
4
|
+
import { BvhClient } from "../../../../core/bvh2/bvh3/BvhClient.js";
|
|
5
|
+
import { IllegalStateException } from "../../../../core/fsm/exceptions/IllegalStateException.js";
|
|
6
|
+
import { SurfacePoint3 } from "../../../../core/geom/3d/SurfacePoint3.js";
|
|
7
|
+
import Vector2 from '../../../../core/geom/Vector2.js';
|
|
8
|
+
import { Sampler2D } from '../../../graphics/texture/sampler/Sampler2D.js';
|
|
9
|
+
import { WHITE_PIXEL_DATA_URL } from "../../../graphics/WHITE_PIXEL_DATA_URL.js";
|
|
10
|
+
import { TerrainOverlay } from '../overlay/TerrainOverlay.js';
|
|
11
|
+
|
|
12
|
+
import Clouds from '../TerrainClouds.js';
|
|
13
|
+
import { TerrainPreview } from "../TerrainPreview.js";
|
|
14
|
+
|
|
15
|
+
import TerrainTileManager from '../tiles/TerrainTileManager.js';
|
|
16
|
+
import { buildLightTexture } from "./BuildLightTexture.js";
|
|
17
|
+
import { GridTransformKind } from "./GridTransformKind.js";
|
|
18
|
+
import { TerrainLayers } from "./layers/TerrainLayers.js";
|
|
19
|
+
import { makeTerrainWorkerProxy } from "./makeTerrainWorkerProxy.js";
|
|
20
|
+
import { OffsetScaleTransform2D } from "./OffsetScaleTransform2D.js";
|
|
21
|
+
import { SplatMapping } from "./splat/SplatMapping.js";
|
|
22
|
+
import { TerrainFlags } from "./TerrainFlags.js";
|
|
23
|
+
|
|
24
|
+
let idCounter = 0;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Terrain is split into equal sized square patches
|
|
28
|
+
* Dimensions of single patch in width and height
|
|
29
|
+
* NOTE: edges of the terrain will typically result in patches smaller than this, so this is upper bound.
|
|
30
|
+
* A fine {@link Terrain#resolution} lowers it further, see {@link TerrainTileManager#maxTileVertexCount}.
|
|
31
|
+
* @type {number}
|
|
32
|
+
*/
|
|
33
|
+
const TILE_SIZE = 32;
|
|
34
|
+
|
|
35
|
+
class Terrain {
|
|
36
|
+
/**
|
|
37
|
+
* @readonly
|
|
38
|
+
* @type {number}
|
|
39
|
+
*/
|
|
40
|
+
id = idCounter++;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @private
|
|
44
|
+
* @type {number|TerrainFlags}
|
|
45
|
+
*/
|
|
46
|
+
flags = 0;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
*
|
|
50
|
+
* @type {number}
|
|
51
|
+
*/
|
|
52
|
+
gridScale = 1;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Transform from grid coordinate system to world coordinate system
|
|
56
|
+
* @type {OffsetScaleTransform2D}
|
|
57
|
+
*/
|
|
58
|
+
gridTransform = new OffsetScaleTransform2D();
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
*
|
|
62
|
+
* @type {number}
|
|
63
|
+
*/
|
|
64
|
+
gridTransformKind = GridTransformKind.Direct;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Number of geometric subdivisions per single terrain tile
|
|
68
|
+
* @example if value is set to 4, each tile will be split into 4x4 quads
|
|
69
|
+
* @type {number}
|
|
70
|
+
*/
|
|
71
|
+
resolution = 4;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @readonly
|
|
75
|
+
* @type {Vector2}
|
|
76
|
+
*/
|
|
77
|
+
size = new Vector2(0, 0);
|
|
78
|
+
/**
|
|
79
|
+
*
|
|
80
|
+
* @type {TerrainPreview}
|
|
81
|
+
*/
|
|
82
|
+
preview = new TerrainPreview();
|
|
83
|
+
/**
|
|
84
|
+
* @readonly
|
|
85
|
+
* @type {SplatMapping}
|
|
86
|
+
*/
|
|
87
|
+
splat = new SplatMapping();
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @readonly
|
|
91
|
+
* @type {TerrainLayers}
|
|
92
|
+
*/
|
|
93
|
+
layers = new TerrainLayers();
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @readonly
|
|
97
|
+
* @type {WorkerProxy}
|
|
98
|
+
*/
|
|
99
|
+
__buildWorker = makeTerrainWorkerProxy();
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @readonly
|
|
103
|
+
* @type {BvhClient}
|
|
104
|
+
*/
|
|
105
|
+
bvh = new BvhClient();
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @deprecated
|
|
109
|
+
* @type {number}
|
|
110
|
+
*/
|
|
111
|
+
heightRange = 0;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* whether or not frustum culling is enabled
|
|
115
|
+
* @type {boolean}
|
|
116
|
+
*/
|
|
117
|
+
frustumCulled = true;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
*
|
|
121
|
+
* @type {AssetManager}
|
|
122
|
+
* @private
|
|
123
|
+
*/
|
|
124
|
+
__assetManager = null;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Authored data with no consumer: the lightmap it names was bound as the terrain material's
|
|
128
|
+
* `aoMap`, and terrain ambient occlusion under Shade is the renderer's own GTAO. Kept because
|
|
129
|
+
* levels on disk carry it (I-13) and the field is what round-trips them.
|
|
130
|
+
*
|
|
131
|
+
* @type {String}
|
|
132
|
+
*/
|
|
133
|
+
lightMapURL = null;
|
|
134
|
+
|
|
135
|
+
constructor() {
|
|
136
|
+
/**
|
|
137
|
+
*
|
|
138
|
+
* @type {Clouds}
|
|
139
|
+
*/
|
|
140
|
+
this.clouds = new Clouds();
|
|
141
|
+
this.clouds.enabled = true;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
*
|
|
145
|
+
* @type {Sampler2D}
|
|
146
|
+
*/
|
|
147
|
+
this.samplerHeight = Sampler2D.float32(1, 1, 1);
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* 4x4 transform matrix
|
|
151
|
+
* @private
|
|
152
|
+
* @type {Float32Array}
|
|
153
|
+
*/
|
|
154
|
+
this.__transform_matrix = m4_allocate();
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
*
|
|
158
|
+
* @type {TerrainOverlay}
|
|
159
|
+
*/
|
|
160
|
+
this.overlay = new TerrainOverlay(this.size);
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
*
|
|
164
|
+
* @type {TerrainTileManager}
|
|
165
|
+
* @private
|
|
166
|
+
*/
|
|
167
|
+
this.__tiles = new TerrainTileManager({
|
|
168
|
+
buildWorker: this.__buildWorker
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
this.__tiles.maxTileSize.set(TILE_SIZE, TILE_SIZE);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
*
|
|
176
|
+
* @param {number|TerrainFlags} flag
|
|
177
|
+
* @returns {void}
|
|
178
|
+
*/
|
|
179
|
+
setFlag(flag) {
|
|
180
|
+
this.flags |= flag;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
*
|
|
185
|
+
* @param {number|TerrainFlags} flag
|
|
186
|
+
* @returns {void}
|
|
187
|
+
*/
|
|
188
|
+
clearFlag(flag) {
|
|
189
|
+
this.flags &= ~flag;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
*
|
|
194
|
+
* @param {number|TerrainFlags} flag
|
|
195
|
+
* @param {boolean} value
|
|
196
|
+
*/
|
|
197
|
+
writeFlag(flag, value) {
|
|
198
|
+
if (value) {
|
|
199
|
+
this.setFlag(flag);
|
|
200
|
+
} else {
|
|
201
|
+
this.clearFlag(flag);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
*
|
|
207
|
+
* @param {number|TerrainFlags} flag
|
|
208
|
+
* @returns {boolean}
|
|
209
|
+
*/
|
|
210
|
+
getFlag(flag) {
|
|
211
|
+
return (this.flags & flag) === flag;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Stand the terrain's live services up: the tile build worker starts and the height field is
|
|
216
|
+
* shipped to it.
|
|
217
|
+
*
|
|
218
|
+
* The renderer is not in it. Linking used to bind a three `ShaderMaterial` through the graphics
|
|
219
|
+
* engine's material manager, which is what made this a renderer entry point; drawing terrain is
|
|
220
|
+
* `TerrainSystem`'s, and it reads the component rather than being handed a material by it.
|
|
221
|
+
*/
|
|
222
|
+
link() {
|
|
223
|
+
|
|
224
|
+
if (this.getFlag(TerrainFlags.Linked)) {
|
|
225
|
+
// already linked
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
this.startBuildService();
|
|
230
|
+
|
|
231
|
+
this.setFlag(TerrainFlags.Linked);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* disconnect the component, here all resources are released
|
|
236
|
+
*/
|
|
237
|
+
unlink() {
|
|
238
|
+
|
|
239
|
+
if (!this.getFlag(TerrainFlags.Linked)) {
|
|
240
|
+
// not linked
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
this.stopBuildService();
|
|
245
|
+
|
|
246
|
+
this.__tiles.dispose();
|
|
247
|
+
|
|
248
|
+
this.bvh.unlink();
|
|
249
|
+
|
|
250
|
+
this.clearFlag(TerrainFlags.Linked);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
dispose() {
|
|
254
|
+
if (this.getFlag(TerrainFlags.Linked)) {
|
|
255
|
+
throw new IllegalStateException('component is linked, must be unlinked first');
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
update(timeDelta) {
|
|
260
|
+
this.clouds.update(timeDelta);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* @param {number} x
|
|
265
|
+
* @param {number} y
|
|
266
|
+
* @param {function} callback
|
|
267
|
+
* @param {function} missCallback
|
|
268
|
+
* @param {function} errorCallback
|
|
269
|
+
*/
|
|
270
|
+
sampleHeight(x, y, callback, missCallback, errorCallback) {
|
|
271
|
+
assert.isFunction(callback, 'callback');
|
|
272
|
+
assert.isFunction(missCallback, 'missCallback');
|
|
273
|
+
assert.isFunction(errorCallback, 'errorCallback');
|
|
274
|
+
|
|
275
|
+
const hit = new SurfacePoint3();
|
|
276
|
+
|
|
277
|
+
if (this.raycastVerticalFirstSync(hit, x, y)) {
|
|
278
|
+
callback(hit.position.y);
|
|
279
|
+
} else {
|
|
280
|
+
missCallback();
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
*
|
|
286
|
+
* @param {SurfacePoint3} result
|
|
287
|
+
* @param {number} originX
|
|
288
|
+
* @param {number} originY
|
|
289
|
+
* @param {number} originZ
|
|
290
|
+
* @param {number} directionX
|
|
291
|
+
* @param {number} directionY
|
|
292
|
+
* @param {number} directionZ
|
|
293
|
+
* @returns {boolean}
|
|
294
|
+
*/
|
|
295
|
+
raycastFirstSync(
|
|
296
|
+
result,
|
|
297
|
+
originX, originY, originZ,
|
|
298
|
+
directionX, directionY, directionZ
|
|
299
|
+
) {
|
|
300
|
+
return this.__tiles.raycastFirstSync(result, originX, originY, originZ, directionX, directionY, directionZ);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
*
|
|
305
|
+
* @param {SurfacePoint3} contact
|
|
306
|
+
* @param {number} x
|
|
307
|
+
* @param {number} y
|
|
308
|
+
* @return {boolean}
|
|
309
|
+
*/
|
|
310
|
+
raycastVerticalFirstSync(contact, x, y) {
|
|
311
|
+
return this.__tiles.raycastVerticalFirstSync(contact, x, y);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
*
|
|
316
|
+
* @param {Array.<Vector3>} points3v points in world coordinate space
|
|
317
|
+
* @param {function} callback
|
|
318
|
+
* @param {function} errorCallback
|
|
319
|
+
*/
|
|
320
|
+
projectPointsVertical(points3v, callback, errorCallback) {
|
|
321
|
+
/**
|
|
322
|
+
*
|
|
323
|
+
* @type {Terrain}
|
|
324
|
+
*/
|
|
325
|
+
const terrain = this;
|
|
326
|
+
|
|
327
|
+
let mappedCount = 0;
|
|
328
|
+
|
|
329
|
+
const l = points3v.length;
|
|
330
|
+
|
|
331
|
+
const missedPoints = [];
|
|
332
|
+
|
|
333
|
+
function finalizePoint() {
|
|
334
|
+
if (++mappedCount >= l) {
|
|
335
|
+
mendMissedPoints(points3v, missedPoints);
|
|
336
|
+
callback(points3v);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
function mapPoint(index) {
|
|
342
|
+
const p = points3v[index];
|
|
343
|
+
|
|
344
|
+
function missedCallback() {
|
|
345
|
+
//no mapping
|
|
346
|
+
missedPoints.push(index);
|
|
347
|
+
|
|
348
|
+
finalizePoint();
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function hitCallback(y) {
|
|
352
|
+
p.y = y;
|
|
353
|
+
|
|
354
|
+
finalizePoint();
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
terrain.sampleHeight(p.x, p.z, hitCallback, missedCallback, errorCallback);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (l === 0) {
|
|
361
|
+
callback(points3v);
|
|
362
|
+
} else {
|
|
363
|
+
for (let i = 0; i < l; i++) {
|
|
364
|
+
mapPoint(i);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
*
|
|
371
|
+
* @param {Array.<Vector2>} points2v
|
|
372
|
+
* @param {Vector3[]} result
|
|
373
|
+
* @param {function} callback
|
|
374
|
+
* @param {function} errorCallback
|
|
375
|
+
*/
|
|
376
|
+
mapGridPoints(points2v, result, callback, errorCallback) {
|
|
377
|
+
const terrain = this;
|
|
378
|
+
|
|
379
|
+
const pointCount = points2v.length;
|
|
380
|
+
|
|
381
|
+
for (let i = 0; i < pointCount; i++) {
|
|
382
|
+
const v2 = points2v[i];
|
|
383
|
+
|
|
384
|
+
const v3 = result[i];
|
|
385
|
+
|
|
386
|
+
terrain.mapPointGrid2World(v2.x, v2.y, v3);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
this.projectPointsVertical(result, callback, errorCallback);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
*
|
|
394
|
+
* @param {number} x
|
|
395
|
+
* @param {number} y
|
|
396
|
+
* @param {Vector3} result
|
|
397
|
+
*/
|
|
398
|
+
mapPointGrid2World(x, y, result) {
|
|
399
|
+
assert.isNumber(x, 'x');
|
|
400
|
+
assert.isNumber(y, 'y');
|
|
401
|
+
|
|
402
|
+
assert.notNull(result,'result');
|
|
403
|
+
assert.defined(result, 'result');
|
|
404
|
+
assert.ok(result.isVector3, 'result is not Vector3');
|
|
405
|
+
|
|
406
|
+
const transform = this.gridTransform;
|
|
407
|
+
|
|
408
|
+
const _x = x * transform.scale_x + transform.offset_x;
|
|
409
|
+
const _z = y * transform.scale_y + transform.offset_y;
|
|
410
|
+
|
|
411
|
+
result.set(_x, result.y, _z);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
*
|
|
416
|
+
* @param {Vector3} v3
|
|
417
|
+
* @param {Vector2} result
|
|
418
|
+
*/
|
|
419
|
+
mapPointWorld2Grid(v3, result) {
|
|
420
|
+
const transform = this.gridTransform;
|
|
421
|
+
|
|
422
|
+
const x = (v3.x - transform.offset_x) / transform.scale_x;
|
|
423
|
+
const y = (v3.z - transform.offset_y) / transform.scale_y;
|
|
424
|
+
|
|
425
|
+
result.set(x, y);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
*
|
|
430
|
+
* @return {Promise}
|
|
431
|
+
*/
|
|
432
|
+
promiseAllTiles() {
|
|
433
|
+
/**
|
|
434
|
+
*
|
|
435
|
+
* @type {TerrainTileManager}
|
|
436
|
+
*/
|
|
437
|
+
const tiles = this.__tiles;
|
|
438
|
+
|
|
439
|
+
const promisedTiles = [];
|
|
440
|
+
|
|
441
|
+
tiles.traverse(function (tile) {
|
|
442
|
+
const position = tile.gridPosition;
|
|
443
|
+
|
|
444
|
+
const x = position.x;
|
|
445
|
+
const y = position.y;
|
|
446
|
+
|
|
447
|
+
const tilePromise = tiles.obtain(x, y);
|
|
448
|
+
|
|
449
|
+
promisedTiles.push(tilePromise);
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
//promise all tiles
|
|
453
|
+
return Promise.all(promisedTiles);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
*
|
|
458
|
+
* @param {mat4|Float32Array|number[]} m4
|
|
459
|
+
*/
|
|
460
|
+
set transform(m4) {
|
|
461
|
+
array_copy(m4, 0, this.__transform_matrix, 0, 16);
|
|
462
|
+
|
|
463
|
+
this.__tiles.transform = m4;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
*
|
|
468
|
+
* @return {Float32Array}
|
|
469
|
+
*/
|
|
470
|
+
get transform() {
|
|
471
|
+
return this.__transform_matrix;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
*
|
|
476
|
+
* @param {TerrainLayer} layer
|
|
477
|
+
*/
|
|
478
|
+
addLayer(layer) {
|
|
479
|
+
const layers = this.layers;
|
|
480
|
+
const index = layers.addLayer(layer);
|
|
481
|
+
|
|
482
|
+
// expand splat
|
|
483
|
+
this.splat.addWeightLayer();
|
|
484
|
+
|
|
485
|
+
if (this.getFlag(TerrainFlags.Built)) {
|
|
486
|
+
// terrain is built, need to do a few updates
|
|
487
|
+
|
|
488
|
+
layers.buildTexture();
|
|
489
|
+
|
|
490
|
+
layer.loadTextureData(this.__assetManager).then(() => {
|
|
491
|
+
// verify that layer is still present
|
|
492
|
+
if (layers.get(index) !== layer) {
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
layers.writeLayerDataIntoTexture(index);
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return index;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Replace the terrain's layer set.
|
|
505
|
+
*
|
|
506
|
+
* Rebuilds only what a change of layers actually reaches: the splat map's depth and the layer
|
|
507
|
+
* texture array. Distinct from {@link Terrain#build}, which registers layers as one step of
|
|
508
|
+
* standing a terrain up from nothing -- grid transform, build-worker snapshot and a fresh set
|
|
509
|
+
* of tiles. A terrain that is already built needs none of that to take new layers, and paying
|
|
510
|
+
* for it throws away tile geometry that is still good.
|
|
511
|
+
*
|
|
512
|
+
* @param {TerrainLayer[]} layers
|
|
513
|
+
* @param {AssetManager} assetManager
|
|
514
|
+
* @returns {Promise} settles once every layer's texture data has been written into the array
|
|
515
|
+
*/
|
|
516
|
+
replaceLayers(layers, assetManager) {
|
|
517
|
+
assert.defined(assetManager, 'assetManager');
|
|
518
|
+
assert.notNull(assetManager, 'assetManager');
|
|
519
|
+
assert.equal(assetManager.isAssetManager, true, '.isAssetManager !== true');
|
|
520
|
+
|
|
521
|
+
this.__assetManager = assetManager;
|
|
522
|
+
|
|
523
|
+
const terrain_layers = this.layers;
|
|
524
|
+
|
|
525
|
+
terrain_layers.clear();
|
|
526
|
+
|
|
527
|
+
const layer_count = layers.length;
|
|
528
|
+
|
|
529
|
+
for (let i = 0; i < layer_count; i++) {
|
|
530
|
+
terrain_layers.addLayer(layers[i]);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// the splat map carries one weight channel per layer; `Terrain#addLayer` keeps the two in
|
|
534
|
+
// step one layer at a time, this does it for the whole set at once
|
|
535
|
+
this.splat.resize(this.splat.size.x, this.splat.size.y, layer_count);
|
|
536
|
+
|
|
537
|
+
terrain_layers.buildTexture();
|
|
538
|
+
|
|
539
|
+
return terrain_layers.loadTextureData(assetManager);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Should be called after modifying heights to actualize changes
|
|
544
|
+
* @returns {Promise<void>}
|
|
545
|
+
*/
|
|
546
|
+
async updateHeights() {
|
|
547
|
+
await this.updateWorkerHeights();
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
startBuildService() {
|
|
551
|
+
this.__buildWorker.start();
|
|
552
|
+
this.updateWorkerHeights();
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Ship the current height field to the build worker, which builds tile geometry from a copy of
|
|
557
|
+
* it and is otherwise blind to main-thread height writes.
|
|
558
|
+
*
|
|
559
|
+
* @returns {Promise<void>}
|
|
560
|
+
*/
|
|
561
|
+
async updateWorkerHeights() {
|
|
562
|
+
const s = this.samplerHeight;
|
|
563
|
+
const worker = this.__buildWorker;
|
|
564
|
+
|
|
565
|
+
const version = s.version;
|
|
566
|
+
|
|
567
|
+
const pending = worker.setHeightSampler(s.data, s.itemSize, s.width, s.height);
|
|
568
|
+
|
|
569
|
+
// Claim the snapshot for every tile build submitted from here on -- the worker serves
|
|
570
|
+
// requests in order, so they all see these heights -- and retire the tiles that describe
|
|
571
|
+
// an earlier one. Deliberately not awaited: waiting would leave a window in which builds
|
|
572
|
+
// are already reading the new heights while tiles still claim to hold the old.
|
|
573
|
+
this.__tiles.setHeightVersion(version);
|
|
574
|
+
|
|
575
|
+
await pending;
|
|
576
|
+
|
|
577
|
+
return await worker.computeHeightRange()
|
|
578
|
+
.then(({ min, max }) => {
|
|
579
|
+
this.__tiles.setHeightRange(min, max);
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
stopBuildService() {
|
|
584
|
+
this.__buildWorker.stop();
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
buildGridTransform() {
|
|
588
|
+
if (this.gridTransformKind === GridTransformKind.Legacy) {
|
|
589
|
+
this.gridTransform.scale_x = (this.size.x / (this.size.x - 1)) * this.gridScale;
|
|
590
|
+
this.gridTransform.scale_y = (this.size.y / (this.size.y - 1)) * this.gridScale;
|
|
591
|
+
|
|
592
|
+
this.gridTransform.offset_x = 0;
|
|
593
|
+
this.gridTransform.offset_y = 0;
|
|
594
|
+
|
|
595
|
+
} else if (this.gridTransformKind === GridTransformKind.Direct) {
|
|
596
|
+
this.gridTransform.scale_x = this.gridScale;
|
|
597
|
+
this.gridTransform.scale_y = this.gridScale;
|
|
598
|
+
|
|
599
|
+
this.gridTransform.offset_x = this.gridScale / 2;
|
|
600
|
+
this.gridTransform.offset_y = this.gridScale / 2;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
buildNonVisual() {
|
|
605
|
+
|
|
606
|
+
this.buildGridTransform();
|
|
607
|
+
|
|
608
|
+
this.bvh.resize(0, 0, 0, 0, 0, 0);
|
|
609
|
+
|
|
610
|
+
//
|
|
611
|
+
this.overlay.size.copy(this.size);
|
|
612
|
+
|
|
613
|
+
this.__tiles.totalSize.copy(this.size);
|
|
614
|
+
this.__tiles.scale.set(this.gridScale, this.gridScale);
|
|
615
|
+
this.__tiles.resolution.set(this.resolution);
|
|
616
|
+
|
|
617
|
+
this.updateWorkerHeights();
|
|
618
|
+
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
*
|
|
623
|
+
* @param {AssetManager} assetManager
|
|
624
|
+
*/
|
|
625
|
+
build(assetManager) {
|
|
626
|
+
if (this.getFlag(TerrainFlags.Built)) {
|
|
627
|
+
// already built
|
|
628
|
+
console.warn('already built, if you want rebuild to occur, clear this flag first');
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
assert.defined(assetManager, 'assetManager');
|
|
633
|
+
assert.notNull(assetManager, 'assetManager');
|
|
634
|
+
assert.equal(assetManager.isAssetManager, true, '.isAssetManager !== true');
|
|
635
|
+
|
|
636
|
+
this.__assetManager = assetManager;
|
|
637
|
+
|
|
638
|
+
this.buildNonVisual();
|
|
639
|
+
|
|
640
|
+
this.layers.buildTexture();
|
|
641
|
+
|
|
642
|
+
this.layers.loadTextureData(assetManager);
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
*
|
|
646
|
+
* @type {Promise<TerrainTileManager>}
|
|
647
|
+
* @deprecated
|
|
648
|
+
*/
|
|
649
|
+
this.pTiles = Promise.resolve(this.__tiles);
|
|
650
|
+
|
|
651
|
+
this.__tiles.initialize();
|
|
652
|
+
|
|
653
|
+
this.setFlag(TerrainFlags.Built);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Note: For advanced users only. You can seriously mess up how things look and function with respect to terrain here
|
|
658
|
+
* @return {TerrainTileManager}
|
|
659
|
+
*/
|
|
660
|
+
get tiles() {
|
|
661
|
+
return this.__tiles;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Bake this terrain's ambient-occlusion lightmap onto its material.
|
|
666
|
+
*
|
|
667
|
+
* **Retired (D38, 2026-08-20). Calling this throws.** See {@link buildLightTexture} for what it
|
|
668
|
+
* did and what it cost: a second WebGL context per generated level, tracing a Monte-Carlo AO map
|
|
669
|
+
* into a texture that only the three-based terrain material ever sampled. Terrain shading under
|
|
670
|
+
* Shade is U3b's virtual-texture path, and its ambient occlusion is the renderer's own GTAO.
|
|
671
|
+
*
|
|
672
|
+
* @deprecated retired by D38 — terrain AO is not baked, and this throws if called
|
|
673
|
+
* @throws {Error} always
|
|
674
|
+
*/
|
|
675
|
+
buildLightMap() {
|
|
676
|
+
buildLightTexture();
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
*
|
|
681
|
+
* @param opt
|
|
682
|
+
* @param {Engine} engine
|
|
683
|
+
*/
|
|
684
|
+
fromJSON({
|
|
685
|
+
resolution = 4,
|
|
686
|
+
preview,
|
|
687
|
+
size = 1,
|
|
688
|
+
scale = 1,
|
|
689
|
+
material,
|
|
690
|
+
heights,
|
|
691
|
+
layers,
|
|
692
|
+
splat,
|
|
693
|
+
overlayTileImage
|
|
694
|
+
} = {}, engine) {
|
|
695
|
+
// mark as needing rebuilding
|
|
696
|
+
this.clearFlag(TerrainFlags.Built);
|
|
697
|
+
|
|
698
|
+
if (preview !== undefined) {
|
|
699
|
+
this.preview.fromJSON(preview);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
this.resolution = resolution;
|
|
703
|
+
|
|
704
|
+
this.size.fromJSON(size);
|
|
705
|
+
|
|
706
|
+
this.gridScale = scale;
|
|
707
|
+
//
|
|
708
|
+
|
|
709
|
+
this.materialDesc = material;
|
|
710
|
+
|
|
711
|
+
if (heights !== undefined) {
|
|
712
|
+
this.samplerHeight.fromJSON(heights);
|
|
713
|
+
} else {
|
|
714
|
+
this.samplerHeight.data = new Float32Array(1);
|
|
715
|
+
this.samplerHeight.width = 1;
|
|
716
|
+
this.samplerHeight.height = 1;
|
|
717
|
+
this.samplerHeight.itemSize = 1;
|
|
718
|
+
this.samplerHeight.version++;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
this.layers.fromJSON(layers);
|
|
722
|
+
this.splat.fromJSON(splat);
|
|
723
|
+
|
|
724
|
+
if (overlayTileImage !== undefined) {
|
|
725
|
+
this.overlay.baseTileImage = overlayTileImage;
|
|
726
|
+
} else {
|
|
727
|
+
this.overlay.baseTileImage = WHITE_PIXEL_DATA_URL;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
// debugSamplers(this);
|
|
732
|
+
this.build(engine.assetManager);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
toJSON() {
|
|
736
|
+
|
|
737
|
+
const result = {
|
|
738
|
+
size: this.size.toJSON(),
|
|
739
|
+
scale: this.gridScale,
|
|
740
|
+
resolution: this.resolution,
|
|
741
|
+
material: this.materialDesc,
|
|
742
|
+
preview: this.preview.toJSON(),
|
|
743
|
+
heights: this.samplerHeight.toJSON(),
|
|
744
|
+
layers: this.layers.toJSON(),
|
|
745
|
+
splat: this.splat.toJSON(),
|
|
746
|
+
overlayTileImage: this.overlay.baseTileImage
|
|
747
|
+
};
|
|
748
|
+
|
|
749
|
+
return result;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
Terrain.typeName = "Terrain";
|
|
754
|
+
|
|
755
|
+
/**
|
|
756
|
+
*
|
|
757
|
+
* @param {Vector3[]} points
|
|
758
|
+
* @param {number[]} missIndices
|
|
759
|
+
*/
|
|
760
|
+
function mendMissedPoints(points, missIndices) {
|
|
761
|
+
const numPoints = points.length;
|
|
762
|
+
const lastPointIndex = numPoints - 1;
|
|
763
|
+
|
|
764
|
+
const numMisses = missIndices.length;
|
|
765
|
+
|
|
766
|
+
for (let i = 0; i < numMisses; i++) {
|
|
767
|
+
const index = missIndices[i];
|
|
768
|
+
|
|
769
|
+
let heightSum = 0;
|
|
770
|
+
let sampleCount = 0;
|
|
771
|
+
|
|
772
|
+
if (index > 0) {
|
|
773
|
+
heightSum += points[index - 1].y;
|
|
774
|
+
sampleCount++;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
if (index < lastPointIndex) {
|
|
778
|
+
heightSum += points[index + 1].y;
|
|
779
|
+
sampleCount++;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
if (sampleCount > 0) {
|
|
783
|
+
points[index].y = heightSum / sampleCount;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
export default Terrain;
|
|
790
|
+
|