@sakuzu/maplibre-gl-draw 1.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/CHANGELOG.md +43 -0
- package/LICENSE +661 -0
- package/README.ja.md +248 -0
- package/README.md +255 -0
- package/THIRD_PARTY_NOTICES.md +275 -0
- package/dist/api/api.d.ts +1259 -0
- package/dist/api/api.js +86 -0
- package/dist/api/context.d.ts +173 -0
- package/dist/api/context.js +193 -0
- package/dist/api/display-api.d.ts +1 -0
- package/dist/api/display-api.js +23 -0
- package/dist/api/event-api.d.ts +13 -0
- package/dist/api/event-api.js +17 -0
- package/dist/api/extension-api.d.ts +46 -0
- package/dist/api/extension-api.js +85 -0
- package/dist/api/feature-api.d.ts +11 -0
- package/dist/api/feature-api.js +101 -0
- package/dist/api/geometry/apply.d.ts +51 -0
- package/dist/api/geometry/apply.js +114 -0
- package/dist/api/geometry/boolean.d.ts +28 -0
- package/dist/api/geometry/boolean.js +65 -0
- package/dist/api/geometry/buffer.d.ts +11 -0
- package/dist/api/geometry/buffer.js +105 -0
- package/dist/api/geometry/split.d.ts +16 -0
- package/dist/api/geometry/split.js +75 -0
- package/dist/api/geometry/targets.d.ts +76 -0
- package/dist/api/geometry/targets.js +158 -0
- package/dist/api/geometry/types.d.ts +31 -0
- package/dist/api/geometry/types.js +3 -0
- package/dist/api/geometry-operations.d.ts +162 -0
- package/dist/api/geometry-operations.js +94 -0
- package/dist/api/group-api.d.ts +10 -0
- package/dist/api/group-api.js +78 -0
- package/dist/api/import-export/constants.d.ts +29 -0
- package/dist/api/import-export/constants.js +40 -0
- package/dist/api/import-export/embedded-file.d.ts +13 -0
- package/dist/api/import-export/embedded-file.js +31 -0
- package/dist/api/import-export/file-name.d.ts +10 -0
- package/dist/api/import-export/file-name.js +20 -0
- package/dist/api/import-export/format-detection.d.ts +12 -0
- package/dist/api/import-export/format-detection.js +29 -0
- package/dist/api/import-export/geojson-export.d.ts +19 -0
- package/dist/api/import-export/geojson-export.js +262 -0
- package/dist/api/import-export/geojson-import.d.ts +34 -0
- package/dist/api/import-export/geojson-import.js +538 -0
- package/dist/api/import-export/geometry-validation.d.ts +20 -0
- package/dist/api/import-export/geometry-validation.js +107 -0
- package/dist/api/import-export/image-import.d.ts +12 -0
- package/dist/api/import-export/image-import.js +53 -0
- package/dist/api/import-export/index.d.ts +9 -0
- package/dist/api/import-export/index.js +107 -0
- package/dist/api/import-export/native-format.d.ts +15 -0
- package/dist/api/import-export/native-format.js +126 -0
- package/dist/api/import-export/native-validation.d.ts +28 -0
- package/dist/api/import-export/native-validation.js +212 -0
- package/dist/api/import-export/own-property.d.ts +10 -0
- package/dist/api/import-export/own-property.js +19 -0
- package/dist/api/import-export/style-validation.d.ts +27 -0
- package/dist/api/import-export/style-validation.js +49 -0
- package/dist/api/import-export/types.d.ts +26 -0
- package/dist/api/import-export/types.js +3 -0
- package/dist/api/index.d.ts +15 -0
- package/dist/api/index.js +3 -0
- package/dist/api/input-api.d.ts +158 -0
- package/dist/api/input-api.js +144 -0
- package/dist/api/instance-api.d.ts +38 -0
- package/dist/api/instance-api.js +136 -0
- package/dist/api/layer-api.d.ts +12 -0
- package/dist/api/layer-api.js +62 -0
- package/dist/api/selection-api.d.ts +7 -0
- package/dist/api/selection-api.js +78 -0
- package/dist/api/snapping-api.d.ts +125 -0
- package/dist/api/snapping-api.js +50 -0
- package/dist/api/topology-api.d.ts +30 -0
- package/dist/api/topology-api.js +16 -0
- package/dist/api/tracing-api.d.ts +31 -0
- package/dist/api/tracing-api.js +16 -0
- package/dist/dispatcher/hit-test/box-strategies.d.ts +19 -0
- package/dist/dispatcher/hit-test/box-strategies.js +275 -0
- package/dist/dispatcher/hit-test/box-strategy.d.ts +59 -0
- package/dist/dispatcher/hit-test/box-strategy.js +37 -0
- package/dist/dispatcher/hit-test/globe-shape.d.ts +46 -0
- package/dist/dispatcher/hit-test/globe-shape.js +70 -0
- package/dist/dispatcher/hit-test/index.d.ts +14 -0
- package/dist/dispatcher/hit-test/index.js +9 -0
- package/dist/dispatcher/hit-test/local-frame.d.ts +77 -0
- package/dist/dispatcher/hit-test/local-frame.js +112 -0
- package/dist/dispatcher/hit-test/segment-grid.d.ts +32 -0
- package/dist/dispatcher/hit-test/segment-grid.js +79 -0
- package/dist/dispatcher/hit-test/service.d.ts +120 -0
- package/dist/dispatcher/hit-test/service.js +333 -0
- package/dist/dispatcher/hit-test/strategies/base.d.ts +136 -0
- package/dist/dispatcher/hit-test/strategies/base.js +66 -0
- package/dist/dispatcher/hit-test/strategies/circle.d.ts +10 -0
- package/dist/dispatcher/hit-test/strategies/circle.js +56 -0
- package/dist/dispatcher/hit-test/strategies/image.d.ts +22 -0
- package/dist/dispatcher/hit-test/strategies/image.js +115 -0
- package/dist/dispatcher/hit-test/strategies/index.d.ts +11 -0
- package/dist/dispatcher/hit-test/strategies/index.js +10 -0
- package/dist/dispatcher/hit-test/strategies/line.d.ts +17 -0
- package/dist/dispatcher/hit-test/strategies/line.js +30 -0
- package/dist/dispatcher/hit-test/strategies/multi.d.ts +44 -0
- package/dist/dispatcher/hit-test/strategies/multi.js +141 -0
- package/dist/dispatcher/hit-test/strategies/point.d.ts +20 -0
- package/dist/dispatcher/hit-test/strategies/point.js +29 -0
- package/dist/dispatcher/hit-test/strategies/polygon.d.ts +52 -0
- package/dist/dispatcher/hit-test/strategies/polygon.js +138 -0
- package/dist/dispatcher/hit-test/topmost.d.ts +48 -0
- package/dist/dispatcher/hit-test/topmost.js +157 -0
- package/dist/dispatcher/hit-test/visibility-lookup.d.ts +23 -0
- package/dist/dispatcher/hit-test/visibility-lookup.js +40 -0
- package/dist/dispatcher/index.d.ts +15 -0
- package/dist/dispatcher/index.js +3 -0
- package/dist/dispatcher/input-router.d.ts +1 -0
- package/dist/dispatcher/input-router.js +288 -0
- package/dist/dispatcher/normalizer.d.ts +1 -0
- package/dist/dispatcher/normalizer.js +513 -0
- package/dist/dispatcher/types.d.ts +144 -0
- package/dist/dispatcher/types.js +15 -0
- package/dist/display/chunk-set.d.ts +24 -0
- package/dist/display/chunk-set.js +533 -0
- package/dist/display/chunk.d.ts +1 -0
- package/dist/display/chunk.js +104 -0
- package/dist/display/columnar/index.d.ts +12 -0
- package/dist/display/columnar/index.js +13 -0
- package/dist/display/columnar/prepare.d.ts +42 -0
- package/dist/display/columnar/prepare.js +116 -0
- package/dist/display/columnar/source.d.ts +1 -0
- package/dist/display/columnar/source.js +531 -0
- package/dist/display/columnar/table.d.ts +1 -0
- package/dist/display/columnar/table.js +471 -0
- package/dist/display/columnar/types.d.ts +223 -0
- package/dist/display/columnar/types.js +3 -0
- package/dist/display/dataset.d.ts +2 -0
- package/dist/display/dataset.js +891 -0
- package/dist/display/index.d.ts +13 -0
- package/dist/display/index.js +3 -0
- package/dist/display/interaction.d.ts +1 -0
- package/dist/display/interaction.js +90 -0
- package/dist/display/manager.d.ts +1 -0
- package/dist/display/manager.js +440 -0
- package/dist/display/packed-rtree.d.ts +1 -0
- package/dist/display/packed-rtree.js +244 -0
- package/dist/display/partition.d.ts +1 -0
- package/dist/display/partition.js +226 -0
- package/dist/display/provider.d.ts +1 -0
- package/dist/display/provider.js +342 -0
- package/dist/display/retained.d.ts +40 -0
- package/dist/display/retained.js +898 -0
- package/dist/display/selection.d.ts +13 -0
- package/dist/display/selection.js +226 -0
- package/dist/display/source.d.ts +1 -0
- package/dist/display/source.js +119 -0
- package/dist/display/spatial.d.ts +1 -0
- package/dist/display/spatial.js +71 -0
- package/dist/display/style.d.ts +1 -0
- package/dist/display/style.js +126 -0
- package/dist/display/thinning.d.ts +65 -0
- package/dist/display/thinning.js +910 -0
- package/dist/display/triangulation.d.ts +1 -0
- package/dist/display/triangulation.js +0 -0
- package/dist/display/types.d.ts +561 -0
- package/dist/display/types.js +43 -0
- package/dist/extension/feature-handler.d.ts +182 -0
- package/dist/extension/feature-handler.js +3 -0
- package/dist/extension/index.d.ts +9 -0
- package/dist/extension/index.js +3 -0
- package/dist/extension/renderers.d.ts +208 -0
- package/dist/extension/renderers.js +3 -0
- package/dist/geometry/angle.d.ts +47 -0
- package/dist/geometry/angle.js +44 -0
- package/dist/geometry/bbox.d.ts +48 -0
- package/dist/geometry/bbox.js +83 -0
- package/dist/geometry/boolean.d.ts +162 -0
- package/dist/geometry/boolean.js +331 -0
- package/dist/geometry/buffer.d.ts +72 -0
- package/dist/geometry/buffer.js +218 -0
- package/dist/geometry/circle.d.ts +55 -0
- package/dist/geometry/circle.js +107 -0
- package/dist/geometry/coords.d.ts +97 -0
- package/dist/geometry/coords.js +149 -0
- package/dist/geometry/distance.d.ts +79 -0
- package/dist/geometry/distance.js +111 -0
- package/dist/geometry/errors.d.ts +74 -0
- package/dist/geometry/errors.js +104 -0
- package/dist/geometry/index.d.ts +28 -0
- package/dist/geometry/index.js +38 -0
- package/dist/geometry/measure.d.ts +81 -0
- package/dist/geometry/measure.js +236 -0
- package/dist/geometry/predicates.d.ts +62 -0
- package/dist/geometry/predicates.js +132 -0
- package/dist/geometry/simplify.d.ts +74 -0
- package/dist/geometry/simplify.js +159 -0
- package/dist/geometry/split.d.ts +68 -0
- package/dist/geometry/split.js +430 -0
- package/dist/geometry/types.d.ts +95 -0
- package/dist/geometry/types.js +3 -0
- package/dist/geometry/units.d.ts +35 -0
- package/dist/geometry/units.js +41 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.js +20 -0
- package/dist/maplibre-gl-draw.d.ts +47 -0
- package/dist/maplibre-gl-draw.js +407 -0
- package/dist/messages.d.ts +64 -0
- package/dist/messages.js +36 -0
- package/dist/modes/cursor.d.ts +1 -0
- package/dist/modes/cursor.js +72 -0
- package/dist/modes/draw/circle.d.ts +1 -0
- package/dist/modes/draw/circle.js +222 -0
- package/dist/modes/draw/commit-layer.d.ts +26 -0
- package/dist/modes/draw/commit-layer.js +31 -0
- package/dist/modes/draw/freehand.d.ts +1 -0
- package/dist/modes/draw/freehand.js +264 -0
- package/dist/modes/draw/image.d.ts +1 -0
- package/dist/modes/draw/image.js +60 -0
- package/dist/modes/draw/index.d.ts +9 -0
- package/dist/modes/draw/index.js +11 -0
- package/dist/modes/draw/line.d.ts +1 -0
- package/dist/modes/draw/line.js +363 -0
- package/dist/modes/draw/point.d.ts +1 -0
- package/dist/modes/draw/point.js +87 -0
- package/dist/modes/draw/polygon.d.ts +1 -0
- package/dist/modes/draw/polygon.js +378 -0
- package/dist/modes/draw/trace-support.d.ts +79 -0
- package/dist/modes/draw/trace-support.js +161 -0
- package/dist/modes/handler.d.ts +285 -0
- package/dist/modes/handler.js +3 -0
- package/dist/modes/index.d.ts +7 -0
- package/dist/modes/index.js +3 -0
- package/dist/modes/manager.d.ts +15 -0
- package/dist/modes/manager.js +196 -0
- package/dist/modes/select/box-selection.d.ts +52 -0
- package/dist/modes/select/box-selection.js +140 -0
- package/dist/modes/select/click-handler.d.ts +32 -0
- package/dist/modes/select/click-handler.js +166 -0
- package/dist/modes/select/cursor-handler.d.ts +15 -0
- package/dist/modes/select/cursor-handler.js +59 -0
- package/dist/modes/select/drag/auxiliary.d.ts +26 -0
- package/dist/modes/select/drag/auxiliary.js +56 -0
- package/dist/modes/select/drag/intermediate-writes.d.ts +1 -0
- package/dist/modes/select/drag/intermediate-writes.js +171 -0
- package/dist/modes/select/drag/move.d.ts +24 -0
- package/dist/modes/select/drag/move.js +59 -0
- package/dist/modes/select/drag/operation.d.ts +30 -0
- package/dist/modes/select/drag/operation.js +18 -0
- package/dist/modes/select/drag/radius.d.ts +15 -0
- package/dist/modes/select/drag/radius.js +49 -0
- package/dist/modes/select/drag/transform.d.ts +17 -0
- package/dist/modes/select/drag/transform.js +155 -0
- package/dist/modes/select/drag/vertex.d.ts +17 -0
- package/dist/modes/select/drag/vertex.js +163 -0
- package/dist/modes/select/drag-handler.d.ts +1 -0
- package/dist/modes/select/drag-handler.js +254 -0
- package/dist/modes/select/hit-helpers.d.ts +40 -0
- package/dist/modes/select/hit-helpers.js +51 -0
- package/dist/modes/select/mode.d.ts +1 -0
- package/dist/modes/select/mode.js +397 -0
- package/dist/modes/select/shortcut-handler.d.ts +40 -0
- package/dist/modes/select/shortcut-handler.js +128 -0
- package/dist/operations/index.d.ts +9 -0
- package/dist/operations/index.js +3 -0
- package/dist/operations/layer-operations.d.ts +1 -0
- package/dist/operations/layer-operations.js +350 -0
- package/dist/operations/resize.d.ts +71 -0
- package/dist/operations/resize.js +252 -0
- package/dist/operations/rotate.d.ts +17 -0
- package/dist/operations/rotate.js +166 -0
- package/dist/operations/selection-operations.d.ts +20 -0
- package/dist/operations/selection-operations.js +159 -0
- package/dist/operations/shared-vertex.d.ts +1 -0
- package/dist/operations/shared-vertex.js +210 -0
- package/dist/operations/trace-graph.d.ts +96 -0
- package/dist/operations/trace-graph.js +283 -0
- package/dist/operations/vertex.d.ts +1 -0
- package/dist/operations/vertex.js +538 -0
- package/dist/plugins/index.d.ts +10 -0
- package/dist/plugins/index.js +3 -0
- package/dist/plugins/mutation-hooks.d.ts +28 -0
- package/dist/plugins/mutation-hooks.js +84 -0
- package/dist/plugins/plugin-context.d.ts +1 -0
- package/dist/plugins/plugin-context.js +367 -0
- package/dist/plugins/plugin-manager.d.ts +103 -0
- package/dist/plugins/plugin-manager.js +316 -0
- package/dist/plugins/plugin.d.ts +529 -0
- package/dist/plugins/plugin.js +3 -0
- package/dist/shared/config/constants.d.ts +66 -0
- package/dist/shared/config/constants.js +60 -0
- package/dist/shared/config/feature-style.d.ts +155 -0
- package/dist/shared/config/feature-style.js +154 -0
- package/dist/shared/config/index.d.ts +17 -0
- package/dist/shared/config/index.js +8 -0
- package/dist/shared/config/rendering.d.ts +107 -0
- package/dist/shared/config/rendering.js +33 -0
- package/dist/shared/config/selection-highlight.d.ts +29 -0
- package/dist/shared/config/selection-highlight.js +35 -0
- package/dist/shared/config/selection.d.ts +273 -0
- package/dist/shared/config/selection.js +266 -0
- package/dist/shared/config/topology.d.ts +33 -0
- package/dist/shared/config/topology.js +17 -0
- package/dist/shared/config/trace.d.ts +40 -0
- package/dist/shared/config/trace.js +17 -0
- package/dist/shared/math/angle.d.ts +21 -0
- package/dist/shared/math/angle.js +34 -0
- package/dist/shared/math/circle.d.ts +6 -0
- package/dist/shared/math/circle.js +10 -0
- package/dist/shared/math/constants.d.ts +48 -0
- package/dist/shared/math/constants.js +59 -0
- package/dist/shared/math/distance.d.ts +78 -0
- package/dist/shared/math/distance.js +147 -0
- package/dist/shared/math/globe-subdivision.d.ts +62 -0
- package/dist/shared/math/globe-subdivision.js +99 -0
- package/dist/shared/math/index.d.ts +17 -0
- package/dist/shared/math/index.js +21 -0
- package/dist/shared/math/intersection.d.ts +63 -0
- package/dist/shared/math/intersection.js +236 -0
- package/dist/shared/math/longitude.d.ts +20 -0
- package/dist/shared/math/longitude.js +31 -0
- package/dist/shared/math/mercator-plane.d.ts +27 -0
- package/dist/shared/math/mercator-plane.js +26 -0
- package/dist/shared/math/obb.d.ts +65 -0
- package/dist/shared/math/obb.js +107 -0
- package/dist/shared/math/rotation.d.ts +93 -0
- package/dist/shared/math/rotation.js +186 -0
- package/dist/shared/math/segment-grid.d.ts +69 -0
- package/dist/shared/math/segment-grid.js +159 -0
- package/dist/shared/math/transform.d.ts +140 -0
- package/dist/shared/math/transform.js +189 -0
- package/dist/shared/types/events.d.ts +128 -0
- package/dist/shared/types/events.js +3 -0
- package/dist/shared/types/model.d.ts +950 -0
- package/dist/shared/types/model.js +3 -0
- package/dist/shared/types/selection-box.d.ts +23 -0
- package/dist/shared/types/selection-box.js +3 -0
- package/dist/shared/types/style.d.ts +68 -0
- package/dist/shared/types/style.js +3 -0
- package/dist/shared/utils/color.d.ts +49 -0
- package/dist/shared/utils/color.js +180 -0
- package/dist/shared/utils/coordinates.d.ts +52 -0
- package/dist/shared/utils/coordinates.js +75 -0
- package/dist/shared/utils/embedded-image.d.ts +34 -0
- package/dist/shared/utils/embedded-image.js +161 -0
- package/dist/shared/utils/event-emitter.d.ts +262 -0
- package/dist/shared/utils/event-emitter.js +44 -0
- package/dist/shared/utils/feature-bbox.d.ts +8 -0
- package/dist/shared/utils/feature-bbox.js +207 -0
- package/dist/shared/utils/feature-segments.d.ts +23 -0
- package/dist/shared/utils/feature-segments.js +179 -0
- package/dist/shared/utils/id.d.ts +1 -0
- package/dist/shared/utils/id.js +35 -0
- package/dist/shared/utils/image.d.ts +34 -0
- package/dist/shared/utils/image.js +106 -0
- package/dist/shared/utils/index.d.ts +15 -0
- package/dist/shared/utils/index.js +24 -0
- package/dist/shared/utils/map.d.ts +26 -0
- package/dist/shared/utils/map.js +35 -0
- package/dist/shared/utils/name-generator.d.ts +197 -0
- package/dist/shared/utils/name-generator.js +337 -0
- package/dist/shared/utils/pixel-ratio.d.ts +111 -0
- package/dist/shared/utils/pixel-ratio.js +85 -0
- package/dist/shared/utils/property.d.ts +88 -0
- package/dist/shared/utils/property.js +140 -0
- package/dist/shared/utils/vertex-ref.d.ts +23 -0
- package/dist/shared/utils/vertex-ref.js +20 -0
- package/dist/snapping/custom-targets.d.ts +1 -0
- package/dist/snapping/custom-targets.js +21 -0
- package/dist/snapping/geometry.d.ts +1 -0
- package/dist/snapping/geometry.js +61 -0
- package/dist/snapping/index.d.ts +14 -0
- package/dist/snapping/index.js +4 -0
- package/dist/snapping/indicator.d.ts +19 -0
- package/dist/snapping/indicator.js +145 -0
- package/dist/snapping/providers/display.d.ts +72 -0
- package/dist/snapping/providers/display.js +268 -0
- package/dist/snapping/providers/guide.d.ts +69 -0
- package/dist/snapping/providers/guide.js +187 -0
- package/dist/snapping/providers/intersection.d.ts +1 -0
- package/dist/snapping/providers/intersection.js +92 -0
- package/dist/snapping/providers/shared.d.ts +39 -0
- package/dist/snapping/providers/shared.js +146 -0
- package/dist/snapping/providers/store.d.ts +1 -0
- package/dist/snapping/providers/store.js +132 -0
- package/dist/snapping/service.d.ts +1 -0
- package/dist/snapping/service.js +272 -0
- package/dist/snapping/types.d.ts +267 -0
- package/dist/snapping/types.js +66 -0
- package/dist/store/change-merger.d.ts +1 -0
- package/dist/store/change-merger.js +102 -0
- package/dist/store/draw-store.d.ts +1 -0
- package/dist/store/draw-store.js +396 -0
- package/dist/store/event-bridge.d.ts +1 -0
- package/dist/store/event-bridge.js +161 -0
- package/dist/store/index.d.ts +12 -0
- package/dist/store/index.js +4 -0
- package/dist/store/local-visibility.d.ts +21 -0
- package/dist/store/local-visibility.js +27 -0
- package/dist/store/lock.d.ts +67 -0
- package/dist/store/lock.js +54 -0
- package/dist/store/memory/change-bus.d.ts +60 -0
- package/dist/store/memory/change-bus.js +232 -0
- package/dist/store/memory/file-store.d.ts +15 -0
- package/dist/store/memory/file-store.js +33 -0
- package/dist/store/memory/frozen.d.ts +21 -0
- package/dist/store/memory/frozen.js +51 -0
- package/dist/store/memory/ui-state.d.ts +51 -0
- package/dist/store/memory/ui-state.js +223 -0
- package/dist/store/memory.d.ts +26 -0
- package/dist/store/memory.js +708 -0
- package/dist/store/spatial/index.d.ts +6 -0
- package/dist/store/spatial/index.js +4 -0
- package/dist/store/spatial/spatial-index.d.ts +90 -0
- package/dist/store/spatial/spatial-index.js +148 -0
- package/dist/store/spatial/store-spatial-index.d.ts +60 -0
- package/dist/store/spatial/store-spatial-index.js +125 -0
- package/dist/store/store.d.ts +417 -0
- package/dist/store/store.js +3 -0
- package/dist/store/types.d.ts +8 -0
- package/dist/store/types.js +3 -0
- package/dist/store/writable-layer.d.ts +35 -0
- package/dist/store/writable-layer.js +20 -0
- package/dist/view/cache/buffer.d.ts +28 -0
- package/dist/view/cache/buffer.js +176 -0
- package/dist/view/cache/earcut.d.ts +1 -0
- package/dist/view/cache/earcut.js +122 -0
- package/dist/view/cache/style-rule.d.ts +1 -0
- package/dist/view/cache/style-rule.js +97 -0
- package/dist/view/cache/terrain-fill.d.ts +30 -0
- package/dist/view/cache/terrain-fill.js +60 -0
- package/dist/view/cache/texture.d.ts +14 -0
- package/dist/view/cache/texture.js +292 -0
- package/dist/view/coordinator.d.ts +27 -0
- package/dist/view/coordinator.js +72 -0
- package/dist/view/feature-companion.d.ts +173 -0
- package/dist/view/feature-companion.js +108 -0
- package/dist/view/globe-subdivision.d.ts +78 -0
- package/dist/view/globe-subdivision.js +128 -0
- package/dist/view/index.d.ts +47 -0
- package/dist/view/index.js +20 -0
- package/dist/view/layer/attach.d.ts +20 -0
- package/dist/view/layer/attach.js +47 -0
- package/dist/view/layer/blend.d.ts +57 -0
- package/dist/view/layer/blend.js +14 -0
- package/dist/view/layer/custom-layer.d.ts +1 -0
- package/dist/view/layer/custom-layer.js +509 -0
- package/dist/view/layer/depth-state.d.ts +14 -0
- package/dist/view/layer/depth-state.js +44 -0
- package/dist/view/layer/display-list.d.ts +1 -0
- package/dist/view/layer/display-list.js +111 -0
- package/dist/view/layer/drape-planner.d.ts +139 -0
- package/dist/view/layer/drape-planner.js +726 -0
- package/dist/view/layer/frame-render.d.ts +57 -0
- package/dist/view/layer/frame-render.js +209 -0
- package/dist/view/layer/frame-state.d.ts +147 -0
- package/dist/view/layer/frame-state.js +484 -0
- package/dist/view/layer/gl-state.d.ts +77 -0
- package/dist/view/layer/gl-state.js +132 -0
- package/dist/view/layer/index.d.ts +6 -0
- package/dist/view/layer/index.js +5 -0
- package/dist/view/layer/render-scope.d.ts +30 -0
- package/dist/view/layer/render-scope.js +28 -0
- package/dist/view/layer/render.d.ts +87 -0
- package/dist/view/layer/render.js +187 -0
- package/dist/view/layer/renderers.d.ts +81 -0
- package/dist/view/layer/renderers.js +142 -0
- package/dist/view/layer/slot-manager.d.ts +26 -0
- package/dist/view/layer/slot-manager.js +133 -0
- package/dist/view/layer/slots.d.ts +33 -0
- package/dist/view/layer/slots.js +50 -0
- package/dist/view/layer/store-retained-bbox.d.ts +36 -0
- package/dist/view/layer/store-retained-bbox.js +188 -0
- package/dist/view/layer/store-retained-chunk.d.ts +97 -0
- package/dist/view/layer/store-retained-chunk.js +94 -0
- package/dist/view/layer/store-retained-classify.d.ts +34 -0
- package/dist/view/layer/store-retained-classify.js +88 -0
- package/dist/view/layer/store-retained-collect.d.ts +24 -0
- package/dist/view/layer/store-retained-collect.js +121 -0
- package/dist/view/layer/store-retained-coord-patch.d.ts +119 -0
- package/dist/view/layer/store-retained-coord-patch.js +168 -0
- package/dist/view/layer/store-retained-immediate.d.ts +63 -0
- package/dist/view/layer/store-retained-immediate.js +49 -0
- package/dist/view/layer/store-retained-invalidation.d.ts +96 -0
- package/dist/view/layer/store-retained-invalidation.js +192 -0
- package/dist/view/layer/store-retained.d.ts +198 -0
- package/dist/view/layer/store-retained.js +430 -0
- package/dist/view/layer/terrain-resolver.d.ts +1 -0
- package/dist/view/layer/terrain-resolver.js +174 -0
- package/dist/view/renderers/batch-manager.d.ts +61 -0
- package/dist/view/renderers/batch-manager.js +718 -0
- package/dist/view/renderers/draw-factors.d.ts +60 -0
- package/dist/view/renderers/draw-factors.js +35 -0
- package/dist/view/renderers/drawer.d.ts +1 -0
- package/dist/view/renderers/drawer.js +346 -0
- package/dist/view/renderers/image.d.ts +1 -0
- package/dist/view/renderers/image.js +255 -0
- package/dist/view/renderers/line/dash.d.ts +31 -0
- package/dist/view/renderers/line/dash.js +152 -0
- package/dist/view/renderers/line/line-geometry.d.ts +39 -0
- package/dist/view/renderers/line/line-geometry.js +460 -0
- package/dist/view/renderers/line/line-gl.d.ts +1 -0
- package/dist/view/renderers/line/line-gl.js +236 -0
- package/dist/view/renderers/line/line-shader.d.ts +1 -0
- package/dist/view/renderers/line/line-shader.js +364 -0
- package/dist/view/renderers/line/line-types.d.ts +43 -0
- package/dist/view/renderers/line/line-types.js +3 -0
- package/dist/view/renderers/line/line-uniforms.d.ts +1 -0
- package/dist/view/renderers/line/line-uniforms.js +390 -0
- package/dist/view/renderers/line/sdf-line.d.ts +92 -0
- package/dist/view/renderers/line/sdf-line.js +567 -0
- package/dist/view/renderers/point/billboard-depth.d.ts +10 -0
- package/dist/view/renderers/point/billboard-depth.js +56 -0
- package/dist/view/renderers/point/point-instance.d.ts +124 -0
- package/dist/view/renderers/point/point-instance.js +738 -0
- package/dist/view/renderers/point/point-sdf.d.ts +58 -0
- package/dist/view/renderers/point/point-sdf.js +170 -0
- package/dist/view/renderers/point/point-shape.d.ts +99 -0
- package/dist/view/renderers/point/point-shape.js +504 -0
- package/dist/view/renderers/point/point-style.d.ts +1 -0
- package/dist/view/renderers/point/point-style.js +46 -0
- package/dist/view/renderers/polygon/batch.d.ts +26 -0
- package/dist/view/renderers/polygon/batch.js +336 -0
- package/dist/view/renderers/polygon/earcut-input.d.ts +37 -0
- package/dist/view/renderers/polygon/earcut-input.js +55 -0
- package/dist/view/renderers/polygon/earcut-sliced.d.ts +69 -0
- package/dist/view/renderers/polygon/earcut-sliced.js +960 -0
- package/dist/view/renderers/polygon/fill.d.ts +74 -0
- package/dist/view/renderers/polygon/fill.js +251 -0
- package/dist/view/renderers/polygon/sdf-polygon.d.ts +62 -0
- package/dist/view/renderers/polygon/sdf-polygon.js +919 -0
- package/dist/view/renderers/polygon/terrain-cull.d.ts +3 -0
- package/dist/view/renderers/polygon/terrain-cull.js +14 -0
- package/dist/view/renderers/polygon/triangulator.d.ts +41 -0
- package/dist/view/renderers/polygon/triangulator.js +3 -0
- package/dist/view/renderers/retained.d.ts +43 -0
- package/dist/view/renderers/retained.js +3 -0
- package/dist/view/renderers/stroke.d.ts +121 -0
- package/dist/view/renderers/stroke.js +621 -0
- package/dist/view/shaders/frame.d.ts +8 -0
- package/dist/view/shaders/frame.js +37 -0
- package/dist/view/shaders/helpers.d.ts +238 -0
- package/dist/view/shaders/helpers.js +611 -0
- package/dist/view/shaders/initializer.d.ts +27 -0
- package/dist/view/shaders/initializer.js +125 -0
- package/dist/view/shaders/projection.d.ts +123 -0
- package/dist/view/shaders/projection.js +299 -0
- package/dist/view/shaders/quad-grid.d.ts +77 -0
- package/dist/view/shaders/quad-grid.js +128 -0
- package/dist/view/shaders/quad.d.ts +189 -0
- package/dist/view/shaders/quad.js +582 -0
- package/dist/view/shaders/retained-origin.d.ts +50 -0
- package/dist/view/shaders/retained-origin.js +67 -0
- package/dist/view/shaders/terrain-shade.d.ts +23 -0
- package/dist/view/shaders/terrain-shade.js +93 -0
- package/dist/view/style-rule.d.ts +166 -0
- package/dist/view/style-rule.js +300 -0
- package/dist/view/terrain/anchor.d.ts +135 -0
- package/dist/view/terrain/anchor.js +226 -0
- package/dist/view/terrain/context.d.ts +132 -0
- package/dist/view/terrain/context.js +437 -0
- package/dist/view/terrain/dem-atlas.d.ts +97 -0
- package/dist/view/terrain/dem-atlas.js +534 -0
- package/dist/view/terrain/detect.d.ts +126 -0
- package/dist/view/terrain/detect.js +198 -0
- package/dist/view/terrain/drape/bin-store.d.ts +179 -0
- package/dist/view/terrain/drape/bin-store.js +529 -0
- package/dist/view/terrain/drape/binning.d.ts +259 -0
- package/dist/view/terrain/drape/binning.js +604 -0
- package/dist/view/terrain/drape/edge-constrain.d.ts +37 -0
- package/dist/view/terrain/drape/edge-constrain.js +175 -0
- package/dist/view/terrain/drape/geometry.d.ts +95 -0
- package/dist/view/terrain/drape/geometry.js +260 -0
- package/dist/view/terrain/drape/mesh.d.ts +50 -0
- package/dist/view/terrain/drape/mesh.js +86 -0
- package/dist/view/terrain/drape/pass.d.ts +122 -0
- package/dist/view/terrain/drape/pass.js +379 -0
- package/dist/view/terrain/drape/quad-glyphs.d.ts +64 -0
- package/dist/view/terrain/drape/quad-glyphs.js +117 -0
- package/dist/view/terrain/drape/quad.d.ts +249 -0
- package/dist/view/terrain/drape/quad.js +835 -0
- package/dist/view/terrain/drape/renderer.d.ts +184 -0
- package/dist/view/terrain/drape/renderer.js +706 -0
- package/dist/view/terrain/drape/shared.d.ts +80 -0
- package/dist/view/terrain/drape/shared.js +173 -0
- package/dist/view/terrain/drape/stitch.d.ts +155 -0
- package/dist/view/terrain/drape/stitch.js +228 -0
- package/dist/view/terrain/ground.d.ts +72 -0
- package/dist/view/terrain/ground.js +151 -0
- package/dist/view/terrain/metrics.d.ts +180 -0
- package/dist/view/terrain/metrics.js +231 -0
- package/dist/view/terrain/occlusion.d.ts +11 -0
- package/dist/view/terrain/occlusion.js +129 -0
- package/dist/view/terrain/polygon.d.ts +86 -0
- package/dist/view/terrain/polygon.js +301 -0
- package/dist/view/terrain/shade.d.ts +48 -0
- package/dist/view/terrain/shade.js +45 -0
- package/dist/view/terrain/state.d.ts +99 -0
- package/dist/view/terrain/state.js +186 -0
- package/dist/view/terrain/tessellation.d.ts +265 -0
- package/dist/view/terrain/tessellation.js +924 -0
- package/dist/view/terrain/tiling.d.ts +56 -0
- package/dist/view/terrain/tiling.js +155 -0
- package/dist/view/terrain/upstream-terrain.d.ts +82 -0
- package/dist/view/terrain/upstream-terrain.js +116 -0
- package/dist/view/ui/auxiliary-handles.d.ts +151 -0
- package/dist/view/ui/auxiliary-handles.js +22 -0
- package/dist/view/ui/bounds.d.ts +53 -0
- package/dist/view/ui/bounds.js +149 -0
- package/dist/view/ui/box-selection.d.ts +1 -0
- package/dist/view/ui/box-selection.js +83 -0
- package/dist/view/ui/handle-test.d.ts +1 -0
- package/dist/view/ui/handle-test.js +437 -0
- package/dist/view/ui/handle-thinning.d.ts +122 -0
- package/dist/view/ui/handle-thinning.js +430 -0
- package/dist/view/ui/handles.d.ts +25 -0
- package/dist/view/ui/handles.js +673 -0
- package/dist/view/ui/helper.d.ts +19 -0
- package/dist/view/ui/helper.js +76 -0
- package/dist/view/ui/index.d.ts +15 -0
- package/dist/view/ui/index.js +15 -0
- package/dist/view/ui/selection-scope.d.ts +25 -0
- package/dist/view/ui/selection-scope.js +34 -0
- package/dist/view/ui/selection-ui/bounding-box.d.ts +44 -0
- package/dist/view/ui/selection-ui/bounding-box.js +240 -0
- package/dist/view/ui/selection-ui/extension-registry.d.ts +76 -0
- package/dist/view/ui/selection-ui/extension-registry.js +78 -0
- package/dist/view/ui/selection-ui/index.d.ts +12 -0
- package/dist/view/ui/selection-ui/index.js +12 -0
- package/dist/view/ui/selection-ui/renderer.d.ts +29 -0
- package/dist/view/ui/selection-ui/renderer.js +227 -0
- package/dist/view/ui/selection-ui/types.d.ts +55 -0
- package/dist/view/ui/selection-ui/types.js +3 -0
- package/dist/view/ui/selection-ui-drawer.d.ts +52 -0
- package/dist/view/ui/selection-ui-drawer.js +329 -0
- package/dist/view/ui/tentative.d.ts +1 -0
- package/dist/view/ui/tentative.js +320 -0
- package/dist/view/viewport.d.ts +119 -0
- package/dist/view/viewport.js +254 -0
- package/package.json +113 -0
|
@@ -0,0 +1,706 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { SELECTION_HIGHLIGHT_FILL_OPACITY, SELECTION_HIGHLIGHT_RGB, SELECTION_HIGHLIGHT_STROKE_EXTRA, } from '../../../shared/config/selection-highlight.js';
|
|
4
|
+
import { createProgram } from '../../shaders/helpers.js';
|
|
5
|
+
import { DRAPE_SELECTION_TEXEL, DRAPE_STYLE_TEXELS } from './bin-store.js';
|
|
6
|
+
import { applyEdgeConstrainUniforms, EDGE_CONSTRAIN_GLSL, EDGE_CONSTRAIN_UNIFORMS, EDGE_UNITS, } from './edge-constrain.js';
|
|
7
|
+
import { createTerrainMeshBuffers, disposeTerrainMeshBuffers, TILE_EXTENT, } from './mesh.js';
|
|
8
|
+
import { applyDrapeProjectionUniforms, applyDrapeTerrainUniforms, DRAPE_PROJECTION_UNIFORMS, DRAPE_TERRAIN_UNIFORMS, TERRAIN_SAMPLE_GLSL, TERRAIN_SHADE_GLSL, } from './shared.js';
|
|
9
|
+
export { EDGE_UNITS };
|
|
10
|
+
/**
|
|
11
|
+
* Width of the data textures (texels)
|
|
12
|
+
*
|
|
13
|
+
* The maximum texture dimension WebGL2 is guaranteed to provide is 2048. The wider
|
|
14
|
+
* it is taken, the fewer rows the same number of edges fits into, and the better
|
|
15
|
+
* the mechanism that transfers only the increment works.
|
|
16
|
+
*/
|
|
17
|
+
const DATA_TEX_WIDTH = 2048;
|
|
18
|
+
/** Texture units */
|
|
19
|
+
const UNIT_TERRAIN = 0;
|
|
20
|
+
const UNIT_EDGE = 1;
|
|
21
|
+
const UNIT_RUN = 2;
|
|
22
|
+
const UNIT_CELL = 3;
|
|
23
|
+
const UNIT_STYLE = 4;
|
|
24
|
+
/**
|
|
25
|
+
* Upper limit on the sources of the factors
|
|
26
|
+
*
|
|
27
|
+
* 0 = neutral (factor 1), then the datasets, then the Store layers
|
|
28
|
+
* (their opacity; see `drapeLayerSource` in pass.ts). A dataset past the limit is
|
|
29
|
+
* drawn with a factor of 1 (the plain color), and a layer past it has its opacity
|
|
30
|
+
* baked into its colors. 64 vec2 stay well inside the 224 fragment uniform vectors
|
|
31
|
+
* WebGL2 guarantees.
|
|
32
|
+
*/
|
|
33
|
+
export const DRAPE_MAX_SOURCES = 64;
|
|
34
|
+
/**
|
|
35
|
+
* The defaults of the shading, 335 degrees as seen on screen (northwest), an
|
|
36
|
+
* altitude of 45 degrees and a strength of 0.45
|
|
37
|
+
*/
|
|
38
|
+
export const DRAPE_LIGHT_AZIMUTH_DEG = 335;
|
|
39
|
+
export const DRAPE_LIGHT_ALTITUDE_DEG = 45;
|
|
40
|
+
export const DRAPE_LIGHT_STRENGTH = 0.45;
|
|
41
|
+
/**
|
|
42
|
+
* Converts a screen-anchored (anchor viewport) light source into a vector in the
|
|
43
|
+
* map coordinate system
|
|
44
|
+
*
|
|
45
|
+
* So that the light always comes from the top left on screen, the map's rotation
|
|
46
|
+
* (bearing) is added to convert it into an azimuth in the map coordinate system.
|
|
47
|
+
*/
|
|
48
|
+
export function resolveDrapeLight(bearingDeg) {
|
|
49
|
+
const azimuth = ((DRAPE_LIGHT_AZIMUTH_DEG + bearingDeg) * Math.PI) / 180;
|
|
50
|
+
const altitude = (DRAPE_LIGHT_ALTITUDE_DEG * Math.PI) / 180;
|
|
51
|
+
const horizontal = Math.cos(altitude);
|
|
52
|
+
return {
|
|
53
|
+
direction: [Math.sin(azimuth) * horizontal, Math.cos(azimuth) * horizontal, Math.sin(altitude)],
|
|
54
|
+
strength: DRAPE_LIGHT_STRENGTH,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The ratio of the lift from the ground surface (a proportion of the tile's ground
|
|
59
|
+
* size)
|
|
60
|
+
*
|
|
61
|
+
* One ten-thousandth. That amounts to 2 m for a z11 tile (about 19 km) and 6 cm
|
|
62
|
+
* for z16 (about 600 m). On screen it is less than 0.1 pixel, so it is invisible,
|
|
63
|
+
* yet in depth it reliably wins against the terrain surface.
|
|
64
|
+
*/
|
|
65
|
+
export const DRAPE_LIFT_RATIO = 1 / 2500;
|
|
66
|
+
const VERTEX_SOURCE = (prelude, define) => `#version 300 es
|
|
67
|
+
${prelude}
|
|
68
|
+
${define}
|
|
69
|
+
layout(location = 0) in vec2 a_pos;
|
|
70
|
+
// A very slight lift from the ground surface (meters), in order to win against the
|
|
71
|
+
// terrain surface in depth
|
|
72
|
+
uniform float u_drape_lift_m;
|
|
73
|
+
out vec2 v_tile;
|
|
74
|
+
${TERRAIN_SAMPLE_GLSL}
|
|
75
|
+
${EDGE_CONSTRAIN_GLSL}
|
|
76
|
+
|
|
77
|
+
void main() {
|
|
78
|
+
// A boundary vertex is constrained to the coarser side's polyline only when the
|
|
79
|
+
// neighbor is coarser (edge-constrain.ts)
|
|
80
|
+
float ele = drape_edge_constrained(a_pos, drape_get_elevation(a_pos));
|
|
81
|
+
|
|
82
|
+
// The boundary is not moved. Neither an overhang nor a skirt is created; it is
|
|
83
|
+
// closed only in the form where adjacent tiles share the same polyline.
|
|
84
|
+
gl_Position = projectTileWithElevation(a_pos, ele + u_drape_lift_m);
|
|
85
|
+
v_tile = a_pos / ${TILE_EXTENT}.0;
|
|
86
|
+
}`;
|
|
87
|
+
/**
|
|
88
|
+
* The shader that paints the pixels (exported because a test watches its structure)
|
|
89
|
+
*/
|
|
90
|
+
export const DRAPE_FRAGMENT_SOURCE = `#version 300 es
|
|
91
|
+
precision highp float;
|
|
92
|
+
precision highp int;
|
|
93
|
+
precision highp sampler2D;
|
|
94
|
+
|
|
95
|
+
in vec2 v_tile;
|
|
96
|
+
|
|
97
|
+
uniform sampler2D u_edge_tex;
|
|
98
|
+
uniform sampler2D u_run_tex;
|
|
99
|
+
uniform sampler2D u_cell_tex;
|
|
100
|
+
uniform sampler2D u_style_tex;
|
|
101
|
+
uniform int u_data_width;
|
|
102
|
+
uniform int u_cell_base;
|
|
103
|
+
uniform float u_cells;
|
|
104
|
+
uniform float u_opacity;
|
|
105
|
+
uniform float u_zoom;
|
|
106
|
+
// The factors per source (x = opacity, y = size). The zoom response of a
|
|
107
|
+
// dataset is applied here (baking it into the elements would mean
|
|
108
|
+
// rebuilding the index on every zoom)
|
|
109
|
+
uniform vec2 u_source_factors[${DRAPE_MAX_SOURCES}];
|
|
110
|
+
// Shading (an aid to reading the terrain). It is applied only to the fill, with
|
|
111
|
+
// the same light source and the same formula as the ground. This is not 3D
|
|
112
|
+
// lighting that illuminates symbols with an arbitrary light. It is also distinct
|
|
113
|
+
// from vertical exaggeration of the terrain (which follows the map's own factor), and
|
|
114
|
+
// it does not change the dimensions of the relief at all.
|
|
115
|
+
uniform vec3 u_light_dir; // a unit vector in the map coordinate system (east, north, up)
|
|
116
|
+
uniform float u_shade_strength;
|
|
117
|
+
uniform float u_tile_meters; // the ground size of this tile (meters)
|
|
118
|
+
// The selection highlight (rgb = the base color, a = the opacity of the area fill)
|
|
119
|
+
uniform vec4 u_selection_color;
|
|
120
|
+
// The extra outline thickness added by the selection highlight (physical pixels)
|
|
121
|
+
uniform float u_selection_stroke_extra;
|
|
122
|
+
// The range of elements to paint, [x, y). In order to insert an image (a quad)
|
|
123
|
+
// between polygons and lines following the stacking order, the element sequence is
|
|
124
|
+
// split at the image's position and drawn range by range. Elements outside the
|
|
125
|
+
// range still count toward the coverage of the selection highlight (the final
|
|
126
|
+
// segment composes the coverage of all elements)
|
|
127
|
+
uniform vec2 u_paint_range;
|
|
128
|
+
// Whether to compose the selection highlight in this draw (1 only for the final
|
|
129
|
+
// segment)
|
|
130
|
+
uniform float u_emit_selection;
|
|
131
|
+
|
|
132
|
+
out vec4 fragColor;
|
|
133
|
+
|
|
134
|
+
` +
|
|
135
|
+
TERRAIN_SAMPLE_GLSL +
|
|
136
|
+
TERRAIN_SHADE_GLSL +
|
|
137
|
+
`
|
|
138
|
+
|
|
139
|
+
vec4 fetchData(sampler2D tex, int i) {
|
|
140
|
+
return texelFetch(tex, ivec2(i % u_data_width, i / u_data_width), 0);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
float cross2(vec2 a, vec2 b) {
|
|
144
|
+
return a.x * b.y - a.y * b.x;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Whether the segment (p, q) and the segment (a, b) intersect
|
|
148
|
+
bool crosses(vec2 p, vec2 q, vec2 a, vec2 b) {
|
|
149
|
+
float d1 = cross2(b - a, p - a);
|
|
150
|
+
float d2 = cross2(b - a, q - a);
|
|
151
|
+
float d3 = cross2(q - p, a - p);
|
|
152
|
+
float d4 = cross2(q - p, b - p);
|
|
153
|
+
return (d1 * d2 < 0.0) && (d3 * d4 < 0.0);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// The shortest vector from a point to a segment (in tile-local coordinates)
|
|
157
|
+
vec2 closestVector(vec2 p, vec2 a, vec2 b) {
|
|
158
|
+
vec2 ab = b - a;
|
|
159
|
+
float len2 = dot(ab, ab);
|
|
160
|
+
float t = len2 > 0.0 ? clamp(dot(p - a, ab) / len2, 0.0, 1.0) : 0.0;
|
|
161
|
+
return p - (a + ab * t);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Compose on top (premultiplied alpha)
|
|
165
|
+
vec4 over(vec4 below, vec3 rgb, float a) {
|
|
166
|
+
return vec4(rgb * a + below.rgb * (1.0 - a), a + below.a * (1.0 - a));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
void main() {
|
|
170
|
+
vec2 p = v_tile;
|
|
171
|
+
|
|
172
|
+
// The inverse Jacobian, mapping a displacement in tile-local coordinates to a
|
|
173
|
+
// displacement in screen pixels. The derivatives are taken before entering a
|
|
174
|
+
// branch (under uniform control flow).
|
|
175
|
+
vec2 dpdx = dFdx(p);
|
|
176
|
+
vec2 dpdy = dFdy(p);
|
|
177
|
+
float det = dpdx.x * dpdy.y - dpdy.x * dpdx.y;
|
|
178
|
+
mat2 jacobianInverse;
|
|
179
|
+
if (abs(det) < 1e-24) {
|
|
180
|
+
// When the derivatives vanish, for instance on a surface seen exactly edge
|
|
181
|
+
// on, the matrix cannot be built. An isotropic approximation stands in for
|
|
182
|
+
// it (discarding would leave that pixel unpainted)
|
|
183
|
+
float s = max(max(length(dpdx), length(dpdy)), 1e-12);
|
|
184
|
+
jacobianInverse = mat2(1.0 / s, 0.0, 0.0, 1.0 / s);
|
|
185
|
+
} else {
|
|
186
|
+
jacobianInverse = mat2(dpdy.y, -dpdx.y, -dpdy.x, dpdx.x) / det;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
ivec2 cell = ivec2(clamp(floor(p * u_cells), vec2(0.0), vec2(u_cells - 1.0)));
|
|
190
|
+
int cellIndex = u_cell_base + cell.y * int(u_cells) + cell.x;
|
|
191
|
+
vec4 cellData = fetchData(u_cell_tex, cellIndex);
|
|
192
|
+
int runStart = int(cellData.x);
|
|
193
|
+
int runCount = int(cellData.y);
|
|
194
|
+
if (runCount == 0) discard;
|
|
195
|
+
|
|
196
|
+
vec2 origin = vec2(cell) / u_cells;
|
|
197
|
+
|
|
198
|
+
vec4 acc = vec4(0.0);
|
|
199
|
+
float shade = -1.0;
|
|
200
|
+
// The coverage of the selection highlight (the maximum over the features that
|
|
201
|
+
// are selected at this pixel)
|
|
202
|
+
float selFill = 0.0;
|
|
203
|
+
float selStroke = 0.0;
|
|
204
|
+
|
|
205
|
+
for (int r = 0; r < runCount; r++) {
|
|
206
|
+
vec4 run = fetchData(u_run_tex, runStart + r);
|
|
207
|
+
int elementIndex = int(run.x);
|
|
208
|
+
int edgeStart = int(run.y);
|
|
209
|
+
int edgeCount = int(run.z);
|
|
210
|
+
bool inside = run.w > 0.5;
|
|
211
|
+
|
|
212
|
+
// Range drawing. Only the elements in u_paint_range are painted. The coverage
|
|
213
|
+
// of the selection is accumulated from outside the range as well, but only by
|
|
214
|
+
// the segment that composes it (u_emit_selection); the other segments skip it.
|
|
215
|
+
// The runs of a cell are in draw order (binning.ts), so a segment that does not
|
|
216
|
+
// compose the selection is done once it passes the end of its range: with k
|
|
217
|
+
// images between the sections, a section no longer pays for the runs of the
|
|
218
|
+
// sections after it
|
|
219
|
+
if (u_emit_selection < 0.5 && float(elementIndex) >= u_paint_range.y) break;
|
|
220
|
+
bool paints = float(elementIndex) >= u_paint_range.x
|
|
221
|
+
&& float(elementIndex) < u_paint_range.y;
|
|
222
|
+
bool selected = u_emit_selection > 0.5
|
|
223
|
+
&& fetchData(u_style_tex, elementIndex * ${DRAPE_STYLE_TEXELS} + ${DRAPE_SELECTION_TEXEL}).x
|
|
224
|
+
> 0.5;
|
|
225
|
+
if (!paints && !selected) continue;
|
|
226
|
+
|
|
227
|
+
float minDist = 1.0e9;
|
|
228
|
+
for (int e = 0; e < edgeCount; e++) {
|
|
229
|
+
vec4 seg = fetchData(u_edge_tex, edgeStart + e);
|
|
230
|
+
vec2 a = seg.xy;
|
|
231
|
+
vec2 b = seg.zw;
|
|
232
|
+
if (crosses(origin, p, a, b)) inside = !inside;
|
|
233
|
+
vec2 offset = closestVector(p, a, b);
|
|
234
|
+
minDist = min(minDist, length(jacobianInverse * offset));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
int styleAt = elementIndex * ${DRAPE_STYLE_TEXELS};
|
|
238
|
+
vec4 fill = fetchData(u_style_tex, styleAt);
|
|
239
|
+
vec4 stroke = fetchData(u_style_tex, styleAt + 1);
|
|
240
|
+
vec4 params = fetchData(u_style_tex, styleAt + 2);
|
|
241
|
+
int source = int(params.z);
|
|
242
|
+
vec2 factors = source >= 0 && source < ${DRAPE_MAX_SOURCES}
|
|
243
|
+
? u_source_factors[source]
|
|
244
|
+
: vec2(1.0, 1.0);
|
|
245
|
+
// An element that has a reference zoom for its line width changes its
|
|
246
|
+
// thickness with the same formula as the retained batch path
|
|
247
|
+
float widthScale = params.w >= 0.0 ? exp2(u_zoom - params.w) : 1.0;
|
|
248
|
+
float halfWidth = params.x * 0.5 * factors.y * widthScale;
|
|
249
|
+
bool isPolygon = params.y < 0.5;
|
|
250
|
+
|
|
251
|
+
if (paints && isPolygon && fill.a > 0.0) {
|
|
252
|
+
// A signed distance, negative inside and positive outside (screen pixels)
|
|
253
|
+
float signedDist = inside ? -minDist : minDist;
|
|
254
|
+
float coverage = clamp(0.5 - signedDist, 0.0, 1.0);
|
|
255
|
+
if (coverage > 0.0) {
|
|
256
|
+
// Apply the same shading as the ground only to the fill (lines,
|
|
257
|
+
// points and handles are unshaded)
|
|
258
|
+
if (shade < 0.0) shade = terrainShade(p);
|
|
259
|
+
acc = over(acc, fill.rgb * shade, fill.a * coverage * factors.x);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (paints && halfWidth > 0.0 && stroke.a > 0.0) {
|
|
264
|
+
float coverage = clamp(halfWidth + 0.5 - minDist, 0.0, 1.0);
|
|
265
|
+
if (coverage > 0.0) acc = over(acc, stroke.rgb, stroke.a * coverage * factors.x);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Accumulate the coverage of the selection highlight. It is not composed
|
|
269
|
+
// here.
|
|
270
|
+
//
|
|
271
|
+
// Composing it at the stacking order of the selected feature buries the
|
|
272
|
+
// highlight under the fill of the features stacked above it (the
|
|
273
|
+
// municipalities when a prefecture is selected). Small features appear as
|
|
274
|
+
// the zoom is raised, so it showed up as "the red disappears when you zoom
|
|
275
|
+
// in". The immediate mode always overpainted it last, so this is aligned
|
|
276
|
+
// with the same "compose last" convention.
|
|
277
|
+
if (selected) {
|
|
278
|
+
if (isPolygon) {
|
|
279
|
+
float signedDist = inside ? -minDist : minDist;
|
|
280
|
+
float coverage = clamp(0.5 - signedDist, 0.0, 1.0);
|
|
281
|
+
selFill = max(selFill, coverage * factors.x);
|
|
282
|
+
}
|
|
283
|
+
// The added thickness is kept constant in screen pixels (so that "an
|
|
284
|
+
// outline one size thicker" always looks the same regardless of the
|
|
285
|
+
// unit of the original thickness). The highlight outline is also drawn
|
|
286
|
+
// for features that have no outline (the same as the immediate mode)
|
|
287
|
+
float selHalf = halfWidth + u_selection_stroke_extra * 0.5;
|
|
288
|
+
selStroke = max(selStroke, clamp(selHalf + 0.5 - minDist, 0.0, 1.0) * factors.x);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// The selection highlight is composed at the end of the pixel (so it is not
|
|
293
|
+
// buried under the features stacked above). In range drawing only the final
|
|
294
|
+
// segment composes it (composing per segment would bury it under the fill of
|
|
295
|
+
// later segments, and the overlapping places would also turn darker)
|
|
296
|
+
if (u_emit_selection > 0.5 && selFill > 0.0) {
|
|
297
|
+
// The fill gets the same shading as the ground (the same convention as the
|
|
298
|
+
// underlying fill)
|
|
299
|
+
if (shade < 0.0) shade = terrainShade(p);
|
|
300
|
+
acc = over(acc, u_selection_color.rgb * shade, u_selection_color.a * selFill);
|
|
301
|
+
}
|
|
302
|
+
if (u_emit_selection > 0.5 && selStroke > 0.0) acc = over(acc, u_selection_color.rgb, selStroke);
|
|
303
|
+
|
|
304
|
+
if (acc.a <= 0.0) discard;
|
|
305
|
+
fragColor = acc * u_opacity;
|
|
306
|
+
}`;
|
|
307
|
+
/**
|
|
308
|
+
* The renderer of the analytic drape
|
|
309
|
+
*/
|
|
310
|
+
export class DrapeRenderer {
|
|
311
|
+
constructor(gl) {
|
|
312
|
+
Object.defineProperty(this, "gl", {
|
|
313
|
+
enumerable: true,
|
|
314
|
+
configurable: true,
|
|
315
|
+
writable: true,
|
|
316
|
+
value: void 0
|
|
317
|
+
});
|
|
318
|
+
Object.defineProperty(this, "program", {
|
|
319
|
+
enumerable: true,
|
|
320
|
+
configurable: true,
|
|
321
|
+
writable: true,
|
|
322
|
+
value: null
|
|
323
|
+
});
|
|
324
|
+
Object.defineProperty(this, "variantName", {
|
|
325
|
+
enumerable: true,
|
|
326
|
+
configurable: true,
|
|
327
|
+
writable: true,
|
|
328
|
+
value: ''
|
|
329
|
+
});
|
|
330
|
+
Object.defineProperty(this, "mesh", {
|
|
331
|
+
enumerable: true,
|
|
332
|
+
configurable: true,
|
|
333
|
+
writable: true,
|
|
334
|
+
value: null
|
|
335
|
+
});
|
|
336
|
+
Object.defineProperty(this, "edgeTex", {
|
|
337
|
+
enumerable: true,
|
|
338
|
+
configurable: true,
|
|
339
|
+
writable: true,
|
|
340
|
+
value: null
|
|
341
|
+
});
|
|
342
|
+
Object.defineProperty(this, "runTex", {
|
|
343
|
+
enumerable: true,
|
|
344
|
+
configurable: true,
|
|
345
|
+
writable: true,
|
|
346
|
+
value: null
|
|
347
|
+
});
|
|
348
|
+
Object.defineProperty(this, "cellTex", {
|
|
349
|
+
enumerable: true,
|
|
350
|
+
configurable: true,
|
|
351
|
+
writable: true,
|
|
352
|
+
value: null
|
|
353
|
+
});
|
|
354
|
+
Object.defineProperty(this, "styleTex", {
|
|
355
|
+
enumerable: true,
|
|
356
|
+
configurable: true,
|
|
357
|
+
writable: true,
|
|
358
|
+
value: null
|
|
359
|
+
});
|
|
360
|
+
Object.defineProperty(this, "edgeTexSize", {
|
|
361
|
+
enumerable: true,
|
|
362
|
+
configurable: true,
|
|
363
|
+
writable: true,
|
|
364
|
+
value: [0, 0]
|
|
365
|
+
});
|
|
366
|
+
Object.defineProperty(this, "runTexSize", {
|
|
367
|
+
enumerable: true,
|
|
368
|
+
configurable: true,
|
|
369
|
+
writable: true,
|
|
370
|
+
value: [0, 0]
|
|
371
|
+
});
|
|
372
|
+
Object.defineProperty(this, "cellTexSize", {
|
|
373
|
+
enumerable: true,
|
|
374
|
+
configurable: true,
|
|
375
|
+
writable: true,
|
|
376
|
+
value: [0, 0]
|
|
377
|
+
});
|
|
378
|
+
Object.defineProperty(this, "styleTexSize", {
|
|
379
|
+
enumerable: true,
|
|
380
|
+
configurable: true,
|
|
381
|
+
writable: true,
|
|
382
|
+
value: [0, 0]
|
|
383
|
+
});
|
|
384
|
+
Object.defineProperty(this, "uploaded", {
|
|
385
|
+
enumerable: true,
|
|
386
|
+
configurable: true,
|
|
387
|
+
writable: true,
|
|
388
|
+
value: { builderId: -1, edges: 0, runs: 0, cells: 0, styles: 0 }
|
|
389
|
+
});
|
|
390
|
+
/** The selection version the transferred style table reflects (-1 = not transferred) */
|
|
391
|
+
Object.defineProperty(this, "uploadedSelection", {
|
|
392
|
+
enumerable: true,
|
|
393
|
+
configurable: true,
|
|
394
|
+
writable: true,
|
|
395
|
+
value: -1
|
|
396
|
+
});
|
|
397
|
+
Object.defineProperty(this, "locations", {
|
|
398
|
+
enumerable: true,
|
|
399
|
+
configurable: true,
|
|
400
|
+
writable: true,
|
|
401
|
+
value: {}
|
|
402
|
+
});
|
|
403
|
+
/** The most recent failure reason (for diagnostics) */
|
|
404
|
+
Object.defineProperty(this, "lastError", {
|
|
405
|
+
enumerable: true,
|
|
406
|
+
configurable: true,
|
|
407
|
+
writable: true,
|
|
408
|
+
value: ''
|
|
409
|
+
});
|
|
410
|
+
/** MAX_TEXTURE_SIZE of the context (read once, 0 = not read yet) */
|
|
411
|
+
Object.defineProperty(this, "maxTextureSize", {
|
|
412
|
+
enumerable: true,
|
|
413
|
+
configurable: true,
|
|
414
|
+
writable: true,
|
|
415
|
+
value: 0
|
|
416
|
+
});
|
|
417
|
+
this.gl = gl;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Allocates the shader and the mesh
|
|
421
|
+
*/
|
|
422
|
+
ensure(shaderData, meshSize) {
|
|
423
|
+
const gl = this.gl;
|
|
424
|
+
if (!this.mesh || this.mesh.meshSize !== meshSize) {
|
|
425
|
+
if (this.mesh)
|
|
426
|
+
disposeTerrainMeshBuffers(gl, this.mesh);
|
|
427
|
+
this.mesh = createTerrainMeshBuffers(gl, meshSize);
|
|
428
|
+
if (!this.mesh) {
|
|
429
|
+
this.lastError = 'mesh-alloc-failed';
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
if (this.program && this.variantName === shaderData.variantName)
|
|
434
|
+
return true;
|
|
435
|
+
if (this.program)
|
|
436
|
+
gl.deleteProgram(this.program);
|
|
437
|
+
try {
|
|
438
|
+
this.program = createProgram(gl, VERTEX_SOURCE(shaderData.vertexShaderPrelude, shaderData.define), DRAPE_FRAGMENT_SOURCE);
|
|
439
|
+
}
|
|
440
|
+
catch (error) {
|
|
441
|
+
this.lastError = `shader: ${String(error)}`;
|
|
442
|
+
this.program = null;
|
|
443
|
+
return false;
|
|
444
|
+
}
|
|
445
|
+
this.variantName = shaderData.variantName;
|
|
446
|
+
const names = [
|
|
447
|
+
...DRAPE_PROJECTION_UNIFORMS,
|
|
448
|
+
...DRAPE_TERRAIN_UNIFORMS,
|
|
449
|
+
'u_edge_tex',
|
|
450
|
+
'u_run_tex',
|
|
451
|
+
'u_cell_tex',
|
|
452
|
+
'u_style_tex',
|
|
453
|
+
'u_data_width',
|
|
454
|
+
'u_cell_base',
|
|
455
|
+
'u_cells',
|
|
456
|
+
'u_opacity',
|
|
457
|
+
'u_zoom',
|
|
458
|
+
'u_source_factors[0]',
|
|
459
|
+
'u_light_dir',
|
|
460
|
+
'u_shade_strength',
|
|
461
|
+
'u_tile_meters',
|
|
462
|
+
'u_drape_lift_m',
|
|
463
|
+
'u_selection_color',
|
|
464
|
+
'u_selection_stroke_extra',
|
|
465
|
+
'u_paint_range',
|
|
466
|
+
'u_emit_selection',
|
|
467
|
+
...EDGE_CONSTRAIN_UNIFORMS,
|
|
468
|
+
];
|
|
469
|
+
this.locations = {};
|
|
470
|
+
for (const name of names) {
|
|
471
|
+
this.locations[name] = gl.getUniformLocation(this.program, name);
|
|
472
|
+
}
|
|
473
|
+
return true;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Transfers the part of the packed arrays that has not been sent yet to the GPU
|
|
477
|
+
*
|
|
478
|
+
* The arrays are append-only, so sending only the rows that were added is
|
|
479
|
+
* enough. Everything is sent only when the version has been swapped (it became a
|
|
480
|
+
* different builder) and when the textures have been recreated.
|
|
481
|
+
*
|
|
482
|
+
* @returns false when a table does not fit in a texture of this GPU (taller than
|
|
483
|
+
* MAX_TEXTURE_SIZE, or the allocation failed). The caller then draws the frame
|
|
484
|
+
* without the analytic drape, the same way as when the index is over its budget
|
|
485
|
+
*/
|
|
486
|
+
upload(pack) {
|
|
487
|
+
if (this.uploaded.builderId !== pack.id) {
|
|
488
|
+
this.uploaded = { builderId: pack.id, edges: 0, runs: 0, cells: 0, styles: 0 };
|
|
489
|
+
this.uploadedSelection = -1;
|
|
490
|
+
}
|
|
491
|
+
// The selection highlight rewrites rows that have already been sent (it is not
|
|
492
|
+
// an append), so when the version moves only the style table is sent again from
|
|
493
|
+
// the beginning. The style table is 4 texels per element, orders of magnitude
|
|
494
|
+
// smaller than the edge table
|
|
495
|
+
if (this.uploadedSelection !== pack.selectionVersion) {
|
|
496
|
+
this.uploaded.styles = 0;
|
|
497
|
+
this.uploadedSelection = pack.selectionVersion;
|
|
498
|
+
}
|
|
499
|
+
this.edgeTex = this.uploadTexture(this.edgeTex, 'edgeTexSize', 'edges', DATA_TEX_WIDTH, pack.edges, pack.edgeCount);
|
|
500
|
+
this.runTex = this.uploadTexture(this.runTex, 'runTexSize', 'runs', DATA_TEX_WIDTH, pack.runs, pack.runCount);
|
|
501
|
+
this.cellTex = this.uploadTexture(this.cellTex, 'cellTexSize', 'cells', DATA_TEX_WIDTH, pack.cells, pack.cellCount);
|
|
502
|
+
// The style table is laid out like the others (4 texels per element in rows of
|
|
503
|
+
// DATA_TEX_WIDTH, a multiple of 4), so its height grows with elements / 512, not elements
|
|
504
|
+
this.styleTex = this.uploadTexture(this.styleTex, 'styleTexSize', 'styles', DATA_TEX_WIDTH, pack.styles, DRAPE_STYLE_TEXELS * Math.max(1, pack.elementCount));
|
|
505
|
+
return (this.edgeTex !== null &&
|
|
506
|
+
this.runTex !== null &&
|
|
507
|
+
this.cellTex !== null &&
|
|
508
|
+
this.styleTex !== null);
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Draws a single tile
|
|
512
|
+
*
|
|
513
|
+
* @param projectionData The ProjectionData of that tile
|
|
514
|
+
* @param sourceFactors The factors per source (x = opacity, y = size)
|
|
515
|
+
* @param opacity The overall opacity (default 1)
|
|
516
|
+
* @param segment The segment of range drawing (omitted = all elements + the
|
|
517
|
+
* selection highlight). When inserting an image between polygons and lines
|
|
518
|
+
* following the stacking order, the caller splits the element sequence at the
|
|
519
|
+
* image's position and draws it segment by segment
|
|
520
|
+
*/
|
|
521
|
+
drawTile(draw, projectionData, light, zoom, sourceFactors, pixelRatio = 1, opacity = 1, segment) {
|
|
522
|
+
const gl = this.gl;
|
|
523
|
+
const program = this.program;
|
|
524
|
+
const mesh = this.mesh;
|
|
525
|
+
if (!program || !mesh || !this.edgeTex || !this.cellTex || !this.styleTex) {
|
|
526
|
+
this.lastError = 'draw: missing resources';
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
gl.useProgram(program);
|
|
530
|
+
const set = this.locations;
|
|
531
|
+
applyDrapeProjectionUniforms(gl, set, projectionData);
|
|
532
|
+
applyDrapeTerrainUniforms(gl, set, draw.terrain, UNIT_TERRAIN);
|
|
533
|
+
this.bindData(UNIT_EDGE, this.edgeTex, set.u_edge_tex);
|
|
534
|
+
this.bindData(UNIT_RUN, this.runTex, set.u_run_tex);
|
|
535
|
+
this.bindData(UNIT_CELL, this.cellTex, set.u_cell_tex);
|
|
536
|
+
this.bindData(UNIT_STYLE, this.styleTex, set.u_style_tex);
|
|
537
|
+
if (set.u_data_width)
|
|
538
|
+
gl.uniform1i(set.u_data_width, DATA_TEX_WIDTH);
|
|
539
|
+
if (set.u_cell_base)
|
|
540
|
+
gl.uniform1i(set.u_cell_base, draw.cellOffset);
|
|
541
|
+
if (set.u_cells)
|
|
542
|
+
gl.uniform1f(set.u_cells, draw.grid);
|
|
543
|
+
if (set.u_opacity)
|
|
544
|
+
gl.uniform1f(set.u_opacity, opacity);
|
|
545
|
+
if (set.u_zoom)
|
|
546
|
+
gl.uniform1f(set.u_zoom, zoom);
|
|
547
|
+
if (set['u_source_factors[0]']) {
|
|
548
|
+
gl.uniform2fv(set['u_source_factors[0]'], sourceFactors);
|
|
549
|
+
}
|
|
550
|
+
if (set.u_light_dir) {
|
|
551
|
+
gl.uniform3f(set.u_light_dir, light.direction[0], light.direction[1], light.direction[2]);
|
|
552
|
+
}
|
|
553
|
+
if (set.u_shade_strength)
|
|
554
|
+
gl.uniform1f(set.u_shade_strength, light.strength);
|
|
555
|
+
if (set.u_tile_meters)
|
|
556
|
+
gl.uniform1f(set.u_tile_meters, draw.groundMeters);
|
|
557
|
+
// The lift is made proportional to the tile's ground size. It then amounts to
|
|
558
|
+
// the same quantity on screen, so at any zoom it stays within "too small to
|
|
559
|
+
// see, yet reliably winning in depth". A constant depth bias (polygonOffset)
|
|
560
|
+
// depends on the on-screen gradient of the depth and on the resolution of the
|
|
561
|
+
// depth buffer, so on a shallow-angle slope it works too strongly or not at all
|
|
562
|
+
if (set.u_drape_lift_m) {
|
|
563
|
+
gl.uniform1f(set.u_drape_lift_m, draw.groundMeters * DRAPE_LIFT_RATIO);
|
|
564
|
+
}
|
|
565
|
+
// The appearance of the selection highlight is constant, so the values
|
|
566
|
+
// themselves are the same every frame (a uniform is state that persists per
|
|
567
|
+
// program, so writing it once per tile is enough)
|
|
568
|
+
if (set.u_selection_color) {
|
|
569
|
+
gl.uniform4f(set.u_selection_color, SELECTION_HIGHLIGHT_RGB[0], SELECTION_HIGHLIGHT_RGB[1], SELECTION_HIGHLIGHT_RGB[2], SELECTION_HIGHLIGHT_FILL_OPACITY);
|
|
570
|
+
}
|
|
571
|
+
if (set.u_selection_stroke_extra) {
|
|
572
|
+
gl.uniform1f(set.u_selection_stroke_extra, SELECTION_HIGHLIGHT_STROKE_EXTRA * pixelRatio);
|
|
573
|
+
}
|
|
574
|
+
// The segment of range drawing. When omitted, all elements are painted and the
|
|
575
|
+
// selection highlight is composed as well (a uniform is state that persists per
|
|
576
|
+
// program, so it is written explicitly every time)
|
|
577
|
+
if (set.u_paint_range) {
|
|
578
|
+
gl.uniform2f(set.u_paint_range, segment?.paintFrom ?? 0, segment?.paintTo ?? 1e9);
|
|
579
|
+
}
|
|
580
|
+
if (set.u_emit_selection) {
|
|
581
|
+
gl.uniform1f(set.u_emit_selection, (segment?.emitSelection ?? true) ? 1 : 0);
|
|
582
|
+
}
|
|
583
|
+
// The step and the DEM are written from one and the same value (see the note in
|
|
584
|
+
// edge-constrain.ts)
|
|
585
|
+
applyEdgeConstrainUniforms(gl, set, draw.edges, draw.terrain);
|
|
586
|
+
// The ground surface is one-sided, but a slope is sometimes seen from behind.
|
|
587
|
+
// No culling is applied
|
|
588
|
+
gl.disable(gl.CULL_FACE);
|
|
589
|
+
gl.bindVertexArray(mesh.vao);
|
|
590
|
+
gl.drawElements(gl.TRIANGLES, mesh.indexCount, gl.UNSIGNED_INT, 0);
|
|
591
|
+
gl.bindVertexArray(null);
|
|
592
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Releases the resources
|
|
596
|
+
*/
|
|
597
|
+
dispose() {
|
|
598
|
+
const gl = this.gl;
|
|
599
|
+
if (this.program) {
|
|
600
|
+
gl.deleteProgram(this.program);
|
|
601
|
+
this.program = null;
|
|
602
|
+
}
|
|
603
|
+
if (this.mesh) {
|
|
604
|
+
disposeTerrainMeshBuffers(gl, this.mesh);
|
|
605
|
+
this.mesh = null;
|
|
606
|
+
}
|
|
607
|
+
for (const texture of [this.edgeTex, this.runTex, this.cellTex, this.styleTex]) {
|
|
608
|
+
if (texture)
|
|
609
|
+
gl.deleteTexture(texture);
|
|
610
|
+
}
|
|
611
|
+
this.edgeTex = null;
|
|
612
|
+
this.runTex = null;
|
|
613
|
+
this.cellTex = null;
|
|
614
|
+
this.styleTex = null;
|
|
615
|
+
this.edgeTexSize = [0, 0];
|
|
616
|
+
this.runTexSize = [0, 0];
|
|
617
|
+
this.cellTexSize = [0, 0];
|
|
618
|
+
this.styleTexSize = [0, 0];
|
|
619
|
+
this.uploaded = { builderId: -1, edges: 0, runs: 0, cells: 0, styles: 0 };
|
|
620
|
+
this.uploadedSelection = -1;
|
|
621
|
+
}
|
|
622
|
+
bindData(unit, texture, location) {
|
|
623
|
+
const gl = this.gl;
|
|
624
|
+
gl.activeTexture(gl.TEXTURE0 + unit);
|
|
625
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
626
|
+
if (location)
|
|
627
|
+
gl.uniform1i(location, unit);
|
|
628
|
+
}
|
|
629
|
+
/** The tallest data texture this GPU allows (MAX_TEXTURE_SIZE, read once) */
|
|
630
|
+
textureSizeLimit() {
|
|
631
|
+
if (this.maxTextureSize === 0) {
|
|
632
|
+
const max = Number(this.gl.getParameter(this.gl.MAX_TEXTURE_SIZE));
|
|
633
|
+
this.maxTextureSize = Number.isFinite(max) && max > 0 ? max : 4096;
|
|
634
|
+
}
|
|
635
|
+
return this.maxTextureSize;
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Allocates a data texture and transfers the rows that have not been sent yet
|
|
639
|
+
*
|
|
640
|
+
* texStorage2D is immutable, so the texture is recreated whenever the required
|
|
641
|
+
* size changes (once recreated, everything is sent again).
|
|
642
|
+
*/
|
|
643
|
+
uploadTexture(texture, sizeField, markField, width, data, texelCount) {
|
|
644
|
+
const gl = this.gl;
|
|
645
|
+
const size = this[sizeField];
|
|
646
|
+
const neededRows = Math.max(1, Math.ceil(texelCount / width));
|
|
647
|
+
const maxRows = this.textureSizeLimit();
|
|
648
|
+
let target = texture;
|
|
649
|
+
if (!target || size[0] !== width || size[1] < neededRows) {
|
|
650
|
+
if (target)
|
|
651
|
+
gl.deleteTexture(target);
|
|
652
|
+
this[sizeField] = [0, 0];
|
|
653
|
+
this.uploaded[markField] = 0;
|
|
654
|
+
// A table taller than the GPU allows cannot be allocated (texStorage2D would fail with
|
|
655
|
+
// INVALID_VALUE and leave a texture that samples as zeros)
|
|
656
|
+
if (neededRows > maxRows) {
|
|
657
|
+
this.lastError = `texture-limit: ${markField} needs ${neededRows} rows of ${maxRows}`;
|
|
658
|
+
return null;
|
|
659
|
+
}
|
|
660
|
+
target = gl.createTexture();
|
|
661
|
+
if (!target)
|
|
662
|
+
return null;
|
|
663
|
+
// Allocate a few extra rows (so it is not recreated on every increase)
|
|
664
|
+
const rows = Math.min(maxRows, Math.max(1, Math.ceil(neededRows * 1.5)));
|
|
665
|
+
gl.bindTexture(gl.TEXTURE_2D, target);
|
|
666
|
+
gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, width, rows);
|
|
667
|
+
// Only the allocation is checked (it is rare; getError is a synchronous round trip)
|
|
668
|
+
if (gl.getError() !== gl.NO_ERROR) {
|
|
669
|
+
gl.deleteTexture(target);
|
|
670
|
+
this.lastError = `texture-alloc-failed: ${markField}`;
|
|
671
|
+
return null;
|
|
672
|
+
}
|
|
673
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
674
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
675
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
676
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
677
|
+
this[sizeField] = [width, rows];
|
|
678
|
+
this.uploaded[markField] = 0;
|
|
679
|
+
}
|
|
680
|
+
else {
|
|
681
|
+
gl.bindTexture(gl.TEXTURE_2D, target);
|
|
682
|
+
}
|
|
683
|
+
const uploaded = this.uploaded[markField];
|
|
684
|
+
if (texelCount <= uploaded)
|
|
685
|
+
return target;
|
|
686
|
+
// Writing continues from the middle of an already transferred row, so the
|
|
687
|
+
// transfer starts at the beginning of that row
|
|
688
|
+
const fromRow = Math.floor(uploaded / width);
|
|
689
|
+
const toRow = Math.ceil(texelCount / width);
|
|
690
|
+
const rows = toRow - fromRow;
|
|
691
|
+
const needed = rows * width * 4;
|
|
692
|
+
const offset = fromRow * width * 4;
|
|
693
|
+
const payload = data.length >= offset + needed
|
|
694
|
+
? data.subarray(offset, offset + needed)
|
|
695
|
+
: padTo(data.subarray(offset), needed);
|
|
696
|
+
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, fromRow, width, rows, gl.RGBA, gl.FLOAT, payload);
|
|
697
|
+
this.uploaded[markField] = texelCount;
|
|
698
|
+
return target;
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
/** Pads with 0 up to the length required for the transfer */
|
|
702
|
+
function padTo(data, length) {
|
|
703
|
+
const out = new Float32Array(length);
|
|
704
|
+
out.set(data.subarray(0, Math.min(data.length, length)));
|
|
705
|
+
return out;
|
|
706
|
+
}
|