@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,164 @@
|
|
|
1
|
+
import { Mesh, BoxGeometry, MeshBasicMaterial } from "three";
|
|
2
|
+
import { describe, it, expect, vi } from "vitest";
|
|
3
|
+
|
|
4
|
+
import { TexturizedSceneByTileCoordinates, TileScene } from "./scene";
|
|
5
|
+
|
|
6
|
+
function createMockRenderer() {
|
|
7
|
+
return {
|
|
8
|
+
getContext: vi.fn(),
|
|
9
|
+
getPixelRatio: vi.fn().mockReturnValue(1),
|
|
10
|
+
getSize: vi.fn(),
|
|
11
|
+
setSize: vi.fn(),
|
|
12
|
+
render: vi.fn(),
|
|
13
|
+
} as unknown as ConstructorParameters<
|
|
14
|
+
typeof TexturizedSceneByTileCoordinates
|
|
15
|
+
>[0];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function createMesh(): Mesh {
|
|
19
|
+
return new Mesh(new BoxGeometry(1, 1, 1), new MeshBasicMaterial());
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function getGroup(ts: TexturizedSceneByTileCoordinates, handle: bigint) {
|
|
23
|
+
const group = ts.map.get(handle);
|
|
24
|
+
if (!group) throw new Error("group not found");
|
|
25
|
+
return group;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe("add", () => {
|
|
29
|
+
it("add creates a new TileScene with layerId inside SceneGroup", () => {
|
|
30
|
+
const ts = new TexturizedSceneByTileCoordinates(createMockRenderer());
|
|
31
|
+
const handle = 1n;
|
|
32
|
+
const mesh = createMesh();
|
|
33
|
+
|
|
34
|
+
ts.add(handle, "layer-a", mesh, 0);
|
|
35
|
+
|
|
36
|
+
const group = getGroup(ts, handle);
|
|
37
|
+
expect(group.tileScenes).toHaveLength(1);
|
|
38
|
+
expect(group.tileScenes[0].layerId).toBe("layer-a");
|
|
39
|
+
expect(group.tileScenes[0]).toBeInstanceOf(TileScene);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("add with same layerId reuses existing Scene", () => {
|
|
43
|
+
const ts = new TexturizedSceneByTileCoordinates(createMockRenderer());
|
|
44
|
+
const handle = 1n;
|
|
45
|
+
|
|
46
|
+
ts.add(handle, "layer-a", createMesh(), 0);
|
|
47
|
+
ts.add(handle, "layer-a", createMesh(), 0);
|
|
48
|
+
|
|
49
|
+
const group = getGroup(ts, handle);
|
|
50
|
+
expect(group.tileScenes).toHaveLength(1);
|
|
51
|
+
expect(group.tileScenes[0].children).toHaveLength(2);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("scenes are sorted by layerIndex", () => {
|
|
55
|
+
const ts = new TexturizedSceneByTileCoordinates(createMockRenderer());
|
|
56
|
+
const handle = 1n;
|
|
57
|
+
|
|
58
|
+
ts.add(handle, "c", createMesh(), 2);
|
|
59
|
+
ts.add(handle, "b", createMesh(), 1);
|
|
60
|
+
ts.add(handle, "a", createMesh(), 0);
|
|
61
|
+
|
|
62
|
+
const group = getGroup(ts, handle);
|
|
63
|
+
expect(group.tileScenes.map((c) => c.layerIndex)).toEqual([0, 1, 2]);
|
|
64
|
+
expect(group.tileScenes.map((c) => c.layerId)).toEqual(["a", "b", "c"]);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("revision increments on add", () => {
|
|
68
|
+
const ts = new TexturizedSceneByTileCoordinates(createMockRenderer());
|
|
69
|
+
const handle = 1n;
|
|
70
|
+
|
|
71
|
+
ts.add(handle, "layer-a", createMesh(), 0);
|
|
72
|
+
const scene = ts.findSceneByLayerId(handle, "layer-a");
|
|
73
|
+
expect(scene?.revision).toBe(1);
|
|
74
|
+
|
|
75
|
+
ts.add(handle, "layer-a", createMesh(), 0);
|
|
76
|
+
expect(scene?.revision).toBe(2);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("removeMesh removes only that mesh, keeping siblings, and bumps revision", () => {
|
|
80
|
+
const ts = new TexturizedSceneByTileCoordinates(createMockRenderer());
|
|
81
|
+
const handle = 1n;
|
|
82
|
+
const a = createMesh();
|
|
83
|
+
const b = createMesh();
|
|
84
|
+
|
|
85
|
+
ts.add(handle, "layer-a", a, 0);
|
|
86
|
+
ts.add(handle, "layer-a", b, 0);
|
|
87
|
+
const scene = ts.findSceneByLayerId(handle, "layer-a");
|
|
88
|
+
const revBefore = scene?.revision ?? 0;
|
|
89
|
+
|
|
90
|
+
ts.removeMesh(handle, "layer-a", a);
|
|
91
|
+
|
|
92
|
+
expect(scene?.children).toHaveLength(1);
|
|
93
|
+
expect(scene?.children[0]).toBe(b);
|
|
94
|
+
expect(scene?.removed).toBe(false);
|
|
95
|
+
expect(scene?.revision).toBe(revBefore + 1);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("removeMesh prunes the empty TileScene and SceneGroup once the last mesh leaves", () => {
|
|
99
|
+
const ts = new TexturizedSceneByTileCoordinates(createMockRenderer());
|
|
100
|
+
const handle = 1n;
|
|
101
|
+
const a = createMesh();
|
|
102
|
+
|
|
103
|
+
ts.add(handle, "layer-a", a, 0);
|
|
104
|
+
const scene = ts.findSceneByLayerId(handle, "layer-a");
|
|
105
|
+
|
|
106
|
+
ts.removeMesh(handle, "layer-a", a);
|
|
107
|
+
|
|
108
|
+
expect(scene?.removed).toBe(true);
|
|
109
|
+
// The empty scene group is pruned from the map (no leak).
|
|
110
|
+
expect(ts.map.has(handle)).toBe(false);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("delete removes the entire SceneGroup for a tile handle", () => {
|
|
114
|
+
const ts = new TexturizedSceneByTileCoordinates(createMockRenderer());
|
|
115
|
+
const handle = 1n;
|
|
116
|
+
|
|
117
|
+
ts.add(handle, "layer-a", createMesh(), 0);
|
|
118
|
+
ts.delete(handle);
|
|
119
|
+
|
|
120
|
+
expect(ts.map.has(handle)).toBe(false);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
describe("findSceneByLayerId", () => {
|
|
125
|
+
it("returns the TileScene for a known layerId", () => {
|
|
126
|
+
const ts = new TexturizedSceneByTileCoordinates(createMockRenderer());
|
|
127
|
+
const handle = 1n;
|
|
128
|
+
|
|
129
|
+
ts.add(handle, "layer-a", createMesh(), 0);
|
|
130
|
+
|
|
131
|
+
const scene = ts.findSceneByLayerId(handle, "layer-a");
|
|
132
|
+
expect(scene).toBeInstanceOf(TileScene);
|
|
133
|
+
expect(scene?.layerId).toBe("layer-a");
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it("returns undefined for unknown layerId", () => {
|
|
137
|
+
const ts = new TexturizedSceneByTileCoordinates(createMockRenderer());
|
|
138
|
+
|
|
139
|
+
expect(ts.findSceneByLayerId(1n, "nonexistent")).toBeUndefined();
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe("markDirty", () => {
|
|
144
|
+
it("bumps the layer scene's revision without changing children", () => {
|
|
145
|
+
const ts = new TexturizedSceneByTileCoordinates(createMockRenderer());
|
|
146
|
+
const handle = 1n;
|
|
147
|
+
|
|
148
|
+
ts.add(handle, "layer-a", createMesh(), 0);
|
|
149
|
+
const scene = ts.findSceneByLayerId(handle, "layer-a");
|
|
150
|
+
const revBefore = scene?.revision ?? 0;
|
|
151
|
+
const childrenBefore = scene?.children.length ?? 0;
|
|
152
|
+
|
|
153
|
+
ts.markDirty(handle, "layer-a");
|
|
154
|
+
|
|
155
|
+
expect(scene?.revision).toBe(revBefore + 1);
|
|
156
|
+
expect(scene?.children.length).toBe(childrenBefore);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("is a no-op for an unknown handle/layerId", () => {
|
|
160
|
+
const ts = new TexturizedSceneByTileCoordinates(createMockRenderer());
|
|
161
|
+
|
|
162
|
+
expect(() => ts.markDirty(999n, "nonexistent")).not.toThrow();
|
|
163
|
+
});
|
|
164
|
+
});
|
package/src/scene.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { TileHandle } from "@navaramap/core";
|
|
2
|
+
import { OrthographicCamera, Scene, WebGLRenderer, Mesh, Group } from "three";
|
|
3
|
+
|
|
4
|
+
export type Scenes = {
|
|
5
|
+
// Render light in all scenes.
|
|
6
|
+
light: Group;
|
|
7
|
+
// Render general mesh to MRT. The mesh added to this scene needs a normal buffer.
|
|
8
|
+
mrt: Scene;
|
|
9
|
+
// Render only globe.
|
|
10
|
+
globe: Scene;
|
|
11
|
+
// Render only draped mesh on the globe
|
|
12
|
+
draped: Scene;
|
|
13
|
+
// Render this scene at last. This scene should not be handled in MRT.
|
|
14
|
+
opaque: Scene;
|
|
15
|
+
// Render this scene after the atmosphere effect. This scene should not be handled in MRT.
|
|
16
|
+
// It is useful to render a transparent mesh.
|
|
17
|
+
transparent: Scene;
|
|
18
|
+
// Render sky environment map to a cube map for reflections
|
|
19
|
+
skyEnvMap: Scene;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export class TileScene extends Scene {
|
|
23
|
+
layerId: string;
|
|
24
|
+
layerIndex: number;
|
|
25
|
+
removed = false;
|
|
26
|
+
revision = 0;
|
|
27
|
+
|
|
28
|
+
constructor(layerId: string, layerIndex: number) {
|
|
29
|
+
super();
|
|
30
|
+
this.layerId = layerId;
|
|
31
|
+
this.layerIndex = layerIndex;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class SceneGroup extends Group {
|
|
36
|
+
get tileScenes(): TileScene[] {
|
|
37
|
+
return this.children as TileScene[];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class TexturizedSceneByTileCoordinates {
|
|
42
|
+
map = new Map<TileHandle, SceneGroup>();
|
|
43
|
+
renderer: WebGLRenderer;
|
|
44
|
+
camera: OrthographicCamera;
|
|
45
|
+
|
|
46
|
+
constructor(renderer: WebGLRenderer) {
|
|
47
|
+
this.renderer = renderer;
|
|
48
|
+
this.camera = new OrthographicCamera(-1, 1, 1, -1, 0, 1);
|
|
49
|
+
this.camera.position.z = 1;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get(handle: TileHandle) {
|
|
53
|
+
let scene = this.map.get(handle);
|
|
54
|
+
if (!scene) {
|
|
55
|
+
scene = new SceneGroup();
|
|
56
|
+
this.map.set(handle, scene);
|
|
57
|
+
}
|
|
58
|
+
return scene;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private findTileScene(
|
|
62
|
+
handle: TileHandle,
|
|
63
|
+
layerId: string,
|
|
64
|
+
): TileScene | undefined {
|
|
65
|
+
return this.map.get(handle)?.tileScenes.find((o) => o.layerId === layerId);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
add(handle: TileHandle, layerId: string, mesh: Mesh, layerIndex: number) {
|
|
69
|
+
const scenes = this.get(handle);
|
|
70
|
+
let scene = this.findTileScene(handle, layerId);
|
|
71
|
+
if (!scene) {
|
|
72
|
+
scene = new TileScene(layerId, layerIndex);
|
|
73
|
+
scenes.add(scene);
|
|
74
|
+
scenes.tileScenes.sort((a, b) => a.layerIndex - b.layerIndex);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
scene.removed = false;
|
|
78
|
+
|
|
79
|
+
scene.add(mesh);
|
|
80
|
+
scene.revision++;
|
|
81
|
+
|
|
82
|
+
return scene;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
findSceneByLayerId(handle: TileHandle, layerId: string) {
|
|
86
|
+
return this.findTileScene(handle, layerId);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Bump a layer scene's revision without changing its contents. Draped-feature
|
|
91
|
+
* material/visibility changes that don't add or remove a mesh use this so the
|
|
92
|
+
* consuming TileMesh's bake signature (which folds in `revision`) re-bakes.
|
|
93
|
+
*/
|
|
94
|
+
markDirty(handle: TileHandle, layerId: string) {
|
|
95
|
+
const scene = this.findTileScene(handle, layerId);
|
|
96
|
+
if (!scene) return;
|
|
97
|
+
scene.revision++;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Remove a single feature mesh from its (tile, layer) scene. Only when the scene's last
|
|
102
|
+
* mesh leaves do we mark it `removed` and prune the empty `TileScene` (and the
|
|
103
|
+
* `SceneGroup` if it too becomes empty). This keeps sibling draped features in the same
|
|
104
|
+
* tile+layer intact — unlike a whole-scene clear, which blanked them all on one removal.
|
|
105
|
+
*/
|
|
106
|
+
removeMesh(handle: TileHandle, layerId: string, mesh: Mesh) {
|
|
107
|
+
const scene = this.findTileScene(handle, layerId);
|
|
108
|
+
if (!scene) return;
|
|
109
|
+
scene.remove(mesh);
|
|
110
|
+
scene.revision++;
|
|
111
|
+
if (scene.children.length === 0) {
|
|
112
|
+
scene.removed = true;
|
|
113
|
+
const group = this.map.get(handle);
|
|
114
|
+
group?.remove(scene);
|
|
115
|
+
if (group && group.tileScenes.length === 0) this.delete(handle);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
delete(handle: TileHandle) {
|
|
120
|
+
const sceneGroup = this.map.get(handle);
|
|
121
|
+
if (!sceneGroup) return;
|
|
122
|
+
|
|
123
|
+
sceneGroup.clear();
|
|
124
|
+
|
|
125
|
+
this.map.delete(handle);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@takram/three-geospatial/shaders";
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { AstroTime, Body, HourAngle, Observer } from "astronomy-engine";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
getSunElevation,
|
|
6
|
+
shiftDateToElevation,
|
|
7
|
+
shiftDateToHourAngle,
|
|
8
|
+
} from "./solar";
|
|
9
|
+
|
|
10
|
+
// Summer solstice — well-defined sun positions at all test locations
|
|
11
|
+
const BASE_DATE = new Date("2024-06-21T00:00:00Z");
|
|
12
|
+
|
|
13
|
+
function sunHourAngle(date: Date, lng: number): number {
|
|
14
|
+
return HourAngle(Body.Sun, new AstroTime(date), new Observer(0, lng, 0));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe("shiftDateToHourAngle", () => {
|
|
18
|
+
it("preserves hour angle when moving from Tokyo to London", () => {
|
|
19
|
+
const haBefore = sunHourAngle(BASE_DATE, 139.69);
|
|
20
|
+
const result = shiftDateToHourAngle(BASE_DATE, 139.69, -0.12);
|
|
21
|
+
expect(sunHourAngle(result, -0.12)).toBeCloseTo(haBefore, 2);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("preserves hour angle when moving from London to New York", () => {
|
|
25
|
+
const date = new Date("2024-06-21T08:00:00Z");
|
|
26
|
+
const haBefore = sunHourAngle(date, -0.12);
|
|
27
|
+
const result = shiftDateToHourAngle(date, -0.12, -74.01);
|
|
28
|
+
expect(sunHourAngle(result, -74.01)).toBeCloseTo(haBefore, 2);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("is a no-op when target longitude equals source longitude", () => {
|
|
32
|
+
const result = shiftDateToHourAngle(BASE_DATE, 139.69, 139.69);
|
|
33
|
+
expect(result.getTime()).toBeCloseTo(BASE_DATE.getTime(), -3); // within ~1s
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("handles crossing the date line (Tokyo → Honolulu)", () => {
|
|
37
|
+
const haBefore = sunHourAngle(BASE_DATE, 139.69);
|
|
38
|
+
const result = shiftDateToHourAngle(BASE_DATE, 139.69, -157.85);
|
|
39
|
+
expect(sunHourAngle(result, -157.85)).toBeCloseTo(haBefore, 2);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe("shiftDateToElevation", () => {
|
|
44
|
+
it("preserves sun elevation when moving from Tokyo to London (morning)", () => {
|
|
45
|
+
// ~8 AM solar at Tokyo
|
|
46
|
+
const date = new Date("2024-06-20T22:40:00Z");
|
|
47
|
+
const elevBefore = getSunElevation(date, 35.68, 139.69);
|
|
48
|
+
const result = shiftDateToElevation(date, 35.68, 139.69, 51.5, -0.12);
|
|
49
|
+
expect(getSunElevation(result, 51.5, -0.12)).toBeCloseTo(elevBefore, 1);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("preserves sun elevation when moving from Tokyo to London (afternoon)", () => {
|
|
53
|
+
// ~4 PM solar at Tokyo
|
|
54
|
+
const date = new Date("2024-06-21T07:00:00Z");
|
|
55
|
+
const elevBefore = getSunElevation(date, 35.68, 139.69);
|
|
56
|
+
const result = shiftDateToElevation(date, 35.68, 139.69, 51.5, -0.12);
|
|
57
|
+
expect(getSunElevation(result, 51.5, -0.12)).toBeCloseTo(elevBefore, 1);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("clamps to solar noon when target elevation exceeds location maximum", () => {
|
|
61
|
+
// High elevation at equator around noon in December — unreachable at Reykjavik (~3° max)
|
|
62
|
+
const date = new Date("2024-12-21T12:00:00Z");
|
|
63
|
+
const result = shiftDateToElevation(date, 0, 0, 64.1, -22.0);
|
|
64
|
+
expect(result).toBeInstanceOf(Date);
|
|
65
|
+
expect(isNaN(result.getTime())).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe("getSunElevation", () => {
|
|
70
|
+
it("returns positive elevation at solar noon", () => {
|
|
71
|
+
// Tokyo solar noon ≈ 02:43 UTC on 2024-06-21
|
|
72
|
+
const date = new Date("2024-06-21T02:43:00Z");
|
|
73
|
+
expect(getSunElevation(date, 35.68, 139.69)).toBeGreaterThan(0);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("returns negative elevation at solar midnight", () => {
|
|
77
|
+
// Tokyo solar midnight ≈ 14:43 UTC on 2024-06-21
|
|
78
|
+
const date = new Date("2024-06-21T14:43:00Z");
|
|
79
|
+
expect(getSunElevation(date, 35.68, 139.69)).toBeLessThan(0);
|
|
80
|
+
});
|
|
81
|
+
});
|
package/src/solar.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AstroTime,
|
|
3
|
+
Body,
|
|
4
|
+
Equator,
|
|
5
|
+
Horizon,
|
|
6
|
+
HourAngle,
|
|
7
|
+
Observer,
|
|
8
|
+
SearchAltitude,
|
|
9
|
+
SearchHourAngle,
|
|
10
|
+
} from "astronomy-engine";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Returns the sun elevation angle in degrees at the given location and time.
|
|
14
|
+
* Includes atmospheric refraction correction.
|
|
15
|
+
*/
|
|
16
|
+
export function getSunElevation(date: Date, lat: number, lng: number): number {
|
|
17
|
+
const time = new AstroTime(date);
|
|
18
|
+
const observer = new Observer(lat, lng, 0);
|
|
19
|
+
const eq = Equator(Body.Sun, time, observer, true, true);
|
|
20
|
+
return Horizon(time, observer, eq.ra, eq.dec, "normal").altitude;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Returns a new Date such that the sun's hour angle at `targetLng` matches the
|
|
25
|
+
* hour angle currently at `fromLng`.
|
|
26
|
+
*
|
|
27
|
+
* Hour angle is longitude-dependent and increases monotonically 0→24 over a
|
|
28
|
+
* solar day, so there is exactly one solution per day — no morning/afternoon
|
|
29
|
+
* ambiguity.
|
|
30
|
+
*/
|
|
31
|
+
export function shiftDateToHourAngle(
|
|
32
|
+
date: Date,
|
|
33
|
+
fromLng: number,
|
|
34
|
+
targetLng: number,
|
|
35
|
+
targetLat = 0,
|
|
36
|
+
): Date {
|
|
37
|
+
const time = new AstroTime(date);
|
|
38
|
+
const ha = HourAngle(Body.Sun, time, new Observer(0, fromLng, 0));
|
|
39
|
+
const dayStart = new AstroTime(
|
|
40
|
+
new Date(
|
|
41
|
+
Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()),
|
|
42
|
+
),
|
|
43
|
+
);
|
|
44
|
+
return SearchHourAngle(
|
|
45
|
+
Body.Sun,
|
|
46
|
+
new Observer(targetLat, targetLng, 0),
|
|
47
|
+
ha,
|
|
48
|
+
dayStart,
|
|
49
|
+
1,
|
|
50
|
+
).time.date;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Returns a new Date such that the sun elevation at `(targetLat, targetLng)`
|
|
55
|
+
* matches the elevation at `(fromLat, fromLng)` on the given date.
|
|
56
|
+
*
|
|
57
|
+
* Morning/afternoon context (rising vs setting) is inferred from the hour
|
|
58
|
+
* angle at `fromLng`. If the target elevation exceeds the maximum achievable
|
|
59
|
+
* at the location (e.g. polar night), the date is clamped to solar noon.
|
|
60
|
+
*/
|
|
61
|
+
export function shiftDateToElevation(
|
|
62
|
+
date: Date,
|
|
63
|
+
fromLat: number,
|
|
64
|
+
fromLng: number,
|
|
65
|
+
targetLat: number,
|
|
66
|
+
targetLng: number,
|
|
67
|
+
): Date {
|
|
68
|
+
const targetAltitude = getSunElevation(date, fromLat, fromLng);
|
|
69
|
+
|
|
70
|
+
// HA > 12 means morning (0 = solar noon, 12 = solar midnight).
|
|
71
|
+
const isMorning =
|
|
72
|
+
HourAngle(Body.Sun, new AstroTime(date), new Observer(0, fromLng, 0)) > 12;
|
|
73
|
+
|
|
74
|
+
const observer = new Observer(targetLat, targetLng, 0);
|
|
75
|
+
const dayStart = new AstroTime(
|
|
76
|
+
new Date(
|
|
77
|
+
Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()),
|
|
78
|
+
),
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const noonTime = SearchHourAngle(Body.Sun, observer, 0, dayStart, 1).time;
|
|
82
|
+
const midnightTime = SearchHourAngle(
|
|
83
|
+
Body.Sun,
|
|
84
|
+
observer,
|
|
85
|
+
12,
|
|
86
|
+
new AstroTime(new Date(noonTime.date.getTime() - 13 * 3_600_000)),
|
|
87
|
+
1,
|
|
88
|
+
).time;
|
|
89
|
+
|
|
90
|
+
const searchStart = isMorning ? midnightTime : noonTime;
|
|
91
|
+
const result = SearchAltitude(
|
|
92
|
+
Body.Sun,
|
|
93
|
+
observer,
|
|
94
|
+
isMorning ? 1 : -1,
|
|
95
|
+
searchStart,
|
|
96
|
+
0.6,
|
|
97
|
+
targetAltitude,
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
return result?.date ?? noonTime.date;
|
|
101
|
+
}
|
package/src/source.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { Core } from "@navaramap/engine";
|
|
2
|
+
|
|
3
|
+
import type { SourceDescription } from "./type";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A handle to a data source (GeoJSON, vector tile, raster tile, raster DEM,
|
|
7
|
+
* quantized mesh, 3D Tiles) registered via {@link ThreeView.addSource}.
|
|
8
|
+
*
|
|
9
|
+
* A source describes where data comes from and how it is fetched/decoded. One
|
|
10
|
+
* source can be referenced by multiple layers (by its `id`). The engine
|
|
11
|
+
* reference-counts sources and refuses to delete a source while any layer still
|
|
12
|
+
* references it.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const poi = view.addSource({
|
|
17
|
+
* type: "vector-tile",
|
|
18
|
+
* url: "https://example.com/{z}/{x}/{y}.pbf",
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* view.addLayer({
|
|
22
|
+
* type: "vector",
|
|
23
|
+
* source: poi,
|
|
24
|
+
* sourceLayers: ["building"],
|
|
25
|
+
* polygon: { color: 0x00aaff },
|
|
26
|
+
* });
|
|
27
|
+
* view.addLayer({
|
|
28
|
+
* type: "vector",
|
|
29
|
+
* source: poi,
|
|
30
|
+
* sourceLayers: ["building"],
|
|
31
|
+
* polyline: { color: 0xffffff },
|
|
32
|
+
* });
|
|
33
|
+
*/
|
|
34
|
+
export class Source {
|
|
35
|
+
/** The unique identifier of this source, used to reference it from layers. */
|
|
36
|
+
readonly id: string;
|
|
37
|
+
/** The discriminant type of this source (e.g. "vector-tile"). */
|
|
38
|
+
readonly type: string;
|
|
39
|
+
private core: Core;
|
|
40
|
+
|
|
41
|
+
constructor(id: string, type: string, core: Core) {
|
|
42
|
+
this.id = id;
|
|
43
|
+
this.type = type;
|
|
44
|
+
this.core = core;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Updates the source configuration and re-fetches its data. Every layer that
|
|
49
|
+
* references this source is reset (its resources are torn down) and reloaded
|
|
50
|
+
* against the new configuration.
|
|
51
|
+
*
|
|
52
|
+
* The update is partial, like {@link Layer.update}: any field you omit keeps
|
|
53
|
+
* its current value instead of resetting to a default. `type` cannot change
|
|
54
|
+
* and is always required; `url` is required by the type but, when set to the
|
|
55
|
+
* unchanged value, leaves the fetched URL as-is.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* // Only maxZoom changes; tms and the other fields are preserved.
|
|
60
|
+
* imagery.update({
|
|
61
|
+
* type: "raster-tile",
|
|
62
|
+
* url: "https://example.com/{z}/{x}/{y}.png",
|
|
63
|
+
* maxZoom: 22,
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
update(s: SourceDescription) {
|
|
68
|
+
this.core.updateSource(this.id, s);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Removes the source and its resources.
|
|
73
|
+
*
|
|
74
|
+
* @returns `false` (and removes nothing) while any layer still references this
|
|
75
|
+
* source; `true` once the source has been removed.
|
|
76
|
+
*/
|
|
77
|
+
delete(): boolean {
|
|
78
|
+
return this.core.deleteSource(this.id);
|
|
79
|
+
}
|
|
80
|
+
}
|
package/src/stats.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import Stats from "stats.js";
|
|
2
|
+
|
|
3
|
+
type Renderer = {
|
|
4
|
+
beginRender: () => void;
|
|
5
|
+
endRender: () => {
|
|
6
|
+
calls?: number;
|
|
7
|
+
triangles?: number;
|
|
8
|
+
memGeometries?: number;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type MemorySample = {
|
|
13
|
+
/** WASM BufferStore bytes (WASM-resident only), in MB. */
|
|
14
|
+
wasmMB?: number;
|
|
15
|
+
/** JS-side `InMemoryBufferStore` bytes (WASM `External` entries), in MB. */
|
|
16
|
+
jsBufMB?: number;
|
|
17
|
+
/** JS heap usage (Chrome-only `performance.memory`), in MB. */
|
|
18
|
+
jsHeapMB?: number;
|
|
19
|
+
/** Cache budget for the panel scale, in MB. */
|
|
20
|
+
budgetMB?: number;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/** How often the (relatively costly) memory sampler runs. */
|
|
24
|
+
const MEMORY_SAMPLE_INTERVAL_MS = 1000;
|
|
25
|
+
|
|
26
|
+
export class RendererStats {
|
|
27
|
+
stats: Stats;
|
|
28
|
+
renderer: Renderer;
|
|
29
|
+
drawCalls: Stats.Panel;
|
|
30
|
+
numTriangles: Stats.Panel;
|
|
31
|
+
memGeometries: Stats.Panel;
|
|
32
|
+
wasmMemory: Stats.Panel;
|
|
33
|
+
jsMemory: Stats.Panel;
|
|
34
|
+
private memorySampler?: () => MemorySample | undefined;
|
|
35
|
+
private lastMemorySampleAt = 0;
|
|
36
|
+
private maxWasmMB = 1;
|
|
37
|
+
private maxJsHeapMB = 1;
|
|
38
|
+
constructor(r: Renderer, memorySampler?: () => MemorySample | undefined) {
|
|
39
|
+
this.stats = new Stats();
|
|
40
|
+
this.renderer = r;
|
|
41
|
+
this.memorySampler = memorySampler;
|
|
42
|
+
this.drawCalls = this.stats.addPanel(
|
|
43
|
+
new Stats.Panel("Draws", "#0ff", "#002"),
|
|
44
|
+
);
|
|
45
|
+
this.numTriangles = this.stats.addPanel(
|
|
46
|
+
new Stats.Panel("Triangles", "#0fff57", "#013a12"),
|
|
47
|
+
);
|
|
48
|
+
this.memGeometries = this.stats.addPanel(
|
|
49
|
+
new Stats.Panel("Geometries", "#ffa100", "#301e00"),
|
|
50
|
+
);
|
|
51
|
+
this.wasmMemory = this.stats.addPanel(
|
|
52
|
+
new Stats.Panel("WASM MB", "#f08", "#201"),
|
|
53
|
+
);
|
|
54
|
+
this.jsMemory = this.stats.addPanel(
|
|
55
|
+
new Stats.Panel("JS MB", "#f4f", "#210"),
|
|
56
|
+
);
|
|
57
|
+
this.stats.showPanel(0);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
begin() {
|
|
61
|
+
this.renderer.beginRender();
|
|
62
|
+
this.stats.begin();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
end() {
|
|
66
|
+
const info = this.renderer.endRender();
|
|
67
|
+
if (info.calls) {
|
|
68
|
+
this.drawCalls.update(info.calls, 500);
|
|
69
|
+
}
|
|
70
|
+
if (info.triangles) {
|
|
71
|
+
this.numTriangles.update(info.triangles, 500);
|
|
72
|
+
}
|
|
73
|
+
if (info.memGeometries) {
|
|
74
|
+
this.memGeometries.update(info.memGeometries, 500);
|
|
75
|
+
}
|
|
76
|
+
this.sampleMemory();
|
|
77
|
+
this.stats.end();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Samples memory at most once per second to keep FFI out of the hot path. */
|
|
81
|
+
private sampleMemory() {
|
|
82
|
+
if (!this.memorySampler) return;
|
|
83
|
+
const now = performance.now();
|
|
84
|
+
if (now - this.lastMemorySampleAt < MEMORY_SAMPLE_INTERVAL_MS) return;
|
|
85
|
+
this.lastMemorySampleAt = now;
|
|
86
|
+
|
|
87
|
+
const sample = this.memorySampler();
|
|
88
|
+
if (!sample) return;
|
|
89
|
+
if (sample.wasmMB !== undefined) {
|
|
90
|
+
this.maxWasmMB = Math.max(this.maxWasmMB, sample.wasmMB);
|
|
91
|
+
this.wasmMemory.update(sample.wasmMB, sample.budgetMB ?? this.maxWasmMB);
|
|
92
|
+
}
|
|
93
|
+
if (sample.jsHeapMB !== undefined) {
|
|
94
|
+
this.maxJsHeapMB = Math.max(this.maxJsHeapMB, sample.jsHeapMB);
|
|
95
|
+
this.jsMemory.update(sample.jsHeapMB, this.maxJsHeapMB);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
get dom() {
|
|
100
|
+
return this.stats.dom;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type BufferGeometry } from "three";
|
|
2
|
+
|
|
3
|
+
import { fromBufferGeometryLike, toBufferGeometryLike } from "../utils";
|
|
4
|
+
|
|
5
|
+
import { queueTask } from "./queueTask";
|
|
6
|
+
|
|
7
|
+
export async function computeVertexNormalsAsync(
|
|
8
|
+
geometry: BufferGeometry,
|
|
9
|
+
): Promise<BufferGeometry> {
|
|
10
|
+
const [geometryLike, transfer] = toBufferGeometryLike(geometry);
|
|
11
|
+
const result = await queueTask("computeVertexNormals", [geometryLike], {
|
|
12
|
+
transfer,
|
|
13
|
+
});
|
|
14
|
+
return fromBufferGeometryLike(result, geometry);
|
|
15
|
+
}
|