@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,177 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
type AtlasImage,
|
|
5
|
+
type AtlasRect,
|
|
6
|
+
BillboardAtlas,
|
|
7
|
+
} from "./billboardAtlas";
|
|
8
|
+
|
|
9
|
+
/** Solid-color RGBA image where every pixel is (r, g, b, 255). */
|
|
10
|
+
const solidImage = (
|
|
11
|
+
width: number,
|
|
12
|
+
height: number,
|
|
13
|
+
r: number,
|
|
14
|
+
g = 0,
|
|
15
|
+
b = 0,
|
|
16
|
+
): AtlasImage => {
|
|
17
|
+
const data = new Uint8Array(width * height * 4);
|
|
18
|
+
for (let i = 0; i < width * height; i++) {
|
|
19
|
+
data[i * 4 + 0] = r;
|
|
20
|
+
data[i * 4 + 1] = g;
|
|
21
|
+
data[i * 4 + 2] = b;
|
|
22
|
+
data[i * 4 + 3] = 255;
|
|
23
|
+
}
|
|
24
|
+
return { width, height, data };
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/** loadImage stub: url "WxH:r" resolves to a solid image of that size/color. */
|
|
28
|
+
const stubLoader = () =>
|
|
29
|
+
vi.fn(async (url: string): Promise<AtlasImage> => {
|
|
30
|
+
const [size, r] = url.split(":");
|
|
31
|
+
const [w, h] = size.split("x").map(Number);
|
|
32
|
+
return solidImage(w, h, Number(r ?? 0));
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const overlaps = (a: AtlasRect, b: AtlasRect) =>
|
|
36
|
+
a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h;
|
|
37
|
+
|
|
38
|
+
/** pack() that fails the test instead of resolving undefined. */
|
|
39
|
+
const mustPack = async (
|
|
40
|
+
atlas: BillboardAtlas,
|
|
41
|
+
url: string,
|
|
42
|
+
): Promise<AtlasRect> => {
|
|
43
|
+
const rect = await atlas.pack(url);
|
|
44
|
+
if (!rect) throw new Error(`pack failed for ${url}`);
|
|
45
|
+
return rect;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
describe("BillboardAtlas", () => {
|
|
49
|
+
it("packs an image and returns its pixel rect", async () => {
|
|
50
|
+
const atlas = new BillboardAtlas({
|
|
51
|
+
initialSize: 64,
|
|
52
|
+
loadImage: stubLoader(),
|
|
53
|
+
});
|
|
54
|
+
const rect = await mustPack(atlas, "16x8:255");
|
|
55
|
+
|
|
56
|
+
expect(rect.w).toBe(16);
|
|
57
|
+
expect(rect.h).toBe(8);
|
|
58
|
+
expect(rect.x + rect.w).toBeLessThanOrEqual(atlas.size);
|
|
59
|
+
expect(rect.y + rect.h).toBeLessThanOrEqual(atlas.size);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("writes the image pixels at the rect position", async () => {
|
|
63
|
+
const atlas = new BillboardAtlas({
|
|
64
|
+
initialSize: 64,
|
|
65
|
+
loadImage: stubLoader(),
|
|
66
|
+
});
|
|
67
|
+
const rect = await mustPack(atlas, "4x4:200");
|
|
68
|
+
|
|
69
|
+
const data = atlas.texture.image.data as Uint8Array;
|
|
70
|
+
// Sample the rect's first and last pixels.
|
|
71
|
+
const first = (rect.y * atlas.size + rect.x) * 4;
|
|
72
|
+
const last = ((rect.y + rect.h - 1) * atlas.size + rect.x + rect.w - 1) * 4;
|
|
73
|
+
expect(data[first]).toBe(200);
|
|
74
|
+
expect(data[first + 3]).toBe(255);
|
|
75
|
+
expect(data[last]).toBe(200);
|
|
76
|
+
// One past the rect horizontally is gutter: untouched (transparent).
|
|
77
|
+
const gutter = (rect.y * atlas.size + rect.x + rect.w) * 4;
|
|
78
|
+
expect(data[gutter + 3]).toBe(0);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("dedupes by URL, including in-flight loads", async () => {
|
|
82
|
+
const loadImage = stubLoader();
|
|
83
|
+
const atlas = new BillboardAtlas({ initialSize: 64, loadImage });
|
|
84
|
+
|
|
85
|
+
const [a, b] = await Promise.all([
|
|
86
|
+
atlas.pack("8x8:1"),
|
|
87
|
+
atlas.pack("8x8:1"),
|
|
88
|
+
]);
|
|
89
|
+
const c = await atlas.pack("8x8:1");
|
|
90
|
+
|
|
91
|
+
expect(loadImage).toHaveBeenCalledTimes(1);
|
|
92
|
+
expect(a).toEqual(b);
|
|
93
|
+
expect(a).toEqual(c);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("packs distinct images into non-overlapping rects", async () => {
|
|
97
|
+
const atlas = new BillboardAtlas({
|
|
98
|
+
initialSize: 64,
|
|
99
|
+
loadImage: stubLoader(),
|
|
100
|
+
});
|
|
101
|
+
const rects = await Promise.all([
|
|
102
|
+
mustPack(atlas, "16x16:1"),
|
|
103
|
+
mustPack(atlas, "8x4:2"),
|
|
104
|
+
mustPack(atlas, "20x12:3"),
|
|
105
|
+
mustPack(atlas, "3x30:4"),
|
|
106
|
+
]);
|
|
107
|
+
|
|
108
|
+
for (let i = 0; i < rects.length; i++) {
|
|
109
|
+
for (let j = i + 1; j < rects.length; j++) {
|
|
110
|
+
expect(overlaps(rects[i], rects[j])).toBe(false);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("grows when full and keeps existing rects and pixels valid", async () => {
|
|
116
|
+
const atlas = new BillboardAtlas({
|
|
117
|
+
initialSize: 16,
|
|
118
|
+
maxSize: 64,
|
|
119
|
+
loadImage: stubLoader(),
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const small = await mustPack(atlas, "8x8:11");
|
|
123
|
+
const initialTexture = atlas.texture;
|
|
124
|
+
expect(atlas.size).toBe(16);
|
|
125
|
+
|
|
126
|
+
// Doesn't fit in the remaining 16x16 space: forces growth.
|
|
127
|
+
const big = await mustPack(atlas, "20x20:22");
|
|
128
|
+
|
|
129
|
+
expect(atlas.size).toBeGreaterThan(16);
|
|
130
|
+
expect(atlas.texture).not.toBe(initialTexture);
|
|
131
|
+
expect(overlaps(small, big)).toBe(false);
|
|
132
|
+
|
|
133
|
+
// The first image's pixels survived the copy into the larger buffer.
|
|
134
|
+
const data = atlas.texture.image.data as Uint8Array;
|
|
135
|
+
const first = (small.y * atlas.size + small.x) * 4;
|
|
136
|
+
expect(data[first]).toBe(11);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("returns undefined when an image cannot fit even at maxSize", async () => {
|
|
140
|
+
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
141
|
+
const atlas = new BillboardAtlas({
|
|
142
|
+
initialSize: 16,
|
|
143
|
+
maxSize: 32,
|
|
144
|
+
loadImage: stubLoader(),
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
expect(await atlas.pack("64x64:0")).toBeUndefined();
|
|
148
|
+
warn.mockRestore();
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("reports its footprint as CPU buffer + GPU texture and tracks growth", async () => {
|
|
152
|
+
const atlas = new BillboardAtlas({
|
|
153
|
+
initialSize: 16,
|
|
154
|
+
maxSize: 64,
|
|
155
|
+
loadImage: stubLoader(),
|
|
156
|
+
});
|
|
157
|
+
// 16×16 RGBA, twice (CPU pixel buffer + GPU copy).
|
|
158
|
+
expect(atlas.byteLength).toBe(16 * 16 * 4 * 2);
|
|
159
|
+
|
|
160
|
+
// Forces growth to 32 (20+gutter doesn't fit in 16).
|
|
161
|
+
await mustPack(atlas, "20x20:0");
|
|
162
|
+
expect(atlas.byteLength).toBe(32 * 32 * 4 * 2);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("caches failed loads and resolves them as undefined", async () => {
|
|
166
|
+
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
167
|
+
const loadImage = vi.fn(async (): Promise<AtlasImage> => {
|
|
168
|
+
throw new Error("404");
|
|
169
|
+
});
|
|
170
|
+
const atlas = new BillboardAtlas({ initialSize: 16, loadImage });
|
|
171
|
+
|
|
172
|
+
expect(await atlas.pack("bad")).toBeUndefined();
|
|
173
|
+
expect(await atlas.pack("bad")).toBeUndefined();
|
|
174
|
+
expect(loadImage).toHaveBeenCalledTimes(1);
|
|
175
|
+
warn.mockRestore();
|
|
176
|
+
});
|
|
177
|
+
});
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { DataTexture, LinearFilter, RGBAFormat, UnsignedByteType } from "three";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Sub-rectangle of the atlas in pixels. Row 0 is the bottom of the texture
|
|
5
|
+
* (v = 0), matching the flipY applied at decode time. Rects are stored in
|
|
6
|
+
* pixel space and normalized by `uAtlasSize` in the shader, so they stay
|
|
7
|
+
* valid when the atlas grows.
|
|
8
|
+
*/
|
|
9
|
+
export type AtlasRect = {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
w: number;
|
|
13
|
+
h: number;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type AtlasImage = {
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
/** RGBA, tightly packed, row 0 = bottom of the image (flipY at decode). */
|
|
20
|
+
data: Uint8Array;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type LoadAtlasImage = (url: string) => Promise<AtlasImage>;
|
|
24
|
+
|
|
25
|
+
export type BillboardAtlasOptions = {
|
|
26
|
+
initialSize?: number;
|
|
27
|
+
maxSize?: number;
|
|
28
|
+
/**
|
|
29
|
+
* How to fetch and decode a URL into RGBA pixels. Kept injectable (and out
|
|
30
|
+
* of this module) so the atlas has no browser/worker dependencies — use
|
|
31
|
+
* `loadAtlasImageFromUrl` from `billboardAtlasImageLoader` in the app.
|
|
32
|
+
*/
|
|
33
|
+
loadImage: LoadAtlasImage;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** Spacing between entries so LinearFilter sampling never bleeds neighbors. */
|
|
37
|
+
const GUTTER = 1;
|
|
38
|
+
const DEFAULT_INITIAL_SIZE = 256;
|
|
39
|
+
// Conservative floor of WebGL2 MAX_TEXTURE_SIZE across devices.
|
|
40
|
+
const DEFAULT_MAX_SIZE = 4096;
|
|
41
|
+
|
|
42
|
+
type Shelf = {
|
|
43
|
+
y: number;
|
|
44
|
+
height: number;
|
|
45
|
+
/** Horizontal cursor: next free x within this shelf. */
|
|
46
|
+
x: number;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* A texture atlas for billboard images: packs arbitrarily sized images into a
|
|
51
|
+
* single square RGBA `DataTexture` with a shelf allocator, deduplicating loads
|
|
52
|
+
* by URL (including in-flight ones — the promise itself is cached).
|
|
53
|
+
*
|
|
54
|
+
* The atlas grows by doubling up to `maxSize`. Growth preserves the layout, so
|
|
55
|
+
* previously returned rects remain valid; only the texture object is replaced
|
|
56
|
+
* (a `DataTexture` cannot be resized in place). Callers must re-read `texture`
|
|
57
|
+
* and `size` after every `pack()` and re-sync their uniforms.
|
|
58
|
+
*
|
|
59
|
+
* Failed loads are cached as `undefined` so a bad URL shared by many features
|
|
60
|
+
* is fetched once, not once per feature.
|
|
61
|
+
*/
|
|
62
|
+
export class BillboardAtlas {
|
|
63
|
+
private _size: number;
|
|
64
|
+
private readonly _maxSize: number;
|
|
65
|
+
private _data: Uint8Array;
|
|
66
|
+
private _texture: DataTexture;
|
|
67
|
+
private _shelves: Shelf[] = [];
|
|
68
|
+
private _nextShelfY = 0;
|
|
69
|
+
private readonly _rects = new Map<string, Promise<AtlasRect | undefined>>();
|
|
70
|
+
private readonly _loadImage: LoadAtlasImage;
|
|
71
|
+
|
|
72
|
+
constructor(options: BillboardAtlasOptions) {
|
|
73
|
+
this._size = options.initialSize ?? DEFAULT_INITIAL_SIZE;
|
|
74
|
+
this._maxSize = options.maxSize ?? DEFAULT_MAX_SIZE;
|
|
75
|
+
this._loadImage = options.loadImage;
|
|
76
|
+
this._data = new Uint8Array(this._size * this._size * 4);
|
|
77
|
+
this._texture = this._createTexture();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
get texture(): DataTexture {
|
|
81
|
+
return this._texture;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Current atlas edge length in pixels (the atlas is always square). */
|
|
85
|
+
get size(): number {
|
|
86
|
+
return this._size;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Memory footprint of the atlas in bytes: the CPU pixel buffer (kept
|
|
91
|
+
* resident for growth re-blits and `needsUpdate` re-uploads) plus the
|
|
92
|
+
* equal-sized GPU copy held by the `DataTexture` (RGBA8, no mipmaps).
|
|
93
|
+
*/
|
|
94
|
+
get byteLength(): number {
|
|
95
|
+
return this._data.byteLength * 2;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Load `url` (once) and pack it into the atlas.
|
|
100
|
+
* Resolves to the entry's pixel rect, or `undefined` when the image fails
|
|
101
|
+
* to load or the atlas is full even at `maxSize`.
|
|
102
|
+
*/
|
|
103
|
+
pack(url: string): Promise<AtlasRect | undefined> {
|
|
104
|
+
const cached = this._rects.get(url);
|
|
105
|
+
if (cached) return cached;
|
|
106
|
+
|
|
107
|
+
const pending = this._loadAndPack(url).catch((error) => {
|
|
108
|
+
console.warn(`BillboardAtlas: failed to load image "${url}"`, error);
|
|
109
|
+
return undefined;
|
|
110
|
+
});
|
|
111
|
+
this._rects.set(url, pending);
|
|
112
|
+
return pending;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
dispose(): void {
|
|
116
|
+
this._texture.dispose();
|
|
117
|
+
this._rects.clear();
|
|
118
|
+
this._shelves = [];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private async _loadAndPack(url: string): Promise<AtlasRect | undefined> {
|
|
122
|
+
const image = await this._loadImage(url);
|
|
123
|
+
const rect = this._allocate(image.width, image.height);
|
|
124
|
+
if (!rect) {
|
|
125
|
+
console.warn(
|
|
126
|
+
`BillboardAtlas: no space for "${url}" (${image.width}x${image.height}) at max atlas size ${this._maxSize}`,
|
|
127
|
+
);
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
this._blit(image, rect);
|
|
131
|
+
return rect;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private _allocate(w: number, h: number): AtlasRect | undefined {
|
|
135
|
+
for (;;) {
|
|
136
|
+
const rect = this._tryAllocate(w, h);
|
|
137
|
+
if (rect) return rect;
|
|
138
|
+
if (!this._grow()) return undefined;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private _tryAllocate(w: number, h: number): AtlasRect | undefined {
|
|
143
|
+
const needW = w + GUTTER;
|
|
144
|
+
const needH = h + GUTTER;
|
|
145
|
+
if (needW > this._size) return undefined;
|
|
146
|
+
|
|
147
|
+
// Best-fit shelf: the shortest existing shelf that still fits the entry.
|
|
148
|
+
let best: Shelf | undefined;
|
|
149
|
+
for (const shelf of this._shelves) {
|
|
150
|
+
if (needH > shelf.height || shelf.x + needW > this._size) continue;
|
|
151
|
+
if (!best || shelf.height < best.height) best = shelf;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (!best && this._nextShelfY + needH <= this._size) {
|
|
155
|
+
best = { y: this._nextShelfY, height: needH, x: 0 };
|
|
156
|
+
this._shelves.push(best);
|
|
157
|
+
this._nextShelfY += needH;
|
|
158
|
+
}
|
|
159
|
+
if (!best) return undefined;
|
|
160
|
+
|
|
161
|
+
const rect = { x: best.x, y: best.y, w, h };
|
|
162
|
+
best.x += needW;
|
|
163
|
+
return rect;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Double the atlas edge, preserving the existing layout: old pixel rows are
|
|
168
|
+
* copied into the wider buffer, shelves keep their y/height and simply gain
|
|
169
|
+
* free space to the right, and new shelves can open below `_nextShelfY`.
|
|
170
|
+
*/
|
|
171
|
+
private _grow(): boolean {
|
|
172
|
+
const newSize = this._size * 2;
|
|
173
|
+
if (newSize > this._maxSize) return false;
|
|
174
|
+
|
|
175
|
+
const newData = new Uint8Array(newSize * newSize * 4);
|
|
176
|
+
for (let row = 0; row < this._size; row++) {
|
|
177
|
+
newData.set(
|
|
178
|
+
this._data.subarray(row * this._size * 4, (row + 1) * this._size * 4),
|
|
179
|
+
row * newSize * 4,
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
this._size = newSize;
|
|
184
|
+
this._data = newData;
|
|
185
|
+
this._texture.dispose();
|
|
186
|
+
this._texture = this._createTexture();
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
private _blit(image: AtlasImage, rect: AtlasRect): void {
|
|
191
|
+
for (let row = 0; row < rect.h; row++) {
|
|
192
|
+
this._data.set(
|
|
193
|
+
image.data.subarray(row * rect.w * 4, (row + 1) * rect.w * 4),
|
|
194
|
+
((rect.y + row) * this._size + rect.x) * 4,
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
this._texture.needsUpdate = true;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private _createTexture(): DataTexture {
|
|
201
|
+
const texture = new DataTexture(this._data, this._size, this._size);
|
|
202
|
+
texture.format = RGBAFormat;
|
|
203
|
+
texture.type = UnsignedByteType;
|
|
204
|
+
texture.minFilter = LinearFilter;
|
|
205
|
+
texture.magFilter = LinearFilter;
|
|
206
|
+
texture.generateMipmaps = false;
|
|
207
|
+
texture.needsUpdate = true;
|
|
208
|
+
return texture;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { TEXTURE_LOADER } from "../../event/loaders";
|
|
2
|
+
import { getImageDataFromImageBitmap } from "../../tasks/getImageDataFromImageBitmap";
|
|
3
|
+
|
|
4
|
+
import type { LoadAtlasImage } from "./billboardAtlas";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Browser decode pipeline for `BillboardAtlas`: fetch via the shared texture
|
|
8
|
+
* loader, rasterize to RGBA off the main thread. Lives outside billboardAtlas
|
|
9
|
+
* so the atlas itself stays importable in worker-free environments (tests).
|
|
10
|
+
*
|
|
11
|
+
* flipY at decode matches the previous DataArrayTexture path: row 0 of the
|
|
12
|
+
* pixel data is the bottom of the image, i.e. v = 0 in the atlas texture.
|
|
13
|
+
*/
|
|
14
|
+
export const loadAtlasImageFromUrl: LoadAtlasImage = async (url) => {
|
|
15
|
+
const texture = await TEXTURE_LOADER.loadAsync(url);
|
|
16
|
+
try {
|
|
17
|
+
const img = texture.image as HTMLImageElement | ImageBitmap;
|
|
18
|
+
const width = img.width;
|
|
19
|
+
const height = img.height;
|
|
20
|
+
|
|
21
|
+
const data = await getImageDataFromImageBitmap(
|
|
22
|
+
await createImageBitmap(img, { imageOrientation: "flipY" }),
|
|
23
|
+
new OffscreenCanvas(width, height),
|
|
24
|
+
);
|
|
25
|
+
return { width, height, data: new Uint8Array(data) };
|
|
26
|
+
} finally {
|
|
27
|
+
texture.dispose();
|
|
28
|
+
}
|
|
29
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./instancedSprite";
|