@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,588 @@
|
|
|
1
|
+
import { generate_id_from_entity } from "@navaramap/core";
|
|
2
|
+
import type { EntityEvent, HillshadeBackfilledEvent } from "@navaramap/engine";
|
|
3
|
+
|
|
4
|
+
import type { TileMesh } from "../mesh/tile";
|
|
5
|
+
import { getTextureFragmentSlots } from "../utils/textureFragmentIndex";
|
|
6
|
+
|
|
7
|
+
import type { EventContext } from "./context";
|
|
8
|
+
import type { HillshadeContext } from "./HillshadeContext";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Resolve the entity ID that hillshade state is keyed by.
|
|
12
|
+
* For edge updates with target_entity_ind/gen, use the target.
|
|
13
|
+
* Otherwise fall back to the event's own entity.
|
|
14
|
+
*/
|
|
15
|
+
export function resolveHillshadeEntityId(
|
|
16
|
+
event: HillshadeBackfilledEvent,
|
|
17
|
+
): string {
|
|
18
|
+
if (
|
|
19
|
+
event.target_entity_ind !== undefined &&
|
|
20
|
+
event.target_entity_gen !== undefined
|
|
21
|
+
) {
|
|
22
|
+
return `${event.target_entity_ind}_${event.target_entity_gen}`;
|
|
23
|
+
}
|
|
24
|
+
return generate_id_from_entity(event);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Create padded DEM data (CPU only, no GPU upload)
|
|
29
|
+
* @returns { data, paddedSize } or undefined if invalid
|
|
30
|
+
*/
|
|
31
|
+
function createPaddedDemData(
|
|
32
|
+
originalBytes: Uint8Array,
|
|
33
|
+
): { data: Uint8Array; paddedSize: number } | undefined {
|
|
34
|
+
if (originalBytes.length % 4 !== 0) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const originalSize = Math.sqrt(originalBytes.length / 4);
|
|
39
|
+
if (!Number.isInteger(originalSize) || originalSize < 1) {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const paddedSize = originalSize + 2;
|
|
44
|
+
const paddedBytes = new Uint8Array(paddedSize * paddedSize * 4);
|
|
45
|
+
|
|
46
|
+
const rowBytes = originalSize * 4;
|
|
47
|
+
for (let y = 0; y < originalSize; y++) {
|
|
48
|
+
const srcRowStart = y * rowBytes;
|
|
49
|
+
const dstRowStart = (y + 1) * paddedSize * 4 + 4;
|
|
50
|
+
paddedBytes.set(
|
|
51
|
+
originalBytes.subarray(srcRowStart, srcRowStart + rowBytes),
|
|
52
|
+
dstRowStart,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
replicateEdgesToPadding(paddedBytes, paddedSize);
|
|
57
|
+
|
|
58
|
+
return { data: paddedBytes, paddedSize };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Apply pending edges that arrived before texture creation.
|
|
63
|
+
* @returns Array of { direction, bytes } for each successfully applied edge
|
|
64
|
+
*/
|
|
65
|
+
function applyPendingEdges(
|
|
66
|
+
demData: Uint8Array,
|
|
67
|
+
paddedSize: number,
|
|
68
|
+
hillshadeContext: HillshadeContext,
|
|
69
|
+
entityId: string,
|
|
70
|
+
): { direction: number; bytes: Uint8Array }[] {
|
|
71
|
+
const applied: { direction: number; bytes: Uint8Array }[] = [];
|
|
72
|
+
const pending = hillshadeContext.pendingEdges.get(entityId);
|
|
73
|
+
|
|
74
|
+
if (!pending || pending.size === 0) {
|
|
75
|
+
return applied;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
for (const [edgeDirection, edgeBytes] of pending) {
|
|
79
|
+
const edgeSize = edgeBytes.length / 4;
|
|
80
|
+
const expectedTexSize = edgeSize + 2;
|
|
81
|
+
|
|
82
|
+
if (paddedSize === expectedTexSize) {
|
|
83
|
+
updatePaddingEdge(demData, edgeBytes, paddedSize, edgeDirection);
|
|
84
|
+
applied.push({ direction: edgeDirection, bytes: edgeBytes });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
hillshadeContext.pendingEdges.delete(entityId);
|
|
89
|
+
|
|
90
|
+
return applied;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Rebind textures to all meshes using this entity
|
|
95
|
+
*/
|
|
96
|
+
function rebindTexturesForEntity(entityId: string, ctx: EventContext): void {
|
|
97
|
+
const { textureFragmentIndex, loadedTexs, textureOptions } = ctx;
|
|
98
|
+
|
|
99
|
+
// These are guaranteed to exist by validation in processHillshadeBackfilled
|
|
100
|
+
if (!textureFragmentIndex || !loadedTexs || !textureOptions) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const slots = getTextureFragmentSlots(textureFragmentIndex, entityId);
|
|
105
|
+
if (!slots) return;
|
|
106
|
+
|
|
107
|
+
// Deduplicate tileMeshes: same mesh may appear in multiple slots
|
|
108
|
+
const uniqueMeshes = new Set<TileMesh>();
|
|
109
|
+
for (const { tileMesh } of slots) {
|
|
110
|
+
uniqueMeshes.add(tileMesh);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
for (const tileMesh of uniqueMeshes) {
|
|
114
|
+
tileMesh.rebindTextures(loadedTexs, textureOptions);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Process initial hillshade texture creation
|
|
120
|
+
*/
|
|
121
|
+
function processInitialHillshadeTexture(
|
|
122
|
+
ctx: EventContext,
|
|
123
|
+
event: HillshadeBackfilledEvent,
|
|
124
|
+
entityId: string,
|
|
125
|
+
): void {
|
|
126
|
+
const { loadedTexs, buf, tileHandler, hillshadeContext } = ctx;
|
|
127
|
+
|
|
128
|
+
// These are guaranteed to exist by validation in processHillshadeBackfilled
|
|
129
|
+
if (!loadedTexs || !buf || !tileHandler || !hillshadeContext) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Validate original_handle exists
|
|
134
|
+
const originalHandle = event.original_handle;
|
|
135
|
+
if (originalHandle === undefined || originalHandle === null) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Read data without removing - DataManager handles cleanup via reference counting
|
|
140
|
+
// When multiple consumers (terrain, hillshade) share the same URL, the data is shared.
|
|
141
|
+
// Reference count is decremented when each consumer entity is deleted.
|
|
142
|
+
// Only when ref count reaches 0 (last consumer removed) is the data actually deleted.
|
|
143
|
+
// buf.u8 returns a short-lived view into WASM memory; createPaddedDemData
|
|
144
|
+
// copies it synchronously below, so no further copy is needed.
|
|
145
|
+
const originalBytes = buf.u8(originalHandle);
|
|
146
|
+
if (!originalBytes) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Create padded DEM data (CPU only, no GPU upload)
|
|
151
|
+
const padded = createPaddedDemData(originalBytes);
|
|
152
|
+
if (!padded) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const { data: demData, paddedSize } = padded;
|
|
156
|
+
|
|
157
|
+
// Get tile handle for calculations
|
|
158
|
+
const tileHandleBigInt =
|
|
159
|
+
typeof event.tile_handle === "bigint"
|
|
160
|
+
? event.tile_handle
|
|
161
|
+
: BigInt(event.tile_handle);
|
|
162
|
+
|
|
163
|
+
// Get tile info for zoom level (validate before doing expensive work)
|
|
164
|
+
const tile = tileHandler.getTile(tileHandleBigInt);
|
|
165
|
+
if (!tile) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Apply any pending edge updates that arrived before texture creation
|
|
170
|
+
const appliedEdges = applyPendingEdges(
|
|
171
|
+
demData,
|
|
172
|
+
paddedSize,
|
|
173
|
+
hillshadeContext,
|
|
174
|
+
entityId,
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
const metersPerTexel = tileHandler.calcMetersPerTexel(
|
|
178
|
+
tileHandleBigInt,
|
|
179
|
+
tile.coords.z,
|
|
180
|
+
paddedSize,
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const hillshadeConfig = hillshadeContext.getHillshadeConfig(
|
|
184
|
+
tileHandler,
|
|
185
|
+
tileHandleBigInt,
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
const contentWidth = paddedSize - 2;
|
|
189
|
+
const contentHeight = paddedSize - 2;
|
|
190
|
+
|
|
191
|
+
// Sanity check: in normal flow, loadedTexs should not have this entity yet
|
|
192
|
+
if (loadedTexs.has(entityId)) {
|
|
193
|
+
console.warn(
|
|
194
|
+
`[Hillshade] Unexpected: loadedTexs already contains ${entityId}, cleaning up`,
|
|
195
|
+
);
|
|
196
|
+
hillshadeContext.clearRenderTarget(entityId);
|
|
197
|
+
loadedTexs.delete(entityId);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Generate normal map (DEM is uploaded transiently and freed after render)
|
|
201
|
+
const normalMap = hillshadeContext.generateNormalMap(
|
|
202
|
+
entityId,
|
|
203
|
+
ctx.viewContext,
|
|
204
|
+
demData,
|
|
205
|
+
paddedSize,
|
|
206
|
+
metersPerTexel,
|
|
207
|
+
hillshadeConfig,
|
|
208
|
+
contentWidth,
|
|
209
|
+
contentHeight,
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
loadedTexs.set(entityId, normalMap);
|
|
213
|
+
|
|
214
|
+
// Store handle-only TempDem entry (no full padded DEM retained)
|
|
215
|
+
hillshadeContext.storeTempDem(
|
|
216
|
+
entityId,
|
|
217
|
+
originalHandle,
|
|
218
|
+
paddedSize,
|
|
219
|
+
metersPerTexel,
|
|
220
|
+
hillshadeConfig,
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
// Persist edge bytes so padded DEM can be reconstructed on subsequent edge arrivals
|
|
224
|
+
for (const { direction, bytes } of appliedEdges) {
|
|
225
|
+
hillshadeContext.storeEdgeData(entityId, direction, bytes);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Mark the edges that were already applied from pending as received
|
|
229
|
+
for (const { direction } of appliedEdges) {
|
|
230
|
+
const allEdgesReceived = hillshadeContext.markEdgeReceived(
|
|
231
|
+
entityId,
|
|
232
|
+
direction,
|
|
233
|
+
);
|
|
234
|
+
if (allEdgesReceived) {
|
|
235
|
+
hillshadeContext.clearTempDem(entityId);
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Rebind textures to update the meshes
|
|
241
|
+
rebindTexturesForEntity(entityId, ctx);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Process hillshade edge update
|
|
246
|
+
*/
|
|
247
|
+
function processHillshadeEdgeUpdate(
|
|
248
|
+
ctx: EventContext,
|
|
249
|
+
event: HillshadeBackfilledEvent,
|
|
250
|
+
entityId: string,
|
|
251
|
+
): void {
|
|
252
|
+
const { loadedTexs, buf, hillshadeContext } = ctx;
|
|
253
|
+
|
|
254
|
+
// These are guaranteed to exist by validation in processHillshadeBackfilled
|
|
255
|
+
if (!loadedTexs || !buf || !hillshadeContext) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Validate edge_data_handle exists
|
|
260
|
+
const edgeDataHandle = event.edge_data_handle;
|
|
261
|
+
if (edgeDataHandle === undefined || edgeDataHandle === null) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Read edge data and remove from BufferStore immediately to prevent leaks
|
|
266
|
+
const edgeBytes = buf.removeU8(edgeDataHandle);
|
|
267
|
+
if (!edgeBytes) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Validate edge data: one edge (size pixels × 4 bytes RGBA)
|
|
272
|
+
if (edgeBytes.length % 4 !== 0) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const texture = loadedTexs.get(entityId);
|
|
277
|
+
|
|
278
|
+
if (!texture) {
|
|
279
|
+
// Texture doesn't exist yet - queue this edge update for later application
|
|
280
|
+
let pending = hillshadeContext.pendingEdges.get(entityId);
|
|
281
|
+
if (!pending) {
|
|
282
|
+
pending = new Map<number, Uint8Array>();
|
|
283
|
+
hillshadeContext.pendingEdges.set(entityId, pending);
|
|
284
|
+
}
|
|
285
|
+
// Copy and store edge data, replacing any previous update for this direction
|
|
286
|
+
pending.set(event.edge_direction, new Uint8Array(edgeBytes));
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Texture exists (it's a normal map), check if we have the temporary DEM entry
|
|
291
|
+
const tempDemEntry = hillshadeContext.getTempDem(entityId);
|
|
292
|
+
if (!tempDemEntry) {
|
|
293
|
+
// No temp DEM - edge updates complete or timed out, ignore this late arrival
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const edgeSize = edgeBytes.length / 4;
|
|
298
|
+
const { originalHandle, paddedSize } = tempDemEntry;
|
|
299
|
+
|
|
300
|
+
// Texture should be padded (edgeSize + 2)
|
|
301
|
+
const expectedTexSize = edgeSize + 2;
|
|
302
|
+
if (paddedSize !== expectedTexSize) {
|
|
303
|
+
// Size mismatch - different zoom levels, discard this edge data
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Store edge bytes for reconstruction on future edge arrivals
|
|
308
|
+
hillshadeContext.storeEdgeData(
|
|
309
|
+
entityId,
|
|
310
|
+
event.edge_direction,
|
|
311
|
+
new Uint8Array(edgeBytes),
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
// Mark this edge as received
|
|
315
|
+
const allEdgesReceived = hillshadeContext.markEdgeReceived(
|
|
316
|
+
entityId,
|
|
317
|
+
event.edge_direction,
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
// Re-read the original DEM from WASM buffer (reference-counted, still valid).
|
|
321
|
+
// The returned view is consumed synchronously by createPaddedDemData below.
|
|
322
|
+
const originalBytes = buf.u8(originalHandle);
|
|
323
|
+
if (originalBytes) {
|
|
324
|
+
// Rebuild the padded DEM transiently, apply all received edges, generate normal map
|
|
325
|
+
const padded = createPaddedDemData(originalBytes);
|
|
326
|
+
if (padded) {
|
|
327
|
+
for (const [dir, storedBytes] of tempDemEntry.receivedEdgeData) {
|
|
328
|
+
updatePaddingEdge(padded.data, storedBytes, padded.paddedSize, dir);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const contentWidth = padded.paddedSize - 2;
|
|
332
|
+
const contentHeight = padded.paddedSize - 2;
|
|
333
|
+
const updatedTexture = hillshadeContext.generateNormalMap(
|
|
334
|
+
entityId,
|
|
335
|
+
ctx.viewContext,
|
|
336
|
+
padded.data,
|
|
337
|
+
padded.paddedSize,
|
|
338
|
+
tempDemEntry.metersPerTexel,
|
|
339
|
+
tempDemEntry.hillshadeConfig,
|
|
340
|
+
contentWidth,
|
|
341
|
+
contentHeight,
|
|
342
|
+
);
|
|
343
|
+
loadedTexs.set(entityId, updatedTexture);
|
|
344
|
+
// padded.data is released here (no persistent reference kept)
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// If all 4 edges received, cleanup the temporary entry
|
|
349
|
+
if (allEdgesReceived) {
|
|
350
|
+
hillshadeContext.clearTempDem(entityId);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Rebind textures to update the meshes
|
|
354
|
+
rebindTexturesForEntity(entityId, ctx);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Handle a hillshade_canceled event.
|
|
359
|
+
*
|
|
360
|
+
* Two responsibilities, both scoped to "the canceled entity":
|
|
361
|
+
* 1. Pre-empt any pending `hillshade_backfilled` events in the EventManager
|
|
362
|
+
* stack whose effect would target this entity, so they never run. Matched
|
|
363
|
+
* via `resolveHillshadeEntityId` so an edge update X→Y (keyed by target Y)
|
|
364
|
+
* survives a cancel of source X — Y still wants that edge data.
|
|
365
|
+
* 2. Drop in-flight backfill state that earlier events created — queued
|
|
366
|
+
* neighbor edges and the in-progress DEM assembly entry.
|
|
367
|
+
*
|
|
368
|
+
* Does NOT dispose render targets or `loadedTexs` textures: those belong to
|
|
369
|
+
* the texture-fragment lifecycle and are released by
|
|
370
|
+
* `processTextureFragmentRemoved`. Disposing them here would race against
|
|
371
|
+
* other tiles that may still reference the texture.
|
|
372
|
+
*
|
|
373
|
+
* Idempotent: safe to call when no state exists for the entity.
|
|
374
|
+
*/
|
|
375
|
+
export function processHillshadeCanceled(
|
|
376
|
+
ctx: EventContext,
|
|
377
|
+
event: EntityEvent | undefined,
|
|
378
|
+
) {
|
|
379
|
+
if (!event) return;
|
|
380
|
+
|
|
381
|
+
const { hillshadeContext, eventManager } = ctx;
|
|
382
|
+
if (!hillshadeContext) return;
|
|
383
|
+
|
|
384
|
+
const entityId = generate_id_from_entity(event);
|
|
385
|
+
|
|
386
|
+
const backfillStack = eventManager.stacks
|
|
387
|
+
.hillshade_backfilled as HillshadeBackfilledEvent[];
|
|
388
|
+
if (backfillStack.length > 0) {
|
|
389
|
+
const kept: HillshadeBackfilledEvent[] = [];
|
|
390
|
+
for (const bf of backfillStack) {
|
|
391
|
+
if (resolveHillshadeEntityId(bf) === entityId) {
|
|
392
|
+
if (bf && "free" in bf && typeof bf.free === "function") {
|
|
393
|
+
bf.free();
|
|
394
|
+
}
|
|
395
|
+
} else {
|
|
396
|
+
kept.push(bf);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
eventManager.stacks.hillshade_backfilled = kept;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
hillshadeContext.pendingEdges.delete(entityId);
|
|
403
|
+
hillshadeContext.clearTempDem(entityId);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export function processHillshadeBackfilled(
|
|
407
|
+
ctx: EventContext,
|
|
408
|
+
event: HillshadeBackfilledEvent | undefined,
|
|
409
|
+
) {
|
|
410
|
+
if (!event) return;
|
|
411
|
+
|
|
412
|
+
const {
|
|
413
|
+
loadedTexs,
|
|
414
|
+
buf,
|
|
415
|
+
textureFragmentIndex,
|
|
416
|
+
textureOptions,
|
|
417
|
+
tileHandler,
|
|
418
|
+
hillshadeContext,
|
|
419
|
+
} = ctx;
|
|
420
|
+
|
|
421
|
+
if (
|
|
422
|
+
!loadedTexs ||
|
|
423
|
+
!buf ||
|
|
424
|
+
!tileHandler ||
|
|
425
|
+
!hillshadeContext ||
|
|
426
|
+
!textureOptions ||
|
|
427
|
+
!textureFragmentIndex
|
|
428
|
+
) {
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
const entityId = resolveHillshadeEntityId(event);
|
|
433
|
+
|
|
434
|
+
// 1. Create texture if original data is provided
|
|
435
|
+
if (event.original_handle !== undefined && event.original_handle !== null) {
|
|
436
|
+
processInitialHillshadeTexture(ctx, event, entityId);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// 2. Update edges if edge data is provided
|
|
440
|
+
if (event.edge_data_handle !== undefined && event.edge_data_handle !== null) {
|
|
441
|
+
processHillshadeEdgeUpdate(ctx, event, entityId);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* TODO: define this function in Rust and use it in web worker
|
|
447
|
+
* Update a padding edge of a padded texture from neighbor edge data
|
|
448
|
+
* @param textureData - The Uint8Array backing the DataTexture (paddedSize×paddedSize×4 bytes)
|
|
449
|
+
* @param edgeBytes - Buffer containing one edge from neighbor (contentSize pixels × 4 bytes RGBA)
|
|
450
|
+
* @param paddedSize - Padded texture size (e.g., 258 for 256×256 content)
|
|
451
|
+
* @param direction - Edge direction: 0=Left, 1=Right, 2=Top, 3=Bottom
|
|
452
|
+
* @internal Exported for testing only
|
|
453
|
+
*/
|
|
454
|
+
export function updatePaddingEdge(
|
|
455
|
+
textureData: Uint8Array,
|
|
456
|
+
edgeBytes: Uint8Array,
|
|
457
|
+
paddedSize: number,
|
|
458
|
+
direction: number,
|
|
459
|
+
): void {
|
|
460
|
+
const contentSize = paddedSize - 2;
|
|
461
|
+
|
|
462
|
+
switch (direction) {
|
|
463
|
+
case 0: // Left padding (x=0)
|
|
464
|
+
for (let y = 0; y < contentSize; y++) {
|
|
465
|
+
const srcIdx = y * 4;
|
|
466
|
+
const dstY = y + 1; // Content starts at y=1
|
|
467
|
+
const dstIdx = (dstY * paddedSize + 0) * 4;
|
|
468
|
+
textureData.set(edgeBytes.subarray(srcIdx, srcIdx + 4), dstIdx);
|
|
469
|
+
}
|
|
470
|
+
break;
|
|
471
|
+
|
|
472
|
+
case 1: // Right padding (x=paddedSize-1)
|
|
473
|
+
for (let y = 0; y < contentSize; y++) {
|
|
474
|
+
const srcIdx = y * 4;
|
|
475
|
+
const dstY = y + 1;
|
|
476
|
+
const dstX = paddedSize - 1;
|
|
477
|
+
const dstIdx = (dstY * paddedSize + dstX) * 4;
|
|
478
|
+
textureData.set(edgeBytes.subarray(srcIdx, srcIdx + 4), dstIdx);
|
|
479
|
+
}
|
|
480
|
+
break;
|
|
481
|
+
|
|
482
|
+
case 2: // Top padding (y=0)
|
|
483
|
+
for (let x = 0; x < contentSize; x++) {
|
|
484
|
+
const srcIdx = x * 4;
|
|
485
|
+
const dstX = x + 1; // Content starts at x=1
|
|
486
|
+
const dstIdx = (0 * paddedSize + dstX) * 4;
|
|
487
|
+
textureData.set(edgeBytes.subarray(srcIdx, srcIdx + 4), dstIdx);
|
|
488
|
+
}
|
|
489
|
+
break;
|
|
490
|
+
|
|
491
|
+
case 3: // Bottom padding (y=paddedSize-1)
|
|
492
|
+
for (let x = 0; x < contentSize; x++) {
|
|
493
|
+
const srcIdx = x * 4;
|
|
494
|
+
const dstX = x + 1;
|
|
495
|
+
const dstY = paddedSize - 1;
|
|
496
|
+
const dstIdx = (dstY * paddedSize + dstX) * 4;
|
|
497
|
+
textureData.set(edgeBytes.subarray(srcIdx, srcIdx + 4), dstIdx);
|
|
498
|
+
}
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* TODO: define this function in Rust and use it in web worker
|
|
505
|
+
* Initialize padding by replicating content edges
|
|
506
|
+
* @param paddedBytes - Padded texture data (paddedSize×paddedSize×4 bytes)
|
|
507
|
+
* @param paddedSize - Padded texture size (e.g., 258)
|
|
508
|
+
* @internal Exported for testing only
|
|
509
|
+
*/
|
|
510
|
+
export function replicateEdgesToPadding(
|
|
511
|
+
paddedBytes: Uint8Array,
|
|
512
|
+
paddedSize: number,
|
|
513
|
+
): void {
|
|
514
|
+
const contentSize = paddedSize - 2;
|
|
515
|
+
|
|
516
|
+
// Top padding (y=0): copy from first content row (y=1)
|
|
517
|
+
for (let x = 1; x <= contentSize; x++) {
|
|
518
|
+
const srcIdx = (1 * paddedSize + x) * 4;
|
|
519
|
+
const dstIdx = (0 * paddedSize + x) * 4;
|
|
520
|
+
paddedBytes[dstIdx] = paddedBytes[srcIdx];
|
|
521
|
+
paddedBytes[dstIdx + 1] = paddedBytes[srcIdx + 1];
|
|
522
|
+
paddedBytes[dstIdx + 2] = paddedBytes[srcIdx + 2];
|
|
523
|
+
paddedBytes[dstIdx + 3] = paddedBytes[srcIdx + 3];
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// Bottom padding (y=paddedSize-1): copy from last content row (y=contentSize)
|
|
527
|
+
for (let x = 1; x <= contentSize; x++) {
|
|
528
|
+
const srcIdx = (contentSize * paddedSize + x) * 4;
|
|
529
|
+
const dstIdx = ((paddedSize - 1) * paddedSize + x) * 4;
|
|
530
|
+
paddedBytes[dstIdx] = paddedBytes[srcIdx];
|
|
531
|
+
paddedBytes[dstIdx + 1] = paddedBytes[srcIdx + 1];
|
|
532
|
+
paddedBytes[dstIdx + 2] = paddedBytes[srcIdx + 2];
|
|
533
|
+
paddedBytes[dstIdx + 3] = paddedBytes[srcIdx + 3];
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// Left padding (x=0): copy from first content column (x=1)
|
|
537
|
+
for (let y = 1; y <= contentSize; y++) {
|
|
538
|
+
const srcIdx = (y * paddedSize + 1) * 4;
|
|
539
|
+
const dstIdx = (y * paddedSize + 0) * 4;
|
|
540
|
+
paddedBytes[dstIdx] = paddedBytes[srcIdx];
|
|
541
|
+
paddedBytes[dstIdx + 1] = paddedBytes[srcIdx + 1];
|
|
542
|
+
paddedBytes[dstIdx + 2] = paddedBytes[srcIdx + 2];
|
|
543
|
+
paddedBytes[dstIdx + 3] = paddedBytes[srcIdx + 3];
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// Right padding (x=paddedSize-1): copy from last content column (x=contentSize)
|
|
547
|
+
for (let y = 1; y <= contentSize; y++) {
|
|
548
|
+
const srcIdx = (y * paddedSize + contentSize) * 4;
|
|
549
|
+
const dstIdx = (y * paddedSize + (paddedSize - 1)) * 4;
|
|
550
|
+
paddedBytes[dstIdx] = paddedBytes[srcIdx];
|
|
551
|
+
paddedBytes[dstIdx + 1] = paddedBytes[srcIdx + 1];
|
|
552
|
+
paddedBytes[dstIdx + 2] = paddedBytes[srcIdx + 2];
|
|
553
|
+
paddedBytes[dstIdx + 3] = paddedBytes[srcIdx + 3];
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// Corners: copy from adjacent content pixels
|
|
557
|
+
// Top-left (0, 0)
|
|
558
|
+
const tlSrcIdx = (1 * paddedSize + 1) * 4;
|
|
559
|
+
const tlDstIdx = 0;
|
|
560
|
+
paddedBytes[tlDstIdx] = paddedBytes[tlSrcIdx];
|
|
561
|
+
paddedBytes[tlDstIdx + 1] = paddedBytes[tlSrcIdx + 1];
|
|
562
|
+
paddedBytes[tlDstIdx + 2] = paddedBytes[tlSrcIdx + 2];
|
|
563
|
+
paddedBytes[tlDstIdx + 3] = paddedBytes[tlSrcIdx + 3];
|
|
564
|
+
|
|
565
|
+
// Top-right (paddedSize-1, 0)
|
|
566
|
+
const trSrcIdx = (1 * paddedSize + contentSize) * 4;
|
|
567
|
+
const trDstIdx = (paddedSize - 1) * 4;
|
|
568
|
+
paddedBytes[trDstIdx] = paddedBytes[trSrcIdx];
|
|
569
|
+
paddedBytes[trDstIdx + 1] = paddedBytes[trSrcIdx + 1];
|
|
570
|
+
paddedBytes[trDstIdx + 2] = paddedBytes[trSrcIdx + 2];
|
|
571
|
+
paddedBytes[trDstIdx + 3] = paddedBytes[trSrcIdx + 3];
|
|
572
|
+
|
|
573
|
+
// Bottom-left (0, paddedSize-1)
|
|
574
|
+
const blSrcIdx = (contentSize * paddedSize + 1) * 4;
|
|
575
|
+
const blDstIdx = (paddedSize - 1) * paddedSize * 4;
|
|
576
|
+
paddedBytes[blDstIdx] = paddedBytes[blSrcIdx];
|
|
577
|
+
paddedBytes[blDstIdx + 1] = paddedBytes[blSrcIdx + 1];
|
|
578
|
+
paddedBytes[blDstIdx + 2] = paddedBytes[blSrcIdx + 2];
|
|
579
|
+
paddedBytes[blDstIdx + 3] = paddedBytes[blSrcIdx + 3];
|
|
580
|
+
|
|
581
|
+
// Bottom-right (paddedSize-1, paddedSize-1)
|
|
582
|
+
const brSrcIdx = (contentSize * paddedSize + contentSize) * 4;
|
|
583
|
+
const brDstIdx = ((paddedSize - 1) * paddedSize + (paddedSize - 1)) * 4;
|
|
584
|
+
paddedBytes[brDstIdx] = paddedBytes[brSrcIdx];
|
|
585
|
+
paddedBytes[brDstIdx + 1] = paddedBytes[brSrcIdx + 1];
|
|
586
|
+
paddedBytes[brDstIdx + 2] = paddedBytes[brSrcIdx + 2];
|
|
587
|
+
paddedBytes[brDstIdx + 3] = paddedBytes[brSrcIdx + 3];
|
|
588
|
+
}
|