@navaramap/three 0.0.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/LICENSE +8 -0
- package/dist/assets/atmosphere/README.md +1 -0
- package/dist/assets/atmosphere/higher_order_scattering.bin +0 -0
- package/dist/assets/atmosphere/higher_order_scattering.exr +0 -0
- package/dist/assets/atmosphere/irradiance.bin +0 -0
- package/dist/assets/atmosphere/irradiance.exr +0 -0
- package/dist/assets/atmosphere/scattering.bin +0 -0
- package/dist/assets/atmosphere/scattering.exr +0 -0
- package/dist/assets/atmosphere/single_mie_scattering.bin +0 -0
- package/dist/assets/atmosphere/single_mie_scattering.exr +0 -0
- package/dist/assets/atmosphere/stars.bin +0 -0
- package/dist/assets/atmosphere/transmittance.bin +0 -0
- package/dist/assets/atmosphere/transmittance.exr +0 -0
- package/dist/assets/cloud/README.md +1 -0
- package/dist/assets/cloud/local_weather.png +0 -0
- package/dist/assets/cloud/shape.bin +1 -0
- package/dist/assets/cloud/shape_detail.bin +1 -0
- package/dist/assets/cloud/turbulence.png +0 -0
- package/dist/assets/fontWorker-CEJEfRpb.js +2 -0
- package/dist/assets/fontWorker-CEJEfRpb.js.map +1 -0
- package/dist/assets/index-BUB-ijMO.js +12 -0
- package/dist/assets/index-BUB-ijMO.js.map +1 -0
- package/dist/assets/navara_wasm_font_worker_bg-665OLxjy.wasm +0 -0
- package/dist/assets/navara_wasm_worker_bg-BXhKC5bE.wasm +0 -0
- package/dist/assets/noise/README.md +1 -0
- package/dist/assets/noise/stbn.bin +0 -0
- package/dist/assets/water/README.md +3 -0
- package/dist/assets/water/waternormals.jpg +0 -0
- package/dist/index.d.ts +10114 -0
- package/dist/index.js +34481 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.cjs +6345 -0
- package/dist/index.umd.cjs.map +1 -0
- package/package.json +95 -0
- package/src/Color.ts +111 -0
- package/src/ShadowMapViewers.ts +49 -0
- package/src/atmosphere.test.ts +76 -0
- package/src/atmosphere.ts +364 -0
- package/src/bufferView.ts +90 -0
- package/src/camera.ts +182 -0
- package/src/concurrency.ts +15 -0
- package/src/constants/assets.ts +30 -0
- package/src/constants/decoder.ts +7 -0
- package/src/constants/index.ts +2 -0
- package/src/core/BaseDesc.ts +142 -0
- package/src/core/BaseHandle.ts +126 -0
- package/src/core/DescRegistry.ts +88 -0
- package/src/core/EffectDesc.ts +343 -0
- package/src/core/EffectDescRegistry.ts +31 -0
- package/src/core/InstancedMeshDesc.ts +413 -0
- package/src/core/LightDesc.ts +216 -0
- package/src/core/LightDescRegistry.ts +32 -0
- package/src/core/MeshDesc.ts +457 -0
- package/src/core/MeshDescRegistry.ts +32 -0
- package/src/core/MeshDescWithSelectiveEffect.ts +129 -0
- package/src/core/Registries.ts +59 -0
- package/src/core/SelectiveEffectRegistry.ts +90 -0
- package/src/core/ViewContext.ts +235 -0
- package/src/core/errors.ts +16 -0
- package/src/core/index.ts +50 -0
- package/src/device.ts +414 -0
- package/src/effects/CustomEffectPass.ts +28 -0
- package/src/effects/copy.ts +10 -0
- package/src/effects/effect.ts +87 -0
- package/src/effects/index.ts +4 -0
- package/src/effects/render.ts +10 -0
- package/src/evaluations/FeatureEvaluator.ts +529 -0
- package/src/evaluations/index.ts +1 -0
- package/src/event/HillshadeContext.test.ts +232 -0
- package/src/event/HillshadeContext.ts +299 -0
- package/src/event/context.ts +279 -0
- package/src/event/feature.ts +357 -0
- package/src/event/featureEvent.ts +81 -0
- package/src/event/features/billboard.ts +30 -0
- package/src/event/features/model.ts +192 -0
- package/src/event/features/modelGpuBytes.test.ts +69 -0
- package/src/event/features/modelGpuBytes.ts +87 -0
- package/src/event/features/point.ts +25 -0
- package/src/event/features/polygon.ts +23 -0
- package/src/event/features/polygonOutline.ts +19 -0
- package/src/event/features/polyline.ts +19 -0
- package/src/event/features/text.ts +71 -0
- package/src/event/hillshade.test.ts +842 -0
- package/src/event/hillshade.ts +588 -0
- package/src/event/index.ts +700 -0
- package/src/event/loaders.ts +53 -0
- package/src/event/tile.ts +19 -0
- package/src/event/worker.ts +999 -0
- package/src/event/workerTaskSettlement.test.ts +243 -0
- package/src/event/workerTaskSettlement.ts +128 -0
- package/src/inMemoryBufferStore.test.ts +60 -0
- package/src/inMemoryBufferStore.ts +67 -0
- package/src/index.iife.ts +11 -0
- package/src/index.ts +2556 -0
- package/src/input.ts +144 -0
- package/src/layer.ts +183 -0
- package/src/layers/effect/FinalCopyEffectDesc.ts +29 -0
- package/src/layers/effect/MRTPassEffectDesc.ts +105 -0
- package/src/layers/effect/README.md +9 -0
- package/src/layers/effect/SelectiveEffectDesc.ts +113 -0
- package/src/layers/effect/SkyEnvMapEffectDesc.ts +58 -0
- package/src/layers/effect/TransparentPassEffectDesc.ts +62 -0
- package/src/layers/effect/index.ts +5 -0
- package/src/layers/index.ts +1 -0
- package/src/layersManager.ts +63 -0
- package/src/light.ts +15 -0
- package/src/loaders/AbortableImageLoader.ts +203 -0
- package/src/loaders/AbortableTextureLoader.ts +74 -0
- package/src/loaders/index.ts +5 -0
- package/src/material/enhancer/DESIGN.md +300 -0
- package/src/material/enhancer/MaterialEnhancer.ts +112 -0
- package/src/material/enhancer/ShaderReplacer.test.ts +114 -0
- package/src/material/enhancer/ShaderReplacer.ts +97 -0
- package/src/material/enhancer/batchTexture.ts +8 -0
- package/src/material/enhancer/index.ts +46 -0
- package/src/material/enhancer/instancedSprite/index.ts +7 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/index.test.ts +214 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/index.ts +134 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/markers.ts +21 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/material.ts +32 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/mutates.test.ts +277 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/mutates.ts +151 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/shader.test.ts +114 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/shader.ts +49 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/state.test.ts +82 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/state.ts +80 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/types.ts +146 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteMaterialEnhancer.ts +105 -0
- package/src/material/enhancer/model/index.ts +25 -0
- package/src/material/enhancer/model/modelBaseEnhancer/index.test.ts +74 -0
- package/src/material/enhancer/model/modelBaseEnhancer/index.ts +110 -0
- package/src/material/enhancer/model/modelBaseEnhancer/markers.ts +27 -0
- package/src/material/enhancer/model/modelBaseEnhancer/material.test.ts +66 -0
- package/src/material/enhancer/model/modelBaseEnhancer/material.ts +44 -0
- package/src/material/enhancer/model/modelBaseEnhancer/mutates.test.ts +84 -0
- package/src/material/enhancer/model/modelBaseEnhancer/mutates.ts +47 -0
- package/src/material/enhancer/model/modelBaseEnhancer/shader.test.ts +24 -0
- package/src/material/enhancer/model/modelBaseEnhancer/shader.ts +162 -0
- package/src/material/enhancer/model/modelBaseEnhancer/state.test.ts +103 -0
- package/src/material/enhancer/model/modelBaseEnhancer/state.ts +52 -0
- package/src/material/enhancer/model/modelBaseEnhancer/types.ts +89 -0
- package/src/material/enhancer/model/modelMaterialEnhancer.ts +91 -0
- package/src/material/enhancer/model/modelWaterEnhancer/index.test.ts +71 -0
- package/src/material/enhancer/model/modelWaterEnhancer/index.ts +175 -0
- package/src/material/enhancer/model/modelWaterEnhancer/material.test.ts +48 -0
- package/src/material/enhancer/model/modelWaterEnhancer/material.ts +25 -0
- package/src/material/enhancer/model/modelWaterEnhancer/mutates.test.ts +89 -0
- package/src/material/enhancer/model/modelWaterEnhancer/mutates.ts +89 -0
- package/src/material/enhancer/model/modelWaterEnhancer/shader.test.ts +34 -0
- package/src/material/enhancer/model/modelWaterEnhancer/shader.ts +111 -0
- package/src/material/enhancer/model/modelWaterEnhancer/state.test.ts +105 -0
- package/src/material/enhancer/model/modelWaterEnhancer/state.ts +59 -0
- package/src/material/enhancer/model/modelWaterEnhancer/types.ts +141 -0
- package/src/material/enhancer/model/pntsEnhancer/index.test.ts +96 -0
- package/src/material/enhancer/model/pntsEnhancer/index.ts +82 -0
- package/src/material/enhancer/model/pntsEnhancer/markers.ts +6 -0
- package/src/material/enhancer/model/pntsEnhancer/material.test.ts +37 -0
- package/src/material/enhancer/model/pntsEnhancer/material.ts +21 -0
- package/src/material/enhancer/model/pntsEnhancer/mutates.test.ts +80 -0
- package/src/material/enhancer/model/pntsEnhancer/mutates.ts +29 -0
- package/src/material/enhancer/model/pntsEnhancer/shader.test.ts +32 -0
- package/src/material/enhancer/model/pntsEnhancer/shader.ts +56 -0
- package/src/material/enhancer/model/pntsEnhancer/state.test.ts +87 -0
- package/src/material/enhancer/model/pntsEnhancer/state.ts +29 -0
- package/src/material/enhancer/model/pntsEnhancer/types.ts +38 -0
- package/src/material/enhancer/polygon/index.ts +22 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/index.test.ts +101 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/index.ts +130 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/markers.ts +23 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/material.test.ts +19 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/material.ts +38 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/mutates.test.ts +75 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/mutates.ts +122 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/shader.test.ts +25 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/shader.ts +249 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/state.test.ts +102 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/state.ts +92 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/types.ts +150 -0
- package/src/material/enhancer/polygon/polygonMaterialEnhancer.ts +97 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/index.test.ts +72 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/index.ts +164 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/material.test.ts +48 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/material.ts +35 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/mutates.ts +61 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/shader.test.ts +34 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/shader.ts +96 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/state.test.ts +98 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/state.ts +57 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/types.ts +115 -0
- package/src/material/enhancer/polyline/index.ts +7 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/index.test.ts +157 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/index.ts +154 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/markers.ts +19 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/material.test.ts +42 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/material.ts +38 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/mutates.test.ts +120 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/mutates.ts +169 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/shader.test.ts +67 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/shader.ts +75 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/state.test.ts +55 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/state.ts +91 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/types.ts +170 -0
- package/src/material/enhancer/polyline/polylineMaterialEnhancer.ts +102 -0
- package/src/material/enhancer/sdfText/index.ts +7 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/index.ts +125 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/markers.ts +19 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/material.test.ts +35 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/material.ts +32 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/mutates.test.ts +381 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/mutates.ts +232 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/shader.ts +36 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/state.test.ts +118 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/state.ts +107 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/types.ts +184 -0
- package/src/material/enhancer/sdfText/sdfTextMaterialEnhancer.ts +100 -0
- package/src/material/enhancer/shadowMap/index.ts +7 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/index.ts +97 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/markers.ts +10 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/material.ts +31 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/mutates.ts +8 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/shader.test.ts +17 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/shader.ts +53 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/state.ts +17 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/types.ts +26 -0
- package/src/material/enhancer/test-utils/shaderCompatibility.ts +124 -0
- package/src/material/enhancer/tileComposite/compose.test.ts +95 -0
- package/src/material/enhancer/tileComposite/compose.ts +112 -0
- package/src/material/enhancer/tileComposite/index.ts +23 -0
- package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/index.ts +11 -0
- package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/mutates.ts +132 -0
- package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/shader.ts +245 -0
- package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/types.ts +43 -0
- package/src/material/enhancer/tileComposite/tileElevationHeatmapEnhancer/index.ts +29 -0
- package/src/material/enhancer/tileComposite/tileElevationHeatmapEnhancer/mutates.ts +68 -0
- package/src/material/enhancer/tileComposite/tileElevationHeatmapEnhancer/shader.ts +24 -0
- package/src/material/enhancer/tileComposite/tileHillshadeEnhancer/index.ts +29 -0
- package/src/material/enhancer/tileComposite/tileHillshadeEnhancer/mutates.ts +34 -0
- package/src/material/enhancer/tileComposite/tileHillshadeEnhancer/shader.ts +36 -0
- package/src/material/enhancer/tileComposite/tileWaterEnhancer/index.ts +23 -0
- package/src/material/enhancer/tileComposite/tileWaterEnhancer/mutates.ts +23 -0
- package/src/material/enhancer/tileComposite/tileWaterEnhancer/shader.ts +8 -0
- package/src/material/enhancer/tileComposite/tileWatermaskEnhancer/index.ts +23 -0
- package/src/material/enhancer/tileComposite/tileWatermaskEnhancer/mutates.ts +34 -0
- package/src/material/enhancer/tileComposite/tileWatermaskEnhancer/shader.ts +13 -0
- package/src/material/enhancer/tileComposite/types.ts +58 -0
- package/src/material/index.ts +3 -0
- package/src/material/macro/index.ts +1 -0
- package/src/material/macro/tileShader.test.ts +136 -0
- package/src/material/macro/tileShader.ts +287 -0
- package/src/material/overrideMaterialsForMRT.ts +439 -0
- package/src/material/selectiveEffectMaterialSetup.test.ts +52 -0
- package/src/material/selectiveEffectMaterialSetup.ts +53 -0
- package/src/material/types/index.ts +1 -0
- package/src/material/types/uniform.ts +1 -0
- package/src/mesh/DrapedMesh.ts +101 -0
- package/src/mesh/batchTexture.test.ts +646 -0
- package/src/mesh/batchTexture.ts +437 -0
- package/src/mesh/batchedFeature.ts +186 -0
- package/src/mesh/batchedSdfText.ts +484 -0
- package/src/mesh/featureMesh.ts +43 -0
- package/src/mesh/index.ts +16 -0
- package/src/mesh/instanced.ts +117 -0
- package/src/mesh/model.ts +483 -0
- package/src/mesh/pickableMesh.ts +55 -0
- package/src/mesh/pickableMeshWrapper.ts +529 -0
- package/src/mesh/polygon.ts +699 -0
- package/src/mesh/polygonOutline.ts +393 -0
- package/src/mesh/polyline.ts +523 -0
- package/src/mesh/releaseGeometryArrays.ts +57 -0
- package/src/mesh/rtcRteHelper.ts +211 -0
- package/src/mesh/sdfText.test.ts +200 -0
- package/src/mesh/sdfText.ts +1019 -0
- package/src/mesh/sprite/billboardAtlas.test.ts +177 -0
- package/src/mesh/sprite/billboardAtlas.ts +210 -0
- package/src/mesh/sprite/billboardAtlasImageLoader.ts +29 -0
- package/src/mesh/sprite/index.ts +1 -0
- package/src/mesh/sprite/instancedSprite.ts +694 -0
- package/src/mesh/tile.test.ts +393 -0
- package/src/mesh/tile.ts +1790 -0
- package/src/object3DEvent.ts +6 -0
- package/src/orchestrators/RenderPassOrchestrator.ts +147 -0
- package/src/orchestrators/index.ts +1 -0
- package/src/passes/AllDepthCopyPass.ts +165 -0
- package/src/passes/CustomRenderPass.ts +279 -0
- package/src/passes/NormalCopyPass.ts +125 -0
- package/src/passes/RenderTargetCopyPass.ts +91 -0
- package/src/passes/SkyEnvMapPass.ts +58 -0
- package/src/passes/index.ts +5 -0
- package/src/pick/pickHelper.ts +273 -0
- package/src/pick/pickTerrain.ts +254 -0
- package/src/plugins/AttributionPlugin/AttributionPlugin.test.ts +210 -0
- package/src/plugins/AttributionPlugin/attribution.test.ts +225 -0
- package/src/plugins/AttributionPlugin/attribution.ts +355 -0
- package/src/plugins/AttributionPlugin/attributionStyles.ts +163 -0
- package/src/plugins/AttributionPlugin/index.ts +702 -0
- package/src/plugins/index.ts +1 -0
- package/src/quality.ts +1 -0
- package/src/renderOrder.ts +3 -0
- package/src/scene.test.ts +164 -0
- package/src/scene.ts +127 -0
- package/src/shaders/index.ts +1 -0
- package/src/solar.test.ts +81 -0
- package/src/solar.ts +101 -0
- package/src/source.ts +80 -0
- package/src/stats.ts +102 -0
- package/src/tasks/computeVertexNormalsAsync.ts +15 -0
- package/src/tasks/constructPolygonBatchedFeature.ts +34 -0
- package/src/tasks/constructPolylineBatchedFeature.ts +27 -0
- package/src/tasks/constructQuantizedMeshTerrainMesh.ts +24 -0
- package/src/tasks/constructTerrainMesh.ts +25 -0
- package/src/tasks/getImageDataFromBlob.ts +13 -0
- package/src/tasks/getImageDataFromImageBitmap.ts +12 -0
- package/src/tasks/parseMvtTile.ts +22 -0
- package/src/tasks/queueTask.ts +19 -0
- package/src/tasks/toCreasedNormalsAsync.ts +18 -0
- package/src/tasks/upsampleQuantizedMeshTerrainMesh.ts +44 -0
- package/src/tasks/upsampleTerrainMesh.ts +39 -0
- package/src/texture.ts +19 -0
- package/src/textures.ts +13 -0
- package/src/tileTexture/CompositeShader.snapshot.test.ts +59 -0
- package/src/tileTexture/CompositeShader.test.ts +168 -0
- package/src/tileTexture/CompositeShader.ts +53 -0
- package/src/tileTexture/SlotPlanner.test.ts +105 -0
- package/src/tileTexture/SlotPlanner.ts +102 -0
- package/src/tileTexture/TileTextureCache.test.ts +227 -0
- package/src/tileTexture/TileTextureCache.ts +192 -0
- package/src/tileTexture/TileTextureCompositor.test.ts +260 -0
- package/src/tileTexture/TileTextureCompositor.ts +421 -0
- package/src/tileTexture/__snapshots__/CompositeShader.snapshot.test.ts.snap +2649 -0
- package/src/tileTexture/index.ts +8 -0
- package/src/tileTexture/types.ts +150 -0
- package/src/type/index.ts +261 -0
- package/src/uniforms.ts +20 -0
- package/src/utils/arraysEqual.ts +9 -0
- package/src/utils/blendModes.ts +80 -0
- package/src/utils/geometry.ts +53 -0
- package/src/utils/hillshadeNormalMapGenerator.ts +193 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/object.test.ts +14 -0
- package/src/utils/object.ts +7 -0
- package/src/utils/replacer.test.ts +42 -0
- package/src/utils/replacer.ts +89 -0
- package/src/utils/screen.ts +29 -0
- package/src/utils/textureFragmentIndex.test.ts +224 -0
- package/src/utils/textureFragmentIndex.ts +97 -0
- package/src/utils/worker.ts +3 -0
- package/src/vite-env.d.ts +2 -0
- package/src/worker/index.ts +13 -0
- package/src/worker/tasks/computeVertexNormals.ts +15 -0
- package/src/worker/tasks/toCreasedNormals.ts +22 -0
|
@@ -0,0 +1,700 @@
|
|
|
1
|
+
import {
|
|
2
|
+
generate_id_from_entity,
|
|
3
|
+
IMAGE_EXTENSIONS,
|
|
4
|
+
isEntityEvent,
|
|
5
|
+
} from "@navaramap/core";
|
|
6
|
+
import {
|
|
7
|
+
type Transform,
|
|
8
|
+
type EntityEvent,
|
|
9
|
+
type ObjectTransformEvent,
|
|
10
|
+
type DataRequestEvent,
|
|
11
|
+
type CameraFrustum,
|
|
12
|
+
TextureFragmentRequestedEvent,
|
|
13
|
+
TextureFragmentStatus,
|
|
14
|
+
DataRequesterRemovedEvent,
|
|
15
|
+
RenderableFeatureRemovedEvent,
|
|
16
|
+
Events,
|
|
17
|
+
} from "@navaramap/engine";
|
|
18
|
+
import { radianToDegree } from "@navaramap/three_api";
|
|
19
|
+
import { canWorkerProcessImmediately } from "@navaramap/worker";
|
|
20
|
+
import { Mesh, Object3D, Sprite } from "three";
|
|
21
|
+
|
|
22
|
+
import { BatchedSdfTextMesh, Layer } from "..";
|
|
23
|
+
import { disposeTexture } from "../loaders";
|
|
24
|
+
import { getImageDataFromBlob } from "../tasks/getImageDataFromBlob";
|
|
25
|
+
|
|
26
|
+
import { EventContext } from "./context";
|
|
27
|
+
import {
|
|
28
|
+
checkFeatureParallel,
|
|
29
|
+
processRenderableFeatureAdded,
|
|
30
|
+
processRenderableFeatureChanged,
|
|
31
|
+
} from "./feature";
|
|
32
|
+
import {
|
|
33
|
+
processHillshadeBackfilled,
|
|
34
|
+
processHillshadeCanceled,
|
|
35
|
+
} from "./hillshade";
|
|
36
|
+
import { ABORTABLE_TEXTURE_LOADER } from "./loaders";
|
|
37
|
+
import { processMeshAdded, processMeshChanged } from "./tile";
|
|
38
|
+
import {
|
|
39
|
+
processWorkerTaskDelegatedEvent,
|
|
40
|
+
processWorkerTaskRemovedEvent,
|
|
41
|
+
} from "./worker";
|
|
42
|
+
|
|
43
|
+
export type {
|
|
44
|
+
BufferLoader,
|
|
45
|
+
TextureFragmentHandler,
|
|
46
|
+
WorkerTaskHandler,
|
|
47
|
+
TileHandler,
|
|
48
|
+
GlobeHandler,
|
|
49
|
+
FeatureHandler,
|
|
50
|
+
MeshHandler,
|
|
51
|
+
LayerHandler,
|
|
52
|
+
} from "./context";
|
|
53
|
+
export { EventContext } from "./context";
|
|
54
|
+
export { HillshadeContext } from "./HillshadeContext";
|
|
55
|
+
|
|
56
|
+
export function processEvent(ctx: EventContext, event: Events | undefined) {
|
|
57
|
+
const {
|
|
58
|
+
eventManager,
|
|
59
|
+
meshes,
|
|
60
|
+
meshHandler,
|
|
61
|
+
viewEvents,
|
|
62
|
+
layersManager,
|
|
63
|
+
viewContext,
|
|
64
|
+
} = ctx;
|
|
65
|
+
|
|
66
|
+
eventManager.pushEvents(event);
|
|
67
|
+
|
|
68
|
+
eventManager.forEachStack("camera_transform_updated", (ev) =>
|
|
69
|
+
processCameraTransformUpdated(ctx, ev),
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
eventManager.forEachStack("camera_frustum_updated", (ev) =>
|
|
73
|
+
processCameraFrustumUpdated(ctx, ev),
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
eventManager.forEachStack("object_transform_updated", (ev) =>
|
|
77
|
+
processObjectTransformUpdated(ctx, ev),
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
eventManager.forEachStack("update_sample_terrain_height", (ev) =>
|
|
81
|
+
viewEvents.emit("_sample_terrain_height_received", ev),
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// Process cancels before backfills, synchronously. Each cancel drops its
|
|
85
|
+
// own matching pending backfills from the stack (see processHillshadeCanceled),
|
|
86
|
+
// so the subsequent forEachStack only iterates surviving events.
|
|
87
|
+
//
|
|
88
|
+
// Using forEachStack here matches main's per-frame timing — switching this
|
|
89
|
+
// to processTransactionEvents earlier caused hillshade adds to be spread
|
|
90
|
+
// across frames via the TransactionManager chain, which produced visible
|
|
91
|
+
// texture offset during fast pan/zoom.
|
|
92
|
+
eventManager.forEachStack(
|
|
93
|
+
"hillshade_canceled",
|
|
94
|
+
(ev) => processHillshadeCanceled(ctx, ev),
|
|
95
|
+
Infinity,
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
eventManager.forEachStack("hillshade_backfilled", (ev) =>
|
|
99
|
+
processHillshadeBackfilled(ctx, ev),
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
eventManager.processTransactionEvents(
|
|
103
|
+
"meshEvent",
|
|
104
|
+
{
|
|
105
|
+
add: {
|
|
106
|
+
key: "mesh_added",
|
|
107
|
+
},
|
|
108
|
+
remove: {
|
|
109
|
+
key: "mesh_removed",
|
|
110
|
+
// This process is not heavy for now, so we can process it infinitely.
|
|
111
|
+
max: Infinity,
|
|
112
|
+
},
|
|
113
|
+
change: {
|
|
114
|
+
key: "mesh_updated",
|
|
115
|
+
// This process is not heavy for now, so we can process it infinitely.
|
|
116
|
+
max: Infinity,
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
async ({ type, event }) => {
|
|
120
|
+
switch (type) {
|
|
121
|
+
case "add":
|
|
122
|
+
await processMeshAdded(ctx, event);
|
|
123
|
+
meshHandler.setTileMeshPrepared(event.tile_handle);
|
|
124
|
+
break;
|
|
125
|
+
case "remove":
|
|
126
|
+
processObjectRemoved(ctx, event);
|
|
127
|
+
break;
|
|
128
|
+
case "change":
|
|
129
|
+
processMeshChanged(ctx, event);
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
shouldProcess: ({ type }) => {
|
|
135
|
+
switch (type) {
|
|
136
|
+
case "add":
|
|
137
|
+
return canWorkerProcessImmediately();
|
|
138
|
+
case "remove":
|
|
139
|
+
return true;
|
|
140
|
+
case "change":
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
eventManager.processTransactionEvents(
|
|
148
|
+
"workerTaskEvent",
|
|
149
|
+
{
|
|
150
|
+
add: {
|
|
151
|
+
key: "worker_task_delegated",
|
|
152
|
+
},
|
|
153
|
+
remove: {
|
|
154
|
+
key: "worker_task_removed",
|
|
155
|
+
max: Infinity,
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
async ({ type, event }) => {
|
|
159
|
+
switch (type) {
|
|
160
|
+
case "add":
|
|
161
|
+
await processWorkerTaskDelegatedEvent(ctx, event);
|
|
162
|
+
break;
|
|
163
|
+
case "remove":
|
|
164
|
+
processWorkerTaskRemovedEvent(ctx, event);
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
shouldProcess: ({ type }) => {
|
|
170
|
+
switch (type) {
|
|
171
|
+
case "add":
|
|
172
|
+
return canWorkerProcessImmediately();
|
|
173
|
+
case "remove":
|
|
174
|
+
return true;
|
|
175
|
+
case "change":
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
onAbort: (event) => {
|
|
180
|
+
processWorkerTaskRemovedEvent(ctx, event);
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
eventManager.processTransactionEvents(
|
|
186
|
+
"renderableFeatureEvent",
|
|
187
|
+
{
|
|
188
|
+
add: {
|
|
189
|
+
key: "renderable_feature_added",
|
|
190
|
+
},
|
|
191
|
+
remove: {
|
|
192
|
+
key: "renderable_feature_removed",
|
|
193
|
+
// This process is not heavy for now, so we can process it infinitely.
|
|
194
|
+
max: Infinity,
|
|
195
|
+
},
|
|
196
|
+
change: {
|
|
197
|
+
key: "renderable_feature_changed",
|
|
198
|
+
// This process is not heavy for now, so we can process it infinitely.
|
|
199
|
+
max: Infinity,
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
async ({ type, event }) => {
|
|
203
|
+
switch (type) {
|
|
204
|
+
case "add":
|
|
205
|
+
await processRenderableFeatureAdded(ctx, event);
|
|
206
|
+
break;
|
|
207
|
+
case "remove":
|
|
208
|
+
{
|
|
209
|
+
const removed = event as RenderableFeatureRemovedEvent;
|
|
210
|
+
const layer = layersManager.get(removed.layer_id);
|
|
211
|
+
if (layer && layer instanceof Layer) {
|
|
212
|
+
layer._unregisterFeatureEvaluator(removed.bits);
|
|
213
|
+
layer.emit("featureRemoved", { featureSetId: removed.bits });
|
|
214
|
+
}
|
|
215
|
+
processObjectRemoved(ctx, event);
|
|
216
|
+
}
|
|
217
|
+
break;
|
|
218
|
+
case "change":
|
|
219
|
+
await processRenderableFeatureChanged(ctx, event);
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
shouldProcess: ({ type, event }) => {
|
|
225
|
+
switch (type) {
|
|
226
|
+
case "add":
|
|
227
|
+
return (
|
|
228
|
+
!checkFeatureParallel(event.feature) ||
|
|
229
|
+
viewContext.concurrencyManager.canIncrement()
|
|
230
|
+
);
|
|
231
|
+
case "remove":
|
|
232
|
+
return true;
|
|
233
|
+
case "change":
|
|
234
|
+
if (isEntityEvent(event)) {
|
|
235
|
+
const id = generate_id_from_entity(event);
|
|
236
|
+
return meshes.has(id);
|
|
237
|
+
}
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
eventManager.processTransactionEvents(
|
|
245
|
+
"textureFragmentEvent",
|
|
246
|
+
{
|
|
247
|
+
add: {
|
|
248
|
+
key: "texture_fragment_requested",
|
|
249
|
+
},
|
|
250
|
+
remove: {
|
|
251
|
+
key: "texture_fragment_removed",
|
|
252
|
+
// This process is not heavy for now, so we can process it infinitely.
|
|
253
|
+
max: Infinity,
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
async ({ type, event }) => {
|
|
257
|
+
switch (type) {
|
|
258
|
+
case "add":
|
|
259
|
+
await processTextureFragmentRequested(ctx, event);
|
|
260
|
+
break;
|
|
261
|
+
case "remove":
|
|
262
|
+
processTextureFragmentRemoved(ctx, event);
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
onAbort: (event) => {
|
|
268
|
+
processTextureFragmentRemoved(ctx, event);
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
eventManager.processTransactionEvents(
|
|
274
|
+
"dataRequesterEvent",
|
|
275
|
+
{
|
|
276
|
+
add: {
|
|
277
|
+
key: "data_requested",
|
|
278
|
+
},
|
|
279
|
+
remove: {
|
|
280
|
+
key: "data_requester_removed",
|
|
281
|
+
// This process is not heavy for now, so we can process it infinitely.
|
|
282
|
+
max: Infinity,
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
async ({ type, event }) => {
|
|
286
|
+
switch (type) {
|
|
287
|
+
case "add":
|
|
288
|
+
await processRequestedData(ctx, event);
|
|
289
|
+
break;
|
|
290
|
+
case "remove":
|
|
291
|
+
processDataRequesterRemoved(ctx, event);
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
onAbort: (event) => {
|
|
297
|
+
processDataRequesterRemoved(ctx, event);
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function processCameraTransformUpdated(
|
|
304
|
+
ctx: EventContext,
|
|
305
|
+
transform: Transform | undefined,
|
|
306
|
+
) {
|
|
307
|
+
if (!transform) return;
|
|
308
|
+
setTransform(ctx.camera.raw, transform);
|
|
309
|
+
|
|
310
|
+
ctx.camera.updateStatus();
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function processCameraFrustumUpdated(
|
|
314
|
+
ctx: EventContext,
|
|
315
|
+
frustum: CameraFrustum | undefined,
|
|
316
|
+
) {
|
|
317
|
+
if (!frustum) return;
|
|
318
|
+
|
|
319
|
+
ctx.camera.raw.near = frustum.near;
|
|
320
|
+
ctx.camera.raw.far = frustum.far;
|
|
321
|
+
ctx.camera.raw.fov = radianToDegree(frustum.fov);
|
|
322
|
+
ctx.camera.raw.updateProjectionMatrix();
|
|
323
|
+
ctx.camera.emit("frustumChanged");
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function processObjectTransformUpdated(
|
|
327
|
+
ctx: EventContext,
|
|
328
|
+
e: ObjectTransformEvent,
|
|
329
|
+
) {
|
|
330
|
+
const id = generate_id_from_entity(e);
|
|
331
|
+
const m = ctx.meshes.get(id);
|
|
332
|
+
if (m) {
|
|
333
|
+
setTransform(m, e.transform);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
function processObjectRemoved(ctx: EventContext, obj: EntityEvent) {
|
|
338
|
+
const { meshes } = ctx;
|
|
339
|
+
const id = generate_id_from_entity(obj);
|
|
340
|
+
const m = meshes.get(id);
|
|
341
|
+
if (!m) return;
|
|
342
|
+
|
|
343
|
+
meshes.delete(id);
|
|
344
|
+
|
|
345
|
+
// Sprite, Mesh, and Group are all subclasses of Object3D
|
|
346
|
+
if (m instanceof Object3D) {
|
|
347
|
+
disposeObject3D(m);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (m instanceof BatchedSdfTextMesh) {
|
|
351
|
+
m.dispose();
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Custom event not in Object3DEventMap
|
|
355
|
+
// @ts-expect-error - removedFromWorld is a custom event
|
|
356
|
+
m.dispatchEvent({ type: "removedFromWorld" });
|
|
357
|
+
|
|
358
|
+
// clear should after dispose, otherwise model's children will not be disposed
|
|
359
|
+
m.clear();
|
|
360
|
+
|
|
361
|
+
// Detach from whatever scene it was added to (mrt for opaque features,
|
|
362
|
+
// transparent for always-on-top overlay sprites, globe for globe meshes).
|
|
363
|
+
m.removeFromParent();
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function disposeObject3D(model: Object3D): void {
|
|
367
|
+
model.traverse((object: Object3D) => {
|
|
368
|
+
if (object instanceof Mesh) {
|
|
369
|
+
const mesh = object as Mesh;
|
|
370
|
+
|
|
371
|
+
// Dispose geometry and aggressively drop all attributes
|
|
372
|
+
const g = mesh.geometry;
|
|
373
|
+
if (g) {
|
|
374
|
+
g.dispose?.();
|
|
375
|
+
|
|
376
|
+
// Remove every BufferAttribute (handles polyline/polygon custom attrs)
|
|
377
|
+
if (g.attributes) {
|
|
378
|
+
for (const key of Object.keys(g.attributes)) {
|
|
379
|
+
g.deleteAttribute(key);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
g.index = null;
|
|
384
|
+
g.boundingBox = null;
|
|
385
|
+
g.boundingSphere = null;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Dispose material(s)
|
|
389
|
+
if (mesh.material) {
|
|
390
|
+
if (Array.isArray(mesh.material)) {
|
|
391
|
+
mesh.material.forEach((material) => {
|
|
392
|
+
material.dispose();
|
|
393
|
+
});
|
|
394
|
+
} else {
|
|
395
|
+
const material = mesh.material;
|
|
396
|
+
material.dispose();
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
// point, billboard, text
|
|
401
|
+
else if (object instanceof Sprite) {
|
|
402
|
+
const sprite = object as Sprite;
|
|
403
|
+
|
|
404
|
+
// Dispose material
|
|
405
|
+
if (sprite.material) {
|
|
406
|
+
if (Array.isArray(sprite.material)) {
|
|
407
|
+
sprite.material.forEach((material) => {
|
|
408
|
+
material.dispose();
|
|
409
|
+
});
|
|
410
|
+
} else {
|
|
411
|
+
const material = sprite.material;
|
|
412
|
+
material.dispose();
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// TODO: Need to check if the cached texture is removed completely
|
|
420
|
+
async function processRequestedData(ctx: EventContext, req: DataRequestEvent) {
|
|
421
|
+
const { buf, abortControllers } = ctx;
|
|
422
|
+
const id = generate_id_from_entity(req);
|
|
423
|
+
|
|
424
|
+
const abortController = (() => {
|
|
425
|
+
const a = abortControllers.get(id);
|
|
426
|
+
if (a) {
|
|
427
|
+
return a;
|
|
428
|
+
} else {
|
|
429
|
+
const a = new AbortController();
|
|
430
|
+
abortControllers.set(id, a);
|
|
431
|
+
return a;
|
|
432
|
+
}
|
|
433
|
+
})();
|
|
434
|
+
|
|
435
|
+
if (IMAGE_EXTENSIONS.includes(req.extension)) {
|
|
436
|
+
// Fetch the compressed bytes here and hand the Blob to a worker that runs
|
|
437
|
+
// createImageBitmap + getImageData. Decoding the image (e.g. terrain-RGB
|
|
438
|
+
// DEM tiles) entirely on the worker keeps the costly "Image Decode" off the
|
|
439
|
+
// main thread — previously we decoded an HTMLImageElement and then
|
|
440
|
+
// re-decoded it via createImageBitmap on the main thread.
|
|
441
|
+
await fetch(req.url, { signal: abortController.signal })
|
|
442
|
+
.then((res) => {
|
|
443
|
+
if (!res.ok) throw new Error();
|
|
444
|
+
return res.blob();
|
|
445
|
+
})
|
|
446
|
+
.then(async (blob) => {
|
|
447
|
+
if (abortController.signal.aborted) {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
const promise = getImageDataFromBlob(blob);
|
|
452
|
+
|
|
453
|
+
ctx.workerPoolPromises.set(id, promise);
|
|
454
|
+
const data = await (async () => {
|
|
455
|
+
try {
|
|
456
|
+
return await promise;
|
|
457
|
+
} finally {
|
|
458
|
+
ctx.workerPoolPromises.delete(id);
|
|
459
|
+
}
|
|
460
|
+
})();
|
|
461
|
+
|
|
462
|
+
if (abortController.signal.aborted) {
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
let u8a: Uint8Array | null = new Uint8Array(data);
|
|
467
|
+
buf.setU8(req.handle, req.bits, u8a);
|
|
468
|
+
|
|
469
|
+
// Prevent memory leak
|
|
470
|
+
u8a.set([]);
|
|
471
|
+
u8a = null;
|
|
472
|
+
|
|
473
|
+
data.set([]);
|
|
474
|
+
})
|
|
475
|
+
.catch(() => {
|
|
476
|
+
buf.triggerDataRequesterFailed(req.bits);
|
|
477
|
+
})
|
|
478
|
+
.finally(() => {
|
|
479
|
+
abortControllers.delete(id);
|
|
480
|
+
});
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// Quantized-mesh extensions requested for this terrain tile (empty otherwise).
|
|
485
|
+
// The hyphen-joined token list is shared by the Accept header (server
|
|
486
|
+
// negotiation) and the URL query (cache key) below.
|
|
487
|
+
const terrainExts =
|
|
488
|
+
req.extension === "terrain"
|
|
489
|
+
? [
|
|
490
|
+
...(req.requestVertexNormals ? ["octvertexnormals"] : []),
|
|
491
|
+
...(req.requestWaterMask ? ["watermask"] : []),
|
|
492
|
+
]
|
|
493
|
+
: [];
|
|
494
|
+
|
|
495
|
+
// Cesium-style quantized-mesh servers gate the normals/watermask extensions
|
|
496
|
+
// behind an explicit Accept header. Only opt in when the layer requested it
|
|
497
|
+
// — otherwise some servers refuse to respond, and we don't want to pay for
|
|
498
|
+
// bytes we won't use anyway.
|
|
499
|
+
let headers = (() => {
|
|
500
|
+
if (req.extension !== "terrain") {
|
|
501
|
+
return req.token ? { Authorization: `Bearer ${req.token}` } : undefined;
|
|
502
|
+
}
|
|
503
|
+
const accept = terrainExts.length
|
|
504
|
+
? `application/vnd.quantized-mesh;extensions=${terrainExts.join("-")},application/octet-stream;q=0.9,*/*;q=0.01`
|
|
505
|
+
: "application/vnd.quantized-mesh,application/octet-stream;q=0.9,*/*;q=0.01";
|
|
506
|
+
const h: Record<string, string> = { Accept: accept };
|
|
507
|
+
if (req.token) h.Authorization = `Bearer ${req.token}`;
|
|
508
|
+
return h;
|
|
509
|
+
})();
|
|
510
|
+
|
|
511
|
+
// Partial fetch: PMTiles (and any future range-based source) sets a byte
|
|
512
|
+
// range on the request. `!= null` is intentional so a 0n offset (the header
|
|
513
|
+
// bootstrap read) is still treated as present. A length of 0n (from a
|
|
514
|
+
// malformed header/directory or an upstream bug) would underflow `end` to
|
|
515
|
+
// `offset - 1n` and emit an invalid `Range` header — and falling back to a
|
|
516
|
+
// full fetch could silently download an entire multi-GB archive — so fail
|
|
517
|
+
// the request instead.
|
|
518
|
+
if (req.offset != null && req.length != null) {
|
|
519
|
+
if (req.length <= 0n) {
|
|
520
|
+
buf.triggerDataRequesterFailed(req.bits);
|
|
521
|
+
abortControllers.delete(id);
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
const end = req.offset + req.length - 1n;
|
|
525
|
+
headers = { ...(headers ?? {}), Range: `bytes=${req.offset}-${end}` };
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// Set extensions as query params to stale the cache.
|
|
529
|
+
const fetchUrl = (() => {
|
|
530
|
+
if (!terrainExts.length) return req.url;
|
|
531
|
+
const u = new URL(req.url, globalThis.location?.href);
|
|
532
|
+
u.searchParams.set("extensions", terrainExts.join("-"));
|
|
533
|
+
return u.toString();
|
|
534
|
+
})();
|
|
535
|
+
|
|
536
|
+
await fetch(fetchUrl, { signal: abortController.signal, headers })
|
|
537
|
+
.then((res) => {
|
|
538
|
+
// For range reads, require 206 so we don't silently accept a full-body 200
|
|
539
|
+
// response and download an entire PMTiles archive.
|
|
540
|
+
const isRangeRequest = req.offset != null && req.length != null;
|
|
541
|
+
if (isRangeRequest && res.status !== 206) {
|
|
542
|
+
throw new Error(
|
|
543
|
+
`Range request expected 206 Partial Content, got ${res.status} ${res.statusText}`,
|
|
544
|
+
);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// A successful range request returns 206 Partial Content, which is in
|
|
548
|
+
// the ok range (200-299), so this guard handles both 200 and 206.
|
|
549
|
+
if (!res.ok) {
|
|
550
|
+
throw new Error(`Request failed with ${res.status} ${res.statusText}`);
|
|
551
|
+
}
|
|
552
|
+
return res.arrayBuffer();
|
|
553
|
+
})
|
|
554
|
+
.then((val) => {
|
|
555
|
+
if (abortController.signal.aborted) {
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
const bytes = new Uint8Array(val);
|
|
560
|
+
// MVT pbf: with the default delegated worker Rust never reads these
|
|
561
|
+
// bytes — they only travel back out to `processParseMvtTile`. Adopt
|
|
562
|
+
// them into the JS-side store (WASM tracks a byte-count-only `External`
|
|
563
|
+
// handle) so they never round-trip through WASM linear memory. Ownership
|
|
564
|
+
// moves into the store, so do NOT clear `bytes` afterward.
|
|
565
|
+
// Range reads (PMTiles) also arrive with the `mvt` extension but Rust
|
|
566
|
+
// parses those bytes (header/directory/payload), so they must stay
|
|
567
|
+
// WASM-resident.
|
|
568
|
+
const isRangeRequest = req.offset != null && req.length != null;
|
|
569
|
+
if (req.extension === "mvt" && !isRangeRequest) {
|
|
570
|
+
buf.setExternal(req.handle, req.bits, bytes);
|
|
571
|
+
} else {
|
|
572
|
+
buf.setU8(req.handle, req.bits, bytes);
|
|
573
|
+
|
|
574
|
+
// Prevent memory leak
|
|
575
|
+
bytes.set([]);
|
|
576
|
+
}
|
|
577
|
+
})
|
|
578
|
+
.catch(() => {
|
|
579
|
+
buf.triggerDataRequesterFailed(req.bits);
|
|
580
|
+
})
|
|
581
|
+
.finally(() => {
|
|
582
|
+
abortControllers.delete(id);
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
function processDataRequesterRemoved(
|
|
587
|
+
ctx: EventContext,
|
|
588
|
+
req: DataRequesterRemovedEvent,
|
|
589
|
+
) {
|
|
590
|
+
const { abortControllers, workerPoolPromises, loadedTexs, hillshadeContext } =
|
|
591
|
+
ctx;
|
|
592
|
+
const id = generate_id_from_entity(req);
|
|
593
|
+
const abortController = abortControllers.get(id);
|
|
594
|
+
const workerPool = workerPoolPromises.get(id);
|
|
595
|
+
|
|
596
|
+
// Clean up hillshade resources first (if applicable)
|
|
597
|
+
// For hillshade entities, clearRenderTarget will dispose the RenderTarget and its texture
|
|
598
|
+
if (hillshadeContext) {
|
|
599
|
+
hillshadeContext.pendingEdges.delete(id);
|
|
600
|
+
hillshadeContext.clearTempDem(id);
|
|
601
|
+
hillshadeContext.clearRenderTarget(id);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// Dispose and remove texture from loadedTexs
|
|
605
|
+
// For hillshade entities, texture is already disposed by clearRenderTarget above
|
|
606
|
+
// Check isRenderTargetTexture to avoid double-dispose
|
|
607
|
+
if (loadedTexs) {
|
|
608
|
+
const texture = loadedTexs.get(id);
|
|
609
|
+
if (texture && !texture.isRenderTargetTexture) {
|
|
610
|
+
disposeTexture(texture);
|
|
611
|
+
}
|
|
612
|
+
loadedTexs.delete(id);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// Note: Do NOT call buf.remove(req.handle) here!
|
|
616
|
+
// The handle is shared among multiple consumers (via Rust DataManager)
|
|
617
|
+
// Rust side manages the lifecycle and will remove data when ref count reaches 0
|
|
618
|
+
|
|
619
|
+
abortController?.abort();
|
|
620
|
+
workerPool?.cancel();
|
|
621
|
+
|
|
622
|
+
abortControllers.delete(id);
|
|
623
|
+
workerPoolPromises.delete(id);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
async function processTextureFragmentRequested(
|
|
627
|
+
ctx: EventContext,
|
|
628
|
+
req: TextureFragmentRequestedEvent,
|
|
629
|
+
) {
|
|
630
|
+
const { texFragment, loadedTexs, abortControllers } = ctx;
|
|
631
|
+
const id = generate_id_from_entity(req);
|
|
632
|
+
if (loadedTexs.has(id)) return;
|
|
633
|
+
|
|
634
|
+
const abortController = (() => {
|
|
635
|
+
const a = abortControllers.get(id);
|
|
636
|
+
if (a) {
|
|
637
|
+
return a;
|
|
638
|
+
} else {
|
|
639
|
+
const a = new AbortController();
|
|
640
|
+
abortControllers.set(id, a);
|
|
641
|
+
return a;
|
|
642
|
+
}
|
|
643
|
+
})();
|
|
644
|
+
|
|
645
|
+
await ABORTABLE_TEXTURE_LOADER.loadAsyncWithAbort(req.url, abortController)
|
|
646
|
+
.then((t) => {
|
|
647
|
+
loadedTexs.set(id, t);
|
|
648
|
+
texFragment.triggerTextureFragmentLoaded(
|
|
649
|
+
req.bits,
|
|
650
|
+
TextureFragmentStatus.Success,
|
|
651
|
+
);
|
|
652
|
+
})
|
|
653
|
+
.catch(() => {
|
|
654
|
+
texFragment.triggerTextureFragmentLoaded(
|
|
655
|
+
req.bits,
|
|
656
|
+
TextureFragmentStatus.Fail,
|
|
657
|
+
);
|
|
658
|
+
})
|
|
659
|
+
.finally(() => {
|
|
660
|
+
abortControllers.delete(id);
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
function processTextureFragmentRemoved(ctx: EventContext, req: EntityEvent) {
|
|
665
|
+
const { loadedTexs, abortControllers, hillshadeContext } = ctx;
|
|
666
|
+
const id = generate_id_from_entity(req);
|
|
667
|
+
const abortController = abortControllers.get(id);
|
|
668
|
+
|
|
669
|
+
// Clean up hillshade resources first (if applicable)
|
|
670
|
+
// For hillshade entities, clearRenderTarget will dispose the RenderTarget and its texture
|
|
671
|
+
if (hillshadeContext) {
|
|
672
|
+
hillshadeContext.pendingEdges.delete(id);
|
|
673
|
+
hillshadeContext.clearTempDem(id);
|
|
674
|
+
hillshadeContext.clearRenderTarget(id);
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
// Dispose and remove texture from loadedTexs
|
|
678
|
+
// For hillshade entities, texture is already disposed by clearRenderTarget above
|
|
679
|
+
// Check isRenderTargetTexture to avoid double-dispose
|
|
680
|
+
const texture = loadedTexs.get(id);
|
|
681
|
+
if (texture && !texture.isRenderTargetTexture) {
|
|
682
|
+
disposeTexture(texture);
|
|
683
|
+
}
|
|
684
|
+
loadedTexs.delete(id);
|
|
685
|
+
|
|
686
|
+
abortController?.abort();
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
export function setTransform(
|
|
690
|
+
obj: Object3D,
|
|
691
|
+
transform: Transform,
|
|
692
|
+
keepPosition?: boolean,
|
|
693
|
+
) {
|
|
694
|
+
const { tx, ty, tz, qx, qy, qz, qw, sx, sy, sz } = transform;
|
|
695
|
+
if (!keepPosition) {
|
|
696
|
+
obj.position.set(tx, ty, tz);
|
|
697
|
+
}
|
|
698
|
+
obj.quaternion.set(qx, qy, qz, qw);
|
|
699
|
+
obj.scale.set(sx, sy, sz);
|
|
700
|
+
}
|